diff --git a/config/default.php b/config/default.php index aa503c14fa..c22857700e 100644 --- a/config/default.php +++ b/config/default.php @@ -105,6 +105,8 @@ ], 'password' => [ 'create' => filter_var(env('PASSBOLT_EMAIL_SEND_PASSWORD_CREATE', false), FILTER_VALIDATE_BOOLEAN), + 'updateSelf' => filter_var(env('PASSBOLT_EMAIL_SEND_PASSWORD_UPDATE_SELF', true), FILTER_VALIDATE_BOOLEAN), + 'deleteSelf' => filter_var(env('PASSBOLT_EMAIL_SEND_PASSWORD_DELETE_SELF', false), FILTER_VALIDATE_BOOLEAN), 'share' => filter_var(env('PASSBOLT_EMAIL_SEND_PASSWORD_SHARE', true), FILTER_VALIDATE_BOOLEAN), 'update' => filter_var(env('PASSBOLT_EMAIL_SEND_PASSWORD_UPDATE', true), FILTER_VALIDATE_BOOLEAN), 'delete' => filter_var(env('PASSBOLT_EMAIL_SEND_PASSWORD_DELETE', true), FILTER_VALIDATE_BOOLEAN), @@ -166,6 +168,8 @@ ], 'folder' => [ 'create' => filter_var(env('PASSBOLT_EMAIL_SEND_FOLDER_CREATE', false), FILTER_VALIDATE_BOOLEAN), + 'updateSelf' => filter_var(env('PASSBOLT_EMAIL_SEND_FOLDER_UPDATE_SELF', true), FILTER_VALIDATE_BOOLEAN), + 'deleteSelf' => filter_var(env('PASSBOLT_EMAIL_SEND_FOLDER_DELETE_SELF', false), FILTER_VALIDATE_BOOLEAN), 'update' => filter_var(env('PASSBOLT_EMAIL_SEND_FOLDER_UPDATE', true), FILTER_VALIDATE_BOOLEAN), 'delete' => filter_var(env('PASSBOLT_EMAIL_SEND_FOLDER_DELETE', true), FILTER_VALIDATE_BOOLEAN), 'share' => filter_var(env('PASSBOLT_EMAIL_SEND_FOLDER_SHARE', true), FILTER_VALIDATE_BOOLEAN), diff --git a/plugins/PassboltCe/EmailNotificationSettings/tests/TestCase/Controllers/NotificationOrgSettingsGetControllerTest.php b/plugins/PassboltCe/EmailNotificationSettings/tests/TestCase/Controllers/NotificationOrgSettingsGetControllerTest.php index cc9fa5d953..0c5a2e3849 100644 --- a/plugins/PassboltCe/EmailNotificationSettings/tests/TestCase/Controllers/NotificationOrgSettingsGetControllerTest.php +++ b/plugins/PassboltCe/EmailNotificationSettings/tests/TestCase/Controllers/NotificationOrgSettingsGetControllerTest.php @@ -98,6 +98,8 @@ public function testNotificationOrgSettingsGetControllerSuccessDBOverride() $cases = [ 'send_comment_add' => false, 'send_password_create' => true, + 'send_password_updateSelf' => false, + 'send_password_deleteSelf' => true, 'send_password_share' => false, ]; @@ -125,6 +127,8 @@ public function testNotificationOrgSettingsGetControllerSuccessFileOverride() $cases = [ 'send_comment_add' => false, 'send_password_create' => true, + 'send_password_updateSelf' => false, + 'send_password_deleteSelf' => true, 'send_password_share' => false, ]; @@ -154,6 +158,8 @@ public function testNotificationOrgSettingsGetControllerSuccessBothOverride() $cases = [ 'send_comment_add' => false, 'send_password_create' => true, + 'send_password_updateSelf' => false, + 'send_password_deleteSelf' => true, 'send_password_share' => false, ]; diff --git a/plugins/PassboltCe/EmailNotificationSettings/tests/TestCase/Controllers/NotificationOrgSettingsPostControllerTest.php b/plugins/PassboltCe/EmailNotificationSettings/tests/TestCase/Controllers/NotificationOrgSettingsPostControllerTest.php index 86267089d6..42dc6c0a9f 100644 --- a/plugins/PassboltCe/EmailNotificationSettings/tests/TestCase/Controllers/NotificationOrgSettingsPostControllerTest.php +++ b/plugins/PassboltCe/EmailNotificationSettings/tests/TestCase/Controllers/NotificationOrgSettingsPostControllerTest.php @@ -119,6 +119,8 @@ public function testNotificationOrgSettingsPostControllerSuccess() 'show_username' => false, 'send_comment_add' => false, 'send_password_create' => false, + 'send_password_updateSelf' => false, + 'send_password_deleteSelf' => false, 'send_password_share' => false, 'send_password_update' => false, 'send_password_delete' => false, diff --git a/plugins/PassboltCe/Folders/src/Notification/Email/DeleteFolderEmailRedactor.php b/plugins/PassboltCe/Folders/src/Notification/Email/DeleteFolderEmailRedactor.php index c507a23492..3f3f6e1ab0 100644 --- a/plugins/PassboltCe/Folders/src/Notification/Email/DeleteFolderEmailRedactor.php +++ b/plugins/PassboltCe/Folders/src/Notification/Email/DeleteFolderEmailRedactor.php @@ -27,6 +27,7 @@ use Cake\ORM\Query\SelectQuery; use Cake\ORM\TableRegistry; use InvalidArgumentException; +use Passbolt\EmailNotificationSettings\Utility\EmailNotificationSettings; use Passbolt\Folders\Model\Entity\Folder; use Passbolt\Folders\Service\Folders\FoldersDeleteService; use Passbolt\Locale\Service\LocaleService; @@ -96,9 +97,14 @@ public function onSubscribedEvent(Event $event): EmailCollection } $operator = $this->usersTable->findFirstForEmail($uac->getId()); + $sendDeleteSelfEmail = EmailNotificationSettings::get('send.folder.deleteSelf'); /** @var array<\App\Model\Entity\User> $recipients */ $recipients = $this->findUsersUsernameToSendEmailTo($users); foreach ($recipients as $recipient) { + if ($recipient->id === $operator->id && !$sendDeleteSelfEmail) { + continue; + } + $email = $this->createEmail($recipient, $operator, $folder); $emailCollection->addEmail($email); } diff --git a/plugins/PassboltCe/Folders/src/Notification/Email/UpdateFolderEmailRedactor.php b/plugins/PassboltCe/Folders/src/Notification/Email/UpdateFolderEmailRedactor.php index 4c9bb95126..e3110b0733 100644 --- a/plugins/PassboltCe/Folders/src/Notification/Email/UpdateFolderEmailRedactor.php +++ b/plugins/PassboltCe/Folders/src/Notification/Email/UpdateFolderEmailRedactor.php @@ -28,6 +28,7 @@ use Cake\ORM\Query\SelectQuery; use Cake\ORM\TableRegistry; use InvalidArgumentException; +use Passbolt\EmailNotificationSettings\Utility\EmailNotificationSettings; use Passbolt\Folders\Model\Entity\Folder; use Passbolt\Folders\Service\Folders\FoldersUpdateService; use Passbolt\Locale\Service\LocaleService; @@ -105,9 +106,14 @@ public function onSubscribedEvent(Event $event): EmailCollection } $operator = $this->usersTable->findFirstForEmail($uac->getId()); + $sendUpdateSelfEmail = EmailNotificationSettings::get('send.folder.updateSelf'); /** @var array<\App\Model\Entity\User> $recipients */ $recipients = $this->findUsersUsernameToSendEmailTo($folder); foreach ($recipients as $recipient) { + if ($recipient->id === $operator->id && !$sendUpdateSelfEmail) { + continue; + } + $email = $this->createEmail($recipient, $operator, $folder, $isV5); $emailCollection->addEmail($email); } diff --git a/plugins/PassboltCe/Folders/src/Notification/NotificationSettings/FolderNotificationSettingsDefinition.php b/plugins/PassboltCe/Folders/src/Notification/NotificationSettings/FolderNotificationSettingsDefinition.php index 4c87f60a15..4c1f75d137 100644 --- a/plugins/PassboltCe/Folders/src/Notification/NotificationSettings/FolderNotificationSettingsDefinition.php +++ b/plugins/PassboltCe/Folders/src/Notification/NotificationSettings/FolderNotificationSettingsDefinition.php @@ -33,6 +33,8 @@ public function buildSchema(Schema $schema): Schema { return $schema ->addField('send_folder_create', ['type' => 'boolean', 'default' => false]) + ->addField('send_folder_updateSelf', ['type' => 'boolean', 'default' => true]) + ->addField('send_folder_deleteSelf', ['type' => 'boolean', 'default' => false]) ->addField('send_folder_delete', ['type' => 'boolean', 'default' => true]) ->addField('send_folder_update', ['type' => 'boolean', 'default' => true]) ->addField('send_folder_share', ['type' => 'boolean', 'default' => true]); @@ -46,6 +48,8 @@ public function buildValidator(Validator $validator): Validator { return $validator ->boolean('send_folder_create', __('An email notification setting should be a boolean.')) + ->boolean('send_folder_updateSelf', __('An email notification setting should be a boolean.')) + ->boolean('send_folder_deleteSelf', __('An email notification setting should be a boolean.')) ->boolean('send_folder_delete', __('An email notification setting should be a boolean.')) ->boolean('send_folder_update', __('An email notification setting should be a boolean.')) ->boolean('send_folder_share', __('An email notification setting should be a boolean.')); diff --git a/plugins/PassboltCe/Folders/tests/TestCase/Notification/NotificationSettings/FolderNotificationSettingsDefinitionTest.php b/plugins/PassboltCe/Folders/tests/TestCase/Notification/NotificationSettings/FolderNotificationSettingsDefinitionTest.php index aa5d9cf737..9642887d13 100644 --- a/plugins/PassboltCe/Folders/tests/TestCase/Notification/NotificationSettings/FolderNotificationSettingsDefinitionTest.php +++ b/plugins/PassboltCe/Folders/tests/TestCase/Notification/NotificationSettings/FolderNotificationSettingsDefinitionTest.php @@ -27,6 +27,8 @@ class FolderNotificationSettingsDefinitionTest extends TestCase public const EXPECTED_FIELDS = [ 'send_folder_delete', 'send_folder_create', + 'send_folder_updateSelf', + 'send_folder_deleteSelf', 'send_folder_update', 'send_folder_share', ]; diff --git a/plugins/PassboltCe/Folders/tests/TestCase/Service/Folders/FoldersDeleteServiceTest.php b/plugins/PassboltCe/Folders/tests/TestCase/Service/Folders/FoldersDeleteServiceTest.php index 7e71a0f79e..39089fac21 100644 --- a/plugins/PassboltCe/Folders/tests/TestCase/Service/Folders/FoldersDeleteServiceTest.php +++ b/plugins/PassboltCe/Folders/tests/TestCase/Service/Folders/FoldersDeleteServiceTest.php @@ -25,6 +25,7 @@ use App\Utility\UuidFactory; use Cake\Http\Exception\ForbiddenException; use Cake\Http\Exception\NotFoundException; +use Passbolt\EmailDigest\Test\Factory\EmailQueueFactory; use Passbolt\EmailNotificationSettings\Test\Lib\EmailNotificationSettingsTestTrait; use Passbolt\Folders\Model\Entity\FoldersRelation; use Passbolt\Folders\Service\Folders\FoldersDeleteService; @@ -107,6 +108,27 @@ public function testFolderDelete_CommonSuccess2_NotifyUsersAfterDelete() $this->service->delete($this->makeUac($userA), $folderA->id); + $this->assertEmailQueueCount(1); + $this->assertSame(0, EmailQueueFactory::find()->where(['email' => $userA->username])->all()->count()); + $this->assertEmailSubject($userB->username, "{$userA->profile->first_name} deleted the folder A"); + $this->assertEmailInBatchContains("{$userA->profile->first_name} deleted a folder", $userB->username); + } + + public function testFolderDelete_CommonSuccess2_NotifyOperatorAfterDeleteWhenEnabled() + { + // Ada is OWNER of folder A + // Betty is OWNER of folder A + // The folder delete self notification is enabled + // --- + // A (Ada:O, Betty:O) + [$userA, $userB] = UserFactory::make(2)->persist(); + /** @var \Passbolt\Folders\Model\Entity\Folder $folderA */ + $folderA = FolderFactory::make(['name' => 'A'])->withPermissionsFor([$userA, $userB])->persist(); + + $this->setEmailNotificationSetting('send.folder.deleteSelf', true); + + $this->service->delete($this->makeUac($userA), $folderA->id); + $this->assertEmailQueueCount(2); $this->assertEmailSubject($userA->username, 'You deleted the folder A'); $this->assertEmailInBatchContains('You deleted a folder', $userA->username); @@ -583,9 +605,9 @@ public function testFolderDelete_CommonSuccess3_NotifyGroupMembersAfterDelete() $this->service->delete($this->makeUac($userA), $folderA->id); - // All users with access (direct and via group) should be notified - $this->assertEmailQueueCount(3); - $this->assertEmailSubject($userA->username, 'You deleted the folder A'); + // All users with access (direct and via group), except the operator, should be notified. + $this->assertEmailQueueCount(2); + $this->assertSame(0, EmailQueueFactory::find()->where(['email' => $userA->username])->all()->count()); $this->assertEmailSubject($userB->username, "{$userA->profile->first_name} deleted the folder A"); $this->assertEmailSubject($userC->username, "{$userA->profile->first_name} deleted the folder A"); } @@ -743,7 +765,7 @@ public function testFolderDelete_SharedSuccess8_NoCascadeMoveResourcesToRootForA $this->assertFolderRelation($resource1->id, FoldersRelation::FOREIGN_MODEL_RESOURCE, $userB->id, null); } - public function testFolderDelete_CommonSuccess4_NotifyOnlyOperatorForPersonalFolder() + public function testFolderDelete_CommonSuccess4_DoesNotNotifyOperatorForPersonalFolder() { // Ada is OWNER of personal folder A (no other users) // --- @@ -755,8 +777,27 @@ public function testFolderDelete_CommonSuccess4_NotifyOnlyOperatorForPersonalFol $this->service->delete($this->makeUac($userA), $folderA->id); + $this->assertEmailQueueCount(0); + } + + public function testFolderDelete_CommonSuccess4_NotifyOperatorForPersonalFolderWhenEnabled() + { + // Ada is OWNER of personal folder A (no other users) + // The folder delete self notification is enabled + // --- + // A (Ada:O) + /** @var \App\Model\Entity\User $userA */ + $userA = UserFactory::make()->persist(); + /** @var \Passbolt\Folders\Model\Entity\Folder $folderA */ + $folderA = FolderFactory::make(['name' => 'A'])->withPermissionsFor([$userA])->persist(); + + $this->setEmailNotificationSetting('send.folder.deleteSelf', true); + + $this->service->delete($this->makeUac($userA), $folderA->id); + $this->assertEmailQueueCount(1); $this->assertEmailSubject($userA->username, 'You deleted the folder A'); + $this->assertEmailInBatchContains('You deleted a folder', $userA->username); } public function testFolderDelete_CommonSuccess5_NotificationRespectsEmailSettings() diff --git a/plugins/PassboltCe/Folders/tests/TestCase/Service/Folders/FoldersUpdateServiceTest.php b/plugins/PassboltCe/Folders/tests/TestCase/Service/Folders/FoldersUpdateServiceTest.php index 85f012f733..db603713ea 100644 --- a/plugins/PassboltCe/Folders/tests/TestCase/Service/Folders/FoldersUpdateServiceTest.php +++ b/plugins/PassboltCe/Folders/tests/TestCase/Service/Folders/FoldersUpdateServiceTest.php @@ -28,6 +28,7 @@ use Cake\Http\Exception\ForbiddenException; use Cake\Http\Exception\NotFoundException; use Cake\ORM\TableRegistry; +use Passbolt\EmailDigest\Test\Factory\EmailQueueFactory; use Passbolt\EmailNotificationSettings\Test\Lib\EmailNotificationSettingsTestTrait; use Passbolt\Folders\Service\Folders\FoldersUpdateService; use Passbolt\Folders\Test\Factory\FolderFactory; @@ -96,7 +97,7 @@ public function testUpdateFolderSuccess_UpdateFolderMeta() $this->assertEquals('new name', $folderBUpdated->get('name')); } - public function testUpdateFolderSuccess_NotifyUserAfterUpdate() + public function testUpdateFolderSuccess_NotifyUsersAfterUpdate() { // Ada is OWNER of folder A // Betty has READ on folder A @@ -119,6 +120,30 @@ public function testUpdateFolderSuccess_NotifyUserAfterUpdate() $this->assertEmailInBatchContains("{$userA->profile->first_name} edited a folder", $userB->username); } + public function testUpdateFolderSuccess_DoesNotNotifyOperatorWhenUpdateSelfDisabled() + { + $this->setEmailNotificationSetting('send.folder.updateSelf', false); + + // Ada is OWNER of folder A + // Betty has READ on folder A + // --- + // A (Ada:O, Betty:R) + [$userA, $userB] = UserFactory::make(2)->persist(); + $folderA = FolderFactory::make() + ->withPermissionsFor([$userA]) + ->withPermissionsFor([$userB], Permission::READ) + ->persist(); + + $name = 'new name'; + $dto = MetadataFolderDto::fromArray(['name' => $name]); + $this->service->update($this->makeUac($userA), $folderA->get('id'), $dto); + + $this->assertEmailQueueCount(1); + $this->assertSame(0, EmailQueueFactory::find()->where(['email' => $userA->username])->all()->count()); + $this->assertEmailSubject($userB->username, "{$userA->profile->first_name} edited the folder $name"); + $this->assertEmailInBatchContains("{$userA->profile->first_name} edited a folder", $userB->username); + } + public function testUpdateFolderError_ValidationError() { // Ada is OWNER of folder A diff --git a/plugins/PassboltCe/Metadata/templates/email/html/LU/resource_delete_v5.php b/plugins/PassboltCe/Metadata/templates/email/html/LU/resource_delete_v5.php index 3768e38fe1..f9d8584d7d 100644 --- a/plugins/PassboltCe/Metadata/templates/email/html/LU/resource_delete_v5.php +++ b/plugins/PassboltCe/Metadata/templates/email/html/LU/resource_delete_v5.php @@ -22,6 +22,7 @@ $subject = $body['subject']; $user = $body['user']; $resource = $body['resource']; +$isOperator = $body['isOperator']; echo $this->element('Email/module/avatar',[ 'url' => AvatarHelper::getAvatarUrl($user['profile']['avatar']), @@ -32,7 +33,9 @@ ]) ]); -$text = __('{0} deleted a password.', Purifier::clean($user['profile']['first_name'] . ' ' . $user['profile']['last_name'])) . '
'; +$text = $isOperator + ? __('You deleted a password.') . '
' + : __('{0} deleted a password.', Purifier::clean($user['profile']['first_name'] . ' ' . $user['profile']['last_name'])) . '
'; echo $this->element('Email/module/text', ['text' => $text]); diff --git a/plugins/PassboltCe/Metadata/tests/TestCase/Controller/Resources/ResourcesUpdateControllerTest.php b/plugins/PassboltCe/Metadata/tests/TestCase/Controller/Resources/ResourcesUpdateControllerTest.php index 27d34f9974..62d6aed7d4 100644 --- a/plugins/PassboltCe/Metadata/tests/TestCase/Controller/Resources/ResourcesUpdateControllerTest.php +++ b/plugins/PassboltCe/Metadata/tests/TestCase/Controller/Resources/ResourcesUpdateControllerTest.php @@ -50,6 +50,7 @@ public function setUp(): void { parent::setUp(); $this->setEmailNotificationsSetting('password.create', true); + Configure::write('passbolt.email.send.password.updateSelf', false); $this->enableFeaturePlugin(ResourceTypesPlugin::class); RoleFactory::make()->guest()->persist(); // enable event tracking @@ -122,8 +123,8 @@ public function testResourcesUpdateController_Success_SharedKey(string $resource 'isV5', true ); - $this->assertEmailQueueCount(2); - $this->assertEmailIsInQueue(['email' => $user->username, 'subject' => 'You edited a resource']); + $this->assertEmailQueueCount(1); + $this->assertEmailWithRecipientIsInNotQueue($user->username); $this->assertEmailIsInQueue([ 'email' => $userWithPermission->username, 'subject' => $user->profile->first_name . ' edited a resource', diff --git a/plugins/PassboltCe/PasswordExpiry/tests/TestCase/Controller/Resources/PasswordExpiryResourcesUpdateControllerTest.php b/plugins/PassboltCe/PasswordExpiry/tests/TestCase/Controller/Resources/PasswordExpiryResourcesUpdateControllerTest.php index b4b26b207f..e255170ed7 100644 --- a/plugins/PassboltCe/PasswordExpiry/tests/TestCase/Controller/Resources/PasswordExpiryResourcesUpdateControllerTest.php +++ b/plugins/PassboltCe/PasswordExpiry/tests/TestCase/Controller/Resources/PasswordExpiryResourcesUpdateControllerTest.php @@ -21,6 +21,7 @@ use App\Test\Factory\UserFactory; use App\Test\Lib\AppIntegrationTestCase; use App\Test\Lib\Model\EmailQueueTrait; +use Cake\Core\Configure; use Cake\I18n\Date; use Cake\I18n\DateTime; use Passbolt\Folders\Test\Factory\ResourceFactory; @@ -37,6 +38,7 @@ public function setUp(): void parent::setUp(); $this->enableFeaturePlugin(PasswordExpiryPlugin::class); PasswordExpirySettingFactory::make()->persist(); + Configure::write('passbolt.email.send.password.updateSelf', false); } public function testPasswordExpiryResourcesUpdateController_Update_Expiry_Date_In_Future(): void @@ -59,7 +61,7 @@ public function testPasswordExpiryResourcesUpdateController_Update_Expiry_Date_I $resourceUpdated = ResourceFactory::get($resourceToUpdate->id); $this->assertFalse($resourceUpdated->isExpired()); - $this->assertEmailQueueCount(1); + $this->assertEmailQueueIsEmpty(); } public static function isResourceAlreadyExpired(): array @@ -105,7 +107,7 @@ public function testPasswordExpiryResourcesUpdateController_Update_Expiry_Date_I $this->assertTrue($resourceUpdated->isExpired()); // If the resource is already expired, do not notify the owner who is not performing // the action, that they have expired emails - $expectedEmails = $isResourceAlreadyExpired ? 3 : 4; + $expectedEmails = $isResourceAlreadyExpired ? 2 : 3; $this->assertEmailQueueCount($expectedEmails); $emailDataToOwner = [ 'email' => $ownerWithAccess->username, diff --git a/resources/locales/cs_CZ/default.po b/resources/locales/cs_CZ/default.po index 5bcc1b9361..a841605f0e 100644 --- a/resources/locales/cs_CZ/default.po +++ b/resources/locales/cs_CZ/default.po @@ -1273,6 +1273,9 @@ msgstr "Nastavení send on password shared by mělo být platný boolean." msgid "The send on password updated setting should be a boolean." msgstr "Nastavení send on password updated by mělo být platný boolean." +msgid "The send on password update creator setting should be a boolean." +msgstr "Nastavení odesílání tvůrci při aktualizaci hesla musí být boolean." + msgid "The send on password deleted setting should be a boolean." msgstr "Nastavení send on password deleted by mělo být platný boolean." diff --git a/resources/locales/de_DE/default.po b/resources/locales/de_DE/default.po index 667670f698..bde6ab54c0 100644 --- a/resources/locales/de_DE/default.po +++ b/resources/locales/de_DE/default.po @@ -1273,6 +1273,9 @@ msgstr "Die Einstellung \"Senden wenn ein Passwort geteilt wird\" sollte ein Boo msgid "The send on password updated setting should be a boolean." msgstr "Die Einstellung \"Senden beim Aktualisieren eines Passworts\" sollte ein Boolean sein." +msgid "The send on password update creator setting should be a boolean." +msgstr "Die Einstellung zum Benachrichtigen des Erstellers bei einer Passwortaktualisierung sollte ein Boolean sein." + msgid "The send on password deleted setting should be a boolean." msgstr "Die Einstellung \"Senden, wenn ein Passwort gelöscht wird\" sollte ein Boolean sein." diff --git a/resources/locales/en_UK/default.po b/resources/locales/en_UK/default.po index 58035704cb..391826ba69 100644 --- a/resources/locales/en_UK/default.po +++ b/resources/locales/en_UK/default.po @@ -1271,6 +1271,9 @@ msgstr "" msgid "The send on password updated setting should be a boolean." msgstr "" +msgid "The send on password update creator setting should be a boolean." +msgstr "" + msgid "The send on password deleted setting should be a boolean." msgstr "" diff --git a/resources/locales/es_ES/default.po b/resources/locales/es_ES/default.po index 520918f67b..d03ce4c4db 100644 --- a/resources/locales/es_ES/default.po +++ b/resources/locales/es_ES/default.po @@ -1273,6 +1273,9 @@ msgstr "La configuración \"enviar al compartir una contraseña\" debe ser un va msgid "The send on password updated setting should be a boolean." msgstr "La configuración \"enviar al actualizar la contraseña\" debe ser un valor booleano." +msgid "The send on password update creator setting should be a boolean." +msgstr "La configuración para notificar al creador cuando se actualiza una contraseña debe ser un valor booleano." + msgid "The send on password deleted setting should be a boolean." msgstr "La configuración \"enviar al borrar una contraseña\" debe ser un valor booleano." diff --git a/resources/locales/fr_FR/default.po b/resources/locales/fr_FR/default.po index e3b69b48cc..ea70fc0210 100644 --- a/resources/locales/fr_FR/default.po +++ b/resources/locales/fr_FR/default.po @@ -1273,6 +1273,9 @@ msgstr "Le réglage de l'envoi lorsqu'un mot de passe est partagé doit être un msgid "The send on password updated setting should be a boolean." msgstr "Le réglage de l'envoi lorsqu'un mot de passe est partagé doit être un booléen." +msgid "The send on password update creator setting should be a boolean." +msgstr "Le réglage de l’envoi au créateur lorsqu’un mot de passe est mis à jour doit être un booléen." + msgid "The send on password deleted setting should be a boolean." msgstr "Le réglage de l'envoi lorsqu'un mot de passe est supprimé doit être un booléen." diff --git a/resources/locales/it_IT/default.po b/resources/locales/it_IT/default.po index 24af9eade2..afa5189687 100644 --- a/resources/locales/it_IT/default.po +++ b/resources/locales/it_IT/default.po @@ -1273,6 +1273,9 @@ msgstr "L'impostazione \"invia alla condivisione di una password\" deve essere u msgid "The send on password updated setting should be a boolean." msgstr "L'impostazione \"invia all'aggiornamento di una password\" deve essere un valore booleano." +msgid "The send on password update creator setting should be a boolean." +msgstr "L’impostazione per avvisare il creatore quando una password viene aggiornata deve essere un valore booleano." + msgid "The send on password deleted setting should be a boolean." msgstr "L'impostazione \"invia alla cancellazione di una password\" deve essere un valore booleano." diff --git a/resources/locales/ja_JP/default.po b/resources/locales/ja_JP/default.po index 54afed9595..d384cea04d 100644 --- a/resources/locales/ja_JP/default.po +++ b/resources/locales/ja_JP/default.po @@ -1273,6 +1273,9 @@ msgstr "パスワード共有時に送信する設定はブール値でなけれ msgid "The send on password updated setting should be a boolean." msgstr "パスワード更新時に送信する設定はブール値でなければなりません。" +msgid "The send on password update creator setting should be a boolean." +msgstr "パスワードが更新されたときに作成者へ送信する設定はブール値でなければなりません。" + msgid "The send on password deleted setting should be a boolean." msgstr "パスワード削除時に送信する設定はブール値でなければなりません。" diff --git a/resources/locales/ko_KR/default.po b/resources/locales/ko_KR/default.po index e5e71ca19a..22c3b65c94 100644 --- a/resources/locales/ko_KR/default.po +++ b/resources/locales/ko_KR/default.po @@ -1273,6 +1273,9 @@ msgstr "암호 공유 시 보내기 설정은 참 또는 거짓이어야 합니 msgid "The send on password updated setting should be a boolean." msgstr "암호 수정 시 보내기 설정은 참 또는 거짓이어야 합니다." +msgid "The send on password update creator setting should be a boolean." +msgstr "비밀번호가 업데이트될 때 만든 사람에게 알리는 설정은 참 또는 거짓이어야 합니다." + msgid "The send on password deleted setting should be a boolean." msgstr "암호 삭제 시 보내기 설정은 참 또는 거짓이어야 합니다." diff --git a/resources/locales/lt_LT/default.po b/resources/locales/lt_LT/default.po index 521d0d01ae..5bfc0a086c 100644 --- a/resources/locales/lt_LT/default.po +++ b/resources/locales/lt_LT/default.po @@ -1273,6 +1273,9 @@ msgstr "Nustatymas „Siųsti bendrinamą slaptažodį“ turėtų būti loginis msgid "The send on password updated setting should be a boolean." msgstr "Nustatymas „Siųsti atnaujinus slaptažodį“ turėtų būti loginis." +msgid "The send on password update creator setting should be a boolean." +msgstr "Nustatymas pranešti kūrėjui, kai slaptažodis atnaujinamas, turi būti loginis." + msgid "The send on password deleted setting should be a boolean." msgstr "Nustatymas „Siųsti ištrynus slaptažodį“ turėtų būti loginis." diff --git a/resources/locales/nl_NL/default.po b/resources/locales/nl_NL/default.po index ac92132208..1a8690e847 100644 --- a/resources/locales/nl_NL/default.po +++ b/resources/locales/nl_NL/default.po @@ -1273,6 +1273,9 @@ msgstr "De instelling voor \"verzenden zodra een wachtwoord is gedeeld\" moet ee msgid "The send on password updated setting should be a boolean." msgstr "De instelling voor \"verzenden zodra een wachtwoord is bijgewerkt\" moet een Boolean zijn." +msgid "The send on password update creator setting should be a boolean." +msgstr "De instelling voor het informeren van de maker wanneer een wachtwoord wordt bijgewerkt moet een Boolean zijn." + msgid "The send on password deleted setting should be a boolean." msgstr "De instelling voor \"verzenden zodra een wachtwoord is verwijderd\" moet een Boolean zijn." diff --git a/resources/locales/pl_PL/default.po b/resources/locales/pl_PL/default.po index 4f94f93792..4399e7d508 100644 --- a/resources/locales/pl_PL/default.po +++ b/resources/locales/pl_PL/default.po @@ -1273,6 +1273,9 @@ msgstr "Ustawienie wysyłki po udostępnieniu hasła powinno być wartością lo msgid "The send on password updated setting should be a boolean." msgstr "Ustawienie wysyłki po zaktualizowaniu hasła powinno być wartością logiczną." +msgid "The send on password update creator setting should be a boolean." +msgstr "Ustawienie powiadamiania twórcy po zaktualizowaniu hasła powinno być wartością logiczną." + msgid "The send on password deleted setting should be a boolean." msgstr "Ustawienie wysyłki po usunięciu hasła powinno być wartością logiczną." diff --git a/resources/locales/pt_BR/default.po b/resources/locales/pt_BR/default.po index 0fb47c2954..68f358c65f 100644 --- a/resources/locales/pt_BR/default.po +++ b/resources/locales/pt_BR/default.po @@ -1273,6 +1273,9 @@ msgstr "A configuração enviar ao compartilhamento de senha deve ser um boolean msgid "The send on password updated setting should be a boolean." msgstr "A configuração de atualização de senha deve ser booleana." +msgid "The send on password update creator setting should be a boolean." +msgstr "A configuração para notificar o criador quando uma senha é atualizada deve ser booleana." + msgid "The send on password deleted setting should be a boolean." msgstr "A configuração enviar ao excluir a senha deve ser um booleano." diff --git a/resources/locales/ro_RO/default.po b/resources/locales/ro_RO/default.po index a3e1766b1f..25b1ff42b9 100644 --- a/resources/locales/ro_RO/default.po +++ b/resources/locales/ro_RO/default.po @@ -1273,6 +1273,9 @@ msgstr "Setarea pentru trimite la parolă partajată ar trebui să fie booleană msgid "The send on password updated setting should be a boolean." msgstr "Setarea pentru trimite la parolă modificată ar trebui să fie booleană." +msgid "The send on password update creator setting should be a boolean." +msgstr "Setarea pentru notificarea creatorului când o parolă este actualizată ar trebui să fie booleană." + msgid "The send on password deleted setting should be a boolean." msgstr "Setarea pentru trimite la parolă ștearsă ar trebui să fie booleană." diff --git a/resources/locales/ru_RU/default.po b/resources/locales/ru_RU/default.po index 8bfae60bea..9e0f98cd24 100644 --- a/resources/locales/ru_RU/default.po +++ b/resources/locales/ru_RU/default.po @@ -1273,6 +1273,9 @@ msgstr "Общий параметр отправки пароля должен msgid "The send on password updated setting should be a boolean." msgstr "Параметр отправки обновленного пароля должен быть логическим." +msgid "The send on password update creator setting should be a boolean." +msgstr "Параметр уведомления создателя при обновлении пароля должен быть логическим." + msgid "The send on password deleted setting should be a boolean." msgstr "Параметр отправки удаленного пароля должен быть логическим." diff --git a/resources/locales/sl_SI/default.po b/resources/locales/sl_SI/default.po index 359c13a1ba..e4c01ba2f9 100644 --- a/resources/locales/sl_SI/default.po +++ b/resources/locales/sl_SI/default.po @@ -1273,6 +1273,9 @@ msgstr "Nastavitev za pošiljanje ob deljenem geslu mora biti logična vrednost. msgid "The send on password updated setting should be a boolean." msgstr "Nastavitev za pošiljanje ob posodobljenem geslu mora biti logična vrednost." +msgid "The send on password update creator setting should be a boolean." +msgstr "Nastavitev za obveščanje ustvarjalca ob posodobitvi gesla mora biti logična vrednost." + msgid "The send on password deleted setting should be a boolean." msgstr "Nastavitev za pošiljanje ob izbrisu gesla mora biti logična vrednost." diff --git a/resources/locales/sv_SE/default.po b/resources/locales/sv_SE/default.po index 90c4b85833..d2c081b67e 100644 --- a/resources/locales/sv_SE/default.po +++ b/resources/locales/sv_SE/default.po @@ -1273,6 +1273,9 @@ msgstr "Inställningen skicka när lösenord delas bör vara en boolean." msgid "The send on password updated setting should be a boolean." msgstr "Inställningen skicka när lösenord uppdaterats bör vara en boolean." +msgid "The send on password update creator setting should be a boolean." +msgstr "Inställningen för att meddela skaparen när ett lösenord uppdateras ska vara en boolean." + msgid "The send on password deleted setting should be a boolean." msgstr "Inställningen skicka när lösenord raderats bör vara en boolean." diff --git a/resources/locales/uk_UA/default.po b/resources/locales/uk_UA/default.po index aac87b8288..e20901e41e 100644 --- a/resources/locales/uk_UA/default.po +++ b/resources/locales/uk_UA/default.po @@ -1273,6 +1273,9 @@ msgstr "Налаштування надсилання після поширен msgid "The send on password updated setting should be a boolean." msgstr "Налаштування надсилання після оновленням пароля має бути логічним значенням." +msgid "The send on password update creator setting should be a boolean." +msgstr "Налаштування надсилання творцю після оновлення пароля має бути логічним значенням." + msgid "The send on password deleted setting should be a boolean." msgstr "Налаштування надсилання після видалення пароля має бути логічним значенням." diff --git a/src/Controller/Resources/ResourcesDeleteController.php b/src/Controller/Resources/ResourcesDeleteController.php index 399d7fb112..704e724ce1 100644 --- a/src/Controller/Resources/ResourcesDeleteController.php +++ b/src/Controller/Resources/ResourcesDeleteController.php @@ -95,12 +95,11 @@ public function delete(string $id): void // Get the list of users who have access to the resource // useful to do now to notify users later, since it wont be possible to after delete - // The logged in user will not be notified. + // The logged in user self-notification is controlled by send.password.deleteSelf. $options = ['contain' => ['role'], 'filter' => ['has-access' => [$resource->id]]]; $users = $this->Users ->findIndex(Role::USER, $options) ->find('locale') - ->where(['Users.id !=' => $this->User->id()]) ->all(); // Update the entity to delete=1, clear uri/desc/username and drop associated permissions @@ -145,7 +144,7 @@ protected function _handleDeleteError(Resource $resource): void * Send email notification * * @param \App\Model\Entity\Resource $resource Resource - * @param \Cake\Datasource\ResultSetInterface $users Users who had access to the resource, deleter excluded + * @param \Cake\Datasource\ResultSetInterface $users Users who had access to the resource * @return void */ protected function _notifyUser(Resource $resource, ResultSetInterface $users): void diff --git a/src/Notification/Email/Redactor/Resource/ResourceDeleteEmailRedactor.php b/src/Notification/Email/Redactor/Resource/ResourceDeleteEmailRedactor.php index 1d32235dda..be34e5895e 100644 --- a/src/Notification/Email/Redactor/Resource/ResourceDeleteEmailRedactor.php +++ b/src/Notification/Email/Redactor/Resource/ResourceDeleteEmailRedactor.php @@ -27,6 +27,7 @@ use App\Notification\Email\SubscribedEmailRedactorTrait; use Cake\Event\Event; use Cake\ORM\TableRegistry; +use Passbolt\EmailNotificationSettings\Utility\EmailNotificationSettings; use Passbolt\Locale\Service\LocaleService; use Passbolt\Metadata\Model\Dto\MetadataResourceDto; @@ -89,18 +90,22 @@ public function onSubscribedEvent(Event $event): EmailCollection /** @var \Cake\ORM\ResultSet $users */ $users = $event->getData('users'); - // if there is nobody, give it up. The deleter has already been removed from $users. + // if there is nobody, give it up. if ($users->count() < 1) { return $emailCollection; } $owner = $this->usersTable->findFirstForEmail($deletedBy); + $sendDeleteSelfEmail = EmailNotificationSettings::get('send.password.deleteSelf'); /** @var \App\Model\Entity\User $user */ foreach ($users as $user) { if ($user->isDisabled()) { continue; } + if ($user->id === $owner->id && !$sendDeleteSelfEmail) { + continue; + } $emailCollection->addEmail($this->createDeleteEmail($user, $owner, $resource, $resourceDto->isV5())); } @@ -118,10 +123,15 @@ private function createDeleteEmail(User $recipient, User $owner, Resource $resou { $subject = (new LocaleService())->translateString( $recipient->locale, - function () use ($owner, $resource, $isV5) { - $sub = __('{0} deleted the password {1}', $owner->profile->first_name, $resource->name); + function () use ($recipient, $owner, $resource, $isV5) { + $isRecipientPerformingTheAction = $recipient->id === $owner->id; + $sub = $isRecipientPerformingTheAction + ? __('You deleted the password {0}', $resource->name) + : __('{0} deleted the password {1}', $owner->profile->first_name, $resource->name); if ($isV5) { - $sub = __('{0} deleted a password', $owner->profile->first_name); + $sub = $isRecipientPerformingTheAction + ? __('You deleted a password') + : __('{0} deleted a password', $owner->profile->first_name); } return $sub; @@ -131,6 +141,8 @@ function () use ($owner, $resource, $isV5) { $data = [ 'body' => [ 'user' => $owner, + 'recipient' => $recipient, + 'isOperator' => $recipient->id === $owner->id, 'subject' => $subject, 'resource' => $resource, 'showUsername' => $this->getConfig('show.username'), diff --git a/src/Notification/Email/Redactor/Resource/ResourceUpdateEmailRedactor.php b/src/Notification/Email/Redactor/Resource/ResourceUpdateEmailRedactor.php index 74ebb99971..059a6586ea 100644 --- a/src/Notification/Email/Redactor/Resource/ResourceUpdateEmailRedactor.php +++ b/src/Notification/Email/Redactor/Resource/ResourceUpdateEmailRedactor.php @@ -29,6 +29,7 @@ use Cake\Event\Event; use Cake\ORM\TableRegistry; use Cake\Utility\Hash; +use Passbolt\EmailNotificationSettings\Utility\EmailNotificationSettings; use Passbolt\Locale\Service\LocaleService; class ResourceUpdateEmailRedactor implements SubscribedEmailRedactorInterface @@ -105,9 +106,15 @@ public function onSubscribedEvent(Event $event): EmailCollection $secretsDataById = Hash::combine($secrets, '{n}.user_id', '{n}.data'); } - // Send emails to everybody that can see the resource + $sendUpdateSelfEmail = EmailNotificationSettings::get('send.password.updateSelf'); + + // Send emails to everybody that can see the resource. The updater is controlled separately. /** @var \App\Model\Entity\User $user */ foreach ($users as $user) { + if ($user->id === $owner->id && !$sendUpdateSelfEmail) { + continue; + } + $emailCollection->addEmail( $this->createUpdateEmail( $user, diff --git a/src/Notification/NotificationSettings/CoreNotificationSettingsDefinition.php b/src/Notification/NotificationSettings/CoreNotificationSettingsDefinition.php index 6c4b396f75..4b9bff8a3d 100644 --- a/src/Notification/NotificationSettings/CoreNotificationSettingsDefinition.php +++ b/src/Notification/NotificationSettings/CoreNotificationSettingsDefinition.php @@ -54,6 +54,8 @@ public function buildSchema(Schema $schema): Schema ->addField('send_group_manager_update', ['type' => 'boolean', 'default' => true]) ->addField('send_group_manager_requestAddUser', ['type' => 'boolean', 'default' => true]) ->addField('send_password_create', ['type' => 'boolean', 'default' => false]) + ->addField('send_password_updateSelf', ['type' => 'boolean', 'default' => true]) + ->addField('send_password_deleteSelf', ['type' => 'boolean', 'default' => false]) ->addField('send_password_share', ['type' => 'boolean', 'default' => true]) ->addField('send_password_update', ['type' => 'boolean', 'default' => true]) ->addField('send_password_delete', ['type' => 'boolean', 'default' => true]) @@ -100,6 +102,14 @@ public function buildValidator(Validator $validator): Validator ->boolean('send_password_create', __('The send on password created setting should be a boolean.')) ->boolean('send_password_share', __('The send on password shared setting should be a boolean.')) ->boolean('send_password_update', __('The send on password updated setting should be a boolean.')) + ->boolean( + 'send_password_updateSelf', + __('The send on password update creator setting should be a boolean.') + ) + ->boolean( + 'send_password_deleteSelf', + __('The send on password self deleted setting should be a boolean.') + ) ->boolean('send_password_delete', __('The send on password deleted setting should be a boolean.')) ->boolean('send_user_create', __('The send on user created setting should be a boolean.')) ->boolean('send_user_recover', __('The send on user recovered setting should be a boolean.')); diff --git a/tests/TestCase/Controller/Notifications/ResourcesDeleteNotificationTest.php b/tests/TestCase/Controller/Notifications/ResourcesDeleteNotificationTest.php index c83d479065..d3a0707740 100644 --- a/tests/TestCase/Controller/Notifications/ResourcesDeleteNotificationTest.php +++ b/tests/TestCase/Controller/Notifications/ResourcesDeleteNotificationTest.php @@ -45,6 +45,7 @@ public function tearDown(): void public function testResourcesDeleteNotification_NotificationEnabled(): void { $this->setEmailNotificationSetting('send.password.delete', true); + $this->setEmailNotificationSetting('send.password.deleteSelf', false); RoleFactory::make()->guest()->persist(); [$user, $user2] = UserFactory::make(2)->user()->active()->persist(); @@ -62,6 +63,44 @@ public function testResourcesDeleteNotification_NotificationEnabled(): void $this->assertEmailWithRecipientIsInNotQueue($disabled->username); } + public function testResourcesDeleteNotification_SelfDeleteNotificationEnabled(): void + { + $this->setEmailNotificationSetting('send.password.delete', true); + $this->setEmailNotificationSetting('send.password.deleteSelf', true); + + RoleFactory::make()->guest()->persist(); + [$user, $user2] = UserFactory::make(2)->user()->active()->persist(); + ResourceTypeFactory::make()->default()->persist(); + $r = ResourceFactory::make(['name' => 'Secret A'])->withPermissionsFor([$user, $user2])->persist(); + + $this->logInAs($user); + $this->deleteJson('/resources/' . $r->id . '.json'); + $this->assertSuccess(); + + $this->assertEmailSubject($user->username, 'You deleted the password Secret A'); + $this->assertEmailInBatchContains('You deleted the password Secret A', $user->username); + $this->assertEmailInBatchContains('deleted the password', $user2->username); + } + + public function testResourcesDeleteNotification_PrivateResourceSelfDeleteNotificationEnabled(): void + { + $this->setEmailNotificationSetting('send.password.delete', true); + $this->setEmailNotificationSetting('send.password.deleteSelf', true); + + RoleFactory::make()->guest()->persist(); + $user = UserFactory::make()->user()->active()->persist(); + ResourceTypeFactory::make()->default()->persist(); + $r = ResourceFactory::make(['name' => 'Secret A'])->withPermissionsFor([$user])->persist(); + + $this->logInAs($user); + $this->deleteJson('/resources/' . $r->id . '.json'); + $this->assertSuccess(); + + $this->assertEmailQueueCount(1); + $this->assertEmailSubject($user->username, 'You deleted the password Secret A'); + $this->assertEmailInBatchContains('You deleted the password Secret A', $user->username); + } + public function testResourcesDeleteNotification_NotificationDisabled(): void { $this->setEmailNotificationSetting('send.password.delete', false); diff --git a/tests/TestCase/Controller/Notifications/ResourcesUpdateNotificationTest.php b/tests/TestCase/Controller/Notifications/ResourcesUpdateNotificationTest.php index 95f1847e09..c8bfdb49be 100644 --- a/tests/TestCase/Controller/Notifications/ResourcesUpdateNotificationTest.php +++ b/tests/TestCase/Controller/Notifications/ResourcesUpdateNotificationTest.php @@ -45,6 +45,7 @@ public function tearDown(): void public function testResourcesUpdateNotification_NotificationEnabled(): void { $this->setEmailNotificationSetting('send.password.update', true); + $this->setEmailNotificationSetting('send.password.updateSelf', true); RoleFactory::make()->guest()->persist(); [$user, $user2] = UserFactory::make(2)->user()->active()->persist(); @@ -64,10 +65,83 @@ public function testResourcesUpdateNotification_NotificationEnabled(): void // check email notification $this->assertEmailInBatchContains('edited the resource', $user2->username); - $this->assertEmailInBatchContains('edited the resource', $user->username); + $this->assertEmailInBatchContains('You edited the resource', $user->username); $this->assertEmailWithRecipientIsInNotQueue($disabled->username); } + public function testResourcesUpdateNotification_DisabledSelfUpdateSkipsModifier(): void + { + $this->setEmailNotificationSetting('send.password.update', true); + $this->setEmailNotificationSetting('send.password.updateSelf', false); + + RoleFactory::make()->guest()->persist(); + [$user, $user2] = UserFactory::make(2)->user()->active()->persist(); + ResourceTypeFactory::make()->default()->persist(); + $r = ResourceFactory::make()->withPermissionsFor([$user, $user2])->persist(); + + // Post updated data + $this->logInAs($user); + $this->putJson('/resources/' . $r->id . '.json', [ + 'name' => 'R1 name updated', + 'username' => 'R1 username updated', + 'uri' => 'https://r1-updated.com', + 'description' => 'R1 description updated', + ]); + $this->assertSuccess(); + + // check email notification + $this->assertEmailInBatchContains('edited the resource', $user2->username); + $this->assertEmailWithRecipientIsInNotQueue($user->username); + } + + public function testResourcesUpdateNotification_PrivateResourceNotifiesModifierByDefault(): void + { + $this->setEmailNotificationSetting('send.password.update', true); + $this->setEmailNotificationSetting('send.password.updateSelf', true); + + RoleFactory::make()->guest()->persist(); + $user = UserFactory::make()->user()->active()->persist(); + ResourceTypeFactory::make()->default()->persist(); + $r = ResourceFactory::make()->withPermissionsFor([$user])->persist(); + + // Post updated data + $this->logInAs($user); + $this->putJson('/resources/' . $r->id . '.json', [ + 'name' => 'R1 name updated', + 'username' => 'R1 username updated', + 'uri' => 'https://r1-updated.com', + 'description' => 'R1 description updated', + ]); + $this->assertSuccess(); + + // check email notification + $this->assertEmailInBatchContains('You edited the resource', $user->username); + } + + public function testResourcesUpdateNotification_PrivateResourceSkipsModifierWhenSelfUpdateDisabled(): void + { + $this->setEmailNotificationSetting('send.password.update', true); + $this->setEmailNotificationSetting('send.password.updateSelf', false); + + RoleFactory::make()->guest()->persist(); + $user = UserFactory::make()->user()->active()->persist(); + ResourceTypeFactory::make()->default()->persist(); + $r = ResourceFactory::make()->withPermissionsFor([$user])->persist(); + + // Post updated data + $this->logInAs($user); + $this->putJson('/resources/' . $r->id . '.json', [ + 'name' => 'R1 name updated', + 'username' => 'R1 username updated', + 'uri' => 'https://r1-updated.com', + 'description' => 'R1 description updated', + ]); + $this->assertSuccess(); + + // check email notification + $this->assertEmailQueueIsEmpty(); + } + public function testResourcesUpdateNotification_NotificationDisabled_Metadata(): void { $this->setEmailNotificationSetting('send.password.update', false); diff --git a/tests/TestCase/Controller/Notifications/ResourcesUpdateNotificationWithFactoriesTest.php b/tests/TestCase/Controller/Notifications/ResourcesUpdateNotificationWithFactoriesTest.php index 2d4759b54d..a2b2b10392 100644 --- a/tests/TestCase/Controller/Notifications/ResourcesUpdateNotificationWithFactoriesTest.php +++ b/tests/TestCase/Controller/Notifications/ResourcesUpdateNotificationWithFactoriesTest.php @@ -49,6 +49,7 @@ public function testResourcesUpdateNotificationSuccess_Secrets(): void { SecretRevisionsSettingsFactory::make()->setMaxRevisions(2)->persist(); $this->setEmailNotificationSetting('send.password.update', true); + $this->setEmailNotificationSetting('send.password.updateSelf', false); // Create users RoleFactory::make()->guest()->persist(); [$userA, $userB, $userC, $userD] = UserFactory::make(4)->withValidGpgKey()->persist(); @@ -83,7 +84,7 @@ public function testResourcesUpdateNotificationSuccess_Secrets(): void $this->assertSuccess(); // Assert email contents $this->assertEmailInBatchContains('edited the resource', $userA->username); - $this->assertEmailInBatchContains('edited the resource', $userB->username); + $this->assertEmailWithRecipientIsInNotQueue($userB->username); $this->assertEmailInBatchContains('edited the resource', $userC->username); $this->assertEmailInBatchContains('edited the resource', $userD->username); } diff --git a/tests/TestCase/Notification/Email/Redactor/Resource/ResourceUpdateEmailRedactorTest.php b/tests/TestCase/Notification/Email/Redactor/Resource/ResourceUpdateEmailRedactorTest.php index 3f39aff392..ee5700eabd 100644 --- a/tests/TestCase/Notification/Email/Redactor/Resource/ResourceUpdateEmailRedactorTest.php +++ b/tests/TestCase/Notification/Email/Redactor/Resource/ResourceUpdateEmailRedactorTest.php @@ -47,6 +47,8 @@ public function setUp(): void $this->sut = new ResourceUpdateEmailRedactor(); $this->loadPlugins(['Passbolt/Locale' => []]); RoleFactory::make()->guest()->persist(); + RoleFactory::make()->user()->persist(); + RoleFactory::make()->admin()->persist(); $this->loadNotificationSettings(); } @@ -84,10 +86,14 @@ public function testResourceUpdateEmailRedactor_V5_WithMultipleRecipients(): voi 'secrets' => $secrets, 'isV5' => true, ]); - $emailCollection = $this->sut->onSubscribedEvent($event); + $emails = $this->sut->onSubscribedEvent($event)->getEmails(); + $emailRecipients = array_map(function ($email) { + return $email->getData()['body']['recipient']->id; + }, $emails); - $this->assertCount(3, $emailCollection->getEmails()); - foreach ($emailCollection->getEmails() as $email) { + $this->assertCount(3, $emails); + $this->assertContains($owner->id, $emailRecipients); + foreach ($emails as $email) { $recipient = $email->getData()['body']['recipient']; if ($recipient->id === $owner->id) { $this->assertSame('You edited a resource', $email->getSubject()); @@ -98,4 +104,78 @@ public function testResourceUpdateEmailRedactor_V5_WithMultipleRecipients(): voi $this->assertSame(ResourceUpdateEmailRedactor::TEMPLATE_V5, $email->getTemplate()); } } + + public function testResourceUpdateEmailRedactor_UsesUpdateNotificationSetting(): void + { + $this->assertSame('send.password.update', $this->sut->getNotificationSettingPath()); + } + + public function testResourceUpdateEmailRedactor_DisabledSelfUpdateSkipsModifierButKeepsOtherRecipients(): void + { + $owner = UserFactory::make()->user()->active()->persist(); + $recipient = UserFactory::make()->user()->active()->persist(); + /** @var \App\Model\Entity\Resource $resource */ + $resource = ResourceFactory::make(['created_by' => $owner->id, 'modified_by' => $owner->id]) + ->withPermissionsFor([$owner], Permission::OWNER) + ->withPermissionsFor([$recipient], Permission::READ) + ->withSecretsFor([$owner, $recipient]) + ->persist(); + $this->setEmailNotificationSetting('send.password.updateSelf', false); + + $event = new Event(ResourcesUpdateService::UPDATE_SUCCESS_EVENT_NAME); + $event->setData([ + 'resource' => $resource, + 'accessControl' => $this->makeUac($owner), + 'secrets' => SecretFactory::find()->all()->toArray(), + 'isV5' => false, + ]); + $emails = $this->sut->onSubscribedEvent($event)->getEmails(); + + $this->assertCount(1, $emails); + $this->assertSame($recipient->id, $emails[0]->getData()['body']['recipient']->id); + } + + public function testResourceUpdateEmailRedactor_PrivateResourceNotifiesModifierByDefault(): void + { + $owner = UserFactory::make()->user()->active()->persist(); + /** @var \App\Model\Entity\Resource $resource */ + $resource = ResourceFactory::make(['created_by' => $owner->id, 'modified_by' => $owner->id]) + ->withPermissionsFor([$owner], Permission::OWNER) + ->withSecretsFor([$owner]) + ->persist(); + + $event = new Event(ResourcesUpdateService::UPDATE_SUCCESS_EVENT_NAME); + $event->setData([ + 'resource' => $resource, + 'accessControl' => $this->makeUac($owner), + 'secrets' => SecretFactory::find()->all()->toArray(), + 'isV5' => false, + ]); + $emails = $this->sut->onSubscribedEvent($event)->getEmails(); + + $this->assertCount(1, $emails); + $this->assertSame($owner->id, $emails[0]->getData()['body']['recipient']->id); + $this->assertSame('You edited the resource ' . $resource->name, $emails[0]->getSubject()); + } + + public function testResourceUpdateEmailRedactor_PrivateResourceSkipsModifierWhenSelfUpdateDisabled(): void + { + $owner = UserFactory::make()->user()->active()->persist(); + /** @var \App\Model\Entity\Resource $resource */ + $resource = ResourceFactory::make(['created_by' => $owner->id, 'modified_by' => $owner->id]) + ->withPermissionsFor([$owner], Permission::OWNER) + ->withSecretsFor([$owner]) + ->persist(); + $this->setEmailNotificationSetting('send.password.updateSelf', false); + + $event = new Event(ResourcesUpdateService::UPDATE_SUCCESS_EVENT_NAME); + $event->setData([ + 'resource' => $resource, + 'accessControl' => $this->makeUac($owner), + 'secrets' => SecretFactory::find()->all()->toArray(), + 'isV5' => false, + ]); + + $this->assertCount(0, $this->sut->onSubscribedEvent($event)->getEmails()); + } } diff --git a/tests/TestCase/Notification/NotificationSettings/Form/EmailNotificationSettingsFormTest.php b/tests/TestCase/Notification/NotificationSettings/Form/EmailNotificationSettingsFormTest.php index 43976b2a01..b2a99fb6c4 100644 --- a/tests/TestCase/Notification/NotificationSettings/Form/EmailNotificationSettingsFormTest.php +++ b/tests/TestCase/Notification/NotificationSettings/Form/EmailNotificationSettingsFormTest.php @@ -136,6 +136,34 @@ public function testNotificationSettingsFormFieldSendPasswordCreate() ); } + public function testNotificationSettingsFormFieldSendPasswordUpdateSelf() + { + $testCases = [ + 'boolean' => $this->getBooleanTestCases(), + ]; + + $this->assertFormFieldFormatValidation( + EmailNotificationSettingsForm::class, + 'send_password_updateSelf', + self::getDummyData(), + $testCases + ); + } + + public function testNotificationSettingsFormFieldSendPasswordDeleteSelf() + { + $testCases = [ + 'boolean' => $this->getBooleanTestCases(), + ]; + + $this->assertFormFieldFormatValidation( + EmailNotificationSettingsForm::class, + 'send_password_deleteSelf', + self::getDummyData(), + $testCases + ); + } + public function testNotificationSettingsFormFieldSendPasswordShare() { $testCases = [ @@ -348,6 +376,8 @@ public static function getDummyData(?array $data = []): array 'show_username' => true, 'send_comment_add' => true, 'send_password_create' => true, + 'send_password_updateSelf' => true, + 'send_password_deleteSelf' => true, 'send_password_share' => true, 'send_password_update' => true, 'send_password_delete' => true, diff --git a/tests/TestCase/Notification/NotificationSettings/Utility/EmailNotificationSettingsTest.php b/tests/TestCase/Notification/NotificationSettings/Utility/EmailNotificationSettingsTest.php index 9d85cb38bb..c03a276fd6 100644 --- a/tests/TestCase/Notification/NotificationSettings/Utility/EmailNotificationSettingsTest.php +++ b/tests/TestCase/Notification/NotificationSettings/Utility/EmailNotificationSettingsTest.php @@ -73,6 +73,8 @@ public function testNotificationSettingReturnsConfigSetting() 'show.username' => true, 'send.comment.add' => true, 'send.password.create' => true, + 'send.password.updateSelf' => true, + 'send.password.deleteSelf' => false, 'send.password.share' => true, 'send.password.update' => true, 'send.password.delete' => true, @@ -111,6 +113,8 @@ public function testNotificationSettingReturnsDBSetting() 'send.comment.add' => false, 'send.password.create' => true, 'send.password.share' => false, + 'send.password.updateSelf' => false, + 'send.password.deleteSelf' => true, ]; $uac = UserFactory::make()->admin()->persistedUAC(); diff --git a/tests/TestCase/Service/Healthcheck/Application/EmailNotificationEnabledApplicationHealthcheckTest.php b/tests/TestCase/Service/Healthcheck/Application/EmailNotificationEnabledApplicationHealthcheckTest.php index 5aa923bfbb..9daeaecc28 100644 --- a/tests/TestCase/Service/Healthcheck/Application/EmailNotificationEnabledApplicationHealthcheckTest.php +++ b/tests/TestCase/Service/Healthcheck/Application/EmailNotificationEnabledApplicationHealthcheckTest.php @@ -56,6 +56,7 @@ public function tearDown(): void public function testEmailNotificationEnabledApplicationHealthcheck_Success_File(): void { Configure::write('passbolt.email.send.password.create', true); + Configure::write('passbolt.email.send.password.deleteSelf', true); Configure::write('passbolt.email.send.comment.add', true); Configure::write('passbolt.email.send.user.create', true); Configure::write('passbolt.email.send.folder.create', true); @@ -69,6 +70,7 @@ public function testEmailNotificationEnabledApplicationHealthcheck_Success_Datab { $defaults = static::getDefaultEmailNotificationConfig(); $defaults['send']['password']['create'] = true; + $defaults['send']['password']['deleteSelf'] = true; EmailNotificationSettingFactory::make()->setField('value', json_encode($defaults))->persist(); $service = $this->healthcheck->check(); $this->assertTrue($service->isPassed()); diff --git a/tests/TestCase/Utility/OpenPGP/Backends/OpenPGPBackendTest.php b/tests/TestCase/Utility/OpenPGP/Backends/OpenPGPBackendTest.php index 9141cfefa6..0978c5d46a 100644 --- a/tests/TestCase/Utility/OpenPGP/Backends/OpenPGPBackendTest.php +++ b/tests/TestCase/Utility/OpenPGP/Backends/OpenPGPBackendTest.php @@ -359,7 +359,7 @@ public function testOpenPGPBackendSignSuccess(OpenPGPBackend $gnupg): void $gnupg->setVerifyKeyFromFingerprint($keyInfo['fingerprint']); $gnupg->verify($signedMessage, $messageUnsigned); - $this->assertEquals($messageToSign . "\n", $messageUnsigned); + $this->assertContains($messageUnsigned, [$messageToSign, $messageToSign . "\n"]); } /** diff --git a/webroot/js/app/api-app.js b/webroot/js/app/api-app.js index 3364176318..d82115340c 100644 --- a/webroot/js/app/api-app.js +++ b/webroot/js/app/api-app.js @@ -1,2 +1,2 @@ /*! For license information please see api-app.js.LICENSE.txt */ -(()=>{"use strict";var e,t,a,n={3652(e,t,a){var n=a(6540),s=a(5556),i=a.n(s),r=a(4296);function o(){return o=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},displayWarning:()=>{},displayError:()=>{},remove:()=>{}});class c extends n.Component{constructor(e){super(e),this.state=this.defaultState}get defaultState(){return{feedbacks:[],displaySuccess:this.displaySuccess.bind(this),displayWarning:this.displayWarning.bind(this),displayError:this.displayError.bind(this),remove:this.remove.bind(this)}}displaySuccess(e){this.setState({feedbacks:[...this.state.feedbacks,{id:(0,r.A)(),type:"success",message:e}]})}displayWarning(e){this.setState({feedbacks:[...this.state.feedbacks,{id:(0,r.A)(),type:"warning",message:e}]})}displayError(e){this.setState({feedbacks:[...this.state.feedbacks,{id:(0,r.A)(),type:"error",message:e}]})}remove(e){this.setState(t=>({feedbacks:t.feedbacks.filter(t=>e.id!==t.id)}))}render(){return n.createElement(l.Provider,{value:this.state},this.props.children)}}function m(e){return class extends n.Component{render(){return n.createElement(l.Consumer,null,t=>n.createElement(e,o({actionFeedbackContext:t},this.props)))}}}function d(){return d=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},close:()=>{}});class p extends n.Component{constructor(e){super(e),this.state=this.defaultState}get defaultState(){return{dialogs:[],open:(e,t)=>{const a=(0,r.A)();return this.setState(n=>({dialogs:[...n.dialogs,{key:a,Dialog:e,DialogProps:t}]})),a},close:e=>{this.setState(t=>({dialogs:t.dialogs.filter(t=>e!==t.key)}))},closeAll:()=>this.setState({dialogs:[]})}}render(){return n.createElement(u.Provider,{value:this.state},this.props.children)}}function h(e){return class extends n.Component{render(){return n.createElement(u.Consumer,null,t=>n.createElement(e,d({dialogContext:t},this.props)))}}}function g(){return g=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},hide:()=>{}});class b extends n.Component{constructor(e){super(e),this.state=this.defaultState}get defaultState(){return{contextualMenus:[],show:(e,t)=>this.setState({contextualMenus:[...this.state.contextualMenus,{ContextualMenuComponent:e,componentProps:t}]}),hide:e=>this.setState({contextualMenus:this.state.contextualMenus.filter((t,a)=>a!==e)})}}render(){return n.createElement(y.Provider,{value:this.state},this.props.children)}}b.displayName="ContextualMenuContextProvider",b.propTypes={children:i().any};var f=a(2389);class E extends n.Component{static get DEFAULT_WAIT_TO_CLOSE_TIME_IN_MS(){return 500}constructor(e){super(e),this.state=this.defaultState,this.bindCallbacks()}get defaultState(){return{shouldRender:!0,isPersisted:!1,timeoutId:null}}componentDidMount(){this.displayWithTimer(this.props.displayTimeInMs)}componentDidUpdate(e){const t=e&&e.feedback.id!==this.props.feedback.id,a=e&&this.props.displayTimeInMs&&e.displayTimeInMs!==this.props.displayTimeInMs;t?(this.setState({shouldRender:!0}),this.displayWithTimer(this.props.displayTimeInMs)):a&&this.updateTimer(this.props.displayTimeInMs)}componentWillUnmount(){this.state.timeoutId&&clearTimeout(this.state.timeoutId)}bindCallbacks(){this.persist=this.persist.bind(this),this.displayWithTimer=this.displayWithTimer.bind(this),this.close=this.close.bind(this)}displayWithTimer(e){this.state.timeoutId&&clearTimeout(this.state.timeoutId);const t=setTimeout(this.close,e),a=Date.now();this.setState({timeoutId:t,time:a})}updateTimer(e){const t=e-(Date.now()-this.state.time);t>0?this.displayWithTimer(t):(clearTimeout(this.state.timeoutId),this.close())}persist(){this.state.timeoutId&&!this.state.isPersisted&&(clearTimeout(this.state.timeoutId),this.setState({isPersisted:!0}))}close(){this.setState({shouldRender:!1}),setTimeout(this.props.onClose,E.DEFAULT_WAIT_TO_CLOSE_TIME_IN_MS)}render(){return n.createElement("div",{className:"notification",onMouseOver:this.persist,onMouseLeave:this.displayWithTimer,onClick:this.close},n.createElement("div",{className:`message animated ${this.state.shouldRender?"fadeInUp":"fadeOutUp"} ${this.props.feedback.type}`},n.createElement("span",{className:"content"},n.createElement("strong",null,"success"===this.props.feedback.type&&n.createElement(n.Fragment,null,n.createElement(f.x6,null,"Success"),":"," "),"error"===this.props.feedback.type&&n.createElement(n.Fragment,null,n.createElement(f.x6,null,"Error"),":"," "),"warning"===this.props.feedback.type&&n.createElement(n.Fragment,null,n.createElement(f.x6,null,"Warning"),":"," ")),this.props.feedback.message)))}}E.propTypes={feedback:i().object,onClose:i().func,displayTimeInMs:i().number};const v=(0,f.CI)("common")(E);class w extends n.Component{constructor(e){super(e),this.bindCallbacks()}static get DEFAULT_DISPLAY_TIME_IN_MS(){return 5e3}static get DEFAULT_DISPLAY_MIN_TIME_IN_MS(){return 1200}bindCallbacks(){this.close=this.close.bind(this)}get feedbackToDisplay(){return this.props.actionFeedbackContext.feedbacks[0]}get length(){return this.props.actionFeedbackContext.feedbacks.length}get hasFeedbacks(){return this.length>0}async close(e){await this.props.actionFeedbackContext.remove(e)}render(){const e=this.length>1?w.DEFAULT_DISPLAY_MIN_TIME_IN_MS:w.DEFAULT_DISPLAY_TIME_IN_MS;return n.createElement(n.Fragment,null,this.hasFeedbacks&&n.createElement("div",{className:"notification-container"},n.createElement(v,{feedback:this.feedbackToDisplay,onClose:()=>this.close(this.feedbackToDisplay),displayTimeInMs:e})))}}w.propTypes={actionFeedbackContext:i().any};const k=m(w);var _=a(4625),x=a(6347);function S(){return S=Object.assign?Object.assign.bind():function(e){for(var t=1;tn.createElement(e,S({context:t},this.props)))}}}const T=C;function A(){return A=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},remove:()=>{}});class R extends n.Component{constructor(e){super(e),this.state=this.defaultState}get defaultState(){return{counter:0,add:()=>{this.setState(e=>({counter:e.counter+1}))},remove:()=>{this.setState(e=>({counter:Math.min(e.counter-1,0)}))}}}render(){return n.createElement(I.Provider,{value:this.state},this.props.children)}}R.propTypes={children:i().any};class P{}class D extends P{static execute(){return!0}}class O extends P{static execute(){return!1}}const M="Folders.use",U="Users.viewWorkspace",F="Administration.viewWorkspace",j="GroupsAdd.addPost",L="AccountRecoveryRequestsView.view",q="AccountRecoveryRequestsIndex.index",z="AccountRecoveryResponsesCreate.post",K="Allow",V="Deny",G="AllowIfGroupManagerInOneGroup",B={[K]:D,[V]:O,[G]:class extends P{static execute(e){return e.groups_users.some(e=>e.is_admin)}}},W={[M]:B[K]},H={[F]:B[V],[j]:B[V],[L]:B[V],[q]:B[V],[z]:B[V]};class ${static getByRbac(e){return B[e.controlFunction]||(console.warn(`Could not find control function for the given rbac entity (${e.id})`),O)}static getDefaultForAdminAndAction(e){return W[e]||D}static getDefaultForUserAndAction(e){return H[e]||D}}class Y extends Error{constructor(e="Collection validation error."){super(e),this.name="CollectionValidationError",this.errors=[]}addItemValidationError(e,t){if(!Number.isInteger(e))throw new TypeError('CollectionValidationError::addEntityValidationError expects "position" to be an integer.');if(!(t instanceof X||t instanceof Y))throw new TypeError('CollectionValidationError::addEntityValidationError expects "entityValidationError" to be an instance of EntityValidationError or CollectionValidationError.');this.errors[e]=t}addCollectionValidationError(e,t){if("string"!=typeof e)throw new TypeError('CollectionValidationError::addCollectionValidationError expects "rule" to be a string.');if("string"!=typeof t)throw new TypeError('CollectionValidationError::addCollectionValidationError expects "error" to be a string.');this.errors[e]=t}hasErrors(){return this.errors.some(e=>Object.keys(e.details).length>0)}get details(){const e={};for(const t in this.errors)this.errors[t]instanceof X||this.errors[t]instanceof Y?e[t]=this.errors[t].details:e[t]=this.errors[t];return e}}const Z=Y;class J extends Error{constructor(e="Entity validation error."){super(e),this.name="EntityValidationError",this.details={}}addError(e,t,a){if("string"!=typeof e)throw new TypeError("EntityValidationError addError property should be a string.");if("string"!=typeof t)throw new TypeError("EntityValidationError addError rule should be a string.");if("string"!=typeof a)throw new TypeError("EntityValidationError addError message should be a string.");Object.prototype.hasOwnProperty.call(this.details,e)||(this.details[e]={}),this.details[e][t]=a}addAssociationError(e,t){if("string"!=typeof e)throw new TypeError("EntityValidationError addAssociationError associationName should be a string.");if(!(t instanceof J||t instanceof Z))throw new TypeError("EntityValidationError addAssociationError errorDetails should be an object.");this.details[e]=t}getError(e,t){if(!this.hasError(e,t))return null;const a=this.details[e];return t?a[t]:a}hasError(e,t){if("string"!=typeof e)throw new TypeError("EntityValidationError hasError property should be a string.");const a=this.details&&Object.prototype.hasOwnProperty.call(this.details,e);if(!a)return!1;if(!t)return a;if("string"!=typeof t)throw new TypeError("EntityValidationError hasError rule should be a string.");return Object.prototype.hasOwnProperty.call(this.details[e],t)}hasErrors(){return Object.keys(this.details).length>0}getFirstRuleErrorByField(e){if(!this.hasError(e))return null;const t=this.details[e];return t[Object.keys(t)[0]]}}const X=J;var Q=a(7761),ee=a.n(Q);class te{static validateSchema(e,t){if(!t)throw new TypeError(`Could not validate entity ${e}. No schema for entity ${e}.`);if(!t.type)throw new TypeError(`Could not validate entity ${e}. Type missing.`);if("array"!==t.type){if("object"===t.type){if(!t.required||!Array.isArray(t.required))throw new TypeError(`Could not validate entity ${e}. Schema error: no required properties.`);if(!t.properties||!Object.keys(t).length)throw new TypeError(`Could not validate entity ${e}. Schema error: no properties.`);const a=t.properties;for(const e in a){if(!Object.prototype.hasOwnProperty.call(a,e)||!a[e].type&&!a[e].anyOf)throw TypeError(`Invalid schema. Type missing for ${e}...`);if(a[e].anyOf&&(!Array.isArray(a[e].anyOf)||!a[e].anyOf.length))throw new TypeError(`Invalid schema, prop ${e} anyOf should be an array`)}}}else if(!t.items)throw new TypeError(`Could not validate entity ${e}. Schema error: missing item definition.`)}static validate(e,t,a){if(!e||!t||!a)throw new TypeError(`Could not validate entity ${e}. No data provided.`);switch(a.type){case"object":return te.validateObject(e,t,a);case"array":return te.validateArray(e,t,a);default:throw new TypeError(`Could not validate entity ${e}. Unsupported type.`)}}static validateArray(e,t,a){let n;const s=te.validateProp("items",t,a);if("number"==typeof a.minItems&&(te.isGreaterThanOrEqual(t.length,a.minItems)||(n=te.handleCollectionValidationError("minItems",`The items array should contain at least ${a.minItems} item(s).`,n))),"number"==typeof a.maxItems&&(te.isLessThanOrEqual(t.length,a.maxItems)||(n=te.handleCollectionValidationError("maxItems",`The items array should contain at maximum ${a.maxItems} item(s).`,n))),n)throw n;return s}static validateObject(e,t,a){const n=a.required,s=a.properties,i={};let r;for(const a in s)if(Object.prototype.hasOwnProperty.call(s,a))if(null!==t?.[a]||!0!==s[a]?.nullable){if(n.includes(a)){if(!Object.prototype.hasOwnProperty.call(t,a)){r=te.getOrInitEntityValidationError(e,r),r.addError(a,"required",`The ${a} is required.`);continue}}else if(!Object.prototype.hasOwnProperty.call(t,a))continue;try{i[a]=te.validateProp(a,t[a],s[a])}catch(t){if(!(t instanceof X))throw t;r=te.getOrInitEntityValidationError(e,r),r.details[a]=t.details[a]}}else i[a]=null;if(r)throw r;return i}static getOrInitEntityValidationError(e,t){return t||new X(`Could not validate entity ${e}.`)}static validateProp(e,t,a){if(a.anyOf)return te.validateAnyOf(e,t,a.anyOf),t;if(!0===a.nullable&&null===t)return t;if(te.validatePropType(e,t,a),a.enum)return te.validatePropEnum(e,t,a),t;switch(a.type){case"string":te.validatePropTypeString(e,t,a);break;case"integer":case"number":te.validatePropTypeNumber(e,t,a);break;case"array":te.validatePropTypeArray(e,t,a);break;case"object":case"boolean":case"blob":case"null":break;case"x-custom":te.validatePropCustom(e,t,a);break;default:throw new TypeError(`Could not validate property ${e}. Unsupported prop type ${a.type}`)}return t}static validatePropType(e,t,a){if(!te.isValidPropType(t,a.type))throw te.handlePropertyValidationError(e,"type",`The ${e} is not a valid ${a.type}.`)}static validatePropCustom(e,t,a){try{a.validationCallback(t)}catch(t){throw te.handlePropertyValidationError(e,"custom",`The ${e} is not valid: ${t.message}`)}}static validatePropTypeString(e,t,a){let n;if(a.format&&(te.isValidStringFormat(t,a.format)||(n=te.handlePropertyValidationError(e,"format",`The ${e} is not a valid ${a.format}.`,n))),a.length&&(te.isValidStringLength(t,a.length,a.length)||(n=te.handlePropertyValidationError(e,"length",`The ${e} should be ${a.length} character in length.`,n))),a.minLength&&(te.isValidStringLength(t,a.minLength)||(n=te.handlePropertyValidationError(e,"minLength",`The ${e} should be ${a.minLength} character in length minimum.`,n))),a.maxLength&&(te.isValidStringLength(t,0,a.maxLength)||(n=te.handlePropertyValidationError(e,"maxLength",`The ${e} should be ${a.maxLength} character in length maximum.`,n))),a.pattern&&(ee().matches(t,a.pattern)||(n=te.handlePropertyValidationError(e,"pattern",`The ${e} is not valid.`,n))),a.custom&&(a.custom(t)||(n=te.handlePropertyValidationError(e,"custom",`The ${e} is not valid.`,n))),n)throw n}static handlePropertyValidationError(e,t,a,n=null){return(n=n||new X(`Could not validate property ${e}.`)).addError(e,t,a),n}static handleCollectionValidationError(e,t,a=null){return(a=a||new Z("Could not validate collection.")).addCollectionValidationError(e,t),a}static validatePropTypeNumber(e,t,a){let n;if("number"==typeof a.minimum&&(te.isGreaterThanOrEqual(t,a.minimum)||(n=te.handlePropertyValidationError(e,"minimum",`The ${e} should be greater or equal to ${a.minimum}.`,n))),"number"==typeof a.maximum&&(te.isLesserThanOrEqual(t,a.maximum)||(n=te.handlePropertyValidationError(e,"maximum",`The ${e} should be lesser or equal to ${a.maximum}.`,n))),n)throw n}static validatePropTypeArray(e,t,a){let n;if(a?.items&&"object"==typeof a.items){for(let s=0;s=t}static isLessThanOrEqual(e,t){return e<=t}static isLesserThanOrEqual(e,t){return e<=t}}const ae=te;class ne{constructor(e,t={}){(t?.clone??!0)&&(e=JSON.parse(JSON.stringify(e))),this._props=e}toDto(){return JSON.parse(JSON.stringify(this))}toJSON(){return this._props}_hasProp(e){if(!e.includes(".")){const t=ne._normalizePropName(e);return Object.prototype.hasOwnProperty.call(this._props,t)}try{return this._getPropByPath(e),!0}catch(t){return console.error(`Failed to check if property "${e}" is set:`,t),!1}}_getPropByPath(e){return ne._normalizePropName(e).split(".").reduce((e,t)=>{if(Object.prototype.hasOwnProperty.call(e,t))return e[t];throw new Error},this._props)}static _normalizePropName(e){return e.replace(/([A-Z])/g,(e,t)=>`_${t.toLowerCase()}`).replace(/\._/,".").replace(/^_/,"").replace(/^\./,"")}}const se=ne;var ie=a(5648);const re=e=>e?.replace(/_([a-z])/g,(e,t)=>t.toUpperCase()),oe=e=>e?e.charAt(0).toLocaleUpperCase()+e.slice(1):e;class le extends Error{constructor(e,t,a){if(super(a=a||"Entity collection error."),"number"!=typeof e)throw new TypeError("EntityCollectionError requires a valid position");if(!t||"string"!=typeof t)throw new TypeError("EntityCollectionError requires a valid rule");if(!a||"string"!=typeof a)throw new TypeError("EntityCollectionError requires a valid message");this.position=e,this.rule=t}}const ce=le;class me{constructor(e=[],t={}){const a=t?.clone??!0;this._items=[],a&&(e=JSON.parse(JSON.stringify(e))),this._props=e}toDto(){return JSON.parse(JSON.stringify(this._items))}toJSON(){return this.toDto()}get items(){return this._items}get length(){return this._items.length}[Symbol.iterator](){let e=0;return{next:()=>eObject.prototype.hasOwnProperty.call(a._props,e)&&a._props[e]===t)}getFirst(e,t){if("string"!=typeof e||"string"!=typeof t)throw new TypeError("EntityCollection getFirst by expect propName and search to be strings");const a=this.getAll(e,t);if(a&&a.length)return a[0]}extract(e){if("string"!=typeof e)throw new TypeError("EntityCollection extract expects propName to be a string.");return this._items.reduce((t,a)=>(void 0!==a._props[e]&&t.push(a._props[e]),t),[])}push(e){return this._items.push(e),this._items.length}unshift(e){return this._items.unshift(e),this._items.length}filterByPropertyValueIn(e,t,a=!0){if("string"!=typeof e)throw new TypeError("EntityCollection filterByPropertyValueIn expects propName to be a string.");if(!Array.isArray(t))throw new TypeError("EntityCollection filterByPropertyValueIn expects needles to be an array.");this.filterByCallback(n=>{const s=Object.prototype.hasOwnProperty.call(n._props,e);return!(a&&!s||s&&!t.includes(n._props[e]))})}filterByCallback(e){if("function"!=typeof e)throw new TypeError("EntityCollection filterByCallback expects callback to be a function.");for(let t=this._items.length-1;t>=0;t--)e(this._items[t])||this._items.splice(t,1)}assertUniqueByProperty(e,t){const a=`unique_${e}`,n=this.extract(e),s=new Set;t=t||`The collection should only contain items with unique values for the property: ${e}.`,n.forEach((e,n)=>{if(s.add(e),n!==s.size-1)throw new ce(n,a,t)})}assertNotExist(e,t,a={}){if(void 0===t)return;let n=a?.haystackSet;if(!n){const t=this.extract(e);n=new Set(t)}if(n.has(t)){const t=new X,n=a?.message||`The collection already includes an element that has a property (${e}) with an identical value.`;throw t.addError(e,"unique",n),t}}}const de=me,ue=["string","number","integer","boolean"];class pe extends se{static _cachedSchema={};constructor(e={},t={}){const a=t?.validate??!0;super(e,t),this.marshall(),a&&this.validateSchema({schema:t?.schema,skipSchemaAssociationValidation:t?.skipSchemaAssociationValidation}),this.createAssociations(t),a&&this.validateBuildRules(t?.validateBuildRules)}marshall(){}validate(e={}){try{this.validateSchema({schema:e?.schema,skipSchemaAssociationValidation:e?.skipSchemaAssociationValidation}),this.validateBuildRules(e?.validateBuildRules),this.validateAssociations(e)}catch(e){if(!(e instanceof X))throw e;return e}return null}validateSchema(e=null){let t=e?.schema??this.cachedSchema;if(e?.skipSchemaAssociationValidation){t={...t};const e=Object.keys(this.constructor.associations),a=t.required.filter(t=>!e.includes(t));t.required=a}this._props=ae.validate(this.constructor.name,this._props,t)}get cachedSchema(){return this.constructor._cachedSchema[this.constructor.name]||(this.constructor._cachedSchema[this.constructor.name]=this.constructor.getSchema()),this.constructor._cachedSchema[this.constructor.name]}static getSchema(){throw new Error("The entity class should declare its schema.")}validateBuildRules(e={}){}createAssociations(e={}){if(Object.keys(this.constructor.associations).length>0){const t=new X;for(const[a,n]of Object.entries(this.constructor.associations))try{this._props[a]&&(this[`_${re(a)}`]=new n(this._props[a],{...e,clone:!1}),delete this._props[a])}catch(e){if(!(e instanceof X))throw e;t.addAssociationError(a,e)}if(t.hasErrors())throw t}}static get associations(){return{}}get(e){(0,ie.A)(e);const t=this.constructor.getSchema().properties[e];if(!t)throw new Error(`The property "${e}" has no schema definition.`);if(!ue.includes(t?.type))throw new Error('The property "associated_entity" should reference scalar properties only.');return this._props[e]}set(e,t,a={}){(0,ie.A)(e);const n=a?.validate??!0;if(this.isAssociation(e))this.setAssociation(e,t,a);else{const s=e.split(".")[0],i=this.constructor.getSchema().properties[s];if(!i)throw new Error(`The property "${s}" has no schema definition.`);if("array"===i?.type)this.setArrayProp(e,t,a);else{if(i?.type&&!ue.includes(i?.type))throw new Error('The property "associated_entity" should reference scalar properties only.');if(i?.anyOf?.some(e=>!ue.includes(e.type)))throw new Error('The property "associated_entity" should reference scalar properties only.');n&&ae.validateProp(s,t,i),this._props[s]=t}}}setArrayProp(e,t,a){(0,ie.A)(e);const n=e.split("."),s=n[0];let i=null;const r=this.constructor.getSchema().properties[s],o=a?.validate??!0;if(2!==n.length)throw new Error(`The property "${n[0]}" has no index passed.`);{const e=n[1].match(/^(\d+)$/);if(!e)throw new Error(`The property "${n[0]}" has an invalid index format. Expected format: digits.`);i=parseInt(e[1],10)}if(!ue.includes(r.items.type))throw new Error('The property "associated_entity" with array type should reference scalar properties only.');o&&ae.validateProp(s,t,r.items),this._props[s]||(this._props[s]=[]),null!=t?this._props[s][i]=t:this._props[s].splice(i,1)}setCollection(e,t,a){(0,ie.A)(e);const n=e.split("."),s=n[0];let i=null;if(1===n.length)t instanceof this.constructor.associations[e]?this[`_${s}`]=t:this[`_${s}`]=new this.constructor.associations[e](t,a);else{if(!(n.length>1))throw new Error(`The property "${n[0]}" has no index passed.`);{const e=n[1].match(/^(\d+)$/);if(!e)throw new Error(`The property "${n[0]}" has an invalid index format. Expected format: digits.`);i=parseInt(e[1],10)}}if(!this[`_${s}`])throw new Error(`The collection "${n[0]}" has no item".`);if(null!=t)if(n.length>2){if(!this[`_${s}`]._items[i])throw new Error(`The collection "${n[0]}" has no item at the index "${n[1]}".`);const e=n.slice(2).join(".");this[`_${s}`]._items[i].set(e,t,a)}else this[`_${s}`].push(t,a,a);else this[`_${s}`].items.splice(i,1)}setAssociation(e,t,a={}){if((0,ie.A)(e),this.isAssociation(e)){const n=e.split("."),s=re(n[0]);if(n.length>1)if(this[`_${s}`]||(this[`_${s}`]=new this.constructor.associations[n[0]]({},{validate:!1})),this[`_${s}`]instanceof de){const e=n.toSpliced(0,1,s).join(".");this.setCollection(e,t,a)}else{const e=n.slice(1).join(".");this[`_${s}`].set(e,t,a)}else t instanceof this.constructor.associations[e]?this[`_${s}`]=t:this[`_${s}`]=new this.constructor.associations[e](t,a)}}validateAssociations(e={}){const t=new X;if(Object.keys(this.constructor.associations).length>0&&Object.keys(this.constructor.associations).forEach(a=>{const n=re(a);if(this[`_${n}`]){const s=this[n].validate(e);s&&t.addAssociationError(a,s)}}),t.hasErrors())throw t}diffProps(e){if(!(e instanceof pe))throw new TypeError('The property "compareEntity" should be of "EntityV2" type.');const t={},a=this.constructor.getSchema(),n=Object.keys(a.properties).filter(e=>ue.includes(a.properties[e].type));for(const a of n){const n=this.get(a),s=e.get(a);n!==s&&(t[a]=s)}return t}hasDiffProps(e){const t=this.diffProps(e);return Object.keys(t).length>0}isAssociation(e){const t=e.split(".")[0];return Boolean(this.constructor.associations?.[t])}}const he=pe;class ge extends he{static getSchema(){return{type:"object",required:["name"],properties:{id:{type:"string",format:"uuid"},name:{type:"string",minLength:1,maxLength:50},description:{type:"string",maxLength:255,nullable:!0},created:{type:"string",format:"date-time"},modified:{type:"string",format:"date-time"}}}}validateBuildRules(){this.assertNoTrailingSpaces("name",this._props.name)}get id(){return this._props.id||null}get name(){return this._props.name}isAdmin(){return this.name.toLowerCase()===ge.ROLE_ADMIN}isUser(){return this.name.toLowerCase()===ge.ROLE_USER}isGuest(){return this.name.toLowerCase()===ge.ROLE_GUEST}isAReservedRole(){return this.isAdmin()||this.isUser()||this.isGuest()}verifyHealth(){let e=null;return 50===this.name.length&&(e=new X,e.addError("name","maxLength","name reached maximum length limit")),e}assertNoTrailingSpaces(e,t){if(t.trim()!==t){const t=new X;throw t.addError(e,"trailing-spaces",`The property (${e}) contains forbidden trailing spaces.`),t}}static get ENTITY_NAME(){return"Role"}static get ROLE_ADMIN(){return"admin"}static get ROLE_USER(){return"user"}static get ROLE_GUEST(){return"guest"}static get ROLE_NAME_MAX_LENGTH(){return 50}toUpdateDto(){return{name:this.name}}}class ye{static canRoleUseAction(e,t,a){if(window.chrome?.webview){const n=t.findRbacByActionName(a);if(n)return $.getByRbac(n).execute(e)}const n=new ge(e.role);if(n.isAdmin())return $.getDefaultForAdminAndAction(a).execute();const s=t.findRbacByRoleAndActionName(n,a);return this.getByRbacOrDefault(s,a,e)}static getByRbacOrDefault(e,t,a){return e?$.getByRbac(e).execute(a):$.getDefaultForUserAndAction(t).execute()}}function be(){return be=Object.assign?Object.assign.bind():function(e){for(var t=1;t{}});class Ee extends n.Component{constructor(e){super(e),this.state=this.defaultState}get defaultState(){return{canIUseAction:this.canIUseAction.bind(this)}}canIUseAction(e){return ye.canRoleUseAction(this.props.context.loggedInUser,this.props.context.rbacs,e)}render(){return n.createElement(fe.Provider,{value:this.state},this.props.children)}}Ee.propTypes={context:i().any,children:i().any};const ve=N(Ee);function we(e){return class extends n.Component{render(){return n.createElement(fe.Consumer,null,t=>n.createElement(e,be({rbacContext:t},this.props)))}}}function ke(){return ke=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},resetDisplayAdministrationWorkspaceAction:()=>{},onUpdateSubscriptionKeyRequested:()=>{},onSaveEnabled:()=>{},onMustSaveSettings:()=>{},onMustEditSubscriptionKey:()=>{},onMustRefreshSubscriptionKey:()=>{},onResetActionsSettings:()=>{}});class xe extends n.Component{constructor(e){super(e),this.state=this.defaultState}get defaultState(){return{selectedAdministration:Te.NONE,can:{save:!1},must:{save:!1,editSubscriptionKey:!1,refreshSubscriptionKey:!1},administrationWorkspaceAction:()=>n.createElement(n.Fragment,null),setDisplayAdministrationWorkspaceAction:this.setDisplayAdministrationWorkspaceAction.bind(this),resetDisplayAdministrationWorkspaceAction:this.resetDisplayAdministrationWorkspaceAction.bind(this),onSaveEnabled:this.handleSaveEnabled.bind(this),onMustSaveSettings:this.handleMustSaveSettings.bind(this),onMustEditSubscriptionKey:this.handleMustEditSubscriptionKey.bind(this),onMustRefreshSubscriptionKey:this.handleMustRefreshSubscriptionKey.bind(this),onResetActionsSettings:this.handleResetActionsSettings.bind(this)}}componentDidMount(){this.handleAdministrationMenuRouteChange()}componentDidUpdate(e){this.handleRouteChange(e.location)}handleSaveEnabled(){this.setState({can:{...this.state.can,save:!0}})}handleMustSaveSettings(){this.setState({must:{...this.state.must,save:!0}})}handleMustEditSubscriptionKey(){this.setState({must:{...this.state.must,editSubscriptionKey:!0}})}handleMustRefreshSubscriptionKey(){this.setState({must:{...this.state.must,refreshSubscriptionKey:!0}})}handleResetActionsSettings(){this.setState({must:{save:!1,test:!1,synchronize:!1,editSubscriptionKey:!1,refreshSubscriptionKey:!1}})}handleRouteChange(e){this.props.location.key!==e.key&&this.handleAdministrationMenuRouteChange()}handleAdministrationMenuRouteChange(){const e={can:{save:!1,test:!1,synchronize:!1},must:{save:!1,test:!1,synchronize:!1,editSubscriptionKey:!1,refreshSubscriptionKey:!1}};if(!this.props.rbacContext.canIUseAction(F))return e.selectedAdministration=Te.HTTP_403_ACCESS_DENIED,void this.setState(e);const t=this.props.location.pathname,a=Ie.homePage.test(t),n=Ie.mfa.test(t),s=Ie.mfaPolicy.test(t),i=Ie.passwordPolicies.test(t),r=Ie.usersDirectory.test(t),o=Ie.emailNotification.test(t),l=Ie.subscription.test(t),c=Ie.internationalization.test(t),m=Ie.accountRecovery.test(t),d=Ie.smtpSettings.test(t),u=Ie.selfRegistration.test(t),p=Ie.sso.test(t),h=Ie.rbac.test(t),g=Ie.userPassphrasePolicies.test(t),y=Ie.passwordExpirySettings.test(t),b=Ie.healthcheck.test(t),f=Ie.contentTypesEncryptedMetadata.test(t),E=Ie.contentTypesMetadataKey.test(t),v=Ie.migrateEncryptedMetadata.test(t),w=Ie.allowContentTypes.test(t),k=Ie.gettingStarted.test(t),_=Ie.scim.test(t),x=Ie.secretHistory.test(t),S=Ie.mfaPolicyTeasing.test(t),C=Ie.passwordPoliciesTeasing.test(t),N=Ie.usersDirectoryTeasing.test(t),T=Ie.subscriptionTeasing.test(t),A=Ie.accountRecoveryTeasing.test(t),I=Ie.userPassphrasePoliciesTeasing.test(t),R=Ie.ssoTeasing.test(t),P=Ie.scimTeasing.test(t);let D;if(a?D=Te.HOME:s||S?D=Te.MFA_POLICY:i||C?D=Te.PASSWORD_POLICIES:n?D=Te.MFA:r||N?D=Te.USER_DIRECTORY:o?D=Te.EMAIL_NOTIFICATION:l||T?D=Te.SUBSCRIPTION:c?D=Te.INTERNATIONALIZATION:m||A?D=Te.ACCOUNT_RECOVERY:d?D=Te.SMTP_SETTINGS:u?D=Te.SELF_REGISTRATION:p||R?D=Te.SSO:h?D=Te.RBAC:g||I?D=Te.USER_PASSPHRASE_POLICIES:y?D=Te.PASSWORD_EXPIRY:b?D=Te.HEALTHCHECK:f?D=Te.CONTENT_TYPES_ENCRYPTED_METADATA:E?D=Te.CONTENT_TYPES_METADATA_KEY:v?D=Te.MIGRATE_METADATA:w?D=Te.ALLOW_CONTENT_TYPES:k?D=Te.METADATA_GETTING_STARTED:_||P?D=Te.SCIM:x&&(D=Te.SECRET_HISTORY),!D)return e.selectedAdministration=Te.HTTP_404_NOT_FOUND,void this.setState(e);const O=Ae?.[D];e.selectedAdministration=O&&!(this.props.context.siteSettings.canIUse(O)||Re.includes(D)&&this.props.context.siteSettings.isCommunityEdition)?Te.HTTP_404_NOT_FOUND:D,this.setState(e)}setDisplayAdministrationWorkspaceAction(e){this.setState({administrationWorkspaceAction:e})}resetDisplayAdministrationWorkspaceAction(){this.setState({administrationWorkspaceAction:()=>n.createElement(n.Fragment,null)})}render(){return n.createElement(_e.Provider,{value:this.state},this.props.children)}}xe.displayName="AdministrationWorkspaceContextProvider",xe.propTypes={context:i().object,children:i().any,location:i().object,match:i().object,history:i().object,loadingContext:i().object,rbacContext:i().object};const Se=(0,x.withRouter)(N(we((Ce=xe,class extends n.Component{render(){return n.createElement(I.Consumer,null,e=>n.createElement(Ce,A({loadingContext:e},this.props)))}}))));var Ce;function Ne(e){return class extends n.Component{render(){return n.createElement(_e.Consumer,null,t=>n.createElement(e,ke({administrationWorkspaceContext:t},this.props)))}}}const Te={NONE:"NONE",HOME:"HOME",MFA:"MFA",MFA_POLICY:"MFA-POLICY",PASSWORD_POLICIES:"PASSWORD-POLICIES",USER_DIRECTORY:"USER-DIRECTORY",EMAIL_NOTIFICATION:"EMAIL-NOTIFICATION",SUBSCRIPTION:"SUBSCRIPTION",INTERNATIONALIZATION:"INTERNATIONALIZATION",ACCOUNT_RECOVERY:"ACCOUNT-RECOVERY",SMTP_SETTINGS:"SMTP-SETTINGS",SELF_REGISTRATION:"SELF-REGISTRATION",SSO:"SSO",RBAC:"RBAC",USER_PASSPHRASE_POLICIES:"USER-PASSPHRASE-POLICIES",PASSWORD_EXPIRY:"PASSWORD-EXPIRY",HTTP_403_ACCESS_DENIED:"403-ACCESS-DENIED",HTTP_404_NOT_FOUND:"404-NOT-FOUND",HEALTHCHECK:"HEALTHCHECK",CONTENT_TYPES_ENCRYPTED_METADATA:"CONTENT_TYPES_ENCRYPTED_METADATA",CONTENT_TYPES_METADATA_KEY:"CONTENT_TYPES_METADATA_KEY",MIGRATE_METADATA:"MIGRATE_METADATA",ALLOW_CONTENT_TYPES:"ALLOW_CONTENT_TYPES",METADATA_GETTING_STARTED:"METADATA_GETTING_STARTED",SCIM:"SCIM",SECRET_HISTORY:"SECRET_HISTORY"},Ae={[Te.MFA]:"multiFactorAuthentication",[Te.MFA_POLICY]:"mfaPolicies",[Te.PASSWORD_POLICIES]:"passwordPoliciesUpdate",[Te.USER_DIRECTORY]:"directorySync",[Te.SUBSCRIPTION]:"ee",[Te.INTERNATIONALIZATION]:"locale",[Te.ACCOUNT_RECOVERY]:"accountRecovery",[Te.SMTP_SETTINGS]:"smtpSettings",[Te.SELF_REGISTRATION]:"selfRegistration",[Te.SSO]:"sso",[Te.RBAC]:"rbacs",[Te.USER_PASSPHRASE_POLICIES]:"userPassphrasePolicies",[Te.PASSWORD_EXPIRY]:"passwordExpiry",[Te.HEALTHCHECK]:"healthcheckUi",[Te.CONTENT_TYPES_ENCRYPTED_METADATA]:"metadata",[Te.CONTENT_TYPES_METADATA_KEY]:"metadata",[Te.MIGRATE_METADATA]:"metadata",[Te.ALLOW_CONTENT_TYPES]:"metadata",[Te.METADATA_GETTING_STARTED]:"metadata",[Te.SCIM]:"scim",[Te.SECRET_HISTORY]:"secretRevisions"},Ie={homePage:/^\/app\/administration\/?$/,mfa:/^\/app\/administration\/mfa\/?$/,mfaPolicy:/^\/app\/administration\/mfa-policy\/?$/,mfaPolicyTeasing:/^\/app\/administration\/mfa-policy-teasing\/?$/,passwordPolicies:/^\/app\/administration\/password-policies\/?$/,passwordPoliciesTeasing:/^\/app\/administration\/password-policies-teasing\/?$/,usersDirectory:/^\/app\/administration\/users-directory\/?$/,usersDirectoryTeasing:/^\/app\/administration\/users-directory-teasing\/?$/,emailNotification:/^\/app\/administration\/email-notification\/?$/,subscription:/^\/app\/administration\/subscription\/?$/,subscriptionTeasing:/^\/app\/administration\/subscription-teasing\/?$/,internationalization:/^\/app\/administration\/internationalization\/?$/,accountRecovery:/^\/app\/administration\/account-recovery\/?$/,accountRecoveryTeasing:/^\/app\/administration\/account-recovery-teasing\/?$/,smtpSettings:/^\/app\/administration\/smtp-settings\/?$/,selfRegistration:/^\/app\/administration\/self-registration\/?$/,sso:/^\/app\/administration\/sso\/?$/,ssoTeasing:/^\/app\/administration\/sso-teasing\/?$/,rbac:/^\/app\/administration\/rbacs\/?$/,userPassphrasePolicies:/^\/app\/administration\/user-passphrase-policies\/?$/,userPassphrasePoliciesTeasing:/^\/app\/administration\/user-passphrase-policies-teasing\/?$/,passwordExpirySettings:/^\/app\/administration\/password-expiry\/?$/,healthcheck:/^\/app\/administration\/healthcheck\/?$/,contentTypesEncryptedMetadata:/^\/app\/administration\/content-types\/metadata\/?$/,contentTypesMetadataKey:/^\/app\/administration\/content-types\/metadata-key\/?$/,migrateEncryptedMetadata:/^\/app\/administration\/migrate-metadata\/?$/,allowContentTypes:/^\/app\/administration\/allow-content-types\/?$/,gettingStarted:/^\/app\/administration\/content-types\/metadata-getting-started\/?$/,scim:/^\/app\/administration\/user-provisionning\/scim\/?$/,scimTeasing:/^\/app\/administration\/scim-teasing\/?$/,secretHistory:/^\/app\/administration\/secret-history\/?$/},Re=[Te.SUBSCRIPTION,Te.PASSWORD_POLICIES,Te.USER_PASSPHRASE_POLICIES,Te.ACCOUNT_RECOVERY,Te.SSO,Te.MFA_POLICY,Te.USER_DIRECTORY,Te.SCIM];function Pe(){return Pe=Object.assign?Object.assign.bind():function(e){for(var t=1;tt===e);t?.DialogProps?.onClose&&t.DialogProps.onClose(),this.props.dialogContext.close(e)}render(){return n.createElement(n.Fragment,null,this.props.dialogContext.dialogs.map(({key:e,Dialog:t,DialogProps:a})=>n.createElement(t,Pe({key:e},a,{onClose:()=>this.close(e)}))),this.props.children)}}De.propTypes={dialogContext:i().any,children:i().any};const Oe=h(De);function Me(){return Me=Object.assign?Object.assign.bind():function(e){for(var t=1;tn.createElement(e.ContextualMenuComponent,Me({key:t,hide:()=>this.handleHide(t)},e.componentProps))))}}Ue.propTypes={contextualMenuContext:i().any};const Fe=function(e){return class extends n.Component{render(){return n.createElement(y.Consumer,null,t=>n.createElement(e,g({contextualMenuContext:t},this.props)))}}}(Ue);function je(){return je=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},onGoToAdministrationSelfRegistrationRequested:()=>{},onGoToAdministrationMfaRequested:()=>{},onGoToAdministrationUsersDirectoryRequested:()=>{},onGoToAdministrationEmailNotificationsRequested:()=>{},onGoToAdministrationSubscriptionRequested:()=>{},onGoToAdministrationInternationalizationRequested:()=>{},onGoToAdministrationAccountRecoveryRequested:()=>{},onGoToAdministrationSmtpSettingsRequested:()=>{},onGoToAdministrationSsoRequested:()=>{},onGoToAdministrationPasswordPoliciesRequested:()=>{},onGoToAdministrationSecretHistoryRequested:()=>{},onGoToAdministrationUserPassphrasePoliciesRequested:()=>{},onGoToAdministrationPasswordExpirySettingsRequested:()=>{},onGoToAdministrationHealthcheckRequested:()=>{},onGoToPasswordsRequested:()=>{},onGoToUsersRequested:()=>{},onGoToHelpRequested:()=>{},onGoToUserSettingsProfileRequested:()=>{},onGoToUserSettingsPassphraseRequested:()=>{},onGoToUserSettingsSecurityTokenRequested:()=>{},onGoToUserSettingsThemeRequested:()=>{},onGoToUserSettingsMfaRequested:()=>{},onGoToUserSettingsKeysRequested:()=>{},onGoToUserSettingsMobileRequested:()=>{},onGoToUserSettingsDesktopRequested:()=>{},onGoToUserSettingsAccountRecoveryRequested:()=>{},onGoToNewTab:()=>{},onGoToAdministrationRbacsRequested:()=>{},onGoToAdministrationMigrateMetadataRequested:()=>{},onGoToAdministrationAllowContentTypesRequested:()=>{},onGoToAdministrationMetadataGettingStartedRequested:()=>{},onGoToAdministrationSubscriptionRequestedTeasing:()=>{},onGoToAdministrationPasswordPoliciesRequestedTeasing:()=>{},onGoToAdministrationUserPassphrasePoliciesRequestedTeasing:()=>{},onGoToAdministrationAccountRecoveryRequestedTeasing:()=>{},onGoToAdministrationSsoRequestedTeasing:()=>{},onGoToAdministrationMfaPolicyRequestedTeasing:()=>{},onGoToAdministrationUsersDirectoryRequestedTeasing:()=>{},onGoToAdministrationScimRequestedTeasing:()=>{},onGoToAdministrationScimRequested:()=>{}});class qe extends n.Component{constructor(e){super(e),this.state=this.defaultState}get defaultState(){return{onGoToNewTab:this.onGoToNewTab.bind(this),onGoToAdministrationRequested:this.onGoToAdministrationRequested.bind(this),onGoToAdministrationMfaRequested:this.onGoToAdministrationMfaRequested.bind(this),onGoToAdministrationUsersDirectoryRequested:this.onGoToAdministrationUsersDirectoryRequested.bind(this),onGoToAdministrationEmailNotificationsRequested:this.onGoToAdministrationEmailNotificationsRequested.bind(this),onGoToAdministrationSubscriptionRequested:this.onGoToAdministrationSubscriptionRequested.bind(this),onGoToAdministrationInternationalizationRequested:this.onGoToAdministrationInternationalizationRequested.bind(this),onGoToAdministrationAccountRecoveryRequested:this.onGoToAdministrationAccountRecoveryRequested.bind(this),onGoToAdministrationSmtpSettingsRequested:this.onGoToAdministrationSmtpSettingsRequested.bind(this),onGoToAdministrationSelfRegistrationRequested:this.onGoToAdministrationSelfRegistrationRequested.bind(this),onGoToAdministrationSsoRequested:this.onGoToAdministrationSsoRequested.bind(this),onGoToAdministrationMfaPolicyRequested:this.onGoToAdministrationMfaPolicyRequested.bind(this),onGoToAdministrationPasswordPoliciesRequested:this.onGoToAdministrationPasswordPoliciesRequested.bind(this),onGoToAdministrationSecretHistoryRequested:this.onGoToAdministrationSecretHistoryRequested.bind(this),onGoToAdministrationUserPassphrasePoliciesRequested:this.onGoToAdministrationUserPassphrasePoliciesRequested.bind(this),onGoToAdministrationPasswordExpirySettingsRequested:this.onGoToAdministrationPasswordExpirySettingsRequested.bind(this),onGoToAdministrationHealthcheckRequested:this.onGoToAdministrationHealthcheckRequested.bind(this),onGoToAdministrationContentTypesEncryptedMetadataRequested:this.onGoToAdministrationContentTypesEncryptedMetadataRequested.bind(this),onGoToAdministrationContentTypesMetadataKeyRequested:this.onGoToAdministrationContentTypesMetadataKeyRequested.bind(this),onGoToAdministrationMigrateMetadataRequested:this.onGoToAdministrationMigrateMetadataRequested.bind(this),onGoToAdministrationAllowContentTypesRequested:this.onGoToAdministrationAllowContentTypesRequested.bind(this),onGoToPasswordsRequested:this.onGoToPasswordsRequested.bind(this),onGoToUsersRequested:this.onGoToUsersRequested.bind(this),onGoToHelpRequested:this.onGoToHelpRequested.bind(this),onGoToUserSettingsProfileRequested:this.onGoToUserSettingsProfileRequested.bind(this),onGoToUserSettingsPassphraseRequested:this.onGoToUserSettingsPassphraseRequested.bind(this),onGoToUserSettingsSecurityTokenRequested:this.onGoToUserSettingsSecurityTokenRequested.bind(this),onGoToUserSettingsThemeRequested:this.onGoToUserSettingsThemeRequested.bind(this),onGoToUserSettingsMfaRequested:this.onGoToUserSettingsMfaRequested.bind(this),onGoToUserSettingsKeysRequested:this.onGoToUserSettingsKeysRequested.bind(this),onGoToUserSettingsMobileRequested:this.onGoToUserSettingsMobileRequested.bind(this),onGoToUserSettingsDesktopRequested:this.onGoToUserSettingsDesktopRequested.bind(this),onGoToUserSettingsAccountRecoveryRequested:this.onGoToUserSettingsAccountRecoveryRequested.bind(this),onGoToAdministrationRbacsRequested:this.onGoToAdministrationRbacsRequested.bind(this),onGoToAdministrationMetadataGettingStartedRequested:this.onGoToAdministrationMetadataGettingStartedRequested.bind(this),onGoToAdministrationSubscriptionRequestedTeasing:this.onGoToAdministrationSubscriptionRequestedTeasing.bind(this),onGoToAdministrationPasswordPoliciesRequestedTeasing:this.onGoToAdministrationPasswordPoliciesRequestedTeasing.bind(this),onGoToAdministrationUserPassphrasePoliciesRequestedTeasing:this.onGoToAdministrationUserPassphrasePoliciesRequestedTeasing.bind(this),onGoToAdministrationAccountRecoveryRequestedTeasing:this.onGoToAdministrationAccountRecoveryRequestedTeasing.bind(this),onGoToAdministrationSsoRequestedTeasing:this.onGoToAdministrationSsoRequestedTeasing.bind(this),onGoToAdministrationMfaPolicyRequestedTeasing:this.onGoToAdministrationMfaPolicyRequestedTeasing.bind(this),onGoToAdministrationUsersDirectoryRequestedTeasing:this.onGoToAdministrationUsersDirectoryRequestedTeasing.bind(this),onGoToAdministrationScimRequestedTeasing:this.onGoToAdministrationScimRequestedTeasing.bind(this),onGoToAdministrationScimRequested:this.onGoToAdministrationScimRequested.bind(this)}}async goTo(e,t){if(e===this.props.context.name)return void await this.props.history.push({pathname:t});if("api"===e)return void await this.props.context.port.request("passbolt.tabs.open-admin-page",t);const a=`${this.props.context.userSettings?this.props.context.userSettings.getTrustedDomain():this.props.context.trustedDomain}${t}`;window.open(a,"_parent","noopener,noreferrer")}onGoToNewTab(e){window.open(e,"_blank","noopener,noreferrer")}async onGoToAdministrationRequested(){await this.goTo("browser-extension","/app/administration")}async onGoToAdministrationMfaRequested(){await this.goTo("api","/app/administration/mfa")}async onGoToAdministrationMfaPolicyRequested(){await this.goTo("api","/app/administration/mfa-policy")}async onGoToAdministrationPasswordPoliciesRequested(){await this.goTo("browser-extension","/app/administration/password-policies")}async onGoToAdministrationSecretHistoryRequested(){await this.goTo("browser-extension","/app/administration/secret-history")}async onGoToAdministrationSelfRegistrationRequested(){await this.goTo("api","/app/administration/self-registration")}async onGoToAdministrationUsersDirectoryRequested(){await this.goTo("api","/app/administration/users-directory")}async onGoToAdministrationHealthcheckRequested(){await this.goTo("api","/app/administration/healthcheck")}async onGoToAdministrationEmailNotificationsRequested(){await this.goTo("api","/app/administration/email-notification")}async onGoToAdministrationSmtpSettingsRequested(){await this.goTo("api","/app/administration/smtp-settings")}async onGoToAdministrationSubscriptionRequested(){await this.goTo("browser-extension","/app/administration/subscription")}async onGoToAdministrationInternationalizationRequested(){await this.goTo("api","/app/administration/internationalization")}async onGoToAdministrationAccountRecoveryRequested(){await this.goTo("browser-extension","/app/administration/account-recovery")}async onGoToAdministrationSsoRequested(){await this.goTo("browser-extension","/app/administration/sso")}async onGoToAdministrationRbacsRequested(){await this.goTo("api","/app/administration/rbacs")}async onGoToAdministrationMetadataGettingStartedRequested(){await this.goTo("browser-extension","/app/administration/content-types/metadata-getting-started")}async onGoToAdministrationScimRequested(){await this.goTo("browser-extension","/app/administration/user-provisionning/scim")}async onGoToAdministrationUserPassphrasePoliciesRequested(){await this.goTo("browser-extension","/app/administration/user-passphrase-policies")}async onGoToAdministrationPasswordExpirySettingsRequested(){await this.goTo("browser-extension","/app/administration/password-expiry")}async onGoToAdministrationContentTypesEncryptedMetadataRequested(){await this.goTo("browser-extension","/app/administration/content-types/metadata")}async onGoToAdministrationContentTypesMetadataKeyRequested(){await this.goTo("browser-extension","/app/administration/content-types/metadata-key")}async onGoToAdministrationMigrateMetadataRequested(){await this.goTo("browser-extension","/app/administration/migrate-metadata")}async onGoToAdministrationAllowContentTypesRequested(){await this.goTo("browser-extension","/app/administration/allow-content-types")}async onGoToAdministrationSubscriptionRequestedTeasing(){await this.goTo("browser-extension","/app/administration/subscription-teasing")}async onGoToAdministrationPasswordPoliciesRequestedTeasing(){await this.goTo("browser-extension","/app/administration/password-policies-teasing")}async onGoToAdministrationUserPassphrasePoliciesRequestedTeasing(){await this.goTo("browser-extension","/app/administration/user-passphrase-policies-teasing")}async onGoToAdministrationAccountRecoveryRequestedTeasing(){await this.goTo("browser-extension","/app/administration/account-recovery-teasing")}async onGoToAdministrationSsoRequestedTeasing(){await this.goTo("browser-extension","/app/administration/sso-teasing")}async onGoToAdministrationMfaPolicyRequestedTeasing(){await this.goTo("browser-extension","/app/administration/mfa-policy-teasing")}async onGoToAdministrationUsersDirectoryRequestedTeasing(){await this.goTo("browser-extension","/app/administration/users-directory-teasing")}async onGoToAdministrationScimRequestedTeasing(){await this.goTo("browser-extension","/app/administration/scim-teasing")}get isMfaEnabled(){const e=this.props.context.siteSettings;return e&&e.canIUse("multiFactorAuthentication")}get isUserDirectoryEnabled(){const e=this.props.context.siteSettings;return e&&e.canIUse("directorySync")}get isSmtpSettingsEnable(){const e=this.props.context.siteSettings;return e&&e.canIUse("smtpSettings")}get isSelfRegistrationEnable(){const e=this.props.context.siteSettings;return e&&e.canIUse("selfRegistration")}get isPasswordPoliciesEnable(){const e=this.props.context.siteSettings;return e&&e.canIUse("passwordPoliciesUpdate")}get isUserPassphrasePoliciesEnable(){const e=this.props.context.siteSettings;return e&&e.canIUse("userPassphrasePolicies")}get isPasswordExpiryEnable(){const e=this.props.context.siteSettings;return e&&e.canIUse("passwordExpiry")}async onGoToPasswordsRequested(){await this.goTo("browser-extension","/app/passwords")}async onGoToUsersRequested(){await this.goTo("browser-extension","/app/users")}async onGoToHelpRequested(){await this.onGoToNewTab("https://www.passbolt.com/docs/")}async onGoToUserSettingsProfileRequested(){await this.goTo("browser-extension","/app/settings/profile")}async onGoToUserSettingsPassphraseRequested(){await this.goTo("browser-extension","/app/settings/passphrase")}async onGoToUserSettingsSecurityTokenRequested(){await this.goTo("browser-extension","/app/settings/security-token")}async onGoToUserSettingsThemeRequested(){await this.goTo("browser-extension","/app/settings/theme")}async onGoToUserSettingsMfaRequested(){await this.goTo("browser-extension","/app/settings/mfa")}async onGoToUserSettingsDuoSetupRequested(){let e="api";window.chrome?.webview&&(e="browser-extension"),await this.goTo(e,"/app/settings/mfa")}async onGoToUserSettingsKeysRequested(){await this.goTo("browser-extension","/app/settings/keys")}async onGoToUserSettingsMobileRequested(){await this.goTo("browser-extension","/app/settings/mobile")}async onGoToUserSettingsDesktopRequested(){await this.goTo("browser-extension","/app/settings/desktop")}async onGoToUserSettingsAccountRecoveryRequested(){await this.goTo("browser-extension","/app/settings/account-recovery")}render(){return n.createElement(Le.Provider,{value:this.state},this.props.children)}}qe.displayName="NavigationContextProvider",qe.propTypes={context:i().object,children:i().any,location:i().object,match:i().object,history:i().object};const ze=(0,x.withRouter)(N(qe));function Ke(e){return class extends n.Component{render(){return n.createElement(Le.Consumer,null,t=>n.createElement(e,je({navigationContext:t},this.props)))}}}function Ve(){return Ve=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},getOrganizationPolicy:()=>{},getRequestor:()=>{},getRequestedDate:()=>{},getPolicy:()=>{},getUserAccountRecoverySubscriptionStatus:()=>{},isAccountRecoveryChoiceRequired:()=>{},isPolicyEnabled:()=>{},loadAccountRecoveryPolicy:()=>{},reloadAccountRecoveryPolicy:()=>{},isReady:()=>{}});class Be extends n.Component{constructor(e){super(e),this.state=this.defaultState}get defaultState(){return{accountRecoveryOrganizationPolicy:null,status:null,isDataLoaded:!1,findAccountRecoveryPolicy:this.findAccountRecoveryPolicy.bind(this),getOrganizationPolicy:this.getOrganizationPolicy.bind(this),getRequestor:this.getRequestor.bind(this),getRequestedDate:this.getRequestedDate.bind(this),getPolicy:this.getPolicy.bind(this),getUserAccountRecoverySubscriptionStatus:this.getUserAccountRecoverySubscriptionStatus.bind(this),setUserAccountRecoveryStatus:this.setUserAccountRecoveryStatus.bind(this),isAccountRecoveryChoiceRequired:this.isAccountRecoveryChoiceRequired.bind(this),isPolicyEnabled:this.isPolicyEnabled.bind(this),loadAccountRecoveryPolicy:this.loadAccountRecoveryPolicy.bind(this),reloadAccountRecoveryPolicy:this.reloadAccountRecoveryPolicy.bind(this),isReady:this.isReady.bind(this)}}async loadAccountRecoveryPolicy(){this.state.isDataLoaded||await this.findAccountRecoveryPolicy()}async reloadAccountRecoveryPolicy(){await this.findAccountRecoveryPolicy()}async findAccountRecoveryPolicy(){if(!this.props.context.siteSettings.canIUse("accountRecovery"))return;const e=this.props.context.loggedInUser;if(!e)return;const t=await this.props.accountRecoveryUserService.getOrganizationAccountRecoverySettings(),a=e.account_recovery_user_setting?.status||Be.STATUS_PENDING;this.setState({accountRecoveryOrganizationPolicy:t,status:a,isDataLoaded:!0})}isReady(){return this.state.isDataLoaded}getOrganizationPolicy(){return this.state.accountRecoveryOrganizationPolicy}getRequestedDate(){return this.getOrganizationPolicy()?.modified}getRequestor(){return this.getOrganizationPolicy()?.creator}getPolicy(){return this.getOrganizationPolicy()?.policy}getUserAccountRecoverySubscriptionStatus(){return this.state.status}setUserAccountRecoveryStatus(e){this.setState({status:e})}isAccountRecoveryChoiceRequired(){if(null===this.getOrganizationPolicy())return!1;const e=this.getPolicy();return this.state.status===Be.STATUS_PENDING&&e!==Be.POLICY_DISABLED}isPolicyEnabled(){const e=this.getPolicy();return e&&e!==Be.POLICY_DISABLED}static get STATUS_PENDING(){return"pending"}static get POLICY_DISABLED(){return"disabled"}static get POLICY_MANDATORY(){return"mandatory"}static get POLICY_OPT_OUT(){return"opt-out"}static get STATUS_APPROVED(){return"approved"}render(){return n.createElement(Ge.Provider,{value:this.state},this.props.children)}}Be.propTypes={context:i().any.isRequired,children:i().any,accountRecoveryUserService:i().object.isRequired};const We=N(Be);function He(e){return class extends n.Component{render(){return n.createElement(Ge.Consumer,null,t=>n.createElement(e,Ve({accountRecoveryContext:t},this.props)))}}}var $e,Ye,Ze;function Je(){return Je=Object.assign?Object.assign.bind():function(e){for(var t=1;t-1?"firefox":e.indexOf("samsungbrowser")>-1?"samsung":e.indexOf("opera")>-1||e.indexOf("opr")>-1?"opera":e.indexOf("trident")>-1?"internet-explorer":e.indexOf("edg")>-1?"edge":e.indexOf("chrome")>-1?"chrome":e.indexOf("safari")>-1?at:"unknown",t}()===at}shouldDisplayDefaultAvatar(){if(this.isRunningUnderSafari())return!0;const e=Boolean(this.getAvatarSrc());return this.state.error||!this.props.user||this.isDefaultAvatarUrlFromApi()||!e}getAvatarSrc(){return this.propsHasUrl()?this.propsUrlHasProtocol()?this.avatarUrl:this.formatUrl(this.avatarUrl):null}handleError(){console.error(`Could not load avatar image url: ${this.getAvatarSrc()}`),this.setState({error:!0})}handleLoaded(){this.setState({isLoading:!1})}getAltText(){const e=this.props?.user;return e?.first_name&&e?.last_name?this.props.t("Avatar of user {{first_name}} {{last_name}}.",{firstname:e.first_name,lastname:e.last_name}):"..."}render(){const e=this.shouldDisplayDefaultAvatar();return n.createElement("div",{className:`${this.props.className}`},n.createElement("div",{className:"default-avatar"},(e||this.state.isLoading)&&n.createElement(Xe,null),!e&&n.createElement("img",{src:this.getAvatarSrc(),className:this.state.isLoading?"is-loading":"",onError:this.handleError,onLoad:this.handleLoaded,alt:this.getAltText()})),this.props.attentionRequired&&n.createElement(tt,{className:"attention-required"}))}}st.defaultProps={className:"avatar user-avatar"},st.propTypes={baseUrl:i().string,user:i().object,attentionRequired:i().bool,className:i().string,t:i().func};const it=(0,f.CI)("common")(st);class rt extends Error{constructor(e,t){super(e),this.name="PassboltApiFetchError",this.data=t||{}}}const ot=rt;class lt extends Error{constructor(){super("An internal error occurred. The server response could not be parsed. Please contact your administrator."),this.name="PassboltBadResponseError"}}const ct=lt;class mt extends Error{constructor(e){super(e=e||"The service is unavailable"),this.name="PassboltServiceUnavailableError"}}const dt=mt,ut=["GET","POST","PUT","DELETE"];class pt{constructor(e){if(this.options=e,!this.options.getBaseUrl())throw new TypeError("ApiClient constructor error: baseUrl is required.");if(!this.options.getResourceName())throw new TypeError("ApiClient constructor error: resourceName is required.");try{let e=this.options.getBaseUrl().toString();e.endsWith("/")&&(e=e.slice(0,-1));let t=this.options.getResourceName();t.startsWith("/")&&(t=t.slice(1)),t.endsWith("/")&&(t=t.slice(0,-1)),this.baseUrl=`${e}/${t}`,this.baseUrl=new URL(this.baseUrl)}catch(e){throw new TypeError("ApiClient constructor error: b.",{cause:e})}this.apiVersion="api-version=v2"}getDefaultHeaders(){return{Accept:"application/json","content-type":"application/json"}}async buildFetchOptions(){const e=await this.options.getHeaders();return{credentials:"include",headers:{...this.getDefaultHeaders(),...e}}}async get(e,t){this.assertValidId(e);const a=this.buildUrl(`${this.baseUrl}/${e}`,t||{});return this.fetchAndHandleResponse("GET",a)}async delete(e,t,a,n){let s;this.assertValidId(e),void 0===n&&(n=!1),s=n?this.buildUrl(`${this.baseUrl}/${e}/dry-run`,a||{}):this.buildUrl(`${this.baseUrl}/${e}`,a||{});let i=null;return t&&(i=this.buildBody(t)),this.fetchAndHandleResponse("DELETE",s,i)}async findAll(e){const t=this.buildUrl(this.baseUrl.toString(),e||{});return this.fetchAndHandleResponse("GET",t)}async create(e,t){const a=this.buildUrl(this.baseUrl.toString(),t||{}),n=this.buildBody(e);return this.fetchAndHandleResponse("POST",a,n)}async update(e,t,a,n){let s;this.assertValidId(e),void 0===n&&(n=!1),s=n?this.buildUrl(`${this.baseUrl}/${e}/dry-run`,a||{}):this.buildUrl(`${this.baseUrl}/${e}`,a||{});let i=null;return t&&(i=this.buildBody(t)),this.fetchAndHandleResponse("PUT",s,i)}async updateAll(e,t={}){const a=this.buildUrl(this.baseUrl.toString(),t),n=e?this.buildBody(e):null;return this.fetchAndHandleResponse("PUT",a,n)}assertValidId(e){if(!e)throw new TypeError("ApiClient.assertValidId error: id cannot be empty");if("string"!=typeof e)throw new TypeError("ApiClient.assertValidId error: id should be a string")}assertMethod(e){if("string"!=typeof e)throw new TypeError("ApiClient.assertValidMethod method should be a string.");if(ut.indexOf(e.toUpperCase())<0)throw new TypeError(`ApiClient.assertValidMethod error: method ${e} is not supported.`)}assertUrl(e){if(!e)throw new TypeError("ApliClient.assertUrl error: url is required.");if(!(e instanceof URL))throw new TypeError("ApliClient.assertUrl error: url should be a valid URL object.");if("https:"!==e.protocol&&"http:"!==e.protocol)throw new TypeError("ApliClient.assertUrl error: url protocol should only be https or http.")}assertBody(e){if(!(e instanceof FormData)&&"string"!=typeof e)throw new TypeError("ApiClient.assertBody error: body should be a string or a FormData.")}buildBody(e){return JSON.stringify(e)}buildUrl(e,t){if("string"!=typeof e)throw new TypeError("ApiClient.buildUrl error: url should be a string.");const a=new URL(`${e}.json?${this.apiVersion}`);t=t||{};for(const[e,n]of Object.entries(t)){if("string"!=typeof e)throw new TypeError("ApiClient.buildUrl error: urlOptions key should be a string.");if("string"==typeof n)a.searchParams.append(e,n);else{if(!Array.isArray(n))throw new TypeError("ApiClient.buildUrl error: urlOptions value should be a string or array.");n.forEach(t=>{a.searchParams.append(e,t)})}}return a}async sendRequest(e,t,a,n){this.assertUrl(t),this.assertMethod(e),a&&this.assertBody(a);const s="undefined"!=typeof customApiClientFetch?customApiClientFetch:fetch,i={...await this.buildFetchOptions(),...n};i.method=e,a&&(i.body=a);try{return await s(t.toString(),i)}catch(e){throw console.error(e),navigator.onLine?new dt("Unable to reach the server, an unexpected error occurred"):new dt("Unable to reach the server, you are not connected to the network")}}async fetchAndHandleResponse(e,t,a,n){const s=await this.sendRequest(e,t,a,n);return this.parseResponseJson(s)}async parseResponseJson(e){let t;try{t=await e.json()}catch(t){throw console.debug(e.url.toString(),t),new ct(t,e)}if(!e.ok){const a=t.header.message;throw new ot(a,{code:e.status,body:t.body})}return t}}const ht=class{constructor(e){e.setResourceName("mfa-policies/settings"),this.apiClient=new pt(e)}async find(){return(await this.apiClient.findAll()).body}async save(e){await this.apiClient.create(e)}},gt=class{constructor(e){this.apiClientOptions=e}async findAllSettings(){return this.initClient(),(await this.apiClient.findAll()).body}async save(e){return this.initClient(),(await this.apiClient.create(e)).body}async getUserSettings(){return this.initClient("setup/select"),(await this.apiClient.findAll()).body}initClient(e="settings"){this.apiClientOptions.setResourceName(`mfa/${e}`),this.apiClient=new pt(this.apiClientOptions)}};function yt(){return yt=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},getMfaOrganisationSettings:()=>{},getMfaUserSettings:()=>{},findPolicy:()=>{},setProcessing:()=>{},isProcessing:()=>{},clearContext:()=>{},isMfaChoiceRequired:()=>{},checkMfaChoiceRequired:()=>{},hasMfaUserSettings:()=>{},navigate:()=>{},setProvider:()=>{},goToProviderList:()=>{},validateTotpCode:()=>{},removeProvider:()=>{},validateYubikeyCode:()=>{}});class Et extends n.Component{constructor(e){super(e),this.state=this.defaultState}get defaultState(){return{state:bt,setup:null,policy:null,provider:null,processing:!0,mfaUserSettings:null,mfaOrganisationSettings:null,mfaChoiceRequired:!1,getPolicy:this.getPolicy.bind(this),getMfaOrganisationSettings:this.getMfaOrganisationSettings.bind(this),getMfaUserSettings:this.getMfaUserSettings.bind(this),findPolicy:this.findPolicy.bind(this),findMfaSettings:this.findMfaSettings.bind(this),isProcessing:this.isProcessing.bind(this),setProcessing:this.setProcessing.bind(this),hasMfaOrganisationSettings:this.hasMfaOrganisationSettings.bind(this),hasMfaUserSettings:this.hasMfaUserSettings.bind(this),clearContext:this.clearContext.bind(this),checkMfaChoiceRequired:this.checkMfaChoiceRequired.bind(this),isMfaChoiceRequired:this.isMfaChoiceRequired.bind(this),navigate:this.navigate.bind(this),setProvider:this.setProvider.bind(this),goToProviderList:this.goToProviderList.bind(this),validateTotpCode:this.validateTotpCode.bind(this),removeProvider:this.removeProvider.bind(this),validateYubikeyCode:this.validateYubikeyCode.bind(this),handleGetStartedWithDuo:this.handleGetStartedWithDuo.bind(this)}}async findPolicy(){const{policy:e}=this.state;if(null!==e)return e;let t;if(this.setProcessing(!0),this.props.context.port)t=await this.props.context.port.request("passbolt.mfa-policy.get-policy");else{const e=new ht(this.props.context.getApiClientOptions());t=await e.find()}const a=t?t.policy:null;return this.setState({policy:a}),this.setProcessing(!1),a}async findMfaSettings(){let e;if(this.setProcessing(!0),this.props.context.port)e=await this.props.context.port.request("passbolt.mfa-policy.get-mfa-settings");else{const t=new gt(this.props.context.getApiClientOptions());e=await t.getUserSettings()}const t=e.MfaAccountSettings,a=e.MfaOrganizationSettings;return this.setState({mfaUserSettings:t,mfaOrganisationSettings:a}),this.setProcessing(!1),{mfaUserSettings:t,mfaOrganisationSettings:a}}getPolicy(){return this.state.policy}getMfaOrganisationSettings(){return this.state.mfaOrganisationSettings}getMfaUserSettings(){return this.state.mfaUserSettings}hasMfaOrganisationSettings(){return this.state.mfaOrganisationSettings&&Object.values(this.state.mfaOrganisationSettings).some(e=>e)}hasMfaUserSettings(){return this.state.mfaUserSettings&&Object.values(this.state.mfaUserSettings).some(e=>e)}isProcessing(){return this.state.processing}setProcessing(e){this.setState({processing:e})}clearContext(){const{policy:e,processing:t}=this.defaultState;this.setState({policy:e,processing:t})}async checkMfaChoiceRequired(){const e=await this.findPolicy();if(null===e||"mandatory"!==e)return!1;const{mfaUserSettings:t,mfaOrganisationSettings:a}=await this.findMfaSettings(),n=a&&Object.values(a).some(e=>e),s=t&&Object.values(t).some(e=>e);this.setState({mfaChoiceRequired:n&&!s})}isMfaChoiceRequired(){return this.state.mfaChoiceRequired}navigate(e){this.setState({state:e})}goToProviderList(){this.setState({state:bt,provider:null})}setProvider(e){this.setState({provider:e})}async validateTotpCode(e,t){try{this.setProcessing(!0),await this.props.context.port.request("passbolt.mfa-setup.verify-totp-code",{otpProvisioningUri:e,totp:t})}catch(e){throw console.error(e),e}finally{this.setProcessing(!1)}}async validateYubikeyCode(e){try{this.setProcessing(!0),await this.props.context.port.request("passbolt.mfa-setup.verify-yubikey-code",{hotp:e})}catch(e){throw console.error(e),e}finally{this.setProcessing(!1)}}async removeProvider(){try{this.setProcessing(!0),await this.props.context.port.request("passbolt.mfa-setup.remove-provider",{provider:this.state.provider})}catch(e){throw console.error(e),e}finally{this.setProcessing(!1)}}async handleGetStartedWithDuo(){await this.props.context.port.request("passbolt.mfa-setup.start-with-duo")}render(){return n.createElement(ft.Provider,{value:this.state},this.props.children)}}Et.propTypes={context:i().any,children:i().any};const vt=N(Et);var wt,kt,_t;function xt(){return xt=Object.assign?Object.assign.bind():function(e){for(var t=1;tn.createElement(e,yt({mfaContext:t},this.props)))}}}((0,f.CI)("common")(Yt)))))));class Jt extends he{static getSchema(){return{type:"object",required:["enabled"],properties:{enabled:{type:"boolean"}}}}static createFromDefault(e={}){const t={enabled:!1,...e};return new Jt(t)}get enabled(){return this._props.enabled}}var Xt=a(3050),Qt=a.n(Xt);const ea=/^[a-f0-9]{8}-[a-f0-9]{4}-[0-5][a-f0-9]{3}-[089ab][a-f0-9]{3}-[a-f0-9]{12}$/i,ta=e=>new(Qt())(ea).test(e),aa=(e,t="The given parameter is not a valid number")=>{if(void 0!==e&&"number"!=typeof e)throw new TypeError(t)},na="desc",sa=class{constructor(e,t){e.setResourceName(t),this.apiClient=new pt(e)}formatContainOptions(e,t){const a={};for(const n in e){if("string"!=typeof n){const t=JSON.stringify(e);throw new TypeError(`Invalid contain ${t}, items should be a string.`)}t.includes(n)&&(a[`contain[${n}]`]=e[n]?"1":"0")}return a}formatFilterOptions(e,t){const a={};for(const n in e)if(Object.prototype.hasOwnProperty.call(e,n)&&t.includes(n))if("boolean"==typeof e[n])a[`filter[${n}]`]=e[n]?"1":"0";else if("string"==typeof e[n])a[`filter[${n}]`]=e[n];else{if(!Array.isArray(e[n]))throw new TypeError("Service error. Filter option should be an array or a string.");a[`filter[${n}][]`]=e[n]}return a}formatOrderOptions(e,t){const a={};for(const n in e)t.includes(n)&&(a["order[]"]=n);return a}formatPageOptions(e,t){const a={};if(e.limit){if(aa(e.limit),e.limit<1)throw new Error("The 'limit' parameter must be an integer greater than or equal to 1");a.limit=e.limit.toString()}if(e.page&&a.limit){if(aa(e.page),e.page<1)throw new Error("The 'page' parameter must be an integer greater than or equal to 1");a.page=e.page.toString()}return e.sorts&&Object.keys(e.sorts).forEach(n=>{if(!t.includes(n))return;const s=e.sorts[n]===na?na:"asc";a[`sort[${n}]`]=s}),a}assertValidId(e){if(!e||"string"!=typeof e||!ee().isUUID(e))throw new TypeError(`Service error. The id '${e}' is not a valid uuid.`)}assertNonEmptyData(e){if(!e)throw new TypeError("Service error. Data cannot be empty.")}},ia=class extends he{static getSchema(){return{type:"object",required:["count","limit","page"],properties:{count:{type:"integer",minimum:0},limit:{type:"integer",minimum:0,nullable:!0},page:{type:"integer",minimum:0}}}}get count(){return this._props.count}get limit(){return this._props.limit}get page(){return this._props.page}get pageCount(){const e=parseInt(this._props.count,10),t=parseInt(this._props.limit,10);return Math.ceil(e/t)}},ra=class extends he{constructor(e,t={}){super(e,t),this._props.pagination&&(this._pagination=new ia(this._props.pagination,t),delete this._props.pagination)}static getSchema(){return{type:"object",required:[],properties:{pagination:{type:"object"}}}}get pagination(){return this._pagination||null}toDto(){const e=Object.assign({},this._props);return this._pagination&&(e.pagination=this._pagination.toDto()),e}},oa=class extends he{constructor(e,t={}){super(e,t),this._props.header&&(this._header=new ra(this._props.header,t),delete this._props.header)}static getSchema(){return{type:"object",required:["header","body"],properties:{header:{type:"object"},body:{anyOf:[{type:"string"},{type:"object"}],nullable:!0}}}}get header(){return this._header}get body(){return this._props.body}};class la extends sa{constructor(e){super(e,"metadata/settings/")}async get(){const e=await this.apiClient.get("getting-started");return new oa(e)}}class ca{constructor(e){this.metadataGettingStartedSettingsApiService=new la(e)}async findGettingStartedSettings(){try{const e=await this.metadataGettingStartedSettingsApiService.get();return new Jt(e.body)}catch(e){return console.error(e),Jt.createFromDefault()}}}class ma{constructor(e){this.port=e}async enableEncryptedMetadata(){await this.port.request("passbolt.metadata.enable-encrypted-metadata-for-existing-instance")}async keepLegacyClearTextMetadata(){await this.port.request("passbolt.metadata.keep-cleartext-metadata-for-existing-instance")}async findGettingStartedSettings(){const e=await this.port.request("passbolt.metadata.find-getting-started-settings");return new Jt(e)}}function da(){return da=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},metadataGettingStartedSettings:null,update:()=>{}});class pa extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.runningUpdatePromise=null}get defaultState(){return{get:this.get.bind(this),metadataGettingStartedSettings:null,update:this.update.bind(this)}}set(e){this.setState({metadataGettingStartedSettings:e})}get(){return null===this.state.metadataGettingStartedSettings?(this.update(),null):this.state.metadataGettingStartedSettings}async update(){if(null===this.runningUpdatePromise){this.runningUpdatePromise=this.props.service.findGettingStartedSettings();const e=await this.runningUpdatePromise;this.set(e),this.runningUpdatePromise=null}else await this.runningUpdatePromise}render(){return n.createElement(ua.Provider,{value:this.state},this.props.children)}}pa.propTypes={service:i().oneOfType([i().instanceOf(ca),i().instanceOf(ma)]),children:i().any};const ha=pa;function ga(e){return class extends n.Component{render(){return n.createElement(ua.Consumer,null,t=>n.createElement(e,da({administrationEncryptedMetadataGettingStartedContext:t,metadataGettingStartedSettings:t.get()},this.props)))}}}var ya,ba;function fa(){return fa=Object.assign?Object.assign.bind():function(e){for(var t=1;tthis.handleSubmenuClick("isContentTypesOpened")},this.state.isContentTypesOpened?n.createElement(Vt,null):n.createElement(Wt,null),n.createElement("span",null,n.createElement(f.x6,null,"Resource types")))))),this.state.isContentTypesOpened&&n.createElement("ul",{id:"administration-sub-menu-content-type",className:"menu"},this.shouldShowGettingStartedMenu&&n.createElement("li",{id:"metadata_getting_started_menu"},n.createElement("div",{className:"row "+(this.isMetadataGettingStartedSelected()?"selected":"")},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:this.handleMetadataGettingStartedClick},n.createElement("span",null,n.createElement(f.x6,null,"Getting started")),n.createElement("span",{className:"chips new"},"new")))))),!this.shouldShowGettingStartedMenu&&n.createElement(n.Fragment,null,n.createElement("li",{id:"metadata_key_menu"},n.createElement("div",{className:"row "+(this.isContentTypesMetadataKeySelected()?"selected":"")},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:this.handleContentTypesMetadataKeyClick},n.createElement("span",null,n.createElement(f.x6,null,"Metadata key")),this.isBeta("metadata")&&n.createElement("span",{className:"chips beta"},"beta")))))),n.createElement("li",{id:"encrypted_metadata_menu"},n.createElement("div",{className:"row "+(this.isContentTypesEncryptedMetadataSelected()?"selected":"")},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:this.handleContentTypesEncryptedMetadataClick},n.createElement("span",null,n.createElement(f.x6,null,"Encrypted metadata")),this.isBeta("metadata")&&n.createElement("span",{className:"chips beta"},"beta")))))),n.createElement("li",{id:"migrate_metadata_menu"},n.createElement("div",{className:"row "+(this.isMigrateMetadataSelected()?"selected":"")},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:this.handleMigrateMetadataClick},n.createElement("span",null,n.createElement(f.x6,null,"Migrate metadata")),this.isBeta("metadata")&&n.createElement("span",{className:"chips beta"},"beta")))))),n.createElement("li",{id:"allowed_content_type_menu"},n.createElement("div",{className:"row "+(this.isAllowedContentTypesSelected()?"selected":"")},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:this.handleAllowedContentTypesClick},n.createElement("span",null,n.createElement(f.x6,null,"Allow content types")),this.isBeta("metadata")&&n.createElement("span",{className:"chips beta"},"beta"))))))))),this.canSeeResourceConfiguration()&&n.createElement("li",{id:"password-configuration",className:"accordion-header"},n.createElement("div",{className:"row"},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:()=>this.handleSubmenuClick("isResourceConfigurationOpened")},this.state.isResourceConfigurationOpened?n.createElement(Vt,null):n.createElement(Wt,null),n.createElement("span",null,n.createElement(f.x6,null,"Resource policies")))))),this.state.isResourceConfigurationOpened&&n.createElement("ul",null,this.canIUsePasswordExpiry&&n.createElement("li",{id:"password_expiry_menu"},n.createElement("div",{className:"row "+(this.isPasswordExpirySettingsSelected()?"selected":"")},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:this.handlePasswordExpirySettingsClick},n.createElement("span",null,n.createElement(f.x6,null,"Password Expiry"))))))),this.canIUsePasswordPolicies&&n.createElement("li",{id:"password_policy_menu"},n.createElement("div",{className:"row "+(this.isPasswordPoliciesSelected()?"selected":"")},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:this.handlePasswordPoliciesClick},n.createElement("span",null,n.createElement(f.x6,null,"Password Policy")),this.isCommunityEdition()&&n.createElement(Ea,{className:"pro-teasing-icon"})))))),this.canIUseSecretHistory&&n.createElement("li",{id:"secret_history_menu"},n.createElement("div",{className:"row "+(this.isSecretHistorySelected()?"selected":"")},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:this.handleSecretHistoryClick},n.createElement("span",null,n.createElement(f.x6,null,"Secret history")),this.isBeta("secretRevisions")&&n.createElement("span",{className:"chips beta"},"beta")))))))),this.canSeeAuthentication()&&n.createElement("li",{id:"authentication",className:"accordion-header"},n.createElement("div",{className:"row"},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:()=>this.handleSubmenuClick("isAuthenticationOpened")},this.state.isAuthenticationOpened?n.createElement(Vt,null):n.createElement(Wt,null),n.createElement("span",null,n.createElement(f.x6,null,"Authentication")))))),this.state.isAuthenticationOpened&&n.createElement("ul",null,this.canIUseUserPassphrasePolicies&&n.createElement("li",{id:"user_passphrase_policies_menu"},n.createElement("div",{className:"row "+(this.isUserPassphrasePoliciesSelected()?"selected":"")},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:this.handleUserPassphrasePoliciesClick},n.createElement("span",null,n.createElement(f.x6,null,"User Passphrase Policies")),this.isCommunityEdition()&&n.createElement(Ea,{className:"pro-teasing-icon"})))))),this.canIUseAccountRecovery&&n.createElement("li",{id:"account_recovery_menu"},n.createElement("div",{className:"row "+(this.isAccountRecoverySelected()?"selected":"")},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:this.handleAccountRecoveryClick},n.createElement("span",null,n.createElement(f.x6,null,"Account Recovery")),this.isCommunityEdition()&&n.createElement(Ea,{className:"pro-teasing-icon"})))))),this.canIUseSso&&n.createElement("li",{id:"sso_menu"},n.createElement("div",{className:"row "+(this.isSsoSelected()?"selected":"")},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:this.handleSsoClick},n.createElement("span",null,n.createElement(f.x6,null,"Single Sign-On")),this.isCommunityEdition()&&n.createElement(Ea,{className:"pro-teasing-icon"})))))),this.canIUseMfaPolicy&&n.createElement("li",{id:"mfa_policy_menu"},n.createElement("div",{className:"row "+(this.isMfaPolicySelected()?"selected":"")},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:this.handleMfaPolicyClick},n.createElement("span",null,n.createElement(f.x6,null,"MFA Policy")),this.isCommunityEdition()&&n.createElement(Ea,{className:"pro-teasing-icon"})))))),this.isMfaEnabled&&n.createElement("li",{id:"mfa_menu"},n.createElement("div",{className:"row "+(this.isMfaSelected()?"selected":"")},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:this.handleMfaClick},n.createElement("span",null,n.createElement(f.x6,null,"Multi Factor Authentication"))))))))),this.canSeeUserProvisionning()&&n.createElement("li",{id:"user-provisionning",className:"accordion-header"},n.createElement("div",{className:"row"},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:()=>this.handleSubmenuClick("isUserProvisionningOpened")},this.state.isUserProvisionningOpened?n.createElement(Vt,null):n.createElement(Wt,null),n.createElement("span",null,n.createElement(f.x6,null,"User provisionning")))))),this.state.isUserProvisionningOpened&&n.createElement("ul",null,this.canIUseScim&&n.createElement("li",{id:"scim_menu"},n.createElement("div",{className:"row "+(this.isScimSelected()?"selected":"")},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:this.handleScimClick},n.createElement("span",null,n.createElement(f.x6,null,"SCIM")),this.isBeta("scim")&&n.createElement("span",{className:"chips beta"},"beta"),this.isCommunityEdition()&&n.createElement(Ea,{className:"pro-teasing-icon"})))))),this.isUserDirectoryEnabled&&n.createElement("li",{id:"user_directory_menu"},n.createElement("div",{className:"row "+(this.isUserDirectorySelected()?"selected":"")},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:this.handleUserDirectoryClick},n.createElement("span",null,n.createElement(f.x6,null,"Users Directory")),this.isCommunityEdition()&&n.createElement(Ea,{className:"pro-teasing-icon"})))))),this.canIUseSelfRegistrationSettings&&n.createElement("li",{id:"self_registration_menu"},n.createElement("div",{className:"row "+(this.isSelfRegistrationSettingsSelected()?"selected":"")},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:this.handleSelfRegistrationClick},n.createElement("span",null,n.createElement(f.x6,null,"Self Registration"))))))))),n.createElement("li",{id:"emails",className:"accordion-header"},n.createElement("div",{className:"row"},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:()=>this.handleSubmenuClick("isEmailsOpened")},this.state.isEmailsOpened?n.createElement(Vt,null):n.createElement(Wt,null),n.createElement("span",null,n.createElement(f.x6,null,"Emails")))))),this.state.isEmailsOpened&&n.createElement("ul",null,this.canIUseSmtpSettings&&n.createElement("li",{id:"smtp_settings_menu"},n.createElement("div",{className:"row "+(this.isSmtpSettingsSelected()?"selected":"")},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:this.handleSmtpSettingsClick},n.createElement("span",null,n.createElement(f.x6,null,"Email server"))))))),n.createElement("li",{id:"email_notification_menu"},n.createElement("div",{className:"row "+(this.isEmailNotificationsSelected()?"selected":"")},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:this.handleEmailNotificationsClick},n.createElement("span",null,n.createElement(f.x6,null,"Email Notifications"))))))))),this.canIUseRbacs&&n.createElement("li",{id:"rbacs_menu"},n.createElement("div",{className:"row "+(this.isRbacSelected()?"selected":"")},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:this.handleRbacsClick},n.createElement("span",null,n.createElement(f.x6,null,"Role-Based Access Control"))))))),this.canIUseLocale&&n.createElement("li",{id:"internationalization_menu"},n.createElement("div",{className:"row "+(this.isInternationalizationSelected()?"selected":"")},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:this.handleInternationalizationClick},n.createElement("span",null,n.createElement(f.x6,null,"Internationalisation"))))))),this.canIUseHealthcheck&&n.createElement("li",{id:"healthcheck_menu"},n.createElement("div",{className:"row "+(this.isHealthcheckSelected()?"selected":"")},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:this.handleHealthcheckClick},n.createElement("span",null,n.createElement(f.x6,null,"Passbolt API Status"))))))))))}}va.propTypes={context:i().object,administrationWorkspaceContext:i().object,history:i().object,navigationContext:i().any,metadataGettingStartedSettings:i().instanceOf(Jt)};const wa=(0,x.withRouter)(N(Ke(Ne(ga((0,f.CI)("common")(va))))));var ka,_a;function xa(){return xa=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},getSettings:()=>{},setSettings:()=>{},hasSettingsChanges:()=>{},findMfaSettings:()=>{},save:()=>{},setProcessing:()=>{},isProcessing:()=>{},getErrors:()=>{},setError:()=>{},isSubmitted:()=>{},setSubmitted:()=>{},setErrors:()=>{},clearContext:()=>{}});class Ma extends n.Component{constructor(e){super(e),this.state=this.defaultState;const t=e.context.getApiClientOptions();this.mfaService=new gt(t)}get defaultState(){return{errors:this.initErrors(),currentSettings:null,settings:new Aa,submitted:!1,processing:!0,getCurrentSettings:this.getCurrentSettings.bind(this),getSettings:this.getSettings.bind(this),setSettings:this.setSettings.bind(this),findMfaSettings:this.findMfaSettings.bind(this),hasSettingsChanges:this.hasSettingsChanges.bind(this),isProcessing:this.isProcessing.bind(this),isSubmitted:this.isSubmitted.bind(this),setSubmitted:this.setSubmitted.bind(this),setProcessing:this.setProcessing.bind(this),save:this.save.bind(this),getErrors:this.getErrors.bind(this),setError:this.setError.bind(this),setErrors:this.setErrors.bind(this),clearContext:this.clearContext.bind(this)}}initErrors(){return{yubikeyClientIdentifierError:null,yubikeySecretKeyError:null,duoHostnameError:null,duoClientIdError:null,duoClientSecretError:null}}async findMfaSettings(){this.setProcessing(!0);const e=await this.mfaService.findAllSettings(),t=new Aa(e);this.setState({currentSettings:t}),this.setState({settings:Object.assign({},t)}),this.setProcessing(!1)}getCurrentSettings(){return this.state.currentSettings}getSettings(){return this.state.settings}setSettings(e,t){const a=Object.assign({},this.state.settings,{[e]:t});this.setState({settings:a})}isProcessing(){return this.state.processing}setProcessing(e){this.setState({processing:e})}hasSettingsChanges(){return JSON.stringify(this.state.currentSettings)!==JSON.stringify(this.state.settings)}isSubmitted(){return this.state.submitted}setSubmitted(e){this.setState({submitted:e})}clearContext(){const{currentSettings:e,settings:t,processing:a}=this.defaultState;this.setState({currentSettings:e,settings:t,processing:a})}async save(){this.setProcessing(!0);const e=new Pa(this.state.settings);await this.mfaService.save(e),await this.findMfaSettings()}getErrors(){return this.state.errors}setError(e,t){const a=Object.assign({},this.state.errors,{[e]:t});this.setState({errors:a})}setErrors(e,t=()=>{}){const a=Object.assign({},this.state.errors,e);this.setState({errors:a},t)}render(){return n.createElement(Oa.Provider,{value:this.state},this.props.children)}}Ma.propTypes={context:i().any,children:i().any};const Ua=N(Ma);function Fa(e){return class extends n.Component{render(){return n.createElement(Oa.Consumer,null,t=>n.createElement(e,Da({adminMfaContext:t},this.props)))}}}class ja{constructor(e,t){this.context=e,this.translation=t}static getInstance(e,t){return this.instance||(this.instance=new ja(e,t)),this.instance}static killInstance(){this.instance=null}validateInput(e,t,a){const n=e.trim();return n.length?Qt()(t).test(n)?null:this.translation(a.regex):this.translation(a.required)}validateYubikeyClientIdentifier(e){const t=this.validateInput(e,"^[0-9]{1,64}$",{required:"A client identifier is required.",regex:"The client identifier should be an integer."});return this.context.setError("yubikeyClientIdentifierError",t),t}validateYubikeySecretKey(e){const t=this.validateInput(e,"^[a-zA-Z0-9\\/=+]{10,128}$",{required:"A secret key is required.",regex:"This secret key is not valid."});return this.context.setError("yubikeySecretKeyError",t),t}validateDuoHostname(e){const t=this.validateInput(e,"^api-[a-fA-F0-9]{8,16}\\.duosecurity\\.com$",{required:"A hostname is required.",regex:"This is not a valid hostname."});return this.context.setError("duoHostnameError",t),t}validateDuoClientId(e){const t=this.validateInput(e,"^[a-zA-Z0-9]{16,32}$",{required:"A client id is required.",regex:"This is not a valid client id."});return this.context.setError("duoClientIdError",t),t}validateDuoClientSecret(e){const t=this.validateInput(e,"^[a-zA-Z0-9]{32,128}$",{required:"A client secret is required.",regex:"This is not a valid client secret."});return this.context.setError("duoClientSecretError",t),t}validateYubikeyInputs(){let e=null,t=null;const a=this.context.getSettings();let n={};return a.yubikeyToggle&&(e=this.validateYubikeyClientIdentifier(a.yubikeyClientIdentifier),t=this.validateYubikeySecretKey(a.yubikeySecretKey),n={yubikeyClientIdentifierError:e,yubikeySecretKeyError:t}),n}validateDuoInputs(){let e=null,t=null,a=null,n={};const s=this.context.getSettings();return s.duoToggle&&(e=this.validateDuoHostname(s.duoHostname),t=this.validateDuoClientId(s.duoClientId),a=this.validateDuoClientSecret(s.duoClientSecret),n={duoHostnameError:e,duoClientIdError:t,duoClientSecretError:a}),n}async validate(){const e=Object.assign(this.validateYubikeyInputs(),this.validateDuoInputs());return await this.context.setErrors(e),0===Object.values(e).filter(e=>e).length}}const La=ja;class qa extends n.Component{constructor(e){super(e),this.bindCallbacks(),this.mfaFormService=La.getInstance(this.props.adminMfaContext,this.props.t)}async handleSaveClick(){try{await this.mfaFormService.validate()&&(await this.props.adminMfaContext.save(),this.handleSaveSuccess())}catch(e){this.handleSaveError(e)}finally{this.props.adminMfaContext.setSubmitted(!0),this.props.adminMfaContext.setProcessing(!1)}}isSaveEnabled(){return!this.props.adminMfaContext.isProcessing()&&this.props.adminMfaContext.hasSettingsChanges()}bindCallbacks(){this.handleSaveClick=this.handleSaveClick.bind(this)}async handleSaveSuccess(){await this.props.actionFeedbackContext.displaySuccess(this.props.t("The multi factor authentication settings for the organization were updated."))}async handleSaveError(e){"UserAbortsOperationError"!==e.name&&(console.error(e),await this.handleError(e))}async handleError(e){await this.props.actionFeedbackContext.displayError(e.message)}render(){return n.createElement("div",{className:"actions-wrapper"},n.createElement("button",{id:"save-settings",className:"button primary form",type:"button",disabled:!this.isSaveEnabled(),onClick:this.handleSaveClick},n.createElement("span",null,n.createElement(f.x6,null,"Save"))))}}qa.propTypes={adminMfaContext:i().object,actionFeedbackContext:i().object,t:i().func};const za=Fa(m((0,f.CI)("common")(qa)));var Ka,Va;function Ga(){return Ga=Object.assign?Object.assign.bind():function(e){for(var t=1;t>16&255)+.587*(a>>8&255)+.114*(255&a))/255>.5?"var(--Token-Token-text-and-icon)":"var(--Token-Token-text-and-icon-reversed)"}handleMouseDown(){this.setState({isPassphraseActive:!0})}handleMouseUp(){this.setState({isPassphraseActive:!1})}render(){return n.createElement("div",{className:`input password ${this.props.disabled?"disabled":""} ${this.state.hasPassphraseFocus?"":"no-focus"} ${this.state.isPassphraseActive?"active":""} ${this.props.securityToken?"security":""}`,style:this.props.securityToken?this.passphraseInputStyle:void 0},n.createElement("input",{id:this.props.id,name:this.props.name,maxLength:this.props.maxLength,placeholder:this.props.placeholder,type:this.state.viewPassword&&!this.props.disabled?"text":"password",onKeyUp:this.props.onKeyUp,value:this.props.value,onFocus:this.handlePasswordInputFocus,onBlur:this.handlePasswordInputBlur,onChange:this.handleInputChange,disabled:this.props.disabled,readOnly:this.props.readOnly,autoComplete:this.props.autoComplete,onMouseDown:this.handleMouseDown,onMouseUp:this.handleMouseUp,"aria-required":!0,ref:this.props.inputRef}),this.props.preview&&n.createElement("div",{className:"password-view-wrapper"},n.createElement("button",{type:"button",onClick:this.handleViewPasswordButtonClick,style:this.props.securityToken?this.previewStyle:void 0,className:"password-view infield button-transparent "+(this.props.disabled?"disabled":"")},!this.state.viewPassword&&n.createElement(Ba,{className:"svg-icon eye-open"}),this.state.viewPassword&&n.createElement($a,{className:"svg-icon eye-close"}),n.createElement("span",{className:"visually-hidden"},n.createElement(f.x6,null,"View")))),this.props.securityToken&&n.createElement("div",{className:"security-token-wrapper"},n.createElement("span",{className:"security-token",style:this.securityTokenStyle},this.props.securityToken.code)))}}Ya.defaultProps={id:"",name:"",autoComplete:"off",maxLength:4096},Ya.propTypes={context:i().any,id:i().string,name:i().string,value:i().string,placeholder:i().string,autoComplete:i().string,inputRef:i().object,disabled:i().bool,readOnly:i().bool,preview:i().bool,onChange:i().func,onKeyUp:i().func,securityToken:i().shape({code:i().string,backgroundColor:i().string,textColor:i().string}),maxLength:i().number};const Za=(0,f.CI)("common")(Ya);var Ja=a(961);function Xa(e,t,a){return n.createElement(n.Fragment,null,t&&(0,Ja.createPortal)(e,t,a))}class Qa extends n.Component{constructor(e){super(e),this.mfaFormService=La.getInstance(this.props.adminMfaContext,this.props.t),this.bindCallbacks()}async componentDidMount(){this.props.administrationWorkspaceContext.setDisplayAdministrationWorkspaceAction(za),this.isRunningUnderHttps&&this.props.adminMfaContext.findMfaSettings()}componentWillUnmount(){this.props.administrationWorkspaceContext.resetDisplayAdministrationWorkspaceAction(),this.props.adminMfaContext.clearContext(),La.killInstance(),this.mfaFormService=null}bindCallbacks(){this.handleInputChange=this.handleInputChange.bind(this)}handleInputChange(e){const t=e.target,a="checkbox"===t.type?t.checked:t.value,n=t.name;this.props.adminMfaContext.setSettings(n,a),this.validateInput(n,a)}validateInput(e,t){switch(e){case"yubikeyClientIdentifier":this.mfaFormService.validateYubikeyClientIdentifier(t);break;case"yubikeySecretKey":this.mfaFormService.validateYubikeySecretKey(t);break;case"duoHostname":this.mfaFormService.validateDuoHostname(t);break;case"duoClientId":this.mfaFormService.validateDuoClientId(t);break;case"duoClientSecret":this.mfaFormService.validateDuoClientSecret(t)}}get isRunningUnderHttps(){const e=this.props.context.trustedDomain;return"https:"===new URL(e).protocol}hasAllInputDisabled(){return this.props.adminMfaContext.isProcessing()}render(){const e=this.props.adminMfaContext.isSubmitted(),t=this.props.adminMfaContext.getSettings(),a=this.props.adminMfaContext.getErrors(),s=null!==this.props.adminMfaContext.getCurrentSettings()&&this.props.adminMfaContext.hasSettingsChanges();return n.createElement("div",{className:"row"},n.createElement("div",{className:"mfa-settings main-column"},n.createElement("div",{className:"main-content"},n.createElement("h3",{className:"title"},"Multi Factor Authentication"),!this.isRunningUnderHttps&&n.createElement("p",null,n.createElement(f.x6,null,"Sorry the multi factor authentication feature is only available in a secure context (HTTPS).")),this.isRunningUnderHttps&&n.createElement(n.Fragment,null,n.createElement("p",null,n.createElement(f.x6,null,"In this section you can choose which multi factor authentication will be available.")),n.createElement("div",{className:"provider-section"},n.createElement("h4",{className:"no-border"},n.createElement("span",{className:"input toggle-switch form-element ready"},n.createElement("input",{id:"totp-provider-toggle-button",type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"totpProviderToggle",onChange:this.handleInputChange,checked:t.totpProviderToggle,disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"totp-provider-toggle-button"},n.createElement(f.x6,null,"Time-based One Time Password")))),!t.totpProviderToggle&&n.createElement("p",{className:"description"},n.createElement(f.x6,null,"The Time-based One Time Password provider is disabled for all users.")),t.totpProviderToggle&&n.createElement("p",{className:"description"},n.createElement(f.x6,null,"The Time-based One Time Password provider is enabled for all users. They can setup this provider in their profile and use it as second factor authentication."))),n.createElement("div",{className:"provider-section"},n.createElement("h4",null,n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{id:"yubikey-provider-toggle-button",type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"yubikeyToggle",onChange:this.handleInputChange,checked:t.yubikeyToggle,disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"yubikey-provider-toggle-button"},"Yubikey"))),!t.yubikeyToggle&&n.createElement("p",{className:"description"},n.createElement(f.x6,null,"The Yubikey provider is disabled for all users.")),t.yubikeyToggle&&n.createElement(n.Fragment,null,n.createElement("p",{className:"description"},n.createElement(f.x6,null,"The Yubikey provider is enabled for all users. They can setup this provider in their profile and use it as second factor authentication.")),n.createElement("div",{className:`input text required yubikey ${a.yubikeyClientIdentifierError&&e?"error":""} ${this.hasAllInputDisabled()?"disabled":""}`},n.createElement("label",null,n.createElement(f.x6,null,"Client identifier")),n.createElement("input",{id:"yubikeyClientIdentifier",name:"yubikeyClientIdentifier",className:"required fluid form-element ready",type:"text","aria-required":!0,onChange:this.handleInputChange,value:t.yubikeyClientIdentifier,placeholder:"123456789",disabled:this.hasAllInputDisabled()}),a.yubikeyClientIdentifierError&&e&&n.createElement("div",{className:"yubikey_client_identifier error-message"},a.yubikeyClientIdentifierError)),n.createElement("div",{className:`input required input-secret ${a.yubikeySecretKeyError&&e?"error":""} ${this.hasAllInputDisabled()?"disabled":""}`},n.createElement("label",null,n.createElement(f.x6,null,"Secret key")),n.createElement(Za,{id:"yubikeySecretKey",onChange:this.handleInputChange,autoComplete:"off",name:"yubikeySecretKey",placeholder:"**********",disabled:this.hasAllInputDisabled(),value:t.yubikeySecretKey,preview:!0}),a.yubikeySecretKeyError&&e&&n.createElement("div",{className:"yubikey_secret_key error-message"},a.yubikeySecretKeyError)))),n.createElement("div",{className:"provider-section"},n.createElement("h4",null,n.createElement("span",{className:"input toggle-switch form-element ready"},n.createElement("input",{id:"duo-provider-toggle-button",type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"duoToggle",onChange:this.handleInputChange,checked:t.duoToggle,disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"duo-provider-toggle-button"},"Duo"))),!t.duoToggle&&n.createElement("p",{className:"description"},n.createElement(f.x6,null,"The Duo provider is disabled for all users.")),t.duoToggle&&n.createElement(n.Fragment,null,n.createElement("p",{className:"description enabled"},n.createElement(f.x6,null,"The Duo provider is enabled for all users. They can setup this provider in their profile and use it as second factor authentication.")),n.createElement("div",{className:`input text required ${a.duoHostnameError&&e?"error":""} ${this.hasAllInputDisabled()?"disabled":""}`},n.createElement("label",null,n.createElement(f.x6,null,"Hostname")),n.createElement("input",{id:"duoHostname",type:"text",name:"duoHostname","aria-required":!0,className:"required fluid form-element ready",placeholder:"api-24zlkn4.duosecurity.com",value:t.duoHostname,onChange:this.handleInputChange,disabled:this.hasAllInputDisabled()}),a.duoHostnameError&&e&&n.createElement("div",{className:"duo_hostname error-message"},a.duoHostnameError)),n.createElement("div",{className:`input text required ${a.duoClientIdError&&e?"error":""} ${this.hasAllInputDisabled()?"disabled":""}`},n.createElement("label",null,n.createElement(f.x6,null,"Client id")),n.createElement("input",{id:"duoClientId",type:"text",name:"duoClientId","aria-required":!0,className:"required fluid form-element ready",placeholder:"HASJKDSQJO213123KQSLDF",value:t.duoClientId,onChange:this.handleInputChange,disabled:this.hasAllInputDisabled()}),a.duoClientIdError&&e&&n.createElement("div",{className:"duo_client_id error-message"},a.duoClientIdError)),n.createElement("div",{className:`input text required ${a.duoClientSecretError&&e?"error":""} ${this.hasAllInputDisabled()?"disabled":""}`},n.createElement("label",null,n.createElement(f.x6,null,"Client secret")),n.createElement(Za,{id:"duoClientSecret",onChange:this.handleInputChange,autoComplete:"off",name:"duoClientSecret",placeholder:"**********",disabled:this.hasAllInputDisabled(),value:t.duoClientSecret,preview:!0}),a.duoClientSecretError&&e&&n.createElement("div",{className:"duo_client_secret error-message"},a.duoClientSecretError)))))),s&&n.createElement("div",{className:"warning message"},n.createElement("div",null,n.createElement("p",null,n.createElement(f.x6,null,"Don't forget to save your settings to apply your modification."))))),n.createElement(za,null),Xa(n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"Need some help?")),n.createElement("p",null,n.createElement(f.x6,null,"Check out our Multi Factor Authentication configuration guide.")),n.createElement("a",{className:"button",href:"https://passbolt.com/docs/admin/authentication/mfa/",target:"_blank",rel:"noopener noreferrer"},n.createElement(Sa,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}Qa.propTypes={context:i().object,adminMfaContext:i().object,createPortal:i().func,administrationWorkspaceContext:i().object,t:i().func};const en=N(Fa(Ne((0,f.CI)("common")(Qa))));class tn extends n.Component{render(){let e=0;return n.createElement("div",{className:"breadcrumbs"},n.createElement("ul",{className:"menu"},this.props.items&&this.props.items.map(t=>(e++,n.createElement("li",{key:e},t)))),this.props.children)}}tn.propTypes={items:i().array,children:i().any};const an=tn;class nn extends n.Component{render(){return n.createElement("button",{type:"button",className:"link no-border inline ellipsis",onClick:this.props.onClick},this.props.name)}}nn.propTypes={name:i().string,onClick:i().func};const sn=nn;class rn extends n.Component{get items(){switch(this.props.administrationWorkspaceContext.selectedAdministration){case Te.NONE:return[];case Te.HOME:return[n.createElement(sn,{key:"bread-2",name:this.translate("Home"),onClick:this.onLastBreadcrumbClick.bind(this)})];default:return[n.createElement(sn,{key:"bread-3",name:this.translate("Home"),onClick:this.props.navigationContext.onGoToAdministrationRequested}),n.createElement(sn,{key:"bread-2",name:this.getLastBreadcrumbItemName(),onClick:this.onLastBreadcrumbClick.bind(this)})]}}getLastBreadcrumbItemName(){switch(this.props.administrationWorkspaceContext.selectedAdministration){case Te.MFA:return this.translate("Multi Factor Authentication");case Te.USER_DIRECTORY:return this.translate("Users Directory");case Te.EMAIL_NOTIFICATION:return this.translate("Email Notification");case Te.SUBSCRIPTION:return this.translate("Subscription");case Te.INTERNATIONALIZATION:return this.translate("Internationalisation");case Te.ACCOUNT_RECOVERY:return this.translate("Account Recovery");case Te.SMTP_SETTINGS:return this.translate("Email server");case Te.SELF_REGISTRATION:return this.translate("Self Registration");case Te.SSO:return this.translate("Single Sign-On");case Te.MFA_POLICY:return this.translate("MFA Policy");case Te.RBAC:return this.translate("Role-Based Access Control");case Te.PASSWORD_POLICIES:return this.translate("Password Policy");case Te.USER_PASSPHRASE_POLICIES:return this.translate("User Passphrase Policies");case Te.PASSWORD_EXPIRY:return this.translate("Password Expiry");case Te.HEALTHCHECK:return this.translate("Passbolt API Status");case Te.CONTENT_TYPES_ENCRYPTED_METADATA:return this.translate("Encrypted metadata");case Te.CONTENT_TYPES_METADATA_KEY:return this.translate("Metadata key");case Te.MIGRATE_METADATA:return this.translate("Migrate metadata");case Te.ALLOW_CONTENT_TYPES:return this.translate("Allow content types");case Te.METADATA_GETTING_STARTED:return this.translate("Getting started");case Te.SCIM:return this.translate("SCIM");case Te.SECRET_HISTORY:return this.translate("Secret history");default:return""}}async onLastBreadcrumbClick(){const e=this.props.location.pathname;this.props.history.push({pathname:e})}get translate(){return this.props.t}render(){return n.createElement(an,{items:this.items})}}rn.propTypes={administrationWorkspaceContext:i().object,location:i().object,history:i().object,navigationContext:i().any,t:i().func};const on=(0,x.withRouter)(Ke(Ne((0,f.CI)("common")(rn)))),ln=new class{allPropTypes=(...e)=>(...t)=>{const a=e.map(e=>e(...t)).filter(Boolean);if(0===a.length)return;const n=a.map(e=>e.message).join("\n");return new Error(n)}};var cn;function mn(){return mn=Object.assign?Object.assign.bind():function(e){for(var t=1;te.value!==this.state.selectedValue);return this.props.search&&""!==this.state.search?this.getItemsMatch(e,this.state.search):e}get selectedItemLabel(){const e=this.props.items&&this.props.items.find(e=>e.value===this.state.selectedValue);return e&&e.label||n.createElement(n.Fragment,null," ")}static getDerivedStateFromProps(e,t){return void 0!==e.value&&e.value!==t.selectedValue?{selectedValue:e.value}:null}bindCallback(){this.handleDocumentClickEvent=this.handleDocumentClickEvent.bind(this),this.handleDocumentContextualMenuEvent=this.handleDocumentContextualMenuEvent.bind(this),this.handleDocumentDragStartEvent=this.handleDocumentDragStartEvent.bind(this),this.handleDocumentScrollEvent=this.handleDocumentScrollEvent.bind(this),this.handleSelectClick=this.handleSelectClick.bind(this),this.handleInputChange=this.handleInputChange.bind(this),this.handleItemClick=this.handleItemClick.bind(this),this.handleSelectKeyDown=this.handleSelectKeyDown.bind(this),this.handleItemKeyDown=this.handleItemKeyDown.bind(this),this.handleBlur=this.handleBlur.bind(this)}createRefs(){this.selectedItemRef=n.createRef(),this.selectItemsRef=n.createRef(),this.itemsRef=n.createRef()}componentDidMount(){document.addEventListener("click",this.handleDocumentClickEvent,{capture:!0}),document.addEventListener("contextmenu",this.handleDocumentContextualMenuEvent,{capture:!0}),document.addEventListener("dragstart",this.handleDocumentDragStartEvent,{capture:!0}),document.addEventListener("scroll",this.handleDocumentScrollEvent,{capture:!0})}componentWillUnmount(){document.removeEventListener("click",this.handleDocumentClickEvent,{capture:!0}),document.removeEventListener("contextmenu",this.handleDocumentContextualMenuEvent,{capture:!0}),document.removeEventListener("dragstart",this.handleDocumentDragStartEvent,{capture:!0}),document.removeEventListener("scroll",this.handleDocumentScrollEvent,{capture:!0})}handleDocumentClickEvent(e){this.selectedItemRef.current.contains(e.target)||this.selectItemsRef.current.contains(e.target)||this.closeSelect()}handleDocumentContextualMenuEvent(e){this.selectedItemRef.current.contains(e.target)||this.selectItemsRef.current.contains(e.target)||this.closeSelect()}handleDocumentDragStartEvent(){this.closeSelect()}handleDocumentScrollEvent(e){this.itemsRef.current.contains(e.target)||this.selectItemsRef.current.contains(e.target)||this.closeSelect()}handleSelectClick(){if(this.props.disabled)this.closeSelect();else{const e=!this.state.open;e?this.forceVisibilitySelect():this.resetStyleSelect(),this.setState({open:e})}}getFirstParentWithTransform(){let e=this.selectedItemRef.current.parentElement;for(;null!==e&&""===e.style.getPropertyValue("transform");)e=e.parentElement;return e}forceVisibilitySelect(){const e=this.selectedItemRef.current.getBoundingClientRect(),{width:t,height:a}=e;let{top:n,left:s}=e;const i=this.getFirstParentWithTransform();if(i){const e=i.getBoundingClientRect();n-=e.top,s-=e.left}const r={position:"fixed",zIndex:1,width:t,height:a,top:n,left:s};this.setState({style:r})}handleBlur(e){e.currentTarget.contains(e.relatedTarget)||this.closeSelect()}closeSelect(){this.resetStyleSelect(),this.setState({open:!1})}resetStyleSelect(){this.setState({style:void 0})}handleInputChange(e){const t=e.target,a=t.value,n=t.name;this.setState({[n]:a})}handleItemClick(e){if(this.setState({selectedValue:e.value,open:!1}),"function"==typeof this.props.onChange){const t={target:{value:e.value,name:this.props.name}};this.props.onChange(t)}this.closeSelect()}getItemsMatch(e,t){const a=t&&t.split(/\s+/)||[""];return e.filter(e=>a.every(t=>((e,t)=>(e=>new RegExp((e=>e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"))(e),"i"))(e).test(t))(t,e.label)))}handleSelectKeyDown(e){switch(e.keyCode){case 13:return e.stopPropagation(),void this.handleSelectClick();case 40:return e.preventDefault(),e.stopPropagation(),void(this.state.open?this.focusItem(0):this.handleSelectClick());case 38:return e.preventDefault(),e.stopPropagation(),void(this.state.open?this.focusItem(this.listItemsFiltered.length-1):this.handleSelectClick());case 27:return e.stopPropagation(),void this.closeSelect();default:return}}focusItem(e){this.itemsRef.current.childNodes[e]?.focus()}handleItemKeyDown(e,t){switch(e.keyCode){case 13:return e.stopPropagation(),void this.handleItemClick(t);case 40:return e.stopPropagation(),e.preventDefault(),void(e.target.nextSibling?e.target.nextSibling.focus():this.focusItem(0));case 38:return e.stopPropagation(),e.preventDefault(),void(e.target.previousSibling?e.target.previousSibling.focus():this.focusItem(this.listItemsFiltered.length-1));default:return}}hasFilteredItems(){return this.listItemsFiltered.length>0}render(){return n.createElement("div",{className:`select-container ${this.props.className}`,style:{width:this.state.style?.width,height:this.state.style?.height}},n.createElement("div",{onKeyDown:this.handleSelectKeyDown,onBlur:this.handleBlur,id:this.props.id,className:`select ${this.props.direction} ${this.state.open?"open":""}`,style:this.state.style},n.createElement("div",{ref:this.selectedItemRef,className:"selected-value "+(this.props.disabled?"disabled":""),tabIndex:this.props.disabled?-1:0,onClick:this.handleSelectClick},n.createElement("span",{className:"value"},this.selectedItemLabel),n.createElement(Vt,null)),n.createElement("div",{ref:this.selectItemsRef,className:"select-items "+(this.state.open?"visible":"")},this.props.search&&n.createElement(n.Fragment,null,n.createElement("input",{className:"search-input",name:"search",value:this.state.search,onChange:this.handleInputChange,type:"text"}),n.createElement(dn,{className:"search"})),n.createElement("ul",{ref:this.itemsRef,className:"items"},this.hasFilteredItems()&&this.listItemsFiltered.map(e=>n.createElement("li",{tabIndex:e.disabled?-1:0,key:e.value,title:e.title,className:`option ${e.value}`,onKeyDown:t=>this.handleItemKeyDown(t,e),onClick:()=>this.handleItemClick(e)},e.label)),!this.hasFilteredItems()&&this.props.search&&n.createElement("li",{className:"option no-results"},n.createElement(f.x6,null,"No results match")," ",n.createElement("span",null,this.state.search))))))}}un.defaultProps={id:"",name:"select",className:"",direction:"bottom"},un.propTypes={id:i().string,name:i().string,className:i().string,direction:i().oneOf(Object.values({top:"top",bottom:"bottom",left:"left",right:"right"})),search:i().bool,items:i().array,value:ln.allPropTypes(i().oneOfType([i().string,i().number,i().bool]),(e,t,a)=>{const n=e[t],s=e.items;if(null!==n&&s.length>0&&s.every(e=>e.value!==n))return new Error(`Invalid prop ${t} passed to ${a}. Expected the value ${n} in items.`)}),disabled:i().bool,onChange:i().func};const pn=(0,f.CI)("common")(un);class hn extends n.Component{constructor(e){super(e),this.bindCallbacks()}bindCallbacks(){this.handleClick=this.handleClick.bind(this)}handleClick(){this.props.disabled||this.props.onClick()}render(){return n.createElement("button",{type:"button",disabled:this.props.disabled,className:"link cancel",onClick:this.handleClick},this.props.value)}}hn.defaultProps={value:n.createElement(f.x6,null,"Cancel")},hn.propTypes={disabled:i().bool,onClick:i().func,value:i().oneOfType([i().arrayOf(i().node),i().node,i().string])};const gn=(0,f.CI)("common")(hn);var yn,bn;function fn(){return fn=Object.assign?Object.assign.bind():function(e){for(var t=1;t{const e=this.state.infiniteTimer+2;this.setState({infiniteTimer:e})},500)}calculateInfiniteProgress(){return 100-100/Math.pow(1.1,this.state.infiniteTimer)}handleClose(){this.props.onClose()}render(){const e=this.calculateInfiniteProgress(),t={width:`${e}%`};return n.createElement(qt,{className:"loading-dialog",title:this.props.title,onClose:this.handleClose,disabled:!0},n.createElement("div",{className:"form-content"},n.createElement("label",null,n.createElement(f.x6,null,"Take a deep breath and enjoy being in the present moment...")),n.createElement("div",{className:"progress-bar-wrapper"},n.createElement("span",{className:"progress-bar"},n.createElement("span",{className:"progress "+(100===e?"completed":""),style:t})))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement("button",{type:"submit",disabled:!0,className:"processing"},"Submit",n.createElement(En,null))))}}vn.propTypes={onClose:i().func,title:i().string};const wn=(0,f.CI)("common")(vn),kn="directorysync",_n=class{constructor(e){this.apiClientOptions=e,e.setResourceName(`${kn}`)}async findAll(){this.apiClientOptions.setResourceName(`${kn}/settings`);const e=new pt(this.apiClientOptions);return(await e.findAll()).body}async update(e){this.apiClientOptions.setResourceName(`${kn}`);const t=new pt(this.apiClientOptions);return(await t.update("settings",e)).body}async delete(){return this.apiClientOptions.setResourceName(`${kn}`),new pt(this.apiClientOptions).delete("settings")}async test(e){return this.apiClientOptions.setResourceName(`${kn}/settings/test`),new pt(this.apiClientOptions).create(e)}async simulate(){this.apiClientOptions.setResourceName(`${kn}`);const e=new pt(this.apiClientOptions);return(await e.get("synchronize/dry-run")).body}async synchronize(){this.apiClientOptions.setResourceName(`${kn}/synchronize`);const e=new pt(this.apiClientOptions);return(await e.create({})).body}};class xn extends sa{constructor(e){super(e,xn.RESOURCE_NAME)}static get RESOURCE_NAME(){return"users"}static getSupportedContainOptions(){return["LastLoggedIn","is_mfa_enabled","last_logged_in","gpgkey","groups_users","profile","role","account_recovery_user_setting","pending_account_recovery_request","missing_metadata_key_ids"]}static getSupportedFiltersOptions(){return["search","has-groups","has-access","is-admin","is-active","has-role-id"]}static getSupportedOrdersOptions(){return["Profile.first_name DESC","Profile.first_name ASC","Profile.last_name DESC","Profile.last_name ASC","Profile.created DESC","Profile.created ASC","Profile.modified DESC","Profile.modified ASC"]}async get(e,t){this.assertValidId(e),t=t?this.formatContainOptions(t,xn.getSupportedContainOptions()):null;const a={...t};return(await this.apiClient.get(e,a)).body}async findAll(e,t,a){const n=xn.remapToLegacyContain(e);e=e?this.formatContainOptions(n,xn.getSupportedContainOptions()):null,t=t?this.formatFilterOptions(t,xn.getSupportedFiltersOptions()):null,a=a?this.formatOrderOptions(a,xn.getSupportedOrdersOptions()):null;const s={...e,...t,...a},i=await this.apiClient.findAll(s);return new oa(i)}async findByRoleId(e){return this.assertValidId(e),this.findAll({},{"has-role-id":e})}static remapToLegacyContain(e){if(e)return Object.prototype.hasOwnProperty.call(e,"last_logged_in")&&(e.LastLoggedIn=e.last_logged_in,delete e.last_logged_in),e}async create(e){return this.assertNonEmptyData(e),(await this.apiClient.create(e)).body}async update(e,t){return this.assertValidId(e),this.assertNonEmptyData(t),(await this.apiClient.update(e,t)).body}async updateAvatar(e,t,a){this.assertValidId(e),this.assertNonEmptyData(t),this.assertNonEmptyData(a);const n=this.apiClient.buildUrl(`${this.apiClient.baseUrl}/${e}`),s=new FormData;s.append("profile[avatar][file]",t,a);const i=await this.apiClient.buildFetchOptions();return delete i.headers["content-type"],(await this.apiClient.fetchAndHandleResponse("POST",n,s,i)).body}async delete(e,t,a){this.assertValidId(e);const n=t?{transfer:t}:{};return(await this.apiClient.delete(e,n,{},a)).body}async resendInvite(e){const t=this.apiClient.buildUrl(`${this.apiClient.baseUrl}/recover`),a={username:e},n=this.apiClient.buildBody(a);return this.apiClient.fetchAndHandleResponse("POST",t,n)}async keepSessionAlive(){const e=this.apiClient.buildUrl(`${this.apiClient.baseUrl}/me`,{});return await this.apiClient.fetchAndHandleResponse("GET",e),!0}async requestHelpCredentialsLost(e){const t=this.apiClient.buildBody(e),a=this.apiClient.buildUrl(`${this.apiClient.baseUrl}/recover`,{});return(await this.apiClient.fetchAndHandleResponse("POST",a,t)).body}}const Sn=xn,Cn="mail",Nn="uniqueMember";class Tn{constructor(e=[],t=""){if(!e||0===e?.length)return void this.setDefaut(t);const a=e.domains?.org_domain;this.openCredentials=!0,this.openDirectoryConfiguration=!1,this.openSynchronizationOptions=!1,this.source=e.source,this.authenticationType=a?.authentication_type||"basic",this.directoryType=a?.directory_type||"ad",this.connectionType=a?.connection_type||"plain",this.host=a?.hosts?.length>0?a?.hosts[0]:"",this.hostError=null,this.port=a?.port?.toString()||"389",this.portError=null,this.username=a?.username||"",this.password=a?.password||"",this.domain=a?.domain_name||"",this.domainError=null,this.baseDn=a?.base_dn||"",this.groupPath=e.group_path||"",this.userPath=e.user_path||"",this.groupCustomFilters=e.group_custom_filters||"",this.userCustomFilters=e.user_custom_filters||"",this.groupObjectClass=e.group_object_class||"",this.userObjectClass=e.user_object_class||"",this.useEmailPrefix=e.use_email_prefix_suffix||!1,this.emailPrefix=e.email_prefix||"",this.emailSuffix=e.email_suffix||"",this.fieldsMapping=Tn.defaultFieldsMapping(e.fields_mapping),this.fallbackFields=Tn.defaultFallbackFields(e.field_fallbacks),this.defaultAdmin=e.default_user||t,this.defaultGroupAdmin=e.default_group_admin_user||t,this.groupsParentGroup=e.groups_parent_group||"",this.usersParentGroup=e.users_parent_group||"",this.enabledUsersOnly=Boolean(e.enabled_users_only),this.createUsers=Boolean(e.sync_users_create),this.deleteUsers=Boolean(e.sync_users_delete),this.updateUsers=Boolean(e.sync_users_update),this.createGroups=Boolean(e.sync_groups_create),this.deleteGroups=Boolean(e.sync_groups_delete),this.updateGroups=Boolean(e.sync_groups_update),this.deleteUserBehavior=e.delete_user_behavior||"delete",this.userDirectoryToggle=Boolean(this.port)&&Boolean(this.host)&&e?.enabled}setDefaut(e){this.openCredentials=!0,this.openDirectoryConfiguration=!1,this.openSynchronizationOptions=!1,this.source="default",this.authenticationType="basic",this.directoryType="ad",this.connectionType="plain",this.host="",this.hostError=null,this.port="389",this.portError=null,this.username="",this.password="",this.domain="",this.domainError=null,this.baseDn="",this.groupPath="",this.userPath="",this.groupCustomFilters="",this.userCustomFilters="",this.groupObjectClass="",this.userObjectClass="",this.useEmailPrefix=!1,this.emailPrefix="",this.emailSuffix="",this.fieldsMapping=Tn.defaultFieldsMapping(),this.fallbackFields=Tn.defaultFallbackFields(),this.defaultAdmin=e,this.defaultGroupAdmin=e,this.groupsParentGroup="",this.usersParentGroup="",this.enabledUsersOnly=!1,this.createUsers=!0,this.deleteUsers=!0,this.updateUsers=!0,this.createGroups=!0,this.deleteGroups=!0,this.updateGroups=!0,this.deleteUserBehavior="delete",this.userDirectoryToggle=!1}static defaultFieldsMapping(e={}){return{ad:{user:Object.assign({id:"objectGuid",firstname:"givenName",lastname:"sn",username:Cn,created:"whenCreated",modified:"whenChanged",groups:"memberOf",enabled:"userAccountControl"},e?.ad?.user),group:Object.assign({id:"objectGuid",name:"cn",created:"whenCreated",modified:"whenChanged",users:"member"},e?.ad?.group)},openldap:{user:Object.assign({id:"entryUuid",firstname:"givenname",lastname:"sn",username:"mail",created:"createtimestamp",modified:"modifytimestamp"},e?.openldap?.user),group:Object.assign({id:"entryUuid",name:"cn",created:"createtimestamp",modified:"modifytimestamp",users:Nn},e?.openldap?.group)}}}static defaultFallbackFields(e={}){return{ad:Object.assign({username:""},e?.ad)}}static get DEFAULT_AD_FIELDS_MAPPING_USER_USERNAME_VALUE(){return Cn}static get DEFAULT_OPENLDAP_FIELDS_MAPPING_GROUP_USERS_VALUE(){return Nn}}const An=Tn,In=class{constructor(e){const t=e.directoryType,a=!e.authenticationType||"basic"===e.authenticationType;this.enabled=e.userDirectoryToggle,this.group_path=e.groupPath,this.user_path=e.userPath,this.group_custom_filters=e.groupCustomFilters,this.user_custom_filters=e.userCustomFilters,this.group_object_class="openldap"===t?e.groupObjectClass:"",this.user_object_class="openldap"===t?e.userObjectClass:"",this.use_email_prefix_suffix="openldap"===t&&e.useEmailPrefix,this.email_prefix="openldap"===t&&this.useEmailPrefix?e.emailPrefix:"",this.email_suffix="openldap"===t&&this.useEmailPrefix?e.emailSuffix:"",this.default_user=e.defaultAdmin,this.default_group_admin_user=e.defaultGroupAdmin,this.groups_parent_group=e.groupsParentGroup,this.users_parent_group=e.usersParentGroup,this.enabled_users_only=e.enabledUsersOnly,this.sync_users_create=e.createUsers,this.sync_users_delete=e.deleteUsers,this.sync_users_update=e.updateUsers,this.sync_groups_create=e.createGroups,this.sync_groups_delete=e.deleteGroups,this.sync_groups_update=e.updateGroups,this.fields_mapping=e.fieldsMapping,this.field_fallbacks=e.fallbackFields,this.delete_user_behavior=e.deleteUserBehavior,this.domains={org_domain:{connection_type:e.connectionType,authentication_type:e.authenticationType,directory_type:t,domain_name:e.domain,username:a?e.username:void 0,password:a?e.password:void 0,base_dn:e.baseDn,hosts:[e.host],port:parseInt(e.port,10)}}}};function Rn(){return Rn=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},getSettings:()=>{},setSettings:()=>{},setAdUserFieldsMappingSettings:()=>{},setOpenLdapGroupFieldsMappingSettings:()=>{},setAdFallbackFieldsSettings:()=>{},hadDisabledSettings:()=>{},getUsers:()=>{},hasSettingsChanges:()=>{},findUserDirectorySettings:()=>{},save:()=>{},delete:()=>{},test:()=>{},setProcessing:()=>{},isProcessing:()=>{},getErrors:()=>{},setError:()=>{},simulateUsers:()=>{},requestSynchronization:()=>{},mustOpenSynchronizePopUp:()=>{},synchronizeUsers:()=>{},isSubmitted:()=>{},setSubmitted:()=>{},setErrors:()=>{},clearContext:()=>{}});class On extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.userDirectoryService=new _n(e.context.getApiClientOptions()),this.userApiService=new Sn(e.context.getApiClientOptions())}get defaultState(){return{users:[],errors:this.initErrors(),mustSynchronize:!1,currentSettings:null,settings:new An,submitted:!1,processing:!0,getCurrentSettings:this.getCurrentSettings.bind(this),getSettings:this.getSettings.bind(this),setSettings:this.setSettings.bind(this),setAdUserFieldsMappingSettings:this.setAdUserFieldsMappingSettings.bind(this),setOpenLdapGroupFieldsMappingSettings:this.setOpenLdapGroupFieldsMappingSettings.bind(this),setAdFallbackFieldsSettings:this.setAdFallbackFieldsSettings.bind(this),hadDisabledSettings:this.hadDisabledSettings.bind(this),findUserDirectorySettings:this.findUserDirectorySettings.bind(this),hasSettingsChanges:this.hasSettingsChanges.bind(this),isProcessing:this.isProcessing.bind(this),isSubmitted:this.isSubmitted.bind(this),setSubmitted:this.setSubmitted.bind(this),setProcessing:this.setProcessing.bind(this),simulateUsers:this.simulateUsers.bind(this),synchronizeUsers:this.synchronizeUsers.bind(this),save:this.save.bind(this),delete:this.delete.bind(this),test:this.test.bind(this),getErrors:this.getErrors.bind(this),setError:this.setError.bind(this),setErrors:this.setErrors.bind(this),getUsers:this.getUsers.bind(this),requestSynchronization:this.requestSynchronization.bind(this),mustOpenSynchronizePopUp:this.mustOpenSynchronizePopUp.bind(this),clearContext:this.clearContext.bind(this)}}initErrors(){return{hostError:null,portError:null,domainError:null}}async findUserDirectorySettings(){this.setProcessing(!0);let e=[];try{e=await this.userDirectoryService.findAll()}catch(e){this.handleError(e)}const t=(await this.userApiService.findAll()).body,a=t.find(e=>this.props.context.loggedInUser.id===e.id),n=new An(e,a.id);this.setState({users:this.sortUsers(t),currentSettings:n,settings:Object.assign({},n),processing:!1})}sortUsers(e){const t=e=>`${e.profile.first_name} ${e.profile.last_name}`;return e.sort((e,a)=>t(e).localeCompare(t(a)))}getCurrentSettings(){return this.state.currentSettings}getSettings(){return this.state.settings}requestSynchronization(e){this.setState({mustSynchronize:e})}mustOpenSynchronizePopUp(){return this.state.mustSynchronize}setSettings(e,t){const a=Object.assign({},this.state.settings,{[e]:t});this.isAdFieldsMappingUserUsernameResetNeeded(e,t)&&(a.fieldsMapping.ad.user.username=An.DEFAULT_AD_FIELDS_MAPPING_USER_USERNAME_VALUE,this.setError("fieldsMappingAdUserUsernameError",null),this.setError("fieldsMappingAdUserUsernameFallbackeError",null)),this.isOpenLdapFieldsMappingGroupUsersResetNeeded(e,t)&&(a.fieldsMapping.openldap.group.users=An.DEFAULT_OPENLDAP_FIELDS_MAPPING_GROUP_USERS_VALUE,this.setError("fieldsMappingOpenLdapGroupUsersError",null)),this.setState({settings:a})}isAdFieldsMappingUserUsernameResetNeeded(e,t){return e===Pn&&"openldap"===t}isOpenLdapFieldsMappingGroupUsersResetNeeded(e,t){return e===Pn&&"ad"===t}setAdUserFieldsMappingSettings(e,t){const a=Object.assign({},this.state.settings);a.fieldsMapping.ad.user[e]=t,this.setState({settings:a})}setOpenLdapGroupFieldsMappingSettings(e,t){const a=Object.assign({},this.state.settings);a.fieldsMapping.openldap.group[e]=t,this.setState({settings:a})}setAdFallbackFieldsSettings(e,t){const a=Object.assign({},this.state.settings);a.fallbackFields.ad[e]=t,this.setState({settings:a})}hadDisabledSettings(){const e=this.getCurrentSettings();return Boolean(e?.port)&&Boolean(e?.host)&&!e?.userDirectoryToggle}isProcessing(){return this.state.processing}setProcessing(e){this.setState({processing:e})}hasSettingsChanges(){return JSON.stringify(this.state.currentSettings)!==JSON.stringify(this.state.settings)}isSubmitted(){return this.state.submitted}setSubmitted(e){this.setState({submitted:e})}clearContext(){const{currentSettings:e,settings:t,processing:a}=this.defaultState;this.setState({currentSettings:e,settings:t,processing:a})}async save(){this.setProcessing(!0);const e=new In(this.state.settings);await this.userDirectoryService.update(e),await this.findUserDirectorySettings()}async delete(){this.setProcessing(!0),await this.userDirectoryService.delete(),await this.findUserDirectorySettings()}async test(){this.setProcessing(!0);const e=new In(this.state.settings),t=await this.userDirectoryService.test(e);return this.setProcessing(!1),t}async simulateUsers(){return this.userDirectoryService.simulate()}async synchronizeUsers(){return this.userDirectoryService.synchronize()}getErrors(){return this.state.errors}setError(e,t){const a=Object.assign({},this.state.errors,{[e]:t});this.setState({errors:a})}getUsers(){return this.state.users}setErrors(e,t=()=>{}){const a=Object.assign({},this.state.errors,e);this.setState({errors:a},t)}handleError(e){const t={error:e};this.props.dialogContext.open($t,t)}render(){return n.createElement(Dn.Provider,{value:this.state},this.props.children)}}On.propTypes={context:i().any,children:i().any,dialogContext:i().object};const Mn=N(h(On));function Un(e){return class extends n.Component{render(){return n.createElement(Dn.Consumer,null,t=>n.createElement(e,Rn({adminUserDirectoryContext:t},this.props)))}}}var Fn=a(8140),jn=a.n(Fn);class Ln extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.bindEventHandlers()}get defaultState(){return{loading:!0,openFullReport:!1,userDirectorySimulateSynchronizeResult:null}}bindEventHandlers(){this.handleFullReportClicked=this.handleFullReportClicked.bind(this),this.handleClose=this.handleClose.bind(this),this.handleSynchronize=this.handleSynchronize.bind(this),this.handleDownloadFullReport=this.handleDownloadFullReport.bind(this)}async componentDidMount(){try{const e=await this.props.adminUserDirectoryContext.simulateUsers();this.setState({loading:!1,userDirectorySimulateSynchronizeResult:e})}catch(e){await this.handleError(e)}}async handleError(e){console.error(e),await this.props.actionFeedbackContext.displayError(e.message),this.handleClose()}handleFullReportClicked(){this.setState({openFullReport:!this.state.openFullReport})}handleClose(){this.props.onClose()}handleSynchronize(){this.props.adminUserDirectoryContext.requestSynchronization(!0),this.handleClose()}isLoading(){return this.state.loading}get users(){return this.state.userDirectorySimulateSynchronizeResult?.users}get groups(){return this.state.userDirectorySimulateSynchronizeResult?.groups}get usersSuccess(){return this.users.filter(e=>"success"===e.status)}get groupsSuccess(){return this.groups.filter(e=>"success"===e.status)}get usersWarning(){return this.users.filter(e=>"warning"===e.status)}get groupsWarning(){return this.groups.filter(e=>"warning"===e.status)}get usersError(){return this.users.filter(e=>"error"===e.status)}get groupsError(){return this.groups.filter(e=>"error"===e.status)}get usersIgnored(){return this.users.filter(e=>"ignore"===e.status)}get groupsIgnored(){return this.groups.filter(e=>"ignore"===e.status)}hasSuccessResource(){return this.usersSuccess.length>0||this.groupsSuccess.length>0}hasSuccessUserResource(){return this.usersSuccess.length>0}hasSuccessGroupResource(){return this.groupsSuccess.length>0}hasErrorOrIgnoreResource(){return this.usersError.length>0||this.groupsError.length>0||this.usersWarning.length>0||this.groupsWarning.length>0||this.usersIgnored.length>0||this.groupsIgnored.length>0}getFullReport(){let e="";return e=e.concat(this.getUsersFullReport()),e=e.concat(this.getGroupsFullReport()),e}handleDownloadFullReport(e,t){e.preventDefault();const a=`passbolt-user-directory-simulate-synchronization-report-${(new Date).toISOString().slice(0,19).replace("T","_").replace(/:/g,"-")}.txt`;jn()(t,a,"text/plain")}getUsersFullReport(){if(!(this.usersSuccess.length>0||this.usersWarning.length>0||this.usersError.length>0||this.usersIgnored.length>0))return"";let e="";const t=`-----------------------------------------------\n${this.props.t("Users")}\n-----------------------------------------------\n`;e=e.concat(t);const a=t=>e=e.concat(`- ${t.message}\n`);return this.usersSuccess.length>0&&(e=e.concat(`\n${this.props.t("Success:")}\n`),this.usersSuccess.map(a)),this.usersWarning.length>0&&(e=e.concat(`\n${this.props.t("Warning:")}\n`),this.usersWarning.map(a)),this.usersError.length>0&&(e=e.concat(`\n${this.props.t("Errors:")}\n`),this.usersError.map(a)),this.usersIgnored.length>0&&(e=e.concat(`\n${this.props.t("Ignored:")}\n`),this.usersIgnored.map(a)),e.concat("\n")}getGroupsFullReport(){if(!(this.groupsSuccess.length>0||this.groupsWarning.length>0||this.groupsError.length>0||this.groupsIgnored.length>0))return"";let e="";const t=`-----------------------------------------------\n${this.props.t("Groups")}\n-----------------------------------------------\n`;e=e.concat(t);const a=t=>e=e.concat(`- ${t.message}\n`);return this.groupsSuccess.length>0&&(e=e.concat(`\n${this.props.t("Success:")}\n`),this.groupsSuccess.map(a)),this.groupsWarning.length>0&&(e=e.concat(`\n${this.props.t("Warning:")}\n`),this.groupsWarning.map(a)),this.groupsError.length>0&&(e=e.concat(`\n${this.props.t("Errors:")}\n`),this.groupsError.map(a)),this.groupsIgnored.length>0&&(e=e.concat(`\n${this.props.t("Ignored:")}\n`),this.groupsIgnored.map(a)),e}get translate(){return this.props.t}render(){const e=this.users?String(this.getFullReport()):"";return n.createElement("div",null,this.isLoading()&&n.createElement(wn,{onClose:this.handleClose,title:this.props.t("Synchronize simulation")}),!this.isLoading()&&n.createElement(qt,{className:"ldap-simulate-synchronize-dialog",title:this.props.t("Synchronize simulation report"),onClose:this.handleClose,disabled:this.isLoading()},n.createElement("div",{className:"form-content",onSubmit:this.handleFormSubmit},n.createElement("p",null,n.createElement("strong",null,n.createElement(f.x6,null,"The operation was successful."))),e&&n.createElement(n.Fragment,null,this.hasSuccessResource()&&n.createElement("p",{id:"resources-synchronize"},this.hasSuccessUserResource()&&n.createElement(n.Fragment,null,this.props.t("{{count}} user will be synchronized.",{count:this.usersSuccess.length})),this.hasSuccessUserResource()&&this.hasSuccessGroupResource()&&n.createElement("br",null),this.hasSuccessGroupResource()&&n.createElement(n.Fragment,null,this.props.t("{{count}} group will be synchronized.",{count:this.groupsSuccess.length}))),!this.hasSuccessResource()&&n.createElement("p",{id:"no-resources"}," ",n.createElement(f.x6,null,"No resources will be synchronized.")," "),n.createElement("div",{className:"accordion operation-details "+(this.state.openFullReport?"":"closed")},n.createElement("div",{className:"accordion-header",onClick:this.handleFullReportClicked},n.createElement("button",{type:"button",className:"link no-border"},n.createElement("span",null,n.createElement(f.x6,null,"Full report")),this.state.openFullReport?n.createElement(Vt,{className:"baseline svg-icon"}):n.createElement(Wt,{className:"baseline svg-icon"}))),n.createElement("div",{className:"accordion-content"},n.createElement("div",{className:"input text"},n.createElement("textarea",{className:"full_report",readOnly:!0,value:e}))),n.createElement("button",{type:"button",className:"link download-full-report",onClick:t=>this.handleDownloadFullReport(t,e)},n.createElement(f.x6,null,"Download the Full Report")))),!e&&n.createElement("p",{id:"no-report-message"},n.createElement("span",null,n.createElement(f.x6,null,"There is nothing to synchronize"))),this.hasErrorOrIgnoreResource()&&n.createElement("div",{className:"warning message no-margin"},n.createElement("p",null,n.createElement(f.x6,null,"Some resources will not be synchronized and will require your attention, see the full report.")))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement("a",{className:"button",target:"_blank",rel:"noopener noreferrer",href:"https://www.passbolt.com/docs/admin/user-provisioning/users-directory/advanced-directory-options/"}," ",n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation"))),e&&n.createElement(n.Fragment,null,n.createElement(gn,{disabled:this.isLoading(),onClick:this.handleClose}),n.createElement("button",{type:"submit",disabled:this.isLoading(),className:"primary button form",onClick:this.handleSynchronize},n.createElement(f.x6,null,"Synchronize"))),!e&&n.createElement("button",{disabled:this.isLoading(),className:"primary button form",type:"button",onClick:this.handleClose},n.createElement(f.x6,null,"Ok")))))}}Ln.propTypes={onClose:i().func,dialogContext:i().object,actionFeedbackContext:i().any,adminUserDirectoryContext:i().object,t:i().func};const qn=m(Un((0,f.CI)("common")(Ln)));class zn extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.bindEventHandlers()}get defaultState(){return{loading:!0,openFullReport:!1,userDirectorySynchronizeResult:null}}bindEventHandlers(){this.handleFullReportClicked=this.handleFullReportClicked.bind(this),this.handleClose=this.handleClose.bind(this),this.handleSynchronize=this.handleSynchronize.bind(this),this.handleDownloadFullReport=this.handleDownloadFullReport.bind(this)}async componentDidMount(){try{const e=await this.props.adminUserDirectoryContext.synchronizeUsers();this.setState({loading:!1,userDirectorySynchronizeResult:e})}catch(e){await this.handleError(e)}}async handleError(e){console.error(e),await this.props.actionFeedbackContext.displayError(e.message),this.handleClose()}handleFullReportClicked(){this.setState({openFullReport:!this.state.openFullReport})}handleClose(){this.props.onClose()}handleSynchronize(){this.handleClose()}isLoading(){return this.state.loading}get users(){return this.state.userDirectorySynchronizeResult?.users}get groups(){return this.state.userDirectorySynchronizeResult?.groups}get usersSuccess(){return this.users.filter(e=>"success"===e.status)}get groupsSuccess(){return this.groups.filter(e=>"success"===e.status)}get usersWarning(){return this.users.filter(e=>"warning"===e.status)}get groupsWarning(){return this.groups.filter(e=>"warning"===e.status)}get usersError(){return this.users.filter(e=>"error"===e.status)}get groupsError(){return this.groups.filter(e=>"error"===e.status)}get usersIgnored(){return this.users.filter(e=>"ignore"===e.status)}get groupsIgnored(){return this.groups.filter(e=>"ignore"===e.status)}hasSuccessResource(){return this.usersSuccess.length>0||this.groupsSuccess.length>0}hasSuccessUserResource(){return this.usersSuccess.length>0}hasSuccessGroupResource(){return this.groupsSuccess.length>0}hasErrorOrIgnoreResource(){return this.usersError.length>0||this.groupsError.length>0||this.usersWarning.length>0||this.groupsWarning.length>0||this.usersIgnored.length>0||this.groupsIgnored.length>0}getFullReport(){let e="";return e=e.concat(this.getUsersFullReport()),e=e.concat(this.getGroupsFullReport()),e}handleDownloadFullReport(e,t){e.preventDefault();const a=`passbolt-user-directory-synchronization-report-${(new Date).toISOString().slice(0,19).replace("T","_").replace(/:/g,"-")}.txt`;jn()(t,a,"text/plain")}getUsersFullReport(){if(!(this.usersSuccess.length>0||this.usersWarning.length>0||this.usersError.length>0||this.usersIgnored.length>0))return"";let e="";const t=`-----------------------------------------------\n${this.translate("Users")}\n-----------------------------------------------\n`;e=e.concat(t);const a=t=>e=e.concat(`- ${t.message}\n`);return this.usersSuccess.length>0&&(e=e.concat(`\n${this.translate("Success:")}\n`),this.usersSuccess.map(a)),this.usersWarning.length>0&&(e=e.concat(`\n${this.translate("Warning:")}\n`),this.usersWarning.map(a)),this.usersError.length>0&&(e=e.concat(`\n${this.translate("Errors:")}\n`),this.usersError.map(a)),this.usersIgnored.length>0&&(e=e.concat(`\n${this.translate("Ignored:")}\n`),this.usersIgnored.map(a)),e.concat("\n")}getGroupsFullReport(){if(!(this.groupsSuccess.length>0||this.groupsWarning.length>0||this.groupsError.length>0||this.groupsIgnored.length>0))return"";let e="";const t=`-----------------------------------------------\n${this.translate("Groups")}\n-----------------------------------------------\n`;e=e.concat(t);const a=t=>e=e.concat(`- ${t.message}\n`);return this.groupsSuccess.length>0&&(e=e.concat(`\n${this.translate("Success:")}\n`),this.groupsSuccess.map(a)),this.groupsWarning.length>0&&(e=e.concat(`\n${this.translate("Warning:")}\n`),this.groupsWarning.map(a)),this.groupsError.length>0&&(e=e.concat(`\n${this.translate("Errors:")}\n`),this.groupsError.map(a)),this.groupsIgnored.length>0&&(e=e.concat(`\n${this.translate("Ignored:")}\n`),this.groupsIgnored.map(a)),e}get translate(){return this.props.t}render(){const e=this.users?String(this.getFullReport()):"";return n.createElement("div",null,this.isLoading()&&n.createElement(wn,{onClose:this.handleClose,title:this.translate("Synchronize")}),!this.isLoading()&&n.createElement(qt,{className:"ldap-simulate-synchronize-dialog",title:this.translate("Synchronize report"),onClose:this.handleClose,disabled:this.isLoading()},n.createElement("div",{className:"form-content",onSubmit:this.handleFormSubmit},n.createElement("p",null,n.createElement("strong",null,n.createElement(f.x6,null,"The operation was successful."))),e&&n.createElement(n.Fragment,null,this.hasSuccessResource()&&n.createElement("p",{id:"resources-synchronize"},this.hasSuccessUserResource()&&n.createElement(n.Fragment,null,this.translate("{{count}} user has been synchronized.",{count:this.usersSuccess.length})),this.hasSuccessUserResource()&&this.hasSuccessGroupResource()&&n.createElement("br",null),this.hasSuccessGroupResource()&&n.createElement(n.Fragment,null,this.translate("{{count}} group has been synchronized.",{count:this.groupsSuccess.length}))),!this.hasSuccessResource()&&n.createElement("p",{id:"no-resources"}," ",n.createElement(f.x6,null,"No resources have been synchronized.")," "),n.createElement("div",{className:"accordion operation-details "+(this.state.openFullReport?"":"closed")},n.createElement("div",{className:"accordion-header",onClick:this.handleFullReportClicked},n.createElement("button",{type:"button",className:"link no-border"},n.createElement("span",null,n.createElement(f.x6,null,"Full report")),this.state.openFullReport?n.createElement(Vt,{className:"baeline svg-icon"}):n.createElement(Wt,{className:"baeline svg-icon"}))),n.createElement("div",{className:"accordion-content"},n.createElement("div",{className:"input text"},n.createElement("textarea",{className:"full_report",readOnly:!0,value:e}))),n.createElement("button",{type:"button",className:"link download-full-report",onClick:t=>this.handleDownloadFullReport(t,e)},n.createElement(f.x6,null,"Download the Full Report")))),!e&&n.createElement("p",{id:"no-report-message"},n.createElement("span",null,n.createElement(f.x6,null,"There is nothing to synchronize"))),this.hasErrorOrIgnoreResource()&&n.createElement("div",{className:"warning message no-margin"},n.createElement("p",null,n.createElement(f.x6,null,"Some resources will not be synchronized and will require your attention, see the full report.")))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement("a",{className:"button",target:"_blank",rel:"noopener noreferrer",href:"https://www.passbolt.com/docs/admin/user-provisioning/users-directory/advanced-directory-options/"}," ",n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation"))),n.createElement("button",{disabled:this.isLoading(),className:"primary button form",type:"button",onClick:this.handleClose},n.createElement(f.x6,null,"Ok")))))}}zn.propTypes={onClose:i().func,actionFeedbackContext:i().any,adminUserDirectoryContext:i().object,t:i().func};const Kn=m(Un((0,f.CI)("common")(zn)));class Vn{constructor(e,t){this.context=e,this.translate=t}static getInstance(e,t){return this.instance||(this.instance=new Vn(e,t)),this.instance}static killInstance(){this.instance=null}validate(){const e={hostError:this.validateHostInput(),portError:this.validatePortInput(),domainError:this.validateDomainInput(),fieldsMappingAdUserUsernameError:this.validateFieldsMappingAdUserUsernameInput(),fieldsMappingOpenLdapGroupUsersError:this.validateOpenLdapFieldsMappingGroupUsersInput()};return this.context.setErrors(e),0===Object.values(e).filter(e=>null!==e).length}validateHostInput(){const e=this.context.getSettings(),t=e.host?.trim();return t.length?null:this.translate("A host is required.")}validatePortInput(){let e=null;const t=this.context.getSettings().port.trim();return t.length?Qt()("^[0-9]+").test(t)||(e=this.translate("Only numeric characters allowed.")):e=this.translate("A port is required."),e}validateFieldsMappingAdUserUsernameInput(){const e=this.context.getSettings().fieldsMapping.ad.user.username;let t=null;return e&&""!==e.trim()?e.length>128&&(t=this.translate("The user username field mapping cannot exceed 128 characters.")):t=this.translate("The user username field mapping cannot be empty"),t}validateOpenLdapFieldsMappingGroupUsersInput(){const e=this.context.getSettings().fieldsMapping.openldap.group.users;let t=null;return e&&""!==e.trim()?e.length>128&&(t=this.translate("The group users field mapping cannot exceed 128 characters.")):t=this.translate("The group users field mapping cannot be empty"),t}validateDomainInput(){let e=null;return this.context.getSettings().domain.trim().length||(e=this.translate("A domain name is required.")),e}}const Gn=Vn;class Bn extends n.Component{hasChildren(){return this.props.node.group.groups.length>0}displayUserName(e){return`${e.profile.first_name} ${e.profile.last_name}`}get node(){return this.props.node}render(){return n.createElement("ul",{key:this.node.id},"group"===this.node.type&&n.createElement("li",{className:"group"},this.node.group.name,n.createElement("ul",null,Object.values(this.node.group.users).map(e=>n.createElement("li",{className:"user",key:e.id},e.errors&&n.createElement("span",{className:"error"},e.directory_name),!e.errors&&n.createElement("span",null,this.displayUserName(e.user)," ",n.createElement("em",null,"(",e.user.username,")")))),Object.values(this.node.group.groups).map(e=>n.createElement(Bn,{key:`tree-${e.id}`,node:e})))),"user"===this.node.type&&n.createElement("li",{className:"user"},this.node.errors&&n.createElement("span",{className:"error"},this.node.directory_name),!this.node.errors&&n.createElement("span",null,this.displayUserName(this.node.user)," ",n.createElement("em",null,"(",this.node.user.username,")"))))}}Bn.propTypes={node:i().object};const Wn=Bn;class Hn extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.bindEventHandlers()}get defaultState(){return{loading:!0,openListGroupsUsers:!1,openStructureGroupsUsers:!1,openErrors:!1}}bindEventHandlers(){this.handleListGroupsUsersClicked=this.handleListGroupsUsersClicked.bind(this),this.handleStructureGroupsUsersClicked=this.handleStructureGroupsUsersClicked.bind(this),this.handleErrorsClicked=this.handleErrorsClicked.bind(this),this.handleClose=this.handleClose.bind(this)}componentDidMount(){this.setState({loading:!1})}handleListGroupsUsersClicked(){this.setState({openListGroupsUsers:!this.state.openListGroupsUsers})}handleStructureGroupsUsersClicked(){this.setState({openStructureGroupsUsers:!this.state.openStructureGroupsUsers})}handleErrorsClicked(){this.setState({openErrors:!this.state.openErrors})}handleClose(){this.props.onClose(),this.props.context.setContext({displayTestUserDirectoryDialogProps:null})}hasAllInputDisabled(){return this.state.loading}displayUserName(e){return`${e.profile.first_name} ${e.profile.last_name}`}get users(){return this.props.context.displayTestUserDirectoryDialogProps.userDirectoryTestResult.users}get groups(){return this.props.context.displayTestUserDirectoryDialogProps.userDirectoryTestResult.groups}get tree(){return this.props.context.displayTestUserDirectoryDialogProps.userDirectoryTestResult.tree}get errors(){return this.props.context.displayTestUserDirectoryDialogProps.userDirectoryTestResult.errors}get translate(){return this.props.t}render(){return n.createElement(qt,{className:"ldap-test-settings-dialog",title:this.translate("Test settings report"),onClose:this.handleClose,disabled:this.hasAllInputDisabled()},n.createElement("div",{className:"form-content"},n.createElement("p",null,n.createElement("strong",null,n.createElement(f.x6,null,"A connection could be established. Well done!"))),n.createElement("div",{className:"ldap-test-settings-report"},n.createElement("p",null,this.users.length>0&&n.createElement(n.Fragment,null,this.translate("{{count}} user has been found.",{count:this.users.length})),this.users.length>0&&this.groups.length>0&&n.createElement("br",null),this.groups.length>0&&n.createElement(n.Fragment,null,this.translate("{{count}} group has been found.",{count:this.groups.length}))),n.createElement("div",{className:"accordion directory-list "+(this.state.openListGroupsUsers?"":"closed")},n.createElement("div",{className:"accordion-header",onClick:this.handleListGroupsUsersClicked},n.createElement("button",{type:"button",className:"link no-border"},n.createElement("span",null,n.createElement(f.x6,null,"See list")),this.state.openListGroupsUsers?n.createElement(Vt,{className:"baseline svg-icon"}):n.createElement(Wt,{className:"baseline svg-icon"}))),n.createElement("div",{className:"accordion-content"},n.createElement("div",{className:"directory-list-content"},n.createElement("table",null,n.createElement("tbody",null,n.createElement("tr",null,n.createElement("td",null,n.createElement(f.x6,null,"Groups")),n.createElement("td",null,n.createElement(f.x6,null,"Users"))),n.createElement("tr",null,n.createElement("td",null,this.groups.map(e=>e.errors&&n.createElement("div",{key:e.id},n.createElement("span",{className:"error"},e.directory_name))||n.createElement("div",{key:e.id},e.group.name))),n.createElement("td",null,this.users.map(e=>e.errors&&n.createElement("div",{key:e.id},n.createElement("span",{className:"error"},e.directory_name))||n.createElement("div",{key:e.id},this.displayUserName(e.user)," ",n.createElement("em",null,"(",e.user.username,")")))))))))),n.createElement("div",{className:"accordion accordion-directory-structure "+(this.state.openStructureGroupsUsers?"":"closed")},n.createElement("div",{className:"accordion-header",onClick:this.handleStructureGroupsUsersClicked},n.createElement("button",{type:"button",className:"link no-border"},n.createElement("span",null,n.createElement(f.x6,null,"See structure")),this.state.openStructureGroupsUsers?n.createElement(Vt,{className:"baseline svg-icon"}):n.createElement(Wt,{className:"baseline svg-icon"}))),n.createElement("div",{className:"accordion-content"},n.createElement("div",{className:"directory-structure"},n.createElement("ul",null,n.createElement("li",{className:"group"},"Root",Object.values(this.tree).map(e=>n.createElement(Wn,{key:`tree-${e.id}`,node:e}))))))),this.errors.length>0&&n.createElement(n.Fragment,null,n.createElement("div",{className:"accordion accordion-directory-errors "+(this.state.openErrors?"":"closed")},n.createElement("div",{className:"accordion-header",onClick:this.handleErrorsClicked},n.createElement("button",{type:"button",className:"link no-border"},n.createElement("span",null,n.createElement(f.x6,null,"See error details")),this.state.openErrors?n.createElement(Vt,{className:"baseline svg-icon"}):n.createElement(Wt,{className:"baseline svg-icon"}))),n.createElement("div",{className:"accordion-content"},n.createElement("div",{className:"directory-errors"},n.createElement("textarea",{value:JSON.stringify(this.errors,null," "),readOnly:!0})))),n.createElement("div",{className:"warning message no-margin"},n.createElement("p",{className:""},this.translate("{{count}} entry had errors and will be ignored during synchronization.",{count:this.errors.length})))))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement("button",{type:"button",disabled:this.hasAllInputDisabled(),className:"primary button form",onClick:this.handleClose},n.createElement(f.x6,null,"Ok"))))}}Hn.propTypes={context:i().any,onClose:i().func,t:i().func};const $n=N((0,f.CI)("common")(Hn));var Yn;function Zn(){return Zn=Object.assign?Object.assign.bind():function(e){for(var t=1;tthis.handleFormSubmit("test")},n.createElement(Jn,null),n.createElement("span",null,n.createElement(f.x6,null,"Test settings"))),n.createElement("button",{type:"button",className:"button secondary ",disabled:!this.isSynchronizeEnabled(),onClick:this.handleSimulateSynchronizeClick},n.createElement(ns,null),n.createElement("span",null,n.createElement(f.x6,null,"Simulate synchronize"))),n.createElement("button",{type:"button",className:"button secondary",disabled:!this.isSynchronizeEnabled(),onClick:this.handleSynchronizeClick},n.createElement(os,null),n.createElement("span",null,n.createElement(f.x6,null,"Synchronize")))),n.createElement("button",{type:"button",className:"button primary form",disabled:!this.isSaveEnabled(),onClick:()=>this.handleFormSubmit("save")},n.createElement("span",null,n.createElement(f.x6,null,"Save"))))}}ls.propTypes={context:i().object,dialogContext:i().object,adminUserDirectoryContext:i().object,actionFeedbackContext:i().object,t:i().func};const cs=N(m(h(Un((0,f.CI)("common")(ls)))));var ms,ds;function us(){return us=Object.assign?Object.assign.bind():function(e){for(var t=1;t!0===e.active&&"admin"===e.role.name);return t&&t.map(e=>({value:e.id,label:this.displayUser(e)}))}return[]}getUsersAllowedToBeDefaultGroupAdmin(){const e=this.props.adminUserDirectoryContext.getUsers();if(null!==e){const t=e.filter(e=>!0===e.active);return t&&t.map(e=>({value:e.id,label:this.displayUser(e)}))}return[]}displayUser(e){return`${e.profile.first_name} ${e.profile.last_name} (${e.username})`}shouldShowSourceWarningMessage(){const e=this.props.adminUserDirectoryContext;return"file"===e?.getCurrentSettings()?.source&&e?.hasSettingsChanges()}get settingsSource(){return this.props.adminUserDirectoryContext?.getCurrentSettings()?.source}get configurationSource(){return{env:this.props.t("environment variables"),file:this.props.t("file"),db:this.props.t("database"),default:this.props.t("default")}[this.settingsSource]||this.props.t("unknown")}get connectionType(){return[{value:"plain",label:"ldap://"},{value:"ssl",label:"ldaps:// (ssl)"},{value:"tls",label:"ldaps:// (tls)"}]}get supportedAuthenticationMethod(){return[{value:"basic",label:this.props.t("Basic")},{value:"sasl",label:"SASL (EE)"}]}render(){const e=this.props.adminUserDirectoryContext.getSettings(),t=this.props.adminUserDirectoryContext.getErrors(),a=this.props.adminUserDirectoryContext.isSubmitted(),s=this.props.adminUserDirectoryContext.hadDisabledSettings(),i=null!==this.props.adminUserDirectoryContext.getCurrentSettings()&&this.props.adminUserDirectoryContext.hasSettingsChanges(),r=this.shouldShowSourceWarningMessage()||!this.isUserDirectoryChecked()||i;return n.createElement("div",{className:"row"},n.createElement("div",{className:"ldap-settings main-column"},n.createElement("div",{className:"main-content"},n.createElement("h3",{className:"title"},n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"userDirectoryToggle",onChange:this.handleInputChange,checked:e.userDirectoryToggle,disabled:this.hasAllInputDisabled(),id:"userDirectoryToggle"}),n.createElement("label",{htmlFor:"userDirectoryToggle"},n.createElement(f.x6,null,"Users Directory")))),this.isUserDirectoryChecked()&&n.createElement(n.Fragment,null,n.createElement("p",{className:"description"},n.createElement(f.x6,null,"A Users Directory is configured. The users and groups of passbolt will synchronize with it.")),n.createElement("div",{className:"accordion section-general "+(e.openCredentials?"":"closed")},n.createElement("h4",{className:"accordion-header"},n.createElement("button",{type:"button",className:"link no-border",onClick:this.handleCredentialTitleClicked},e.openCredentials?n.createElement(Vt,{className:"caret-down"}):n.createElement(Wt,{className:"caret-right"}),n.createElement(f.x6,null,"Credentials"))),n.createElement("div",{className:"accordion-content"},n.createElement("div",{className:"radiolist required"},n.createElement("label",null,n.createElement(f.x6,null,"Directory type")),n.createElement("div",{className:"input radio ad openldap form-element "},n.createElement("div",{className:"input radio"},n.createElement("input",{type:"radio",value:"ad",onChange:this.handleInputChange,name:"directoryType",checked:this.isActiveDirectoryChecked(),id:"directoryTypeAd",disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"directoryTypeAd"},n.createElement(f.x6,null,"Active Directory"))),n.createElement("div",{className:"input radio"},n.createElement("input",{type:"radio",value:"openldap",onChange:this.handleInputChange,name:"directoryType",checked:this.isOpenLdapChecked(),id:"directoryTypeOpenLdap",disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"directoryTypeOpenLdap"},n.createElement(f.x6,null,"Open Ldap"))))),n.createElement("div",{className:"input text required ad openldap "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Server url")),n.createElement("div",{className:`input text singleline connection_info ad openldap ${this.hasAllInputDisabled()?"disabled":""} ${this.state.hasFieldFocus?"no-focus":""}`},n.createElement("input",{id:"server-input",type:"text","aria-required":!0,className:"required host ad openldap form-element",name:"host",value:e.host,onChange:this.handleInputChange,placeholder:this.props.t("host"),disabled:this.hasAllInputDisabled()}),n.createElement("div",{className:"protocol",onBlur:this.handleFieldBlur,onFocus:this.handleFieldFocus},n.createElement(pn,{className:"inline",name:"connectionType",items:this.connectionType,value:e.connectionType,onChange:this.handleInputChange,disabled:this.hasAllInputDisabled()})),n.createElement("div",{className:"port ad openldap"},n.createElement("input",{id:"port-input",type:"number","aria-required":!0,className:"required in-field form-element",name:"port",value:e.port,onChange:this.handleInputChange,onBlur:this.handleFieldBlur,onFocus:this.handleFieldFocus,disabled:this.hasAllInputDisabled()}))),t.hostError&&a&&n.createElement("div",{id:"server-input-feedback",className:"error-message"},t.hostError),t.portError&&a&&n.createElement("div",{id:"port-input-feedback",className:"error-message"},t.portError)),n.createElement("div",{className:"select-wrapper input required ad openldap "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Authentication method")),n.createElement(pn,{items:this.supportedAuthenticationMethod,id:"authentication-type-select",name:"authenticationType",value:e.authenticationType,onChange:this.handleInputChange,disabled:this.hasAllInputDisabled()})),"basic"===e.authenticationType&&n.createElement("div",{className:"singleline clearfix"},n.createElement("div",{className:"input text first-field ad openldap "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Username")),n.createElement("input",{id:"username-input",type:"text",className:"fluid form-element",name:"username",value:e.username,onChange:this.handleInputChange,placeholder:this.props.t("Username"),disabled:this.hasAllInputDisabled()})),n.createElement("div",{className:"input text last-field ad openldap "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Password")),n.createElement("input",{id:"password-input",className:"fluid form-element",name:"password",value:e.password,onChange:this.handleInputChange,placeholder:this.props.t("Password"),type:"password",disabled:this.hasAllInputDisabled()}))),n.createElement("div",{className:"input text required ad openldap "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Domain")),n.createElement("input",{id:"domain-name-input","aria-required":!0,type:"text",name:"domain",value:e.domain,onChange:this.handleInputChange,className:"required fluid form-element",placeholder:"domain.ext",disabled:this.hasAllInputDisabled()}),t.domainError&&a&&n.createElement("div",{id:"domain-name-input-feedback",className:"error-message"},t.domainError)),n.createElement("div",{className:"input text ad openldap "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Base DN")),n.createElement("input",{id:"base-dn-input",type:"text",name:"baseDn",value:e.baseDn,onChange:this.handleInputChange,className:"fluid form-element",placeholder:"OU=OrgUsers,DC=mydomain,DC=local",disabled:this.hasAllInputDisabled()}),n.createElement("div",{className:"help-message"},n.createElement(f.x6,null,"The base DN (default naming context) for the domain.")," ",n.createElement(f.x6,null,"If this is empty then it will be queried from the RootDSE."))))),n.createElement("div",{className:"accordion section-directory-configuration "+(e.openDirectoryConfiguration?"":"closed")},n.createElement("h4",{className:"accordion-header"},n.createElement("button",{type:"button",className:"link no-border",onClick:this.handleDirectoryConfigurationTitleClicked},e.openDirectoryConfiguration?n.createElement(Vt,{className:"caret-down"}):n.createElement(Wt,{className:"caret-right"}),n.createElement(f.x6,null,"Directory configuration"))),n.createElement("div",{className:"accordion-content"},n.createElement("div",{className:"input text ad openldap "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Group path")),n.createElement("input",{id:"group-path-input",type:"text","aria-required":!0,name:"groupPath",value:e.groupPath,onChange:this.handleInputChange,className:"required fluid form-element",placeholder:this.props.t("Group path"),disabled:this.hasAllInputDisabled()}),n.createElement("div",{className:"help-message"},n.createElement(f.x6,null,"Group path is used in addition to the base DN while searching groups.")," ",n.createElement(f.x6,null,"Leave empty if users and groups are in the same DN."))),n.createElement("div",{className:"input text ad openldap "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"User path")),n.createElement("input",{id:"user-path-input",type:"text","aria-required":!0,name:"userPath",value:e.userPath,onChange:this.handleInputChange,className:"required fluid form-element",placeholder:this.props.t("User path"),disabled:this.hasAllInputDisabled()}),n.createElement("div",{className:"help-message"},n.createElement(f.x6,null,"User path is used in addition to base DN while searching users."))),n.createElement("div",{className:"input text ad openldap "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Group custom filters")),n.createElement("input",{id:"group-custom-filters-input",type:"text",name:"groupCustomFilters",value:e.groupCustomFilters,onChange:this.handleInputChange,className:"required fluid form-element",placeholder:this.props.t("Group custom filters"),disabled:this.hasAllInputDisabled()}),n.createElement("div",{className:"help-message"},n.createElement(f.x6,null,"Group custom filters are used in addition to the base DN and group path while searching groups.")," ",n.createElement(f.x6,null,"Leave empty if no additional filter is required."))),n.createElement("div",{className:"input text ad openldap "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"User custom filters")),n.createElement("input",{id:"user-custom-filters-input",type:"text",name:"userCustomFilters",value:e.userCustomFilters,onChange:this.handleInputChange,className:"required fluid form-element",placeholder:this.props.t("User custom filters"),disabled:this.hasAllInputDisabled()}),n.createElement("div",{className:"help-message"},n.createElement(f.x6,null,"User custom filters are used in addition to the base DN and user path while searching users.")," ",n.createElement(f.x6,null,"Leave empty if no additional filter is required."))),this.isOpenLdapChecked()&&n.createElement("div",null,n.createElement("div",{className:"input text ad openldap "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Group object class")),n.createElement("input",{id:"group-object-class-input",type:"text","aria-required":!0,name:"groupObjectClass",value:e.groupObjectClass,onChange:this.handleInputChange,className:"required fluid",placeholder:"GroupObjectClass",disabled:this.hasAllInputDisabled()}),n.createElement("div",{className:"help-message"},n.createElement(f.x6,null,"For Openldap only. Defines which group object to use.")," (",n.createElement(f.x6,null,"Default"),": groupOfUniqueNames)")),n.createElement("div",{className:"input text ad openldap "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"User object class")),n.createElement("input",{id:"user-object-class-input",type:"text","aria-required":!0,name:"userObjectClass",value:e.userObjectClass,onChange:this.handleInputChange,className:"required fluid form-element",placeholder:"UserObjectClass",disabled:this.hasAllInputDisabled()}),n.createElement("div",{className:"help-message"},n.createElement(f.x6,null,"For Openldap only. Defines which user object to use.")," (",n.createElement(f.x6,null,"Default"),": inetOrgPerson)")),n.createElement("div",{className:"input text openldap "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Use email prefix / suffix?")),n.createElement("div",{className:"input toggle-switch openldap form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"useEmailPrefix",value:e.useEmailPrefix,onChange:this.handleInputChange,id:"use-email-prefix-suffix-toggle-button",disabled:this.hasAllInputDisabled()}),n.createElement("label",{className:"text",htmlFor:"use-email-prefix-suffix-toggle-button"},n.createElement(f.x6,null,"Build email based on a prefix and suffix?"))),n.createElement("div",{className:"help-message"},n.createElement(f.x6,null,"Use this option when user entries do not include an email address by default"))),this.isUseEmailPrefixChecked()&&n.createElement("div",{className:"singleline clearfix",id:"use-email-prefix-suffix-options"},n.createElement("div",{className:"input text first-field openldap "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Email prefix")),n.createElement("input",{id:"email-prefix-input",type:"text","aria-required":!0,name:"emailPrefix",checked:e.emailPrefix,onChange:this.handleInputChange,className:"required fluid form-element",placeholder:this.props.t("Username"),disabled:this.hasAllInputDisabled()}),n.createElement("div",{className:"help-message"},n.createElement(f.x6,null,"The attribute you would like to use for the first part of the email (usually username)."))),n.createElement("div",{className:"input text last-field openldap "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Email suffix")),n.createElement("input",{id:"email-suffix-input",type:"text","aria-required":!0,name:"emailSuffix",value:e.emailSuffix,onChange:this.handleInputChange,className:"required form-element",placeholder:this.props.t("@your-domain.com"),disabled:this.hasAllInputDisabled()}),n.createElement("div",{className:"help-message"},n.createElement(f.x6,null,"The domain name part of the email (@your-domain-name).")))),n.createElement("div",{className:"input text ad openldap "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Group users field mapping")),n.createElement("input",{id:"field-mapping-openldap-group-users-input",type:"text","aria-required":!0,name:"users",value:e.fieldsMapping.openldap.group.users,onChange:this.handleOpenLdapGroupFieldsMappingInputChange,className:"fluid form-element",placeholder:this.props.t("Group users field mapping"),disabled:this.hasAllInputDisabled()}),n.createElement("div",{className:"help-message"},n.createElement(f.x6,null,"Directory group's users field to map to Passbolt group's field.")),t.fieldsMappingOpenLdapGroupUsersError&&a&&n.createElement("div",{id:"field-mapping-openldap-group-users-input-feedback",className:"error-message"},t.fieldsMappingOpenLdapGroupUsersError))),this.isActiveDirectoryChecked()&&n.createElement("div",{className:"input text ad openldap "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"User username field mapping")),n.createElement("input",{id:"field-mapping-ad-user-username-input",type:"text","aria-required":!0,name:"username",value:e.fieldsMapping.ad.user.username,onChange:this.handleAdUserFieldsMappingInputChange,className:"fluid form-element",placeholder:this.props.t("User username field mapping"),disabled:this.hasAllInputDisabled()}),n.createElement("div",{className:"help-message"},n.createElement(f.x6,null,"Directory user's username field to map to Passbolt user's username field.")),t.fieldsMappingAdUserUsernameError&&a&&n.createElement("div",{id:"field-mapping-ad-user-username-input-feedback",className:"error-message"},t.fieldsMappingAdUserUsernameError)))),n.createElement("div",{className:"accordion section-sync-options "+(e.openSynchronizationOptions?"":"closed")},n.createElement("h4",{className:"accordion-header"},n.createElement("button",{type:"button",className:"link no-border",onClick:this.handleSynchronizationOptionsTitleClicked},e.openSynchronizationOptions?n.createElement(Vt,{className:"caret-down"}):n.createElement(Wt,{className:"caret-right"}),n.createElement(f.x6,null,"Synchronization options"))),n.createElement("div",{className:"accordion-content"},n.createElement("div",{className:"select-wrapper input required ad openldap "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Default admin")),n.createElement(pn,{items:this.getUsersAllowedToBeDefaultAdmin(),id:"default-user-select",name:"defaultAdmin",value:e.defaultAdmin,onChange:this.handleInputChange,disabled:this.hasAllInputDisabled(),search:!0}),n.createElement("div",{className:"help-message"},n.createElement(f.x6,null,"The default admin user is the user that will perform the operations for the the directory."))),n.createElement("div",{className:"select-wrapper input required ad openldap "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Default group admin")),n.createElement(pn,{items:this.getUsersAllowedToBeDefaultGroupAdmin(),id:"default-group-admin-user-select",name:"defaultGroupAdmin",value:e.defaultGroupAdmin,onChange:this.handleInputChange,disabled:this.hasAllInputDisabled(),search:!0}),n.createElement("div",{className:"help-message"},n.createElement(f.x6,null,"The default group manager is the user that will be the group manager of newly created groups."))),n.createElement("div",{className:"input text ad openldap "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Groups parent group")),n.createElement("input",{id:"groups-parent-group-input",type:"text",name:"groupsParentGroup",value:e.groupsParentGroup,onChange:this.handleInputChange,className:"fluid form-element",placeholder:this.props.t("Groups parent group"),disabled:this.hasAllInputDisabled()}),n.createElement("div",{className:"help-message"},n.createElement(f.x6,null,"Synchronize only the groups which are members of this group."))),n.createElement("div",{className:"input text ad openldap "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Users parent group")),n.createElement("input",{id:"users-parent-group-input",type:"text",name:"usersParentGroup",value:e.usersParentGroup,onChange:this.handleInputChange,className:"fluid form-element",placeholder:this.props.t("Users parent group"),disabled:this.hasAllInputDisabled()}),n.createElement("div",{className:"help-message"},n.createElement(f.x6,null,"Synchronize only the users which are members of this group."))),this.isActiveDirectoryChecked&&n.createElement("div",{className:"input text ad openldap "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"User username fallback field")),n.createElement("input",{id:"fallback-fields-ad-username-fallback-input",type:"text","aria-required":!0,name:"username",value:e.fallbackFields.ad.username,onChange:this.handleAdFallbackFieldInputChange,className:"fluid form-element",placeholder:this.props.t("User username fallback field"),disabled:this.hasAllInputDisabled()}),n.createElement("div",{className:"help-message"},n.createElement(f.x6,null,"Directory user's username fallback field to use when user username field cannot be found.")),t.fallbackFieldsAdUsernameError&&a&&n.createElement("div",{id:"fallback-fields-ad-username-fallback-input-feedback",className:"error-message"},t.fallbackFieldsAdUsernameError)),this.isActiveDirectoryChecked()&&n.createElement("div",{className:"input text clearfix ad "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Enabled users only")),n.createElement("div",{className:"input toggle-switch ad form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"enabledUsersOnly",checked:e.enabledUsersOnly,onChange:this.handleInputChange,id:"enabled-users-only-toggle-button",disabled:this.hasAllInputDisabled()}),n.createElement("label",{className:"text",htmlFor:"enabled-users-only-toggle-button"},n.createElement(f.x6,null,"Only synchronize enabled users (AD)")))),n.createElement("div",{className:"input text clearfix ad openldap"},n.createElement("label",null,n.createElement(f.x6,null,"Sync operations")),n.createElement("div",{className:"col6"},n.createElement("div",{className:"input toggle-switch ad openldap form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"createUsers",checked:e.createUsers,onChange:this.handleInputChange,id:"sync-users-create-toggle-button",disabled:this.hasAllInputDisabled()}),n.createElement("label",{className:"text",htmlFor:"sync-users-create-toggle-button"},n.createElement(f.x6,null,"Create users"))),n.createElement("div",{className:"input toggle-switch ad openldap form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"deleteUsers",checked:e.deleteUsers,onChange:this.handleInputChange,id:"sync-users-delete-toggle-button",disabled:this.hasAllInputDisabled()}),n.createElement("label",{className:"text",htmlFor:"sync-users-delete-toggle-button"},n.createElement(f.x6,null,"Delete users"))),n.createElement("div",{className:"input toggle-switch ad openldap form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"updateUsers",checked:e.updateUsers,onChange:this.handleInputChange,id:"sync-users-update-toggle-button",disabled:this.hasAllInputDisabled()}),n.createElement("label",{className:"text",htmlFor:"sync-users-update-toggle-button"},n.createElement(f.x6,null,"Update users")))),n.createElement("div",{className:"col6 last"},n.createElement("div",{className:"input toggle-switch ad openldap form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"createGroups",checked:e.createGroups,onChange:this.handleInputChange,id:"sync-groups-create-toggle-button",disabled:this.hasAllInputDisabled()}),n.createElement("label",{className:"text",htmlFor:"sync-groups-create-toggle-button"},n.createElement(f.x6,null,"Create groups"))),n.createElement("div",{className:"input toggle-switch ad openldap form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"deleteGroups",checked:e.deleteGroups,onChange:this.handleInputChange,id:"sync-groups-delete-toggle-button",disabled:this.hasAllInputDisabled()}),n.createElement("label",{className:"text",htmlFor:"sync-groups-delete-toggle-button"},n.createElement(f.x6,null,"Delete groups"))),n.createElement("div",{className:"input toggle-switch ad openldap form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"updateGroups",checked:e.updateGroups,onChange:this.handleInputChange,id:"sync-groups-update-toggle-button",disabled:this.hasAllInputDisabled()}),n.createElement("label",{className:"text",htmlFor:"sync-groups-update-toggle-button"},n.createElement(f.x6,null,"Update groups"))))),n.createElement("div",{className:"input text clearfix ad openldap"},n.createElement("label",null,n.createElement(f.x6,null,"Delete or suspend users")),n.createElement("div",{className:"help-message"},n.createElement(f.x6,null,"Define the behaviour when existing synchronized users are removed from the users directory"),":"),n.createElement("div",{className:"radiolist-alt"},n.createElement("div",{className:"input radio "+("delete"===e.deleteUserBehavior?"checked":"")},n.createElement("input",{type:"radio",value:"delete",onChange:this.handleInputChange,name:"deleteUserBehavior",checked:"delete"===e.deleteUserBehavior,id:"deleteUserBehaviorDelete",disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"deleteUserBehaviorDelete"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Delete users")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"Delete the users and all the data associated with them.")," ",n.createElement(f.x6,null,"The data will be permanently deleted, this action cannot be undone.")))),n.createElement("div",{className:"input radio "+("disable"===e.deleteUserBehavior?"checked":"")},n.createElement("input",{type:"radio",value:"disable",onChange:this.handleInputChange,name:"deleteUserBehavior",checked:"disable"===e.deleteUserBehavior,id:"deleteUserBehaviorSuspended",disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"deleteUserBehaviorSuspended"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Suspend users")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"Suspend the users, preventing them from signing in to Passbolt and from receiving email notifications.")," ",n.createElement(f.x6,null,"Other users can still share resources with them and add them to groups.")))))))))),r&&n.createElement("div",{className:"warning message"},this.shouldShowSourceWarningMessage()&&n.createElement("div",null,n.createElement(f.x6,null,"These are the settings provided by a configuration file. If you save it, will ignore the settings on file and use the ones from the database.")),i&&n.createElement("div",null,n.createElement(f.x6,null,"Don't forget to save your settings to apply your modification.")),!this.isUserDirectoryChecked()&&n.createElement(n.Fragment,null,s&&n.createElement("div",null,n.createElement(f.x6,null,"The configuration has been disabled as it needs to be checked to make it correct before using it.")),!s&&n.createElement("div",null,n.createElement("p",{className:"description"},n.createElement(f.x6,null,"No Users Directory is configured. Enable it to synchronise your users and groups with passbolt.")))))),n.createElement(cs,null),Xa(n.createElement(n.Fragment,null,n.createElement("div",{className:"sidebar-help-section",id:"user-directory-settings-source"},n.createElement("h3",null,n.createElement(f.x6,null,"Configuration source")),n.createElement("p",null,n.createElement(f.x6,null,"This current configuration source is: "),this.configurationSource,".")),n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"Need help?")),n.createElement("p",null,n.createElement(f.x6,null,"Check out our ldap configuration guide.")),n.createElement("a",{className:"button",href:"https://passbolt.com/docs/admin/user-provisioning/users-directory/",target:"_blank",rel:"noopener noreferrer"},n.createElement(ps,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation"))))),document.getElementById("administration-help-panel")))}}hs.propTypes={adminUserDirectoryContext:i().object,administrationWorkspaceContext:i().object,t:i().func};const gs=Un(Ne((0,f.CI)("common")(hs)));var ys;function bs(){return bs=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},getSettings:()=>{},setSettings:()=>{},hasSettingsChanges:()=>{},findEmailNotificationSettings:()=>{},save:()=>{},setProcessing:()=>{},isProcessing:()=>{},clearContext:()=>{}});class Cs extends n.Component{constructor(e){super(e),this.state=this.defaultState;const t=e.context.getApiClientOptions();this.emailNotificationService=new ws(t)}get defaultState(){return{currentSettings:null,settings:new ks,processing:!0,getCurrentSettings:this.getCurrentSettings.bind(this),getSettings:this.getSettings.bind(this),setSettings:this.setSettings.bind(this),findEmailNotificationSettings:this.findEmailNotificationSettings.bind(this),hasSettingsChanges:this.hasSettingsChanges.bind(this),isProcessing:this.isProcessing.bind(this),setProcessing:this.setProcessing.bind(this),save:this.save.bind(this),clearContext:this.clearContext.bind(this)}}async findEmailNotificationSettings(){this.setProcessing(!0);const e=await this.emailNotificationService.find(),t=new ks(e);this.setState({currentSettings:t}),this.setState({settings:Object.assign({},t)}),this.setProcessing(!1)}getCurrentSettings(){return this.state.currentSettings}getSettings(){return this.state.settings}setSettings(e,t){const a=Object.assign({},this.state.settings,{[e]:t});this.setState({settings:a})}isProcessing(){return this.state.processing}setProcessing(e){this.setState({processing:e})}hasSettingsChanges(){return this.state.currentSettings&&JSON.stringify(this.state.currentSettings)!==JSON.stringify(this.state.settings)}clearContext(){const{currentSettings:e,settings:t,processing:a}=this.defaultState;this.setState({currentSettings:e,settings:t,processing:a})}async save(){this.setProcessing(!0);const e=new _s(this.state.settings);await this.emailNotificationService.save(e),await this.findEmailNotificationSettings()}render(){return n.createElement(Ss.Provider,{value:this.state},this.props.children)}}Cs.propTypes={context:i().any,children:i().any};const Ns=N(Cs);function Ts(e){return class extends n.Component{render(){return n.createElement(Ss.Consumer,null,t=>n.createElement(e,xs({adminEmailNotificationContext:t},this.props)))}}}class As extends n.Component{constructor(e){super(e),this.bindCallbacks()}async handleSaveClick(){try{await this.props.adminEmailNotificationContext.save(),this.handleSaveSuccess()}catch(e){this.handleSaveError(e)}finally{this.props.adminEmailNotificationContext.setProcessing(!1)}}isSaveEnabled(){return!this.props.adminEmailNotificationContext.isProcessing()&&this.props.adminEmailNotificationContext.hasSettingsChanges()}bindCallbacks(){this.handleSaveClick=this.handleSaveClick.bind(this)}async handleSaveSuccess(){await this.props.actionFeedbackContext.displaySuccess(this.props.t("The email notification settings were updated."))}async handleSaveError(e){"UserAbortsOperationError"!==e.name&&(console.error(e),await this.handleError(e))}async handleError(e){await this.props.actionFeedbackContext.displayError(e.message)}render(){return n.createElement("div",{className:"actions-wrapper"},n.createElement("button",{className:"button primary form",type:"button",disabled:!this.isSaveEnabled(),onClick:this.handleSaveClick,id:"save-settings"},n.createElement("span",null,n.createElement(f.x6,null,"Save"))))}}As.propTypes={adminEmailNotificationContext:i().object,actionFeedbackContext:i().object,t:i().func};const Is=Ts(m((0,f.CI)("common")(As)));class Rs extends n.Component{constructor(e){super(e),this.bindCallbacks()}async componentDidMount(){this.props.adminEmailNotificationContext.findEmailNotificationSettings()}componentWillUnmount(){this.props.administrationWorkspaceContext.resetDisplayAdministrationWorkspaceAction(),this.props.adminEmailNotificationContext.clearContext()}bindCallbacks(){this.handleInputChange=this.handleInputChange.bind(this)}handleInputChange(e){const t=e.target.checked,a=e.target.name;this.props.adminEmailNotificationContext.setSettings(a,t)}hasAllInputDisabled(){return this.props.adminEmailNotificationContext.isProcessing()}hasDatabaseSetting(){return this.props.adminEmailNotificationContext.getSettings().hasDatabaseSetting}hasFileConfigSetting(){return this.props.adminEmailNotificationContext.getSettings().hasFileConfigSetting}canUseFolders(){return this.props.context.siteSettings.canIUse("folders")}canUseAccountRecovery(){return this.props.context.siteSettings.canIUse("accountRecovery")}canUsePasswordExpiry(){return this.props.context.siteSettings.canIUse("passwordExpiry")||this.props.context.siteSettings.canIUse("passwordExpiryPolicies")}canUsePasswordExpiryAdvancedSettings(){return this.props.context.siteSettings.canIUse("passwordExpiryPolicies")}get settingsSource(){return this.hasDatabaseSetting()?"db":this.hasFileConfigSetting()?"file":"env"}get configurationSource(){return{env:this.props.t("environment variables"),file:this.props.t("file"),db:this.props.t("database")}[this.settingsSource]||this.props.t("unknown")}render(){const e=this.props.adminEmailNotificationContext.getSettings(),t=e&&this.props.adminEmailNotificationContext.hasSettingsChanges(),a=e&&this.hasFileConfigSetting(),s=e&&this.hasDatabaseSetting(),i=a||t;return n.createElement("div",{className:"row"},n.createElement("div",{className:"email-notification-settings main-column"},n.createElement("div",{className:"main-content"},n.createElement("h3",{className:"title"},n.createElement(f.x6,null,"Email delivery")),n.createElement("div",{className:"divider"}),n.createElement("p",null,n.createElement(f.x6,null,"In this section you can choose which email notifications will be sent.")),n.createElement("div",{className:"section"},n.createElement("div",{className:"password-section"},n.createElement("label",null,n.createElement(f.x6,null,"Passwords")),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"passwordCreate",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.passwordCreate,id:"send-password-create-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"send-password-create-toggle-button"},n.createElement(f.x6,null,"When a password is created, notify its creator."))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"passwordUpdate",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.passwordUpdate,id:"send-password-update-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"send-password-update-toggle-button"},n.createElement(f.x6,null,"When a password is updated, notify the users who have access to it."))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"passwordDelete",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.passwordDelete,id:"send-password-delete-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"send-password-delete-toggle-button"},n.createElement(f.x6,null,"When a password is deleted, notify the users who had access to it."))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"passwordShare",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.passwordShare,id:"send-password-share-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"send-password-share-toggle-button"},n.createElement(f.x6,null,"When a password is shared, notify the users who gain access to it.")))),this.canUseFolders()&&n.createElement("div",{className:"folder-section"},n.createElement("label",null,n.createElement(f.x6,null,"Folders")),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"folderCreate",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.folderCreate,id:"send-folder-create-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"send-folder-create-toggle-button"},n.createElement(f.x6,null,"When a folder is created, notify its creator."))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"folderUpdate",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.folderUpdate,id:"send-folder-update-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"send-folder-update-toggle-button"},n.createElement(f.x6,null,"When a folder is updated, notify the users who have access to it."))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"folderDelete",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.folderDelete,id:"send-folder-delete-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"send-folder-delete-toggle-button"},n.createElement(f.x6,null,"When a folder is deleted, notify the users who had access to it."))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"folderShare",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.folderShare,id:"send-folder-share-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"send-folder-share-toggle-button"},n.createElement(f.x6,null,"When a folder is shared, notify the users who gain access to it."))))),n.createElement("div",{className:"section"},n.createElement("div",{className:"comment-section"},n.createElement("label",null,n.createElement(f.x6,null,"Comments")),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"commentAdd",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.commentAdd,id:"send-comment-add-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"send-comment-add-toggle-button"},n.createElement(f.x6,null,"When a comment is posted on a password, notify the users who have access to this password."))))),n.createElement("div",{className:"section"},n.createElement("div",{className:"group-section"},n.createElement("label",null,n.createElement(f.x6,null,"Group membership")),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"groupDelete",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.groupDelete,id:"send-group-delete-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"send-group-delete-toggle-button"},n.createElement(f.x6,null,"When a group is deleted, notify the users who were members of it."))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"groupUserAdd",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.groupUserAdd,id:"send-group-user-add-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"send-group-user-add-toggle-button"},n.createElement(f.x6,null,"When users are added to a group, notify them."))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"groupUserDelete",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.groupUserDelete,id:"send-group-user-delete-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"send-group-user-delete-toggle-button"},n.createElement(f.x6,null,"When users are removed from a group, notify them."))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"groupUserUpdate",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.groupUserUpdate,id:"send-group-user-update-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"send-group-user-update-toggle-button"},n.createElement(f.x6,null,"When user roles change in a group, notify the corresponding users.")))),n.createElement("div",{className:"group-admin-section"},n.createElement("label",null,n.createElement(f.x6,null,"Group manager")),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"groupManagerUpdate",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.groupManagerUpdate,id:"send-group-manager-update-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"send-group-manager-update-toggle-button"},n.createElement(f.x6,null,"When members of a group change, notify the group manager(s)."))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"groupManagerRequestAddUser",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.groupManagerRequestAddUser,id:"send-group-manager-request-add-user-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"send-group-manager-request-add-user-toggle-button"},n.createElement(f.x6,null,"When group managers are requested to add users to a group, notify them."))))),n.createElement("h3",{className:"title"},n.createElement(f.x6,null,"Registration & Recovery")),n.createElement("div",{className:"divider"}),n.createElement("div",{className:"section"},n.createElement("div",{className:"admin-section"},n.createElement("label",null,n.createElement(f.x6,null,"Admin")),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"userSetupCompleteAdmin",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.userSetupCompleteAdmin,id:"user-setup-complete-admin-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"user-setup-complete-admin-toggle-button"},n.createElement(f.x6,null,"When a user completed a setup, notify all the administrators."))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"userRecoverCompleteAdmin",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.userRecoverCompleteAdmin,id:"user-recover-complete-admin-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"user-recover-complete-admin-toggle-button"},n.createElement(f.x6,null,"When a user completed a recover, notify all the administrators."))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"userRecoverAbortAdmin",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.userRecoverAbortAdmin,id:"user-recover-abort-admin-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"user-recover-abort-admin-toggle-button"},n.createElement(f.x6,null,"When a user aborted a recover, notify all the administrators.")))),n.createElement("div",{className:"user-section"},n.createElement("label",null,n.createElement(f.x6,null,"User")),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"userCreate",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.userCreate,id:"send-user-create-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"send-user-create-toggle-button"},n.createElement(f.x6,null,"When new users are invited to passbolt, notify them."))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"userRecover",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.userRecover,id:"send-user-recover-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"send-user-recover-toggle-button"},n.createElement(f.x6,null,"When users try to recover their account, notify them."))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"userRecoverComplete",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.userRecoverComplete,id:"user-recover-complete-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"user-recover-complete-toggle-button"},n.createElement(f.x6,null,"When users completed the recover of their account, notify them."))))),this.canUseAccountRecovery()&&n.createElement(n.Fragment,null,n.createElement("h3",{className:"title"},n.createElement(f.x6,null,"Account recovery")),n.createElement("div",{className:"divider"}),n.createElement("div",{className:"section"},n.createElement("div",{className:"admin-section"},n.createElement("label",null,n.createElement(f.x6,null,"Admin")),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"accountRecoveryRequestAdmin",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.accountRecoveryRequestAdmin,id:"account-recovery-request-admin-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"account-recovery-request-admin-toggle-button"},n.createElement(f.x6,null,"When an account recovery is requested, notify all the administrators."))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"accountRecoveryRequestPolicyUpdate",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.accountRecoveryRequestPolicyUpdate,id:"account-recovery-policy-update-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"account-recovery-policy-update-toggle-button"},n.createElement(f.x6,null,"When an account recovery policy is updated, notify all the administrators."))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"accountRecoveryRequestCreatedAmin",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.accountRecoveryRequestCreatedAmin,id:"account-recovery-response-created-admin-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"account-recovery-response-created-admin-toggle-button"},n.createElement(f.x6,null,"When an administrator answered to an account recovery request, notify the administrator at the origin of the action."))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"accountRecoveryRequestCreatedAllAdmins",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.accountRecoveryRequestCreatedAllAdmins,id:"account-recovery-response-created-all-admin-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"account-recovery-response-created-all-admin-toggle-button"},n.createElement(f.x6,null,"When an administrator answered to an account recovery request, notify all the administrators.")))),n.createElement("div",{className:"user-section"},n.createElement("label",null,n.createElement(f.x6,null,"User")),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"accountRecoveryRequestUser",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.accountRecoveryRequestUser,id:"account-recovery-request-user-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"account-recovery-request-user-toggle-button"},n.createElement(f.x6,null,"When an account recovery is requested, notify the user."))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"accountRecoveryRequestUserApproved",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.accountRecoveryRequestUserApproved,id:"account-recovery-response-user-approved-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"account-recovery-response-user-approved-toggle-button"},n.createElement(f.x6,null,"When an account recovery is approved, notify the user."))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"accountRecoveryRequestUserRejected",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.accountRecoveryRequestUserRejected,id:"account-recovery-response-user-rejected-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"account-recovery-response-user-rejected-toggle-button"},n.createElement(f.x6,null,"When an account recovery is rejected, notify the user.")))))),this.canUsePasswordExpiry()&&n.createElement(n.Fragment,null,n.createElement("h3",{className:"title"},n.createElement(f.x6,null,"Password expiry")),n.createElement("div",{className:"divider"}),n.createElement("div",{className:"section"},n.createElement("div",{className:"password-expiry-section"},n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"passwordExpiryExpiredUser",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.passwordExpiryExpiredUser,id:"password-expiry-expired-user-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"password-expiry-expired-user-toggle-button"},n.createElement(f.x6,null,"When a permission is revoked on a consumed password, notify the owner(s) to change it.")))))),n.createElement("h3",{className:"title"},n.createElement(f.x6,null,"Email content visibility")),n.createElement("div",{className:"divider"}),n.createElement("p",null,n.createElement(f.x6,null,"In this section you can adjust the composition of the emails, e.g. which information will be included in the notification.")),n.createElement("div",{className:"section"},n.createElement("div",{className:"password-section"},n.createElement("label",null,n.createElement(f.x6,null,"Passwords")),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"showUsername",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.showUsername,id:"show-username-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"show-username-toggle-button"},n.createElement(f.x6,null,"Username"))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"showUri",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.showUri,id:"show-uri-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"show-uri-toggle-button"},n.createElement(f.x6,null,"URI"))),n.createElement("span",{className:"input toggle-switch form-element ready"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"showSecret",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.showSecret,id:"show-secret-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"show-secret-toggle-button"},n.createElement(f.x6,null,"Encrypted secret"))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"showDescription",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.showDescription,id:"show-description-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"show-description-toggle-button"},n.createElement(f.x6,null,"Description")))),n.createElement("div",{className:"comment-section"},n.createElement("label",null,n.createElement(f.x6,null,"Comments")),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"showComment",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.showComment,id:"show-comment-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"show-comment-toggle-button"},n.createElement(f.x6,null,"Comment content")))))),i&&n.createElement("div",{className:"warning message"},t&&n.createElement("div",{id:"email-notification-save-banner"},n.createElement("p",null,n.createElement(f.x6,null,"Don't forget to save your settings to apply your modification."))),a&&!s&&n.createElement("div",{id:"email-notification-fileconfig-exists-banner"},n.createElement("p",null,n.createElement(f.x6,null,"You seem to have Email Notification Settings defined in your passbolt.php (or via environment variables).")," ",n.createElement(f.x6,null,"Submitting the form will overwrite those settings with the ones you choose in the form below."))),a&&s&&n.createElement("div",{id:"email-notification-setting-overridden-banner"},n.createElement("p",null,n.createElement(f.x6,null,"Settings have been found in your database as well as in your passbolt.php (or environment variables).")," ",n.createElement(f.x6,null,"The settings displayed in the form below are the one stored in your database and have precedence over others."))))),n.createElement(Is,null),Xa(n.createElement(n.Fragment,null,n.createElement("div",{className:"sidebar-help-section",id:"email-notifications-source"},n.createElement("h3",null,n.createElement(f.x6,null,"Configuration source")),n.createElement("p",null,n.createElement(f.x6,null,"This current configuration source is: "),this.configurationSource,".")),n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"Need some help?")),n.createElement("p",null,n.createElement(f.x6,null,"For more information about email notification, checkout the dedicated page on the help website.")),n.createElement("a",{className:"button",href:"https://passbolt.com/docs/admin/emails/email-notifications/",target:"_blank",rel:"noopener noreferrer"},n.createElement(Sa,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation"))))),document.getElementById("administration-help-panel")))}}Rs.propTypes={context:i().any,administrationWorkspaceContext:i().object,adminEmailNotificationContext:i().object,t:i().func};const Ps=N(Ts(Ne((0,f.CI)("common")(Rs))));var Ds=a(8097);const Os=class{constructor(e){this.customerId=e?.customer_id||"",this.subscriptionId=e?"subscription_id"in e?e.subscription_id:"N/A":"",this.users=e?.users||null,this.email=e?"email"in e?e.email:"N/A":"",this.expiry=e?.expiry||null,this.created=e?.created||null,this.data=e?.data||null}};function Ms(){return Ms=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},findSubscriptionKey:()=>{},isProcessing:()=>{},setProcessing:()=>{},getActiveUsers:()=>{},clearContext:()=>{}});class Fs extends n.Component{constructor(e){super(e),this.state=this.defaultState}get defaultState(){return{subscription:new Os,processing:!0,getSubscription:this.getSubscription.bind(this),findSubscriptionKey:this.findSubscriptionKey.bind(this),isProcessing:this.isProcessing.bind(this),setProcessing:this.setProcessing.bind(this),getActiveUsers:this.getActiveUsers.bind(this),clearContext:this.clearContext.bind(this)}}async findSubscriptionKey(){this.setProcessing(!0);let e=new Os;try{const t=await this.props.context.onGetSubscriptionKeyRequested();e=new Os(t.toDto())}catch(t){"PassboltSubscriptionError"===t.name&&(e=new Os(t.subscription))}finally{this.setState({subscription:e}),this.setProcessing(!1)}}async getActiveUsers(){return(await this.props.context.port.request("passbolt.users.get-all")).filter(e=>e.active).length}getSubscription(){return this.state.subscription}isProcessing(){return this.state.processing}setProcessing(e){this.setState({processing:e})}clearContext(){const{subscription:e,processing:t}=this.defaultState;this.setState({subscription:e,processing:t})}render(){return n.createElement(Us.Provider,{value:this.state},this.props.children)}}function js(e){return class extends n.Component{render(){return n.createElement(Us.Consumer,null,t=>n.createElement(e,Ms({adminSubscriptionContext:t},this.props)))}}}Fs.propTypes={context:i().any,children:i().any},N(Fs);class Ls extends n.Component{constructor(e){super(e),this.bindCallbacks()}bindCallbacks(){this.getClassName=this.getClassName.bind(this)}getClassName(){let e="button primary form";return this.props.warning?e+=" warning":this.props.attention&&(e+=" attention"),this.props.disabled&&(e+=" disabled"),this.props.processing&&(e+=" processing"),this.props.big&&(e+=" big"),this.props.medium&&(e+=" medium"),this.props.fullWidth&&(e+=" full-width"),e}render(){return n.createElement("button",{type:"submit",className:this.getClassName(),disabled:this.props.disabled},this.props.value||n.createElement(f.x6,null,"Save"),this.props.processing&&n.createElement(En,null))}}Ls.defaultProps={warning:!1,attention:!1},Ls.propTypes={processing:i().bool,disabled:i().bool,value:i().oneOfType([i().arrayOf(i().node),i().node,i().string]),warning:i().bool,attention:i().bool,big:i().bool,medium:i().bool,fullWidth:i().bool};const qs=(0,f.CI)("common")(Ls),zs=class extends he{static getSchema(){return{type:"object",required:["subscription_id","users","expiry","created","data"],properties:{customer_id:{type:"string"},subscription_id:{type:"string"},users:{type:"integer"},email:{type:"string",format:"email"},created:{type:"string",format:"date-time"},expiry:{type:"string",format:"date-time"},data:{type:"string"}}}}get expiry(){return this._props.expiry}toDto(){return Object.assign({},this._props)}toJSON(){return this.toDto()}static get ENTITY_NAME(){return"Subscription"}},Ks=class{constructor(e){this.port=e}async createOrganizationSubscriptionKey(e){(0,ie.A)(e);const t=await this.port.request("passbolt.subscription.create",{data:e});return new zs(t)}async findOrganizationSubscriptionKey(){const e=await this.port.request("passbolt.subscription.get");return new zs(e)}async updateOrganizationSubscriptionKey(e){(0,ie.A)(e);const t=await this.port.request("passbolt.subscription.update",{data:e});return new zs(t)}async deleteOrganizationSubscriptionKey(){await this.port.request("passbolt.subscription.downgrade")}};class Vs extends n.Component{constructor(e){super(e),this.state=this.getDefaultState(),this.initEventHandlers(),this.createInputRef(),this.subscriptionKeyService=new Ks(e.context.port)}getDefaultState(){return{selectedFile:null,key:"",keyError:"",processing:!1,hasBeenValidated:!1}}initEventHandlers(){this.handleCloseClick=this.handleCloseClick.bind(this),this.handleFormSubmit=this.handleFormSubmit.bind(this),this.handleInputChange=this.handleInputChange.bind(this),this.handleKeyInputKeyUp=this.handleKeyInputKeyUp.bind(this),this.handleSelectSubscriptionKeyFile=this.handleSelectSubscriptionKeyFile.bind(this),this.handleSelectFile=this.handleSelectFile.bind(this)}createInputRef(){this.keyInputRef=n.createRef(),this.fileUploaderRef=n.createRef()}componentDidMount(){this.setState({key:this.props.context.editSubscriptionKey?.key||""})}async handleFormSubmit(e){e.preventDefault(),this.state.processing||await this.save()}handleInputChange(e){const t=e.target,a=t.value,n=t.name;this.setState({[n]:a})}handleKeyInputKeyUp(){if(this.state.hasAlreadyBeenValidated){const e=this.validateNameInput();this.setState(e)}}handleCloseClick(){this.props.context.setContext({editSubscriptionKey:null}),this.props.onClose()}handleSelectFile(){this.fileUploaderRef.current.click()}get selectedFilename(){return this.state.selectedFile?this.state.selectedFile.name:""}async handleSelectSubscriptionKeyFile(e){const[t]=e.target.files,a=await this.readSubscriptionKeyFile(t);this.setState({key:a,selectedFile:t}),this.state.hasBeenValidated&&await this.validate()}readSubscriptionKeyFile(e){const t=new FileReader;return new Promise((a,n)=>{t.onloadend=()=>{try{a(t.result)}catch(e){n(e)}},t.readAsText(e)})}async save(){if(!this.state.processing){if(this.setState({hasBeenValidated:!0,processing:!0}),!await this.validate())return this.handleValidateError(),void this.setState({processing:!1});try{this.props.onSave?await this.props.onSave(this.state.key):await this.subscriptionKeyService.updateOrganizationSubscriptionKey(this.state.key),await this.handleSaveSuccess(),await this.props.adminSubscriptionContext.findSubscriptionKey()}catch(e){this.setState({processing:!1}),this.handleSaveError(e),this.focusFieldError()}}}handleValidateError(){this.focusFieldError()}async handleSaveSuccess(){await this.props.actionFeedbackContext.displaySuccess(this.translate("The subscription key has been updated successfully.")),this.props.administrationWorkspaceContext.onMustRefreshSubscriptionKey(),this.props.context.setContext({editSubscriptionKey:null,refreshSubscriptionAnnouncement:!0}),this.props.onClose()}handleSaveError(e){if("PassboltSubscriptionError"===e.name)this.setState({keyError:e.message});else if("EntityValidationError"===e.name)this.setState({keyError:this.translate("The subscription key is invalid.")});else if("PassboltApiFetchError"===e.name&&e.data&&400===e.data.code)this.setState({keyError:e.message});else{console.error(e);const t={error:e};this.props.dialogContext.open($t,t)}}focusFieldError(){this.state.keyError&&this.keyInputRef.current.focus()}validateKeyInput(){const e=this.state.key.trim();let t="";return e.length||(t=this.translate("A subscription key is required.")),new Promise(e=>{this.setState({keyError:t},e)})}async validate(){return this.setState({keyError:""}),await this.validateKeyInput(),""===this.state.keyError}hasAllInputDisabled(){return this.state.processing}get translate(){return this.props.t}render(){return n.createElement(qt,{title:this.props.title??this.translate("Edit subscription key"),onClose:this.handleCloseClick,disabled:this.state.processing,className:"edit-subscription-dialog"},n.createElement("form",{onSubmit:this.handleFormSubmit,noValidate:!0},n.createElement("div",{className:"form-content"},n.createElement("div",{className:`input textarea required ${this.state.keyError?"error":""} ${this.hasAllInputDisabled()?"disabled":""}`},n.createElement("label",{htmlFor:"edit-tag-form-name"},n.createElement(f.x6,null,"Subscription key")),n.createElement("textarea",{id:"edit-subscription-form-key",name:"key",value:this.state.key,onKeyUp:this.handleKeyInputKeyUp,onChange:this.handleInputChange,disabled:this.hasAllInputDisabled(),ref:this.keyInputRef,className:"required full_report",required:"required",autoComplete:"off",autoFocus:!0})),n.createElement("div",{className:"input file "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("input",{type:"file",ref:this.fileUploaderRef,disabled:this.hasAllInputDisabled(),onChange:this.handleSelectSubscriptionKeyFile}),n.createElement("div",{className:"input-file-inline"},n.createElement("input",{type:"text",disabled:!0,placeholder:this.translate("No key file selected"),value:this.selectedFilename}),n.createElement("button",{type:"button",className:"button primary",onClick:this.handleSelectFile,disabled:this.hasAllInputDisabled()},n.createElement("span",null,n.createElement(f.x6,null,"Choose a file")))),this.state.keyError&&n.createElement("div",{className:"key error-message"},this.state.keyError),this.props.warning&&n.createElement("p",null,this.props.warning))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement(gn,{disabled:this.hasAllInputDisabled(),onClick:this.handleCloseClick}),n.createElement(qs,{disabled:this.hasAllInputDisabled(),processing:this.state.processing,value:this.translate("Save")}))))}}Vs.propTypes={context:i().any,onClose:i().func,actionFeedbackContext:i().any,adminSubscriptionContext:i().object,dialogContext:i().any,administrationWorkspaceContext:i().any,title:i().string,warning:i().string,onSave:i().func,t:i().func};const Gs=N(js(Ne(m(h((0,f.CI)("common")(Vs))))));class Bs{constructor(e){this.context=e.context,this.dialogContext=e.dialogContext,this.subscriptionContext=e.adminSubscriptionContext}static getInstance(e){return this.instance||(this.instance=new Bs(e)),this.instance}static killInstance(){this.instance=null}editSubscription(){const e={key:this.subscriptionContext.getSubscription().data};this.context.setContext({editSubscriptionKey:e}),this.dialogContext.open(Gs)}}const Ws=Bs,Hs=(e,t,a)=>{if(null===e)return"n/a";if("Infinity"===e)return t("Never");const n=Ds.c9.fromISO(e),s=n.diffNow().toMillis();return s>-1e3&&s<0?t("Just now"):n.toRelative({locale:a})};class $s extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.bindCallbacks()}get defaultState(){return{processing:!1,confirmed:!1}}bindCallbacks(){this.handleFormSubmit=this.handleFormSubmit.bind(this),this.handleConfirmChange=this.handleConfirmChange.bind(this)}handleConfirmChange(e){this.setState({confirmed:e.target.checked})}async handleFormSubmit(e){if(e.preventDefault(),!this.state.processing){this.setState({processing:!0});try{await this.props.onSubmit()}catch(e){console.error(e)}this.setState({processing:!1})}}get translate(){return this.props.t}render(){return n.createElement(qt,{title:this.translate("Are you sure you want to downgrade?"),onClose:this.props.onClose,disabled:this.state.processing,className:"confirm-downgrade-subscription-dialog"},n.createElement("form",{onSubmit:this.handleFormSubmit,noValidate:!0},n.createElement("div",{className:"form-content"},n.createElement("p",null,n.createElement(f.x6,null,"You are about to downgrade your subscription from Passbolt Pro to Community Edition.")),n.createElement("p",null,n.createElement(f.x6,null,"All settings and data specific to the Pro edition will be permanently lost, including Single Sign-On (SSO) configuration, directory synchronization (AD/SCIM), advanced role-based policies, audit logs and account recovery settings.")),n.createElement("p",null,n.createElement(f.x6,null,"All ongoing processes such as an import will be stopped and the data could be lost. Please make sure your users are not actively using the platform during the process. This process should take a few seconds.")),n.createElement("p",null,n.createElement(f.x6,null,"You and your team will be disconnected at the end of the process.")),n.createElement("p",null,n.createElement(f.x6,null,"Your team will also lose access to premium technical support. This action cannot be undone.")),n.createElement("div",{className:"input checkbox"},n.createElement("input",{id:"confirm-downgrade",type:"checkbox",name:"confirmed",checked:this.state.confirmed,disabled:this.state.processing,onChange:this.handleConfirmChange}),n.createElement("label",{htmlFor:"confirm-downgrade"},n.createElement(f.x6,null,"I confirm I want to downgrade and accept the data loss.")))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement(gn,{disabled:this.state.processing,onClick:this.props.onClose}),n.createElement(qs,{warning:!0,disabled:this.state.processing||!this.state.confirmed,processing:this.state.processing,value:this.translate("Downgrade and lose data")}))))}}$s.propTypes={context:i().any,dialogContext:i().any,actionFeedbackContext:i().any,onSubmit:i().func,onClose:i().func,t:i().func};const Ys=N(h(m((0,f.CI)("common")($s))));var Zs,Js;function Xs(){return Xs=Object.assign?Object.assign.bind():function(e){for(var t=1;tthis.props.dialogContext.close(e),onSubmit:()=>this.handleDowngrade(e)})}async handleDowngrade(e){try{await this.subscriptionKeyService.deleteOrganizationSubscriptionKey(),await this.props.actionFeedbackContext.displaySuccess(this.translate("Subscription has been removed successfully. The instance is now on Community Edition.")),this.props.dialogContext.close(e)}catch(e){if("UserAbortsOperationError"===e?.name)return;this.props.dialogContext.open($t,{error:e})}}handleRenewKey(){const e=this.props.adminSubscriptionContext.getSubscription();this.hasLimitUsersExceeded()?this.props.navigationContext.onGoToNewTab(`https://www.passbolt.com/subscription/ee/update/qty?subscription_id=${e.subscriptionId}&customer_id=${e.customerId}`):(this.hasSubscriptionKeyExpired()||this.hasSubscriptionKeyGoingToExpire())&&this.props.navigationContext.onGoToNewTab(`https://www.passbolt.com/subscription/ee/update/renew?subscription_id=${e.subscriptionId}&customer_id=${e.customerId}`)}handleUpdateKey(){this.subscriptionActionService.editSubscription()}hasSubscriptionKeyExpired(){return Ds.c9.fromISO(this.props.adminSubscriptionContext.getSubscription().expiry){},getLocale:()=>{},supportedLocales:()=>{},setLocale:()=>{},hasLocaleChanges:()=>{},findLocale:()=>{},save:()=>{},setProcessing:()=>{},isProcessing:()=>{},clearContext:()=>{}});class li extends n.Component{constructor(e){super(e),this.state=this.defaultState;const t=e.context.getApiClientOptions();this.internalisationService=new ii(t)}get defaultState(){return{currentLocale:null,locale:"en-UK",processing:!0,getCurrentLocale:this.getCurrentLocale.bind(this),getLocale:this.getLocale.bind(this),setLocale:this.setLocale.bind(this),findLocale:this.findLocale.bind(this),hasLocaleChanges:this.hasLocaleChanges.bind(this),isProcessing:this.isProcessing.bind(this),setProcessing:this.setProcessing.bind(this),save:this.save.bind(this),clearContext:this.clearContext.bind(this)}}findLocale(){this.setProcessing(!0);const e=this.props.context.siteSettings.locale;this.setState({currentLocale:e,locale:e,processing:!1})}getCurrentLocale(){return this.state.currentLocale}getLocale(){return this.state.locale}setLocale(e){this.setState({locale:e})}isProcessing(){return this.state.processing}setProcessing(e){this.setState({processing:e})}hasLocaleChanges(){return this.state.locale!==this.state.currentLocale}clearContext(){const{currentLocale:e,locale:t,processing:a}=this.defaultState;this.setState({currentLocale:e,locale:t,processing:a})}async save(){this.setProcessing(!0),await this.internalisationService.save({value:this.state.locale}),this.props.context.onRefreshLocaleRequested(this.state.locale),this.findLocale()}render(){return n.createElement(oi.Provider,{value:this.state},this.props.children)}}li.propTypes={context:i().any,children:i().any};const ci=N(li);function mi(e){return class extends n.Component{render(){return n.createElement(oi.Consumer,null,t=>n.createElement(e,ri({adminInternationalizationContext:t},this.props)))}}}class di extends n.Component{constructor(e){super(e),this.bindCallbacks()}async handleSaveClick(){try{await this.props.adminInternationalizationContext.save(),this.handleSaveSuccess()}catch(e){this.handleSaveError(e)}finally{this.props.adminInternationalizationContext.setProcessing(!1)}}isSaveEnabled(){return!this.props.adminInternationalizationContext.isProcessing()&&this.props.adminInternationalizationContext.hasLocaleChanges()}bindCallbacks(){this.handleSaveClick=this.handleSaveClick.bind(this)}async handleSaveSuccess(){await this.props.actionFeedbackContext.displaySuccess(this.props.t("The internationalization settings were updated."))}async handleSaveError(e){"UserAbortsOperationError"!==e.name&&(console.error(e),await this.handleError(e))}async handleError(e){await this.props.actionFeedbackContext.displayError(e.message)}render(){return n.createElement("div",{className:"actions-wrapper"},n.createElement("button",{className:"button primary form",id:"save-settings",type:"button",disabled:!this.isSaveEnabled(),onClick:this.handleSaveClick},n.createElement("span",null,n.createElement(f.x6,null,"Save"))))}}di.propTypes={context:i().object,adminInternationalizationContext:i().object,actionFeedbackContext:i().object,t:i().func};const ui=mi(m((0,f.CI)("common")(di)));class pi extends n.Component{constructor(e){super(e),this.bindCallbacks()}componentDidMount(){this.props.adminInternationalizationContext.findLocale()}componentWillUnmount(){this.props.administrationWorkspaceContext.resetDisplayAdministrationWorkspaceAction(),this.props.adminInternationalizationContext.clearContext()}bindCallbacks(){this.handleInputChange=this.handleInputChange.bind(this)}handleInputChange(e){this.props.adminInternationalizationContext.setLocale(e.target.value)}get supportedLocales(){return this.props.context.siteSettings.supportedLocales?this.props.context.siteSettings.supportedLocales.map(e=>({value:e.locale,label:e.label})):[]}render(){const e=this.props.adminInternationalizationContext.getLocale(),t=null!==this.props.adminInternationalizationContext.getCurrentLocale()&&this.props.adminInternationalizationContext.hasLocaleChanges();return n.createElement("div",{className:"row"},n.createElement("div",{className:"internationalisation-settings main-column"},n.createElement("div",{className:"main-content"},n.createElement("h3",{className:"title"},n.createElement(f.x6,null,"Internationalisation")),n.createElement("form",{className:"form"},n.createElement("div",{className:"select-wrapper input"},n.createElement("label",{htmlFor:"app-locale-input"},n.createElement(f.x6,null,"Language")),n.createElement(pn,{id:"locale-input",name:"locale",items:this.supportedLocales,value:e,onChange:this.handleInputChange}),n.createElement("p",null,n.createElement(f.x6,null,"The default language of the organisation."))))),t&&n.createElement("div",{className:"warning message"},n.createElement("div",null,n.createElement("p",null,n.createElement(f.x6,null,"Don't forget to save your settings to apply your modification."))))),n.createElement(ui,null),Xa(n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"Want to contribute?")),n.createElement("p",null,n.createElement(f.x6,null,"Your language is missing or you discovered an error in the translation, help us to improve passbolt.")),n.createElement("a",{className:"button",href:"https://www.passbolt.com/docs/contribute/translation/",target:"_blank",rel:"noopener noreferrer"},n.createElement(si,null),n.createElement("span",null,n.createElement(f.x6,null,"Contribute")))),document.getElementById("administration-help-panel")))}}pi.propTypes={context:i().object,administrationWorkspaceContext:i().object,adminInternationalizationContext:i().object,t:i().func};const hi=N(mi(Ne((0,f.CI)("common")(pi))));function gi(){return gi=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},getKeyInfo:()=>{},changePolicy:()=>{},changePublicKey:()=>{},hasPolicyChanges:()=>{},resetChanges:()=>{},downloadPrivateKey:()=>{},save:()=>{}});class bi extends n.Component{constructor(e){super(e),this.state=this.defaultState}get defaultState(){return{currentPolicy:null,policyChanges:{},findAccountRecoveryPolicy:this.findAccountRecoveryPolicy.bind(this),getKeyInfo:this.getKeyInfo.bind(this),changePolicy:this.changePolicy.bind(this),changePublicKey:this.changePublicKey.bind(this),hasPolicyChanges:this.hasPolicyChanges.bind(this),resetChanges:this.resetChanges.bind(this),downloadPrivateKey:this.downloadPrivateKey.bind(this),save:this.save.bind(this)}}async findAccountRecoveryPolicy(){if(!this.props.context.siteSettings.canIUse("accountRecovery"))return;const e=await this.props.context.port.request("passbolt.account-recovery.get-organization-policy");this.setState({currentPolicy:e})}changePolicy(e){const t=this.state.policyChanges;e===this.state.currentPolicy?.policy?delete t.policy:t.policy=e,"disabled"===e&&delete t.publicKey,this.setState({policyChanges:t})}changePublicKey(e){const t={...this.state.policyChanges,publicKey:e};this.setState({policyChanges:t})}hasPolicyChanges(){return Boolean(this.state.policyChanges?.publicKey)||Boolean(this.state.policyChanges?.policy)}async getKeyInfo(e){return e?this.props.context.port.request("passbolt.keyring.get-key-info",e):null}resetChanges(){this.setState({policyChanges:{}})}async downloadPrivateKey(e){await this.props.context.port.request("passbolt.account-recovery.download-organization-generated-key",e)}async save(e){const t=this.buildPolicySaveDto(),a=await this.props.context.port.request("passbolt.account-recovery.save-organization-policy",t,e);this.setState({currentPolicy:a,policyChanges:{}}),this.props.accountRecoveryContext.reloadAccountRecoveryPolicy()}buildPolicySaveDto(){const e={};return this.state.policyChanges.policy&&(e.policy=this.state.policyChanges.policy),this.state.policyChanges.publicKey&&(e.account_recovery_organization_public_key={armored_key:this.state.policyChanges.publicKey}),e}render(){return n.createElement(yi.Provider,{value:this.state},this.props.children)}}function fi(e){return class extends n.Component{render(){return n.createElement(yi.Consumer,null,t=>n.createElement(e,gi({adminAccountRecoveryContext:t},this.props)))}}}function Ei(){return Ei=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},stop:()=>{}});class wi extends n.Component{constructor(e){super(e),this.state=this.defaultState}get defaultState(){return{workflows:[],start:(e,t)=>{const a=(0,r.A)();return this.setState({workflows:[...this.state.workflows,{key:a,Workflow:e,workflowProps:t}]}),a},stop:async e=>this.setState({workflows:this.state.workflows.filter(t=>e!==t.key)})}}render(){return n.createElement(vi.Provider,{value:this.state},this.props.children)}}wi.displayName="WorkflowContextProvider",wi.propTypes={children:i().any};class ki extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.bindCallbacks(),this.createInputRef()}get defaultState(){return{processing:!1,key:"",keyError:"",password:"",passwordError:"",passwordWarning:"",hasAlreadyBeenValidated:!1,selectedFile:null}}bindCallbacks(){this.handleFormSubmit=this.handleFormSubmit.bind(this),this.handleCloseClick=this.handleCloseClick.bind(this),this.handleInputChange=this.handleInputChange.bind(this),this.handleKeyInputKeyUp=this.handleKeyInputKeyUp.bind(this),this.handlePasswordInputKeyUp=this.handlePasswordInputKeyUp.bind(this),this.handleSelectFile=this.handleSelectFile.bind(this),this.handleSelectOrganizationKeyFile=this.handleSelectOrganizationKeyFile.bind(this)}createInputRef(){this.keyInputRef=n.createRef(),this.fileUploaderRef=n.createRef(),this.passwordInputRef=n.createRef()}handleKeyInputKeyUp(){if(this.state.hasAlreadyBeenValidated){const e=this.validateKeyInput();this.setState(e)}}async handleSelectOrganizationKeyFile(e){const[t]=e.target.files,a=await this.readOrganizationKeyFile(t);this.fillOrganizationKey(a),this.setState({selectedFile:t}),this.state.hasAlreadyBeenValidated&&await this.validate()}readOrganizationKeyFile(e){const t=new FileReader;return new Promise((a,n)=>{t.onloadend=()=>{try{a(t.result)}catch(e){n(e)}},t.readAsText(e)})}fillOrganizationKey(e){this.setState({key:e})}validateKeyInput(){const e=this.state.key.trim();let t="";return e.length||(t=this.translate("An organization key is required.")),new Promise(e=>{this.setState({keyError:t},e)})}focusFirstFieldError(){this.state.keyError?this.keyInputRef.current.focus():this.state.passwordError&&this.passwordInputRef.current.focus()}handlePasswordInputKeyUp(){if(this.state.hasAlreadyBeenValidated)this.setState({passwordError:""});else{const e=this.state.password.length>=4096,t=this.translate("this is the maximum size for this field, make sure your data was not truncated"),a=e?t:"";this.setState({passwordWarning:a})}}handleInputChange(e){const t=e.target,a=t.value,n=t.name;this.setState({[n]:a})}handleSelectFile(){this.fileUploaderRef.current.click()}async handleFormSubmit(e){e.preventDefault(),this.state.processing||await this.save()}async save(){if(this.state.processing)return;if(this.setState({hasAlreadyBeenValidated:!0,processing:!0}),!await this.validate())return this.handleValidateError(),void this.setState({processing:!1});const e={armored_key:this.state.key,passphrase:this.state.password};try{await this.props.context.port.request("passbolt.account-recovery.validate-organization-private-key",e),await this.props.onSubmit(e),this.setState({processing:!1}),this.props.onClose()}catch(e){await this.handleSubmitError(e),this.setState({processing:!1})}}async handleSubmitError(e){"UserAbortsOperationError"!==e.name&&("WrongOrganizationRecoveryKeyError"===e.name?this.setState({expectedFingerprintError:e.expectedFingerprint}):"InvalidMasterPasswordError"===e.name?this.setState({passwordError:this.translate("This is not a valid passphrase.")}):"BadSignatureMessageGpgKeyError"===e.name||"GpgKeyError"===e.name?this.setState({keyError:e.message}):(console.error("Uncaught uncontrolled error"),this.onUnexpectedError(e)))}onUnexpectedError(e){const t={error:e};this.props.dialogContext.open($t,t)}handleValidateError(){this.focusFirstFieldError()}async validate(){return this.setState({keyError:"",passwordError:"",expectedFingerprintError:""}),await this.validateKeyInput(),""===this.state.keyError&&""===this.state.passwordError}hasAllInputDisabled(){return this.state.processing}handleCloseClick(){this.props.onClose()}formatFingerprint(e){if(!e)return n.createElement(n.Fragment,null);const t=e.toUpperCase().replace(/.{4}/g,"$& ");return n.createElement(n.Fragment,null,t.substr(0,24),n.createElement("br",null),t.substr(25))}get selectedFilename(){return this.state.selectedFile?this.state.selectedFile.name:""}get translate(){return this.props.t}render(){return n.createElement(qt,{title:this.translate("Organization Recovery Key"),onClose:this.handleCloseClick,disabled:this.state.processing,className:"provide-organization-recover-key-dialog"},n.createElement("form",{onSubmit:this.handleFormSubmit,noValidate:!0},n.createElement("div",{className:"form-content provide-organization-key"},n.createElement("div",{className:"input textarea required "+(this.state.keyError||this.state.expectedFingerprintError?"error":"")},n.createElement("label",{htmlFor:"organization-recover-form-key"},n.createElement(f.x6,null,"Enter the private key used by your organization for account recovery")),n.createElement("textarea",{id:"organization-recover-form-key",name:"key",value:this.state.key,onKeyUp:this.handleKeyInputKeyUp,onChange:this.handleInputChange,disabled:this.hasAllInputDisabled(),ref:this.keyInputRef,className:"required",placeholder:this.translate("Paste the OpenPGP Private key here"),required:"required",autoComplete:"off",autoFocus:!0})),n.createElement("div",{className:"input file"},n.createElement("input",{type:"file",id:"dialog-import-private-key",ref:this.fileUploaderRef,disabled:this.hasAllInputDisabled(),onChange:this.handleSelectOrganizationKeyFile}),n.createElement("label",{htmlFor:"dialog-import-private-key"},n.createElement(f.x6,null,"Select a file to import")),n.createElement("div",{className:"input-file-inline"},n.createElement("input",{type:"text",disabled:!0,placeholder:this.translate("No file selected"),defaultValue:this.selectedFilename}),n.createElement("button",{className:"button primary",type:"button",disabled:this.hasAllInputDisabled(),onClick:this.handleSelectFile},n.createElement("span",null,n.createElement(f.x6,null,"Choose a file")))),this.state.keyError&&n.createElement("div",{className:"key error-message"},this.state.keyError),this.state.expectedFingerprintError&&n.createElement("div",{className:"key error-message"},n.createElement(f.x6,null,"Error, this is not the current organization recovery key."),n.createElement("br",null),n.createElement(f.x6,null,"Expected fingerprint:"),n.createElement("br",null),n.createElement("br",null),n.createElement("span",{className:"fingerprint"},this.formatFingerprint(this.state.expectedFingerprintError)))),n.createElement("div",{className:"input-password-wrapper input "+(this.state.passwordError?"error":"")},n.createElement("label",{htmlFor:"generate-organization-key-form-password"},n.createElement(f.x6,null,"Organization key passphrase"),this.state.passwordWarning&&n.createElement(tt,null)),n.createElement(Za,{id:"generate-organization-key-form-password",name:"password",placeholder:this.translate("Passphrase"),autoComplete:"new-password",onKeyUp:this.handlePasswordInputKeyUp,value:this.state.password,securityToken:this.props.context.userSettings.getSecurityToken(),preview:!0,onChange:this.handleInputChange,disabled:this.hasAllInputDisabled(),inputRef:this.passwordInputRef}),this.state.passwordError&&n.createElement("div",{className:"password error-message"},this.state.passwordError),this.state.passwordWarning&&n.createElement("div",{className:"password warning-message"},n.createElement("strong",null,n.createElement(f.x6,null,"Warning:"))," ",this.state.passwordWarning))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement(gn,{disabled:this.hasAllInputDisabled(),onClick:this.handleCloseClick}),n.createElement(qs,{disabled:this.hasAllInputDisabled(),processing:this.state.processing,value:this.translate("Submit")}))))}}ki.propTypes={context:i().any.isRequired,onClose:i().func,onSubmit:i().func,actionFeedbackContext:i().any,dialogContext:i().object,t:i().func};const _i=N(h((0,f.CI)("common")(ki)));class xi extends n.Component{constructor(e){super(e),this.state=this.getDefaultState(),this.bindCallbacks()}getDefaultState(){return{processing:!1}}bindCallbacks(){this.handleSubmit=this.handleSubmit.bind(this),this.handleClose=this.handleClose.bind(this)}handleClose(){this.props.onClose()}get isProcessing(){return this.state.processing}async handleSubmit(e){if(e.preventDefault(),!this.isProcessing){this.setState({processing:!0});try{await this.props.onSubmit(),this.props.onClose()}catch(e){if(this.setState({processing:!1}),"UserAbortsOperationError"!==e.name)throw console.error("Uncaught uncontrolled error"),e}}}formatFingerprint(e){const t=(e=e||"").toUpperCase().replace(/.{4}/g,"$& ");return n.createElement(n.Fragment,null,t.substr(0,24),n.createElement("br",null),t.substr(25))}formatUserIds(e){return(e=e||[]).map((e,t)=>n.createElement(n.Fragment,{key:t},e.name,"<",e.email,">",n.createElement("br",null)))}formatDate(e){return Ds.c9.fromJSDate(new Date(e)).setLocale(this.props.context.locale).toLocaleString(Ds.c9.DATETIME_FULL)}get translate(){return this.props.t}render(){return n.createElement(qt,{title:this.translate("Save Settings Summary"),onClose:this.handleClose,disabled:this.state.processing,className:"save-recovery-account-settings-dialog"},n.createElement("form",{onSubmit:this.handleSubmit},n.createElement("div",{className:"form-content"},this.props.policy&&n.createElement(n.Fragment,null,n.createElement("label",null,n.createElement(f.x6,null,"New Account Recovery Policy")),n.createElement("div",{className:"account-recovery-setting-save"},n.createElement("p",{className:"name"},{mandatory:n.createElement(f.x6,null,"Prompt"),"opt-out":n.createElement(f.x6,null,"Optional, Opt-out"),"opt-in":n.createElement(f.x6,null,"Optional, Opt-in"),disabled:n.createElement(f.x6,null,"Disable")}[this.props.policy]),n.createElement("p",{className:"info"},{mandatory:n.createElement(n.Fragment,null,n.createElement(f.x6,null,"Every user is required to provide a copy of their private key and passphrase during setup."),n.createElement("br",null),n.createElement(f.x6,null,"Warning: You should inform your users not to store personal passwords.")),"opt-out":n.createElement(f.x6,null,"Every user will be prompted to provide a copy of their private key and passphrase by default during the setup, but they can opt out."),"opt-in":n.createElement(f.x6,null,"Every user can decide to provide a copy of their private key and passphrase by default during the setup, but they can opt in."),disabled:n.createElement(n.Fragment,null,n.createElement(f.x6,null,"Backup of the private key and passphrase will not be stored. This is the safest option."),n.createElement("br",null),n.createElement(f.x6,null,"Warning: If users lose their private key and passphrase they will not be able to recover their account."))}[this.props.policy]))),this.props.keyInfo&&n.createElement(n.Fragment,null,n.createElement("label",null,n.createElement(f.x6,null,"New Organization Recovery Key")),n.createElement("div",{className:"recovery-key-details"},n.createElement("table",{className:"table-info recovery-key"},n.createElement("tbody",null,n.createElement("tr",{className:"user-ids"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Uid")),n.createElement("td",{className:"value"},this.formatUserIds(this.props.keyInfo.user_ids))),n.createElement("tr",{className:"fingerprint"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Fingerprint")),n.createElement("td",{className:"value"},this.formatFingerprint(this.props.keyInfo.fingerprint))),n.createElement("tr",{className:"algorithm"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Algorithm")),n.createElement("td",{className:"value"},this.props.keyInfo.algorithm)),n.createElement("tr",{className:"key-length"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Key length")),n.createElement("td",{className:"value"},this.props.keyInfo.length)),n.createElement("tr",{className:"created"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Created")),n.createElement("td",{className:"value"},this.formatDate(this.props.keyInfo.created))),n.createElement("tr",{className:"expires"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Expires")),n.createElement("td",{className:"value",title:this.props.keyInfo.expires},Hs(this.props.keyInfo.expires,this.props.t,this.props.context.locale))))))),n.createElement("div",{className:"warning message no-margin"},n.createElement(f.x6,null,"Please review carefully this configuration as it will not be trivial to change this later."))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement("a",{target:"_blank",rel:"noopener noreferrer",href:"https://www.passbolt.com/docs/admin/authentication/account-recovery/",className:"button button-left "+(this.isProcessing?"disabled":"")},n.createElement(f.x6,null,"Learn more")),n.createElement(gn,{onClick:this.handleClose,disabled:this.isProcessing}),n.createElement(qs,{value:this.translate("Save"),disabled:this.isProcessing,processing:this.isProcessing,warning:!0}))))}}xi.propTypes={context:i().any,onClose:i().func,onSubmit:i().func,policy:i().string,keyInfo:i().object,t:i().func};const Si=N((0,f.CI)("common")(xi));class Ci extends n.Component{constructor(e){super(e),this.bindCallbacks()}componentDidMount(){this.displayConfirmSummaryDialog()}bindCallbacks(){this.handleCloseDialog=this.handleCloseDialog.bind(this),this.handleConfirmSave=this.handleConfirmSave.bind(this),this.handleSave=this.handleSave.bind(this),this.handleError=this.handleError.bind(this)}async displayConfirmSummaryDialog(){this.props.dialogContext.open(Si,{policy:this.props.adminAccountRecoveryContext.policyChanges?.policy,keyInfo:await this.getNewOrganizationKeyInfo(),onClose:this.handleCloseDialog,onSubmit:this.handleConfirmSave})}getNewOrganizationKeyInfo(){const e=this.props.adminAccountRecoveryContext.policyChanges?.publicKey;return e?this.props.adminAccountRecoveryContext.getKeyInfo(e):null}displayProvideAccountRecoveryOrganizationKeyDialog(){this.props.dialogContext.open(_i,{onClose:this.handleCloseDialog,onSubmit:this.handleSave})}handleCloseDialog(){this.props.onStop()}async handleConfirmSave(){Boolean(this.props.adminAccountRecoveryContext.currentPolicy?.account_recovery_organization_public_key)?this.displayProvideAccountRecoveryOrganizationKeyDialog():await this.handleSave()}async handleSave(e=null){try{await this.props.adminAccountRecoveryContext.save(e),await this.props.actionFeedbackContext.displaySuccess(this.translate("The organization recovery policy has been updated successfully")),this.props.onStop()}catch(e){this.handleError(e)}}handleError(e){if(["UserAbortsOperationError","WrongOrganizationRecoveryKeyError","InvalidMasterPasswordError","BadSignatureMessageGpgKeyError","GpgKeyError"].includes(e.name))throw e;"PassboltApiFetchError"===e.name&&e?.data?.body?.account_recovery_organization_public_key?.fingerprint?.isNotAccountRecoveryOrganizationPublicKeyFingerprintRule?this.props.dialogContext.open($t,{error:new Error(this.translate("The new organization recovery key should not be a formerly used organization recovery key."))}):this.props.dialogContext.open($t,{error:e}),this.props.onStop()}get translate(){return this.props.t}render(){return n.createElement(n.Fragment,null)}}Ci.propTypes={dialogContext:i().any,adminAccountRecoveryContext:i().any,actionFeedbackContext:i().object,context:i().object,onStop:i().func.isRequired,t:i().func};const Ni=N(h(m(fi((0,f.CI)("common")(Ci)))));class Ti extends n.Component{constructor(e){super(e),this.bindCallbacks()}bindCallbacks(){this.handleSaveClick=this.handleSaveClick.bind(this),this.handleEditSubscriptionClick=this.handleEditSubscriptionClick.bind(this)}handleSaveClick(){this.props.workflowContext.start(Ni,{})}handleEditSubscriptionClick(){this.props.adminAccountRecoveryContext.resetChanges()}isSaveEnabled(){if(!this.props.adminAccountRecoveryContext.hasPolicyChanges())return!1;const e=this.props.adminAccountRecoveryContext.policyChanges,t=this.props.adminAccountRecoveryContext.currentPolicy;if(e?.policy===Be.POLICY_DISABLED)return!0;const a=e.publicKey||t?.account_recovery_organization_public_key?.armored_key;return!(!Boolean(e.policy)||!Boolean(a))||t.policy!==Be.POLICY_DISABLED&&Boolean(e.publicKey)}isResetEnabled(){return this.props.adminAccountRecoveryContext.hasPolicyChanges()}render(){return n.createElement("div",{className:"actions-wrapper"},n.createElement("div",{className:"left-actions-wrapper"},n.createElement("button",{type:"button",className:"button secondary",disabled:!this.isResetEnabled(),onClick:this.handleEditSubscriptionClick},n.createElement("span",null,n.createElement(f.x6,null,"Reset settings")))),n.createElement("button",{type:"button",className:"button primary form",disabled:!this.isSaveEnabled(),onClick:this.handleSaveClick},n.createElement("span",null,n.createElement(f.x6,null,"Save"))))}}Ti.propTypes={adminAccountRecoveryContext:i().object,workflowContext:i().any};const Ai=function(e){return class extends n.Component{render(){return n.createElement(vi.Consumer,null,t=>n.createElement(e,Ei({workflowContext:t},this.props)))}}}(fi((0,f.CI)("common")(Ti)));class Ii extends n.Component{constructor(e){super(e),this.bindCallback()}bindCallback(){this.handleClick=this.handleClick.bind(this)}handleClick(){this.props.onClick(this.props.name)}render(){return n.createElement("li",{className:"tab "+(this.props.isActive?"active":"")},n.createElement("button",{type:"button",className:"tab-link",onClick:this.handleClick},this.props.name))}}Ii.propTypes={name:i().string,type:i().string.isRequired,isActive:i().bool,onClick:i().func,children:i().any};const Ri=Ii;class Pi extends n.Component{constructor(e){super(e),this.state=this.getDefaultState(e),this.bindCallback()}getDefaultState(e){return{activeTabName:e.activeTabName}}bindCallback(){this.handleTabClick=this.handleTabClick.bind(this)}handleTabClick(e){this.setState({activeTabName:e.type}),"function"==typeof e.onClick&&e.onClick()}render(){return n.createElement("div",{className:"tabs"},n.createElement("ul",{className:"tabs-nav"},this.props.children.map(({key:e,props:t})=>n.createElement(Ri,{key:e,name:t.name,type:t.type,onClick:()=>this.handleTabClick(t),isActive:t.type===this.state.activeTabName}))),n.createElement("div",{className:"tabs-active-content"},this.props.children.find(e=>e.props.type===this.state.activeTabName).props.children))}}Pi.propTypes={activeTabName:i().string,children:i().any};const Di=Pi;class Oi extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.bindCallbacks(),this.createInputRef()}get defaultState(){return{processing:!1,key:"",keyError:"",hasAlreadyBeenValidated:!1,selectedFile:null}}bindCallbacks(){this.handleSelectFile=this.handleSelectFile.bind(this),this.handleFormSubmit=this.handleFormSubmit.bind(this),this.handleInputChange=this.handleInputChange.bind(this),this.handleSelectOrganizationKeyFile=this.handleSelectOrganizationKeyFile.bind(this)}createInputRef(){this.keyInputRef=n.createRef(),this.fileUploaderRef=n.createRef()}async handleSelectOrganizationKeyFile(e){const[t]=e.target.files,a=await this.readOrganizationKeyFile(t);this.setState({key:a,selectedFile:t})}readOrganizationKeyFile(e){const t=new FileReader;return new Promise((a,n)=>{t.onloadend=()=>{try{a(t.result)}catch(e){n(e)}},t.readAsText(e)})}async validateKeyInput(){const e=this.state.key.trim();return""===e?Promise.reject(new Error(this.translate("The key can't be empty."))):await this.props.context.port.request("passbolt.account-recovery.validate-organization-key",e)}async validate(){return this.setState({keyError:""}),await this.validateKeyInput().then(()=>!0).catch(e=>(this.setState({keyError:e.message}),!1))}handleInputChange(e){const t=e.target;this.setState({[t.name]:t.value})}handleSelectFile(){this.fileUploaderRef.current.click()}async handleFormSubmit(e){e.preventDefault(),this.state.processing||await this.save()}async save(){if(!this.state.processing){if(this.setState({hasAlreadyBeenValidated:!0,processing:!0}),!await this.validate())return this.handleValidateError(),void this.setState({processing:!1});await this.props.onUpdateOrganizationKey(this.state.key.trim())}}handleValidateError(){this.focusFieldError()}focusFieldError(){this.state.keyError&&this.keyInputRef.current.focus()}hasAllInputDisabled(){return this.state.processing}get translate(){return this.props.t}get selectedFilename(){return this.state.selectedFile?this.state.selectedFile.name:""}render(){return n.createElement("form",{onSubmit:this.handleFormSubmit,noValidate:!0},n.createElement("div",{className:"form-content import-organization-key"},n.createElement("div",{className:"input textarea required "+(this.state.keyError?"error":"")},n.createElement("label",{htmlFor:"organization-recover-form-key"},n.createElement(f.x6,null,"Import an OpenPGP Public key")),n.createElement("textarea",{id:"organization-recover-form-key",name:"key",value:this.state.key,onKeyUp:this.handleKeyInputKeyUp,onChange:this.handleInputChange,disabled:this.hasAllInputDisabled(),ref:this.keyInputRef,className:"required",placeholder:this.translate("Add Open PGP Public key"),required:"required",autoComplete:"off",autoFocus:!0})),n.createElement("div",{className:"input file"},n.createElement("input",{type:"file",id:"dialog-import-private-key",ref:this.fileUploaderRef,disabled:this.hasAllInputDisabled(),onChange:this.handleSelectOrganizationKeyFile}),n.createElement("label",{htmlFor:"dialog-import-private-key"},n.createElement(f.x6,null,"Select a file to import")),n.createElement("div",{className:"input-file-inline"},n.createElement("input",{type:"text",disabled:!0,placeholder:this.translate("No file selected"),defaultValue:this.selectedFilename}),n.createElement("button",{className:"button primary",type:"button",disabled:this.hasAllInputDisabled(),onClick:this.handleSelectFile},n.createElement("span",null,n.createElement(f.x6,null,"Choose a file")))),this.state.keyError&&n.createElement("div",{className:"key error-message"},this.state.keyError)),!this.state.hasAlreadyBeenValidated&&n.createElement("div",{className:"message notice no-margin"},n.createElement(jt,{className:"svg-icon info baseline"}),n.createElement("strong",null,n.createElement(f.x6,null,"Pro tip"),":")," ",n.createElement(f.x6,null,"Learn how to"," ",n.createElement("a",{href:"https://www.passbolt.com/docs/admin/faq/generate-openpgp-key/",target:"_blank",rel:"noopener noreferrer"},"generate a key separately.")))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement(gn,{disabled:this.hasAllInputDisabled(),onClick:this.props.onClose}),n.createElement(qs,{disabled:this.hasAllInputDisabled(),processing:this.state.processing,value:this.translate("Apply")})))}}Oi.propTypes={context:i().object,onUpdateOrganizationKey:i().func,onClose:i().func,t:i().func};const Mi=N((0,f.CI)("common")(Oi)),Ui={"en-UK":["abdominal","acclimate","accompany","activator","acuteness","aerospace","affecting","affection","affidavit","affiliate","afflicted","afterglow","afterlife","aftermath","aftermost","afternoon","aggregate","agonizing","agreeable","agreeably","agreement","alabaster","albatross","algorithm","alienable","alongside","amazingly","ambiguity","ambiguous","ambitious","ambulance","amendable","amendment","amplifier","amusement","anaerobic","anatomist","angelfish","angriness","anguished","animating","animation","animosity","announcer","answering","antarctic","anthology","antiquely","antiquity","antitoxic","antitrust","antiviral","antivirus","appealing","appeasing","appendage","appetizer","appliance","applicant","appointee","appraisal","appraiser","apprehend","arbitrary","arbitrate","armadillo","arrogance","ascension","ascertain","asparagus","astrology","astronaut","astronomy","atrocious","attendant","attention","attentive","attractor","attribute","audacious","augmented","authentic","autograph","automaker","automated","automatic","autopilot","available","avalanche","backboard","backboned","backfield","backlands","backlight","backpedal","backshift","backspace","backstage","backtrack","backwater","bacterium","bagginess","balancing","bannister","barometer","barracuda","barricade","bartender","basically","battalion","battering","blanching","blandness","blaspheme","blasphemy","blatantly","blunderer","bodacious","boogeyman","boogieman","boondocks","borrowing","botanical","boundless","bountiful","breeching","brilliant","briskness","broadband","broadcast","broadness","broadside","broadways","bronchial","brownnose","brutishly","buccaneer","bucktooth","buckwheat","bulginess","bulldozer","bullfight","bunkhouse","cabdriver","calculate","calibrate","camcorder","canopener","capillary","capricorn","captivate","captivity","cardboard","cardstock","carefully","caregiver","caretaker","carnation","carnivore","carpenter","carpentry","carrousel","cartridge","cartwheel","catatonic","catchable","cathedral","cattishly","caucasian","causation","cauterize","celestial","certainly","certainty","certified","challenge","chamomile","chaperone","character","charbroil","chemicals","cherisher","chihuahua","childcare","childhood","childless","childlike","chokehold","circulate","clamshell","clergyman","clubhouse","clustered","coagulant","coastland","coastline","cofounder","cognition","cognitive","coherence","collected","collector","collision","commodity","commodore","commotion","commuting","compacted","compacter","compactly","compactor","companion","component","composite","composure","comprised","computing","concerned","concierge","condiment","condition","conducive","conductor","confidant","confident","confiding","configure","confining","confusing","confusion","congenial","congested","conjoined","connected","connector","consensus","consoling","consonant","constable","constrain","constrict","construct","consuming","container","contented","contently","contusion","copartner","cornbread","cornfield","cornflake","cornstalk","corporate","corroding","corrosive","cosmetics","cosponsor","countable","countdown","countless","crabgrass","craftsman","craftwork","cranberry","craziness","creamlike","creatable","crestless","crispness","crudeness","cruelness","crummiest","crunching","crushable","cubbyhole","culminate","cultivate","cupbearer","curliness","curvature","custodian","customary","customize","cytoplasm","cytoplast","dandelion","daredevil","darkening","darwinism","dastardly","deafening","dealmaker","debatable","decathlon","deceiving","deception","deceptive","decidable","decimeter","decompose","decorated","decorator","dedicator","defection","defective","defendant","defensive","deflation","deflected","deflector","degrading","dehydrate","delegator","delicious","delighted","delirious","deliverer","demanding","demeaning","democracy","demystify","denatured","deodorant","deodorize","departure","depletion","depravity","deprecate","desecrate","deserving","designate","designing","deskbound","destitute","detection","detective","detention","detergent","detonator","deviation","devotedly","devouring","dexterity","dexterous","diagnoses","diagnosis","diaphragm","dictation","difficult","diffusion","diffusive","diligence","dinginess","direction","directive","directory","dirtiness","disbelief","discharge","discourse","disengage","disfigure","disinfect","disliking","dislocate","dismantle","disparate","disparity","dispersal","dispersed","disperser","displease","disregard","dividable","divisible","divisibly","dizziness","dollhouse","doorframe","dormitory","dragonfly","dragonish","drainable","drainpipe","dramatize","dreadlock","dreamboat","dreamland","dreamless","dreamlike","drinkable","drop-down","dubiously","duplicate","duplicity","dwindling","earthlike","earthling","earthworm","eastbound","eastcoast","eccentric","ecologist","economist","ecosphere","ecosystem","education","effective","efficient","eggbeater","egomaniac","egotistic","elaborate","eldercare","electable","elevating","elevation","eliminate","elongated","eloquence","elsewhere","embattled","embellish","embroider","emergency","emphasize","empirical","emptiness","enactment","enchanted","enchilada","enclosure","encounter","encourage","endearing","endocrine","endorphin","endowment","endurable","endurance","energetic","engraving","enigmatic","enjoyable","enjoyably","enjoyment","enlarging","enlighten","entangled","entertain","entourage","enunciate","epidermal","epidermis","epileptic","equipment","equivocal","eradicate","ergonomic","escalator","escapable","esophagus","espionage","essential","establish","estimator","estranged","ethically","euphemism","evaluator","evaporate","everglade","evergreen","everybody","evolution","excavator","exceeding","exception","excitable","excluding","exclusion","exclusive","excretion","excretory","excursion","excusable","excusably","exemplary","exemplify","exemption","exerciser","exfoliate","exonerate","expansion","expansive","expectant","expedited","expediter","expensive","expletive","exploring","exposable","expulsion","exquisite","extending","extenuate","extortion","extradite","extrovert","extruding","exuberant","facecloth","faceplate","facsimile","factsheet","fanciness","fantasize","fantastic","favorable","favorably","ferocious","festivity","fidgeting","financial","finishing","flagstick","flagstone","flammable","flashback","flashbulb","flashcard","flattered","flatterer","flavorful","flavoring","footboard","footprint","fragility","fragrance","fraternal","freemason","freestyle","freezable","frequency","frightful","frigidity","frivolous","frostbite","frostlike","frugality","frustrate","gainfully","gallantly","gallstone","galvanize","gathering","gentleman","geography","geologist","geometric","geriatric","germicide","germinate","germproof","gestation","gibberish","giddiness","gigahertz","gladiator","glamorous","glandular","glorified","glorifier","glutinous","goldsmith","goofiness","graceless","gradation","gradually","grappling","gratified","gratitude","graveness","graveyard","gravitate","greedless","greyhound","grievance","grimacing","griminess","grumbling","guacamole","guileless","gumminess","habitable","hamburger","hamstring","handbrake","handclasp","handcraft","handiness","handiwork","handlebar","handprint","handsfree","handshake","handstand","handwoven","handwrite","hankering","haphazard","happening","happiness","hardcover","hardening","hardiness","hardwired","harmonica","harmonics","harmonize","hastiness","hatchback","hatchling","headboard","headcount","headdress","headfirst","headphone","headpiece","headscarf","headstand","headstone","heaviness","heftiness","hemstitch","herbicide","hesitancy","humiliate","humongous","humorless","hunchback","hundredth","hurricane","huskiness","hydration","hydroxide","hyperlink","hypertext","hypnotism","hypnotist","hypnotize","hypocrisy","hypocrite","ibuprofen","idealness","identical","illicitly","imaginary","imitation","immersion","immorally","immovable","immovably","impatient","impending","imperfect","implement","implicate","implosion","implosive","important","impotence","impotency","imprecise","impromptu","improving","improvise","imprudent","impulsive","irregular","irritable","irritably","isolating","isolation","italicize","itinerary","jackknife","jailbreak","jailhouse","jaywalker","jeeringly","jockstrap","jolliness","joylessly","jubilance","judgingly","judiciary","juiciness","justifier","kilometer","kinswoman","laborious","landowner","landscape","landslide","lankiness","legislate","legwarmer","lethargic","levitator","liability","librarian","limelight","litigator","livestock","lubricant","lubricate","luckiness","lucrative","ludicrous","luminance","lumpiness","lunchroom","lunchtime","luridness","lustfully","lustiness","luxurious","lyrically","machinist","magnesium","magnetism","magnetize","magnifier","magnitude","majorette","makeshift","malformed","mammogram","mandatory","manhandle","manicotti","manifesto","manliness","marauding","margarine","margarita","marmalade","marshland","marsupial","marvelous","masculine","matchbook","matchless","maternity","matriarch","matrimony","mayflower","modulator","moistness","molecular","monastery","moneybags","moneyless","moneywise","monologue","monstrous","moodiness","moonlight","moonscape","moonshine","moonstone","morbidity","mortality","mortician","mortified","mothproof","motivator","motocross","mountable","mousiness","moustache","multitask","multitude","mummified","municipal","murkiness","murmuring","mushiness","muskiness","mustiness","mutilated","mutilator","mystified","nanometer","nastiness","navigator","nebulizer","neglector","negligent","negotiate","neurology","ninetieth","numerator","nuttiness","obedience","oblivious","obnoxious","obscurity","observant","observing","obsession","obsessive","obstinate","obtrusive","occultist","occupancy","onslaught","operating","operation","operative","oppressed","oppressor","opulently","outnumber","outplayed","outskirts","outsource","outspoken","overblown","overboard","overbuilt","overcrowd","overdraft","overdrawn","overdress","overdrive","overeager","overeater","overexert","overgrown","overjoyed","overlabor","overlying","overnight","overplant","overpower","overprice","overreach","overreact","overshoot","oversight","oversized","oversleep","overspend","overstate","overstock","overstuff","oversweet","overthrow","overvalue","overwrite","oxidation","oxidizing","pacemaker","palatable","palpitate","panhandle","panoramic","pantomime","pantyhose","paparazzi","parachute","paragraph","paralegal","paralyses","paralysis","paramedic","parameter","paramount","parasitic","parchment","partition","partridge","passenger","passivism","patchwork","paternity","patriarch","patronage","patronize","pavestone","pediatric","pedometer","penholder","penniless","pentagram","percolate","perennial","perfected","perfectly","periscope","perkiness","perpetual","perplexed","persecute","persevere","persuaded","persuader","pessimism","pessimist","pesticide","petroleum","petticoat","pettiness","phonebook","phoniness","phosphate","plausible","plausibly","playgroup","playhouse","playmaker","plaything","plentiful","plexiglas","plutonium","pointless","polyester","polygraph","porcupine","portfolio","postnasal","powdering","prankster","preaching","precision","predefine","preflight","preformed","pregnancy","preheated","prelaunch","preoccupy","preschool","prescribe","preseason","president","presuming","pretended","pretender","prevalent","prewashed","primarily","privatize","proactive","probation","probiotic","procedure","procreate","profanity","professed","professor","profusely","prognosis","projector","prolonged","promenade","prominent","promotion","pronounce","proofread","propeller","proponent","protector","prototype","protozoan","providing","provoking","provolone","proximity","prudishly","publisher","pulmonary","pulverize","punctuate","punctured","pureblood","purgatory","purposely","pursuable","pushchair","pushiness","pyromania","qualified","qualifier","quartered","quarterly","quickness","quicksand","quickstep","quintuple","quizzical","quotation","radiantly","radiation","rancidity","ravishing","reacquire","reanalyze","reappoint","reapprove","rearrange","rebalance","recapture","recharger","recipient","reclining","reclusive","recognize","recollect","reconcile","reconfirm","reconvene","rectangle","rectified","recycling","reexamine","referable","reference","refinance","reflected","reflector","reformist","refueling","refurbish","refurnish","refutable","registrar","regretful","regulator","rehydrate","reimburse","reiterate","rejoicing","relapsing","relatable","relenting","relieving","reluctant","remindful","remission","remodeler","removable","rendering","rendition","renewable","renewably","renovator","repackage","repacking","repayment","repossess","repressed","reprimand","reprocess","reproduce","reprogram","reptilian","repugnant","repulsion","repulsive","repurpose","reputable","reputably","requisite","reshuffle","residence","residency","resilient","resistant","resisting","resurface","resurrect","retaining","retaliate","retention","retrieval","retriever","reverence","reversing","reversion","revisable","revivable","revocable","revolving","riverbank","riverboat","riverside","rockiness","rockslide","roundness","roundworm","runaround","sacrament","sacrifice","saddlebag","safeguard","safehouse","salvaging","salvation","sanctuary","sandblast","sandpaper","sandstone","sandstorm","sanitizer","sappiness","sarcastic","sasquatch","satirical","satisfied","sauciness","saxophone","scapegoat","scarecrow","scariness","scavenger","schematic","schilling","scientist","scorebook","scorecard","scoreless","scoundrel","scrambled","scrambler","scrimmage","scrounger","sculpture","secluding","seclusion","sectional","selection","selective","semicolon","semifinal","semisweet","sensation","sensitive","sensitize","sensually","september","sequester","serotonin","sevenfold","seventeen","shadiness","shakiness","sharpener","sharpness","shiftless","shininess","shivering","shortcake","shorthand","shortlist","shortness","shortwave","showpiece","showplace","shredding","shrubbery","shuffling","silliness","similarly","simmering","sincerity","situation","sixtyfold","skedaddle","skintight","skyrocket","slackness","slapstick","sliceable","slideshow","slighting","slingshot","slouching","smartness","smilingly","smokeless","smokiness","smuggling","snowboard","snowbound","snowdrift","snowfield","snowflake","snowiness","snowstorm","spearfish","spearhead","spearmint","spectacle","spectator","speculate","spellbind","spendable","spherical","spiritism","spiritual","splashing","spokesman","spotlight","sprinkled","sprinkler","squatting","squealing","squeamish","squeezing","squishier","stability","stabilize","stainable","stainless","stalemate","staleness","starboard","stargazer","starlight","startling","statistic","statutory","steadfast","steadying","steerable","steersman","stegosaur","sterility","sterilize","sternness","stiffness","stillness","stimulant","stimulate","stipulate","stonewall","stoneware","stonework","stoplight","stoppable","stopwatch","storeroom","storewide","straggler","straining","strangely","strategic","strenuous","strongbox","strongman","structure","stumbling","stylishly","subarctic","subatomic","subdivide","subheader","submarine","submersed","submitter","subscribe","subscript","subsector","subsiding","subsidize","substance","subsystem","subwoofer","succulent","suffering","suffocate","sulphuric","superbowl","superglue","superhero","supernova","supervise","supremacy","surcharge","surfacing","surfboard","surrender","surrogate","surviving","sustained","sustainer","swaddling","swampland","swiftness","swimmable","symphonic","synthesis","synthetic","tableware","tackiness","taekwondo","tarantula","tastiness","theatrics","thesaurus","thickness","thirstily","thirsting","threefold","throbbing","throwaway","throwback","thwarting","tightness","tightrope","tinderbox","tiptoeing","tradition","trailside","transform","translate","transpire","transport","transpose","trapezoid","treachery","treadmill","trembling","tribesman","tributary","trickster","trifocals","trimester","troubling","trustable","trustless","turbulent","twentieth","twiddling","twistable","ultimatum","umbilical","unabashed","unadorned","unadvised","unaligned","unaltered","unarmored","unashamed","unaudited","unbalance","unblended","unblessed","unbounded","unbraided","unbuckled","uncertain","unchanged","uncharted","unclaimed","unclamped","unclothed","uncolored","uncorrupt","uncounted","uncrushed","uncurious","undamaged","undaunted","undecided","undefined","undercoat","undercook","underdone","underfeed","underfoot","undergrad","underhand","underline","underling","undermine","undermost","underpaid","underpass","underrate","undertake","undertone","undertook","underwear","underwent","underwire","undesired","undiluted","undivided","undrafted","undrilled","uneatable","unelected","unengaged","unethical","unexpired","unexposed","unfailing","unfeeling","unfitting","unfixable","unfocused","unfounded","unfrosted","ungreased","unguarded","unhappily","unhealthy","unhearing","unhelpful","unhitched","uniformed","uniformly","unimpeded","uninjured","uninstall","uninsured","uninvited","unisexual","universal","unknotted","unknowing","unlearned","unleveled","unlighted","unlikable","unlimited","unlivable","unlocking","unlovable","unluckily","unmanaged","unmasking","unmatched","unmindful","unmixable","unmovable","unnamable","unnatural","unnerving","unnoticed","unopposed","unpainted","unpiloted","unplanned","unplanted","unpleased","unpledged","unpopular","unraveled","unreached","unreeling","unrefined","unrelated","unretired","unrevised","unrivaled","unroasted","unruffled","unscathed","unscented","unsecured","unselfish","unsettled","unshackle","unsheathe","unshipped","unsightly","unskilled","unspoiled","unstaffed","unstamped","unsterile","unstirred","unstopped","unstuffed","unstylish","untainted","untangled","untoasted","untouched","untracked","untrained","untreated","untrimmed","unvarying","unveiling","unvisited","unwarlike","unwatched","unwelcome","unwilling","unwitting","unwomanly","unworldly","unworried","unwrapped","unwritten","upcountry","uplifting","urologist","uselessly","vagrantly","vagueness","valuables","vaporizer","vehicular","veneering","ventricle","verbalize","vertebrae","viability","viewpoint","vindicate","violation","viscosity","vivacious","vividness","wackiness","washbasin","washboard","washcloth","washhouse","washstand","whimsical","wieldable","wikipedia","willfully","willpower","wolverine","womanhood","womankind","womanless","womanlike","worrisome","worsening","worshiper","wrongdoer","wrongness","yesterday","zestfully","zigzagged","zookeeper","zoologist","abnormal","abrasion","abrasive","abruptly","absentee","absently","absinthe","absolute","abstract","accuracy","accurate","accustom","achiness","acquaint","activate","activism","activist","activity","aeration","aerobics","affected","affluent","aflutter","agnostic","agreeing","alienate","alkaline","alkalize","almighty","alphabet","although","altitude","aluminum","amaretto","ambiance","ambition","amicably","ammonium","amniotic","amperage","amusable","anaconda","aneurism","animator","annotate","annoying","annually","anointer","anteater","antelope","antennae","antibody","antidote","antihero","antiques","antirust","anyplace","anything","anywhere","appendix","appetite","applause","approach","approval","aptitude","aqueduct","ardently","arguable","arguably","armchair","arrogant","aspirate","astonish","atlantic","atonable","attendee","attitude","atypical","audacity","audience","audition","autistic","avenging","aversion","aviation","babbling","backache","backdrop","backfire","backhand","backlash","backless","backpack","backrest","backroom","backside","backslid","backspin","backstab","backtalk","backward","backwash","backyard","bacteria","baffling","baguette","bakeshop","balsamic","banister","bankable","bankbook","banknote","bankroll","barbecue","bargraph","baritone","barrette","barstool","barterer","battered","blatancy","blighted","blinking","blissful","blizzard","bloating","bloomers","blooming","blustery","boastful","boasting","bondless","bonehead","boneless","bonelike","bootlace","borrower","botanist","bottling","bouncing","bounding","breeches","breeding","brethren","broiling","bronzing","browbeat","browsing","bruising","brunette","brussels","bubbling","buckshot","buckskin","buddhism","buddhist","bullfrog","bullhorn","bullring","bullseye","bullwhip","bunkmate","busybody","cadillac","calamari","calamity","calculus","camisole","campfire","campsite","canister","cannabis","capacity","cardigan","cardinal","careless","carmaker","carnival","cartload","cassette","casually","casualty","catacomb","catalyst","catalyze","catapult","cataract","catching","catering","catfight","cathouse","cautious","cavalier","celibacy","celibate","ceramics","ceremony","cesarean","cesspool","chaffing","champion","chaplain","charcoal","charging","charting","chastise","chastity","chatroom","chatting","cheating","chewable","childish","chirping","chitchat","chivalry","chloride","chlorine","choosing","chowtime","cilantro","cinnamon","circling","circular","citation","clambake","clanking","clapping","clarinet","clavicle","clerical","climatic","clinking","closable","clothing","clubbing","clumsily","coasting","coauthor","coeditor","cogwheel","coherent","cohesive","coleslaw","coliseum","collapse","colonial","colonist","colonize","colossal","commence","commerce","composed","composer","compound","compress","computer","conceded","conclude","concrete","condense","confetti","confider","confined","conflict","confound","confront","confused","congrats","congress","conjuror","constant","consumer","contempt","contents","contrite","cornball","cornhusk","cornmeal","coronary","corporal","corridor","cosigner","counting","covenant","coveting","coziness","crabbing","crablike","crabmeat","cradling","craftily","crawfish","crawlers","crawling","crayfish","creasing","creation","creative","creature","credible","credibly","crescent","cresting","crewless","crewmate","cringing","crisping","criteria","crumpled","cruncher","crusader","crushing","cucumber","cufflink","culinary","culpable","cultural","customer","cylinder","daffodil","daintily","dallying","dandruff","dangling","daringly","darkened","darkness","darkroom","datebook","daughter","daunting","daybreak","daydream","daylight","dazzling","deafness","debating","debtless","deceased","deceiver","december","decipher","declared","decrease","dedicate","deepness","defacing","defender","deferral","deferred","defiance","defiling","definite","deflator","deforest","degraded","degrease","dejected","delegate","deletion","delicacy","delicate","delirium","delivery","delusion","demeanor","democrat","demotion","deniable","departed","deplored","depraved","deputize","deranged","designed","designer","deskwork","desolate","destruct","detached","detector","detonate","detoxify","deviancy","deviator","devotion","devourer","devoutly","diabetes","diabetic","diabolic","diameter","dictator","diffused","diffuser","dilation","diligent","diminish","directed","directly","direness","disabled","disagree","disallow","disarray","disaster","disburse","disclose","discolor","discount","discover","disgrace","dislodge","disloyal","dismount","disorder","dispatch","dispense","displace","disposal","disprove","dissuade","distance","distaste","distinct","distract","distress","district","distrust","dividend","dividers","dividing","divinely","divinity","division","divisive","divorcee","doctrine","document","domelike","domestic","dominion","dominoes","donation","doorbell","doorknob","doornail","doorpost","doorstep","doorstop","doubling","dragging","dragster","drainage","dramatic","dreadful","dreamily","drearily","drilling","drinking","dripping","drivable","driveway","dropkick","drowsily","duckbill","duckling","ducktail","dullness","dumpling","dumpster","duration","dwelling","dynamite","dyslexia","dyslexic","earphone","earpiece","earplugs","easiness","eastward","economic","edginess","educated","educator","eggplant","eggshell","election","elective","elephant","elevator","eligible","eligibly","elliptic","eloquent","embezzle","embolism","emission","emoticon","empathic","emphases","emphasis","emphatic","employed","employee","employer","emporium","encircle","encroach","endanger","endeared","endpoint","enduring","energize","enforced","enforcer","engaging","engraved","engraver","enjoying","enlarged","enlisted","enquirer","entering","enticing","entrench","entryway","envelope","enviable","enviably","envision","epidemic","epidural","epilepsy","epilogue","epiphany","equation","erasable","escalate","escapade","escapist","escargot","espresso","esteemed","estimate","estrogen","eternity","evacuate","evaluate","everyday","everyone","evidence","excavate","exchange","exciting","existing","exorcism","exorcist","expenses","expiring","explicit","exponent","exporter","exposure","extended","exterior","external","fabulous","facebook","facedown","faceless","facelift","facility","familiar","famished","fastball","fastness","favoring","favorite","felt-tip","feminine","feminism","feminist","feminize","fernlike","ferocity","festival","fiddling","fidelity","fiftieth","figurine","filtrate","finalist","finalize","fineness","finished","finisher","fiscally","flagpole","flagship","flanking","flannels","flashily","flashing","flatfoot","flatness","flattery","flatware","flatworm","flavored","flaxseed","flogging","flounder","flypaper","follicle","fondling","fondness","football","footbath","footgear","foothill","foothold","footless","footnote","footpath","footrest","footsore","footwear","footwork","founding","fountain","fraction","fracture","fragment","fragrant","freckled","freckles","freebase","freefall","freehand","freeload","freeness","freeware","freewill","freezing","frenzied","frequent","friction","frighten","frigidly","frostily","frosting","fructose","frugally","galleria","gambling","gangrene","gatherer","gauntlet","generous","genetics","geologic","geometry","geranium","germless","gigabyte","gigantic","giggling","giveaway","glancing","glaucoma","gleaming","gloating","gloomily","glorious","glowworm","goatskin","goldfish","goldmine","goofball","gorgeous","graceful","gracious","gradient","graduate","graffiti","grafting","granddad","grandkid","grandson","granular","gratuity","greasily","greedily","greeting","grieving","grievous","grinning","groggily","grooving","grudging","grueling","grumpily","guidable","guidance","gullible","gurgling","gyration","habitant","habitual","handball","handbook","handcart","handclap","handcuff","handgrip","handheld","handling","handmade","handpick","handrail","handwash","handwork","handyman","hangnail","hangover","happiest","hardcopy","hardcore","harddisk","hardened","hardener","hardhead","hardness","hardship","hardware","hardwood","harmless","hatchery","hatching","hazelnut","haziness","headache","headband","headgear","headlamp","headless","headlock","headrest","headroom","headsman","headwear","helpless","helpline","henchman","heritage","hesitant","hesitate","hexagram","huddling","humbling","humility","humorist","humorous","humpback","hungrily","huntress","huntsman","hydrated","hydrogen","hypnoses","hypnosis","hypnotic","idealism","idealist","idealize","identify","identity","ideology","ignition","illusion","illusive","imagines","imbecile","immature","imminent","immobile","immodest","immortal","immunity","immunize","impaired","impeding","imperial","implicit","impolite","importer","imposing","impotent","imprison","improper","impurity","irrigate","irritant","irritate","islamist","isolated","jailbird","jalapeno","jaundice","jingling","jokester","jokingly","joyfully","joystick","jubilant","judicial","juggling","junction","juncture","junkyard","justness","juvenile","kangaroo","keenness","kerchief","kerosene","kilobyte","kilogram","kilowatt","kindling","kindness","kissable","knapsack","knickers","laboring","labrador","ladylike","landfall","landfill","landlady","landless","landline","landlord","landmark","landmass","landmine","landside","language","latitude","latticed","lavender","laxative","laziness","lecturer","leggings","lethargy","leverage","levitate","licorice","ligament","likeness","likewise","limpness","linguini","linguist","linoleum","litigate","luckless","lukewarm","luminous","lunchbox","luncheon","lushness","lustrous","lyricism","lyricist","macarena","macaroni","magazine","magician","magnetic","magnolia","mahogany","majestic","majority","makeover","managing","mandarin","mandolin","manicure","manpower","marathon","marbling","marigold","maritime","massager","matchbox","matching","material","maternal","maturely","maturing","maturity","maverick","maximize","mobility","mobilize","modified","moisture","molasses","molecule","molehill","monetary","monetize","mongoose","monkhood","monogamy","monogram","monopoly","monorail","monotone","monotype","monoxide","monsieur","monument","moonbeam","moonlike","moonrise","moonwalk","morality","morbidly","morphine","morphing","mortally","mortuary","mothball","motivate","mountain","mounting","mournful","mulberry","multiple","multiply","mumbling","munchkin","muscular","mushroom","mutation","national","nativity","naturist","nautical","navigate","nearness","neatness","negation","negative","negligee","neurosis","neurotic","nickname","nicotine","nineteen","nintendo","numbness","numerate","numerous","nuptials","nutrient","nutshell","obedient","obituary","obligate","oblivion","observer","obsessed","obsolete","obstacle","obstruct","occupant","occupier","ointment","olympics","omission","omnivore","oncoming","onlooker","onscreen","operable","operator","opponent","opposing","opposite","outboard","outbound","outbreak","outburst","outclass","outdated","outdoors","outfield","outflank","outgoing","outhouse","outlying","outmatch","outreach","outright","outscore","outshine","outshoot","outsider","outsmart","outtakes","outthink","outweigh","overarch","overbill","overbite","overbook","overcast","overcoat","overcome","overcook","overfeed","overfill","overflow","overfull","overhand","overhang","overhaul","overhead","overhear","overheat","overhung","overkill","overlaid","overload","overlook","overlord","overpass","overplay","overrate","override","overripe","overrule","overshot","oversold","overstay","overstep","overtake","overtime","overtone","overture","overturn","overview","oxymoron","pacifier","pacifism","pacifist","paddling","palpable","pampered","pamperer","pamphlet","pancreas","pandemic","panorama","parabola","parakeet","paralyze","parasail","parasite","parmesan","passable","passably","passcode","passerby","passover","passport","password","pastrami","paternal","patience","pavement","pavilion","paycheck","payphone","peculiar","peddling","pedicure","pedigree","pegboard","penalize","penknife","pentagon","perceive","perjurer","peroxide","petition","phrasing","placidly","platform","platinum","platonic","platypus","playable","playback","playlist","playmate","playroom","playtime","pleading","plethora","plunging","pointing","politely","popsicle","populace","populate","porridge","portable","porthole","portside","possible","possibly","postcard","pouncing","powdered","praising","prancing","prankish","preacher","preamble","precinct","predator","pregnant","premiere","premises","prenatal","preorder","pretense","previous","prideful","princess","pristine","probable","probably","proclaim","procurer","prodigal","profound","progress","prologue","promoter","prompter","promptly","proofing","properly","property","proposal","protegee","protract","protrude","provable","provided","provider","province","prowling","punctual","punisher","purchase","purebred","pureness","purifier","purplish","pursuant","purveyor","pushcart","pushover","puzzling","quadrant","quaintly","quarters","quotable","radiance","radiated","radiator","railroad","rambling","reabsorb","reaction","reactive","reaffirm","reappear","rearview","reassign","reassure","reattach","reburial","rebuttal","reckless","recliner","recovery","recreate","recycled","recycler","reemerge","refinery","refining","refinish","reforest","reformat","reformed","reformer","refreeze","refusing","register","registry","regulate","rekindle","relation","relative","reliable","reliably","reliance","relocate","remedial","remember","reminder","removing","renderer","renegade","renounce","renovate","rentable","reoccupy","repaying","repeated","repeater","rephrase","reporter","reproach","resample","research","reselect","reseller","resemble","resident","residual","resigned","resolute","resolved","resonant","resonate","resource","resubmit","resupply","retainer","retiring","retorted","reusable","reverend","reversal","revision","reviving","revolver","richness","riddance","ripeness","ripening","rippling","riverbed","riveting","robotics","rockband","rockfish","rocklike","rockstar","roulette","rounding","roundish","rumbling","sabotage","saddling","safeness","salaried","salutary","sampling","sanction","sanctity","sandbank","sandfish","sandworm","sanitary","satiable","saturate","saturday","scalding","scallion","scalping","scanning","scarcity","scarring","schedule","scheming","schnapps","scolding","scorpion","scouring","scouting","scowling","scrabble","scraggly","scribble","scribing","scrubbed","scrubber","scrutiny","sculptor","secluded","securely","security","sedation","sedative","sediment","seducing","selected","selector","semantic","semester","semisoft","senorita","sensuous","sequence","serrated","sessions","settling","severity","shakable","shamrock","shelving","shifting","shoplift","shopping","shoptalk","shortage","shortcut","showcase","showdown","showgirl","showroom","shrapnel","shredder","shrewdly","shrouded","shucking","siberian","silenced","silencer","simplify","singular","sinister","situated","sixtieth","sizzling","skeletal","skeleton","skillful","skimming","skimpily","skincare","skinhead","skinless","skinning","skipping","skirmish","skydiver","skylight","slacking","slapping","slashing","slighted","slightly","slimness","slinging","slobbery","sloppily","smashing","smelting","smuggler","smugness","sneezing","snipping","snowbird","snowdrop","snowfall","snowless","snowplow","snowshoe","snowsuit","snugness","spearman","specimen","speckled","spectrum","spelling","spending","spinning","spinster","spirited","splashed","splatter","splendid","splendor","splicing","splinter","splotchy","spoilage","spoiling","spookily","sporting","spotless","spotting","spyglass","squabble","squander","squatted","squatter","squealer","squeegee","squiggle","squiggly","stagnant","stagnate","staining","stalling","stallion","stapling","stardust","starfish","starless","starring","starship","starting","starving","steadier","steadily","steering","sterling","stifling","stimulus","stingily","stinging","stingray","stinking","stoppage","stopping","storable","stowaway","straddle","strained","strainer","stranger","strangle","strategy","strength","stricken","striking","striving","stroller","strongly","struggle","stubborn","stuffing","stunning","sturdily","stylized","subduing","subfloor","subgroup","sublease","sublevel","submerge","subpanel","subprime","subsonic","subtitle","subtotal","subtract","sufferer","suffrage","suitable","suitably","suitcase","sulphate","superior","superjet","superman","supermom","supplier","sureness","surgical","surprise","surround","survival","survivor","suspense","swapping","swimming","swimsuit","swimwear","swinging","sycamore","sympathy","symphony","syndrome","synopses","synopsis","tableful","tackling","tactical","tactless","talisman","tameness","tapeless","tapering","tapestry","tartness","tattered","tattling","theology","theorize","thespian","thieving","thievish","thinness","thinning","thirteen","thousand","threaten","thriving","throttle","throwing","thumping","thursday","tidiness","tightwad","tingling","tinkling","tinsmith","traction","trailing","tranquil","transfer","trapdoor","trapping","traverse","travesty","treading","trespass","triangle","tribunal","trickery","trickily","tricking","tricolor","tricycle","trillion","trimming","trimness","tripping","trolling","trombone","tropical","trousers","trustful","trusting","tubeless","tumbling","turbofan","turbojet","tweezers","twilight","twisting","ultimate","umbrella","unafraid","unbeaten","unbiased","unbitten","unbolted","unbridle","unbroken","unbundle","unburned","unbutton","uncapped","uncaring","uncoated","uncoiled","uncombed","uncommon","uncooked","uncouple","uncurled","underage","underarm","undercut","underdog","underfed","underpay","undertow","underuse","undocked","undusted","unearned","uneasily","unedited","unending","unenvied","unfasten","unfilled","unfitted","unflawed","unframed","unfreeze","unfrozen","unfunded","unglazed","ungloved","ungraded","unguided","unharmed","unheated","unhidden","unicycle","uniquely","unissued","universe","unjustly","unlawful","unleaded","unlinked","unlisted","unloaded","unloader","unlocked","unlovely","unloving","unmanned","unmapped","unmarked","unmasked","unmolded","unmoving","unneeded","unopened","unpadded","unpaired","unpeeled","unpicked","unpinned","unplowed","unproven","unranked","unrented","unrigged","unrushed","unsaddle","unsalted","unsavory","unsealed","unseated","unseeing","unseemly","unselect","unshaken","unshaved","unshaven","unsigned","unsliced","unsmooth","unsocial","unsoiled","unsolved","unsorted","unspoken","unstable","unsteady","unstitch","unsubtle","unsubtly","unsuited","untagged","untapped","unthawed","unthread","untimely","untitled","unturned","unusable","unvalued","unvaried","unveiled","unvented","unviable","unwanted","unwashed","unwieldy","unworthy","upcoming","upheaval","uplifted","uprising","upstairs","upstream","upstroke","upturned","urethane","vacation","vagabond","vagrancy","vanquish","variable","variably","vascular","vaseline","vastness","velocity","vendetta","vengeful","venomous","verbally","vertical","vexingly","vicinity","viewable","viewless","vigorous","vineyard","violator","virtuous","viselike","visiting","vitality","vitalize","vitamins","vocalist","vocalize","vocation","volatile","washable","washbowl","washroom","waviness","whacking","whenever","whisking","whomever","whooping","wildcard","wildfire","wildfowl","wildland","wildlife","wildness","winnings","wireless","wisplike","wobbling","wreckage","wrecking","wrongful","yearbook","yearling","yearning","zeppelin","abdomen","abiding","ability","abreast","abridge","absence","absolve","abstain","acclaim","account","acetone","acquire","acrobat","acronym","actress","acutely","aerosol","affront","ageless","agility","agonize","aground","alfalfa","algebra","almanac","alright","amenity","amiable","ammonia","amnesty","amplify","amusing","anagram","anatomy","anchovy","ancient","android","angelic","angling","angrily","angular","animate","annuity","another","antacid","anthill","antonym","anybody","anymore","anytime","apostle","appease","applaud","applied","approve","apricot","armband","armhole","armless","armoire","armored","armrest","arousal","arrange","arrival","ashamed","aspirin","astound","astride","atrophy","attempt","auction","audible","audibly","average","aviator","awkward","backing","backlit","backlog","badland","badness","baggage","bagging","bagpipe","balance","balcony","banking","banshee","barbell","barcode","barista","barmaid","barrack","barrier","battery","batting","bazooka","blabber","bladder","blaming","blazing","blemish","blinked","blinker","bloated","blooper","blubber","blurred","boaster","bobbing","bobsled","bobtail","bolster","bonanza","bonding","bonfire","booting","bootleg","borough","boxlike","breeder","brewery","brewing","bridged","brigade","brisket","briskly","bristle","brittle","broaden","broadly","broiler","brought","budding","buffalo","buffing","buffoon","bulldog","bullion","bullish","bullpen","bunkbed","busload","cabbage","caboose","cadmium","cahoots","calcium","caliber","caloric","calorie","calzone","camping","candied","canning","canteen","capable","capably","capital","capitol","capsize","capsule","caption","captive","capture","caramel","caravan","cardiac","carless","carload","carnage","carpool","carport","carried","cartoon","carving","carwash","cascade","catalog","catcall","catcher","caterer","catfish","catlike","cattail","catwalk","causing","caution","cavalry","certify","chalice","chamber","channel","chapped","chapter","charger","chariot","charity","charred","charter","chasing","chatter","cheddar","chemist","chevron","chewing","choking","chooser","chowder","citable","citadel","citizen","clapped","clapper","clarify","clarity","clatter","cleaver","clicker","climate","clobber","cloning","closure","clothes","clubbed","clutter","coastal","coaster","cobbler","coconut","coexist","collage","collide","comfort","commend","comment","commode","commute","company","compare","compile","compost","comrade","concave","conceal","concept","concert","concise","condone","conduit","confess","confirm","conform","conical","conjure","consent","console","consult","contact","contend","contest","context","contort","contour","control","convene","convent","copilot","copious","corncob","coroner","correct","corrode","corsage","cottage","country","courier","coveted","coyness","crafter","cranial","cranium","craving","crazily","creamed","creamer","crested","crevice","crewman","cricket","crimson","crinkle","crinkly","crisped","crisply","critter","crouton","crowbar","crucial","crudely","cruelly","cruelty","crumpet","crunchy","crushed","crusher","cryptic","crystal","cubical","cubicle","culprit","culture","cupcake","cupping","curable","curator","curling","cursive","curtain","custard","custody","customs","cycling","cyclist","dancing","darkish","darling","dawdler","daycare","daylong","dayroom","daytime","dazzler","dealing","debrief","decency","decibel","decimal","decline","default","defense","defiant","deflate","defraud","defrost","delouse","density","dentist","denture","deplete","depress","deprive","derived","deserve","desktop","despair","despise","despite","destiny","detract","devalue","deviant","deviate","devious","devotee","diagram","dictate","dimness","dingbat","diocese","dioxide","diploma","dipping","disband","discard","discern","discuss","disdain","disjoin","dislike","dismiss","disobey","display","dispose","dispute","disrupt","distant","distill","distort","divided","dolphin","donated","donator","doorman","doormat","doorway","drained","drainer","drapery","drastic","dreaded","dribble","driller","driving","drizzle","drizzly","dropbox","droplet","dropout","dropper","duchess","ducking","dumping","durable","durably","dutiful","dwelled","dweller","dwindle","dynamic","dynasty","earache","eardrum","earflap","earlobe","earmark","earmuff","earring","earshot","earthen","earthly","easeful","easiest","eatable","eclipse","ecology","economy","edition","effects","egotism","elastic","elderly","elevate","elitism","ellipse","elusive","embargo","embassy","emblaze","emerald","emotion","empathy","emperor","empower","emptier","enclose","encrust","encrypt","endless","endnote","endorse","engaged","engorge","engross","enhance","enjoyer","enslave","ensnare","entitle","entrust","entwine","envious","episode","equator","equinox","erasure","erratic","esquire","essence","etching","eternal","ethanol","evacuee","evasion","evasive","evident","exalted","example","exclaim","exclude","exhaust","expanse","explain","explode","exploit","explore","express","extinct","extrude","faceted","faction","factoid","factual","faculty","failing","falsify","fanatic","fancied","fanfare","fanning","fantasy","fascism","fasting","favored","federal","fencing","ferment","festive","fiction","fidgety","fifteen","figment","filling","finally","finance","finicky","finless","finlike","flaccid","flagman","flakily","flanked","flaring","flatbed","flatten","flattop","fleshed","florist","flyable","flyaway","flyover","footage","footing","footman","footpad","footsie","founder","fragile","framing","frantic","fraying","freebee","freebie","freedom","freeing","freeway","freight","fretful","fretted","frisbee","fritter","frosted","gaining","gallery","gallows","gangway","garbage","garland","garment","garnish","gauging","generic","gentile","geology","gestate","gesture","getaway","getting","giddily","gimmick","gizzard","glacial","glacier","glamour","glaring","glazing","gleeful","gliding","glimmer","glimpse","glisten","glitter","gloater","glorify","glowing","glucose","glutton","goggles","goliath","gondola","gosling","grading","grafted","grandly","grandma","grandpa","granite","granola","grapple","gratify","grating","gravity","grazing","greeter","grimace","gristle","grouped","growing","gruffly","grumble","grumbly","guiding","gumball","gumdrop","gumming","gutless","guzzler","habitat","hacking","hacksaw","haggler","halogen","hammock","hamster","handbag","handful","handgun","handled","handler","handoff","handsaw","handset","hangout","happier","happily","hardhat","harmful","harmony","harness","harpist","harvest","hastily","hatchet","hatless","heading","headset","headway","heavily","heaving","hedging","helpful","helping","hemlock","heroics","heroism","herring","herself","hexagon","humming","hunting","hurling","hurried","husband","hydrant","iciness","ideally","imaging","imitate","immerse","impeach","implant","implode","impound","imprint","improve","impulse","islamic","isotope","issuing","italics","jackpot","janitor","january","jarring","jasmine","jawless","jawline","jaybird","jellied","jitters","jittery","jogging","joining","joyride","jugular","jujitsu","jukebox","juniper","junkman","justice","justify","karaoke","kindred","kinetic","kinfolk","kinship","kinsman","kissing","kitchen","kleenex","krypton","labored","laborer","ladybug","lagging","landing","lantern","lapping","latrine","launder","laundry","legible","legibly","legroom","legwork","leotard","letdown","lettuce","liberty","library","licking","lifting","liftoff","limeade","limping","linseed","liquefy","liqueur","livable","lividly","luckily","lullaby","lumping","lumpish","lustily","machine","magenta","magical","magnify","majesty","mammary","manager","manatee","mandate","manhole","manhood","manhunt","mankind","manlike","manmade","mannish","marbled","marbles","marital","married","marxism","mashing","massive","mastiff","matador","matcher","maximum","moaning","mobster","modular","moisten","mollusk","mongrel","monitor","monsoon","monthly","moocher","moonlit","morally","mortify","mounted","mourner","movable","mullets","mummify","mundane","mushily","mustang","mustard","mutable","myspace","mystify","napping","nastily","natural","nearest","nemeses","nemesis","nervous","neutron","nuclear","nucleus","nullify","numbing","numeral","numeric","nursery","nursing","nurture","nutcase","nutlike","obliged","obscure","obvious","octagon","october","octopus","ominous","onboard","ongoing","onshore","onstage","opacity","operate","opossum","osmosis","outback","outcast","outcome","outgrow","outlast","outline","outlook","outmost","outpost","outpour","outrage","outrank","outsell","outward","overact","overall","overbid","overdue","overfed","overlap","overlay","overpay","overrun","overtly","overuse","oxidant","oxidize","pacific","padding","padlock","pajamas","pampers","pancake","panning","panther","paprika","papyrus","paradox","parched","parking","parkway","parsley","parsnip","partake","parting","partner","passage","passing","passion","passive","pastime","pasture","patient","patriot","payable","payback","payment","payroll","pelican","penalty","pendant","pending","pennant","pension","percent","perfume","perjury","petunia","phantom","phoenix","phonics","placard","placate","planner","plaster","plastic","plating","platter","playful","playing","playoff","playpen","playset","pliable","plunder","plywood","pointed","pointer","polygon","polymer","popcorn","popular","portion","postage","postbox","posting","posture","postwar","pouring","powdery","pranker","praying","preachy","precise","precook","predict","preface","pregame","prelude","premium","prepaid","preplan","preshow","presoak","presume","preteen","pretext","pretzel","prevail","prevent","preview","primary","primate","privacy","private","probing","problem","process","prodigy","produce","product","profane","profile","progeny","program","propose","prorate","proving","provoke","prowess","prowler","pruning","psychic","pulsate","pungent","purging","puritan","pursuit","pushing","pushpin","putdown","pyramid","quaking","qualify","quality","quantum","quarrel","quartet","quicken","quickly","quintet","ragweed","railcar","railing","railway","ranging","ranking","ransack","ranting","rasping","ravioli","reactor","reapply","reawake","rebirth","rebound","rebuild","rebuilt","recital","reclaim","recluse","recolor","recount","rectify","reenact","reenter","reentry","referee","refined","refocus","refract","refrain","refresh","refried","refusal","regalia","regally","regress","regroup","regular","reissue","rejoice","relapse","related","relearn","release","reliant","relieve","relight","remarry","rematch","remnant","remorse","removal","removed","remover","renewal","renewed","reoccur","reorder","repaint","replace","replica","reprint","reprise","reptile","request","require","reroute","rescuer","reshape","reshoot","residue","respect","rethink","retinal","retired","retiree","retouch","retrace","retract","retrain","retread","retreat","retrial","retying","reunion","reunite","reveler","revenge","revenue","revered","reverse","revisit","revival","reviver","rewrite","ribcage","rickety","ricotta","rifling","rigging","rimless","rinsing","ripcord","ripping","riptide","risotto","ritalin","riveter","roaming","robbing","rocking","rotting","rotunda","roundup","routine","routing","rubbing","rubdown","rummage","rundown","running","rupture","sabbath","saddled","sadness","saffron","sagging","salvage","sandbag","sandbar","sandbox","sanding","sandlot","sandpit","sapling","sarcasm","sardine","satchel","satisfy","savanna","savings","scabbed","scalded","scaling","scallop","scandal","scanner","scarily","scholar","science","scooter","scoring","scoured","scratch","scrawny","scrooge","scruffy","scrunch","scuttle","secrecy","secular","segment","seismic","seizing","seltzer","seminar","senator","serpent","service","serving","setback","setting","seventh","seventy","shadily","shading","shakily","shaking","shallot","shallow","shampoo","shaping","sharper","sharpie","sharply","shelter","shifter","shimmer","shindig","shingle","shining","shopper","shorten","shorter","shortly","showbiz","showing","showman","showoff","shrivel","shudder","shuffle","siamese","sibling","sighing","silicon","sincere","singing","sinless","sinuous","sitting","sixfold","sixteen","sixties","sizable","sizably","skating","skeptic","skilled","skillet","skimmed","skimmer","skipper","skittle","skyline","skyward","slacked","slacker","slander","slashed","slather","slicing","sliding","sloping","slouchy","smartly","smasher","smashup","smitten","smoking","smolder","smother","snagged","snaking","snippet","snooper","snoring","snorkel","snowcap","snowman","snuggle","species","specked","speller","spender","spinach","spindle","spinner","spinout","spirits","splashy","splurge","spoiled","spoiler","sponsor","spotted","spotter","spousal","sputter","squeeze","squishy","stadium","staging","stained","stamina","stammer","stardom","staring","starlet","starlit","starter","startle","startup","starved","stature","statute","staunch","stellar","stencil","sterile","sternum","stiffen","stiffly","stimuli","stinger","stipend","stoning","stopped","stopper","storage","stowing","stratus","stretch","strudel","stubbed","stubble","stubbly","student","studied","stuffed","stumble","stunned","stunner","styling","stylist","subdued","subject","sublime","subplot","subside","subsidy","subsoil","subtext","subtype","subzero","suction","suffice","suggest","sulfate","sulfide","sulfite","support","supreme","surface","surgery","surging","surname","surpass","surplus","surreal","survive","suspect","suspend","swagger","swifter","swiftly","swimmer","swinger","swizzle","swooned","symptom","synapse","synergy","t-shirt","tabasco","tabloid","tacking","tactful","tactics","tactile","tadpole","tainted","tannery","tanning","tantrum","tapered","tapioca","tapping","tarnish","tasting","theater","thermal","thermos","thicken","thicket","thimble","thinner","thirsty","thrower","thyself","tidings","tighten","tightly","tigress","timothy","tinfoil","tinwork","tipping","tracing","tractor","trading","traffic","tragedy","traitor","trapeze","trapped","trapper","treason","trekker","tremble","tribune","tribute","triceps","trickle","trident","trilogy","trimmer","trinity","triumph","trivial","trodden","tropics","trouble","truffle","trustee","tubular","tucking","tuesday","tuition","turbine","turmoil","twiddle","twisted","twister","twitter","unaired","unawake","unaware","unbaked","unblock","unboxed","uncanny","unchain","uncheck","uncivil","unclasp","uncloak","uncouth","uncover","uncross","uncrown","uncured","undated","undergo","undoing","undress","undying","unearth","uneaten","unequal","unfazed","unfiled","unfixed","ungodly","unhappy","unheard","unhinge","unicorn","unified","unifier","unkempt","unknown","unlaced","unlatch","unleash","unlined","unloved","unlucky","unmixed","unmoral","unmoved","unnamed","unnerve","unpaved","unquote","unrated","unrobed","unsaved","unscrew","unstuck","unsworn","untaken","untamed","untaxed","untimed","untried","untruth","untwist","untying","unusual","unvocal","unweave","unwired","unwound","unwoven","upchuck","upfront","upgrade","upright","upriver","upscale","upstage","upstart","upstate","upswing","uptight","uranium","urgency","urology","useable","utensil","utility","utilize","vacancy","vaguely","valiant","vanilla","vantage","variety","various","varmint","varnish","varsity","varying","vending","venture","verbose","verdict","version","vertigo","veteran","victory","viewing","village","villain","vintage","violate","virtual","viscous","visible","visibly","visitor","vitally","vividly","vocally","voicing","voltage","volumes","voucher","walmart","wannabe","wanting","washday","washing","washout","washtub","wasting","whoever","whoopee","wielder","wildcat","willing","wincing","winking","wistful","womanly","worried","worrier","wrangle","wrecker","wriggle","wriggly","wrinkle","wrinkly","writing","written","wronged","wrongly","wrought","yanking","yapping","yelling","yiddish","zealous","zipfile","zipping","zoology","abacus","ablaze","abroad","absurd","accent","aching","acting","action","active","affair","affirm","afford","aflame","afloat","afraid","agency","agenda","aghast","agreed","aliens","almost","alumni","always","ambush","amends","amount","amulet","amused","amuser","anchor","anemia","anemic","angled","angler","angles","animal","anthem","antics","antler","anyhow","anyone","anyway","apache","appear","armful","arming","armory","around","arrest","arrive","ascend","ascent","asleep","aspect","aspire","astute","atrium","attach","attain","attest","attire","august","author","autism","avatar","avenge","avenue","awaken","awhile","awning","babble","babied","baboon","backed","backer","backup","badass","baffle","bagful","bagged","baggie","bakery","baking","bamboo","banana","banish","banked","banker","banner","banter","barbed","barber","barley","barman","barrel","basics","basket","batboy","battle","bauble","blazer","bleach","blinks","blouse","bluish","blurry","bobbed","bobble","bobcat","bogged","boggle","bonded","bonnet","bonsai","booted","bootie","boring","botany","bottle","bottom","bounce","bouncy","bovine","boxcar","boxing","breach","breath","breeze","breezy","bright","broken","broker","bronco","bronze","browse","brunch","bubble","bubbly","bucked","bucket","buckle","budget","buffed","buffer","bulgur","bundle","bungee","bunion","busboy","busily","cabana","cabbie","cackle","cactus","caddie","camera","camper","campus","canary","cancel","candle","canine","canned","cannon","cannot","canola","canopy","canyon","capped","carbon","carded","caress","caring","carrot","cartel","carton","casing","casino","casket","catchy","catnap","catnip","catsup","cattle","caucus","causal","caviar","cavity","celery","celtic","cement","census","chance","change","chaste","chatty","cheese","cheesy","cherub","chewer","chirpy","choice","choosy","chosen","chrome","chubby","chummy","cinema","circle","circus","citric","citrus","clammy","clamor","clause","clench","clever","client","clinic","clique","clover","clumsy","clunky","clutch","cobalt","cobweb","coerce","coffee","collar","collie","colony","coming","common","compel","comply","concur","copied","copier","coping","copper","cornea","corned","corner","corral","corset","cortex","cosmic","cosmos","cotton","county","cozily","cradle","crafty","crayon","crazed","crease","create","credit","creole","cringe","crispy","crouch","crummy","crying","cuddle","cuddly","cupped","curdle","curfew","curing","curled","curler","cursor","curtly","curtsy","cussed","cyclic","cymbal","dagger","dainty","dander","danger","dangle","dating","daybed","deacon","dealer","debate","debtor","debunk","decade","deceit","decent","decode","decree","deduce","deduct","deepen","deeply","deface","defame","defeat","defile","define","deftly","defuse","degree","delete","deluge","deluxe","demise","demote","denial","denote","dental","depict","deploy","deport","depose","deputy","derail","detail","detest","device","diaper","dicing","dilute","dimmed","dimmer","dimple","dinghy","dining","dinner","dipped","dipper","disarm","dismay","disown","diving","doable","docile","dollar","dollop","domain","doodle","dorsal","dosage","dotted","douche","dreamt","dreamy","dreary","drench","drippy","driven","driver","drudge","dubbed","duffel","dugout","duller","duplex","duress","during","earful","earthy","earwig","easily","easing","easter","eatery","eating","eclair","edging","editor","effort","egging","eggnog","either","elated","eldest","eleven","elixir","embark","emblem","embody","emboss","enable","enamel","encode","encore","ending","energy","engine","engulf","enrage","enrich","enroll","ensure","entail","entire","entity","entomb","entrap","entree","enzyme","equate","equity","erased","eraser","errand","errant","eskimo","estate","ethics","evolve","excess","excuse","exhale","exhume","exodus","expand","expend","expert","expire","expose","extent","extras","fabric","facial","facing","factor","fading","falcon","family","famine","faster","faucet","fedora","feeble","feisty","feline","fender","ferret","ferris","fervor","fester","fiddle","figure","filing","filled","filler","filter","finale","finite","flashy","flatly","fleshy","flight","flinch","floral","flying","follow","fondly","fondue","footer","fossil","foster","frayed","freely","french","frenzy","friday","fridge","friend","fringe","frolic","frosty","frozen","frying","galley","gallon","galore","gaming","gander","gangly","garage","garden","gargle","garlic","garnet","garter","gating","gazing","geiger","gender","gently","gerbil","giblet","giggle","giggly","gigolo","gilled","girdle","giving","gladly","glance","glider","glitch","glitzy","gloomy","gluten","gnarly","google","gopher","gorged","gossip","gothic","gotten","graded","grader","granny","gravel","graves","greedy","grinch","groggy","groove","groovy","ground","grower","grudge","grunge","gurgle","gutter","hacked","hacker","halved","halves","hamlet","hamper","handed","hangup","hankie","harbor","hardly","hassle","hatbox","hatred","hazard","hazily","hazing","headed","header","helium","helmet","helper","herald","herbal","hermit","hubcap","huddle","humble","humbly","hummus","humped","humvee","hunger","hungry","hunter","hurdle","hurled","hurler","hurray","husked","hybrid","hyphen","idiocy","ignore","iguana","impale","impart","impish","impose","impure","iodine","iodize","iphone","itunes","jackal","jacket","jailer","jargon","jersey","jester","jigsaw","jingle","jockey","jogger","jovial","joyous","juggle","jumble","junior","junkie","jurist","justly","karate","keenly","kennel","kettle","kimono","kindle","kindly","kisser","kitten","kosher","ladder","ladies","lagged","lagoon","landed","lapdog","lapped","laptop","lather","latter","launch","laurel","lavish","lazily","legacy","legend","legged","legume","length","lesser","letter","levers","liable","lifter","likely","liking","lining","linked","liquid","litmus","litter","little","lively","living","lizard","lugged","lumber","lunacy","lushly","luster","luxury","lyrics","maggot","maimed","making","mammal","manger","mangle","manila","manned","mantis","mantra","manual","margin","marina","marine","marlin","maroon","marrow","marshy","mascot","mashed","masses","mating","matrix","matron","matted","matter","mayday","moaner","mobile","mocker","mockup","modify","module","monday","mooing","mooned","morale","mosaic","motion","motive","moving","mowing","mulled","mumble","muppet","museum","musket","muster","mutate","mutiny","mutual","muzzle","myself","naming","napkin","napped","narrow","native","nature","nearby","nearly","neatly","nebula","nectar","negate","nephew","neuron","neuter","nibble","nimble","nimbly","nuclei","nugget","number","numbly","nutmeg","nuzzle","object","oblong","obtain","obtuse","occupy","ocelot","octane","online","onward","oppose","outage","outbid","outfit","outing","outlet","output","outwit","oxford","oxygen","oyster","pacify","padded","paddle","paging","palace","paltry","panama","pantry","papaya","parade","parcel","pardon","parish","parlor","parole","parrot","parted","partly","pasted","pastel","pastor","patchy","patrol","pauper","paving","pawing","payday","paying","pebble","pebbly","pectin","pellet","pelvis","pencil","penpal","perish","pester","petite","petted","phobia","phoney","phrase","plasma","plated","player","pledge","plenty","plural","pointy","poison","poking","police","policy","polish","poncho","poplar","popper","porous","portal","portly","posing","possum","postal","posted","poster","pounce","powwow","prance","prayer","precut","prefix","prelaw","prepay","preppy","preset","pretty","prewar","primal","primer","prison","prissy","pronto","proofs","proton","proved","proven","prozac","public","pucker","pueblo","pumice","pummel","puppet","purely","purify","purist","purity","purple","pusher","pushup","puzzle","python","quarry","quench","quiver","racing","racism","racoon","radial","radish","raffle","ragged","raging","raider","raisin","raking","ramble","ramrod","random","ranged","ranger","ranked","rarity","rascal","ravage","ravine","raving","reason","rebate","reboot","reborn","rebuff","recall","recant","recast","recede","recent","recess","recite","recoil","recopy","record","recoup","rectal","refill","reflex","reflux","refold","refund","refuse","refute","regain","reggae","regime","region","reheat","rehire","rejoin","relish","relive","reload","relock","remake","remark","remedy","remold","remote","rename","rental","rented","renter","reopen","repair","repave","repeal","repent","replay","repose","repost","resale","reseal","resend","resent","resize","resort","result","resume","retail","retake","retold","retool","return","retype","reveal","reverb","revert","revise","revoke","revolt","reward","rewash","rewind","rewire","reword","rework","rewrap","ribbon","riches","richly","ridden","riding","rimmed","ripple","rising","roamer","robust","rocker","rocket","roping","roster","rotten","roving","rubbed","rubber","rubble","ruckus","rudder","ruined","rumble","runner","runway","sacred","sadden","safari","safely","salami","salary","saline","saloon","salute","sample","sandal","sanded","savage","savior","scabby","scarce","scared","scenic","scheme","scorch","scored","scorer","scotch","scouts","screen","scribe","script","scroll","scurvy","second","secret","sector","sedate","seduce","seldom","senate","senior","septic","septum","sequel","series","sermon","sesame","settle","shabby","shaded","shadow","shanty","sheath","shelve","sherry","shield","shifty","shimmy","shorts","shorty","shower","shrank","shriek","shrill","shrimp","shrine","shrink","shrubs","shrunk","siding","sierra","siesta","silent","silica","silver","simile","simple","simply","singer","single","sinner","sister","sitcom","sitter","sizing","sizzle","skater","sketch","skewed","skewer","skiing","skinny","slacks","sleeve","sliced","slicer","slider","slinky","sliver","slogan","sloped","sloppy","sludge","smoked","smooth","smudge","smudgy","smugly","snazzy","sneeze","snitch","snooze","snugly","specks","speech","sphere","sphinx","spider","spiffy","spinal","spiral","spleen","splice","spoils","spoken","sponge","spongy","spooky","sports","sporty","spotty","spouse","sprain","sprang","sprawl","spring","sprint","sprite","sprout","spruce","sprung","squall","squash","squeak","squint","squire","squirt","stable","staple","starch","starry","static","statue","status","stench","stereo","stifle","stingy","stinky","stitch","stooge","streak","stream","street","stress","strewn","strict","stride","strife","strike","strive","strobe","strode","struck","strung","stucco","studio","stuffy","stupor","sturdy","stylus","sublet","subpar","subtly","suburb","subway","sudden","sudoku","suffix","suitor","sulfur","sullen","sultry","supper","supply","surely","surfer","survey","swerve","switch","swivel","swoosh","system","tables","tablet","tackle","taking","talcum","tamale","tamper","tanned","target","tarmac","tartar","tartly","tassel","tattle","tattoo","tavern","thesis","thinly","thirty","thrash","thread","thrift","thrill","thrive","throat","throng","tidbit","tiling","timing","tingle","tingly","tinker","tinsel","tipoff","tipped","tipper","tiptop","tiring","tissue","trance","travel","treble","tremor","trench","triage","tricky","trifle","tripod","trophy","trough","trowel","trunks","tumble","turban","turkey","turret","turtle","twelve","twenty","twisty","twitch","tycoon","umpire","unable","unbend","unbent","unclad","unclip","unclog","uncork","undead","undone","unease","uneasy","uneven","unfair","unfold","unglue","unholy","unhook","unison","unkind","unless","unmade","unpack","unpaid","unplug","unread","unreal","unrest","unripe","unroll","unruly","unsafe","unsaid","unseen","unsent","unsnap","unsold","unsure","untidy","untold","untrue","unused","unwary","unwell","unwind","unworn","upbeat","update","upheld","uphill","uphold","upload","uproar","uproot","upside","uptake","uptown","upward","upwind","urchin","urgent","urging","usable","utmost","utopia","vacant","vacate","valium","valley","vanish","vanity","varied","vastly","veggie","velcro","velvet","vendor","verify","versus","vessel","viable","viewer","violet","violin","vision","volley","voting","voyage","waffle","waggle","waking","walnut","walrus","wanted","wasabi","washed","washer","waving","whacky","whinny","whoops","widely","widget","wilder","wildly","willed","willow","winner","winter","wiring","wisdom","wizard","wobble","wobbly","wooing","wreath","wrench","yearly","yippee","yogurt","yonder","zodiac","zombie","zoning","abide","acorn","affix","afoot","agent","agile","aging","agony","ahead","alarm","album","alias","alibi","alike","alive","aloft","aloha","alone","aloof","amaze","amber","amigo","amino","amiss","among","ample","amply","amuck","anger","anime","ankle","annex","antsy","anvil","aorta","apple","apply","april","apron","aptly","arena","argue","arise","armed","aroma","arose","array","arson","ashen","ashes","aside","askew","atlas","attic","audio","avert","avoid","await","award","aware","awoke","bacon","badge","badly","bagel","baggy","baked","balmy","banjo","barge","basil","basin","basis","batch","baton","blade","blame","blank","blast","bleak","bleep","blend","bless","blimp","bling","blitz","bluff","blunt","blurb","blurt","blush","bogus","boned","boney","bonus","booth","boots","boozy","borax","botch","boxer","briar","bribe","brick","bride","bring","brink","brook","broom","brunt","brush","brute","buddy","buggy","bulge","bully","bunch","bunny","cable","cache","cacti","caddy","cadet","cameo","canal","candy","canon","carat","cargo","carol","carry","carve","catty","cause","cedar","chafe","chain","chair","chant","chaos","chaps","charm","chase","cheek","cheer","chemo","chess","chest","chevy","chewy","chief","chili","chill","chimp","chive","chomp","chuck","chump","chunk","churn","chute","cider","cinch","civic","civil","claim","clamp","clang","clash","clasp","class","clean","clear","cleat","cleft","clerk","cling","cloak","clock","clone","cloud","clump","coach","cocoa","comfy","comic","comma","conch","coral","corny","couch","cough","could","cover","cramp","crane","crank","crate","crave","crazy","creed","creme","crepe","crept","cried","crier","crimp","croak","crock","crook","croon","cross","crowd","crown","crumb","crust","cupid","curly","curry","curse","curve","curvy","cushy","cycle","daily","dairy","daisy","dance","dandy","dares","dealt","debit","debug","decaf","decal","decay","decoy","defog","deity","delay","delta","denim","dense","depth","derby","deuce","diary","dimly","diner","dingo","dingy","ditch","ditto","ditzy","dizzy","dodge","dodgy","doily","doing","dolly","donor","donut","doozy","dowry","drank","dress","dried","drier","drift","drone","drool","droop","drove","drown","ducky","duvet","dwarf","dweeb","eagle","early","easel","eaten","ebony","ebook","ecard","eject","elbow","elite","elope","elude","elves","email","ember","emcee","emote","empty","ended","envoy","equal","error","erupt","essay","ether","evade","evict","evoke","exact","exert","exile","expel","fable","false","fancy","feast","femur","fence","ferry","fetal","fetch","fever","fiber","fifth","fifty","filth","finch","finer","flail","flaky","flame","flask","flick","flier","fling","flint","flirt","float","flock","floss","flyer","folic","foyer","frail","frame","frays","fresh","fried","frill","frisk","front","froth","frown","fruit","gaffe","gains","gamma","gauze","gecko","genre","gents","getup","giant","giddy","gills","given","giver","gizmo","glade","glare","glass","glory","gloss","glove","going","gonad","gooey","goofy","grain","grant","grape","graph","grasp","grass","gravy","green","grief","grill","grime","grimy","groin","groom","grope","grout","grove","growl","grunt","guide","guise","gully","gummy","gusto","gusty","haiku","hanky","happy","hardy","harsh","haste","hasty","haunt","haven","heave","hedge","hefty","hence","henna","herbs","hertz","human","humid","hurry","icing","idiom","igloo","image","imply","irate","issue","ivory","jaunt","jawed","jelly","jiffy","jimmy","jolly","judge","juice","juicy","jumbo","juror","kabob","karma","kebab","kitty","knelt","knoll","koala","kooky","kudos","ladle","lance","lanky","lapel","large","lasso","latch","legal","lemon","level","lilac","lilly","limes","limit","lingo","lived","liver","lucid","lunar","lurch","lusty","lying","macaw","magma","maker","mango","mangy","manly","manor","march","mardi","marry","mauve","maybe","mocha","molar","moody","morse","mossy","motor","motto","mouse","mousy","mouth","movie","mower","mulch","mumbo","mummy","mumps","mural","murky","mushy","music","musky","musty","nacho","nanny","nappy","nervy","never","niece","nifty","ninja","ninth","nutty","nylon","oasis","ocean","olive","omega","onion","onset","opium","other","otter","ought","ounce","outer","ovary","ozone","paced","pagan","pager","panda","panic","pants","paper","parka","party","pasta","pasty","patio","paver","payee","payer","pecan","penny","perch","perky","pesky","petal","petri","petty","phony","photo","plank","plant","plaza","pleat","pluck","poach","poise","poker","polar","polio","polka","poppy","poser","pouch","pound","power","press","pried","primp","print","prior","prism","prize","probe","prone","prong","props","proud","proxy","prude","prune","pulse","punch","pupil","puppy","purge","purse","pushy","quack","quail","quake","qualm","query","quiet","quill","quilt","quirk","quote","rabid","radar","radio","rally","ranch","rants","raven","reach","rebel","rehab","relax","relay","relic","remix","reply","rerun","reset","retry","reuse","rhyme","rigid","rigor","rinse","ritzy","rival","roast","robin","rocky","rogue","roman","rover","royal","rumor","runny","rural","sadly","saggy","saint","salad","salon","salsa","sandy","santa","sappy","sassy","satin","saucy","sauna","saved","savor","scale","scant","scarf","scary","scion","scoff","scone","scoop","scope","scorn","scrap","scuba","scuff","sedan","sepia","serve","setup","shack","shady","shaft","shaky","shale","shame","shank","shape","share","shawl","sheep","sheet","shelf","shell","shine","shiny","shirt","shock","shone","shore","shout","shove","shown","showy","shrug","shush","silly","siren","sixth","skied","skier","skies","skirt","skype","slain","slang","slate","sleek","sleep","sleet","slept","slick","slimy","slurp","slush","small","smell","smile","smirk","smite","smith","smock","smoky","snack","snare","snarl","sneak","sneer","snide","sniff","snore","snort","snout","snowy","snuff","speak","speed","spent","spied","spill","spilt","spiny","spoof","spool","spoon","spore","spout","spray","spree","sprig","squad","squid","stack","staff","stage","stamp","stand","stank","stark","stash","state","stays","steam","steed","steep","stick","stilt","stock","stoic","stoke","stole","stomp","stony","stood","stool","stoop","storm","stout","stove","straw","stray","strep","strum","strut","stuck","study","stump","stung","stunt","suave","sugar","suing","sushi","swarm","swear","sweat","sweep","swell","swept","swipe","swirl","swoop","swore","sworn","swung","syrup","tabby","tacky","talon","tamer","tarot","taste","tasty","taunt","thank","theft","theme","these","thigh","thing","think","thong","thorn","those","thumb","tiara","tibia","tidal","tiger","timid","trace","track","trade","train","traps","trash","treat","trend","trial","tried","trout","truce","truck","trump","truth","tubby","tulip","tummy","tutor","tweak","tweed","tweet","twerp","twice","twine","twins","twirl","tying","udder","ultra","uncle","uncut","unify","union","unlit","untie","until","unwed","unzip","upper","urban","usage","usher","usual","utter","valid","value","vegan","venue","venus","verse","vibes","video","viper","viral","virus","visor","vista","vixen","voice","voter","vowed","vowel","wafer","waged","wager","wages","wagon","waltz","watch","water","wharf","wheat","whiff","whiny","whole","widen","widow","width","wince","wired","wispy","woozy","worry","worst","wound","woven","wrath","wrist","xerox","yahoo","yeast","yield","yo-yo","yodel","yummy","zebra","zesty","zippy","able","acid","acre","acts","afar","aged","ahoy","aide","aids","ajar","aloe","alto","amid","anew","aqua","area","army","ashy","atom","atop","avid","awry","axis","barn","bash","bath","bats","blah","blip","blob","blog","blot","boat","body","boil","bolt","bony","book","boss","both","boxy","brim","bulb","bulk","bunt","bush","bust","buzz","cage","cake","calm","cane","cape","case","cash","chef","chip","chop","chug","city","clad","claw","clay","clip","coat","coil","coke","cola","cold","colt","coma","come","cone","cope","copy","cork","cost","cozy","crib","crop","crux","cube","cure","cusp","darn","dart","dash","data","dawn","dean","deck","deed","deem","defy","deny","dial","dice","dill","dime","dish","disk","dock","dole","dork","dose","dove","down","doze","drab","draw","drew","drum","duct","dude","duke","duly","dupe","dusk","dust","duty","each","eats","ebay","echo","edge","edgy","emit","envy","epic","even","evil","exes","exit","fade","fall","fame","fang","feed","feel","film","five","flap","fled","flip","flop","foam","foil","folk","font","food","fool","from","gala","game","gave","gawk","gear","geek","gift","glue","gnat","goal","goes","golf","gone","gong","good","goon","gore","gory","gout","gown","grab","gray","grew","grid","grip","grit","grub","gulf","gulp","guru","gush","guts","half","halt","hash","hate","hazy","heap","heat","huff","hula","hulk","hull","hunk","hurt","hush","icky","icon","idly","ipad","ipod","iron","item","java","jaws","jazz","jeep","jinx","john","jolt","judo","july","jump","june","jury","keep","kelp","kept","kick","kiln","kilt","king","kite","kiwi","knee","kung","lair","lake","lard","lark","lash","last","late","lazy","left","lego","lend","lens","lent","life","lily","limb","line","lint","lion","lisp","list","lung","lure","lurk","mace","malt","mama","many","math","mold","most","move","much","muck","mule","mute","mutt","myth","nail","name","nape","navy","neon","nerd","nest","next","oboe","ogle","oink","okay","omen","omit","only","onto","onyx","oops","ooze","oozy","opal","open","ouch","oval","oven","palm","pang","path","pelt","perm","peso","plod","plop","plot","plow","ploy","plug","plus","poem","poet","pogo","polo","pond","pony","pope","pork","posh","pout","pull","pulp","puma","punk","purr","putt","quit","race","rack","raft","rage","rake","ramp","rare","rash","ream","rely","reps","rice","ride","rift","rind","rink","riot","rise","risk","robe","romp","rope","rosy","ruby","rule","runt","ruse","rush","rust","saga","sage","said","sake","salt","same","sank","sash","scam","self","send","shed","ship","shun","shut","sift","silk","silo","silt","size","skid","slab","slam","slaw","sled","slip","slit","slot","slug","slum","smog","snap","snub","spew","spry","spud","spur","stem","step","stew","stir","such","suds","sulk","swab","swan","sway","taco","take","tall","tank","taps","task","that","thaw","thee","thud","thus","tidy","tile","till","tilt","tint","tiny","tray","tree","trio","turf","tusk","tutu","twig","tyke","unit","upon","used","user","veal","very","vest","veto","vice","visa","void","wake","walk","wand","wasp","wavy","wham","wick","wife","wifi","wilt","wimp","wind","wing","wipe","wiry","wise","wish","wolf","womb","woof","wool","word","work","xbox","yard","yarn","yeah","yelp","yoga","yoyo","zero","zips","zone","zoom","aim","art","bok","cod","cut","dab","dad","dig","dry","duh","duo","eel","elf","elk","elm","emu","fax","fit","foe","fog","fox","gab","gag","gap","gas","gem","guy","had","hug","hut","ice","icy","ion","irk","ivy","jab","jam","jet","job","jot","keg","lid","lip","map","mom","mop","mud","mug","nag","net","oaf","oak","oat","oil","old","opt","owl","pep","pod","pox","pry","pug","rug","rut","say","shy","sip","sly","tag","try","tug","tux","wad","why","wok","wow","yam","yen","yin","zap","zen","zit"]};var Fi=a(2052),ji=a.n(Fi);const Li=[{id:"not_available",label:"N/A",strength:0},{id:"very-weak",label:"Very weak",strength:1},{id:"weak",label:"Weak",strength:60},{id:"fair",label:"Fair",strength:80},{id:"strong",label:"Strong",strength:112},{id:"very-strong",label:"Very strong",strength:128}],qi={mask_upper:{label:"A-Z",characters:["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"]},mask_lower:{label:"a-z",characters:["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"]},mask_digit:{label:"0-9",characters:["0","1","2","3","4","5","6","7","8","9"]},mask_char1:{label:"# $ % & @ ^ ~",characters:["#","$","%","&","@","^","~"]},mask_parenthesis:{label:"{ [ ( | ) ] }",characters:["{","(","[","|","]",")","}"]},mask_char2:{label:". , : ;",characters:[".",",",":",";"]},mask_char3:{label:"' \" `",characters:["'",'"',"`"]},mask_char4:{label:"/ \\ _ -",characters:["/","\\","_","-"]},mask_char5:{label:"< * + ! ? =",characters:["<","*","+","!","?","="]},mask_emoji:{label:"😘",characters:["😀","😁","😂","😃","😄","😅","😆","😇","😈","😉","😊","😋","😌","😍","😎","😏","😐","😑","😒","😓","😔","😕","😖","😗","😘","😙","😚","😛","😜","😝","😞","😟","😠","😡","😢","😣","😤","😥","😦","😧","😨","😩","😪","😫","😬","😭","😮","😯","😰","😱","😲","😳","😴","😵","😶","😷","😸","😹","😺","😻","😼","😽","😾","😿","🙀","🙁","🙂","🙃","🙄","🙅","🙆","🙇","🙈","🙉","🙊","🙋","🙌","🙍","🙎","🙏"]}},zi=["O","l","|","I","0","1"],Ki=Object.values(qi).flatMap(e=>e.characters),Vi={evaluateMaxPasswordEntropy:e=>{const t=Object.entries(qi).filter(([t])=>e[t]).reduce((e,[t])=>[...e,...qi[t].characters],[]).filter(t=>!e.exclude_look_alike_chars||!zi.includes(t));return Gi(e.length,t.length)},entropyPassword:(e="")=>{const t=(new(ji())).splitGraphemes(e);let a=0;for(const[e]of Object.entries(qi)){const n=qi[e];t.some(e=>n.characters.includes(e))&&(a+=n.characters.length)}const n=new Set(t.filter(e=>!Ki.includes(e)));return Gi(t.length,a+n.size)},entropyPassphrase:(e=0,t="")=>Gi(e,3*Ui["en-UK"].length)+Vi.entropyPassword(t),strength:(e=0)=>Li.reduce((t,a)=>t?a.strength>t.strength&&e>=a.strength?a:t:a),calculEntropy:Gi};function Gi(e,t){return e&&t?e*(Math.log(t)/Math.log(2)):0}const Bi=function(e){const t={isPassphrase:!1};if(!e)return t;const a=Ui["en-UK"].reduce((e,t)=>{const a=e.remainingSecret.replace(new RegExp(t,"g"),""),n=(e.remainingSecret.length-a.length)/t.length;return{numberReplacement:e.numberReplacement+n,remainingSecret:a}},{numberReplacement:0,remainingSecret:e.toLowerCase()}),n=a.remainingSecret,s=a.numberReplacement-1;if(1===s)return-1===e.indexOf(n)||e.startsWith(n)||e.endsWith(n)?t:{numberWords:2,separator:n,isPassphrase:!0};if(0==n.length)return{numberWords:a.numberReplacement,separator:"",isPassphrase:!0};if(n.length%s!==0)return t;const i=n.length/s,r=n.substring(0,i),o=String(r).replace(/([-()[\]{}+?*.$^|,:#0}},Ji=(e,t)=>t.split(".").reduce((e,t)=>e?.[t],e),Xi=(e,t)=>{if(void 0===e||"string"!=typeof e||!e.length)return!1;if((t=t||{}).whitelistedProtocols&&!Array.isArray(t.whitelistedProtocols))throw new TypeError("The whitelistedProtocols should be an array of string.");if(t.defaultProtocol&&"string"!=typeof t.defaultProtocol)throw new TypeError("The defaultProtocol should be a string.");const a=t.whitelistedProtocols||[Qi.HTTP,Qi.HTTPS],n=[Qi.JAVASCRIPT],s=t.defaultProtocol||"";!/^(?:(?!:\/\/).)*:\/\//.test(e)&&s&&(e=`${s}//${e}`);try{const t=new URL(e);return!n.includes(t.protocol)&&!!a.includes(t.protocol)&&t.href}catch(e){return console.error("Failed to sanitize URL:",e),!1}},Qi={FTP:"http:",FTPS:"https:",HTTP:"http:",HTTPS:"https:",JAVASCRIPT:"javascript:",SSH:"ssh:"};class er{constructor(e){this.settings=this.sanitizeDto(e)}sanitizeDto(e){const t=JSON.parse(JSON.stringify(e));return this.sanitizeEmailValidateRegex(t),t}sanitizeEmailValidateRegex(e){const t=e?.passbolt?.email?.validate?.regex;t&&"string"==typeof t&&t.trim().length&&(e.passbolt.email.validate.regex=t.trim().replace(/^\/+/,"").replace(/\/+$/,""))}canIUse(e){let t=!1;const a=`passbolt.plugins.${e}`,n=Ji(this.settings,a)||null;if(n&&"object"==typeof n){const e=Ji(n,"enabled");void 0!==e&&!0!==e||(t=!0)}return t}isFeatureBeta(e){(0,ie.A)(e);const t=`passbolt.plugins.${e}.isInBeta`;return Ji(this.settings,t)||!1}getPluginSettings(e){const t=`passbolt.plugins.${e}`;return Ji(this.settings,t)}getRememberMeOptions(){return(this.getPluginSettings("rememberMe")||{}).options||{}}get hasRememberMeUntilILogoutOption(){return void 0!==(this.getRememberMeOptions()||{})[-1]}getServerTimezone(){return Ji(this.settings,"passbolt.app.server_timezone")}get termsLink(){const e=Ji(this.settings,"passbolt.legal.terms.url");return!!e&&Xi(e)}get privacyLink(){const e=Ji(this.settings,"passbolt.legal.privacy_policy.url");return!!e&&Xi(e)}get registrationPublic(){return!0===Ji(this.settings,"passbolt.registration.public")}get debug(){return!0===Ji(this.settings,"app.debug")}get url(){return Ji(this.settings,"app.url")||""}get version(){return Ji(this.settings,"app.version.number")}get isCommunityEdition(){return"ce"===Ji(this.settings,"passbolt.edition")}get locale(){return Ji(this.settings,"app.locale")||er.DEFAULT_LOCALE.locale}async setLocale(e){this.settings.app.locale=e}get supportedLocales(){return Ji(this.settings,"passbolt.plugins.locale.options")||er.DEFAULT_SUPPORTED_LOCALES}get generatorConfiguration(){return Ji(this.settings,"passbolt.plugins.generator.configuration")}get emailValidateRegex(){return this.settings?.passbolt?.email?.validate?.regex||null}static get DEFAULT_SUPPORTED_LOCALES(){return[er.DEFAULT_LOCALE]}static get DEFAULT_LOCALE(){return{locale:"en-UK",label:"English"}}}class tr{static validate(e){return"string"==typeof e&&Qt()("^[\\p{L}0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\p{L}0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[_\\p{L}0-9][-_\\p{L}0-9]*\\.)*(?:[\\p{L}0-9][-\\p{L}0-9]{0,62})\\.(?:(?:[a-z]{2}\\.)?[a-z]{2,})$","i").test(e)}}class ar{constructor(e){if("string"!=typeof e)throw Error("The regex should be a string.");this.regex=new(Qt())(e)}validate(e){return"string"==typeof e&&this.regex.test(e)}}class nr{static validate(e,t){return nr.getValidator(t).validate(e)}static getValidator(e){return e&&e instanceof er&&e.emailValidateRegex?new ar(e.emailValidateRegex):tr}}function sr(){return sr=Object.assign?Object.assign.bind():function(e){for(var t=1;t{}});class rr extends n.Component{constructor(e){super(e),this.state=this.defaultState}get defaultState(){return{policies:null,loadPolicies:this.loadPolicies.bind(this),setPolicies:this.setPolicies.bind(this)}}async loadPolicies(){const{policies:e}=this.state;if(null!==e)return e;const t=await this.props.context.port.request("passbolt.password-policies.get");return this.setPolicies(t),t}setPolicies(e){this.setState({policies:e})}render(){return n.createElement(ir.Provider,{value:this.state},this.props.children)}}function or(e){return class extends n.Component{render(){return n.createElement(ir.Consumer,null,t=>n.createElement(e,sr({passwordPoliciesContext:t},this.props)))}}}rr.propTypes={context:i().any,children:i().any},N(rr);class lr extends n.PureComponent{static getRelativeEntropyPosition(e){return 100-99/(1+Math.pow(e/90,3))}formatEntropy(e){return(e=e||0).toFixed(1)}get relativeTargetEntropyRatio(){return lr.getRelativeEntropyPosition(this.props.targetEntropy)}get targetEntropyPositionStyle(){return{left:`calc(${this.relativeTargetEntropyRatio}% - 0.6rem)`}}get colorClassName(){return this.hasEntropy()?this.props.entropy>=this.props.targetEntropy?"reached":this.props.isMinimumEntropyRequired?"required":"recommended":""}get targetTooltipMessage(){return this.props.isMinimumEntropyRequired?this.props.t("Minimal requirement"):this.props.t("Minimal recommendation")}get currentEntropyTooltipMessage(){const e=this.formatEntropy(this.props.entropy),t=this.formatEntropy(this.props.targetEntropy);return n.createElement(f.x6,null,"Entropy: ",{currentEntropy:e}," / ",{targettedEntropy:t}," bits")}get passwordStrengthLabel(){if(!this.hasEntropy()&&!this.hasError())return n.createElement(f.x6,null,"Quality");const e=Vi.strength(this.props.entropy);return n.createElement(n.Fragment,null,e.label)}getProgresseBarStyle(e){return{width:`${lr.getRelativeEntropyPosition(e)}%`}}hasEntropy(){return null!==this.props.entropy&&void 0!==this.props.entropy}hasError(){return this.props.error}render(){return n.createElement("div",{className:"password-complexity with-goal"},n.createElement("span",{className:"complexity-text"},n.createElement(Mt,{message:this.currentEntropyTooltipMessage},this.passwordStrengthLabel," ",n.createElement(jt,null))),n.createElement("span",{className:"progress"},n.createElement("span",{className:"progress-bar background"}),n.createElement("span",{className:`progress-bar target ${this.colorClassName}`,style:this.hasEntropy()?this.getProgresseBarStyle(this.props.targetEntropy):null}),n.createElement("span",{className:`progress-bar foreground ${this.colorClassName}`,style:this.hasEntropy()?this.getProgresseBarStyle(this.props.entropy):null}),n.createElement("span",{className:`target-entropy ${this.colorClassName}`,style:this.targetEntropyPositionStyle},n.createElement(Mt,{message:this.targetTooltipMessage},n.createElement("span",{className:"tooltip-anchor"})))))}}lr.defaultProps={isMinimumEntropyRequired:!0},lr.propTypes={targetEntropy:i().number.isRequired,isMinimumEntropyRequired:i().bool.isRequired,entropy:i().number,error:i().bool,t:i().func};const cr=(0,f.CI)("common")(lr);class mr extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.bindCallbacks(),this.createInputRef()}get defaultState(){return{name:"",nameError:"",email:"",emailError:"",algorithm:"RSA",keySize:4096,passphrase:"",passphraseConfirmation:"",passphraseWarning:"",passphraseEntropy:null,hasAlreadyBeenValidated:!1,isPwnedServiceAvailable:!0,passphraseInDictionnary:!1}}async componentDidMount(){const e=await this.props.passwordPoliciesContext.loadPolicies();this.initPwnedPasswordService(e)}bindCallbacks(){this.handleFormSubmit=this.handleFormSubmit.bind(this),this.handleInputChange=this.handleInputChange.bind(this),this.handleNameInputKeyUp=this.handleNameInputKeyUp.bind(this),this.handleEmailInputKeyUp=this.handleEmailInputKeyUp.bind(this),this.handlePassphraseChange=this.handlePassphraseChange.bind(this)}createInputRef(){this.nameInputRef=n.createRef(),this.emailInputRef=n.createRef(),this.passphraseInputRef=n.createRef(),this.passphraseConfirmationInputRef=n.createRef()}initPwnedPasswordService(e){const t=e?.external_dictionary_check;t&&(this.pownedService=new Zi(this.props.context.port)),this.setState({isPwnedServiceAvailable:t})}handleNameInputKeyUp(){this.state.hasAlreadyBeenValidated&&this.validateNameInput()}validateNameInput(){let e=null;return this.state.name.trim().length||(e=this.translate("A name is required.")),this.setState({nameError:e}),null===e}handleEmailInputKeyUp(){this.state.hasAlreadyBeenValidated&&this.validateEmailInput()}validateEmailInput(){let e=null;const t=this.state.email.trim();return t.length?nr.validate(t,this.props.context.siteSettings)||(e=this.translate("Please enter a valid email address.")):e=this.translate("An email is required."),this.setState({email:t,emailError:e}),null===e}async handlePassphraseChange(e){const t=e.target.value;this.setState({passphrase:t},()=>this.checkPassphraseValidity())}async checkPassphraseValidity(){let e=null;if(this.state.passphrase.length>0?e=(e=>{const{numberWords:t,separator:a,isPassphrase:n}=Bi(e);return n?Vi.entropyPassphrase(t,a):Vi.entropyPassword(e)})(this.state.passphrase):this.setState({passphraseInDictionnary:!1,passwordEntropy:null}),this.state.hasAlreadyBeenValidated)this.setState({passphraseInDictionnary:!1}),this.validatePassphraseInput();else{const e=this.state.passphrase.length>=4096,t=this.translate("this is the maximum size for this field, make sure your data was not truncated"),a=e?t:"";this.setState({passphraseWarning:a})}this.setState({passphraseEntropy:e})}validatePassphraseInput(){return!this.hasAnyErrors()}validatePassphraseConfirmationInput(){return!this.isEmptyPasswordConfirmation()&&!this.isPassphraseAndConfirmationDifferent()}hasWeakPassword(){return!this.isMinimumRequiredEntropyReached(this.state.passphraseEntropy)}isEmptyPasswordConfirmation(){return!this.state.passphraseConfirmation.length}isEmptyPassword(){return!this.state.passphrase.length}isPassphraseAndConfirmationDifferent(){return!this.isEmptyPasswordConfirmation()&&this.state.passphrase!==this.state.passphraseConfirmation}async evaluatePassphraseIsInDictionary(e){let t=this.state.isPwnedServiceAvailable;if(!t||!this.pownedService)return!1;let a=!1;try{const n=await this.pownedService.evaluateSecret(e);a=this.state.passphrase&&n.inDictionary&&this.isMinimumRequiredEntropyReached(this.state.passphraseEntropy),t=n.isPwnedServiceAvailable}catch(e){if(!(e instanceof Hi||e instanceof Yi))throw e;t=!1,a=!1}return this.setState({isPwnedServiceAvailable:t,passphraseInDictionnary:a}),a}handleInputChange(e){const t=e.target;this.setState({[t.name]:t.value})}handleValidateError(){this.focusFirstFieldError()}focusFirstFieldError(){this.state.nameError?this.nameInputRef.current.focus():this.state.emailError?this.emailInputRef.current.focus():this.hasAnyErrors()?this.passphraseInputRef.current.focus():this.validatePassphraseConfirmationInput()||this.passphraseConfirmationInputRef.current.focus()}async handleFormSubmit(e){e.preventDefault(),this.state.processing||(this.setState({hasAlreadyBeenValidated:!0}),await this.save())}hasAnyErrors(){const e=[this.isEmptyPassword(),this.state.passphraseInDictionnary];return e.push(this.hasWeakPassword()),e.push(!this.pownedService&&this.state.passphrase.length<8),e.includes(!0)}async save(){if(this.state.processing)return;if(this.setState({processing:!0}),!await this.validate())return this.handleValidateError(),void this.setState({processing:!1});if(await this.evaluatePassphraseIsInDictionary(this.state.passphrase))return void this.setState({processing:!1});const e=await this.generateKey();this.props.onUpdateOrganizationKey(e?.public_key?.armored_key,e?.private_key?.armored_key)}async validate(){const e=this.validateNameInput(),t=this.validateEmailInput(),a=this.validatePassphraseInput(),n=this.validatePassphraseConfirmationInput();return e&&t&&a&&n}async generateKey(){const e={name:this.state.name,email:this.state.email,algorithm:this.state.algorithm,keySize:this.state.keySize,passphrase:this.state.passphrase};return await this.props.context.port.request("passbolt.account-recovery.generate-organization-key",e)}hasAllInputDisabled(){return this.state.processing}isMinimumRequiredEntropyReached(e){return e>=80}get translate(){return this.props.t}get isPassphraseWarning(){return this.state.passphrase?.length>0&&!this.state.hasAlreadyBeenValidated&&(!this.state.isPwnedServiceAvailable||this.state.passphraseInDictionnary)}render(){const e=this.state.passphraseInDictionnary?0:this.state.passphraseEntropy;return n.createElement("form",{onSubmit:this.handleFormSubmit,noValidate:!0},n.createElement("div",{className:"form-content generate-organization-key"},n.createElement("div",{className:"input text required "+(this.state.nameError?"error":"")},n.createElement("label",{htmlFor:"generate-organization-key-form-name"},n.createElement(f.x6,null,"Name")),n.createElement("input",{id:"generate-organization-key-form-name",name:"name",type:"text",value:this.state.name,onKeyUp:this.handleNameInputKeyUp,onChange:this.handleInputChange,disabled:this.hasAllInputDisabled(),ref:this.nameInputRef,className:"required fluid",maxLength:"64",required:"required",autoComplete:"off",autoFocus:!0,placeholder:this.translate("Name")}),this.state.nameError&&n.createElement("div",{className:"name error-message"},this.state.nameError)),n.createElement("div",{className:"input text required "+(this.state.emailError?"error":"")},n.createElement("label",{htmlFor:"generate-organization-key-form-email"},n.createElement(f.x6,null,"Email")),n.createElement("input",{id:"generate-organization-key-form-email",name:"email",ref:this.emailInputRef,className:"required fluid",maxLength:"64",type:"email",autoComplete:"off",value:this.state.email,onChange:this.handleInputChange,placeholder:this.translate("Email Address"),onKeyUp:this.handleEmailInputKeyUp,disabled:this.hasAllInputDisabled(),required:"required"}),this.state.emailError&&n.createElement("div",{className:"email error-message"},this.state.emailError)),n.createElement("div",{className:"input select-wrapper"},n.createElement("label",{htmlFor:"generate-organization-key-form-algorithm"},n.createElement(f.x6,null,"Algorithm"),n.createElement(Mt,{message:this.translate("Algorithm and key size cannot be changed at the moment. These are secure default")},n.createElement(jt,null))),n.createElement("input",{id:"generate-organization-key-form-algorithm",name:"algorithm",value:this.state.algorithm,className:"fluid",type:"text",autoComplete:"off",disabled:!0})),n.createElement("div",{className:"input select-wrapper"},n.createElement("label",{htmlFor:"generate-organization-key-form-keySize"},n.createElement(f.x6,null,"Key Size"),n.createElement(Mt,{message:this.translate("Algorithm and key size cannot be changed at the moment. These are secure default")},n.createElement(jt,null))),n.createElement("input",{id:"generate-organization-key-form-key-size",name:"keySize",value:this.state.keySize,className:"fluid",type:"text",autoComplete:"off",disabled:!0})),n.createElement("div",{className:"input-password-wrapper input required "+(this.hasAnyErrors()&&this.state.hasAlreadyBeenValidated?"error":"")},n.createElement("label",{htmlFor:"generate-organization-key-form-password"},n.createElement(f.x6,null,"Organization key passphrase"),this.isPassphraseWarning&&n.createElement(tt,{className:"attention-required"})),n.createElement(Za,{id:"generate-organization-key-form-password",name:"password",placeholder:this.translate("Passphrase"),autoComplete:"new-password",preview:!0,securityToken:this.props.context.userSettings.getSecurityToken(),value:this.state.passphrase,onChange:this.handlePassphraseChange,disabled:this.hasAllInputDisabled(),inputRef:this.passphraseInputRef}),n.createElement(cr,{entropy:e,targetEntropy:80}),this.state.hasAlreadyBeenValidated&&n.createElement("div",{className:"password error-message"},this.isEmptyPassword()&&n.createElement("div",{className:"empty-passphrase error-message"},n.createElement(f.x6,null,"A passphrase is required.")),this.hasWeakPassword()&&e>0&&n.createElement("div",{className:"invalid-passphrase error-message"},n.createElement(f.x6,null,"A strong passphrase is required. The minimum complexity must be 'fair'.")),this.state.passphraseInDictionnary&&0===e&&!this.isEmptyPassword()&&n.createElement("div",{className:"invalid-passphrase error-message"},n.createElement(f.x6,null,"The passphrase should not be part of an exposed data breach.")))),n.createElement("div",{className:"input-password-wrapper input required "+(this.state.hasAlreadyBeenValidated&&!this.validatePassphraseConfirmationInput()?"error":"")},n.createElement("label",{htmlFor:"generate-organization-key-form-password"},n.createElement(f.x6,null,"Organization key passphrase confirmation")),n.createElement(Za,{id:"generate-organization-key-form-password-confirmation",name:"passphraseConfirmation",placeholder:this.translate("Passphrase confirmation"),autoComplete:"new-password",preview:!0,securityToken:this.props.context.userSettings.getSecurityToken(),value:this.state.passphraseConfirmation,onChange:this.handleInputChange,disabled:this.hasAllInputDisabled(),inputRef:this.passphraseConfirmationInputRef}),this.state.hasAlreadyBeenValidated&&n.createElement("div",{className:"password-confirmation error-message"},this.isEmptyPasswordConfirmation()&&n.createElement("div",{className:"empty-passphrase-confirmation error-message"},n.createElement(f.x6,null,"The passphrase confirmation is required.")),this.isPassphraseAndConfirmationDifferent()&&n.createElement("div",{className:"invalid-passphrase-confirmation error-message"},n.createElement(f.x6,null,"The passphrase confirmation should match the passphrase")))),n.createElement("div",{className:"warning message no-margin",id:"generate-organization-key-setting-overridden-banner"},n.createElement("p",null,n.createElement(f.x6,null,"Warning, we encourage you to generate your OpenPGP Organization Recovery Key separately. Make sure you keep a backup in a safe place.")))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement(gn,{disabled:this.hasAllInputDisabled(),onClick:this.props.onClose}),n.createElement(qs,{disabled:this.hasAllInputDisabled(),processing:this.state.processing,value:this.translate("Generate & Apply")})))}}mr.propTypes={context:i().any,onUpdateOrganizationKey:i().func,onClose:i().func,t:i().func,passwordPoliciesContext:i().object};const dr=N(h(or((0,f.CI)("common")(mr))));function ur(){return ur=Object.assign?Object.assign.bind():function(e){for(var t=1;t{await this.props.adminAccountRecoveryContext.downloadPrivateKey(e)}})}hasAllInputDisabled(){return this.state.processing||this.state.loading}hasOrganisationRecoveryKey(){const e=this.state.keyInfoDto;return Boolean(e)}isPolicyEnabled(){return Boolean("disabled"!==this.policy)}resetKeyInfo(){this.setState({keyInfoDto:null})}formatFingerprint(e){if(!e)return null;const t=e.toUpperCase().replace(/.{4}/g,"$& ");return n.createElement(n.Fragment,null,t.substr(0,24),n.createElement("br",null),t.substr(25))}formatUserIds(e){return e?e.map((e,t)=>n.createElement(n.Fragment,{key:t},e.name," <",e.email,">",n.createElement("br",null))):null}get translate(){return this.props.t}render(){const e=this.props.adminAccountRecoveryContext.hasPolicyChanges()||!this.hasOrganisationRecoveryKey()&&this.isPolicyEnabled();return n.createElement("div",{className:"row"},n.createElement("div",{className:"recover-account-settings main-column"},n.createElement("div",{className:"main-content"},n.createElement("h3",{className:"title"},n.createElement(f.x6,null,"Account Recovery")),n.createElement("form",{className:"form"},n.createElement("h4",{className:"no-border"},n.createElement(f.x6,null,"Account Recovery Policy")),n.createElement("p",null,n.createElement(f.x6,null,"In this section you can choose the default behavior of account recovery for all users.")),n.createElement("div",{className:"radiolist-alt"},n.createElement("div",{className:"input radio "+("mandatory"===this.policy?"checked":"")},n.createElement("input",{type:"radio",value:"mandatory",onChange:this.handlePolicyInputChange,name:"accountRecoveryPolicy",checked:"mandatory"===this.policy,id:"accountRecoveryPolicyMandatory",disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"accountRecoveryPolicyMandatory"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Prompt")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"Every user is required to provide a copy of their private key and passphrase during setup."),n.createElement("br",null),n.createElement(f.x6,null,"You should inform your users not to store personal passwords.")))),n.createElement("div",{className:"input radio "+("opt-out"===this.policy?"checked":"")},n.createElement("input",{type:"radio",value:"opt-out",onChange:this.handlePolicyInputChange,name:"accountRecoveryPolicy",checked:"opt-out"===this.policy,id:"accountRecoveryPolicyOptOut",disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"accountRecoveryPolicyOptOut"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Optional, Opt-out")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"Every user will be prompted to provide a copy of their private key and passphrase by default during the setup, but they can opt out.")))),n.createElement("div",{className:"input radio "+("opt-in"===this.policy?"checked":"")},n.createElement("input",{type:"radio",value:"opt-in",onChange:this.handlePolicyInputChange,name:"accountRecoveryPolicy",checked:"opt-in"===this.policy,id:"accountRecoveryPolicyOptIn",disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"accountRecoveryPolicyOptIn"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Optional, Opt-in")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"Every user can decide to provide a copy of their private key and passphrase by default during the setup, but they can opt in.")))),n.createElement("div",{className:"input radio "+("disabled"===this.policy?"checked":"")},n.createElement("input",{type:"radio",value:"disabled",onChange:this.handlePolicyInputChange,name:"accountRecoveryPolicy",checked:"disabled"===this.policy,id:"accountRecoveryPolicyDisable",disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"accountRecoveryPolicyDisable"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Disable (Default)")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"Backup of the private key and passphrase will not be stored. This is the safest option."),n.createElement(f.x6,null,"If users lose their private key and passphrase they will not be able to recover their account."))))),n.createElement("h4",null,n.createElement("span",{className:"input toggle-switch form-element "},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"organisationRecoveryKeyToggle",disabled:this.hasAllInputDisabled(),checked:this.isPolicyEnabled(),id:"recovery-key-toggle-button"}),n.createElement("label",{htmlFor:"recovery-key-toggle-button"},n.createElement(f.x6,null,"Organization Recovery Key")))),this.isPolicyEnabled()&&n.createElement(n.Fragment,null,n.createElement("p",null,n.createElement(f.x6,null,"Your organization recovery key will be used to decrypt and recover the private key and passphrase of the users that are participating in the account recovery program.")," ",n.createElement(f.x6,null,"The organization private recovery key should not be stored in passbolt.")," ",n.createElement(f.x6,null,"You should keep it offline in a safe place.")),n.createElement("div",{className:"recovery-key-details"},n.createElement("table",{className:"table-info recovery-key"},n.createElement("tbody",null,n.createElement("tr",{className:"user-ids"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"User ids")),this.organizationKeyInfo?.user_ids&&n.createElement("td",{className:"value"},this.formatUserIds(this.organizationKeyInfo.user_ids)),!this.organizationKeyInfo?.user_ids&&n.createElement("td",{className:"empty-value"},n.createElement(f.x6,null,"not available")),n.createElement("td",{className:"table-button"},n.createElement("button",{className:"button primary",type:"button",disabled:this.hasAllInputDisabled(),onClick:this.HandleUpdatePublicKeyClick},this.hasOrganisationRecoveryKey()&&n.createElement(f.x6,null,"Rotate Key"),!this.hasOrganisationRecoveryKey()&&n.createElement(f.x6,null,"Add an Organization Recovery Key")))),n.createElement("tr",{className:"fingerprint"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Fingerprint")),this.organizationKeyInfo?.fingerprint&&n.createElement("td",{className:"value"},this.formatFingerprint(this.organizationKeyInfo.fingerprint)),!this.organizationKeyInfo?.fingerprint&&n.createElement("td",{className:"empty-value"},n.createElement(f.x6,null,"not available"))),n.createElement("tr",{className:"algorithm"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Algorithm")),this.organizationKeyInfo?.algorithm&&n.createElement("td",{className:"value"},this.organizationKeyInfo.algorithm),!this.organizationKeyInfo?.algorithm&&n.createElement("td",{className:"empty-value"},n.createElement(f.x6,null,"not available"))),n.createElement("tr",{className:"key-length"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Key length")),this.organizationKeyInfo?.length&&n.createElement("td",{className:"value"},this.organizationKeyInfo.length),!this.organizationKeyInfo?.length&&n.createElement("td",{className:"empty-value"},n.createElement(f.x6,null,"not available"))),n.createElement("tr",{className:"created"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Created")),this.organizationKeyInfo?.created&&n.createElement("td",{className:"value",title:this.organizationKeyInfo.created},Hs(this.organizationKeyInfo.created,this.props.t,this.props.context.locale)),!this.organizationKeyInfo?.created&&n.createElement("td",{className:"empty-value"},n.createElement(f.x6,null,"not available"))),n.createElement("tr",{className:"expires"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Expires")),this.organizationKeyInfo?.expires&&n.createElement("td",{className:"value",title:this.organizationKeyInfo.expires},Hs(this.organizationKeyInfo.expires,this.props.t,this.props.context.locale)),!this.organizationKeyInfo?.expires&&n.createElement("td",{className:"empty-value"},n.createElement(f.x6,null,"not available"))))))))),e&&n.createElement("div",{className:"warning message",id:"email-notification-setting-overridden-banner"},this.props.adminAccountRecoveryContext.hasPolicyChanges()&&n.createElement("div",{id:"email-notification-setting-overridden-banner"},n.createElement("div",null,n.createElement("p",null,n.createElement(f.x6,null,"Don't forget to save your settings to apply your modification.")))),!this.hasOrganisationRecoveryKey()&&this.isPolicyEnabled()&&n.createElement("div",{id:"email-notification-setting-overridden-banner"},n.createElement("div",null,n.createElement("p",null,n.createElement(f.x6,null,"Warning, Don't forget to add an organization recovery key.")))))),n.createElement(Ai,null),Xa(n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"Need some help?")),n.createElement("p",null,n.createElement(f.x6,null,"For more information about account recovery, checkout the dedicated page on the help website.")),n.createElement("a",{className:"button",href:"https://passbolt.com/docs/admin/authentication/account-recovery/",target:"_blank",rel:"noopener noreferrer"},n.createElement(Er,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}vr.propTypes={context:i().object,dialogContext:i().any,administrationWorkspaceContext:i().object,adminAccountRecoveryContext:i().object,t:i().func};const wr=N(h(Ne(fi((0,f.CI)("common")(vr)))));class kr extends n.Component{render(){return n.createElement("div",{className:"row"},n.createElement("div",{className:"recover-account-settings-teasing main-column"},n.createElement("div",{className:"main-content"},n.createElement("h3",{className:"title",id:"recover-account-settings-title"},n.createElement(f.x6,null,"Account Recovery"),n.createElement(Ea,{className:"pro-teasing-icon"})),n.createElement("p",null,n.createElement(f.x6,null,"Recover lost user accounts.")),n.createElement("div",{className:"recover-account-info"},n.createElement("ul",{className:"recover-account-description"},n.createElement("li",null,n.createElement(fs,null),n.createElement(f.x6,null,"In case of passphrase loss.")),n.createElement("li",null,n.createElement(fs,null),n.createElement(f.x6,null,"In case of private key loss.")),n.createElement("li",null,n.createElement(fs,null),n.createElement(f.x6,null,"Configurable with an Organisation Recovery Key."))),n.createElement("div",null,n.createElement("a",{className:"button primary",href:"https://www.passbolt.com/ce-to-pro?utm_campaign=21060976-CE%20to%20Pro&utm_source=product",target:"_blank",rel:"noopener noreferrer"},n.createElement(f.x6,null,"Upgrade to Passbolt Pro")))))),Xa(n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"Need some help?")),n.createElement("p",null,n.createElement(f.x6,null,"For more information about account recovery, checkout the dedicated page on the help website.")),n.createElement("a",{className:"button",href:"https://passbolt.com/docs/admin/authentication/account-recovery/",target:"_blank",rel:"noopener noreferrer"},n.createElement(Er,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}kr.propTypes={context:i().object,t:i().func};const _r=N((0,f.CI)("common")(kr)),xr={25:{port:25,tls:!1},2525:{port:2525,tls:!1},587:{port:587,tls:!0},588:{port:588,tls:!0},465:{port:465,tls:!0}};function Sr(e,t){const a=[];for(let n=0;n(!a||e.host===a)&&e.port===t)}const Nr={id:"aws-ses",name:"AWS SES",icon:"aws-ses.svg",help_page:"https://docs.aws.amazon.com/ses/latest/dg/send-email-smtp.html",availableConfigurations:Sr(function(){const e=[];return["us-east-2","us-east-1","us-west-1","us-west-2","ap-south-1","ap-northeast-3","ap-northeast-2","ap-northeast-1","ap-southeast-1","ap-southeast-2","ca-central-1","eu-central-1","eu-west-1","eu-west-2","eu-west-3","sa-east-1","us-gov-west-1"].forEach(t=>{e.push(`email-smtp.${t}.amazonaws.com`)}),e}(),[25,2525,587])};Nr.defaultConfiguration=Cr(Nr,587,"email-smtp.eu-central-1.amazonaws.com");const Tr={id:"elastic-email",name:"ElasticEmail",icon:"elastic-email.svg",help_page:"https://help.elasticemail.com/en/articles/4803409-smtp-settings",availableConfigurations:Sr(["smtp.elasticemail.com","smtp25.elasticemail.com"],[25,2525,587])};Tr.defaultConfiguration=Cr(Tr,587,"smtp.elasticemail.com");const Ar={id:"google-workspace",name:"Google Workspace",icon:"gmail.svg",help_page:"https://support.google.com/a/answer/2956491",availableConfigurations:Sr(["smtp-relay.gmail.com"],[25,587])};Ar.defaultConfiguration=Cr(Ar,587);const Ir={id:"google-mail",name:"Google Mail",icon:"gmail.svg",help_page:"https://support.google.com/a/answer/2956491",availableConfigurations:Sr(["smtp.gmail.com"],[587])};Ir.defaultConfiguration=Cr(Ir,587);const Rr={id:"mailgun",name:"MailGun",icon:"mailgun.svg",help_page:"https://documentation.mailgun.com/en/latest/quickstart-sending.html",availableConfigurations:Sr(["smtp.mailgun.com"],[587])};Rr.defaultConfiguration=Rr.availableConfigurations[0];const Pr={id:"mailjet",name:"Mailjet",icon:"mailjet.svg",help_page:"https://dev.mailjet.com/smtp-relay/configuration/",availableConfigurations:Sr(["in-v3.mailjet.com"],[25,2525,587,588])};Pr.defaultConfiguration=Cr(Pr,587);const Dr={id:"mandrill",name:"Mandrill",icon:"mandrill.svg",help_page:"https://mailchimp.com/developer/transactional/docs/smtp-integration/",availableConfigurations:Sr(["smtp.mandrillapp.com"],[25,2525,587])};Dr.defaultConfiguration=Cr(Dr,587);const Or={id:"office-365",name:"Office 365",icon:"office365.svg",help_page:"https://learn.microsoft.com/exchange/mail-flow-best-practices/how-to-set-up-a-multifunction-device-or-application-to-send-email-using-microsoft-365-or-office-365",availableConfigurations:Sr(["smtp.office365.com"],[25,587])};Or.defaultConfiguration=Cr(Or,587);const Mr={id:"outlook",name:"Outlook",icon:"outlook.svg",help_page:"https://support.microsoft.com/office/pop-imap-and-smtp-settings-for-outlook-com-d088b986-291d-42b8-9564-9c414e2aa040",availableConfigurations:Sr(["smtp-mail.outlook.com"],[587])};Mr.defaultConfiguration=Cr(Mr,587);const Ur={id:"sendgrid",name:"Sendgrid",icon:"sendgrid.svg",help_page:"https://docs.sendgrid.com/for-developers/sending-email/integrating-with-the-smtp-api",availableConfigurations:Sr(["smtp.sendgrid.net"],[25,2525,587])};Ur.defaultConfiguration=Cr(Ur,587);const Fr={id:"sendinblue",name:"Sendinblue",icon:"sendinblue.svg",help_page:"https://help.sendinblue.com/hc/en-us/articles/209462765",availableConfigurations:Sr(["smtp-relay.sendinblue.com"],[25,587])};Fr.defaultConfiguration=Cr(Fr,587);const jr={id:"zoho",name:"Zoho",icon:"zoho.svg",help_page:"https://www.zoho.com/mail/help/zoho-smtp.html",availableConfigurations:Sr(["smtp.zoho.eu","smtppro.zoho.eu"],[587])};jr.defaultConfiguration=Cr(jr,587,"smtp.zoho.eu");const Lr=[Nr,Tr,Ir,Ar,Rr,Pr,Dr,Or,Mr,Ur,Fr,jr,{id:"other",name:"Other",icon:null,availableConfigurations:[],defaultConfiguration:{host:"",port:"",tls:!0}}];class qr extends sa{constructor(e){super(e,qr.RESOURCE_NAME)}static get RESOURCE_NAME(){return"smtp/settings"}async find(){const e=await this.apiClient.findAll();return e.body.tls=Boolean(e.body.tls),new oa(e)}async create(e){this.assertNonEmptyData(e);const t=await this.apiClient.create(e);return t.body.tls=Boolean(t.body.tls),new oa(t)}}const zr=qr,Kr=class extends he{static getSchema(){return{type:"object",required:[...$r.getSchema().required],properties:{...$r.getSchema().properties}}}marshall(){"string"==typeof this._props.port&&(this._props.port=parseInt(this._props.port,10)),super.marshall()}static getDefaultData(){return{}}toDto(){return{...super.toDto(),username:null,password:null}}static get ENTITY_NAME(){return"SmtpNoneAuthentication"}},Vr=class extends he{static getSchema(){return{type:"object",required:[...$r.getSchema().required,"username"],properties:{...$r.getSchema().properties,username:{type:"string",maxLength:256}}}}marshall(){"string"==typeof this._props.port&&(this._props.port=parseInt(this._props.port,10)),super.marshall()}static getDefaultData(){return{username:"",password:null,tenant_id:null,client_id:null,client_secret:null}}toDto(){return{...super.toDto(),password:null}}static get ENTITY_NAME(){return"SmtpUsernameAuthentication"}},Gr=class extends he{static getSchema(){return{type:"object",required:[...$r.getSchema().required,"username","password"],properties:{...$r.getSchema().properties,username:{type:"string",maxLength:256},password:{type:"string",maxLength:4096}}}}marshall(){"string"==typeof this._props.port&&(this._props.port=parseInt(this._props.port,10)),super.marshall()}static getDefaultData(){return{username:"",password:"",tenant_id:null,client_id:null,client_secret:null}}static get ENTITY_NAME(){return"SmtpUsernamePasswordAuthentication"}},Br=class extends he{static getSchema(){return{type:"object",required:[...$r.getSchema().required,"oauth_username","tenant_id","client_id","client_secret"],properties:{...$r.getSchema().properties,oauth_username:{type:"string",format:"email",maxLength:256},tenant_id:{type:"string",format:"uuid"},client_id:{type:"string",format:"uuid"},client_secret:{type:"string",minLength:1,maxLength:256},username:{type:"string",nullable:!0},password:{type:"string",nullable:!0}}}}marshall(){"string"==typeof this._props.port&&(this._props.port=parseInt(this._props.port,10)),super.marshall()}static getDefaultData(){return{oauth_username:"",password:null,tenant_id:"",client_id:"",client_secret:""}}static get ENTITY_NAME(){return"SmtpOAuthCredentialsGrantSettings"}},Wr="default",Hr="file",$r=class extends he{static getSchema(){return{type:"object",required:["host","port","sender_name","sender_email"],properties:{id:{type:"string",format:"uuid",nullable:!0},created:{type:"string",format:"date-time",nullable:!0},modified:{type:"string",format:"date-time",nullable:!0},source:{type:"string",enum:[Wr,"env","db",Hr]},host:{type:"string",minLength:1,maxLength:256},port:{type:"integer",minimum:1,maximum:65535},tls:{type:"boolean",nullable:!0},client:{type:"string",nullable:!0,maxLength:2048},sender_name:{type:"string",minLength:1,maxLength:256},sender_email:{type:"string",format:"email",maxLength:256}}}}marshall(){"string"==typeof this._props.port&&(this._props.port=parseInt(this._props.port,10)),super.marshall()}static createFromSettings(e,t={}){return"client_id"in e&&null!==e.client_id?new Br(e,t):"username"in e&&null!==e.username?"password"in e&&null!==e.password?new Gr(e,t):new Vr(e,t):new Kr(e,t)}static get ENTITY_NAME(){return"SmtpSettings"}static get SETTINGS_SOURCE_DEFAULT(){return Wr}static get SETTINGS_SOURCE_ENV(){return"env"}static get SETTINGS_SOURCE_DB(){return"db"}static get SETTINGS_SOURCE_FILE(){return Hr}},Yr=class{constructor(e){this.smtpSettingsApiService=new zr(e)}async find(){const e=await this.smtpSettingsApiService.find();return $r.createFromSettings(e.body)}},Zr=class{constructor(e){this.smtpSettingsApiService=new zr(e)}async save(e){const t=await this.smtpSettingsApiService.create(e.toDto());return $r.createFromSettings(t.body)}},Jr=["0-mail.com","007addict.com","020.co.uk","027168.com","0815.ru","0815.su","0clickemail.com","0sg.net","0wnd.net","0wnd.org","1033edge.com","10mail.org","10minutemail.co.za","10minutemail.com","11mail.com","123-m.com","123.com","123box.net","123india.com","123mail.cl","123mail.org","123qwe.co.uk","126.com","126.net","138mail.com","139.com","150mail.com","150ml.com","15meg4free.com","163.com","16mail.com","188.com","189.cn","1auto.com","1ce.us","1chuan.com","1colony.com","1coolplace.com","1email.eu","1freeemail.com","1fsdfdsfsdf.tk","1funplace.com","1internetdrive.com","1mail.ml","1mail.net","1me.net","1mum.com","1musicrow.com","1netdrive.com","1nsyncfan.com","1pad.de","1under.com","1webave.com","1webhighway.com","1zhuan.com","2-mail.com","20email.eu","20mail.in","20mail.it","20minutemail.com","212.com","21cn.com","247emails.com","24horas.com","2911.net","2980.com","2bmail.co.uk","2coolforyou.net","2d2i.com","2die4.com","2fdgdfgdfgdf.tk","2hotforyou.net","2mydns.com","2net.us","2prong.com","2trom.com","3000.it","30minutemail.com","30minutesmail.com","3126.com","321media.com","33mail.com","360.ru","37.com","3ammagazine.com","3dmail.com","3email.com","3g.ua","3mail.ga","3trtretgfrfe.tk","3xl.net","444.net","4email.com","4email.net","4gfdsgfdgfd.tk","4mg.com","4newyork.com","4warding.com","4warding.net","4warding.org","4x4fan.com","4x4man.com","50mail.com","5fm.za.com","5ghgfhfghfgh.tk","5iron.com","5star.com","60minutemail.com","6hjgjhgkilkj.tk","6ip.us","6mail.cf","6paq.com","702mail.co.za","74.ru","7mail.ga","7mail.ml","7tags.com","88.am","8848.net","888.nu","8mail.ga","8mail.ml","97rock.com","99experts.com","9ox.net","a-bc.net","a-player.org","a2z4u.net","a45.in","aaamail.zzn.com","aahlife.com","aamail.net","aapt.net.au","aaronkwok.net","abbeyroadlondon.co.uk","abcflash.net","abdulnour.com","aberystwyth.com","abolition-now.com","about.com","absolutevitality.com","abusemail.de","abv.bg","abwesend.de","abyssmail.com","ac20mail.in","academycougars.com","acceso.or.cr","access4less.net","accessgcc.com","accountant.com","acdcfan.com","acdczone.com","ace-of-base.com","acmecity.com","acmemail.net","acninc.net","acrobatmail.com","activatormail.com","activist.com","adam.com.au","add3000.pp.ua","addcom.de","address.com","adelphia.net","adexec.com","adfarrow.com","adinet.com.uy","adios.net","admin.in.th","administrativos.com","adoption.com","ados.fr","adrenalinefreak.com","adres.nl","advalvas.be","advantimo.com","aeiou.pt","aemail4u.com","aeneasmail.com","afreeinternet.com","africa-11.com","africamail.com","africamel.net","africanpartnersonline.com","afrobacon.com","ag.us.to","agedmail.com","agelessemail.com","agoodmail.com","ahaa.dk","ahk.jp","aichi.com","aim.com","aircraftmail.com","airforce.net","airforceemail.com","airpost.net","aiutamici.com","ajacied.com","ajaxapp.net","ak47.hu","aknet.kg","akphantom.com","albawaba.com","alecsmail.com","alex4all.com","alexandria.cc","algeria.com","algeriamail.com","alhilal.net","alibaba.com","alice.it","aliceadsl.fr","aliceinchainsmail.com","alivance.com","alive.cz","aliyun.com","allergist.com","allmail.net","alloymail.com","allracing.com","allsaintsfan.com","alltel.net","alpenjodel.de","alphafrau.de","alskens.dk","altavista.com","altavista.net","altavista.se","alternativagratis.com","alumni.com","alumnidirector.com","alvilag.hu","ama-trade.de","amail.com","amazonses.com","amele.com","america.hm","ameritech.net","amilegit.com","amiri.net","amiriindustries.com","amnetsal.com","amorki.pl","amrer.net","amuro.net","amuromail.com","ananzi.co.za","ancestry.com","andreabocellimail.com","andylau.net","anfmail.com","angelfan.com","angelfire.com","angelic.com","animail.net","animal.net","animalhouse.com","animalwoman.net","anjungcafe.com","anniefans.com","annsmail.com","ano-mail.net","anonmails.de","anonymbox.com","anonymous.to","anote.com","another.com","anotherdomaincyka.tk","anotherwin95.com","anti-ignorance.net","anti-social.com","antichef.com","antichef.net","antiqueemail.com","antireg.ru","antisocial.com","antispam.de","antispam24.de","antispammail.de","antongijsen.com","antwerpen.com","anymoment.com","anytimenow.com","aol.co.uk","aol.com","aol.de","aol.fr","aol.it","aol.jp","aon.at","apexmail.com","apmail.com","apollo.lv","aport.ru","aport2000.ru","apple.sib.ru","appraiser.net","approvers.net","aquaticmail.net","arabia.com","arabtop.net","arcademaster.com","archaeologist.com","archerymail.com","arcor.de","arcotronics.bg","arcticmail.com","argentina.com","arhaelogist.com","aristotle.org","army.net","armyspy.com","arnet.com.ar","art-en-ligne.pro","artistemail.com","artlover.com","artlover.com.au","artman-conception.com","as-if.com","asdasd.nl","asean-mail","asean-mail.com","asheville.com","asia-links.com","asia-mail.com","asia.com","asiafind.com","asianavenue.com","asiancityweb.com","asiansonly.net","asianwired.net","asiapoint.net","askaclub.ru","ass.pp.ua","assala.com","assamesemail.com","astroboymail.com","astrolover.com","astrosfan.com","astrosfan.net","asurfer.com","atheist.com","athenachu.net","atina.cl","atl.lv","atlas.cz","atlaswebmail.com","atlink.com","atmc.net","ato.check.com","atozasia.com","atrus.ru","att.net","attglobal.net","attymail.com","au.ru","auctioneer.net","aufeminin.com","aus-city.com","ausi.com","aussiemail.com.au","austin.rr.com","australia.edu","australiamail.com","austrosearch.net","autoescuelanerja.com","autograf.pl","automail.ru","automotiveauthority.com","autorambler.ru","aver.com","avh.hu","avia-tonic.fr","avtoritet.ru","awayonvacation.com","awholelotofamechi.com","awsom.net","axoskate.com","ayna.com","azazazatashkent.tk","azimiweb.com","azmeil.tk","bachelorboy.com","bachelorgal.com","backfliper.com","backpackers.com","backstreet-boys.com","backstreetboysclub.com","backtothefuturefans.com","backwards.com","badtzmail.com","bagherpour.com","bahrainmail.com","bakpaka.com","bakpaka.net","baldmama.de","baldpapa.de","ballerstatus.net","ballyfinance.com","balochistan.org","baluch.com","bangkok.com","bangkok2000.com","bannertown.net","baptistmail.com","baptized.com","barcelona.com","bareed.ws","barid.com","barlick.net","bartender.net","baseball-email.com","baseballmail.com","basketballmail.com","batuta.net","baudoinconsulting.com","baxomale.ht.cx","bboy.com","bboy.zzn.com","bcvibes.com","beddly.com","beeebank.com","beefmilk.com","beenhad.com","beep.ru","beer.com","beerandremotes.com","beethoven.com","beirut.com","belice.com","belizehome.com","belizemail.net","belizeweb.com","bell.net","bellair.net","bellsouth.net","berkscounty.com","berlin.com","berlin.de","berlinexpo.de","bestmail.us","betriebsdirektor.de","bettergolf.net","bharatmail.com","big1.us","big5mail.com","bigassweb.com","bigblue.net.au","bigboab.com","bigfoot.com","bigfoot.de","bigger.com","biggerbadder.com","bigmailbox.com","bigmir.net","bigpond.au","bigpond.com","bigpond.com.au","bigpond.net","bigpond.net.au","bigramp.com","bigstring.com","bikemechanics.com","bikeracer.com","bikeracers.net","bikerider.com","billsfan.com","billsfan.net","bimamail.com","bimla.net","bin-wieder-da.de","binkmail.com","bio-muesli.info","bio-muesli.net","biologyfan.com","birdfanatic.com","birdlover.com","birdowner.net","bisons.com","bitmail.com","bitpage.net","bizhosting.com","bk.ru","bkkmail.com","bla-bla.com","blackburnfans.com","blackburnmail.com","blackplanet.com","blader.com","bladesmail.net","blazemail.com","bleib-bei-mir.de","blink182.net","blockfilter.com","blogmyway.org","blondandeasy.com","bluebottle.com","bluehyppo.com","bluemail.ch","bluemail.dk","bluesfan.com","bluewin.ch","blueyonder.co.uk","blumail.org","blushmail.com","blutig.me","bmlsports.net","boardermail.com","boarderzone.com","boatracers.com","bobmail.info","bodhi.lawlita.com","bofthew.com","bol.com.br","bolando.com","bollywoodz.com","bolt.com","boltonfans.com","bombdiggity.com","bonbon.net","boom.com","bootmail.com","bootybay.de","bornagain.com","bornnaked.com","bossofthemoss.com","bostonoffice.com","boun.cr","bounce.net","bounces.amazon.com","bouncr.com","box.az","box.ua","boxbg.com","boxemail.com","boxformail.in","boxfrog.com","boximail.com","boyzoneclub.com","bradfordfans.com","brasilia.net","bratan.ru","brazilmail.com","brazilmail.com.br","breadtimes.press","breakthru.com","breathe.com","brefmail.com","brennendesreich.de","bresnan.net","brestonline.com","brew-master.com","brew-meister.com","brfree.com.br","briefemail.com","bright.net","britneyclub.com","brittonsign.com","broadcast.net","broadwaybuff.com","broadwaylove.com","brokeandhappy.com","brokenvalve.com","brujula.net","brunetka.ru","brusseler.com","bsdmail.com","bsnow.net","bspamfree.org","bt.com","btcc.org","btcmail.pw","btconnect.co.uk","btconnect.com","btinternet.com","btopenworld.co.uk","buerotiger.de","buffymail.com","bugmenot.com","bulgaria.com","bullsfan.com","bullsgame.com","bumerang.ro","bumpymail.com","bumrap.com","bund.us","bunita.net","bunko.com","burnthespam.info","burntmail.com","burstmail.info","buryfans.com","bushemail.com","business-man.com","businessman.net","businessweekmail.com","bust.com","busta-rhymes.com","busymail.com","busymail.com.com","busymail.comhomeart.com","butch-femme.net","butovo.net","buyersusa.com","buymoreplays.com","buzy.com","bvimailbox.com","byke.com","byom.de","byteme.com","c2.hu","c2i.net","c3.hu","c4.com","c51vsgq.com","cabacabana.com","cable.comcast.com","cableone.net","caere.it","cairomail.com","calcuttaads.com","calendar-server.bounces.google.com","calidifontain.be","californiamail.com","callnetuk.com","callsign.net","caltanet.it","camidge.com","canada-11.com","canada.com","canadianmail.com","canoemail.com","cantv.net","canwetalk.com","caramail.com","card.zp.ua","care2.com","careceo.com","careerbuildermail.com","carioca.net","cartelera.org","cartestraina.ro","casablancaresort.com","casema.nl","cash4u.com","cashette.com","casino.com","casualdx.com","cataloniamail.com","cataz.com","catcha.com","catchamail.com","catemail.com","catholic.org","catlover.com","catsrule.garfield.com","ccnmail.com","cd2.com","cek.pm","celineclub.com","celtic.com","center-mail.de","centermail.at","centermail.com","centermail.de","centermail.info","centermail.net","centoper.it","centralpets.com","centrum.cz","centrum.sk","centurylink.net","centurytel.net","certifiedmail.com","cfl.rr.com","cgac.es","cghost.s-a-d.de","chacuo.net","chaiyo.com","chaiyomail.com","chalkmail.net","chammy.info","chance2mail.com","chandrasekar.net","channelonetv.com","charityemail.com","charmedmail.com","charter.com","charter.net","chat.ru","chatlane.ru","chattown.com","chauhanweb.com","cheatmail.de","chechnya.conf.work","check.com","check.com12","check1check.com","cheeb.com","cheerful.com","chef.net","chefmail.com","chek.com","chello.nl","chemist.com","chequemail.com","cheshiremail.com","cheyenneweb.com","chez.com","chickmail.com","chil-e.com","childrens.md","childsavetrust.org","china.com","china.net.vg","chinalook.com","chinamail.com","chinesecool.com","chirk.com","chocaholic.com.au","chocofan.com","chogmail.com","choicemail1.com","chong-mail.com","chong-mail.net","christianmail.net","chronicspender.com","churchusa.com","cia-agent.com","cia.hu","ciaoweb.it","cicciociccio.com","cincinow.net","cirquefans.com","citeweb.net","citiz.net","citlink.net","city-of-bath.org","city-of-birmingham.com","city-of-brighton.org","city-of-cambridge.com","city-of-coventry.com","city-of-edinburgh.com","city-of-lichfield.com","city-of-lincoln.com","city-of-liverpool.com","city-of-manchester.com","city-of-nottingham.com","city-of-oxford.com","city-of-swansea.com","city-of-westminster.com","city-of-westminster.net","city-of-york.net","city2city.com","citynetusa.com","cityofcardiff.net","cityoflondon.org","ciudad.com.ar","ckaazaza.tk","claramail.com","classicalfan.com","classicmail.co.za","clear.net.nz","clearwire.net","clerk.com","clickforadate.com","cliffhanger.com","clixser.com","close2you.ne","close2you.net","clrmail.com","club-internet.fr","club4x4.net","clubalfa.com","clubbers.net","clubducati.com","clubhonda.net","clubmember.org","clubnetnoir.com","clubvdo.net","cluemail.com","cmail.net","cmail.org","cmail.ru","cmpmail.com","cmpnetmail.com","cnegal.com","cnnsimail.com","cntv.cn","codec.ro","codec.ro.ro","codec.roemail.ro","coder.hu","coid.biz","coldemail.info","coldmail.com","collectiblesuperstore.com","collector.org","collegebeat.com","collegeclub.com","collegemail.com","colleges.com","columbus.rr.com","columbusrr.com","columnist.com","comast.com","comast.net","comcast.com","comcast.net","comic.com","communityconnect.com","complxmind.com","comporium.net","comprendemail.com","compuserve.com","computer-expert.net","computer-freak.com","computer4u.com","computerconfused.com","computermail.net","computernaked.com","conexcol.com","cong.ru","conk.com","connect4free.net","connectbox.com","conok.com","consultant.com","consumerriot.com","contractor.net","contrasto.cu.cc","cookiemonster.com","cool.br","cool.fr.nf","coole-files.de","coolgoose.ca","coolgoose.com","coolkiwi.com","coollist.com","coolmail.com","coolmail.net","coolrio.com","coolsend.com","coolsite.net","cooooool.com","cooperation.net","cooperationtogo.net","copacabana.com","copper.net","copticmail.com","cornells.com","cornerpub.com","corporatedirtbag.com","correo.terra.com.gt","corrsfan.com","cortinet.com","cosmo.com","cotas.net","counsellor.com","countrylover.com","courriel.fr.nf","courrieltemporaire.com","cox.com","cox.net","coxinet.net","cpaonline.net","cracker.hu","craftemail.com","crapmail.org","crazedanddazed.com","crazy.ru","crazymailing.com","crazysexycool.com","crewstart.com","cristianemail.com","critterpost.com","croeso.com","crosshairs.com","crosswinds.net","crunkmail.com","crwmail.com","cry4helponline.com","cryingmail.com","cs.com","csinibaba.hu","cubiclink.com","cuemail.com","cumbriamail.com","curio-city.com","curryworld.de","curtsmail.com","cust.in","cute-girl.com","cuteandcuddly.com","cutekittens.com","cutey.com","cuvox.de","cww.de","cyber-africa.net","cyber-innovation.club","cyber-matrix.com","cyber-phone.eu","cyber-wizard.com","cyber4all.com","cyberbabies.com","cybercafemaui.com","cybercity-online.net","cyberdude.com","cyberforeplay.net","cybergal.com","cybergrrl.com","cyberinbox.com","cyberleports.com","cybermail.net","cybernet.it","cyberservices.com","cyberspace-asia.com","cybertrains.org","cyclefanz.com","cymail.net","cynetcity.com","d3p.dk","dabsol.net","dacoolest.com","dadacasa.com","daha.com","dailypioneer.com","dallas.theboys.com","dallasmail.com","dandikmail.com","dangerous-minds.com","dansegulvet.com","dasdasdascyka.tk","data54.com","date.by","daum.net","davegracey.com","dawnsonmail.com","dawsonmail.com","dayrep.com","dazedandconfused.com","dbzmail.com","dcemail.com","dcsi.net","ddns.org","deadaddress.com","deadlymob.org","deadspam.com","deafemail.net","deagot.com","deal-maker.com","dearriba.com","death-star.com","deepseafisherman.net","deforestationsucks.com","degoo.com","dejanews.com","delikkt.de","deliveryman.com","deneg.net","depechemode.com","deseretmail.com","desertmail.com","desertonline.com","desertsaintsmail.com","desilota.com","deskmail.com","deskpilot.com","despam.it","despammed.com","destin.com","detik.com","deutschland-net.com","devnullmail.com","devotedcouples.com","dezigner.ru","dfgh.net","dfwatson.com","dglnet.com.br","dgoh.org","di-ve.com","diamondemail.com","didamail.com","die-besten-bilder.de","die-genossen.de","die-optimisten.de","die-optimisten.net","die.life","diehardmail.com","diemailbox.de","digibel.be","digital-filestore.de","digitalforeplay.net","digitalsanctuary.com","digosnet.com","dingbone.com","diplomats.com","directbox.com","director-general.com","diri.com","dirtracer.com","dirtracers.com","discard.email","discard.ga","discard.gq","discardmail.com","discardmail.de","disciples.com","discofan.com","discovery.com","discoverymail.com","discoverymail.net","disign-concept.eu","disign-revelation.com","disinfo.net","dispomail.eu","disposable.com","disposableaddress.com","disposableemailaddresses.com","disposableinbox.com","dispose.it","dispostable.com","divismail.ru","divorcedandhappy.com","dm.w3internet.co.uk","dmailman.com","dmitrovka.net","dmitry.ru","dnainternet.net","dnsmadeeasy.com","doar.net","doclist.bounces.google.com","docmail.cz","docs.google.com","doctor.com","dodgeit.com","dodgit.com","dodgit.org","dodo.com.au","dodsi.com","dog.com","dogit.com","doglover.com","dogmail.co.uk","dogsnob.net","doityourself.com","domforfb1.tk","domforfb2.tk","domforfb3.tk","domforfb4.tk","domforfb5.tk","domforfb6.tk","domforfb7.tk","domforfb8.tk","domozmail.com","doneasy.com","donegal.net","donemail.ru","donjuan.com","dontgotmail.com","dontmesswithtexas.com","dontreg.com","dontsendmespam.de","doramail.com","dostmail.com","dotcom.fr","dotmsg.com","dotnow.com","dott.it","download-privat.de","dplanet.ch","dr.com","dragoncon.net","dragracer.com","drdrb.net","drivehq.com","dropmail.me","dropzone.com","drotposta.hu","dubaimail.com","dublin.com","dublin.ie","dump-email.info","dumpandjunk.com","dumpmail.com","dumpmail.de","dumpyemail.com","dunlopdriver.com","dunloprider.com","duno.com","duskmail.com","dustdevil.com","dutchmail.com","dvd-fan.net","dwp.net","dygo.com","dynamitemail.com","dyndns.org","e-apollo.lv","e-hkma.com","e-mail.com","e-mail.com.tr","e-mail.dk","e-mail.org","e-mail.ru","e-mail.ua","e-mailanywhere.com","e-mails.ru","e-tapaal.com","e-webtec.com","e4ward.com","earthalliance.com","earthcam.net","earthdome.com","earthling.net","earthlink.net","earthonline.net","eastcoast.co.za","eastlink.ca","eastmail.com","eastrolog.com","easy.com","easy.to","easypeasy.com","easypost.com","easytrashmail.com","eatmydirt.com","ebprofits.net","ec.rr.com","ecardmail.com","ecbsolutions.net","echina.com","ecolo-online.fr","ecompare.com","edmail.com","ednatx.com","edtnmail.com","educacao.te.pt","educastmail.com","eelmail.com","ehmail.com","einmalmail.de","einrot.com","einrot.de","eintagsmail.de","eircom.net","ekidz.com.au","elisanet.fi","elitemail.org","elsitio.com","eltimon.com","elvis.com","elvisfan.com","email-fake.gq","email-london.co.uk","email-value.com","email.biz","email.cbes.net","email.com","email.cz","email.ee","email.it","email.nu","email.org","email.ro","email.ru","email.si","email.su","email.ua","email.women.com","email2me.com","email2me.net","email4u.info","email60.com","emailacc.com","emailaccount.com","emailaddresses.com","emailage.ga","emailage.gq","emailasso.net","emailchoice.com","emailcorner.net","emailem.com","emailengine.net","emailengine.org","emailer.hubspot.com","emailforyou.net","emailgaul.com","emailgo.de","emailgroups.net","emailias.com","emailinfive.com","emailit.com","emaillime.com","emailmiser.com","emailoregon.com","emailpinoy.com","emailplanet.com","emailplus.org","emailproxsy.com","emails.ga","emails.incisivemedia.com","emails.ru","emailsensei.com","emailservice.com","emailsydney.com","emailtemporanea.com","emailtemporanea.net","emailtemporar.ro","emailtemporario.com.br","emailthe.net","emailtmp.com","emailto.de","emailuser.net","emailwarden.com","emailx.at.hm","emailx.net","emailxfer.com","emailz.ga","emailz.gq","emale.ru","ematic.com","embarqmail.com","emeil.in","emeil.ir","emil.com","eml.cc","eml.pp.ua","empereur.com","emptymail.com","emumail.com","emz.net","end-war.com","enel.net","enelpunto.net","engineer.com","england.com","england.edu","englandmail.com","epage.ru","epatra.com","ephemail.net","epiqmail.com","epix.net","epomail.com","epost.de","eposta.hu","eprompter.com","eqqu.com","eramail.co.za","eresmas.com","eriga.lv","ero-tube.org","eshche.net","esmailweb.net","estranet.it","ethos.st","etoast.com","etrademail.com","etranquil.com","etranquil.net","eudoramail.com","europamel.net","europe.com","europemail.com","euroseek.com","eurosport.com","evafan.com","evertonfans.com","every1.net","everyday.com.kh","everymail.net","everyone.net","everytg.ml","evopo.com","examnotes.net","excite.co.jp","excite.co.uk","excite.com","excite.it","execs.com","execs2k.com","executivemail.co.za","exemail.com.au","exg6.exghost.com","explodemail.com","express.net.ua","expressasia.com","extenda.net","extended.com","extremail.ru","eyepaste.com","eyou.com","ezagenda.com","ezcybersearch.com","ezmail.egine.com","ezmail.ru","ezrs.com","f-m.fm","f1fans.net","facebook-email.ga","facebook.com","facebookmail.com","facebookmail.gq","fadrasha.net","fadrasha.org","fahr-zur-hoelle.org","fake-email.pp.ua","fake-mail.cf","fake-mail.ga","fake-mail.ml","fakeinbox.com","fakeinformation.com","fakemailz.com","falseaddress.com","fan.com","fan.theboys.com","fannclub.com","fansonlymail.com","fansworldwide.de","fantasticmail.com","fantasymail.de","farang.net","farifluset.mailexpire.com","faroweb.com","fast-email.com","fast-mail.fr","fast-mail.org","fastacura.com","fastchevy.com","fastchrysler.com","fastem.com","fastemail.us","fastemailer.com","fastemailextractor.net","fastermail.com","fastest.cc","fastimap.com","fastkawasaki.com","fastmail.ca","fastmail.cn","fastmail.co.uk","fastmail.com","fastmail.com.au","fastmail.es","fastmail.fm","fastmail.gr","fastmail.im","fastmail.in","fastmail.jp","fastmail.mx","fastmail.net","fastmail.nl","fastmail.se","fastmail.to","fastmail.tw","fastmail.us","fastmailbox.net","fastmazda.com","fastmessaging.com","fastmitsubishi.com","fastnissan.com","fastservice.com","fastsubaru.com","fastsuzuki.com","fasttoyota.com","fastyamaha.com","fatcock.net","fatflap.com","fathersrightsne.org","fatyachts.com","fax.ru","fbi-agent.com","fbi.hu","fdfdsfds.com","fea.st","federalcontractors.com","feinripptraeger.de","felicity.com","felicitymail.com","female.ru","femenino.com","fepg.net","fetchmail.co.uk","fetchmail.com","fettabernett.de","feyenoorder.com","ffanet.com","fiberia.com","fibertel.com.ar","ficken.de","fificorp.com","fificorp.net","fightallspam.com","filipinolinks.com","filzmail.com","financefan.net","financemail.net","financier.com","findfo.com","findhere.com","findmail.com","findmemail.com","finebody.com","fineemail.com","finfin.com","finklfan.com","fire-brigade.com","fireman.net","fishburne.org","fishfuse.com","fivemail.de","fixmail.tk","fizmail.com","flashbox.5july.org","flashemail.com","flashmail.com","flashmail.net","fleckens.hu","flipcode.com","floridaemail.net","flytecrew.com","fmail.co.uk","fmailbox.com","fmgirl.com","fmguy.com","fnbmail.co.za","fnmail.com","folkfan.com","foodmail.com","footard.com","football.theboys.com","footballmail.com","foothills.net","for-president.com","force9.co.uk","forfree.at","forgetmail.com","fornow.eu","forpresident.com","fortuncity.com","fortunecity.com","forum.dk","fossefans.com","foxmail.com","fr33mail.info","francefans.com","francemel.fr","frapmail.com","free-email.ga","free-online.net","free-org.com","free.com.pe","free.fr","freeaccess.nl","freeaccount.com","freeandsingle.com","freebox.com","freedom.usa.com","freedomlover.com","freefanmail.com","freegates.be","freeghana.com","freelance-france.eu","freeler.nl","freemail.bozz.com","freemail.c3.hu","freemail.com.au","freemail.com.pk","freemail.de","freemail.et","freemail.gr","freemail.hu","freemail.it","freemail.lt","freemail.ms","freemail.nl","freemail.org.mk","freemail.ru","freemails.ga","freemeil.gq","freenet.de","freenet.kg","freeola.com","freeola.net","freeproblem.com","freesbee.fr","freeserve.co.uk","freeservers.com","freestamp.com","freestart.hu","freesurf.fr","freesurf.nl","freeuk.com","freeuk.net","freeukisp.co.uk","freeweb.org","freewebemail.com","freeyellow.com","freezone.co.uk","fresnomail.com","freudenkinder.de","freundin.ru","friction.net","friendlydevices.com","friendlymail.co.uk","friends-cafe.com","friendsfan.com","from-africa.com","from-america.com","from-argentina.com","from-asia.com","from-australia.com","from-belgium.com","from-brazil.com","from-canada.com","from-china.net","from-england.com","from-europe.com","from-france.net","from-germany.net","from-holland.com","from-israel.com","from-italy.net","from-japan.net","from-korea.com","from-mexico.com","from-outerspace.com","from-russia.com","from-spain.net","fromalabama.com","fromalaska.com","fromarizona.com","fromarkansas.com","fromcalifornia.com","fromcolorado.com","fromconnecticut.com","fromdelaware.com","fromflorida.net","fromgeorgia.com","fromhawaii.net","fromidaho.com","fromillinois.com","fromindiana.com","frominter.net","fromiowa.com","fromjupiter.com","fromkansas.com","fromkentucky.com","fromlouisiana.com","frommaine.net","frommaryland.com","frommassachusetts.com","frommiami.com","frommichigan.com","fromminnesota.com","frommississippi.com","frommissouri.com","frommontana.com","fromnebraska.com","fromnevada.com","fromnewhampshire.com","fromnewjersey.com","fromnewmexico.com","fromnewyork.net","fromnorthcarolina.com","fromnorthdakota.com","fromohio.com","fromoklahoma.com","fromoregon.net","frompennsylvania.com","fromrhodeisland.com","fromru.com","fromru.ru","fromsouthcarolina.com","fromsouthdakota.com","fromtennessee.com","fromtexas.com","fromthestates.com","fromutah.com","fromvermont.com","fromvirginia.com","fromwashington.com","fromwashingtondc.com","fromwestvirginia.com","fromwisconsin.com","fromwyoming.com","front.ru","frontier.com","frontiernet.net","frostbyte.uk.net","fsmail.net","ftc-i.net","ftml.net","fuckingduh.com","fudgerub.com","fullmail.com","funiran.com","funkfan.com","funky4.com","fuorissimo.com","furnitureprovider.com","fuse.net","fusemail.com","fut.es","fux0ringduh.com","fwnb.com","fxsmails.com","fyii.de","galamb.net","galaxy5.com","galaxyhit.com","gamebox.com","gamebox.net","gamegeek.com","games.com","gamespotmail.com","gamil.com","gamil.com.au","gamno.config.work","garbage.com","gardener.com","garliclife.com","gatwickemail.com","gawab.com","gay.com","gaybrighton.co.uk","gaza.net","gazeta.pl","gazibooks.com","gci.net","gdi.net","gee-wiz.com","geecities.com","geek.com","geek.hu","geeklife.com","gehensiemirnichtaufdensack.de","gelitik.in","gencmail.com","general-hospital.com","gentlemansclub.de","genxemail.com","geocities.com","geography.net","geologist.com","geopia.com","germanymail.com","get.pp.ua","get1mail.com","get2mail.fr","getairmail.cf","getairmail.com","getairmail.ga","getairmail.gq","getmails.eu","getonemail.com","getonemail.net","gfxartist.ru","gh2000.com","ghanamail.com","ghostmail.com","ghosttexter.de","giantmail.de","giantsfan.com","giga4u.de","gigileung.org","girl4god.com","girlsundertheinfluence.com","gishpuppy.com","givepeaceachance.com","glay.org","glendale.net","globalfree.it","globalpagan.com","globalsite.com.br","globetrotter.net","globo.com","globomail.com","gmail.co.za","gmail.com","gmail.com.au","gmail.com.br","gmail.ru","gmial.com","gmx.at","gmx.ch","gmx.co.uk","gmx.com","gmx.de","gmx.fr","gmx.li","gmx.net","gmx.us","gnwmail.com","go.com","go.ro","go.ru","go2.com.py","go2net.com","go4.it","gobrainstorm.net","gocollege.com","gocubs.com","godmail.dk","goemailgo.com","gofree.co.uk","gol.com","goldenmail.ru","goldmail.ru","goldtoolbox.com","golfemail.com","golfilla.info","golfmail.be","gonavy.net","gonuts4free.com","goodnewsmail.com","goodstick.com","google.com","googlegroups.com","googlemail.com","goosemoose.com","goplay.com","gorillaswithdirtyarmpits.com","gorontalo.net","gospelfan.com","gothere.uk.com","gotmail.com","gotmail.net","gotmail.org","gotomy.com","gotti.otherinbox.com","govolsfan.com","gportal.hu","grabmail.com","graduate.org","graffiti.net","gramszu.net","grandmamail.com","grandmasmail.com","graphic-designer.com","grapplers.com","gratisweb.com","great-host.in","greenmail.net","greensloth.com","groupmail.com","grr.la","grungecafe.com","gsrv.co.uk","gtemail.net","gtmc.net","gua.net","guerillamail.biz","guerillamail.com","guerrillamail.biz","guerrillamail.com","guerrillamail.de","guerrillamail.info","guerrillamail.net","guerrillamail.org","guerrillamailblock.com","guessmail.com","guju.net","gurlmail.com","gustr.com","guy.com","guy2.com","guyanafriends.com","gwhsgeckos.com","gyorsposta.com","gyorsposta.hu","h-mail.us","hab-verschlafen.de","hablas.com","habmalnefrage.de","hacccc.com","hackermail.com","hackermail.net","hailmail.net","hairdresser.com","hairdresser.net","haltospam.com","hamptonroads.com","handbag.com","handleit.com","hang-ten.com","hangglidemail.com","hanmail.net","happemail.com","happycounsel.com","happypuppy.com","harakirimail.com","haramamba.ru","hardcorefreak.com","hardyoungbabes.com","hartbot.de","hat-geld.de","hatespam.org","hawaii.rr.com","hawaiiantel.net","headbone.com","healthemail.net","heartthrob.com","heavynoize.net","heerschap.com","heesun.net","hehe.com","hello.hu","hello.net.au","hello.to","hellokitty.com","helter-skelter.com","hempseed.com","herediano.com","heremail.com","herono1.com","herp.in","herr-der-mails.de","hetnet.nl","hewgen.ru","hey.to","hhdevel.com","hideakifan.com","hidemail.de","hidzz.com","highmilton.com","highquality.com","highveldmail.co.za","hilarious.com","hinduhome.com","hingis.org","hiphopfan.com","hispavista.com","hitmail.com","hitmanrecords.com","hitthe.net","hkg.net","hkstarphoto.com","hmamail.com","hochsitze.com","hockeymail.com","hollywoodkids.com","home-email.com","home.de","home.nl","home.no.net","home.ro","home.se","homeart.com","homelocator.com","homemail.com","homenetmail.com","homeonthethrone.com","homestead.com","homeworkcentral.com","honduras.com","hongkong.com","hookup.net","hoopsmail.com","hopemail.biz","horrormail.com","host-it.com.sg","hot-mail.gq","hot-shop.com","hot-shot.com","hot.ee","hotbot.com","hotbox.ru","hotbrev.com","hotcoolmail.com","hotepmail.com","hotfire.net","hotletter.com","hotlinemail.com","hotmail.be","hotmail.ca","hotmail.ch","hotmail.co","hotmail.co.il","hotmail.co.jp","hotmail.co.nz","hotmail.co.uk","hotmail.co.za","hotmail.com","hotmail.com.ar","hotmail.com.au","hotmail.com.br","hotmail.com.mx","hotmail.com.tr","hotmail.de","hotmail.es","hotmail.fi","hotmail.fr","hotmail.it","hotmail.kg","hotmail.kz","hotmail.my","hotmail.nl","hotmail.ro","hotmail.roor","hotmail.ru","hotpop.com","hotpop3.com","hotvoice.com","housefan.com","housefancom","housemail.com","hsuchi.net","html.tou.com","hu2.ru","hughes.net","hulapla.de","humanoid.net","humanux.com","humn.ws.gy","humour.com","hunsa.com","hurting.com","hush.com","hushmail.com","hypernautica.com","i-connect.com","i-france.com","i-love-cats.com","i-mail.com.au","i-mailbox.net","i-p.com","i.am","i.am.to","i.amhey.to","i.ua","i12.com","i2828.com","i2pmail.org","iam4msu.com","iamawoman.com","iamfinallyonline.com","iamwaiting.com","iamwasted.com","iamyours.com","icestorm.com","ich-bin-verrueckt-nach-dir.de","ich-will-net.de","icloud.com","icmsconsultants.com","icq.com","icqmail.com","icrazy.com","icu.md","id-base.com","id.ru","ididitmyway.com","idigjesus.com","idirect.com","ieatspam.eu","ieatspam.info","ieh-mail.de","iespana.es","ifoward.com","ig.com.br","ignazio.it","ignmail.com","ihateclowns.com","ihateyoualot.info","iheartspam.org","iinet.net.au","ijustdontcare.com","ikbenspamvrij.nl","ilkposta.com","ilovechocolate.com","ilovegiraffes.net","ilovejesus.com","ilovelionking.com","ilovepokemonmail.com","ilovethemovies.com","ilovetocollect.net","ilse.nl","imaginemail.com","imail.org","imail.ru","imailbox.com","imails.info","imap-mail.com","imap.cc","imapmail.org","imel.org","imgof.com","imgv.de","immo-gerance.info","imneverwrong.com","imposter.co.uk","imstations.com","imstressed.com","imtoosexy.com","in-box.net","in2jesus.com","iname.com","inbax.tk","inbound.plus","inbox.com","inbox.lv","inbox.net","inbox.ru","inbox.si","inboxalias.com","inboxclean.com","inboxclean.org","incamail.com","includingarabia.com","incredimail.com","indeedemail.com","index.ua","indexa.fr","india.com","indiatimes.com","indo-mail.com","indocities.com","indomail.com","indosat.net.id","indus.ru","indyracers.com","inerted.com","inet.com","inet.net.au","info-media.de","info-radio.ml","info.com","info66.com","infoapex.com","infocom.zp.ua","infohq.com","infomail.es","infomart.or.jp","informaticos.com","infospacemail.com","infovia.com.ar","inicia.es","inmail.sk","inmail24.com","inmano.com","inmynetwork.tk","innocent.com","inonesearch.com","inorbit.com","inoutbox.com","insidebaltimore.net","insight.rr.com","inspectorjavert.com","instant-mail.de","instantemailaddress.com","instantmail.fr","instruction.com","instructor.net","insurer.com","interburp.com","interfree.it","interia.pl","interlap.com.ar","intermail.co.il","internet-club.com","internet-e-mail.com","internet-mail.org","internet-police.com","internetbiz.com","internetdrive.com","internetegypt.com","internetemails.net","internetmailing.net","internode.on.net","invalid.com","investormail.com","inwind.it","iobox.com","iobox.fi","iol.it","iol.pt","iowaemail.com","ip3.com","ip4.pp.ua","ip6.li","ip6.pp.ua","ipdeer.com","ipex.ru","ipoo.org","iportalexpress.com","iprimus.com.au","iqemail.com","irangate.net","iraqmail.com","ireland.com","irelandmail.com","irish2me.com","irj.hu","iroid.com","iscooler.com","isellcars.com","iservejesus.com","islamonline.net","islandemail.net","isleuthmail.com","ismart.net","isonfire.com","isp9.net","israelmail.com","ist-allein.info","ist-einmalig.de","ist-ganz-allein.de","ist-willig.de","italymail.com","itelefonica.com.br","itloox.com","itmom.com","ivebeenframed.com","ivillage.com","iwan-fals.com","iwi.net","iwmail.com","iwon.com","izadpanah.com","jabble.com","jahoopa.com","jakuza.hu","japan.com","jaydemail.com","jazzandjava.com","jazzfan.com","jazzgame.com","je-recycle.info","jeanvaljean.com","jerusalemmail.com","jesusanswers.com","jet-renovation.fr","jetable.com","jetable.de","jetable.fr.nf","jetable.net","jetable.org","jetable.pp.ua","jetemail.net","jewishmail.com","jfkislanders.com","jingjo.net","jippii.fi","jmail.co.za","jnxjn.com","job4u.com","jobbikszimpatizans.hu","joelonsoftware.com","joinme.com","jojomail.com","jokes.com","jordanmail.com","journalist.com","jourrapide.com","jovem.te.pt","joymail.com","jpopmail.com","jsrsolutions.com","jubiimail.dk","jump.com","jumpy.it","juniormail.com","junk1e.com","junkmail.com","junkmail.gq","juno.com","justemail.net","justicemail.com","justmail.de","justmailz.com","justmarriedmail.com","jwspamspy","k.ro","kaazoo.com","kabissa.org","kaduku.net","kaffeeschluerfer.com","kaffeeschluerfer.de","kaixo.com","kalpoint.com","kansascity.com","kapoorweb.com","karachian.com","karachioye.com","karbasi.com","kasmail.com","kaspop.com","katamail.com","kayafmmail.co.za","kbjrmail.com","kcks.com","kebi.com","keftamail.com","keg-party.com","keinpardon.de","keko.com.ar","kellychen.com","keptprivate.com","keromail.com","kewpee.com","keyemail.com","kgb.hu","khosropour.com","kichimail.com","kickassmail.com","killamail.com","killergreenmail.com","killermail.com","killmail.com","killmail.net","kimo.com","kimsdisk.com","kinglibrary.net","kinki-kids.com","kismail.ru","kissfans.com","kitemail.com","kittymail.com","kitznet.at","kiwibox.com","kiwitown.com","klassmaster.com","klassmaster.net","klzlk.com","km.ru","kmail.com.au","knol-power.nl","koko.com","kolumbus.fi","kommespaeter.de","konkovo.net","konsul.ru","konx.com","korea.com","koreamail.com","kosino.net","koszmail.pl","kozmail.com","kpnmail.nl","kreditor.ru","krim.ws","krongthip.com","krovatka.net","krunis.com","ksanmail.com","ksee24mail.com","kube93mail.com","kukamail.com","kulturbetrieb.info","kumarweb.com","kurzepost.de","kuwait-mail.com","kuzminki.net","kyokodate.com","kyokofukada.net","l33r.eu","la.com","labetteraverouge.at","lackmail.ru","ladyfire.com","ladymail.cz","lagerlouts.com","lags.us","lahoreoye.com","lakmail.com","lamer.hu","land.ru","langoo.com","lankamail.com","laoeq.com","laposte.net","lass-es-geschehen.de","last-chance.pro","lastmail.co","latemodels.com","latinmail.com","latino.com","lavabit.com","lavache.com","law.com","lawlita.com","lawyer.com","lazyinbox.com","learn2compute.net","lebanonatlas.com","leeching.net","leehom.net","lefortovo.net","legalactions.com","legalrc.loan","legislator.com","legistrator.com","lenta.ru","leonlai.net","letsgomets.net","letterbox.com","letterboxes.org","letthemeatspam.com","levele.com","levele.hu","lex.bg","lexis-nexis-mail.com","lhsdv.com","lianozovo.net","libero.it","liberomail.com","lick101.com","liebt-dich.info","lifebyfood.com","link2mail.net","linkmaster.com","linktrader.com","linuxfreemail.com","linuxmail.org","lionsfan.com.au","liontrucks.com","liquidinformation.net","lissamail.com","list.ru","listomail.com","litedrop.com","literaturelover.com","littleapple.com","littleblueroom.com","live.at","live.be","live.ca","live.cl","live.cn","live.co.uk","live.co.za","live.com","live.com.ar","live.com.au","live.com.mx","live.com.my","live.com.pt","live.com.sg","live.de","live.dk","live.fr","live.hk","live.ie","live.in","live.it","live.jp","live.nl","live.no","live.ru","live.se","liveradio.tk","liverpoolfans.com","ljiljan.com","llandudno.com","llangollen.com","lmxmail.sk","lobbyist.com","localbar.com","localgenius.com","locos.com","login-email.ga","loh.pp.ua","lol.ovpn.to","lolfreak.net","lolito.tk","lolnetwork.net","london.com","loobie.com","looksmart.co.uk","looksmart.com","looksmart.com.au","lookugly.com","lopezclub.com","lortemail.dk","louiskoo.com","lov.ru","love.com","love.cz","loveable.com","lovecat.com","lovefall.ml","lovefootball.com","loveforlostcats.com","lovelygirl.net","lovemail.com","lover-boy.com","lovergirl.com","lovesea.gq","lovethebroncos.com","lovethecowboys.com","lovetocook.net","lovetohike.com","loveyouforever.de","lovingjesus.com","lowandslow.com","lr7.us","lr78.com","lroid.com","lubovnik.ru","lukop.dk","luso.pt","luukku.com","luv2.us","luvrhino.com","lvie.com.sg","lvwebmail.com","lycos.co.uk","lycos.com","lycos.es","lycos.it","lycos.ne.jp","lycos.ru","lycosemail.com","lycosmail.com","m-a-i-l.com","m-hmail.com","m21.cc","m4.org","m4ilweb.info","mac.com","macbox.com","macbox.ru","macfreak.com","machinecandy.com","macmail.com","mad.scientist.com","madcrazy.com","madcreations.com","madonnafan.com","madrid.com","maennerversteherin.com","maennerversteherin.de","maffia.hu","magicmail.co.za","mahmoodweb.com","mail-awu.de","mail-box.cz","mail-center.com","mail-central.com","mail-easy.fr","mail-filter.com","mail-me.com","mail-page.com","mail-temporaire.fr","mail-tester.com","mail.austria.com","mail.az","mail.be","mail.bg","mail.bulgaria.com","mail.by","mail.byte.it","mail.co.za","mail.com","mail.com.tr","mail.ee","mail.entrepeneurmag.com","mail.freetown.com","mail.gr","mail.hitthebeach.com","mail.htl22.at","mail.kmsp.com","mail.md","mail.mezimages.net","mail.misterpinball.de","mail.nu","mail.org.uk","mail.pf","mail.pharmacy.com","mail.pt","mail.r-o-o-t.com","mail.ru","mail.salu.net","mail.sisna.com","mail.spaceports.com","mail.svenz.eu","mail.theboys.com","mail.usa.com","mail.vasarhely.hu","mail.vu","mail.wtf","mail.zp.ua","mail114.net","mail15.com","mail1a.de","mail1st.com","mail2007.com","mail21.cc","mail2aaron.com","mail2abby.com","mail2abc.com","mail2actor.com","mail2admiral.com","mail2adorable.com","mail2adoration.com","mail2adore.com","mail2adventure.com","mail2aeolus.com","mail2aether.com","mail2affection.com","mail2afghanistan.com","mail2africa.com","mail2agent.com","mail2aha.com","mail2ahoy.com","mail2aim.com","mail2air.com","mail2airbag.com","mail2airforce.com","mail2airport.com","mail2alabama.com","mail2alan.com","mail2alaska.com","mail2albania.com","mail2alcoholic.com","mail2alec.com","mail2alexa.com","mail2algeria.com","mail2alicia.com","mail2alien.com","mail2allan.com","mail2allen.com","mail2allison.com","mail2alpha.com","mail2alyssa.com","mail2amanda.com","mail2amazing.com","mail2amber.com","mail2america.com","mail2american.com","mail2andorra.com","mail2andrea.com","mail2andy.com","mail2anesthesiologist.com","mail2angela.com","mail2angola.com","mail2ann.com","mail2anna.com","mail2anne.com","mail2anthony.com","mail2anything.com","mail2aphrodite.com","mail2apollo.com","mail2april.com","mail2aquarius.com","mail2arabia.com","mail2arabic.com","mail2architect.com","mail2ares.com","mail2argentina.com","mail2aries.com","mail2arizona.com","mail2arkansas.com","mail2armenia.com","mail2army.com","mail2arnold.com","mail2art.com","mail2artemus.com","mail2arthur.com","mail2artist.com","mail2ashley.com","mail2ask.com","mail2astronomer.com","mail2athena.com","mail2athlete.com","mail2atlas.com","mail2atom.com","mail2attitude.com","mail2auction.com","mail2aunt.com","mail2australia.com","mail2austria.com","mail2azerbaijan.com","mail2baby.com","mail2bahamas.com","mail2bahrain.com","mail2ballerina.com","mail2ballplayer.com","mail2band.com","mail2bangladesh.com","mail2bank.com","mail2banker.com","mail2bankrupt.com","mail2baptist.com","mail2bar.com","mail2barbados.com","mail2barbara.com","mail2barter.com","mail2basketball.com","mail2batter.com","mail2beach.com","mail2beast.com","mail2beatles.com","mail2beauty.com","mail2becky.com","mail2beijing.com","mail2belgium.com","mail2belize.com","mail2ben.com","mail2bernard.com","mail2beth.com","mail2betty.com","mail2beverly.com","mail2beyond.com","mail2biker.com","mail2bill.com","mail2billionaire.com","mail2billy.com","mail2bio.com","mail2biologist.com","mail2black.com","mail2blackbelt.com","mail2blake.com","mail2blind.com","mail2blonde.com","mail2blues.com","mail2bob.com","mail2bobby.com","mail2bolivia.com","mail2bombay.com","mail2bonn.com","mail2bookmark.com","mail2boreas.com","mail2bosnia.com","mail2boston.com","mail2botswana.com","mail2bradley.com","mail2brazil.com","mail2breakfast.com","mail2brian.com","mail2bride.com","mail2brittany.com","mail2broker.com","mail2brook.com","mail2bruce.com","mail2brunei.com","mail2brunette.com","mail2brussels.com","mail2bryan.com","mail2bug.com","mail2bulgaria.com","mail2business.com","mail2buy.com","mail2ca.com","mail2california.com","mail2calvin.com","mail2cambodia.com","mail2cameroon.com","mail2canada.com","mail2cancer.com","mail2capeverde.com","mail2capricorn.com","mail2cardinal.com","mail2cardiologist.com","mail2care.com","mail2caroline.com","mail2carolyn.com","mail2casey.com","mail2cat.com","mail2caterer.com","mail2cathy.com","mail2catlover.com","mail2catwalk.com","mail2cell.com","mail2chad.com","mail2champaign.com","mail2charles.com","mail2chef.com","mail2chemist.com","mail2cherry.com","mail2chicago.com","mail2chile.com","mail2china.com","mail2chinese.com","mail2chocolate.com","mail2christian.com","mail2christie.com","mail2christmas.com","mail2christy.com","mail2chuck.com","mail2cindy.com","mail2clark.com","mail2classifieds.com","mail2claude.com","mail2cliff.com","mail2clinic.com","mail2clint.com","mail2close.com","mail2club.com","mail2coach.com","mail2coastguard.com","mail2colin.com","mail2college.com","mail2colombia.com","mail2color.com","mail2colorado.com","mail2columbia.com","mail2comedian.com","mail2composer.com","mail2computer.com","mail2computers.com","mail2concert.com","mail2congo.com","mail2connect.com","mail2connecticut.com","mail2consultant.com","mail2convict.com","mail2cook.com","mail2cool.com","mail2cory.com","mail2costarica.com","mail2country.com","mail2courtney.com","mail2cowboy.com","mail2cowgirl.com","mail2craig.com","mail2crave.com","mail2crazy.com","mail2create.com","mail2croatia.com","mail2cry.com","mail2crystal.com","mail2cuba.com","mail2culture.com","mail2curt.com","mail2customs.com","mail2cute.com","mail2cutey.com","mail2cynthia.com","mail2cyprus.com","mail2czechrepublic.com","mail2dad.com","mail2dale.com","mail2dallas.com","mail2dan.com","mail2dana.com","mail2dance.com","mail2dancer.com","mail2danielle.com","mail2danny.com","mail2darlene.com","mail2darling.com","mail2darren.com","mail2daughter.com","mail2dave.com","mail2dawn.com","mail2dc.com","mail2dealer.com","mail2deanna.com","mail2dearest.com","mail2debbie.com","mail2debby.com","mail2deer.com","mail2delaware.com","mail2delicious.com","mail2demeter.com","mail2democrat.com","mail2denise.com","mail2denmark.com","mail2dennis.com","mail2dentist.com","mail2derek.com","mail2desert.com","mail2devoted.com","mail2devotion.com","mail2diamond.com","mail2diana.com","mail2diane.com","mail2diehard.com","mail2dilemma.com","mail2dillon.com","mail2dinner.com","mail2dinosaur.com","mail2dionysos.com","mail2diplomat.com","mail2director.com","mail2dirk.com","mail2disco.com","mail2dive.com","mail2diver.com","mail2divorced.com","mail2djibouti.com","mail2doctor.com","mail2doglover.com","mail2dominic.com","mail2dominica.com","mail2dominicanrepublic.com","mail2don.com","mail2donald.com","mail2donna.com","mail2doris.com","mail2dorothy.com","mail2doug.com","mail2dough.com","mail2douglas.com","mail2dow.com","mail2downtown.com","mail2dream.com","mail2dreamer.com","mail2dude.com","mail2dustin.com","mail2dyke.com","mail2dylan.com","mail2earl.com","mail2earth.com","mail2eastend.com","mail2eat.com","mail2economist.com","mail2ecuador.com","mail2eddie.com","mail2edgar.com","mail2edwin.com","mail2egypt.com","mail2electron.com","mail2eli.com","mail2elizabeth.com","mail2ellen.com","mail2elliot.com","mail2elsalvador.com","mail2elvis.com","mail2emergency.com","mail2emily.com","mail2engineer.com","mail2english.com","mail2environmentalist.com","mail2eos.com","mail2eric.com","mail2erica.com","mail2erin.com","mail2erinyes.com","mail2eris.com","mail2eritrea.com","mail2ernie.com","mail2eros.com","mail2estonia.com","mail2ethan.com","mail2ethiopia.com","mail2eu.com","mail2europe.com","mail2eurus.com","mail2eva.com","mail2evan.com","mail2evelyn.com","mail2everything.com","mail2exciting.com","mail2expert.com","mail2fairy.com","mail2faith.com","mail2fanatic.com","mail2fancy.com","mail2fantasy.com","mail2farm.com","mail2farmer.com","mail2fashion.com","mail2fat.com","mail2feeling.com","mail2female.com","mail2fever.com","mail2fighter.com","mail2fiji.com","mail2filmfestival.com","mail2films.com","mail2finance.com","mail2finland.com","mail2fireman.com","mail2firm.com","mail2fisherman.com","mail2flexible.com","mail2florence.com","mail2florida.com","mail2floyd.com","mail2fly.com","mail2fond.com","mail2fondness.com","mail2football.com","mail2footballfan.com","mail2found.com","mail2france.com","mail2frank.com","mail2frankfurt.com","mail2franklin.com","mail2fred.com","mail2freddie.com","mail2free.com","mail2freedom.com","mail2french.com","mail2freudian.com","mail2friendship.com","mail2from.com","mail2fun.com","mail2gabon.com","mail2gabriel.com","mail2gail.com","mail2galaxy.com","mail2gambia.com","mail2games.com","mail2gary.com","mail2gavin.com","mail2gemini.com","mail2gene.com","mail2genes.com","mail2geneva.com","mail2george.com","mail2georgia.com","mail2gerald.com","mail2german.com","mail2germany.com","mail2ghana.com","mail2gilbert.com","mail2gina.com","mail2girl.com","mail2glen.com","mail2gloria.com","mail2goddess.com","mail2gold.com","mail2golfclub.com","mail2golfer.com","mail2gordon.com","mail2government.com","mail2grab.com","mail2grace.com","mail2graham.com","mail2grandma.com","mail2grandpa.com","mail2grant.com","mail2greece.com","mail2green.com","mail2greg.com","mail2grenada.com","mail2gsm.com","mail2guard.com","mail2guatemala.com","mail2guy.com","mail2hades.com","mail2haiti.com","mail2hal.com","mail2handhelds.com","mail2hank.com","mail2hannah.com","mail2harold.com","mail2harry.com","mail2hawaii.com","mail2headhunter.com","mail2heal.com","mail2heather.com","mail2heaven.com","mail2hebe.com","mail2hecate.com","mail2heidi.com","mail2helen.com","mail2hell.com","mail2help.com","mail2helpdesk.com","mail2henry.com","mail2hephaestus.com","mail2hera.com","mail2hercules.com","mail2herman.com","mail2hermes.com","mail2hespera.com","mail2hestia.com","mail2highschool.com","mail2hindu.com","mail2hip.com","mail2hiphop.com","mail2holland.com","mail2holly.com","mail2hollywood.com","mail2homer.com","mail2honduras.com","mail2honey.com","mail2hongkong.com","mail2hope.com","mail2horse.com","mail2hot.com","mail2hotel.com","mail2houston.com","mail2howard.com","mail2hugh.com","mail2human.com","mail2hungary.com","mail2hungry.com","mail2hygeia.com","mail2hyperspace.com","mail2hypnos.com","mail2ian.com","mail2ice-cream.com","mail2iceland.com","mail2idaho.com","mail2idontknow.com","mail2illinois.com","mail2imam.com","mail2in.com","mail2india.com","mail2indian.com","mail2indiana.com","mail2indonesia.com","mail2infinity.com","mail2intense.com","mail2iowa.com","mail2iran.com","mail2iraq.com","mail2ireland.com","mail2irene.com","mail2iris.com","mail2irresistible.com","mail2irving.com","mail2irwin.com","mail2isaac.com","mail2israel.com","mail2italian.com","mail2italy.com","mail2jackie.com","mail2jacob.com","mail2jail.com","mail2jaime.com","mail2jake.com","mail2jamaica.com","mail2james.com","mail2jamie.com","mail2jan.com","mail2jane.com","mail2janet.com","mail2janice.com","mail2japan.com","mail2japanese.com","mail2jasmine.com","mail2jason.com","mail2java.com","mail2jay.com","mail2jazz.com","mail2jed.com","mail2jeffrey.com","mail2jennifer.com","mail2jenny.com","mail2jeremy.com","mail2jerry.com","mail2jessica.com","mail2jessie.com","mail2jesus.com","mail2jew.com","mail2jeweler.com","mail2jim.com","mail2jimmy.com","mail2joan.com","mail2joann.com","mail2joanna.com","mail2jody.com","mail2joe.com","mail2joel.com","mail2joey.com","mail2john.com","mail2join.com","mail2jon.com","mail2jonathan.com","mail2jones.com","mail2jordan.com","mail2joseph.com","mail2josh.com","mail2joy.com","mail2juan.com","mail2judge.com","mail2judy.com","mail2juggler.com","mail2julian.com","mail2julie.com","mail2jumbo.com","mail2junk.com","mail2justin.com","mail2justme.com","mail2k.ru","mail2kansas.com","mail2karate.com","mail2karen.com","mail2karl.com","mail2karma.com","mail2kathleen.com","mail2kathy.com","mail2katie.com","mail2kay.com","mail2kazakhstan.com","mail2keen.com","mail2keith.com","mail2kelly.com","mail2kelsey.com","mail2ken.com","mail2kendall.com","mail2kennedy.com","mail2kenneth.com","mail2kenny.com","mail2kentucky.com","mail2kenya.com","mail2kerry.com","mail2kevin.com","mail2kim.com","mail2kimberly.com","mail2king.com","mail2kirk.com","mail2kiss.com","mail2kosher.com","mail2kristin.com","mail2kurt.com","mail2kuwait.com","mail2kyle.com","mail2kyrgyzstan.com","mail2la.com","mail2lacrosse.com","mail2lance.com","mail2lao.com","mail2larry.com","mail2latvia.com","mail2laugh.com","mail2laura.com","mail2lauren.com","mail2laurie.com","mail2lawrence.com","mail2lawyer.com","mail2lebanon.com","mail2lee.com","mail2leo.com","mail2leon.com","mail2leonard.com","mail2leone.com","mail2leslie.com","mail2letter.com","mail2liberia.com","mail2libertarian.com","mail2libra.com","mail2libya.com","mail2liechtenstein.com","mail2life.com","mail2linda.com","mail2linux.com","mail2lionel.com","mail2lipstick.com","mail2liquid.com","mail2lisa.com","mail2lithuania.com","mail2litigator.com","mail2liz.com","mail2lloyd.com","mail2lois.com","mail2lola.com","mail2london.com","mail2looking.com","mail2lori.com","mail2lost.com","mail2lou.com","mail2louis.com","mail2louisiana.com","mail2lovable.com","mail2love.com","mail2lucky.com","mail2lucy.com","mail2lunch.com","mail2lust.com","mail2luxembourg.com","mail2luxury.com","mail2lyle.com","mail2lynn.com","mail2madagascar.com","mail2madison.com","mail2madrid.com","mail2maggie.com","mail2mail4.com","mail2maine.com","mail2malawi.com","mail2malaysia.com","mail2maldives.com","mail2mali.com","mail2malta.com","mail2mambo.com","mail2man.com","mail2mandy.com","mail2manhunter.com","mail2mankind.com","mail2many.com","mail2marc.com","mail2marcia.com","mail2margaret.com","mail2margie.com","mail2marhaba.com","mail2maria.com","mail2marilyn.com","mail2marines.com","mail2mark.com","mail2marriage.com","mail2married.com","mail2marries.com","mail2mars.com","mail2marsha.com","mail2marshallislands.com","mail2martha.com","mail2martin.com","mail2marty.com","mail2marvin.com","mail2mary.com","mail2maryland.com","mail2mason.com","mail2massachusetts.com","mail2matt.com","mail2matthew.com","mail2maurice.com","mail2mauritania.com","mail2mauritius.com","mail2max.com","mail2maxwell.com","mail2maybe.com","mail2mba.com","mail2me4u.com","mail2mechanic.com","mail2medieval.com","mail2megan.com","mail2mel.com","mail2melanie.com","mail2melissa.com","mail2melody.com","mail2member.com","mail2memphis.com","mail2methodist.com","mail2mexican.com","mail2mexico.com","mail2mgz.com","mail2miami.com","mail2michael.com","mail2michelle.com","mail2michigan.com","mail2mike.com","mail2milan.com","mail2milano.com","mail2mildred.com","mail2milkyway.com","mail2millennium.com","mail2millionaire.com","mail2milton.com","mail2mime.com","mail2mindreader.com","mail2mini.com","mail2minister.com","mail2minneapolis.com","mail2minnesota.com","mail2miracle.com","mail2missionary.com","mail2mississippi.com","mail2missouri.com","mail2mitch.com","mail2model.com","mail2moldova.commail2molly.com","mail2mom.com","mail2monaco.com","mail2money.com","mail2mongolia.com","mail2monica.com","mail2montana.com","mail2monty.com","mail2moon.com","mail2morocco.com","mail2morpheus.com","mail2mors.com","mail2moscow.com","mail2moslem.com","mail2mouseketeer.com","mail2movies.com","mail2mozambique.com","mail2mp3.com","mail2mrright.com","mail2msright.com","mail2museum.com","mail2music.com","mail2musician.com","mail2muslim.com","mail2my.com","mail2myboat.com","mail2mycar.com","mail2mycell.com","mail2mygsm.com","mail2mylaptop.com","mail2mymac.com","mail2mypager.com","mail2mypalm.com","mail2mypc.com","mail2myphone.com","mail2myplane.com","mail2namibia.com","mail2nancy.com","mail2nasdaq.com","mail2nathan.com","mail2nauru.com","mail2navy.com","mail2neal.com","mail2nebraska.com","mail2ned.com","mail2neil.com","mail2nelson.com","mail2nemesis.com","mail2nepal.com","mail2netherlands.com","mail2network.com","mail2nevada.com","mail2newhampshire.com","mail2newjersey.com","mail2newmexico.com","mail2newyork.com","mail2newzealand.com","mail2nicaragua.com","mail2nick.com","mail2nicole.com","mail2niger.com","mail2nigeria.com","mail2nike.com","mail2no.com","mail2noah.com","mail2noel.com","mail2noelle.com","mail2normal.com","mail2norman.com","mail2northamerica.com","mail2northcarolina.com","mail2northdakota.com","mail2northpole.com","mail2norway.com","mail2notus.com","mail2noway.com","mail2nowhere.com","mail2nuclear.com","mail2nun.com","mail2ny.com","mail2oasis.com","mail2oceanographer.com","mail2ohio.com","mail2ok.com","mail2oklahoma.com","mail2oliver.com","mail2oman.com","mail2one.com","mail2onfire.com","mail2online.com","mail2oops.com","mail2open.com","mail2ophthalmologist.com","mail2optometrist.com","mail2oregon.com","mail2oscars.com","mail2oslo.com","mail2painter.com","mail2pakistan.com","mail2palau.com","mail2pan.com","mail2panama.com","mail2paraguay.com","mail2paralegal.com","mail2paris.com","mail2park.com","mail2parker.com","mail2party.com","mail2passion.com","mail2pat.com","mail2patricia.com","mail2patrick.com","mail2patty.com","mail2paul.com","mail2paula.com","mail2pay.com","mail2peace.com","mail2pediatrician.com","mail2peggy.com","mail2pennsylvania.com","mail2perry.com","mail2persephone.com","mail2persian.com","mail2peru.com","mail2pete.com","mail2peter.com","mail2pharmacist.com","mail2phil.com","mail2philippines.com","mail2phoenix.com","mail2phonecall.com","mail2phyllis.com","mail2pickup.com","mail2pilot.com","mail2pisces.com","mail2planet.com","mail2platinum.com","mail2plato.com","mail2pluto.com","mail2pm.com","mail2podiatrist.com","mail2poet.com","mail2poland.com","mail2policeman.com","mail2policewoman.com","mail2politician.com","mail2pop.com","mail2pope.com","mail2popular.com","mail2portugal.com","mail2poseidon.com","mail2potatohead.com","mail2power.com","mail2presbyterian.com","mail2president.com","mail2priest.com","mail2prince.com","mail2princess.com","mail2producer.com","mail2professor.com","mail2protect.com","mail2psychiatrist.com","mail2psycho.com","mail2psychologist.com","mail2qatar.com","mail2queen.com","mail2rabbi.com","mail2race.com","mail2racer.com","mail2rachel.com","mail2rage.com","mail2rainmaker.com","mail2ralph.com","mail2randy.com","mail2rap.com","mail2rare.com","mail2rave.com","mail2ray.com","mail2raymond.com","mail2realtor.com","mail2rebecca.com","mail2recruiter.com","mail2recycle.com","mail2redhead.com","mail2reed.com","mail2reggie.com","mail2register.com","mail2rent.com","mail2republican.com","mail2resort.com","mail2rex.com","mail2rhodeisland.com","mail2rich.com","mail2richard.com","mail2ricky.com","mail2ride.com","mail2riley.com","mail2rita.com","mail2rob.com","mail2robert.com","mail2roberta.com","mail2robin.com","mail2rock.com","mail2rocker.com","mail2rod.com","mail2rodney.com","mail2romania.com","mail2rome.com","mail2ron.com","mail2ronald.com","mail2ronnie.com","mail2rose.com","mail2rosie.com","mail2roy.com","mail2rss.org","mail2rudy.com","mail2rugby.com","mail2runner.com","mail2russell.com","mail2russia.com","mail2russian.com","mail2rusty.com","mail2ruth.com","mail2rwanda.com","mail2ryan.com","mail2sa.com","mail2sabrina.com","mail2safe.com","mail2sagittarius.com","mail2sail.com","mail2sailor.com","mail2sal.com","mail2salaam.com","mail2sam.com","mail2samantha.com","mail2samoa.com","mail2samurai.com","mail2sandra.com","mail2sandy.com","mail2sanfrancisco.com","mail2sanmarino.com","mail2santa.com","mail2sara.com","mail2sarah.com","mail2sat.com","mail2saturn.com","mail2saudi.com","mail2saudiarabia.com","mail2save.com","mail2savings.com","mail2school.com","mail2scientist.com","mail2scorpio.com","mail2scott.com","mail2sean.com","mail2search.com","mail2seattle.com","mail2secretagent.com","mail2senate.com","mail2senegal.com","mail2sensual.com","mail2seth.com","mail2sevenseas.com","mail2sexy.com","mail2seychelles.com","mail2shane.com","mail2sharon.com","mail2shawn.com","mail2ship.com","mail2shirley.com","mail2shoot.com","mail2shuttle.com","mail2sierraleone.com","mail2simon.com","mail2singapore.com","mail2single.com","mail2site.com","mail2skater.com","mail2skier.com","mail2sky.com","mail2sleek.com","mail2slim.com","mail2slovakia.com","mail2slovenia.com","mail2smile.com","mail2smith.com","mail2smooth.com","mail2soccer.com","mail2soccerfan.com","mail2socialist.com","mail2soldier.com","mail2somalia.com","mail2son.com","mail2song.com","mail2sos.com","mail2sound.com","mail2southafrica.com","mail2southamerica.com","mail2southcarolina.com","mail2southdakota.com","mail2southkorea.com","mail2southpole.com","mail2spain.com","mail2spanish.com","mail2spare.com","mail2spectrum.com","mail2splash.com","mail2sponsor.com","mail2sports.com","mail2srilanka.com","mail2stacy.com","mail2stan.com","mail2stanley.com","mail2star.com","mail2state.com","mail2stephanie.com","mail2steve.com","mail2steven.com","mail2stewart.com","mail2stlouis.com","mail2stock.com","mail2stockholm.com","mail2stockmarket.com","mail2storage.com","mail2store.com","mail2strong.com","mail2student.com","mail2studio.com","mail2studio54.com","mail2stuntman.com","mail2subscribe.com","mail2sudan.com","mail2superstar.com","mail2surfer.com","mail2suriname.com","mail2susan.com","mail2suzie.com","mail2swaziland.com","mail2sweden.com","mail2sweetheart.com","mail2swim.com","mail2swimmer.com","mail2swiss.com","mail2switzerland.com","mail2sydney.com","mail2sylvia.com","mail2syria.com","mail2taboo.com","mail2taiwan.com","mail2tajikistan.com","mail2tammy.com","mail2tango.com","mail2tanya.com","mail2tanzania.com","mail2tara.com","mail2taurus.com","mail2taxi.com","mail2taxidermist.com","mail2taylor.com","mail2taz.com","mail2teacher.com","mail2technician.com","mail2ted.com","mail2telephone.com","mail2teletubbie.com","mail2tenderness.com","mail2tennessee.com","mail2tennis.com","mail2tennisfan.com","mail2terri.com","mail2terry.com","mail2test.com","mail2texas.com","mail2thailand.com","mail2therapy.com","mail2think.com","mail2tickets.com","mail2tiffany.com","mail2tim.com","mail2time.com","mail2timothy.com","mail2tina.com","mail2titanic.com","mail2toby.com","mail2todd.com","mail2togo.com","mail2tom.com","mail2tommy.com","mail2tonga.com","mail2tony.com","mail2touch.com","mail2tourist.com","mail2tracey.com","mail2tracy.com","mail2tramp.com","mail2travel.com","mail2traveler.com","mail2travis.com","mail2trekkie.com","mail2trex.com","mail2triallawyer.com","mail2trick.com","mail2trillionaire.com","mail2troy.com","mail2truck.com","mail2trump.com","mail2try.com","mail2tunisia.com","mail2turbo.com","mail2turkey.com","mail2turkmenistan.com","mail2tv.com","mail2tycoon.com","mail2tyler.com","mail2u4me.com","mail2uae.com","mail2uganda.com","mail2uk.com","mail2ukraine.com","mail2uncle.com","mail2unsubscribe.com","mail2uptown.com","mail2uruguay.com","mail2usa.com","mail2utah.com","mail2uzbekistan.com","mail2v.com","mail2vacation.com","mail2valentines.com","mail2valerie.com","mail2valley.com","mail2vamoose.com","mail2vanessa.com","mail2vanuatu.com","mail2venezuela.com","mail2venous.com","mail2venus.com","mail2vermont.com","mail2vickie.com","mail2victor.com","mail2victoria.com","mail2vienna.com","mail2vietnam.com","mail2vince.com","mail2virginia.com","mail2virgo.com","mail2visionary.com","mail2vodka.com","mail2volleyball.com","mail2waiter.com","mail2wallstreet.com","mail2wally.com","mail2walter.com","mail2warren.com","mail2washington.com","mail2wave.com","mail2way.com","mail2waycool.com","mail2wayne.com","mail2webmaster.com","mail2webtop.com","mail2webtv.com","mail2weird.com","mail2wendell.com","mail2wendy.com","mail2westend.com","mail2westvirginia.com","mail2whether.com","mail2whip.com","mail2white.com","mail2whitehouse.com","mail2whitney.com","mail2why.com","mail2wilbur.com","mail2wild.com","mail2willard.com","mail2willie.com","mail2wine.com","mail2winner.com","mail2wired.com","mail2wisconsin.com","mail2woman.com","mail2wonder.com","mail2world.com","mail2worship.com","mail2wow.com","mail2www.com","mail2wyoming.com","mail2xfiles.com","mail2xox.com","mail2yachtclub.com","mail2yahalla.com","mail2yemen.com","mail2yes.com","mail2yugoslavia.com","mail2zack.com","mail2zambia.com","mail2zenith.com","mail2zephir.com","mail2zeus.com","mail2zipper.com","mail2zoo.com","mail2zoologist.com","mail2zurich.com","mail3000.com","mail333.com","mail4trash.com","mail4u.info","mail8.com","mailandftp.com","mailandnews.com","mailas.com","mailasia.com","mailbidon.com","mailbiz.biz","mailblocks.com","mailbolt.com","mailbomb.net","mailboom.com","mailbox.as","mailbox.co.za","mailbox.gr","mailbox.hu","mailbox72.biz","mailbox80.biz","mailbr.com.br","mailbucket.org","mailc.net","mailcan.com","mailcat.biz","mailcatch.com","mailcc.com","mailchoose.co","mailcity.com","mailclub.fr","mailclub.net","mailde.de","mailde.info","maildrop.cc","maildrop.gq","maildx.com","mailed.ro","maileimer.de","mailexcite.com","mailexpire.com","mailfa.tk","mailfly.com","mailforce.net","mailforspam.com","mailfree.gq","mailfreeonline.com","mailfreeway.com","mailfs.com","mailftp.com","mailgate.gr","mailgate.ru","mailgenie.net","mailguard.me","mailhaven.com","mailhood.com","mailimate.com","mailin8r.com","mailinatar.com","mailinater.com","mailinator.com","mailinator.net","mailinator.org","mailinator.us","mailinator2.com","mailinblack.com","mailincubator.com","mailingaddress.org","mailingweb.com","mailisent.com","mailismagic.com","mailite.com","mailmate.com","mailme.dk","mailme.gq","mailme.ir","mailme.lv","mailme24.com","mailmetrash.com","mailmight.com","mailmij.nl","mailmoat.com","mailms.com","mailnator.com","mailnesia.com","mailnew.com","mailnull.com","mailops.com","mailorg.org","mailoye.com","mailpanda.com","mailpick.biz","mailpokemon.com","mailpost.zzn.com","mailpride.com","mailproxsy.com","mailpuppy.com","mailquack.com","mailrock.biz","mailroom.com","mailru.com","mailsac.com","mailscrap.com","mailseal.de","mailsent.net","mailserver.ru","mailservice.ms","mailshell.com","mailshuttle.com","mailsiphon.com","mailslapping.com","mailsnare.net","mailstart.com","mailstartplus.com","mailsurf.com","mailtag.com","mailtemp.info","mailto.de","mailtome.de","mailtothis.com","mailtrash.net","mailtv.net","mailtv.tv","mailueberfall.de","mailup.net","mailwire.com","mailworks.org","mailzi.ru","mailzilla.com","mailzilla.org","makemetheking.com","maktoob.com","malayalamtelevision.net","malayalapathram.com","male.ru","maltesemail.com","mamber.net","manager.de","manager.in.th","mancity.net","manlymail.net","mantrafreenet.com","mantramail.com","mantraonline.com","manutdfans.com","manybrain.com","marchmail.com","marfino.net","margarita.ru","mariah-carey.ml.org","mariahc.com","marijuana.com","marijuana.nl","marketing.lu","marketingfanatic.com","marketweighton.com","married-not.com","marriedandlovingit.com","marry.ru","marsattack.com","martindalemail.com","martinguerre.net","mash4077.com","masrawy.com","matmail.com","mauimail.com","mauritius.com","maximumedge.com","maxleft.com","maxmail.co.uk","mayaple.ru","mbox.com.au","mbx.cc","mchsi.com","mcrmail.com","me-mail.hu","me.com","meanpeoplesuck.com","meatismurder.net","medical.net.au","medmail.com","medscape.com","meetingmall.com","mega.zik.dj","megago.com","megamail.pt","megapoint.com","mehrani.com","mehtaweb.com","meine-dateien.info","meine-diashow.de","meine-fotos.info","meine-urlaubsfotos.de","meinspamschutz.de","mekhong.com","melodymail.com","meloo.com","meltmail.com","members.student.com","menja.net","merda.flu.cc","merda.igg.biz","merda.nut.cc","merda.usa.cc","merseymail.com","mesra.net","message.hu","message.myspace.com","messagebeamer.de","messages.to","messagez.com","metacrawler.com","metalfan.com","metaping.com","metta.lk","mexicomail.com","mezimages.net","mfsa.ru","miatadriver.com","mierdamail.com","miesto.sk","mighty.co.za","migmail.net","migmail.pl","migumail.com","miho-nakayama.com","mikrotamanet.com","millionaireintraining.com","millionairemail.com","milmail.com","milmail.com15","mindless.com","mindspring.com","minermail.com","mini-mail.com","minister.com","ministry-of-silly-walks.de","mintemail.com","misery.net","misterpinball.de","mit.tc","mittalweb.com","mixmail.com","mjfrogmail.com","ml1.net","mlanime.com","mlb.bounce.ed10.net","mm.st","mmail.com","mns.ru","mo3gov.net","moakt.com","mobico.ru","mobilbatam.com","mobileninja.co.uk","mochamail.com","modemnet.net","modernenglish.com","modomail.com","mohammed.com","mohmal.com","moldova.cc","moldova.com","moldovacc.com","mom-mail.com","momslife.com","moncourrier.fr.nf","monemail.com","monemail.fr.nf","money.net","mongol.net","monmail.fr.nf","monsieurcinema.com","montevideo.com.uy","monumentmail.com","moomia.com","moonman.com","moose-mail.com","mor19.uu.gl","mortaza.com","mosaicfx.com","moscowmail.com","mosk.ru","most-wanted.com","mostlysunny.com","motorcyclefan.net","motormania.com","movemail.com","movieemail.net","movieluver.com","mox.pp.ua","mozartmail.com","mozhno.net","mp3haze.com","mp4.it","mr-potatohead.com","mrpost.com","mrspender.com","mscold.com","msgbox.com","msn.cn","msn.com","msn.nl","msx.ru","mt2009.com","mt2014.com","mt2015.com","mt2016.com","mttestdriver.com","muehlacker.tk","multiplechoices","mundomail.net","munich.com","music.com","music.com19","music.maigate.ru","musician.com","musician.org","musicscene.org","muskelshirt.de","muslim.com","muslimemail.com","muslimsonline.com","mutantweb.com","mvrht.com","my.com","my10minutemail.com","mybox.it","mycabin.com","mycampus.com","mycard.net.ua","mycity.com","mycleaninbox.net","mycool.com","mydomain.com","mydotcomaddress.com","myfairpoint.net","myfamily.com","myfastmail.com","myfunnymail.com","mygo.com","myiris.com","myjazzmail.com","mymac.ru","mymacmail.com","mymail-in.net","mymail.ro","mynamedot.com","mynet.com","mynetaddress.com","mynetstore.de","myotw.net","myownemail.com","myownfriends.com","mypacks.net","mypad.com","mypartyclip.de","mypersonalemail.com","myphantomemail.com","myplace.com","myrambler.ru","myrealbox.com","myremarq.com","mysamp.de","myself.com","myspaceinc.net","myspamless.com","mystupidjob.com","mytemp.email","mytempemail.com","mytempmail.com","mythirdage.com","mytrashmail.com","myway.com","myworldmail.com","n2.com","n2baseball.com","n2business.com","n2mail.com","n2soccer.com","n2software.com","nabc.biz","nabuma.com","nafe.com","nagarealm.com","nagpal.net","nakedgreens.com","name.com","nameplanet.com","nanaseaikawa.com","nandomail.com","naplesnews.net","naseej.com","nate.com","nativestar.net","nativeweb.net","naui.net","naver.com","navigator.lv","navy.org","naz.com","nc.rr.com","nc.ru","nchoicemail.com","neeva.net","nekto.com","nekto.net","nekto.ru","nemra1.com","nenter.com","neo.rr.com","neomailbox.com","nepwk.com","nervhq.org","nervmich.net","nervtmich.net","net-c.be","net-c.ca","net-c.cat","net-c.com","net-c.es","net-c.fr","net-c.it","net-c.lu","net-c.nl","net-c.pl","net-pager.net","net-shopping.com","net.tf","net4b.pt","net4you.at","netaddres.ru","netaddress.ru","netbounce.com","netbroadcaster.com","netby.dk","netc.eu","netc.fr","netc.it","netc.lu","netc.pl","netcenter-vn.net","netcity.ru","netcmail.com","netcourrier.com","netexecutive.com","netexpressway.com","netfirms.com","netgenie.com","netian.com","netizen.com.ar","netkushi.com","netlane.com","netlimit.com","netmail.kg","netmails.com","netmails.net","netman.ru","netmanor.com","netmongol.com","netnet.com.sg","netnoir.net","netpiper.com","netposta.net","netradiomail.com","netralink.com","netscape.net","netscapeonline.co.uk","netspace.net.au","netspeedway.com","netsquare.com","netster.com","nettaxi.com","nettemail.com","netterchef.de","netti.fi","netvigator.com","netzero.com","netzero.net","netzidiot.de","netzoola.com","neue-dateien.de","neuf.fr","neuro.md","neustreet.com","neverbox.com","newap.ru","newarbat.net","newmail.com","newmail.net","newmail.ru","newsboysmail.com","newyork.com","newyorkcity.com","nextmail.ru","nexxmail.com","nfmail.com","ngs.ru","nhmail.com","nice-4u.com","nicebush.com","nicegal.com","nicholastse.net","nicolastse.com","niepodam.pl","nightimeuk.com","nightmail.com","nightmail.ru","nikopage.com","nikulino.net","nimail.com","nincsmail.hu","ninfan.com","nirvanafan.com","nm.ru","nmail.cf","nnh.com","nnov.ru","no-spam.ws","no4ma.ru","noavar.com","noblepioneer.com","nogmailspam.info","nomail.pw","nomail.xl.cx","nomail2me.com","nomorespamemails.com","nonpartisan.com","nonspam.eu","nonspammer.de","nonstopcinema.com","norika-fujiwara.com","norikomail.com","northgates.net","nospam.ze.tc","nospam4.us","nospamfor.us","nospammail.net","nospamthanks.info","notmailinator.com","notsharingmy.info","notyouagain.com","novogireevo.net","novokosino.net","nowhere.org","nowmymail.com","ntelos.net","ntlhelp.net","ntlworld.com","ntscan.com","null.net","nullbox.info","numep.ru","nur-fuer-spam.de","nurfuerspam.de","nus.edu.sg","nuvse.com","nwldx.com","nxt.ru","ny.com","nybce.com","nybella.com","nyc.com","nycmail.com","nz11.com","nzoomail.com","o-tay.com","o2.co.uk","o2.pl","oaklandas-fan.com","oath.com","objectmail.com","obobbo.com","oceanfree.net","ochakovo.net","odaymail.com","oddpost.com","odmail.com","odnorazovoe.ru","office-dateien.de","office-email.com","officedomain.com","offroadwarrior.com","oi.com.br","oicexchange.com","oikrach.com","ok.kz","ok.net","ok.ru","okbank.com","okhuman.com","okmad.com","okmagic.com","okname.net","okuk.com","oldbuthealthy.com","oldies1041.com","oldies104mail.com","ole.com","olemail.com","oligarh.ru","olympist.net","olypmall.ru","omaninfo.com","omen.ru","ondikoi.com","onebox.com","onenet.com.ar","oneoffemail.com","oneoffmail.com","onet.com.pl","onet.eu","onet.pl","onewaymail.com","oninet.pt","onlatedotcom.info","online.de","online.ie","online.ms","online.nl","online.ru","onlinecasinogamblings.com","onlinewiz.com","onmicrosoft.com","onmilwaukee.com","onobox.com","onvillage.com","oopi.org","op.pl","opayq.com","opendiary.com","openmailbox.org","operafan.com","operamail.com","opoczta.pl","optician.com","optonline.net","optusnet.com.au","orange.fr","orange.net","orbitel.bg","ordinaryamerican.net","orgmail.net","orthodontist.net","osite.com.br","oso.com","otakumail.com","otherinbox.com","our-computer.com","our-office.com","our.st","ourbrisbane.com","ourklips.com","ournet.md","outel.com","outgun.com","outlawspam.com","outlook.at","outlook.be","outlook.cl","outlook.co.id","outlook.co.il","outlook.co.nz","outlook.co.th","outlook.com","outlook.com.au","outlook.com.br","outlook.com.gr","outlook.com.pe","outlook.com.tr","outlook.com.vn","outlook.cz","outlook.de","outlook.dk","outlook.es","outlook.fr","outlook.hu","outlook.ie","outlook.in","outlook.it","outlook.jp","outlook.kr","outlook.lv","outlook.my","outlook.nl","outlook.ph","outlook.pt","outlook.sa","outlook.sg","outlook.sk","outloook.com","over-the-rainbow.com","ovi.com","ovpn.to","owlpic.com","ownmail.net","ozbytes.net.au","ozemail.com.au","ozz.ru","pacbell.net","pacific-ocean.com","pacific-re.com","pacificwest.com","packersfan.com","pagina.de","pagons.org","paidforsurf.com","pakistanmail.com","pakistanoye.com","palestinemail.com","pancakemail.com","pandawa.com","pandora.be","paradiseemail.com","paris.com","parkjiyoon.com","parrot.com","parsmail.com","partlycloudy.com","partybombe.de","partyheld.de","partynight.at","parvazi.com","passwordmail.com","pathfindermail.com","patmail.com","patra.net","pconnections.net","pcpostal.com","pcsrock.com","pcusers.otherinbox.com","peachworld.com","pechkin.ru","pediatrician.com","pekklemail.com","pemail.net","penpen.com","peoplepc.com","peopleweb.com","pepbot.com","perfectmail.com","perovo.net","perso.be","personal.ro","personales.com","petlover.com","petml.com","petr.ru","pettypool.com","pezeshkpour.com","pfui.ru","phayze.com","phone.net","photo-impact.eu","photographer.net","phpbb.uu.gl","phreaker.net","phus8kajuspa.cu.cc","physicist.net","pianomail.com","pickupman.com","picusnet.com","piercedallover.com","pigeonportal.com","pigmail.net","pigpig.net","pilotemail.com","pimagop.com","pinoymail.com","piracha.net","pisem.net","pjjkp.com","planet-mail.com","planet.nl","planetaccess.com","planetall.com","planetarymotion.net","planetdirect.com","planetearthinter.net","planetmail.com","planetmail.net","planetout.com","plasa.com","playersodds.com","playful.com","playstation.sony.com","plexolan.de","pluno.com","plus.com","plus.google.com","plusmail.com.br","pmail.net","pobox.com","pobox.hu","pobox.ru","pobox.sk","pochta.by","pochta.ru","pochta.ws","pochtamt.ru","poczta.fm","poczta.onet.pl","poetic.com","pokemail.net","pokemonpost.com","pokepost.com","polandmail.com","polbox.com","policeoffice.com","politician.com","politikerclub.de","polizisten-duzer.de","polyfaust.com","poofy.org","poohfan.com","pookmail.com","pool-sharks.com","poond.com","pop3.ru","popaccount.com","popmail.com","popsmail.com","popstar.com","populus.net","portableoffice.com","portugalmail.com","portugalmail.pt","portugalnet.com","positive-thinking.com","post.com","post.cz","post.sk","posta.net","posta.ro","posta.rosativa.ro.org","postaccesslite.com","postafiok.hu","postafree.com","postaweb.com","poste.it","postfach.cc","postinbox.com","postino.ch","postino.it","postmark.net","postmaster.co.uk","postmaster.twitter.com","postpro.net","pousa.com","powerdivas.com","powerfan.com","pp.inet.fi","praize.com","pray247.com","predprinimatel.ru","premium-mail.fr","premiumproducts.com","premiumservice.com","prepodavatel.ru","presidency.com","presnya.net","press.co.jp","prettierthanher.com","priest.com","primposta.com","primposta.hu","printesamargareta.ro","privacy.net","privatdemail.net","privy-mail.com","privymail.de","pro.hu","probemail.com","prodigy.net","prodigy.net.mx","professor.ru","progetplus.it","programist.ru","programmer.net","programozo.hu","proinbox.com","project2k.com","prokuratura.ru","prolaunch.com","promessage.com","prontomail.com","prontomail.compopulus.net","protestant.com","protonmail.com","proxymail.eu","prtnx.com","prydirect.info","psv-supporter.com","ptd.net","public-files.de","public.usa.com","publicist.com","pulp-fiction.com","punkass.com","puppy.com.my","purinmail.com","purpleturtle.com","put2.net","putthisinyourspamdatabase.com","pwrby.com","q.com","qatar.io","qatarmail.com","qdice.com","qip.ru","qmail.com","qprfans.com","qq.com","qrio.com","quackquack.com","quake.ru","quakemail.com","qualityservice.com","quantentunnel.de","qudsmail.com","quepasa.com","quickhosts.com","quickinbox.com","quickmail.nl","quickmail.ru","quicknet.nl","quickwebmail.com","quiklinks.com","quikmail.com","qv7.info","qwest.net","qwestoffice.net","r-o-o-t.com","r7.com","raakim.com","racedriver.com","racefanz.com","racingfan.com.au","racingmail.com","radicalz.com","radiku.ye.vc","radiologist.net","ragingbull.com","ralib.com","rambler.ru","ranmamail.com","rastogi.net","ratt-n-roll.com","rattle-snake.com","raubtierbaendiger.de","ravearena.com","ravefan.com","ravemail.co.za","ravemail.com","razormail.com","rccgmail.org","rcn.com","rcpt.at","realemail.net","realestatemail.net","reality-concept.club","reallyfast.biz","reallyfast.info","reallymymail.com","realradiomail.com","realtyagent.com","realtyalerts.ca","reborn.com","recode.me","reconmail.com","recursor.net","recycledmail.com","recycler.com","recyclermail.com","rediff.com","rediffmail.com","rediffmailpro.com","rednecks.com","redseven.de","redsfans.com","redwhitearmy.com","regbypass.com","reggaefan.com","reggafan.com","regiononline.com","registerednurses.com","regspaces.tk","reincarnate.com","relia.com","reliable-mail.com","religious.com","remail.ga","renren.com","repairman.com","reply.hu","reply.ticketmaster.com","represantive.com","representative.com","rescueteam.com","resgedvgfed.tk","resource.calendar.google.com","resumemail.com","retailfan.com","rexian.com","rezai.com","rhyta.com","richmondhill.com","rickymail.com","rin.ru","ring.by","riopreto.com.br","rklips.com","rmqkr.net","rn.com","ro.ru","roadrunner.com","roanokemail.com","rock.com","rocketmail.com","rocketship.com","rockfan.com","rodrun.com","rogers.com","rojname.com","rol.ro","rome.com","romymichele.com","roosh.com","rootprompt.org","rotfl.com","roughnet.com","royal.net","rpharmacist.com","rr.com","rrohio.com","rsub.com","rt.nl","rtrtr.com","ru.ru","rubyridge.com","runbox.com","rushpost.com","ruttolibero.com","rvshop.com","rxdoc.biz","s-mail.com","s0ny.net","sabreshockey.com","sacbeemail.com","saeuferleber.de","safarimail.com","safe-mail.net","safersignup.de","safetymail.info","safetypost.de","safrica.com","sagra.lu","sagra.lu.lu","sagra.lumarketing.lu","sags-per-mail.de","sailormoon.com","saint-mike.org","saintly.com","saintmail.net","sale-sale-sale.com","salehi.net","salesperson.net","samerica.com","samilan.net","samiznaetekogo.net","sammimail.com","sanchezsharks.com","sandelf.de","sanfranmail.com","sanook.com","sanriotown.com","santanmail.com","sapo.pt","sativa.ro.org","saturnfans.com","saturnperformance.com","saudia.com","savecougars.com","savelife.ml","saveowls.com","sayhi.net","saynotospams.com","sbcglbal.net","sbcglobal.com","sbcglobal.net","scandalmail.com","scanova.in","scanova.io","scarlet.nl","scfn.net","schafmail.de","schizo.com","schmusemail.de","schoolemail.com","schoolmail.com","schoolsucks.com","schreib-doch-mal-wieder.de","schrott-email.de","schweiz.org","sci.fi","science.com.au","scientist.com","scifianime.com","scotland.com","scotlandmail.com","scottishmail.co.uk","scottishtories.com","scottsboro.org","scrapbookscrapbook.com","scubadiving.com","seanet.com","search.ua","search417.com","searchwales.com","sebil.com","seckinmail.com","secret-police.com","secretarias.com","secretary.net","secretemail.de","secretservices.net","secure-mail.biz","secure-mail.cc","seductive.com","seekstoyboy.com","seguros.com.br","sekomaonline.com","selfdestructingmail.com","sellingspree.com","send.hu","sendmail.ru","sendme.cz","sendspamhere.com","senseless-entertainment.com","sent.as","sent.at","sent.com","sentrismail.com","serga.com.ar","servemymail.com","servermaps.net","services391.com","sesmail.com","sexmagnet.com","seznam.cz","sfr.fr","shahweb.net","shaniastuff.com","shared-files.de","sharedmailbox.org","sharewaredevelopers.com","sharklasers.com","sharmaweb.com","shaw.ca","she.com","shellov.net","shieldedmail.com","shieldemail.com","shiftmail.com","shinedyoureyes.com","shitaway.cf","shitaway.cu.cc","shitaway.ga","shitaway.gq","shitaway.ml","shitaway.tk","shitaway.usa.cc","shitmail.de","shitmail.me","shitmail.org","shitware.nl","shmeriously.com","shockinmytown.cu.cc","shootmail.com","shortmail.com","shortmail.net","shotgun.hu","showfans.com","showslow.de","shqiptar.eu","shuf.com","sialkotcity.com","sialkotian.com","sialkotoye.com","sibmail.com","sify.com","sigaret.net","silkroad.net","simbamail.fm","sina.cn","sina.com","sinamail.com","singapore.com","singles4jesus.com","singmail.com","singnet.com.sg","singpost.com","sinnlos-mail.de","sirindia.com","siteposter.net","skafan.com","skeefmail.com","skim.com","skizo.hu","skrx.tk","skunkbox.com","sky.com","skynet.be","slamdunkfan.com","slapsfromlastnight.com","slaskpost.se","slave-auctions.net","slickriffs.co.uk","slingshot.com","slippery.email","slipry.net","slo.net","slotter.com","sm.westchestergov.com","smap.4nmv.ru","smapxsmap.net","smashmail.de","smellfear.com","smellrear.com","smileyface.comsmithemail.net","sminkymail.com","smoothmail.com","sms.at","smtp.ru","snail-mail.net","snail-mail.ney","snakebite.com","snakemail.com","sndt.net","sneakemail.com","sneakmail.de","snet.net","sniper.hu","snkmail.com","snoopymail.com","snowboarding.com","snowdonia.net","so-simple.org","socamail.com","socceraccess.com","socceramerica.net","soccermail.com","soccermomz.com","social-mailer.tk","socialworker.net","sociologist.com","sofimail.com","sofort-mail.de","sofortmail.de","softhome.net","sogetthis.com","sogou.com","sohu.com","sokolniki.net","sol.dk","solar-impact.pro","solcon.nl","soldier.hu","solution4u.com","solvemail.info","songwriter.net","sonnenkinder.org","soodomail.com","soodonims.com","soon.com","soulfoodcookbook.com","soundofmusicfans.com","southparkmail.com","sovsem.net","sp.nl","space-bank.com","space-man.com","space-ship.com","space-travel.com","space.com","spaceart.com","spacebank.com","spacemart.com","spacetowns.com","spacewar.com","spainmail.com","spam.2012-2016.ru","spam4.me","spamail.de","spamarrest.com","spamavert.com","spambob.com","spambob.net","spambob.org","spambog.com","spambog.de","spambog.net","spambog.ru","spambooger.com","spambox.info","spambox.us","spamcannon.com","spamcannon.net","spamcero.com","spamcon.org","spamcorptastic.com","spamcowboy.com","spamcowboy.net","spamcowboy.org","spamday.com","spamdecoy.net","spameater.com","spameater.org","spamex.com","spamfree.eu","spamfree24.com","spamfree24.de","spamfree24.info","spamfree24.net","spamfree24.org","spamgoes.in","spamgourmet.com","spamgourmet.net","spamgourmet.org","spamherelots.com","spamhereplease.com","spamhole.com","spamify.com","spaminator.de","spamkill.info","spaml.com","spaml.de","spammotel.com","spamobox.com","spamoff.de","spamslicer.com","spamspot.com","spamstack.net","spamthis.co.uk","spamtroll.net","spankthedonkey.com","spartapiet.com","spazmail.com","speed.1s.fr","speedemail.net","speedpost.net","speedrules.com","speedrulz.com","speedy.com.ar","speedymail.org","sperke.net","spils.com","spinfinder.com","spiritseekers.com","spl.at","spoko.pl","spoofmail.de","sportemail.com","sportmail.ru","sportsmail.com","sporttruckdriver.com","spray.no","spray.se","spybox.de","spymac.com","sraka.xyz","srilankan.net","ssl-mail.com","st-davids.net","stade.fr","stalag13.com","standalone.net","starbuzz.com","stargateradio.com","starmail.com","starmail.org","starmedia.com","starplace.com","starspath.com","start.com.au","starting-point.com","startkeys.com","startrekmail.com","starwars-fans.com","stealthmail.com","stillchronic.com","stinkefinger.net","stipte.nl","stockracer.com","stockstorm.com","stoned.com","stones.com","stop-my-spam.pp.ua","stopdropandroll.com","storksite.com","streber24.de","streetwisemail.com","stribmail.com","strompost.com","strongguy.com","student.su","studentcenter.org","stuffmail.de","subnetwork.com","subram.com","sudanmail.net","sudolife.me","sudolife.net","sudomail.biz","sudomail.com","sudomail.net","sudoverse.com","sudoverse.net","sudoweb.net","sudoworld.com","sudoworld.net","sueddeutsche.de","suhabi.com","suisse.org","sukhumvit.net","sul.com.br","sunmail1.com","sunpoint.net","sunrise-sunset.com","sunsgame.com","sunumail.sn","suomi24.fi","super-auswahl.de","superdada.com","supereva.it","supergreatmail.com","supermail.ru","supermailer.jp","superman.ru","superposta.com","superrito.com","superstachel.de","surat.com","suremail.info","surf3.net","surfree.com","surfsupnet.net","surfy.net","surgical.net","surimail.com","survivormail.com","susi.ml","sviblovo.net","svk.jp","swbell.net","sweb.cz","swedenmail.com","sweetville.net","sweetxxx.de","swift-mail.com","swiftdesk.com","swingeasyhithard.com","swingfan.com","swipermail.zzn.com","swirve.com","swissinfo.org","swissmail.com","swissmail.net","switchboardmail.com","switzerland.org","sx172.com","sympatico.ca","syom.com","syriamail.com","t-online.de","t.psh.me","t2mail.com","tafmail.com","takoe.com","takoe.net","takuyakimura.com","talk21.com","talkcity.com","talkinator.com","talktalk.co.uk","tamb.ru","tamil.com","tampabay.rr.com","tangmonkey.com","tankpolice.com","taotaotano.com","tatanova.com","tattooedallover.com","tattoofanatic.com","tbwt.com","tcc.on.ca","tds.net","teacher.com","teachermail.net","teachers.org","teamdiscovery.com","teamtulsa.net","tech-center.com","tech4peace.org","techemail.com","techie.com","technisamail.co.za","technologist.com","technologyandstocks.com","techpointer.com","techscout.com","techseek.com","techsniper.com","techspot.com","teenagedirtbag.com","teewars.org","tele2.nl","telebot.com","telebot.net","telefonica.net","teleline.es","telenet.be","telepac.pt","telerymd.com","teleserve.dynip.com","teletu.it","teleworm.com","teleworm.us","telfort.nl","telfortglasvezel.nl","telinco.net","telkom.net","telpage.net","telstra.com","telstra.com.au","temp-mail.com","temp-mail.de","temp-mail.org","temp-mail.ru","temp.headstrong.de","tempail.com","tempe-mail.com","tempemail.biz","tempemail.co.za","tempemail.com","tempemail.net","tempinbox.co.uk","tempinbox.com","tempmail.eu","tempmail.it","tempmail.us","tempmail2.com","tempmaildemo.com","tempmailer.com","tempmailer.de","tempomail.fr","temporarioemail.com.br","temporaryemail.net","temporaryemail.us","temporaryforwarding.com","temporaryinbox.com","temporarymailaddress.com","tempthe.net","tempymail.com","temtulsa.net","tenchiclub.com","tenderkiss.com","tennismail.com","terminverpennt.de","terra.cl","terra.com","terra.com.ar","terra.com.br","terra.com.pe","terra.es","test.com","test.de","tfanus.com.er","tfbnw.net","tfz.net","tgasa.ru","tgma.ru","tgngu.ru","tgu.ru","thai.com","thaimail.com","thaimail.net","thanksnospam.info","thankyou2010.com","thc.st","the-african.com","the-airforce.com","the-aliens.com","the-american.com","the-animal.com","the-army.com","the-astronaut.com","the-beauty.com","the-big-apple.com","the-biker.com","the-boss.com","the-brazilian.com","the-canadian.com","the-canuck.com","the-captain.com","the-chinese.com","the-country.com","the-cowboy.com","the-davis-home.com","the-dutchman.com","the-eagles.com","the-englishman.com","the-fastest.net","the-fool.com","the-frenchman.com","the-galaxy.net","the-genius.com","the-gentleman.com","the-german.com","the-gremlin.com","the-hooligan.com","the-italian.com","the-japanese.com","the-lair.com","the-madman.com","the-mailinglist.com","the-marine.com","the-master.com","the-mexican.com","the-ministry.com","the-monkey.com","the-newsletter.net","the-pentagon.com","the-police.com","the-prayer.com","the-professional.com","the-quickest.com","the-russian.com","the-seasiders.com","the-snake.com","the-spaceman.com","the-stock-market.com","the-student.net","the-whitehouse.net","the-wild-west.com","the18th.com","thecoolguy.com","thecriminals.com","thedoghousemail.com","thedorm.com","theend.hu","theglobe.com","thegolfcourse.com","thegooner.com","theheadoffice.com","theinternetemail.com","thelanddownunder.com","thelimestones.com","themail.com","themillionare.net","theoffice.net","theplate.com","thepokerface.com","thepostmaster.net","theraces.com","theracetrack.com","therapist.net","thereisnogod.com","thesimpsonsfans.com","thestreetfighter.com","theteebox.com","thewatercooler.com","thewebpros.co.uk","thewizzard.com","thewizzkid.com","thexyz.ca","thexyz.cn","thexyz.com","thexyz.es","thexyz.fr","thexyz.in","thexyz.mobi","thexyz.net","thexyz.org","thezhangs.net","thirdage.com","thisgirl.com","thisisnotmyrealemail.com","thismail.net","thoic.com","thraml.com","thrott.com","throwam.com","throwawayemailaddress.com","thundermail.com","tibetemail.com","tidni.com","tilien.com","timein.net","timormail.com","tin.it","tipsandadvice.com","tiran.ru","tiscali.at","tiscali.be","tiscali.co.uk","tiscali.it","tiscali.lu","tiscali.se","tittbit.in","tizi.com","tkcity.com","tlcfan.com","tmail.ws","tmailinator.com","tmicha.net","toast.com","toke.com","tokyo.com","tom.com","toolsource.com","toomail.biz","toothfairy.com","topchat.com","topgamers.co.uk","topletter.com","topmail-files.de","topmail.com.ar","topranklist.de","topsurf.com","topteam.bg","toquedequeda.com","torba.com","torchmail.com","torontomail.com","tortenboxer.de","totalmail.com","totalmail.de","totalmusic.net","totalsurf.com","toughguy.net","townisp.com","tpg.com.au","tradermail.info","trainspottingfan.com","trash-amil.com","trash-mail.at","trash-mail.com","trash-mail.de","trash-mail.ga","trash-mail.ml","trash2009.com","trash2010.com","trash2011.com","trashdevil.com","trashdevil.de","trashemail.de","trashmail.at","trashmail.com","trashmail.de","trashmail.me","trashmail.net","trashmail.org","trashmailer.com","trashymail.com","trashymail.net","travel.li","trayna.com","trbvm.com","trbvn.com","trevas.net","trialbytrivia.com","trialmail.de","trickmail.net","trillianpro.com","trimix.cn","tritium.net","trjam.net","trmailbox.com","tropicalstorm.com","truckeremail.net","truckers.com","truckerz.com","truckracer.com","truckracers.com","trust-me.com","truth247.com","truthmail.com","tsamail.co.za","ttml.co.in","tulipsmail.net","tunisiamail.com","turboprinz.de","turboprinzessin.de","turkey.com","turual.com","tushino.net","tut.by","tvcablenet.be","tverskie.net","tverskoe.net","tvnet.lv","tvstar.com","twc.com","twcny.com","twentylove.com","twinmail.de","twinstarsmail.com","tx.rr.com","tycoonmail.com","tyldd.com","typemail.com","tyt.by","u14269.ml","u2club.com","ua.fm","uae.ac","uaemail.com","ubbi.com","ubbi.com.br","uboot.com","uggsrock.com","uk2.net","uk2k.com","uk2net.com","uk7.net","uk8.net","ukbuilder.com","ukcool.com","ukdreamcast.com","ukmail.org","ukmax.com","ukr.net","ukrpost.net","ukrtop.com","uku.co.uk","ultapulta.com","ultimatelimos.com","ultrapostman.com","umail.net","ummah.org","umpire.com","unbounded.com","underwriters.com","unforgettable.com","uni.de","uni.de.de","uni.demailto.de","unican.es","unihome.com","universal.pt","uno.ee","uno.it","unofree.it","unomail.com","unterderbruecke.de","uogtritons.com","uol.com.ar","uol.com.br","uol.com.co","uol.com.mx","uol.com.ve","uole.com","uole.com.ve","uolmail.com","uomail.com","upc.nl","upcmail.nl","upf.org","upliftnow.com","uplipht.com","uraniomail.com","ureach.com","urgentmail.biz","uroid.com","us.af","usa.com","usa.net","usaaccess.net","usanetmail.com","used-product.fr","userbeam.com","usermail.com","username.e4ward.com","userzap.com","usma.net","usmc.net","uswestmail.net","uymail.com","uyuyuy.com","uzhe.net","v-sexi.com","v8email.com","vaasfc4.tk","vahoo.com","valemail.net","valudeal.net","vampirehunter.com","varbizmail.com","vcmail.com","velnet.co.uk","velnet.com","velocall.com","veloxmail.com.br","venompen.com","verizon.net","verizonmail.com","verlass-mich-nicht.de","versatel.nl","verticalheaven.com","veryfast.biz","veryrealemail.com","veryspeedy.net","vfemail.net","vickaentb.tk","videotron.ca","viditag.com","viewcastmedia.com","viewcastmedia.net","vinbazar.com","violinmakers.co.uk","vip.126.com","vip.21cn.com","vip.citiz.net","vip.gr","vip.onet.pl","vip.qq.com","vip.sina.com","vipmail.ru","viralplays.com","virgilio.it","virgin.net","virginbroadband.com.au","virginmedia.com","virtual-mail.com","virtualactive.com","virtualguam.com","virtualmail.com","visitmail.com","visitweb.com","visto.com","visualcities.com","vivavelocity.com","vivianhsu.net","viwanet.ru","vjmail.com","vjtimail.com","vkcode.ru","vlcity.ru","vlmail.com","vnet.citiz.net","vnn.vn","vnukovo.net","vodafone.nl","vodafonethuis.nl","voila.fr","volcanomail.com","vollbio.de","volloeko.de","vomoto.com","voo.be","vorsicht-bissig.de","vorsicht-scharf.de","vote-democrats.com","vote-hillary.com","vote-republicans.com","vote4gop.org","votenet.com","vovan.ru","vp.pl","vpn.st","vr9.com","vsimcard.com","vubby.com","vyhino.net","w3.to","wahoye.com","walala.org","wales2000.net","walkmail.net","walkmail.ru","walla.co.il","wam.co.za","wanaboo.com","wanadoo.co.uk","wanadoo.es","wanadoo.fr","wapda.com","war-im-urlaub.de","warmmail.com","warpmail.net","warrior.hu","wasteland.rfc822.org","watchmail.com","waumail.com","wazabi.club","wbdet.com","wearab.net","web-contact.info","web-emailbox.eu","web-ideal.fr","web-mail.com.ar","web-mail.pp.ua","web-police.com","web.de","webaddressbook.com","webadicta.org","webave.com","webbworks.com","webcammail.com","webcity.ca","webcontact-france.eu","webdream.com","webemail.me","webemaillist.com","webinbox.com","webindia123.com","webjump.com","webm4il.info","webmail.bellsouth.net","webmail.blue","webmail.co.yu","webmail.co.za","webmail.fish","webmail.hu","webmail.lawyer","webmail.ru","webmail.wiki","webmails.com","webmailv.com","webname.com","webprogramming.com","webskulker.com","webstation.com","websurfer.co.za","webtopmail.com","webtribe.net","webuser.in","wee.my","weedmail.com","weekmail.com","weekonline.com","wefjo.grn.cc","weg-werf-email.de","wegas.ru","wegwerf-emails.de","wegwerfadresse.de","wegwerfemail.com","wegwerfemail.de","wegwerfmail.de","wegwerfmail.info","wegwerfmail.net","wegwerfmail.org","wegwerpmailadres.nl","wehshee.com","weibsvolk.de","weibsvolk.org","weinenvorglueck.de","welsh-lady.com","wesleymail.com","westnet.com","westnet.com.au","wetrainbayarea.com","wfgdfhj.tk","wh4f.org","whale-mail.com","whartontx.com","whatiaas.com","whatpaas.com","wheelweb.com","whipmail.com","whoever.com","wholefitness.com","whoopymail.com","whtjddn.33mail.com","whyspam.me","wickedmail.com","wickmail.net","wideopenwest.com","wildmail.com","wilemail.com","will-hier-weg.de","willhackforfood.biz","willselfdestruct.com","windowslive.com","windrivers.net","windstream.com","windstream.net","winemaven.info","wingnutz.com","winmail.com.au","winning.com","winrz.com","wir-haben-nachwuchs.de","wir-sind-cool.org","wirsindcool.de","witty.com","wiz.cc","wkbwmail.com","wmail.cf","wo.com.cn","woh.rr.com","wolf-web.com","wolke7.net","wollan.info","wombles.com","women-at-work.org","women-only.net","wonder-net.com","wongfaye.com","wooow.it","work4teens.com","worker.com","workmail.co.za","workmail.com","worldbreak.com","worldemail.com","worldmailer.com","worldnet.att.net","wormseo.cn","wosaddict.com","wouldilie.com","wovz.cu.cc","wow.com","wowgirl.com","wowmail.com","wowway.com","wp.pl","wptamail.com","wrestlingpages.com","wrexham.net","writeme.com","writemeback.com","writeremail.com","wronghead.com","wrongmail.com","wtvhmail.com","wwdg.com","www.com","www.e4ward.com","www.mailinator.com","www2000.net","wwwnew.eu","wx88.net","wxs.net","wyrm.supernews.com","x-mail.net","x-networks.net","x.ip6.li","x5g.com","xagloo.com","xaker.ru","xd.ae","xemaps.com","xents.com","xing886.uu.gl","xmail.com","xmaily.com","xmastime.com","xmenfans.com","xms.nl","xmsg.com","xoom.com","xoommail.com","xoxox.cc","xoxy.net","xpectmore.com","xpressmail.zzn.com","xs4all.nl","xsecurity.org","xsmail.com","xtra.co.nz","xtram.com","xuno.com","xww.ro","xy9ce.tk","xyz.am","xyzfree.net","xzapmail.com","y7mail.com","ya.ru","yada-yada.com","yaho.com","yahoo.ae","yahoo.at","yahoo.be","yahoo.ca","yahoo.ch","yahoo.cn","yahoo.co","yahoo.co.id","yahoo.co.il","yahoo.co.in","yahoo.co.jp","yahoo.co.kr","yahoo.co.nz","yahoo.co.th","yahoo.co.uk","yahoo.co.za","yahoo.com","yahoo.com.ar","yahoo.com.au","yahoo.com.br","yahoo.com.cn","yahoo.com.co","yahoo.com.hk","yahoo.com.is","yahoo.com.mx","yahoo.com.my","yahoo.com.ph","yahoo.com.ru","yahoo.com.sg","yahoo.com.tr","yahoo.com.tw","yahoo.com.vn","yahoo.cz","yahoo.de","yahoo.dk","yahoo.es","yahoo.fi","yahoo.fr","yahoo.gr","yahoo.hu","yahoo.ie","yahoo.in","yahoo.it","yahoo.jp","yahoo.net","yahoo.nl","yahoo.no","yahoo.pl","yahoo.pt","yahoo.ro","yahoo.ru","yahoo.se","yahoofs.com","yahoomail.com","yalla.com","yalla.com.lb","yalook.com","yam.com","yandex.com","yandex.mail","yandex.pl","yandex.ru","yandex.ua","yapost.com","yapped.net","yawmail.com","yclub.com","yeah.net","yebox.com","yeehaa.com","yehaa.com","yehey.com","yemenmail.com","yep.it","yepmail.net","yert.ye.vc","yesbox.net","yesey.net","yeswebmaster.com","ygm.com","yifan.net","ymail.com","ynnmail.com","yogamaven.com","yogotemail.com","yomail.info","yopmail.com","yopmail.fr","yopmail.net","yopmail.org","yopmail.pp.ua","yopolis.com","yopweb.com","youareadork.com","youmailr.com","youpy.com","your-house.com","your-mail.com","yourdomain.com","yourinbox.com","yourlifesucks.cu.cc","yourlover.net","yournightmare.com","yours.com","yourssincerely.com","yourteacher.net","yourwap.com","youthfire.com","youthpost.com","youvegotmail.net","yuuhuu.net","yuurok.com","yyhmail.com","z1p.biz","z6.com","z9mail.com","za.com","zahadum.com","zaktouni.fr","zcities.com","zdnetmail.com","zdorovja.net","zeeks.com","zeepost.nl","zehnminuten.de","zehnminutenmail.de","zensearch.com","zensearch.net","zerocrime.org","zetmail.com","zhaowei.net","zhouemail.510520.org","ziggo.nl","zing.vn","zionweb.org","zip.net","zipido.com","ziplip.com","zipmail.com","zipmail.com.br","zipmax.com","zippymail.info","zmail.pt","zmail.ru","zoemail.com","zoemail.net","zoemail.org","zoho.com","zomg.info","zonai.com","zoneview.net","zonnet.nl","zooglemail.com","zoominternet.net","zubee.com","zuvio.com","zuzzurello.com","zvmail.com","zwallet.com","zweb.in","zxcv.com","zxcvbnm.com","zybermail.com","zydecofan.com","zzn.com","zzom.co.uk","zzz.com"];var Xr=a(3975);const Qr="(?:[_\\p{L}0-9][-_\\p{L}0-9]*\\.)*(?:[\\p{L}0-9][-\\p{L}0-9]{0,62})\\.(?:(?:[a-z]{2}\\.)?[a-z]{2,})",eo=class{static extractDomainFromEmail(e){const t=Qt()(`(?<=@)${Qr}`);return Qt().match(e,t)||""}static isProfessional(e){return!Jr.includes(e)}static checkDomainValidity(e){if(!Qt()(`^${Qr}$`).test(e))throw new Error("Cannot parse domain. The domain does not match the pattern.");try{if(!new URL(`https://${e}`).host)throw new Error("Cannot parse domain. The domain does not match the pattern.")}catch(e){throw new Error("Cannot parse domain. The domain is not valid.",{cause:e})}}static isValidHostname(e){return Qt()(`^${Qr}$`).test(e)||(0,Xr.A)({exact:!0}).test(e)}},to="none",ao="username",no="username_password",so="oauth",io=[Kr,Vr,Gr,Br],ro=[...new Set(io.flatMap(e=>Object.keys(e.getDefaultData())))];class oo extends he{static getSchema(){const e=$r.getSchema(),t={};for(const e of ro)for(const a of io){const n=a.getSchema().properties[e];if(n){t[e]={...n,nullable:!0};break}}return{type:"object",required:[...e.required],properties:{...e.properties,...t,provider:{type:"string",nullable:!0}}}}marshall(){if("string"==typeof this._props.port){const e=parseInt(this._props.port,10);this._props.port=isNaN(e)?this._props.port:e}}validate(e={}){this.marshall();let t=null;const a=e?.schema??this.cachedSchema;try{ae.validate(this.constructor.name,{...this._props},a)}catch(e){if(!(e instanceof X))throw e;t=e}let n=null;try{this.validateBuildRules(e?.validateBuildRules)}catch(e){if(!(e instanceof X))throw e;n=e}if(!t&&!n)return null;const s=t||new X;if(n)for(const e in n.details)if(!s.hasError(e)){const t=n.details[e];for(const a in t)s.addError(e,a,t[a])}return s}validateBuildRules(){const e=new X,t=this._props.client;if(t&&t.length>0&&(eo.isValidHostname(t)||e.addError("client","hostname","SMTP client should be a valid domain or IP address")),e.hasErrors())throw e}toFormDto(){const e={host:this._props.host??"",port:this._props.port??"",tls:this._props.tls??!0,client:this._props.client??"",sender_name:this._props.sender_name??"",sender_email:this._props.sender_email??"",provider:this._props.provider??null,source:this._props.source??null};for(const t of ro)e[t]=this._props[t]??null;return e}toApiDto(){const e=this.toDto();return delete e.provider,""===e.client&&(e.client=null),e}detectProvider(e){const t=this._props.host,a=parseInt(this._props.port,10),n=this._props.tls;for(let s=0;se.host===t&&e.port===a&&e.tls===n);if(r)return i.id}return"other"}changeAuthenticationMethod(e){const t=this._getAuthenticationEntityClass(e).getDefaultData(),a={};for(const e of ro)a[e]=this._props[e],this._props[e]=null;for(const[e,n]of Object.entries(t))null!==n&&(this._props[e]=a[e]??n)}_getAuthenticationEntityClass(e){switch(e){case to:return Kr;case ao:return Vr;case no:return Gr;case so:return Br;default:throw new Error(`Unknown authentication method: ${e}`)}}applyProviderDefaults(e){if(e.defaultConfiguration){const t=e.defaultConfiguration;void 0!==t.host&&(this._props.host=t.host),void 0!==t.port&&(this._props.port=t.port),void 0!==t.tls&&(this._props.tls=t.tls)}this._props.provider=e.id}getAuthenticationMethod(){return null!==this._props.client_id&&void 0!==this._props.client_id?so:null===this._props.username||void 0===this._props.username?to:null===this._props.password||void 0===this._props.password?ao:no}static createDefault(){return new oo({host:"",port:"",tls:!0,client:"",sender_email:"",sender_name:"Passbolt",...Gr.getDefaultData()},{validate:!1})}static get ENTITY_NAME(){return"SmtpSettingsForm"}static get AUTHENTICATION_METHOD_NONE(){return to}static get AUTHENTICATION_METHOD_USERNAME(){return ao}static get AUTHENTICATION_METHOD_USERNAME_PASSWORD(){return no}static get AUTHENTICATION_METHOD_OAUTH(){return so}static get AUTH_FIELDS(){return ro}}const lo=oo;class co extends sa{constructor(e){super(e,co.RESOURCE_NAME)}static get RESOURCE_NAME(){return"smtp/email"}async create(e){this.assertNonEmptyData(e);const t=await this.apiClient.create(e);return new oa(t)}}const mo=co,uo=class{constructor(e){this.smtpTestSettingsApiService=new mo(e)}async send(e,t){const a=e.toDto();return a.email_test_to=t,(await this.smtpTestSettingsApiService.create(a)).body}};var po=a(1811);function ho(){return ho=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},findSmtpSettings:()=>{},changeProvider:()=>{},changeAuthenticationMethod:()=>{},getAuthenticationMethod:()=>{},setData:()=>{},isSettingsModified:()=>{},isSettingsValid:()=>{},getErrors:()=>{},validateData:()=>{},getFieldToFocus:()=>{},saveSmtpSettings:()=>{},isProcessing:()=>{},hasProviderChanged:()=>{},sendTestMailTo:()=>{},isDataReady:()=>{},clearContext:()=>{}});class yo extends n.Component{constructor(e){super(e),this.state=this.defaultState;const t=e.context.getApiClientOptions();this.findSmtpSettingsService=new Yr(t),this.saveSmtpSettingsService=new Zr(t),this.sendTestSmtpSettingsService=new uo(t),this.fieldToFocus=null,this.providerHasChanged=!1,this.originalSettings=null,this.formSettings=null}get defaultState(){return{settings:{},isLoaded:!1,processing:!1,hasAlreadyBeenValidated:!1,getCurrentSmtpSettings:this.getCurrentSmtpSettings.bind(this),findSmtpSettings:this.findSmtpSettings.bind(this),changeProvider:this.changeProvider.bind(this),changeAuthenticationMethod:this.changeAuthenticationMethod.bind(this),getAuthenticationMethod:this.getAuthenticationMethod.bind(this),setData:this.setData.bind(this),isSettingsModified:this.isSettingsModified.bind(this),getErrors:this.getErrors.bind(this),validateData:this.validateData.bind(this),getFieldToFocus:this.getFieldToFocus.bind(this),saveSmtpSettings:this.saveSmtpSettings.bind(this),isProcessing:this.isProcessing.bind(this),hasProviderChanged:this.hasProviderChanged.bind(this),sendTestMailTo:this.sendTestMailTo.bind(this),isDataReady:this.isDataReady.bind(this),clearContext:this.clearContext.bind(this)}}validateForm=(0,po.A)(e=>this.formSettings?.validate({validateBuildRules:{siteSettings:this.props.context.siteSettings}}));hasSettingsChanges=(0,po.A)((e,t)=>this.originalSettings?.hasDiffProps(this.formSettings)||!1);async findSmtpSettings(){if(!this.props.context.siteSettings.canIUse("smtpSettings"))return null;let e;try{e=(await this.findSmtpSettingsService.find()).toDto(),e.client=e.client??"",e.username=e.username??null,e.password=e.password??null}catch(t){this.handleError(t),e=lo.createDefault().toFormDto()}e.sender_email=e.sender_email??this.props.context.loggedInUser.username,this.originalSettings=new lo(e,{validate:!1});const t=this.originalSettings.toFormDto();if(t.host&&t.port){const e=this.originalSettings.detectProvider(Lr);this.originalSettings.set("provider",e,{validate:!1})}this.formSettings=new lo(this.originalSettings.toDto(),{validate:!1}),this.setState({settings:this.formSettings.toFormDto(),isLoaded:!0})}clearContext(){this.originalSettings=null,this.formSettings=null;const{settings:e,isLoaded:t,processing:a,hasAlreadyBeenValidated:n}=this.defaultState;this.setState({settings:e,isLoaded:t,processing:a,hasAlreadyBeenValidated:n})}async saveSmtpSettings(){this.setState({processing:!0});try{const e=this.formSettings.toApiDto(),t=$r.createFromSettings(e);await this.saveSmtpSettingsService.save(t),this.props.actionFeedbackContext.displaySuccess(this.props.t("The SMTP settings have been saved successfully")),this.originalSettings=new lo(this.formSettings.toDto(),{validate:!1}),this.setState({settings:this.formSettings.toFormDto()})}catch(e){this.handleError(e)}finally{this.setState({processing:!1})}}async sendTestMailTo(e){const t=this.formSettings.toApiDto(),a=$r.createFromSettings(t);return await this.sendTestSmtpSettingsService.send(a,e)}hasProviderChanged(){const e=this.providerHasChanged;return this.providerHasChanged=!1,e}changeAuthenticationMethod(e){this.formSettings.changeAuthenticationMethod(e);const t=this.formSettings.detectProvider(Lr);this.formSettings.set("provider",t,{validate:!1}),this.setState({settings:this.formSettings.toFormDto()}),this.state.hasAlreadyBeenValidated&&this.validateData({setFocus:!1})}getAuthenticationMethod(){return this.formSettings?.getAuthenticationMethod()??null}changeProvider(e){const t=this.formSettings?.toFormDto()?.provider;e.id!==t&&(this.providerHasChanged=!0,this.formSettings.applyProviderDefaults(e),"office-365"!==e.id&&this.formSettings.getAuthenticationMethod()===lo.AUTHENTICATION_METHOD_OAUTH&&this.formSettings.changeAuthenticationMethod(lo.AUTHENTICATION_METHOD_USERNAME_PASSWORD),this.setState({settings:this.formSettings.toFormDto()}))}setData(e){for(const t in e)this.formSettings.set(t,e[t],{validate:!1});const t=this.formSettings.detectProvider(Lr);this.formSettings.set("provider",t,{validate:!1}),"office-365"!==t&&this.formSettings.getAuthenticationMethod()===lo.AUTHENTICATION_METHOD_OAUTH&&this.formSettings.changeAuthenticationMethod(lo.AUTHENTICATION_METHOD_USERNAME_PASSWORD),this.setState({settings:this.formSettings.toFormDto()}),this.state.hasAlreadyBeenValidated&&this.validateData({setFocus:!1})}isDataReady(){return this.state.isLoaded}isProcessing(){return this.state.processing}isSettingsModified(){return this.hasSettingsChanges(this.originalSettings?.toFormDto(),this.formSettings?.toFormDto())}getErrors(){return this.state.hasAlreadyBeenValidated?this.validateForm(this.state.settings):null}validateData({setFocus:e=!0}={}){const t=this.validateForm(this.state.settings),a=!t;if(!a&&e){const e=["username","password","oauth_username","tenant_id","client_id","client_secret","host","tls","port","client","sender_name","sender_email"];this.fieldToFocus=e.find(e=>t.hasError(e))}return this.setState({hasAlreadyBeenValidated:!0}),a}getCurrentSmtpSettings(){return this.state.settings}getFieldToFocus(){const e=this.fieldToFocus;return this.fieldToFocus=null,e}handleError(e){console.error(e),this.props.dialogContext.open($t,{error:e})}render(){return n.createElement(go.Provider,{value:this.state},this.props.children)}}yo.propTypes={context:i().any,dialogContext:i().object,actionFeedbackContext:i().object,children:i().any,t:i().func};const bo=N(h(m((0,f.CI)("common")(yo))));function fo(e){return class extends n.Component{render(){return n.createElement(go.Consumer,null,t=>n.createElement(e,ho({adminSmtpSettingsContext:t},this.props)))}}}const Eo="form",vo="error",wo="success";class ko extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.bindCallbacks()}get defaultState(){return{uiState:Eo,recipient:this.props.context.loggedInUser.username,processing:!1,displayLogs:!0}}bindCallbacks(){this.handleRetryClick=this.handleRetryClick.bind(this),this.handleError=this.handleError.bind(this),this.handleFormSubmit=this.handleFormSubmit.bind(this),this.handleInputChange=this.handleInputChange.bind(this),this.handleDisplayLogsClick=this.handleDisplayLogsClick.bind(this)}async handleFormSubmit(e){if(e.preventDefault(),this.validateForm()){try{this.setState({processing:!0});const e=await this.props.adminSmtpSettingsContext.sendTestMailTo(this.state.recipient);this.setState({uiState:wo,debugDetails:this.formatDebug(e.debug),displayLogs:!1})}catch(e){this.handleError(e)}this.setState({processing:!1})}}async handleInputChange(e){this.setState({recipient:e.target.value})}validateForm(){const e=nr.validate(this.state.recipient,this.props.context.siteSettings);return this.setState({recipientError:e?"":this.translate("Recipient must be a valid email")}),e}formatDebug(e){return JSON.stringify(e,null,4)}handleError(e){const t=e.data?.body?.debug,a=t?.length>0?t:e?.message;this.setState({uiState:vo,debugDetails:this.formatDebug(a),displayLogs:!0})}handleDisplayLogsClick(){this.setState({displayLogs:!this.state.displayLogs})}handleRetryClick(){this.setState({uiState:Eo})}hasAllInputDisabled(){return this.state.processing}get title(){return{form:this.translate("Send test email"),error:this.translate("Something went wrong!"),success:this.translate("Email sent")}[this.state.uiState]||""}get translate(){return this.props.t}render(){return n.createElement(qt,{className:"send-test-email-dialog",title:this.title,onClose:this.props.handleClose,disabled:this.hasAllInputDisabled()},this.state.uiState===Eo&&n.createElement("form",{onSubmit:this.handleFormSubmit,noValidate:!0},n.createElement("div",{className:"form-content"},n.createElement("div",{className:`input text required ${this.state.recipientError?"error":""} ${this.hasAllInputDisabled()?"disabled":""}`},n.createElement("label",null,n.createElement(f.x6,null,"Recipient")),n.createElement("input",{id:"recipient",type:"text",name:"recipient",required:"required",className:"required fluid form-element ready",placeholder:"name@email.com",onChange:this.handleInputChange,value:this.state.recipient,disabled:this.hasAllInputDisabled()}),this.state.recipientError&&n.createElement("div",{className:"recipient error-message"},this.state.recipientError)),n.createElement("div",{className:"message notice no-margin"},n.createElement("strong",null,n.createElement(f.x6,null,"Pro tip"),":")," ",n.createElement(f.x6,null,"after clicking on send, a test email will be sent to the recipient email in order to check that your configuration is correct."))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement(gn,{disabled:this.hasAllInputDisabled(),onClick:this.props.handleClose}),n.createElement(qs,{disabled:this.hasAllInputDisabled(),processing:this.state.processing,value:this.translate("Send")}))),this.state.uiState===vo&&n.createElement(n.Fragment,null,n.createElement("div",{className:"dialog-body"},n.createElement("p",null,n.createElement(f.x6,null,"The test email could not be sent. Kindly check the logs below for more information."),n.createElement("br",null),n.createElement("a",{className:"faq-link",href:"https://www.passbolt.com/docs/hosting/troubleshooting/email",rel:"noopener noreferrer",target:"_blank"},n.createElement(f.x6,null,"FAQ: Why are my emails not sent?"))),n.createElement("div",{className:"accordion-header"},n.createElement("button",{type:"button",className:"link no-border",onClick:this.handleDisplayLogsClick},n.createElement("span",null,n.createElement(f.x6,null,"Logs")),this.state.displayLogs?n.createElement(Vt,{className:"baseline svg-icon"}):n.createElement(Wt,{className:"baseline svg-icon"}))),this.state.displayLogs&&n.createElement("div",{className:"accordion-content"},n.createElement("textarea",{className:"full_report",readOnly:!0,value:this.state.debugDetails}))),n.createElement("div",{className:"dialog-footer clearfix"},n.createElement("button",{type:"button",className:"cancel",disabled:this.hasAllInputDisabled(),onClick:this.handleRetryClick},n.createElement(f.x6,null,"Retry")),n.createElement("button",{className:"button primary",type:"button",onClick:this.props.handleClose,disabled:this.isProcessing},n.createElement("span",null,n.createElement(f.x6,null,"Close"))))),this.state.uiState===wo&&n.createElement(n.Fragment,null,n.createElement("div",{className:"dialog-body"},n.createElement("p",null,n.createElement(f.x6,null,"The test email has been sent. Check your email box, you should receive it in a minute.")),n.createElement("div",{className:"accordion-header"},n.createElement("button",{type:"button",className:"link no-border",onClick:this.handleDisplayLogsClick},n.createElement("span",null,n.createElement(f.x6,null,"Logs")),this.state.displayLogs?n.createElement(Vt,{className:"baseline svg-icon"}):n.createElement(Wt,{className:"baseline svg-icon"}))),this.state.displayLogs&&n.createElement("div",{className:"accordion-content"},n.createElement("textarea",{className:"full_report",readOnly:!0,value:this.state.debugDetails})),n.createElement("div",{className:"message notice no-margin"},n.createElement("strong",null,n.createElement(f.x6,null,"Pro tip"),":")," ",n.createElement(f.x6,null,"Check your spam folder if you do not hear from us after a while."))),n.createElement("div",{className:"dialog-footer clearfix"},n.createElement("button",{type:"button",className:"cancel",disabled:this.hasAllInputDisabled(),onClick:this.handleRetryClick},n.createElement(f.x6,null,"Retry")),n.createElement("button",{className:"button primary",type:"button",onClick:this.props.handleClose,disabled:this.isProcessing},n.createElement("span",null,n.createElement(f.x6,null,"Close"))))))}}ko.propTypes={context:i().object,adminSmtpSettingsContext:i().object,handleClose:i().func,t:i().func};const _o=N(fo((0,f.CI)("common")(ko)));var xo,So;function Co(){return Co=Object.assign?Object.assign.bind():function(e){for(var t=1;te.id===t);this.props.adminSmtpSettingsContext.changeProvider(a)}handleAuthenticationMethodChange(e){this.props.adminSmtpSettingsContext.changeAuthenticationMethod(e.target.value)}handleInputChange(e){const t=e.target;this.props.adminSmtpSettingsContext.setData({[t.name]:t.value})}handleAdvancedSettingsToggle(){this.setState({showAdvancedSettings:!this.state.showAdvancedSettings})}isProcessing(){return this.props.adminSmtpSettingsContext.isProcessing()}get providerList(){return Lr.map(e=>({value:e.id,label:e.name}))}get authenticationMethodList(){const e=this.props.adminSmtpSettingsContext.getCurrentSmtpSettings(),t=[{value:Do,label:this.translate("None")},{value:Oo,label:this.translate("Username only")},{value:Mo,label:this.translate("Username & password")}];return"office-365"===e?.provider&&t.push({value:Uo,label:this.translate("OAuth (Client Credentials Grant)")}),t}get tlsSelectList(){return[{value:!0,label:this.translate("Yes")},{value:!1,label:this.translate("No")}]}get authenticationMethod(){return this.props.adminSmtpSettingsContext.getAuthenticationMethod()}shouldDisplayUsername(){return this.authenticationMethod===Oo||this.authenticationMethod===Mo}shouldDisplayPassword(){return this.authenticationMethod===Mo}shouldDisplayOAuth(){return this.authenticationMethod===Uo}shouldShowSourceWarningMessage(){const e=this.props.adminSmtpSettingsContext;return"db"!==e.getCurrentSmtpSettings().source&&e.isSettingsModified()}isReady(){return this.props.adminSmtpSettingsContext.isDataReady()}get settingsSource(){return this.props.adminSmtpSettingsContext?.getCurrentSmtpSettings()?.source}get configurationSource(){return{env:this.props.t("environment variables"),file:this.props.t("file"),db:this.props.t("database")}[this.settingsSource]||this.props.t("unknown")}get translate(){return this.props.t}render(){const e=this.props.adminSmtpSettingsContext.getCurrentSmtpSettings(),t=this.props.adminSmtpSettingsContext.getErrors(),a=Lr.find(t=>t.id===e?.provider),s=a?.name,i=this.props.adminSmtpSettingsContext.isSettingsModified(),r=i||this.shouldShowSourceWarningMessage();return n.createElement("div",{className:"row"},n.createElement(n.Fragment,null,n.createElement("div",{className:"third-party-provider-settings smtp-settings main-column"},n.createElement("div",{className:"main-content"},n.createElement("h3",{className:"title"},n.createElement(f.x6,null,"Email server")),this.isReady()&&!e?.provider&&n.createElement(n.Fragment,null,n.createElement("h4",{className:"no-border"},n.createElement(f.x6,null,"Select a provider")),n.createElement("div",{className:"provider-list"},Lr.map(e=>n.createElement("div",{key:e.id,className:"provider button",id:e.id,onClick:()=>this.props.adminSmtpSettingsContext.changeProvider(e)},n.createElement("div",{className:"provider-logo"},"other"===e.id&&n.createElement(Qs,null),"other"!==e.id&&n.createElement("img",{src:`${this.props.context.trustedDomain}/img/third_party/${e.icon}`})),n.createElement("p",{className:"provider-name"},e.name))))),this.isReady()&&e?.provider&&n.createElement(n.Fragment,null,n.createElement("form",{className:"form"},n.createElement("h4",{className:"no-border"},n.createElement(f.x6,null,"SMTP server configuration")),n.createElement("div",{className:"select-wrapper input required "+(this.isProcessing()?"disabled":"")},n.createElement("label",{htmlFor:"smtp-settings-form-provider"},n.createElement(f.x6,null,"Email provider")),n.createElement(pn,{id:"smtp-settings-form-provider",name:"provider",items:this.providerList,value:e.provider,onChange:this.handleProviderChange,disabled:this.isProcessing()})),n.createElement("div",{className:"select-wrapper input required "+(this.isProcessing()?"disabled":"")},n.createElement("label",{htmlFor:"smtp-settings-form-authentication-method"},n.createElement(f.x6,null,"Authentication method")),n.createElement(pn,{id:"smtp-settings-form-authentication-method",name:"authentication-method",items:this.authenticationMethodList,value:this.authenticationMethod,onChange:this.handleAuthenticationMethodChange,disabled:this.isProcessing()})),this.shouldDisplayUsername()&&n.createElement("div",{className:`input text ${t?.hasError("username")?"error":""} ${this.isProcessing()?"disabled":""}`},n.createElement("label",{htmlFor:"smtp-settings-form-username"},n.createElement(f.x6,null,"Username")),n.createElement("input",{id:"smtp-settings-form-username",ref:this.usernameFieldRef,name:"username",className:"fluid",maxLength:"256",type:"text",autoComplete:"off",value:e.username,onChange:this.handleInputChange,placeholder:this.translate("Username"),disabled:this.isProcessing()}),t?.hasError("username")&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"This is the maximum size for this field, make sure your data was not truncated."))),this.shouldDisplayPassword()&&n.createElement("div",{className:`input-password-wrapper input ${t?.hasError("password")?"error":""} ${this.isProcessing()?"disabled":""}`},n.createElement("label",{htmlFor:"smtp-settings-form-password"},n.createElement(f.x6,null,"Password")),n.createElement(Za,{id:"smtp-settings-form-password",name:"password",autoComplete:"new-password",placeholder:this.translate("Password"),preview:!0,value:e.password,onChange:this.handleInputChange,disabled:this.isProcessing(),inputRef:this.passwordFieldRef}),t?.hasError("password")&&n.createElement("div",{className:"password error-message"},n.createElement(f.x6,null,"This is the maximum size for this field, make sure your data was not truncated."))),this.shouldDisplayOAuth()&&n.createElement(n.Fragment,null,n.createElement("div",{className:`input text required ${t?.hasError("oauth_username")?"error":""} ${this.isProcessing()?"disabled":""}`},n.createElement("label",{htmlFor:"smtp-settings-form-oauth-username"},n.createElement(f.x6,null,"OAuth Username")),n.createElement("input",{id:"smtp-settings-form-oauth-username",ref:this.oauth_usernameFieldRef,name:"oauth_username","aria-required":!0,className:"fluid",maxLength:"256",type:"text",autoComplete:"off",value:e.oauth_username,onChange:this.handleInputChange,placeholder:this.translate("OAuth Username"),disabled:this.isProcessing()}),t?.hasError("oauth_username")&&n.createElement("div",{className:"error-message"},!e.oauth_username||t.hasError("oauth_username","required")?n.createElement(f.x6,null,"OAuth Username is required."):n.createElement(f.x6,null,"OAuth Username must be a valid email."))),n.createElement("div",{className:`input text required ${t?.hasError("tenant_id")?"error":""} ${this.isProcessing()?"disabled":""}`},n.createElement("label",{htmlFor:"smtp-settings-form-tenant-id"},n.createElement(f.x6,null,"Tenant ID")),n.createElement("input",{id:"smtp-settings-form-tenant-id",ref:this.tenant_idFieldRef,name:"tenant_id","aria-required":!0,className:"fluid",maxLength:"256",type:"text",autoComplete:"off",value:e.tenant_id,onChange:this.handleInputChange,placeholder:this.translate("Tenant ID"),disabled:this.isProcessing()}),t?.hasError("tenant_id")&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"Tenant ID is required."))),n.createElement("div",{className:`input text required ${t?.hasError("client_id")?"error":""} ${this.isProcessing()?"disabled":""}`},n.createElement("label",{htmlFor:"smtp-settings-form-client-id"},n.createElement(f.x6,null,"Client ID")),n.createElement("input",{id:"smtp-settings-form-client-id",ref:this.client_idFieldRef,name:"client_id","aria-required":!0,className:"fluid",maxLength:"256",type:"text",autoComplete:"off",value:e.client_id,onChange:this.handleInputChange,placeholder:this.translate("Client ID"),disabled:this.isProcessing()}),t?.hasError("client_id")&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"Client ID is required."))),n.createElement("div",{className:`input-password-wrapper input required ${t?.hasError("client_secret")?"error":""} ${this.isProcessing()?"disabled":""}`},n.createElement("label",{htmlFor:"smtp-settings-form-client-secret"},n.createElement(f.x6,null,"Client Secret")),n.createElement(Za,{id:"smtp-settings-form-client-secret",name:"client_secret",autoComplete:"new-password",placeholder:this.translate("Client Secret"),preview:!0,value:e.client_secret,onChange:this.handleInputChange,disabled:this.isProcessing(),inputRef:this.client_secretFieldRef}),t?.hasError("client_secret")&&n.createElement("div",{className:"password error-message"},n.createElement(f.x6,null,"Client Secret is required.")))),n.createElement("div",{className:"accordion-header"},n.createElement("button",{type:"button",className:"link no-border",onClick:this.handleAdvancedSettingsToggle},this.state.showAdvancedSettings?n.createElement(Vt,null):n.createElement(Wt,null),n.createElement(f.x6,null,"Advanced settings"))),this.state.showAdvancedSettings&&n.createElement("div",{className:"advanced-settings"},n.createElement("div",{className:`input text required ${t?.hasError("host")?"error":""} ${this.isProcessing()?"disabled":""}`},n.createElement("label",{htmlFor:"smtp-settings-form-host"},n.createElement(f.x6,null,"SMTP host")),n.createElement("input",{id:"smtp-settings-form-host",ref:this.hostFieldRef,name:"host","aria-required":!0,className:"fluid",maxLength:"256",type:"text",autoComplete:"off",value:e.host,onChange:this.handleInputChange,placeholder:this.translate("SMTP server address"),disabled:this.isProcessing()}),t?.hasError("host")&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"SMTP Host is required"))),n.createElement("div",{className:`input text required ${t?.hasError("tls")?"error":""} ${this.isProcessing()?"disabled":""}`},n.createElement("label",{htmlFor:"smtp-settings-form-tls"},n.createElement(f.x6,null,"Use TLS")),n.createElement(pn,{id:"smtp-settings-form-tls",name:"tls",items:this.tlsSelectList,value:e.tls,onChange:this.handleInputChange,disabled:this.isProcessing()}),t?.hasError("tls")&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"TLS must be set to 'Yes' or 'No'"))),n.createElement("div",{className:`input text required ${t?.hasError("port")?"error":""} ${this.isProcessing()?"disabled":""}`},n.createElement("label",{htmlFor:"smtp-settings-form-port"},n.createElement(f.x6,null,"Port")),n.createElement("input",{id:"smtp-settings-form-port","aria-required":!0,ref:this.portFieldRef,name:"port",className:"fluid",maxLength:"256",type:"text",autoComplete:"off",value:e.port,onChange:this.handleInputChange,placeholder:this.translate("Port number"),disabled:this.isProcessing()}),t?.hasError("port")&&n.createElement("div",{className:"error-message"},t.hasError("port","minimum")||t.hasError("port","maximum")?n.createElement(f.x6,null,"Port must be a number between 1 and 65535"):n.createElement(f.x6,null,"Port must be a valid number"))),n.createElement("div",{className:`input text ${t?.hasError("client")?"error":""} ${this.isProcessing()?"disabled":""}`},n.createElement("label",{htmlFor:"smtp-settings-form-client"},n.createElement(f.x6,null,"SMTP client")),n.createElement("input",{id:"smtp-settings-form-client",ref:this.clientFieldRef,name:"client",maxLength:"2048",type:"text",autoComplete:"off",value:e.client,onChange:this.handleInputChange,placeholder:this.translate("SMTP client address"),disabled:this.isProcessing()}),t?.hasError("client")&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"SMTP client should be a valid domain or IP address")))),n.createElement("h4",null,n.createElement(f.x6,null,"Sender configuration")),n.createElement("div",{className:`input text required ${t?.hasError("sender_name")?"error":""} ${this.isProcessing()?"disabled":""}`},n.createElement("label",{htmlFor:"smtp-settings-form-sender-name"},n.createElement(f.x6,null,"Sender name")),n.createElement("input",{id:"smtp-settings-form-sender-name",ref:this.senderNameFieldRef,name:"sender_name","aria-required":!0,className:"fluid",maxLength:"256",type:"text",autoComplete:"off",value:e.sender_name,onChange:this.handleInputChange,placeholder:this.translate("Sender name"),disabled:this.isProcessing()}),t?.hasError("sender_name")&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"Sender name is required")),n.createElement("p",null,n.createElement(f.x6,null,"This is the name users will see in their mailbox when passbolt sends a notification."))),n.createElement("div",{className:`input text required ${t?.hasError("sender_email")?"error":""} ${this.isProcessing()?"disabled":""}`},n.createElement("label",{htmlFor:"smtp-settings-form-sender-name"},n.createElement(f.x6,null,"Sender email")),n.createElement("input",{id:"smtp-settings-form-sender-email",ref:this.senderEmailFieldRef,name:"sender_email","aria-required":!0,className:"fluid",maxLength:"256",type:"text",autoComplete:"off",value:e.sender_email,onChange:this.handleInputChange,placeholder:this.translate("Sender email"),disabled:this.isProcessing()}),t?.hasError("sender_email")&&n.createElement("div",{className:"error-message"},!e.sender_email||t.hasError("sender_email","required")?n.createElement(f.x6,null,"Sender email is required"):n.createElement(f.x6,null,"Sender email must be a valid email")),n.createElement("p",null,n.createElement(f.x6,null,"This is the email address users will see in their mail box when passbolt sends a notification.",n.createElement("br",null),"It's a good practice to provide a working email address that users can reply to.")))))),r&&n.createElement("div",{className:"warning message"},this.shouldShowSourceWarningMessage()&&n.createElement("div",{id:"smtp-settings-source-warning"},n.createElement(f.x6,null,"These are the settings provided by a configuration file. If you save it, will ignore the settings on file and use the ones from the database.")),i&&n.createElement("div",null,n.createElement("p",null,n.createElement(f.x6,null,"Don't forget to save your settings to apply your modification."))))),n.createElement(Ao,null)),Xa(n.createElement(n.Fragment,null,n.createElement("div",{className:"sidebar-help-section",id:"smtp-settings-source"},n.createElement("h3",null,n.createElement(f.x6,null,"Configuration source")),n.createElement("p",null,n.createElement(f.x6,null,"This current configuration source is: "),this.configurationSource,".")),n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"Why do I need an SMTP server?")),n.createElement("p",null,n.createElement(f.x6,null,"Passbolt needs an smtp server in order to send invitation emails after an account creation and to send email notifications.")),n.createElement("a",{className:"button",href:"https://passbolt.com/docs/admin/emails/email-server/",target:"_blank",rel:"noopener noreferrer"},n.createElement(ps,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),a&&"other"!==a.id&&n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"How do I configure a ",{smtpProviderName:s}," SMTP server?")),n.createElement("a",{className:"button",href:a.help_page,target:"_blank",rel:"noopener noreferrer"},n.createElement(Po,null),n.createElement("span",null,n.createElement(f.x6,null,"See the ",{smtpProviderName:s}," documentation")))),e?.provider&&("google-mail"===e.provider||"google-workspace"===e.provider)&&n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"Why shouldn't I use my login password ?")),n.createElement("p",null,n.createElement(f.x6,null,'In order to use the "Username & Password" authentication method with Google, you will need to enable MFA on your Google Account. The password should not be your login password, you have to create an "App Password" generated by Google.. However, the email remain the same.')),n.createElement("a",{className:"button",href:"https://support.google.com/mail/answer/185833",target:"_blank",rel:"noopener noreferrer"},n.createElement(ps,null),n.createElement("span",null,n.createElement(f.x6,null,"More informations"))))),document.getElementById("administration-help-panel")))}}Fo.propTypes={context:i().object,dialogContext:i().any,administrationWorkspaceContext:i().object,adminSmtpSettingsContext:i().object,t:i().func};const jo=N(fo(h(Ne((0,f.CI)("common")(Fo))))),Lo=class{static clone(e){return new Map(JSON.parse(JSON.stringify(Array.from(e))))}static iterators(e){return[...e.keys()]}static listValues(e){return[...e.values()]}},qo=class{constructor(e){this.apiClientOptions=e}async find(){this.initClient();const e=await this.apiClient.findAll(),t=e?.body;return t}async save(e){this.initClient(),await this.apiClient.create(e)}async delete(e){this.initClient(),await this.apiClient.delete(e)}async checkDomainAllowed(e){this.initClient("dry-run"),await this.apiClient.create(e)}initClient(e="settings"){this.apiClientOptions.setResourceName(`self-registration/${e}`),this.apiClient=new pt(this.apiClientOptions)}},zo=class{constructor(e={}){this.allowedDomains=this.mapAllowedDomains(e.data?.allowed_domains||[])}mapAllowedDomains(e){return new Map(e.map(e=>[(0,r.A)(),e]))}getSettings(){return this.allowedDomains}setSettings(e){this.allowedDomains=this.mapAllowedDomains(e)}},Ko=class{constructor(e,t={}){this.id=t.id,this.provider=t.provider||"email_domains",this.data=this.mapData(e?.allowedDomains)}mapData(e=new Map){return{allowed_domains:Array.from(e.values())}}},Vo=class{constructor(e){this.translate=e,this.fields=new Map}validate(e){return this.fields=e,this.validateInputs()}validateInputs(){const e=new Map;return this.fields.forEach((t,a)=>{this.validateInput(a,t,e)}),e}validateInput(e,t,a){if(t.length)try{eo.checkDomainValidity(t)}catch{a.set(e,this.translate("This should be a valid domain"))}else a.set(e,this.translate("A domain is required."));this.checkDuplicateValue(a)}checkDuplicateValue(e){this.fields.forEach((t,a)=>{Lo.listValues(this.fields).filter(e=>e===t&&""!==e).length>1&&e.set(a,this.translate("This domain already exist"))})}};class Go extends n.Component{constructor(e){super(e),this.bindCallbacks()}bindCallbacks(){this.handleSubmit=this.handleSubmit.bind(this),this.handleClose=this.handleClose.bind(this)}handleClose(){this.props.onClose()}async handleSubmit(e){e.preventDefault(),await this.props.onSubmit(),this.props.onClose()}get allowedDomains(){return this.props.adminSelfRegistrationContext.getAllowedDomains()}render(){const e=this.props.adminSelfRegistrationContext.isProcessing();return n.createElement(qt,{title:this.props.t("Save self registration settings"),onClose:this.handleClose,disabled:e,className:"save-self-registration-settings-dialog"},n.createElement("form",{onSubmit:this.handleSubmit},n.createElement("div",{className:"form-content"},n.createElement("label",null,n.createElement(f.x6,null,"Allowed domains")),n.createElement("div",{className:"radiolist-alt"},n.createElement("div",{className:"input radio"},n.createElement("ul",{id:"domains-list"},this.allowedDomains&&Lo.iterators(this.allowedDomains).map(e=>n.createElement("li",{key:e},this.allowedDomains.get(e)))))),n.createElement("div",{className:"warning message no-margin"},n.createElement(f.x6,null,"Please review carefully this configuration."))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement(gn,{onClick:this.handleClose,disabled:e}),n.createElement(qs,{value:this.props.t("Save"),disabled:e,processing:e,warning:!0}))))}}Go.propTypes={context:i().any,onSubmit:i().func,adminSelfRegistrationContext:i().object,onClose:i().func,t:i().func};const Bo=N(Xo((0,f.CI)("common")(Go)));class Wo extends n.Component{constructor(e){super(e),this.bindCallbacks()}bindCallbacks(){this.handleSubmit=this.handleSubmit.bind(this),this.handleClose=this.handleClose.bind(this)}handleClose(){this.props.onClose()}async handleSubmit(e){e.preventDefault(),await this.props.onSubmit(),this.props.onClose()}render(){const e=this.props.adminSelfRegistrationContext.isProcessing();return n.createElement(qt,{title:this.props.t("Disable self registration"),onClose:this.handleClose,disabled:e,className:"delete-self-registration-settings-dialog"},n.createElement("form",{onSubmit:this.handleSubmit},n.createElement("div",{className:"form-content"},n.createElement("div",null,n.createElement("p",null,n.createElement(f.x6,null,"Are you sure to disable the self registration for the organization ?")),n.createElement("p",null,n.createElement(f.x6,null,"Users will not be able to self register anymore.")," ",n.createElement(f.x6,null,"Only administrators would be able to invite users to register. ")))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement(gn,{onClick:this.handleClose,disabled:e}),n.createElement(qs,{value:this.props.t("Save"),disabled:e,processing:e,warning:!0}))))}}Wo.propTypes={adminSelfRegistrationContext:i().object,onClose:i().func,onSubmit:i().func,t:i().func};const Ho=Xo((0,f.CI)("common")(Wo));function $o(){return $o=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},getAllowedDomains:()=>{},setAllowedDomains:()=>{},hasSettingsChanges:()=>{},setDomains:()=>{},findSettings:()=>{},setProcessing:()=>{},isProcessing:()=>{},clearContext:()=>{},isSubmitted:()=>{},setSubmitted:()=>{},setErrors:()=>{},getErrors:()=>{},setError:()=>{},save:()=>{},delete:()=>{},shouldFocus:()=>{},setFocus:()=>{},isSaved:()=>{},setSaved:()=>{},validateForm:()=>{}});class Zo extends n.Component{constructor(e){super(e),this.state=this.defaultState;const t=e.context.getApiClientOptions();this.selfRegistrationService=new qo(t),this.selfRegistrationFormService=new Vo(this.props.t)}get defaultState(){return{errors:new Map,submitted:!1,currentSettings:null,focus:!1,saved:!1,domains:new zo,processing:!0,getCurrentSettings:this.getCurrentSettings.bind(this),getAllowedDomains:this.getAllowedDomains.bind(this),setAllowedDomains:this.setAllowedDomains.bind(this),setDomains:this.setDomains.bind(this),findSettings:this.findSettings.bind(this),hasSettingsChanges:this.hasSettingsChanges.bind(this),isProcessing:this.isProcessing.bind(this),setProcessing:this.setProcessing.bind(this),clearContext:this.clearContext.bind(this),isSubmitted:this.isSubmitted.bind(this),setSubmitted:this.setSubmitted.bind(this),getErrors:this.getErrors.bind(this),setError:this.setError.bind(this),setErrors:this.setErrors.bind(this),save:this.save.bind(this),shouldFocus:this.shouldFocus.bind(this),setFocus:this.setFocus.bind(this),isSaved:this.isSaved.bind(this),setSaved:this.setSaved.bind(this),deleteSettings:this.deleteSettings.bind(this),validateForm:this.validateForm.bind(this)}}async findSettings(e=()=>{}){this.setProcessing(!0);const t=await this.selfRegistrationService.find();this.setState({currentSettings:t});const a=new zo(t);return this.setDomains(a,e),this.setProcessing(!1),a}getCurrentSettings(){return this.state.currentSettings}getAllowedDomains(){return this.state.domains.allowedDomains}setAllowedDomains(e,t,a=()=>{}){this.setState(a=>{const n=Lo.clone(a.domains.allowedDomains);return n.set(e,t),{domains:{allowedDomains:n}}},a)}setDomains(e,t=()=>{}){this.setState({domains:e},t)}isProcessing(){return this.state.processing}setProcessing(e){this.setState({processing:e})}isSubmitted(){return this.state.submitted}setSubmitted(e){this.setState({submitted:e}),this.setFocus(e)}getErrors(){return this.state.errors}shouldFocus(){return this.state.focus}setFocus(e){this.setState({focus:e})}setError(e,t){const a=Lo.clone(this.state.errors);a.set(e,t),this.setState({errors:a})}setErrors(e){this.setState({errors:e})}hasSettingsChanges(){const e=this.state.currentSettings?.data?.allowed_domains||[],t=Lo.listValues(this.state.domains.allowedDomains);return JSON.stringify(e)!==JSON.stringify(t)}clearContext(){const{currentSettings:e,domains:t,processing:a}=this.defaultState;this.setState({currentSettings:e,domains:t,processing:a})}save(){this.setSubmitted(!0),this.validateForm()&&(this.hasSettingsChanges()&&0===this.getAllowedDomains().size?this.displayConfirmDeletionDialog():this.displayConfirmSummaryDialog())}validateForm(){const e=this.selfRegistrationFormService.validate(this.state.getAllowedDomains());return this.state.setErrors(e),0===e.size}async handleSubmitError(e){"UserAbortsOperationError"!==e.name&&(console.error(e),await this.handleError(e))}async saveSettings(){try{this.setProcessing(!0);const e=new Ko(this.state.domains,this.state.currentSettings);await this.selfRegistrationService.save(e),await this.findSettings(()=>this.setSaved(!0)),await this.props.actionFeedbackContext.displaySuccess(this.props.t("The self registration settings for the organization were updated."))}catch(e){this.handleSubmitError(e)}finally{this.setProcessing(!1),this.setSubmitted(!1)}}async handleError(e){this.handleCloseDialog();const t={error:e};this.props.dialogContext.open($t,t)}handleCloseDialog(){this.props.dialogContext.close()}displayConfirmSummaryDialog(){this.props.dialogContext.open(Bo,{domains:this.getAllowedDomains(),onSubmit:()=>this.saveSettings(),onClose:()=>this.handleCloseDialog()})}displayConfirmDeletionDialog(){this.props.dialogContext.open(Ho,{onSubmit:()=>this.deleteSettings(),onClose:()=>this.handleCloseDialog()})}async deleteSettings(){try{this.setProcessing(!0),await this.selfRegistrationService.delete(this.state.currentSettings.id),await this.findSettings(),await this.props.actionFeedbackContext.displaySuccess(this.props.t("The self registration settings for the organization were updated."))}catch(e){this.handleSubmitError(e)}finally{this.setProcessing(!1),this.setSubmitted(!1)}}isSaved(){return this.state.saved}setSaved(e){return this.setState({saved:e})}render(){return n.createElement(Yo.Provider,{value:this.state},this.props.children)}}Zo.propTypes={context:i().any,children:i().any,t:i().any,dialogContext:i().any,actionFeedbackContext:i().object};const Jo=N(h(m((0,f.CI)("common")(Zo))));function Xo(e){return class extends n.Component{render(){return n.createElement(Yo.Consumer,null,t=>n.createElement(e,$o({adminSelfRegistrationContext:t},this.props)))}}}const Qo=new Map;function el(e){if("string"!=typeof e)return console.warn("useDynamicRefs: Cannot set ref without key");const t=n.createRef();return Qo.set(e,t),t}function tl(e){return e?Qo.get(e):console.warn("useDynamicRefs: Cannot get ref without key")}var al=a(6459),nl=a.n(al);class sl extends n.Component{constructor(e){super(e),this.bindCallbacks()}bindCallbacks(){this.handleSave=this.handleSave.bind(this)}get allowedDomains(){return this.props.adminSelfRegistrationContext.getAllowedDomains()}isSaveEnabled(){let e=!1;return this.props.adminSelfRegistrationContext.getCurrentSettings()?.provider||(e=!this.props.adminSelfRegistrationContext.hasSettingsChanges()),!this.props.adminSelfRegistrationContext.isProcessing()&&!e}async handleSave(){this.isSaveEnabled()&&this.props.adminSelfRegistrationContext.save()}render(){return n.createElement("div",{className:"actions-wrapper"},n.createElement("button",{className:"button primary form",type:"button",disabled:!this.isSaveEnabled(),id:"save-settings",onClick:this.handleSave},n.createElement("span",null,n.createElement(f.x6,null,"Save"))))}}sl.propTypes={adminSelfRegistrationContext:i().object,t:i().func};const il=(0,f.CI)("common")(Xo(sl));var rl;function ol(){return ol=Object.assign?Object.assign.bind():function(e){for(var t=1;tthis.assertNotProfessionalDomains(this.allowedDomains),300),this.bindCallbacks()}async componentDidMount(){await this.findSettings()}componentDidUpdate(){this.shouldFocusOnError(),this.shouldCheckWarnings()}componentWillUnmount(){this.props.administrationWorkspaceContext.resetDisplayAdministrationWorkspaceAction(),this.props.adminSelfRegistrationContext.clearContext()}get defaultState(){return{isEnabled:!1,warnings:new Map}}bindCallbacks(){this.handleToggleClicked=this.handleToggleClicked.bind(this),this.handleAddRowClick=this.handleAddRowClick.bind(this),this.handleInputChange=this.handleInputChange.bind(this),this.handleDeleteRow=this.handleDeleteRow.bind(this)}get currentUser(){return this.props.context.loggedInUser}get allowedDomains(){return this.props.adminSelfRegistrationContext.getAllowedDomains()}async findSettings(){const e=await this.props.adminSelfRegistrationContext.findSettings();this.setState({isEnabled:e.allowedDomains?.size>0}),this.assertNotProfessionalDomains(e.allowedDomains),this.validateForm()}assertNotProfessionalDomains(e){const t=new Map;e?.forEach((e,a)=>{eo.isProfessional(e)||t.set(a,"This is not a safe professional domain")}),this.setState({warnings:t})}setupSettings(){const e=new zo(this.props.adminSelfRegistrationContext.getCurrentSettings());if(this.props.adminSelfRegistrationContext.setDomains(e),this.assertNotProfessionalDomains(e.allowedDomains),0===e.allowedDomains.size){const e=eo.extractDomainFromEmail(this.currentUser?.username);eo.checkDomainValidity(e),this.populateUserDomain(e)}}shouldFocusOnError(){const e=this.props.adminSelfRegistrationContext.shouldFocus(),[t]=this.props.adminSelfRegistrationContext.getErrors().keys();t&&e&&(this.dynamicRefs.getRef(t).current.focus(),this.props.adminSelfRegistrationContext.setFocus(!1))}shouldCheckWarnings(){this.props.adminSelfRegistrationContext.isSaved()&&(this.props.adminSelfRegistrationContext.setSaved(!1),this.assertNotProfessionalDomains(this.allowedDomains))}populateUserDomain(e){const t=eo.isProfessional(e)?e:"";this.addRow(t)}addRow(e=""){const t=(0,r.A)();this.props.adminSelfRegistrationContext.setAllowedDomains(t,e,()=>{const e=this.dynamicRefs.getRef(t);e?.current.focus()})}handleDeleteRow(e){if(this.canDelete()){const t=this.allowedDomains;t.delete(e),this.props.adminSelfRegistrationContext.setDomains({allowedDomains:t}),this.validateForm(),this.assertNotProfessionalDomains(t)}}hasWarnings(){return this.state.warnings.size>0}hasAllInputDisabled(){return this.props.adminSelfRegistrationContext.isProcessing()}handleToggleClicked(){const e=!this.state.isEnabled;e?this.setupSettings():(this.props.adminSelfRegistrationContext.setDomains({allowedDomains:new Map}),this.props.adminSelfRegistrationContext.setErrors(new Map)),this.setState({isEnabled:e})}handleAddRowClick(){this.addRow()}handleInputChange(e){const t=e.target.value,a=e.target.name;this.props.adminSelfRegistrationContext.setAllowedDomains(a,t,()=>this.validateForm()),this.checkForPublicDomainDebounce()}validateForm(){this.props.adminSelfRegistrationContext.validateForm()}canDelete(){return this.allowedDomains.size>1}render(){const e=this.props.adminSelfRegistrationContext.isSubmitted(),t=this.props.adminSelfRegistrationContext.getErrors();return n.createElement("div",{className:"row"},n.createElement(n.Fragment,null,n.createElement("div",{className:"self-registration main-column"},n.createElement("div",{className:"main-content"},n.createElement("h3",null,n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"settings-toggle",onChange:this.handleToggleClicked,checked:this.state.isEnabled,disabled:this.hasAllInputDisabled(),id:"settings-toggle"}),n.createElement("label",{htmlFor:"settings-toggle"},n.createElement(f.x6,null,"Self Registration")))),!this.state.isEnabled&&n.createElement("p",{className:"description",id:"disabled-description"},n.createElement(f.x6,null,"User self registration is disabled.")," ",n.createElement(f.x6,null,"Only administrators can invite users to register.")),this.state.isEnabled&&n.createElement("div",{className:"self-registration-form"},n.createElement("div",{id:"self-registration-subtitle",className:`input ${this.hasWarnings()&&"warning"} ${e&&t.size>0&&"error"}`},n.createElement("label",{id:"enabled-label"},n.createElement(f.x6,null,"Email domain safe list"))),n.createElement("p",{className:"description",id:"enabled-description"},n.createElement(f.x6,null,"All the users with an email address ending with the domain in the safe list are allowed to register on passbolt.")),Lo.iterators(this.allowedDomains).map(a=>n.createElement("div",{key:a,className:"input"},n.createElement("div",{className:"domain-row"},n.createElement("input",{type:"text",className:"full-width",onChange:this.handleInputChange,id:`input-${a}`,name:a,value:this.allowedDomains.get(a),disabled:!this.hasAllInputDisabled,ref:this.dynamicRefs.setRef(a),placeholder:this.props.t("domain")}),n.createElement("button",{type:"button",disabled:!this.canDelete(),className:"button-icon",id:`delete-${a}`,onClick:()=>this.handleDeleteRow(a)},n.createElement(dl,null))),this.hasWarnings()&&this.state.warnings.get(a)&&n.createElement("div",{id:"domain-name-input-feedback",className:"warning-message"},n.createElement(f.x6,null,this.state.warnings.get(a))),t.get(a)&&e&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,t.get(a))))),n.createElement("div",{className:"domain-add"},n.createElement("button",{type:"button",onClick:this.handleAddRowClick},n.createElement(ll,null),n.createElement("span",null,n.createElement(f.x6,null,"Add")))))),this.props.adminSelfRegistrationContext.hasSettingsChanges()&&n.createElement("div",{className:"warning message",id:"self-registration-setting-overridden-banner"},n.createElement("div",null,n.createElement("p",null,n.createElement(f.x6,null,"Don't forget to save your settings to apply your modification."))))),n.createElement(il,null)),Xa(n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"What is user self registration?")),n.createElement("p",null,n.createElement(f.x6,null,"User self registration enables users with an email from a whitelisted domain to create their passbolt account without prior admin invitation.")),n.createElement("a",{className:"button",href:"https://passbolt.com/docs/admin/user-provisioning/self-registration/",target:"_blank",rel:"noopener noreferrer"},n.createElement(ps,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}ul.propTypes={dialogContext:i().any,context:i().any,adminSelfRegistrationContext:i().object,administrationWorkspaceContext:i().object,t:i().func};const pl=N(h(Xo(Ne((0,f.CI)("common")(ul))))),hl=[{id:"azure",name:"Microsoft",icon:n.createElement("svg",{width:"65",height:"64",viewBox:"0 0 65 64",fill:"none",xmlns:"http://www.w3.org/2000/svg"},n.createElement("path",{d:"M31.3512 3.04762H3.92261V30.4762H31.3512V3.04762Z",fill:"#F25022"}),n.createElement("path",{d:"M31.3512 33.5238H3.92261V60.9524H31.3512V33.5238Z",fill:"#00A4EF"}),n.createElement("path",{d:"M61.8274 3.04762H34.3988V30.4762H61.8274V3.04762Z",fill:"#7FBA00"}),n.createElement("path",{d:"M61.8274 33.5238H34.3988V60.9524H61.8274V33.5238Z",fill:"#FFB900"})),defaultConfig:{url:"https://login.microsoftonline.com",client_id:"",client_secret:"",tenant_id:"",client_secret_expiry:"",prompt:"login",email_claim:"email",login_hint:!0}},{id:"google",name:"Google",icon:n.createElement("svg",{width:"65",height:"64",viewBox:"0 0 65 64",fill:"none",xmlns:"http://www.w3.org/2000/svg"},n.createElement("path",{d:"M63.9451 32.72C63.9451 30.6133 63.7584 28.6133 63.4384 26.6667H33.3051V38.6933H50.5584C49.7851 42.64 47.5184 45.9733 44.1584 48.24V56.24H54.4517C60.4784 50.6667 63.9451 42.4533 63.9451 32.72Z",fill:"#4285F4"}),n.createElement("path",{d:"M33.305 64C41.945 64 49.1717 61.12 54.4517 56.24L44.1583 48.24C41.2783 50.16 37.625 51.3333 33.305 51.3333C24.9583 51.3333 17.8917 45.7067 15.3583 38.1067H4.745V46.3467C9.99833 56.8 20.7983 64 33.305 64Z",fill:"#34A853"}),n.createElement("path",{d:"M15.3584 38.1067C14.6917 36.1867 14.3451 34.1333 14.3451 32C14.3451 29.8667 14.7184 27.8133 15.3584 25.8933V17.6533H4.74505C2.55838 21.9733 1.30505 26.8267 1.30505 32C1.30505 37.1733 2.55838 42.0267 4.74505 46.3467L15.3584 38.1067Z",fill:"#FBBC05"}),n.createElement("path",{d:"M33.305 12.6667C38.025 12.6667 42.2383 14.2933 45.5717 17.4667L54.6917 8.34667C49.1717 3.17334 41.945 0 33.305 0C20.7983 0 9.99833 7.20001 4.745 17.6533L15.3583 25.8933C17.8917 18.2933 24.9583 12.6667 33.305 12.6667Z",fill:"#EA4335"})),defaultConfig:{client_id:"",client_secret:""}},{id:"oauth2",name:"OpenID",hiddenIfDisabled:!0,disabledForRecover:!0,icon:n.createElement("svg",{width:"65",height:"60",viewBox:"0 0 65 60",fill:"none",xmlns:"http://www.w3.org/2000/svg"},n.createElement("path",{d:"M64.2468 34.9929L62.9089 21.0968L57.9256 23.9083C53.2914 21.0968 47.3581 19.1061 40.7332 18.3046V24.4577C44.5336 25.117 47.9462 26.3321 50.7513 27.9544L45.5031 30.9146L64.2533 34.9929H64.2468Z",fill:"#B3B3B3"}),n.createElement("path",{d:"M9.94184 38.8774C9.94184 32.0069 17.4264 26.2222 27.632 24.4577V18.2981C12.023 20.1854 0.246826 28.6783 0.246826 38.8774C0.246826 49.0766 12.8891 58.1769 29.3319 59.6312V53.5557C18.2666 52.166 9.94184 46.1228 9.94184 38.8774Z",fill:"#B3B3B3"}),n.createElement("path",{d:"M29.332 5.09999V59.6377L39.027 55.0746V0.362366L29.332 5.09999Z",fill:"#F8931E"})),defaultConfig:{url:"",openid_configuration_path:"",scope:"openid email profile",client_id:"",client_secret:""}},{id:"adfs",name:"AD FS",hiddenIfDisabled:!0,disabledForRecover:!0,icon:n.createElement("svg",{width:"65",height:"64",viewBox:"0 0 65 64",fill:"none",xmlns:"http://www.w3.org/2000/svg"},n.createElement("path",{d:"M64.5443 48.7454V62.166C64.5443 63.7378 64.0607 64.0602 62.5695 63.8184C52.5746 62.3272 42.4587 60.957 32.3831 59.5464C30.5695 59.3046 29.9247 58.6597 29.9247 56.6849C30.0859 49.5514 30.0053 42.3776 29.9247 35.1635C29.9247 33.5917 30.4083 33.1081 31.9801 33.1081C42.2975 33.1887 52.4536 33.1887 62.5695 33.1887C64.2219 33.1887 64.6249 33.8335 64.6249 35.3247C64.4637 39.8386 64.5443 44.2718 64.5443 48.7454Z",fill:"#00AAF2"}),n.createElement("path",{d:"M47.416 30.6093C42.3379 30.6093 37.2598 30.5287 32.1817 30.6093C30.6099 30.6093 29.9651 30.2869 29.9651 28.4733C30.0457 21.1786 30.0457 14.0048 29.9651 6.79069C29.9651 5.38011 30.4487 4.89648 31.7787 4.65467C42.1767 3.16349 52.5747 1.7126 62.9726 0.140816C64.7862 -0.100997 64.4638 1.10807 64.4638 2.11563C64.4638 8.56399 64.5444 15.1333 64.4638 21.5816C64.4638 23.9595 64.3832 26.3373 64.4638 28.7151C64.5444 30.2063 63.9802 30.6093 62.5696 30.6093C57.5721 30.5287 52.4941 30.6093 47.416 30.6093Z",fill:"#00AAF2"}),n.createElement("path",{d:"M13.8038 33.3096H25.1691C26.3782 33.3096 26.9021 33.7126 26.9021 34.962V57.37C26.9021 58.6597 26.3378 58.7806 25.1691 58.6597C17.6326 57.5312 10.096 56.4431 2.59981 55.3952C1.10863 55.1534 0.625 54.6698 0.625 53.098C0.705605 47.1332 0.705605 41.1685 0.625 35.0829C0.625 33.5917 1.02802 33.1887 2.51921 33.1887C6.34792 33.3096 10.0154 33.3096 13.8038 33.3096Z",fill:"#00AAF2"}),n.createElement("path",{d:"M13.8038 30.6093H2.59977C1.18919 30.6093 0.705566 30.1257 0.705566 28.6345C0.786171 22.7504 0.786171 16.8663 0.705566 10.9418C0.705566 9.53126 1.10859 9.04763 2.59977 8.80582C10.1363 7.83856 17.6728 6.7504 25.169 5.54133C26.902 5.29952 27.0633 5.86375 27.0633 7.27433V28.7151C27.0633 30.2869 26.4184 30.5287 25.0078 30.5287C21.2597 30.5287 17.4713 30.6093 13.8038 30.6093Z",fill:"#00AAF2"})),defaultConfig:{url:"",openid_configuration_path:"",scope:"openid email profile",client_id:"",client_secret:""}},{id:"pingone",name:"PingOne",hiddenIfDisabled:!0,icon:n.createElement("svg",{width:"64",height:"64",viewBox:"0 0 64 64",fill:"none",xmlns:"http://www.w3.org/2000/svg"},n.createElement("path",{d:"M0 0H64V64H0V0Z",fill:"#BB2631"}),n.createElement("path",{d:"M30.719 51.2024L31.6177 51.0748V57.6038H30.7179L30.719 51.2024ZM34.43 51.9678V56.1936C34.43 56.9602 34.5576 57.2154 35.2011 57.2154C35.4563 57.2154 35.3287 57.2154 35.5838 57.0878L35.7114 57.6038C35.4562 57.7313 35.3287 57.8589 34.946 57.8589C34.6851 57.8589 34.43 57.7313 34.1748 57.7313C33.7921 57.4762 33.6646 57.0878 33.6646 56.4499V51.9678H32.7647V51.2024H33.537V48.7717H34.43V51.2024H35.839L35.5838 51.9678H34.43ZM36.4837 33.7946C35.7125 33.7946 34.6863 34.3049 33.7933 35.2035V46.5916H29.9547V34.814C29.9547 33.4118 29.8271 32.1304 29.4387 30.9755L32.8946 29.9549C33.283 30.5927 33.4105 31.3593 33.4105 32.0029C34.0484 31.6201 34.4311 31.2317 35.0747 30.849C35.9123 30.4431 36.8287 30.2253 37.7594 30.2112C39.4235 30.2112 40.8325 31.1042 41.3439 32.512C41.6036 33.1499 41.6036 33.7946 41.6036 34.8151V46.5927H37.7594V36.0965C37.7594 34.3049 37.5042 33.7946 36.4837 33.7946ZM47.4901 35.7138C47.4901 34.1761 48.3831 33.2786 49.791 33.2786C51.3287 33.2786 52.0998 34.1773 52.0998 35.7138C52.0998 37.2504 51.2 38.0158 49.6646 38.0158C48.5164 38.0158 47.4901 37.378 47.4901 35.7138ZM51.3275 42.4979H49.2818C48.8991 42.4979 48.644 42.3703 48.644 42.1152C48.644 41.7279 49.1543 41.3441 50.1805 40.8338H50.8184C54.0191 40.8338 56.3211 38.7869 56.3211 35.969C56.3211 34.9427 56.0659 34.0497 55.4281 33.2786C55.6832 33.2786 56.0659 33.4118 56.4486 33.4118C57.4749 33.4118 58.3679 33.0234 59.139 32.258L57.476 29.5676C56.5762 30.4663 55.4281 30.9766 54.4018 30.9766C53.8915 30.9766 53.3767 30.849 52.6101 30.5939C51.5838 30.3387 50.8184 30.2112 49.9197 30.2112C46.0812 30.2112 43.6516 32.3856 43.6516 35.7127C43.6516 38.1434 44.6722 39.5524 46.8523 40.1902C44.417 40.8338 44.1619 41.8544 44.1619 42.8806C44.1619 44.0345 44.5446 44.6723 45.3157 45.0562C45.9536 45.3102 47.1074 45.571 48.8991 45.571H50.5621C52.0998 45.571 53.248 46.0813 53.248 47.4903C53.248 48.1282 52.8652 48.7717 52.3549 49.1556C51.7114 49.5383 50.946 49.6659 49.9197 49.6659C48.128 49.6659 47.1063 49.028 47.1063 47.619C47.1063 47.2363 47.1063 46.9755 47.235 46.5927H43.5229C43.3953 46.8467 43.1345 47.3627 43.1345 48.2557C43.1345 49.4107 43.5217 50.3037 44.4159 51.0748C45.6973 52.4838 47.8717 52.8665 50.0518 52.8665C52.3538 52.8665 54.6558 52.3562 55.9372 50.8197C56.7026 49.9199 57.0911 48.7729 57.0911 47.4914C57.0911 46.0825 56.7038 44.9286 55.8096 44.0345C54.7845 42.8806 53.6341 42.4979 51.3275 42.4979ZM41.9852 57.4762C41.6025 57.4762 41.3416 57.2142 41.3416 56.7051C41.3416 56.3224 41.6036 55.9396 41.9852 55.9396C42.3668 55.9396 42.623 56.1948 42.623 56.7051C42.623 57.0878 42.2403 57.4762 41.9852 57.4762ZM41.9852 55.6845C41.4749 55.6845 41.0865 56.0672 41.0865 56.5775C41.0865 57.0878 41.4738 57.4762 41.9852 57.4762C42.4966 57.4762 42.8782 57.0878 42.8782 56.5764C42.7518 56.1948 42.369 55.6845 41.9852 55.6845ZM41.73 56.5775V56.3224H41.8576C41.9852 56.3224 42.1128 56.3224 42.1128 56.4499C42.1128 56.5775 41.9852 56.5775 41.8576 56.5775H41.73ZM42.3679 56.4499C42.3679 56.1948 42.2415 56.1948 41.9863 56.1948H41.6025V57.2154H41.7312V56.7051H41.8588L42.1139 57.2154H42.2415L41.9863 56.7051C42.2403 56.7051 42.3679 56.7051 42.3679 56.4499ZM41.6025 51.2024L39.5499 57.8589C39.1672 59.1403 38.6569 60.0333 37.6307 60.2885L37.3755 59.6506C37.8858 59.3955 38.2754 59.1403 38.5294 58.4968C38.4018 57.8589 38.4018 57.7313 38.4018 57.7313C38.2742 57.3486 38.0145 56.0672 37.7582 55.4237L36.4825 51.33L37.3755 50.9473L38.5294 55.1685C38.6569 55.8121 38.9121 56.8327 38.9121 56.8327C38.9121 56.8327 39.1672 56.0672 39.2948 55.4237L40.4486 51.2024H41.6025ZM13.4387 55.9385C13.4387 55.9385 13.3112 56.1936 13.056 56.4488C12.6733 56.7039 12.4125 56.8315 11.9022 56.8315C11.3919 56.8315 11.0092 56.5764 10.7483 56.0661C10.5701 55.5297 10.4838 54.9671 10.4932 54.402C10.4932 53.5021 10.6208 52.993 10.8816 52.4827C11.1368 52.0943 11.5195 51.8391 11.9022 51.8391C12.5457 51.8391 13.056 52.0943 13.3112 52.4827L13.4387 55.9385ZM14.3374 48.7706H13.4387V51.9667C13.2651 51.7225 13.0339 51.525 12.7657 51.3915C12.4975 51.258 12.2005 51.1926 11.901 51.2013C11.5198 51.2013 11.1356 51.3288 10.7483 51.584C9.98291 52.2218 9.6002 53.247 9.6002 54.5295C9.6002 56.5764 10.4932 57.8578 11.9022 57.8578C12.5446 57.8585 13.0572 57.6015 13.4399 57.0867C13.4399 57.4739 13.5663 57.7302 13.5663 57.7302H14.4661C14.3374 57.3475 14.3374 56.7039 14.3374 55.6834V48.7706ZM28.2895 51.2013H29.826L29.4376 51.9667H28.1619V56.1925C28.1619 56.9591 28.2895 57.2142 28.9273 57.2142C29.1825 57.2142 29.0549 57.2142 29.31 57.0867L29.4376 57.6026C29.1825 57.7302 29.0549 57.8578 28.6722 57.8578C28.417 57.8578 28.1619 57.7302 27.9067 57.7302C27.5183 57.4751 27.3908 57.0867 27.3908 56.4488V51.9667H26.6253V51.2013H27.3908V48.7706H28.2895V51.2013ZM22.7856 30.7203L26.6242 30.0825V46.5905H22.7856V30.7203ZM22.3984 25.9819C22.3984 24.5729 23.5511 23.4248 24.8325 23.4248C26.1082 23.4248 27.1356 24.5729 27.1356 25.9819C27.1356 27.3909 26.1093 28.6723 24.7049 28.6723C23.4246 28.6723 22.3984 27.5185 22.3984 25.9819ZM25.5979 51.9667C25.7266 52.2218 25.7266 52.4827 25.7266 52.7378V57.6015H24.8336V53.2504C24.8336 52.6125 24.8336 52.3574 24.5785 52.2241C24.4011 52.0653 24.1729 51.9749 23.9349 51.969C23.4246 51.969 22.7868 52.3563 22.2708 52.8677V57.6049H21.3767V52.6125C21.3767 51.7127 21.1215 51.2036 21.1215 51.2036L22.0157 50.9484C22.0157 50.9484 22.2708 51.4587 22.2708 51.969C22.9144 51.3311 23.4246 50.9484 24.0625 50.9484C24.8336 51.076 25.3439 51.4587 25.5991 51.969M16.6394 53.7607C16.6394 52.485 17.1497 51.7138 17.9208 51.7138C18.3035 51.7138 18.8138 51.969 18.9414 52.2241C19.1966 52.7401 19.1965 53.1228 19.3298 53.7607H16.6394ZM18.0484 50.9473C17.4049 50.9473 16.767 51.2035 16.2567 51.8414C15.7407 52.485 15.6132 53.2504 15.6132 54.2767C15.6132 56.4511 16.6394 57.7325 18.176 57.7325C18.9414 57.7325 19.585 57.4773 20.0952 56.9614L19.7125 56.3235C19.3298 56.7062 18.8138 56.9614 18.3036 56.9614C17.6657 56.9614 17.1497 56.7062 16.8946 56.1959C16.6394 55.8132 16.6394 55.4248 16.6394 54.7869V54.6594H20.2228V54.5318C20.2228 52.9941 20.0953 52.3562 19.585 51.8414C19.1977 51.2035 18.6863 50.9484 18.0484 50.9484M7.42578 57.6049H8.31878V48.6453H7.42578V57.6049ZM16.2567 33.7957C15.7407 34.6887 15.2316 34.9438 13.5663 34.9438H11.3919V28.2873H13.949C15.6132 28.2873 16.6394 29.5687 16.6394 31.6213C16.767 32.6419 16.6394 33.2797 16.2567 33.7957ZM18.3036 25.7291C17.1497 25.0912 16.1291 24.7039 12.6733 24.7039H7.42578V46.7215H11.5195V38.6594H13.6939C15.874 38.6594 16.767 38.3985 17.6657 37.8882C19.8412 36.7344 21.1215 34.4324 21.1215 31.4869C21.2491 28.9298 20.2228 26.8829 18.3036 25.7291Z",fill:"white"})),defaultConfig:{url:"https://auth.pingone.com",environment_id:"",client_id:"",client_secret:"",email_claim:"email"}}],gl="form",yl="success";class bl extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.bindCallbacks()}get defaultState(){return{uiState:gl,hasSuccessfullySignedInWithSso:!1,processing:!1,ssoToken:null}}bindCallbacks(){this.handleSignInTestClick=this.handleSignInTestClick.bind(this),this.handleActivateSsoSettings=this.handleActivateSsoSettings.bind(this),this.handleCloseDialog=this.handleCloseDialog.bind(this)}async handleSignInTestClick(e){e.preventDefault();try{this.setState({processing:!0});const e=await this.props.context.port.request("passbolt.sso.dry-run",this.props.configurationId);this.setState({uiState:yl,hasSuccessfullySignedInWithSso:!0,ssoToken:e})}catch(e){"UserAbortsOperationError"!==e?.name&&this.props.adminSsoContext.handleError(e)}this.setState({processing:!1})}async handleActivateSsoSettings(e){e.preventDefault();try{this.setState({processing:!0}),await this.props.context.port.request("passbolt.sso.activate-settings",this.props.configurationId,this.state.ssoToken),await this.props.context.port.request("passbolt.sso.generate-sso-kit",this.props.provider.id),this.props.onSuccessfulSettingsActivation(),await this.props.actionFeedbackContext.displaySuccess(this.props.t("The SSO settings have been saved successfully"))}catch(e){this.props.adminSsoContext.handleError(e)}this.setState({processing:!1}),this.handleCloseDialog()}handleCloseDialog(){this.props.onClose(),this.props.handleClose()}hasAllInputDisabled(){return this.state.processing}canSaveSettings(){return!this.hasAllInputDisabled()&&this.state.hasSuccessfullySignedInWithSso}get title(){return{form:this.translate("Test Single Sign-On configuration"),success:this.translate("Save Single Sign-On configuration")}[this.state.uiState]||""}get translate(){return this.props.t}render(){return n.createElement(qt,{className:"test-sso-settings-dialog sso-login-form",title:this.title,onClose:this.handleCloseDialog,disabled:this.hasAllInputDisabled()},n.createElement("form",{onSubmit:this.handleActivateSsoSettings},n.createElement("div",{className:"form-content"},this.state.uiState===gl&&n.createElement(n.Fragment,null,n.createElement("p",null,n.createElement(f.x6,null,"Before saving the settings, we need to test if the configuration is working.")),n.createElement("button",{type:"button",className:`sso-login-button ${this.props.provider.id}`,onClick:this.handleSignInTestClick,disabled:this.hasAllInputDisabled()},n.createElement("span",{className:"provider-logo"},this.props.provider.icon),this.translate("Sign in with {{providerName}}",{providerName:this.props.provider.name}))),this.state.uiState===yl&&n.createElement("p",null,this.translate("You successfully signed in with your {{providerName}} account. You can safely save your configuration.",{providerName:this.props.provider.name}))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement(gn,{disabled:this.hasAllInputDisabled(),onClick:this.handleCloseDialog}),n.createElement(qs,{disabled:!this.canSaveSettings(),processing:this.state.processing,value:this.translate("Save settings")}))))}}bl.propTypes={context:i().object,adminSsoContext:i().object,onClose:i().func,t:i().func,provider:i().object,configurationId:i().string,actionFeedbackContext:i().any,handleClose:i().func,onSuccessfulSettingsActivation:i().func};const fl=N($l(m((0,f.CI)("common")(bl))));class El extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.bindCallbacks()}get defaultState(){return{processing:!1}}bindCallbacks(){this.handleConfirmDelete=this.handleConfirmDelete.bind(this)}async handleConfirmDelete(e){e.preventDefault(),this.setState({processing:!0}),await this.props.adminSsoContext.deleteSettings(),this.setState({processing:!1}),this.props.onClose()}hasAllInputDisabled(){return this.state.processing}render(){const e=this.hasAllInputDisabled();return n.createElement(qt,{className:"delete-sso-settings-dialog",title:this.props.t("Disable Single Sign-On settings?"),onClose:this.props.onClose,disabled:e},n.createElement("form",{onSubmit:this.handleConfirmDelete,noValidate:!0},n.createElement("div",{className:"form-content"},n.createElement("p",null,n.createElement(f.x6,null,"Are you sure you want to disable the current Single Sign-On settings?")),n.createElement("p",null,n.createElement(f.x6,null,"This action cannot be undone. All the data associated with SSO will be permanently deleted."))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement(gn,{disabled:e,onClick:this.props.onClose}),n.createElement(qs,{warning:!0,disabled:e,processing:this.state.processing,value:this.props.t("Disable")}))))}}El.propTypes={adminSsoContext:i().object,onClose:i().func,t:i().func};const vl=$l((0,f.CI)("common")(El)),wl=["https://login.microsoftonline.com","https://login.microsoftonline.us","https://login.partner.microsoftonline.cn"];class kl extends se{constructor(e,t={}){const a=kl.sanitizeDto(e);super(ae.validate(kl.ENTITY_NAME,a,kl.getSchema()),t)}static getSchema(){return{type:"object",required:["url","client_id","tenant_id","client_secret","client_secret_expiry"],properties:{url:{type:"string",enum:wl},client_id:{type:"string",format:"uuid"},tenant_id:{type:"string",format:"uuid"},client_secret:{type:"string",minLength:1},client_secret_expiry:{type:"string",format:"date-time"},email_claim:{type:"string",enum:["email","preferred_username","upn"]},prompt:{type:"string",enum:["login","none"]},login_hint:{type:"boolean"}}}}static sanitizeDto(e){return e=Object.assign({},e),e?.email_claim||(e.email_claim="email"),e?.prompt||(e.prompt="login"),void 0===e.login_hint&&(e.login_hint=!0),e}static get ENTITY_NAME(){return"AzureSsoSettings"}static get PROVIDER_ID(){return"azure"}static get SUPPORTED_URLS(){return wl}}const _l=kl;class xl extends he{static getSchema(){return{type:"object",required:["url","client_id","tenant_id","client_secret","client_secret_expiry","email_claim","prompt","login_hint"],properties:{id:{type:"string",format:"uuid"},url:{type:"string"},client_id:{type:"string",format:"uuid"},tenant_id:{type:"string",format:"uuid"},client_secret:{type:"string",minLength:1},client_secret_expiry:{type:"string"},email_claim:{type:"string",enum:["email","preferred_username","upn"]},prompt:{type:"string",enum:["login","none"]},login_hint:{type:"boolean"}}}}marshall(){this._props.client_secret_expiry&&(this._props.client_secret_expiry=this._props.client_secret_expiry.toString().substring(0,10)),void 0===this._props.login_hint&&(this._props.login_hint=!0)}validate(e={}){this.marshall();let t=null;const a=e?.schema??this.cachedSchema;try{ae.validate(this.constructor.name,{...this._props},a)}catch(e){if(!(e instanceof X))throw e;t=e}return t||new X}get id(){return this._props.id}get url(){return this._props.url}get client_id(){return this._props.client_id}get tenant_id(){return this._props.tenant_id}get client_secret(){return this._props.client_secret}get client_secret_expiry(){return this._props.client_secret_expiry}get email_claim(){return this._props.email_claim}get prompt(){return this._props.prompt}get login_hint(){return this._props.login_hint}get provider(){return _l.PROVIDER_ID}toFormDto(){return{id:this._props.id,provider:this.provider,url:this._props.url??null,client_id:this._props.client_id??null,tenant_id:this._props.tenant_id??null,client_secret:this._props.client_secret??null,client_secret_expiry:this._props.client_secret_expiry??null,email_claim:this._props.email_claim??null,prompt:this._props.prompt??null,login_hint:this._props.login_hint??!0}}toEntityDto(){let e=this._props.client_secret_expiry;return e&&(e+=" 00:00:00"),{provider:this.provider,data:{url:this._props.url,client_id:this._props.client_id,tenant_id:this._props.tenant_id,client_secret:this._props.client_secret,client_secret_expiry:e,email_claim:this._props.email_claim,prompt:this._props.prompt,login_hint:this._props.login_hint}}}static fromEntityDto(e){const t=e.data,a={id:e?.id,url:t.url,client_id:t.client_id,tenant_id:t.tenant_id,client_secret:t.client_secret,client_secret_expiry:t.client_secret_expiry,email_claim:t.email_claim,prompt:t.prompt,login_hint:t.login_hint};return new xl(a,{validate:!1})}static createDefault(e={}){return new xl(e,{validate:!1})}static get ENTITY_NAME(){return"AzureSsoSettingsForm"}}const Sl=xl,Cl=/^https:\/\/.+[^/]$/;class Nl extends se{constructor(e,t={}){super(ae.validate(Nl.ENTITY_NAME,e,Nl.getSchema()),t)}static getSchema(){return{type:"object",required:["url","openid_configuration_path","scope","client_id","client_secret"],properties:{url:{type:"string",pattern:Cl},openid_configuration_path:{type:"string",minLength:1},scope:{type:"string",minLength:1},client_id:{type:"string",minLength:1},client_secret:{type:"string",minLength:1}}}}static get ENTITY_NAME(){return"OAuth2SsoSettings"}static get PROVIDER_ID(){return"oauth2"}}const Tl=Nl;class Al extends he{static getSchema(){const e=Tl.getSchema();return{...e,properties:{id:{type:"string"},...e.properties}}}get provider(){return Tl.PROVIDER_ID}get id(){return this._props.id||null}get url(){return this._props.url||null}get openid_configuration_path(){return this._props.openid_configuration_path||null}get scope(){return this._props.scope||null}get client_id(){return this._props.client_id||null}get client_secret(){return this._props.client_secret||null}validate(e={}){let t=null;const a=e?.schema??this.cachedSchema;try{ae.validate(this.constructor.name,{...this._props},a)}catch(e){if(!(e instanceof X))throw e;t=e}return t||new X}toFormDto(){return{id:this._props.id,url:this._props.url,openid_configuration_path:this._props.openid_configuration_path,scope:this._props.scope,client_id:this._props.client_id,client_secret:this._props.client_secret}}toEntityDto(){const e=this.toDto();return delete e.id,{provider:this.provider,data:{...e}}}static fromEntityDto({id:e,data:t}={}){const a={id:e,url:t.url,openid_configuration_path:t.openid_configuration_path,scope:t.scope,client_id:t.client_id,client_secret:t.client_secret};return new Al(a,{validate:!1})}static createDefault(e={}){return new Al(e,{validate:!1})}static get ENTITY_NAME(){return"OAuth2SsoSettingsForm"}}const Il=Al,Rl=["https://accounts.google.com"];class Pl extends se{constructor(e,t={}){super(ae.validate(Pl.ENTITY_NAME,e,Pl.getSchema()),t)}static getSchema(){return{type:"object",required:["client_id","client_secret"],properties:{client_id:{type:"string",minLength:1},client_secret:{type:"string",minLength:1}}}}static get ENTITY_NAME(){return"GoogleSsoSettings"}static get PROVIDER_ID(){return"google"}static get SUPPORTED_URLS(){return Rl}}const Dl=Pl;class Ol extends he{static getSchema(){const e=Dl.getSchema();return{...e,properties:{id:{type:"string",format:"uuid"},...e.properties}}}get provider(){return Dl.PROVIDER_ID}get id(){return this._props.id||null}get client_id(){return this._props.client_id||null}get client_secret(){return this._props.client_secret||null}validate(e={}){let t=null;const a=e?.schema??this.cachedSchema;try{ae.validate(this.constructor.name,{...this._props},a)}catch(e){if(!(e instanceof X))throw e;t=e}return t||new X}toFormDto(){return{id:this._props.id,client_id:this._props.client_id,client_secret:this._props.client_secret}}toEntityDto(){const e=this.toDto();return delete e.id,{provider:this.provider,data:{...e}}}static fromEntityDto({id:e,data:t}={}){const a={id:e,client_id:t.client_id,client_secret:t.client_secret};return new Ol(a,{validate:!1})}static createDefault(e={}){return new Ol(e,{validate:!1})}static get ENTITY_NAME(){return"GoogleSsoSettingsForm"}}const Ml=Ol,Ul=/^https:\/\/.+[^/]$/;class Fl extends se{constructor(e,t={}){super(ae.validate(Fl.ENTITY_NAME,e,Fl.getSchema()),t)}static getSchema(){return{type:"object",required:["url","openid_configuration_path","scope","client_id","client_secret"],properties:{url:{type:"string",pattern:Ul},openid_configuration_path:{type:"string",minLength:1},scope:{type:"string",minLength:1},client_id:{type:"string",minLength:1},client_secret:{type:"string",minLength:1}}}}static validateUrl(e){if("string"!=typeof e)throw new TypeError("The url should be a string.");let t;try{t=new URL(e)}catch(e){throw new Error("The url should be a valid url.",{cause:e})}if("https:"!==t.protocol)throw new Error("The url protocol should be HTTPS.")}static get ENTITY_NAME(){return"ADFSSsoSettings"}static get PROVIDER_ID(){return"adfs"}}const jl=Fl;class Ll extends he{static getSchema(){const e=jl.getSchema();return{type:"object",required:["url","openid_configuration_path","scope","client_id","client_secret"],properties:{id:{type:"string",format:"uuid"},url:e.properties.url,openid_configuration_path:e.properties.openid_configuration_path,scope:e.properties.scope,client_id:e.properties.client_id,client_secret:e.properties.client_secret}}}validate(e={}){const t=e?.schema??this.cachedSchema;let a=null;try{ae.validate(this.constructor.name,{...this._props},t)}catch(e){if(!(e instanceof X))throw e;a=e}return a||new X}get id(){return this._props.id}get url(){return this._props.url}get openid_configuration_path(){return this._props.openid_configuration_path}get scope(){return this._props.scope}get client_id(){return this._props.client_id}get client_secret(){return this._props.client_secret}get provider(){return jl.PROVIDER_ID}toFormDto(){return{id:this._props.id,provider:this.provider,url:this._props.url??null,openid_configuration_path:this._props.openid_configuration_path??null,scope:this._props.scope??null,client_id:this._props.client_id??null,client_secret:this._props.client_secret??null}}toEntityDto(){return{provider:this.provider,data:{url:this._props.url,openid_configuration_path:this._props.openid_configuration_path,scope:this._props.scope,client_id:this._props.client_id,client_secret:this._props.client_secret}}}static fromEntityDto(e){const t=e.data,a={id:e?.id,url:t.url,openid_configuration_path:t.openid_configuration_path,scope:t.scope,client_id:t.client_id,client_secret:t.client_secret};return new Ll(a,{validate:!1})}static createDefault(e={}){return new Ll(e,{validate:!1})}}const ql=Ll,zl=["https://auth.pingone.com","https://auth.pingone.eu","https://auth.pingone.ca","https://auth.pingone.asia","https://auth.pingone.com.au","https://auth.pingone.sg"],Kl=class extends he{static getSchema(){return{type:"object",required:["url","environment_id","client_id","client_secret","email_claim"],properties:{url:{type:"string",enum:zl},environment_id:{type:"string",minLength:1},client_id:{type:"string",minLength:1},client_secret:{type:"string",minLength:1},email_claim:{type:"string",minLength:1}}}}static get ENTITY_NAME(){return"PingOneSsoSettings"}static get PROVIDER_ID(){return"pingone"}static get SUPPORTED_URLS(){return zl}};class Vl extends he{static getSchema(){const e=Kl.getSchema();return{...e,properties:{id:{type:"string"},...e.properties}}}get provider(){return Kl.PROVIDER_ID}get id(){return this._props.id||null}get url(){return this._props.url||null}get environment_id(){return this._props.environment_id||null}get client_id(){return this._props.client_id||null}get client_secret(){return this._props.client_secret||null}get email_claim(){return this._props.email_claim||null}validate(e={}){let t=null;const a=e?.schema??this.cachedSchema;try{ae.validate(this.constructor.name,{...this._props},a)}catch(e){if(!(e instanceof X))throw e;t=e}return t||new X}toFormDto(){return{id:this._props.id,url:this._props.url,environment_id:this._props.environment_id,client_id:this._props.client_id,client_secret:this._props.client_secret,email_claim:this._props.email_claim}}toEntityDto(){const e=this.toDto();return delete e.id,{provider:this.provider,data:{...e}}}static fromEntityDto({id:e,data:t}={}){const a={id:e,url:t.url,environment_id:t.environment_id,client_id:t.client_id,client_secret:t.client_secret,email_claim:t.email_claim};return new Vl(a,{validate:!1})}static createDefault(e={}){return new Vl(e,{validate:!1})}static get SCOPE(){return"openid profile email"}static get ENTITY_NAME(){return"PingOneSsoSettingsForm"}}const Gl=Vl;function Bl(){return Bl=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},isProcessing:()=>{},loadSsoConfiguration:()=>{},getSsoConfiguration:()=>{},getProviderList:()=>{},isSsoConfigActivated:()=>{},isDataReady:()=>{},save:()=>{},disableSso:()=>{},hasFormChanged:()=>{},validateData:()=>{},saveAndTestConfiguration:()=>{},openTestDialog:()=>{},handleError:()=>{},getErrors:()=>{},deleteSettings:()=>{},showDeleteConfirmationDialog:()=>{}});class Hl extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.bindCallbacks(),this.isSsoConfigExisting=!1,this.shouldFocusOnError=!1,this.formSettings=null,this.originalSettings=null,this.cachedSsoConfig={}}get defaultState(){return{ssoConfig:null,providers:[],isLoaded:!1,processing:!1,hasBeenValidated:!1,hasFormChanged:this.hasFormChanged.bind(this),isProcessing:this.isProcessing.bind(this),isDataReady:this.isDataReady.bind(this),loadSsoConfiguration:this.loadSsoConfiguration.bind(this),getSsoConfiguration:this.getSsoConfiguration.bind(this),getProviderList:this.getProviderList.bind(this),isSsoConfigActivated:this.isSsoConfigActivated.bind(this),changeProvider:this.changeProvider.bind(this),disableSso:this.disableSso.bind(this),setValue:this.setValue.bind(this),validateData:this.validateData.bind(this),saveAndTestConfiguration:this.saveAndTestConfiguration.bind(this),handleError:this.handleError.bind(this),getErrors:this.getErrors.bind(this),deleteSettings:this.deleteSettings.bind(this),canDeleteSettings:this.canDeleteSettings.bind(this),showDeleteConfirmationDialog:this.showDeleteConfirmationDialog.bind(this),consumeFocusOnError:this.consumeFocusOnError.bind(this)}}bindCallbacks(){this.handleTestConfigCloseDialog=this.handleTestConfigCloseDialog.bind(this),this.handleSettingsActivation=this.handleSettingsActivation.bind(this)}validateForm=(0,po.A)(e=>this.formSettings?.validate());hasSettingsChanges=(0,po.A)((e,t)=>{try{return this.originalSettings?.hasDiffProps(this.formSettings)??!1}catch{return!0}});getSsoConfigDto(){return this.formSettings?{provider:this.formSettings.provider,...this.formSettings.toFormDto()}:null}async loadSsoConfiguration(){let e=null;try{e=await this.props.context.port.request("passbolt.sso.get-current")}catch(e){return this.props.dialogContext.open($t,{error:e}),{}}return this.isSsoConfigExisting=Boolean(e.provider),this.formSettings=this.getSsoProviderFormEntity(e),this.originalSettings=this.getSsoProviderFormEntity(e),this.setState({ssoConfig:this.getSsoConfigDto(),providers:e.providers,isLoaded:!0}),e}getSsoProviderFormEntity(e){if(!e?.provider)return null;switch(e.provider){case _l.PROVIDER_ID:return Sl.fromEntityDto(e);case Dl.PROVIDER_ID:return Ml.fromEntityDto(e);case Tl.PROVIDER_ID:return Il.fromEntityDto(e);case jl.PROVIDER_ID:return ql.fromEntityDto(e);case Kl.PROVIDER_ID:return Gl.fromEntityDto(e)}return null}getSsoConfiguration(){return this.state.ssoConfig}getProviderList(){return this.state.providers}getSsoConfigurationDto(){return this.formSettings.toEntityDto()}isSsoConfigActivated(){return Boolean(this.formSettings)}hasFormChanged(){return this.originalSettings&&this.formSettings?this.hasSettingsChanges(this.originalSettings.toFormDto(),this.formSettings.toFormDto()):null!==this.originalSettings&&null===this.formSettings||null===this.originalSettings&&null!==this.formSettings}setValue(e,t){this.formSettings.set(e,t,{validate:!1}),this.setState({ssoConfig:this.getSsoConfigDto()},()=>{this.state.hasBeenValidated&&this.validateData()})}disableSso(){this.formSettings&&(this.cachedSsoConfig[this.formSettings.provider]=this.formSettings),this.formSettings=null,this.setState({ssoConfig:null})}isDataReady(){return this.state.isLoaded}isProcessing(){return this.state.processing}changeProvider(e){e.disabled||(this.formSettings?.provider&&(this.cachedSsoConfig[this.formSettings.provider]=this.formSettings),this.formSettings=this.getCachedSsoConfigOrDefault(e.id),this.setState({ssoConfig:this.getSsoConfigDto()},()=>{this.state.hasBeenValidated&&this.validateData()}))}getCachedSsoConfigOrDefault(e){if(this.cachedSsoConfig[e])return this.cachedSsoConfig[e];const t=hl.find(t=>t.id===e),a={id:this.formSettings?.id,provider:e,data:t.defaultConfig};return this.getSsoProviderFormEntity(a)}validateData(e=!1){const t=this.validateForm(this.state.ssoConfig),a=Boolean(t?.hasErrors());return this.shouldFocusOnError=e&&a,this.setState({hasBeenValidated:!0}),!a}consumeFocusOnError(){const e=this.shouldFocusOnError;return this.shouldFocusOnError=!1,e}getErrors(){return this.state.hasBeenValidated?this.validateForm(this.state.ssoConfig):null}async saveAndTestConfiguration(){this.setState({processing:!0});const e=this.getSsoConfigurationDto();let t;try{t=await this.props.context.port.request("passbolt.sso.save-draft",e)}catch(e){return this.handleError(e),void this.setState({processing:!1})}await this.runTestConfig(t),this.formSettings=this.getSsoProviderFormEntity(t),this.setState({ssoConfig:this.getSsoConfigDto()})}canDeleteSettings(){return this.isSsoConfigExisting&&null===this.formSettings}showDeleteConfirmationDialog(){this.props.dialogContext.open(vl)}async deleteSettings(){this.setState({processing:!0});try{await this.props.context.port.request("passbolt.sso.delete-settings",this.originalSettings.id),this.props.actionFeedbackContext.displaySuccess(this.props.t("The SSO settings have been deleted successfully")),this.isSsoConfigExisting=!1,this.formSettings=null,this.originalSettings=null,this.setState({ssoConfig:null,processing:!1})}catch(e){this.handleError(e),this.setState({processing:!1})}}async runTestConfig(e){const t=hl.find(t=>t.id===e.provider);this.props.dialogContext.open(fl,{provider:t,configurationId:e.id,handleClose:this.handleTestConfigCloseDialog,onSuccessfulSettingsActivation:this.handleSettingsActivation})}handleTestConfigCloseDialog(){this.setState({processing:!1})}handleSettingsActivation(){this.isSsoConfigExisting=!0,this.originalSettings=this.getSsoProviderFormEntity({id:this.formSettings.id,provider:this.formSettings.provider,data:this.formSettings.toFormDto()})}handleError(e){console.error(e),this.props.dialogContext.open($t,{error:e})}render(){return n.createElement(Wl.Provider,{value:this.state},this.props.children)}}function $l(e){return class extends n.Component{render(){return n.createElement(Wl.Consumer,null,t=>n.createElement(e,Bl({adminSsoContext:t},this.props)))}}}Hl.propTypes={context:i().any,children:i().any,accountRecoveryContext:i().object,dialogContext:i().object,actionFeedbackContext:i().object,t:i().func},N(m(h((0,f.CI)("common")(Hl))));class Yl extends n.Component{constructor(e){super(e),this.bindCallbacks()}bindCallbacks(){this.handleSaveClick=this.handleSaveClick.bind(this)}async handleSaveClick(){const e=this.props.adminSsoContext;e.canDeleteSettings()?e.showDeleteConfirmationDialog():e.validateData(!0)&&await e.saveAndTestConfiguration()}isSaveEnabled(){return Boolean(this.props.adminSsoContext.ssoConfig?.provider)||this.props.adminSsoContext.canDeleteSettings()}render(){return n.createElement("div",{className:"actions-wrapper"},n.createElement("button",{type:"button",className:"button primary form",disabled:!this.isSaveEnabled(),onClick:this.handleSaveClick},n.createElement("span",null,n.createElement(f.x6,null,"Save"))))}}Yl.propTypes={adminSsoContext:i().object};const Zl=$l((0,f.CI)("common")(Yl));var Jl;function Xl(){return Xl=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},copy:()=>{}});class rc extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.clipboardServiceWorkerService=new nc(e.context.port)}get defaultState(){return{copyTemporarily:this.copyTemporarily.bind(this),copy:this.copy.bind(this)}}async copyTemporarily(e,t){(0,ie.A)(e),(0,ie.A)(t),await this.clipboardServiceWorkerService.copyTemporarily(e),this.props.actionFeedbackContext.displaySuccess(n.createElement(n.Fragment,null,t," ",n.createElement(f.x6,null,"It will clear in 30 seconds.")))}async copy(e,t){(0,ie.A)(e),(0,ie.A)(t),await this.clipboardServiceWorkerService.copy(e),this.props.actionFeedbackContext.displaySuccess(t)}render(){return n.createElement(ic.Provider,{value:this.state},this.props.children)}}function oc(e){return class extends n.Component{render(){return n.createElement(ic.Consumer,null,t=>n.createElement(e,sc({clipboardContext:t},this.props)))}}}rc.propTypes={context:i().any.isRequired,actionFeedbackContext:i().any.isRequired,children:i().any,t:i().func},N(m((0,f.CI)("common")(rc)));class lc extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.bindCallbacks(),this.createRefs()}get defaultState(){return{advancedSettingsOpened:!1}}bindCallbacks(){this.handleInputChange=this.handleInputChange.bind(this),this.handleCopyRedirectUrl=this.handleCopyRedirectUrl.bind(this),this.handleAdvancedSettingsCLick=this.handleAdvancedSettingsCLick.bind(this)}createRefs(){this.clientIdInputRef=n.createRef(),this.tenantIdInputRef=n.createRef(),this.clientSecretInputRef=n.createRef(),this.clientSecretExpiryInputRef=n.createRef()}componentDidUpdate(){if(!this.props.adminSsoContext.consumeFocusOnError())return;const e=this.props.adminSsoContext.getErrors();switch(this.getFirstFieldInError(e,["client_id","tenant_id","client_secret","client_secret_expiry"])){case"client_id":this.clientIdInputRef.current.focus();break;case"tenant_id":this.tenantIdInputRef.current.focus();break;case"client_secret":this.clientSecretInputRef.current.focus();break;case"client_secret_expiry":this.clientSecretExpiryInputRef.current.focus()}}getFirstFieldInError(e,t){for(let a=0;a({value:e,label:e}))}get emailClaimList(){return[{value:"email",label:this.translate("Email")},{value:"preferred_username",label:this.translate("Preferred username")},{value:"upn",label:this.translate("UPN")}]}get promptOptionList(){return[{value:"login",label:this.translate("Login")},{value:"none",label:this.translate("None")}]}get fullRedirectUrl(){return`${this.props.context.userSettings.getTrustedDomain()}/sso/azure/redirect`}get translate(){return this.props.t}render(){const e=this.props.adminSsoContext,t=e.getSsoConfiguration(),a=e.getErrors();return n.createElement(n.Fragment,null,n.createElement("div",{className:"select-wrapper input required "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",{htmlFor:"sso-azure-url-input"},n.createElement(f.x6,null,"Login URL")),n.createElement(pn,{id:"sso-azure-url-input",name:"url",items:this.availableUrlList,value:t.url,onChange:this.handleInputChange}),n.createElement("p",null,n.createElement(f.x6,null,"The Azure AD authentication endpoint. See"," ",n.createElement("a",{href:"https://learn.microsoft.com/en-us/azure/active-directory/develop/authentication-national-cloud#azure-ad-authentication-endpoints",rel:"noopener noreferrer",target:"_blank"},"alternatives"),"."))),n.createElement("div",{className:"input text input-wrapper "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Redirect URL")),n.createElement("div",{className:"button-inline"},n.createElement("input",{id:"sso-redirect-url-input",type:"text",className:"fluid form-element disabled",name:"redirect_url",value:this.fullRedirectUrl,placeholder:this.translate("Redirect URL"),readOnly:!0,disabled:!0}),n.createElement("button",{type:"button",onClick:this.handleCopyRedirectUrl,className:"copy-to-clipboard button button-icon"},n.createElement(Ql,null))),n.createElement("p",null,n.createElement(f.x6,null,"The URL to provide to Azure when registering the application."))),n.createElement("div",{className:"input text required "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Application (client) ID")),n.createElement("input",{id:"sso-azure-client-id-input",type:"text",className:"fluid form-element",name:"client_id",ref:this.clientIdInputRef,value:t.client_id,onChange:this.handleInputChange,placeholder:this.translate("Application (client) ID"),disabled:this.hasAllInputDisabled()}),a?.hasError("client_id")&&n.createElement("div",{className:"error-message"},this.displayErrors(a.getError("client_id"))),n.createElement("p",null,n.createElement(f.x6,null,"The public identifier for the app in Azure in UUID format.")," ",n.createElement("a",{href:"https://learn.microsoft.com/en-us/azure/healthcare-apis/register-application#application-id-client-id",rel:"noopener noreferrer",target:"_blank"},n.createElement(f.x6,null,"Where to find it?")))),n.createElement("div",{className:"input text required "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Directory (tenant) ID")),n.createElement("input",{id:"sso-azure-tenant-id-input",type:"text",className:"fluid form-element",name:"tenant_id",ref:this.tenantIdInputRef,value:t.tenant_id,onChange:this.handleInputChange,placeholder:this.translate("Directory ID"),disabled:this.hasAllInputDisabled()}),a?.hasError("tenant_id")&&n.createElement("div",{className:"error-message"},this.displayErrors(a.getError("tenant_id"))),n.createElement("p",null,n.createElement(f.x6,null,"The Azure Active Directory tenant ID, in UUID format.")," ",n.createElement("a",{href:"https://learn.microsoft.com/en-gb/azure/active-directory/fundamentals/active-directory-how-to-find-tenant",rel:"noopener noreferrer",target:"_blank"},n.createElement(f.x6,null,"Where to find it?")))),n.createElement("div",{className:"input text required "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Secret")),n.createElement(Za,{id:"sso-azure-secret-input",className:"fluid form-element",onChange:this.handleInputChange,autoComplete:"off",name:"client_secret",placeholder:this.translate("Secret"),disabled:this.hasAllInputDisabled(),value:t.client_secret,preview:!0,inputRef:this.clientSecretInputRef}),a?.hasError("client_secret")&&n.createElement("div",{className:"error-message"},this.displayErrors(a.getError("client_secret"))),n.createElement("p",null,n.createElement(f.x6,null,"Allows Azure and Passbolt API to securely share information.")," ",n.createElement("a",{href:"https://learn.microsoft.com/en-us/azure/marketplace/create-or-update-client-ids-and-secrets#add-a-client-id-and-client-secret",rel:"noopener noreferrer",target:"_blank"},n.createElement(f.x6,null,"Where to find it?")))),n.createElement("div",{className:"input text date-wrapper required "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Secret expiry")),n.createElement("div",{className:"button-inline"},n.createElement("input",{id:"sso-azure-secret-expiry-input",type:"date",className:"fluid form-element "+(t.client_secret_expiry?"":"empty"),name:"client_secret_expiry",ref:this.clientSecretExpiryInputRef,value:t.client_secret_expiry||"",onChange:this.handleInputChange,disabled:this.hasAllInputDisabled()}),n.createElement(ac,{className:"svg-icon"})),a?.hasError("client_secret_expiry")&&n.createElement("div",{className:"error-message"},this.displayErrors(a.getError("client_secret_expiry")))),n.createElement("div",{className:"warning message"},n.createElement("div",null,n.createElement(f.x6,null,n.createElement("b",null,"Warning"),": This secret will expire after some time (typically a few months). Make sure you save the expiry date and rotate it on time."))),n.createElement("div",null,n.createElement("div",{className:"accordion operation-details "+(this.state.advancedSettingsOpened?"":"closed")},n.createElement("div",{className:"accordion-header",onClick:this.handleAdvancedSettingsCLick},n.createElement("button",{type:"button",className:"link no-border",id:"advanced-settings-panel-button"},this.state.advancedSettingsOpened?n.createElement(Vt,{className:"caret-down"}):n.createElement(Wt,{className:"caret-right"}),n.createElement(f.x6,null,"Advanced settings"))))),this.state.advancedSettingsOpened&&n.createElement(n.Fragment,null,n.createElement("div",{className:"select-wrapper input required "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",{htmlFor:"email-claim-input"},n.createElement(f.x6,null,"Email claim")),n.createElement(pn,{id:"email-claim-input",name:"email_claim",items:this.emailClaimList,value:t.email_claim,onChange:this.handleInputChange}),n.createElement("p",null,n.createElement(f.x6,null,"Defines which Azure field needs to be used as Passbolt username."))),"upn"===t.email_claim&&n.createElement("div",{className:"warning message"},n.createElement("div",null,n.createElement(f.x6,null,n.createElement("b",null,"Warning"),": UPN is not active by default on Azure and requires a specific option set on Azure to be working."))),"email"===t.email_claim&&n.createElement("div",{className:"warning message"},n.createElement("div",null,n.createElement(f.x6,null,n.createElement("b",null,"Warning"),": using Azure email field to map with Passbolt username is generally unsafe (see. noauth vulnerability class)."))),n.createElement("div",{className:"select-wrapper input required "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",{htmlFor:"prompt-input"},n.createElement(f.x6,null,"Prompt")),n.createElement(pn,{id:"prompt-input",name:"prompt",items:this.promptOptionList,value:t.prompt,onChange:this.handleInputChange}),n.createElement("p",null,n.createElement(f.x6,null,"Defines the Azure login behaviour by prompting the user to fully login each time or not."))),n.createElement("div",{className:"input-wrapper form-element"},n.createElement("div",{className:"toggle-swith-title"},n.createElement(f.x6,null,"Login hint")),n.createElement("div",{className:"input toggle-switch"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"login_hint",onChange:this.handleInputChange,checked:t.login_hint,disabled:this.hasAllInputDisabled(),id:"login_hint-input"}),n.createElement("label",{htmlFor:"login_hint-input"},n.createElement(f.x6,null,"If checked, users signing in with Microsoft Azure must use their Passbolt email address."))))))}}lc.propTypes={adminSsoContext:i().object,actionFeedbackContext:i().any,context:i().any,clipboardContext:i().object,t:i().func};const cc=N(m($l(oc((0,f.CI)("common")(lc)))));class mc extends n.PureComponent{constructor(e){super(e),this.bindCallbacks(),this.createRefs()}bindCallbacks(){this.handleInputChange=this.handleInputChange.bind(this),this.handleCopyRedirectUrl=this.handleCopyRedirectUrl.bind(this)}createRefs(){this.clientIdInputRef=n.createRef(),this.clientSecretInputRef=n.createRef()}componentDidUpdate(){if(!this.props.adminSsoContext.consumeFocusOnError())return;const e=this.props.adminSsoContext.getErrors();switch(this.getFirstFieldInError(e,["client_id","client_secret"])){case"client_id":this.clientIdInputRef.current.focus();break;case"client_secret":this.clientSecretInputRef.current.focus()}}getFirstFieldInError(e,t){for(let a=0;ae.hasError(t))}handleInputChange(e){const t=e.target,a="checkbox"===t.type?t.checked:t.value,n=t.name;this.props.adminSsoContext.setValue(n,a)}async handleCopyRedirectUrl(){await this.props.clipboardContext.copy(this.fullRedirectUrl,this.translate("The redirection URL has been copied to the clipboard."))}hasAllInputDisabled(){return this.props.adminSsoContext.isProcessing()}displayErrors(e){return Object.values(e)}get urlSelectItems(){return Kl.SUPPORTED_URLS.map(e=>({value:e,label:e}))}get fullRedirectUrl(){return`${this.props.context.userSettings.getTrustedDomain()}/sso/pingone/redirect`}get translate(){return this.props.t}render(){const e=this.props.adminSsoContext,t=e.getSsoConfiguration(),a=e.getErrors();return n.createElement(n.Fragment,null,n.createElement("div",{className:"select-wrapper input required "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",{htmlFor:"sso-pingone-url-input"},n.createElement(f.x6,null,"URL")),n.createElement(pn,{id:"sso-pingone-url-input",name:"url",items:this.urlSelectItems,value:t.url,onChange:this.handleInputChange,disabled:this.hasAllInputDisabled()}),a?.hasError("url")&&n.createElement("div",{className:"error-message"},this.displayErrors(a.getError("url"))),n.createElement("p",null,n.createElement(f.x6,null,"The PingOne authentication URL for your region."))),n.createElement("div",{className:"input text input-wrapper "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Redirect URL")),n.createElement("div",{className:"button-inline"},n.createElement("input",{id:"sso-pingone-redirect-url-input",type:"text",className:"fluid form-element disabled",name:"redirect_url",value:this.fullRedirectUrl,placeholder:this.translate("Redirect URL"),readOnly:!0,disabled:!0}),n.createElement("button",{type:"button",onClick:this.handleCopyRedirectUrl,className:"copy-to-clipboard button button-icon"},n.createElement(Ql,null))),n.createElement("p",null,n.createElement(f.x6,null,"The URL to provide to PingOne when registering the application."))),n.createElement("div",{className:"input text required "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",{htmlFor:"sso-pingone-environment-id-input"},n.createElement(f.x6,null,"Environment ID")),n.createElement("input",{id:"sso-pingone-environment-id-input",type:"text",className:"fluid form-element",name:"environment_id",ref:this.inputRefs.environment_id,value:t.environment_id,onChange:this.handleInputChange,placeholder:this.translate("Environment ID"),disabled:this.hasAllInputDisabled()}),a?.hasError("environment_id")&&n.createElement("div",{className:"error-message"},this.displayErrors(a.getError("environment_id"))),n.createElement("p",null,n.createElement(f.x6,null,"The public identifier for the PingOne application.")," ",n.createElement("a",{href:"https://docs.pingidentity.com/pingone/applications/p1_edit_application_oidc.html",rel:"noopener noreferrer",target:"_blank"},n.createElement(f.x6,null,"Where to find it?")))),n.createElement("div",{className:"input text required "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",{htmlFor:"sso-pingone-client-id-input"},n.createElement(f.x6,null,"Application (client) ID")),n.createElement("input",{id:"sso-pingone-client-id-input",type:"text",className:"fluid form-element",name:"client_id",ref:this.inputRefs.client_id,value:t.client_id,onChange:this.handleInputChange,placeholder:this.translate("Application (client) ID"),disabled:this.hasAllInputDisabled()}),a?.hasError("client_id")&&n.createElement("div",{className:"error-message"},this.displayErrors(a.getError("client_id"))),n.createElement("p",null,n.createElement(f.x6,null,"The public identifier for the app in PingOne in UUID format.")," ",n.createElement("a",{href:"https://docs.pingidentity.com/pingone/applications/p1_edit_application_oidc.html",rel:"noopener noreferrer",target:"_blank"},n.createElement(f.x6,null,"Where to find it?")))),n.createElement("div",{className:"input text required "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",{htmlFor:"sso-pingone-secret-input"},n.createElement(f.x6,null,"Secret")),n.createElement(Za,{id:"sso-pingone-secret-input",className:"fluid form-element",onChange:this.handleInputChange,autoComplete:"off",name:"client_secret",placeholder:this.translate("Secret"),disabled:this.hasAllInputDisabled(),value:t.client_secret,preview:!0,inputRef:this.inputRefs.client_secret}),a?.hasError("client_secret")&&n.createElement("div",{className:"error-message"},this.displayErrors(a.getError("client_secret"))),n.createElement("p",null,n.createElement(f.x6,null,"Allows PingOne and Passbolt API to securely share information.")," ",n.createElement("a",{href:"https://docs.pingidentity.com/pingone/applications/p1_edit_application_oidc.html",rel:"noopener noreferrer",target:"_blank"},n.createElement(f.x6,null,"Where to find it?")))),n.createElement("div",{className:"input text required disabled"},n.createElement("label",{htmlFor:"sso-pingone-scope-input"},n.createElement(f.x6,null,"Scope")),n.createElement("input",{id:"sso-pingone-scope-input",type:"text",className:"fluid form-element",name:"scope",value:Gl.SCOPE,disabled:!0}),n.createElement("p",null,n.createElement(f.x6,null,"Defines which PingOne field needs to be used as Passbolt username."))),n.createElement("div",{className:"input text required "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",{htmlFor:"sso-pingone-email-claim-input"},n.createElement(f.x6,null,"Email claim")),n.createElement("input",{id:"sso-pingone-email-claim-input",type:"text",className:"fluid form-element",name:"email_claim",ref:this.inputRefs.email_claim,value:t.email_claim,onChange:this.handleInputChange,placeholder:this.translate("Email claim"),disabled:this.hasAllInputDisabled()}),a?.hasError("email_claim")&&n.createElement("div",{className:"error-message"},this.displayErrors(a.getError("email_claim"))),n.createElement("p",null,n.createElement(f.x6,null,"Defines which PingOne field needs to be used as Passbolt username."))))}}Ec.propTypes={adminSsoContext:i().object,clipboardContext:i().object,context:i().any,t:i().func};const vc=N(oc($l((0,f.CI)("common")(Ec))));class wc extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.bindCallbacks()}get defaultState(){return{loading:!0,providers:[]}}async componentDidMount(){const e=await this.props.adminSsoContext.loadSsoConfiguration();this.setState({loading:!1,providers:e?.providers||[]})}bindCallbacks(){this.handleProviderInputChange=this.handleProviderInputChange.bind(this),this.handleSsoSettingToggle=this.handleSsoSettingToggle.bind(this)}handleProviderInputChange(e){this.props.adminSsoContext.changeProvider({id:e.target.value})}handleSsoSettingToggle(){this.props.adminSsoContext.isSsoConfigActivated()&&this.props.adminSsoContext.disableSso()}hasAllInputDisabled(){return this.props.adminSsoContext.isProcessing()||this.state.loading}get allSsoProviders(){const e=this.state.providers;return hl.map(t=>{const a={...t};return a.disabled=Boolean(a.disabled)||!e.includes(a.id),a}).filter(e=>!e.disabled||e.disabled&&!e?.hiddenIfDisabled)}get supportedSsoProviders(){const e=this.state.providers,t=[];return e.forEach(e=>{const a=hl.find(t=>t.id===e);a&&!a.disabled&&t.push({value:a.id,label:a.name})}),t}isReady(){return this.props.adminSsoContext.isDataReady()}render(){const e=this.props.adminSsoContext,t=e.getSsoConfiguration(),a=e.isSsoConfigActivated();return n.createElement("div",{className:"row"},n.createElement("div",{className:"third-party-provider-settings sso-settings main-column"},n.createElement("div",{className:"main-content"},n.createElement("h3",{className:"title"},n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"ssoToggle",onChange:this.handleSsoSettingToggle,checked:a,disabled:this.hasAllInputDisabled(),id:"ssoToggle"}),n.createElement("label",{htmlFor:"ssoToggle"},n.createElement(f.x6,null,"Single Sign-On")))),this.isReady()&&!a&&n.createElement(n.Fragment,null,n.createElement("h4",{className:"no-border"},n.createElement(f.x6,null,"Select a provider")),n.createElement("div",{className:"provider-list"},this.allSsoProviders.map(e=>n.createElement("div",{key:e.id,className:"provider button "+(e.disabled?"disabled":""),id:e.id,onClick:()=>this.props.adminSsoContext.changeProvider(e)},n.createElement("div",{className:"provider-logo"},e.icon),n.createElement("p",{className:"provider-name"},e.name,n.createElement("br",null),e.disabled&&n.createElement(f.x6,null,"(not yet available)")))))),this.isReady()&&a&&n.createElement("form",{className:"form"},n.createElement("div",{className:"select-wrapper input"},n.createElement("label",{htmlFor:"sso-provider-input"},n.createElement(f.x6,null,"Single Sign-On provider")),n.createElement(pn,{id:"sso-provider-input",name:"provider",items:this.supportedSsoProviders,value:t?.provider,onChange:this.handleProviderInputChange})),t?.provider===_l.PROVIDER_ID&&n.createElement(cc,null),t?.provider===Dl.PROVIDER_ID&&n.createElement(dc,null),t?.provider===Tl.PROVIDER_ID&&n.createElement(pc,null),t?.provider===jl.PROVIDER_ID&&n.createElement(gc,null),t?.provider===Kl.PROVIDER_ID&&n.createElement(vc,null))),this.props.adminSsoContext.hasFormChanged()&&n.createElement("div",{className:"warning message",id:"sso-setting-overridden-banner"},n.createElement("div",null,n.createElement("p",null,n.createElement(f.x6,null,"Don't forget to save your settings to apply your modification."))))),n.createElement(Zl,null),Xa(n.createElement(n.Fragment,null,n.createElement("div",{className:"sidebar-help-section warning message",id:"sso-setting-security-warning-banner"},n.createElement("h3",null,n.createElement(f.x6,null,"Important notice:")),n.createElement("p",null,n.createElement(f.x6,null,"Enabling SSO changes the security risks.")," ",n.createElement(f.x6,null,"For example an attacker with a local machine access maybe be able to access secrets, if the user is still logged in with the Identity provider.")," ",n.createElement(f.x6,null,"Make sure users follow screen lock best practices.")," ",n.createElement("a",{href:"https://passbolt.com/docs/admin/authentication/sso/",target:"_blank",rel:"noopener noreferrer"},n.createElement(f.x6,null,"Learn more")))),n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"Need some help?")),n.createElement("p",null,n.createElement(f.x6,null,"For more information about SSO, checkout the dedicated page on the help website.")),n.createElement("a",{className:"button",href:"https://passbolt.com/docs/admin/authentication/sso/",target:"_blank",rel:"noopener noreferrer"},n.createElement(ps,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),t?.provider===_l.PROVIDER_ID&&n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"How do I configure a AzureAD SSO?")),n.createElement("a",{className:"button",href:"https://docs.microsoft.com/en-us/azure/active-directory/manage-apps/add-application-portal-setup-sso",target:"_blank",rel:"noopener noreferrer"},n.createElement(fc,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),t?.provider===Dl.PROVIDER_ID&&n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"How do I configure a Google SSO?")),n.createElement("a",{className:"button",href:"https://developers.google.com/identity/openid-connect/openid-connect",target:"_blank",rel:"noopener noreferrer"},n.createElement(fc,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),t?.provider===jl.PROVIDER_ID&&n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"How do I configure an AD FS SSO?")),n.createElement("a",{className:"button",href:"https://learn.microsoft.com/en-gb/microsoft-365/troubleshoot/active-directory/set-up-adfs-for-single-sign-on",target:"_blank",rel:"noopener noreferrer"},n.createElement(fc,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),t?.provider===Kl.PROVIDER_ID&&n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"How do I configure PingOne SSO?")),n.createElement("a",{className:"button",href:"https://docs.pingidentity.com/pingone/applications/p1_applications_add_applications.html",target:"_blank",rel:"noopener noreferrer"},n.createElement(fc,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation"))))),document.getElementById("administration-help-panel")))}}wc.propTypes={administrationWorkspaceContext:i().object,adminSsoContext:i().object,actionFeedbackContext:i().any,context:i().any,t:i().func};const kc=N(m(Ne($l((0,f.CI)("common")(wc)))));class _c extends n.Component{render(){return n.createElement("div",{className:"row"},n.createElement("div",{className:"third-party-provider-settings-teasing sso-settings main-column"},n.createElement("div",{className:"main-content"},n.createElement("h3",{className:"title",id:"third-party-provider-settings-title"},n.createElement(f.x6,null,"Single Sign-On"),n.createElement(Ea,{className:"pro-teasing-icon"})),n.createElement("p",null,n.createElement(f.x6,null,"Simplify secure access through integration with identity providers.")),n.createElement("div",{className:"third-party-provider-settings-info"},n.createElement("ul",{className:"third-party-provider-settings-description"},n.createElement("li",null,n.createElement(fs,null),n.createElement(f.x6,null,"Reduce password fatigue and simplify login.")),n.createElement("li",null,n.createElement(fs,null),n.createElement(f.x6,null,"Centralise user authentication management.")),n.createElement("li",null,n.createElement(fs,null),n.createElement(f.x6,null,"Support major identity providers like Google and Microsoft."))),n.createElement("div",null,n.createElement("a",{className:"button primary",href:"https://www.passbolt.com/ce-to-pro?utm_campaign=21060976-CE%20to%20Pro&utm_source=product",target:"_blank",rel:"noopener noreferrer"},n.createElement(f.x6,null,"Upgrade to Passbolt Pro")))))),Xa(n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"Need some help?")),n.createElement("p",null,n.createElement(f.x6,null,"For more information about SSO, checkout the dedicated page on the help website.")),n.createElement("a",{className:"button",href:"https://passbolt.com/docs/admin/authentication/sso/",target:"_blank",rel:"noopener noreferrer"},n.createElement(ps,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}_c.propTypes={context:i().any,t:i().func};const xc=N((0,f.CI)("common")(_c)),Sc=class{constructor(e={remember_me_for_a_month:!1}){this.policy=e.policy,this.rememberMeForAMonth=e.remember_me_for_a_month}},Cc=class{constructor(e={rememberMeForAMonth:!1}){this.policy=e.policy||"opt-in",this.remember_me_for_a_month=e.rememberMeForAMonth}};function Nc(){return Nc=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},getSettings:()=>{},setSettings:()=>{},hasSettingsChanges:()=>{},findSettings:()=>{},setProcessing:()=>{},isProcessing:()=>{},clearContext:()=>{},save:()=>{}});class Ac extends n.Component{constructor(e){super(e),this.state=this.defaultState;const t=e.context.getApiClientOptions();this.mfaPolicyService=new ht(t)}get defaultState(){return{settings:new Sc,currentSettings:new Sc,processing:!0,getCurrentSettings:this.getCurrentSettings.bind(this),getSettings:this.getSettings.bind(this),setSettings:this.setSettings.bind(this),findSettings:this.findSettings.bind(this),hasSettingsChanges:this.hasSettingsChanges.bind(this),isProcessing:this.isProcessing.bind(this),setProcessing:this.setProcessing.bind(this),clearContext:this.clearContext.bind(this),save:this.save.bind(this)}}async findSettings(e=()=>{}){this.setProcessing(!0);const t=await this.mfaPolicyService.find(),a=new Sc(t);this.setState({currentSettings:a,settings:a},e),this.setProcessing(!1)}async save(){this.setProcessing(!0);const e=new Cc(this.state.settings);await this.mfaPolicyService.save(e),await this.findSettings()}getCurrentSettings(){return this.state.currentSettings}getSettings(){return this.state.settings}setSettings(e,t,a=()=>{}){const n=Object.assign({},this.state.settings,{[e]:t});this.setState({settings:n},a)}isProcessing(){return this.state.processing}setProcessing(e){this.setState({processing:e})}hasSettingsChanges(){return JSON.stringify(this.state.currentSettings)!==JSON.stringify(this.state.settings)}clearContext(){const{currentSettings:e,settings:t,processing:a}=this.defaultState;this.setState({currentSettings:e,settings:t,processing:a})}render(){return n.createElement(Tc.Provider,{value:this.state},this.props.children)}}Ac.propTypes={context:i().any,children:i().any,t:i().any,actionFeedbackContext:i().object};const Ic=N(Ac);function Rc(e){return class extends n.Component{render(){return n.createElement(Tc.Consumer,null,t=>n.createElement(e,Nc({adminMfaPolicyContext:t},this.props)))}}}class Pc extends n.Component{constructor(e){super(e),this.bindCallbacks()}bindCallbacks(){this.handleSave=this.handleSave.bind(this)}isSaveEnabled(){return!this.props.adminMfaPolicyContext.isProcessing()}async handleSave(){if(this.isSaveEnabled())try{await this.props.adminMfaPolicyContext.save(),this.handleSaveSuccess()}catch(e){this.handleSaveError(e)}finally{this.props.adminMfaPolicyContext.setProcessing(!1)}}async handleSaveSuccess(){await this.props.actionFeedbackContext.displaySuccess(this.props.t("The MFA policy settings were updated."))}async handleSaveError(e){"UserAbortsOperationError"!==e.name&&(console.error(e),await this.props.actionFeedbackContext.displayError(e.message))}render(){return n.createElement("div",{className:"actions-wrapper"},n.createElement("button",{className:"button primary form",type:"button",disabled:!this.isSaveEnabled(),id:"save-settings",onClick:this.handleSave},n.createElement("span",null,n.createElement(f.x6,null,"Save"))))}}Pc.propTypes={adminMfaPolicyContext:i().object,actionFeedbackContext:i().object,t:i().func};const Dc=Rc(m((0,f.CI)("common")(Pc)));class Oc extends n.Component{constructor(e){super(e),this.bindCallbacks()}async componentDidMount(){await this.findSettings()}componentWillUnmount(){this.props.adminMfaPolicyContext.clearContext()}bindCallbacks(){this.handleInputChange=this.handleInputChange.bind(this)}async findSettings(){await this.props.adminMfaPolicyContext.findSettings()}async handleInputChange(e){const t=e.target.name;let a=e.target.value;"rememberMeForAMonth"===t&&(a=e.target.checked),this.props.adminMfaPolicyContext.setSettings(t,a)}hasAllInputDisabled(){return this.props.adminMfaPolicyContext.isProcessing()}render(){const e=this.props.adminMfaPolicyContext.getSettings();return n.createElement("div",{className:"row"},n.createElement("div",{className:"mfa-policy-settings main-column"},n.createElement("div",{className:"main-content"},n.createElement("h3",{className:"title",id:"mfa-policy-settings-title"},n.createElement(f.x6,null,"MFA Policy")),n.createElement("form",{className:"form"},n.createElement("h4",{className:"no-border",id:"mfa-policy-subtitle"},n.createElement(f.x6,null,"Default users multi factor authentication policy")),n.createElement("p",{id:"mfa-policy-description"},n.createElement(f.x6,null,"You can choose the default behaviour of multi factor authentication for all users.")),n.createElement("div",{className:"radiolist-alt"},n.createElement("div",{className:"input radio "+("mandatory"===e?.policy?"checked":""),id:"mfa-policy-mandatory"},n.createElement("input",{type:"radio",value:"mandatory",onChange:this.handleInputChange,name:"policy",checked:"mandatory"===e?.policy,id:"mfa-policy-mandatory-radio",disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"mfa-policy-mandatory-radio"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Prompt")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"Users have to enable multi factor authentication. If they don't, they will be reminded every time they log in.")))),n.createElement("div",{className:"input radio "+("opt-in"===e?.policy?"checked":""),id:"mfa-policy-opt-in"},n.createElement("input",{type:"radio",value:"opt-in",onChange:this.handleInputChange,name:"policy",checked:"opt-in"===e?.policy,id:"mfa-policy-opt-in-radio",disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"mfa-policy-opt-in-radio"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Opt-in (default)")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"Users have the choice to enable multi factor authentication in their profile workspace."))))),n.createElement("h4",{id:"mfa-policy-remember-subtitle"},"Remember a device for a month"),n.createElement("span",{className:"input toggle-switch form-element "},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"rememberMeForAMonth",onChange:this.handleInputChange,disabled:this.hasAllInputDisabled(),checked:e?.rememberMeForAMonth,id:"remember-toggle-button"}),n.createElement("label",{htmlFor:"remember-toggle-button"},n.createElement(f.x6,null,"Allow “Remember this device for a month.” option during MFA."))))),this.props.adminMfaPolicyContext.hasSettingsChanges()&&n.createElement("div",{className:"warning message",id:"mfa-policy-setting-banner"},n.createElement("div",null,n.createElement("p",null,n.createElement(f.x6,null,"Don't forget to save your settings to apply your modification."))))),n.createElement(Dc,null),Xa(n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"Need some help?")),n.createElement("p",null,n.createElement(f.x6,null,"For more information about MFA policy settings, checkout the dedicated page on the help website.")),n.createElement("a",{className:"button",href:"https://passbolt.com/docs/admin/authentication/mfa-policy",target:"_blank",rel:"noopener noreferrer"},n.createElement(ps,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}Oc.propTypes={context:i().object,administrationWorkspaceContext:i().object,adminMfaPolicyContext:i().object,t:i().func};const Mc=N(Ne(Rc((0,f.CI)("common")(Oc))));class Uc extends n.Component{render(){return n.createElement("div",{className:"row"},n.createElement("div",{className:"mfa-settings-teasing main-column"},n.createElement("div",{className:"main-content"},n.createElement("h3",{className:"title",id:"mfa-settings-title"},n.createElement(f.x6,null,"MFA Policy"),n.createElement(Ea,{className:"pro-teasing-icon"})),n.createElement("p",null,n.createElement(f.x6,null,"Enhance security by enforcing multi-factor authentication.")),n.createElement("div",{className:"mfa-settings-info"},n.createElement("ul",{className:"mfa-settings-description"},n.createElement("li",null,n.createElement(fs,null),n.createElement(f.x6,null,"Strengthen user authentication.")),n.createElement("li",null,n.createElement(fs,null),n.createElement(f.x6,null,"Protect against unauthorised access.")),n.createElement("li",null,n.createElement(fs,null),n.createElement(f.x6,null,"Flexible configuration based on user roles or access levels."))),n.createElement("div",null,n.createElement("a",{className:"button primary",href:"https://www.passbolt.com/ce-to-pro?utm_campaign=21060976-CE%20to%20Pro&utm_source=product",target:"_blank",rel:"noopener noreferrer"},n.createElement(f.x6,null,"Upgrade to Passbolt Pro")))))),Xa(n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"Need some help?")),n.createElement("p",null,n.createElement(f.x6,null,"For more information about MFA policy settings, checkout the dedicated page on the help website.")),n.createElement("a",{className:"button",href:"https://passbolt.com/docs/admin/authentication/mfa-policy",target:"_blank",rel:"noopener noreferrer"},n.createElement(Sa,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}Uc.propTypes={context:i().object,t:i().func};const Fc=N((0,f.CI)("common")(Uc));class jc extends se{constructor(e,t={}){super(ae.validate(jc.ENTITY_NAME,e,jc.getSchema()),t)}static getSchema(){return{type:"object",required:["id","name"],properties:{id:{type:"string",format:"uuid"},name:{type:"string",maxLength:255}}}}get id(){return this._props.id}get name(){return this._props.name}static get ENTITY_NAME(){return"Action"}}const Lc=jc;class qc extends se{constructor(e,t={}){super(ae.validate(qc.ENTITY_NAME,e,qc.getSchema()),t)}static getSchema(){return{type:"object",required:["id","name"],properties:{id:{type:"string",format:"uuid"},name:{type:"string",maxLength:255}}}}get id(){return this._props.id}get name(){return this._props.name}static get ENTITY_NAME(){return"UiAction"}}const zc=qc;class Kc extends se{constructor(e,t={}){super(ae.validate(Kc.ENTITY_NAME,e,Kc.getSchema()),t),this._props.action&&(this._action=new Lc(this._props.action,{clone:!1})),delete this._props.action,this._props.ui_action&&(this._ui_action=new zc(this._props.ui_action,{clone:!1})),delete this._props.ui_action}static getSchema(){return{type:"object",required:["id","role_id","foreign_model","foreign_id","control_function"],properties:{id:{type:"string",format:"uuid"},role_id:{type:"string",format:"uuid"},foreign_model:{type:"string",enum:[Kc.FOREIGN_MODEL_ACTION,Kc.FOREIGN_MODEL_UI_ACTION]},foreign_id:{type:"string",format:"uuid"},control_function:{type:"string",enum:[K,V,G]},action:Lc.getSchema(),ui_action:zc.getSchema()}}}toDto(e){const t=Object.assign({},this._props);return e?(this._action&&e.action&&(t.action=this._action.toDto()),this._ui_action&&e.ui_action&&(t.ui_action=this._ui_action.toDto()),t):t}toUpdateDto(){return{id:this.id,control_function:this.controlFunction}}toJSON(){return this.toDto(Kc.ALL_CONTAIN_OPTIONS)}get id(){return this._props.id}get roleId(){return this._props.role_id}get foreignModel(){return this._props.foreign_model}get foreignId(){return this._props.foreign_id}get controlFunction(){return this._props.control_function}set controlFunction(e){ae.validateProp("control_function",e,Kc.getSchema().properties.control_function),this._props.control_function=e}get action(){return this._action||null}get uiAction(){return this._ui_action||null}static get ENTITY_NAME(){return"Rbac"}static get ALL_CONTAIN_OPTIONS(){return{action:!0,ui_action:!0}}static get FOREIGN_MODEL_ACTION(){return"Action"}static get FOREIGN_MODEL_UI_ACTION(){return"UiAction"}}const Vc=Kc;class Gc{static error(e){console.error(e);try{e instanceof Error&&"function"==typeof e.toJSON&&console.log(`Error: ${e.message}\nError structure: ${JSON.stringify(Gc.serializeError(e))}`)}catch(e){console.error("The logger was unable to extract additional error information",e)}}static serializeError(e){const{stack:t,cause:a,...n}=e.toJSON();return e.cause&&e.cause instanceof Error&&(n.cause=Gc.serializeError(e.cause)),e instanceof Z&&Array.isArray(e.errors)&&(n.errors=e.errors.map(e=>Gc.serializeError(e))),n}}const Bc=class extends de{static _cachedSchema={};get entityClass(){throw new Error("The collection class should declare the entity class that is handled.")}constructor(e=[],t={}){super(e,t),(t?.validate??!0)&&this.validateSchema(),this.pushMany(this._props,{...t,clone:!1}),this._props=null}validateSchema(){this._props=ae.validate(this.constructor.name,this._props,this.cachedSchema)}get cachedSchema(){return this.constructor._cachedSchema[this.constructor.name]||(this.constructor._cachedSchema[this.constructor.name]=this.constructor.getSchema()),this.constructor._cachedSchema[this.constructor.name]}static getSchema(){throw new Error("The collection class should declare its schema.")}buildOrCloneEntity(e,t={}){if(!e||"object"!=typeof e)throw new TypeError(`${this.entityClass.name}::buildOrCloneEntity expects "data" to be an object.`);return e instanceof this.entityClass&&(e=e.toDto(this.entityClass?.ALL_CONTAIN_OPTIONS)),new this.entityClass(e,t)}validateBuildRules(e,t={}){}validate(e={}){try{this.validateItems(e)}catch(e){if(!(e instanceof Z))throw e;return e}return null}validateItems(e={}){if(0===this.length)return null;const t=new Z;if(this.items.forEach((a,n)=>{const s=a.validate(e);s&&t.addItemValidationError(n,s)}),t.hasErrors())throw t}push(e,t={},a={}){const n=this.buildOrCloneEntity(e,t);this.validateBuildRules(n,a?.validateBuildRules),this._items.push(n),a?.onItemPushed?.(n)}pushOrReplace(e,t={},a={}){const n=a?.replacePropertyName||"id",s=this.items.findIndex(t=>t[n]===e[n]);if(-1!==s){this.items.splice(s,1);const n=this.buildOrCloneEntity(e,t);this.validateBuildRules(n,a?.validateBuildRules),this.items.splice(s,0,n)}else this.push(e,t,a)}pushMany(e,t={},a={}){if(!Array.isArray(e))throw new TypeError(`${this.constructor.name} pushMany expects "data" to be an array.`);e.forEach((e,n)=>{try{this.push(e,t,a)}catch(e){this.handlePushItemError(n,e,t)}})}handlePushItemError(e,t,a){if(!(t instanceof X||t instanceof Z||t instanceof ce))throw t;if(!a?.ignoreInvalidEntity){const a=new Z;throw a.addItemValidationError(e,t),a}{const a=`${this.entityClass.name}::pushMany ignored item (${e}) due to validation error.`;Gc.error(new Error(a,{cause:t}))}}},Wc=class extends Bc{get entityClass(){return Vc}constructor(e=[],t={}){super(e,t)}static getSchema(){return{type:"array",items:Vc.getSchema()}}validateBuildRules(e,t={}){this.assertNotExist("id",e._props.id,{haystackSet:t?.uniqueIdsSetCache})}toBulkUpdateDto(){return this.items.map(e=>e.toUpdateDto())}findRbacByUiActionName(e){if("string"!=typeof e&&!(e instanceof String))throw new Error("The name parameter should be a valid string.");return this.items.find(t=>t.uiAction?.name===e)}findRbacByRoleAndActionName(e,t){if(!(e instanceof ge))throw new Error("The role parameter should be a role entity.");if("string"!=typeof t&&!(t instanceof String))throw new Error("The name parameter should be a valid string.");return this.items.find(a=>a.roleId===e.id&&(a.uiAction?.name===t||a.action?.name===t))}findRbacByActionName(e){if("string"!=typeof e&&!(e instanceof String))throw new Error("The name parameter should be a valid string.");return this.items.find(t=>t.action?.name===e)}pushMany(e,t={},a={}){const n=new Set(this.extract("id"));a={onItemPushed:e=>{n.add(e._props.id)},validateBuildRules:{...a?.validateBuildRules,uniqueIdsSetCache:n},...a},super.pushMany(e,t,a)}remove(e){const t=this.items.length;let a=0;for(;a{},setRbacsUpdated:()=>{},save:()=>{},isProcessing:()=>{},hasSettingsChanges:()=>{},clearContext:()=>{}});class Zc extends n.Component{constructor(e){super(e),this.state=this.defaultState;const t=e.context.getApiClientOptions();this.rbacApiService=new Hc(t)}get defaultState(){return{processing:!1,rbacs:null,rbacsUpdated:new Wc([]),setRbacs:this.setRbacs.bind(this),setRbacsUpdated:this.setRbacsUpdated.bind(this),isProcessing:this.isProcessing.bind(this),hasSettingsChanges:this.hasSettingsChanges.bind(this),save:this.save.bind(this),clearContext:this.clearContext.bind(this)}}async setRbacs(e){this.setState({rbacs:e})}async setRbacsUpdated(e){this.setState({rbacsUpdated:e})}isProcessing(){return this.state.processing}setProcessing(e){this.setState({processing:e})}hasSettingsChanges(){return this.state.rbacsUpdated.items.length>0}clearContext(){const{rbacs:e,rbacsUpdated:t,processing:a}=this.defaultState;this.setState({rbacs:e,rbacsUpdated:t,processing:a})}async save(){this.setProcessing(!0);try{const e=this.state.rbacsUpdated.toBulkUpdateDto();if(0===this.state.rbacsUpdated.length)return;const t=(await this.rbacApiService.updateAll(e,{ui_action:!0,action:!0})).body,a=this.state.rbacs;t.forEach(e=>a.pushOrReplace(new Vc(e)));const n=new Wc([]);this.setState({rbacs:a,rbacsUpdated:n})}finally{this.setProcessing(!1)}}render(){return n.createElement(Yc.Provider,{value:this.state},this.props.children)}}Zc.propTypes={context:i().any,children:i().any};const Jc=N(Zc);function Xc(e){return class extends n.Component{render(){return n.createElement(Yc.Consumer,null,t=>n.createElement(e,$c({adminRbacContext:t},this.props)))}}}class Qc extends n.Component{constructor(e){super(e),this.bindCallbacks()}bindCallbacks(){this.handleSaveClick=this.handleSaveClick.bind(this)}async handleSaveClick(){try{await this.props.adminRbacContext.save(),this.handleSaveSuccess()}catch(e){this.handleSaveError(e)}}isSaveEnabled(){return!this.props.adminRbacContext.isProcessing()}async handleSaveSuccess(){await this.props.actionFeedbackContext.displaySuccess(this.props.t("The role-based access control settings were updated."))}async handleSaveError(e){console.error(e),await this.props.actionFeedbackContext.displayError(e.message)}render(){return n.createElement("div",{className:"actions-wrapper"},n.createElement("button",{className:"button primary form",type:"button",disabled:!this.isSaveEnabled(),onClick:this.handleSaveClick},n.createElement("span",null,n.createElement(f.x6,null,"Save"))))}}Qc.propTypes={context:i().object,adminRbacContext:i().object,actionFeedbackContext:i().object,t:i().func};const em=Xc(m((0,f.CI)("common")(Qc)));class tm extends n.Component{blankColumnSectionForRoles(){const e=[];for(let t=0;t{n.add(e._props.id),s.add(e._props.name)},validateBuildRules:{...a?.validateBuildRules,uniqueIdsSetCache:n,uniqueNamesSetCache:s},...a},super.pushMany(e,t,a)}filterByCustomRole(){this.filterByCallback(e=>!e.isAReservedRole())}filterOutGuestRole(){this.filterByCallback(e=>!e.isGuest())}getById(e){return this._items.find(t=>t.id===e)||null}static get ENTITY_NAME(){return"Roles"}};class sm extends n.Component{constructor(e){super(e),this.handleInputChange=this.handleInputChange.bind(this)}handleInputChange(e,t){this.props.onChange(t,this.props.actionName,e.target.value)}get allowedCtlFunctions(){const e=[{value:K,label:this.props.t("Allow")},{value:V,label:this.props.t("Deny")}];return this.props.actionName===U&&e.push({value:G,label:this.props.t("Allow group manager"),title:this.props.t("Allow group manager")}),e}get rowClassName(){return this.props.actionName.toLowerCase().replaceAll(/\W/g,"-")}getCtlFunctionForRole(e){const t=this.props.rbacsUpdated?.findRbacByRoleAndActionName(e,this.props.actionName)||this.props.rbacs?.findRbacByRoleAndActionName(e,this.props.actionName);return t?.controlFunction||null}hasChanged(){return!!this.props.rbacsUpdated.findRbacByUiActionName(this.props.actionName)}render(){let e=[];return this.props.roles&&(e=this.props.roles),n.createElement(n.Fragment,null,n.createElement("div",{className:`rbac-row ${this.rowClassName} flex-container inner level-${this.props.level} ${this.hasChanged()?"highlighted":""}`},n.createElement("div",{className:"flex-item first"},n.createElement("span",null,this.props.label)),n.createElement("div",{className:"flex-item"},n.createElement(pn,{className:"admin inline",items:this.allowedCtlFunctions,value:K,disabled:!0})),e.items.map(e=>n.createElement("div",{key:`${this.props.actionName}-${e.id}`,className:"flex-item input"},n.createElement(pn,{className:"inline",items:this.allowedCtlFunctions,value:this.getCtlFunctionForRole(e),disabled:!(this.props.rbacs?.length>0&&this.getCtlFunctionForRole(e)),onChange:t=>this.handleInputChange(t,e)}),!this.getCtlFunctionForRole(e)&&n.createElement("div",{className:"warning-message"},"There is no valid setting found for this action.")))))}}sm.propTypes={label:i().string.isRequired,level:i().number.isRequired,actionName:i().string.isRequired,rbacs:i().object,rbacsUpdated:i().object,roles:i().instanceOf(nm).isRequired,onChange:i().func.isRequired,t:i().func};const im=(0,f.CI)("common")(sm);class rm extends sa{constructor(e){super(e,rm.RESOURCE_NAME)}static get RESOURCE_NAME(){return"roles"}async findAll(){const e=await this.apiClient.findAll(),t=e.body&&e.body.length?e.body:[];return new oa({header:e.header,body:t})}async create(e){if(!e||!e.name)throw new TypeError("Role creation failed, invalid role data.");(0,ie.A)(e.name);const t=await this.apiClient.create(e);return new oa(t)}async update(e,t){if(!e)throw new TypeError("Role update failed, role id is required.");if(!ta(e))throw new TypeError("Role update failed, role id is not a valid uuid.");if(!t||!t.name)throw new TypeError("Role update failed, invalid role data.");(0,ie.A)(t.name);const a=await this.apiClient.update(e,t);return new oa(a)}async delete(e){if(!ta(e))throw new TypeError("Role deletion failed, roleId is not a valid uuid.");const t=await this.apiClient.delete(e);return new oa(t)}}var om;function lm(){return lm=Object.assign?Object.assign.bind():function(e){for(var t=1;tthis.roleEntity.validate(e));verifyDataHealth=(0,po.A)(e=>this.roleEntity.verifyHealth());handleClose(){this.props.onClose()}handleInputChange(e){const t=e.target,a=t.value,n=t.name;this.roleEntity.set(n,a,{validate:!1});const s={role:this.roleEntity.toDto()};this.setState(s)}async handleFormSubmit(e){if(e.preventDefault(),this.state.processing)return;this.setState({hasAlreadyBeenValidated:!0,processing:!0});const t=this.roleEntity.validate();if(t?.hasErrors()||this.roleEntity.isAReservedRole())return this.focusFirstFieldError(),void this.setState({processing:!1});await this.props.onSubmit(this.roleEntity),this.handleClose()}focusFirstFieldError(){this.nameRef.current.focus()}hasAllInputDisabled(){return this.state.processing}get translate(){return this.props.t}render(){const e=this.verifyDataHealth(this.state.role),t=this.state.hasAlreadyBeenValidated?this.validateForm(this.state.role):null,a=this.state.hasAlreadyBeenValidated&&this.roleEntity.isAReservedRole();return n.createElement(qt,{className:"role-create-dialog",title:this.translate("Create role"),onClose:this.handleClose,disabled:this.hasAllInputDisabled()},n.createElement("form",{className:"role-create-form",onSubmit:this.handleFormSubmit,noValidate:!0},n.createElement("div",{className:"form-content"},n.createElement("div",{className:`input text required ${t?.hasError("name")||a?"error":""} ${this.hasAllInputDisabled()?"disabled":""}`},n.createElement("label",{htmlFor:"role-name-input"},n.createElement(f.x6,null,"Role name"),e?.hasErrors()&&n.createElement(tt,{className:"attention-required"})),n.createElement("input",{id:"role-name-input",name:"name",ref:this.nameRef,type:"text",value:this.state.role.name,placeholder:this.props.t("New role"),maxLength:ge.ROLE_NAME_MAX_LENGTH,disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,autoComplete:"off",autoFocus:!0}),t?.hasErrors()&&n.createElement("div",{className:"error-message"},t?.hasError("name","maxLength")&&n.createElement(f.x6,null,"A name can not be more than 50 char in length."),t?.hasError("name","minLength")&&n.createElement(f.x6,null,"A name is required."),t?.hasError("name","trailing-spaces")&&n.createElement(f.x6,null,"The name contains forbidden trailing spaces.")),t?.hasError("name","maxLength")&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"A name can not be more than 255 char in length.")),a&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"This name is reserved by the system.")),e?.hasError("name","maxLength")&&n.createElement("div",{className:"name warning-message"},n.createElement("strong",null,n.createElement(f.x6,null,"Warning:"))," ",n.createElement(f.x6,null,"this is the maximum size for this field, make sure your data was not truncated.")))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement(gn,{disabled:this.hasAllInputDisabled(),onClick:this.handleClose}),n.createElement(qs,{disabled:this.hasAllInputDisabled(),processing:this.state.processing,value:this.translate("Save")}))))}}bm.propTypes={onClose:i().func,onSubmit:i().func.isRequired,t:i().func};const fm=(0,f.CI)("common")(bm);function Em(){return Em=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},onClose:()=>{}});class wm extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.bindCallbacks(),this.createRefs()}get defaultState(){return{dropdownOpen:!1,onClose:this.handleCloseDropdown.bind(this),onOpen:this.handleOpenDropdown.bind(this)}}createRefs(){this.dropdownRef=n.createRef()}bindCallbacks(){this.handleDocumentClickEvent=this.handleDocumentClickEvent.bind(this),this.handleDocumentContextualMenuEvent=this.handleDocumentContextualMenuEvent.bind(this),this.handleDocumentDragStartEvent=this.handleDocumentDragStartEvent.bind(this),this.handleCloseDropdown=this.handleCloseDropdown.bind(this)}componentDidMount(){document.addEventListener("click",this.handleDocumentClickEvent,{capture:!0}),document.addEventListener("contextmenu",this.handleDocumentContextualMenuEvent,{capture:!0}),document.addEventListener("dragstart",this.handleDocumentDragStartEvent,{capture:!0})}componentWillUnmount(){document.removeEventListener("click",this.handleDocumentClickEvent,{capture:!0}),document.removeEventListener("contextmenu",this.handleDocumentContextualMenuEvent,{capture:!0}),document.removeEventListener("dragstart",this.handleDocumentDragStartEvent,{capture:!0})}handleDocumentDragStartEvent(){this.handleCloseDropdown()}handleDocumentClickEvent(e){this.dropdownRef.current.contains(e.target)||this.handleCloseDropdown()}handleDocumentContextualMenuEvent(e){this.dropdownRef.current.contains(e.target)||this.handleCloseDropdown()}handleCloseDropdown(){this.setState({dropdownOpen:!1})}handleOpenDropdown(){const e=!this.state.dropdownOpen;this.setState({dropdownOpen:e})}render(){return n.createElement(vm.Provider,{value:this.state},n.createElement("div",{className:"dropdown",ref:this.dropdownRef},this.props.children))}}function km(e){return class extends n.Component{render(){return n.createElement(vm.Consumer,null,t=>n.createElement(e,Em({dropdownContext:t},this.props)))}}}wm.propTypes={children:i().any};class _m extends n.Component{render(){return n.createElement(wm,null,this.props.children)}}_m.propTypes={children:i().any.isRequired};const xm=_m;class Sm extends n.Component{constructor(e){super(e),this.bindCallbacks()}bindCallbacks(){this.handleDropdownMenuClickEvent=this.handleDropdownMenuClickEvent.bind(this)}handleDropdownMenuClickEvent(){this.props.dropdownContext.onOpen()}get dropdownOpen(){return this.props.dropdownContext.dropdownOpen}render(){return n.createElement("button",{type:"button",className:`${this.props.className} ${this.dropdownOpen?"open":""}`,disabled:this.props.disabled,onClick:this.handleDropdownMenuClickEvent},this.props.children)}}Sm.defaultProps={disabled:!1,direction:"right",className:"button-dropdown"},Sm.propTypes={className:i().string,disabled:i().bool,direction:i().string,dropdownContext:i().any,children:i().any};const Cm=km(Sm);class Nm extends n.Component{get dropdownMenuMustShow(){return this.props.dropdownContext.dropdownOpen}render(){return this.dropdownMenuMustShow&&n.createElement("ul",{className:`dropdown-content menu visible ${this.props.className} ${this.props.direction}`},this.props.children)}}Nm.defaultProps={direction:"right"},Nm.propTypes={direction:i().string,className:i().string,dropdownContext:i().any,children:i().any};const Tm=km(Nm);class Am extends n.Component{constructor(e){super(e),this.bindCallback()}bindCallback(){this.handleClick=this.handleClick.bind(this)}handleClick(){this.props.keepOpenOnClick||this.props.dropdownContext.onClose()}render(){return n.createElement("li",{onClick:this.handleClick,className:this.props.separator?"separator-after":""},n.createElement("div",{className:"row"},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},this.props.children))))}}Am.defaultProps={keepOpenOnClick:!1},Am.propTypes={separator:i().bool,keepOpenOnClick:i().bool,dropdownContext:i().any,children:i().any};const Im=km(Am);class Rm extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.initEventHandlers()}get defaultState(){return{processing:!1}}initEventHandlers(){this.handleClose=this.handleClose.bind(this),this.handleFormSubmit=this.handleFormSubmit.bind(this)}async handleFormSubmit(e){e.preventDefault(),this.state.processing||(this.delete(),this.handleClose())}handleClose(){this.props.onClose()}delete(){this.setState({processing:!0}),this.props.onSubmit(this.props.role)}hasAllInputDisabled(){return this.state.processing}get translate(){return this.props.t}render(){return n.createElement(qt,{title:this.translate("Delete role?"),onClose:this.handleClose,disabled:this.state.processing,className:"delete-role-dialog"},n.createElement("form",{onSubmit:this.handleFormSubmit,noValidate:!0},n.createElement("div",{className:"form-content"},n.createElement("p",null,n.createElement(f.x6,null,"Are you sure you want to delete the role"," ",n.createElement("strong",{className:"dialog-variable"},{roleName:this.props.role.name}),"?")),n.createElement("p",null,n.createElement(f.x6,null,"Once the role is deleted, it will be removed permanently and will not be recoverable."))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement(gn,{disabled:this.hasAllInputDisabled(),onClick:this.handleClose}),n.createElement(qs,{disabled:this.hasAllInputDisabled(),processing:this.state.processing,value:this.translate("Delete"),warning:!0}))))}}Rm.propTypes={onClose:i().func,onSubmit:i().func,role:i().instanceOf(ge).isRequired,t:i().func};const Pm=(0,f.CI)("common")(Rm);class Dm extends n.Component{constructor(e){super(e),this.roleEntity=new ge(e.role),this.state=this.defaultState,this.createInputRefs(),this.bindEventHandlers()}get defaultState(){return{processing:!1,role:this.roleEntity.toDto(),hasAlreadyBeenValidated:!1}}createInputRefs(){this.nameRef=n.createRef()}bindEventHandlers(){this.handleClose=this.handleClose.bind(this),this.handleInputChange=this.handleInputChange.bind(this),this.handleFormSubmit=this.handleFormSubmit.bind(this)}validateForm=(0,po.A)(e=>this.roleEntity.validate(e));verifyDataHealth=(0,po.A)(e=>this.roleEntity.verifyHealth());handleClose(){this.props.onClose()}handleInputChange(e){const t=e.target,a=t.value,n=t.name;this.roleEntity.set(n,a,{validate:!1});const s={role:this.roleEntity.toDto()};this.setState(s)}async handleFormSubmit(e){if(e.preventDefault(),this.state.processing)return;this.setState({hasAlreadyBeenValidated:!0,processing:!0});const t=this.roleEntity.validate();if(t?.hasErrors()||this.roleEntity.isAReservedRole())return this.focusFirstFieldError(),void this.setState({processing:!1});await this.props.onSubmit(this.roleEntity),this.handleClose()}focusFirstFieldError(){this.nameRef.current.focus()}hasAllInputDisabled(){return this.state.processing}get translate(){return this.props.t}render(){const e=this.verifyDataHealth(this.state.role),t=this.state.hasAlreadyBeenValidated?this.validateForm(this.state.role):null,a=this.state.hasAlreadyBeenValidated&&this.roleEntity.isAReservedRole();return n.createElement(qt,{className:"role-edit-dialog",title:this.translate("Rename role"),onClose:this.handleClose,disabled:this.hasAllInputDisabled()},n.createElement("form",{className:"role-edit-form",onSubmit:this.handleFormSubmit,noValidate:!0},n.createElement("div",{className:"form-content"},n.createElement("div",{className:`input text required ${t?.hasError("name")||a?"error":""} ${this.hasAllInputDisabled()?"disabled":""}`},n.createElement("label",{htmlFor:"role-name-input"},n.createElement(f.x6,null,"Role name"),e?.hasErrors()&&n.createElement(tt,{className:"attention-required"})),n.createElement("input",{id:"role-name-input",name:"name",ref:this.nameRef,type:"text",value:this.state.role.name,maxLength:ge.ROLE_NAME_MAX_LENGTH,disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,autoComplete:"off",autoFocus:!0}),t?.hasErrors()&&n.createElement("div",{className:"error-message"},t?.hasError("name","maxLength")&&n.createElement(f.x6,null,"A name can not be more than 50 char in length."),t?.hasError("name","minLength")&&n.createElement(f.x6,null,"A name is required."),t?.hasError("name","trailing-spaces")&&n.createElement(f.x6,null,"The name contains forbidden trailing spaces.")),a&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"This name is reserved by the system.")),e?.hasError("name","maxLength")&&n.createElement("div",{className:"name warning-message"},n.createElement("strong",null,n.createElement(f.x6,null,"Warning:"))," ",n.createElement(f.x6,null,"this is the maximum size for this field, make sure your data was not truncated.")))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement(gn,{disabled:this.hasAllInputDisabled(),onClick:this.handleClose}),n.createElement(qs,{disabled:this.hasAllInputDisabled(),processing:this.state.processing,value:this.translate("Save")}))))}}Dm.propTypes={onClose:i().func,onSubmit:i().func.isRequired,role:i().instanceOf(ge).isRequired,t:i().func};const Om=(0,f.CI)("common")(Dm);class Mm extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.initEventHandlers()}get defaultState(){return{processing:!1}}initEventHandlers(){this.handleClose=this.handleClose.bind(this),this.handleFormSubmit=this.handleFormSubmit.bind(this)}async handleFormSubmit(e){e.preventDefault(),this.state.processing||(this.setState({processing:!0}),this.handleClose())}handleClose(){this.props.onClose()}hasAllInputDisabled(){return this.state.processing}get translate(){return this.props.t}render(){return n.createElement(qt,{title:this.translate("Delete role"),onClose:this.handleClose,disabled:this.state.processing,className:"delete-role-not-allowed-dialog"},n.createElement("form",{onSubmit:this.handleFormSubmit,noValidate:!0},n.createElement("div",{className:"form-content"},n.createElement("p",null,n.createElement(f.x6,null,"The role ",n.createElement("strong",{className:"dialog-variable"},{roleName:this.props.role.name})," can’t be deleted yet.")),n.createElement("p",null,n.createElement(f.x6,{count:this.props.usersCount},{count:this.props.usersCount}," user is still assigned to this role.")," ",n.createElement(f.x6,{count:this.props.usersCount},"Assign him a different role, then try deleting"," ",n.createElement("strong",{className:"dialog-variable"},{roleName:this.props.role.name})," again."))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement(gn,{disabled:this.hasAllInputDisabled(),onClick:this.handleClose}),n.createElement(qs,{disabled:this.hasAllInputDisabled(),processing:this.state.processing,value:this.translate("Ok")}))))}}Mm.propTypes={onClose:i().func,role:i().instanceOf(ge).isRequired,usersCount:i().number.isRequired,t:i().func};const Um=(0,f.CI)("common")(Mm);class Fm extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.bindCallbacks();const t=this.props.context.getApiClientOptions();this.roleApiService=new this.props.RoleApiService(t),this.rbacApiService=new this.props.RbacApiService(t),this.userApiService=new this.props.UserApiService(t)}get defaultState(){return{roles:null}}bindCallbacks(){this.updateRbacControlFunction=this.updateRbacControlFunction.bind(this),this.handleAddRoleClick=this.handleAddRoleClick.bind(this),this.createNewRole=this.createNewRole.bind(this),this.handleDeleteRoleClick=this.handleDeleteRoleClick.bind(this),this.deleteRole=this.deleteRole.bind(this),this.handleRenameRoleClick=this.handleRenameRoleClick.bind(this),this.renameRole=this.renameRole.bind(this)}async componentDidMount(){this.findAndLoadData()}componentWillUnmount(){this.props.adminRbacContext.clearContext()}findAndLoadData(){this.findAndLoadRoles(),this.findAndLoadRbacSettings()}async findAndLoadRoles(){const e=(await this.roleApiService.findAll()).body,t=new nm(e);t.filterOutGuestRole(),this.setState({roles:t})}async findAndLoadRbacSettings(){const e=(await this.rbacApiService.findAll({ui_action:!0,action:!0})).body,t=new Wc(e,!0);this.props.adminRbacContext.setRbacs(t)}updateRbacControlFunction(e,t,a){const n=this.props.adminRbacContext.rbacsUpdated,s=this.props.adminRbacContext.rbacs.findRbacByRoleAndActionName(e,t);if(s.controlFunction===a)n.remove(s);else{const e=new Vc(s.toDto({ui_action:!0,action:!0}));e.controlFunction=a,n.pushOrReplace(e)}this.props.adminRbacContext.setRbacsUpdated(n)}handleAddRoleClick(e){e.preventDefault(),this.props.dialogContext.open(fm,{onSubmit:this.createNewRole})}async createNewRole(e){try{await this.roleApiService.create(e.toDto()),this.findAndLoadData(),await this.props.actionFeedbackContext.displaySuccess(this.props.t("The role has been created successfully."))}catch(e){this.props.dialogContext.open($t,{error:e})}}async handleDeleteRoleClick(e,t){e.preventDefault();const a=(await this.userApiService.findAll()).body.filter(e=>e.role_id===t.id);a.length>0?this.props.dialogContext.open(Um,{role:t,usersCount:a.length}):this.props.dialogContext.open(Pm,{role:t,onSubmit:this.deleteRole})}async deleteRole(e){try{await this.roleApiService.delete(e.id),this.findAndLoadData(),await this.props.actionFeedbackContext.displaySuccess(this.props.t("The role has been deleted successfully."))}catch(e){this.props.dialogContext.open($t,{error:e})}}async handleRenameRoleClick(e,t){e.preventDefault(),this.props.dialogContext.open(Om,{role:t,onSubmit:this.renameRole})}async renameRole(e){try{await this.roleApiService.update(e.id,e.toUpdateDto()),this.findAndLoadData(),await this.props.actionFeedbackContext.displaySuccess(this.props.t("The role has been updated successfully."))}catch(e){this.props.dialogContext.open($t,{error:e})}}get canIUseTags(){return this.props.context.siteSettings.canIUse("tags")}get canIUseDesktop(){return this.props.context.siteSettings.canIUse("desktop")}get canIUseMobile(){return this.props.context.siteSettings.canIUse("mobile")}get canIUseFolders(){return this.props.context.siteSettings.canIUse("folders")}get canIUsePreviewPassword(){return this.props.context.siteSettings.canIUse("previewPassword")}get canIUseExport(){return this.props.context.siteSettings.canIUse("export")}get canIUseImport(){return this.props.context.siteSettings.canIUse("import")}get canIUseAccountRecovery(){return this.props.context.siteSettings.canIUse("accountRecovery")}get isReady(){return null!==this.state.roles}get canAddNewRole(){const e=nm.getSchema().maxItems-1;return null!==this.state.roles&&this.state.roles.lengthe.isUser()),a=this.state.roles.items.filter(e=>!e.isAdmin()&&!e.isUser());e.push(t,...a)}return new nm(e,{validate:!1})}blankColumnSectionForRoles(){const e=[];return this.state.roles?.items.forEach((t,a)=>{e.push(n.createElement("div",{className:"flex-item",key:a}," "))}),n.createElement(n.Fragment,null,e)}render(){const e=this.props.adminRbacContext.hasSettingsChanges(),t=this.customizableRoles,a=this.state.roles?.length;return n.createElement("div",{className:"row"},n.createElement("div",{className:"rbac-settings main-column"},n.createElement("div",{className:"main-content"},n.createElement("h3",{className:"title"},n.createElement(f.x6,null,"Role-Based Access Control")),n.createElement("div",{className:"section-header"},n.createElement("p",null,n.createElement(f.x6,null,"In this section you can define access controls for each user role.")),n.createElement("button",{type:"button",className:"button",onClick:this.handleAddRoleClick,disabled:!this.canAddNewRole,title:this.canAddNewRole?"":this.props.t("Maximum number of roles reached")},n.createElement(cm,null)," ",n.createElement(f.x6,null,"Add role"))),n.createElement("form",{className:"form"},n.createElement("div",{className:"flex-container outer"},n.createElement("div",{className:"flex-container inner header-flex"},n.createElement("div",{className:"flex-item first"}," "),n.createElement("div",{className:"flex-item centered"},n.createElement("span",{className:"ellipsis",title:this.props.t("Admin")},n.createElement(f.x6,null,"Admin"))),t.items.map(e=>n.createElement("div",{className:"flex-item centered",key:e.id},n.createElement("span",{className:"ellipsis",title:oe(this.getTranslatedRoleName(e))},oe(this.getTranslatedRoleName(e))),!e.isAReservedRole()&&n.createElement(xm,null,n.createElement(Cm,{className:"more button-action-icon link no-border"},n.createElement(um,null)),n.createElement(Tm,{className:"menu-action-contextual",direction:"left"},n.createElement(Im,null,n.createElement("button",{id:"rename_role_action",type:"button",className:"no-border",onClick:t=>this.handleRenameRoleClick(t,e)},n.createElement(ym,null),n.createElement("span",null,n.createElement(f.x6,null,"Rename")))),n.createElement(Im,null,n.createElement("button",{id:"delete_role_action",type:"button",className:"no-border",onClick:t=>this.handleDeleteRoleClick(t,e)},n.createElement(dl,null),n.createElement("span",null,n.createElement(f.x6,null,"Delete"))))))))),this.isReady&&n.createElement(n.Fragment,null,n.createElement("div",{className:"flex-container inner header-flex"},n.createElement("div",{className:"flex-item first"},n.createElement("label",null,n.createElement(f.x6,null,"API Permissions"))),this.blankColumnSectionForRoles()),n.createElement(am,{label:this.props.t("Group management"),level:1,rolesCount:a},n.createElement(im,{label:this.props.t("Create a group"),actionName:j,level:2,rbacs:this.props.adminRbacContext.rbacs,rbacsUpdated:this.props.adminRbacContext.rbacsUpdated,roles:t,onChange:this.updateRbacControlFunction})),this.canIUseAccountRecovery&&n.createElement(n.Fragment,null,n.createElement(am,{label:this.props.t("Account recovery request"),level:1,rolesCount:a},n.createElement(im,{label:this.props.t("Account recovery request view"),actionName:L,level:2,rbacs:this.props.adminRbacContext.rbacs,rbacsUpdated:this.props.adminRbacContext.rbacsUpdated,roles:t,onChange:this.updateRbacControlFunction}),n.createElement(im,{label:this.props.t("Account recovery request index"),actionName:q,level:2,rbacs:this.props.adminRbacContext.rbacs,rbacsUpdated:this.props.adminRbacContext.rbacsUpdated,roles:t,onChange:this.updateRbacControlFunction}),n.createElement(im,{label:this.props.t("Account recovery request review"),actionName:z,level:2,rbacs:this.props.adminRbacContext.rbacs,rbacsUpdated:this.props.adminRbacContext.rbacsUpdated,roles:t,onChange:this.updateRbacControlFunction}))),n.createElement("div",{className:"flex-container inner header-flex"},n.createElement("div",{className:"flex-item first"},n.createElement("label",null,n.createElement(f.x6,null,"UI Permissions"))),this.blankColumnSectionForRoles()),n.createElement(am,{label:this.props.t("Resources"),level:1,rolesCount:a},(this.canIUseImport||this.canIUseExport)&&n.createElement(am,{label:this.props.t("Import/Export"),level:2,rolesCount:a},this.canIUseImport&&n.createElement(im,{label:this.props.t("Can import"),actionName:"Resources.import",level:3,rbacs:this.props.adminRbacContext.rbacs,rbacsUpdated:this.props.adminRbacContext.rbacsUpdated,roles:t,onChange:this.updateRbacControlFunction}),this.canIUseExport&&n.createElement(im,{label:this.props.t("Can export"),actionName:"Resources.export",level:3,rbacs:this.props.adminRbacContext.rbacs,rbacsUpdated:this.props.adminRbacContext.rbacsUpdated,roles:t,onChange:this.updateRbacControlFunction})),n.createElement(am,{label:this.props.t("Password"),level:2,rolesCount:a},this.canIUsePreviewPassword&&n.createElement(im,{label:this.props.t("Can preview"),actionName:"Secrets.preview",level:3,rbacs:this.props.adminRbacContext.rbacs,rbacsUpdated:this.props.adminRbacContext.rbacsUpdated,roles:t,onChange:this.updateRbacControlFunction}),n.createElement(im,{label:this.props.t("Can copy"),actionName:"Secrets.copy",level:3,rbacs:this.props.adminRbacContext.rbacs,rbacsUpdated:this.props.adminRbacContext.rbacsUpdated,roles:t,onChange:this.updateRbacControlFunction})),n.createElement(am,{label:this.props.t("Metadata"),level:2,rolesCount:a},n.createElement(im,{label:this.props.t("Can see password activities"),actionName:"Resources.seeActivities",level:3,rbacs:this.props.adminRbacContext.rbacs,rbacsUpdated:this.props.adminRbacContext.rbacsUpdated,roles:t,onChange:this.updateRbacControlFunction}),n.createElement(im,{label:this.props.t("Can see password comments"),actionName:"Resources.seeComments",level:3,rbacs:this.props.adminRbacContext.rbacs,rbacsUpdated:this.props.adminRbacContext.rbacsUpdated,roles:t,onChange:this.updateRbacControlFunction})),(this.canIUseFolders||this.canIUseTags)&&n.createElement(am,{label:this.props.t("Organization"),level:2,rolesCount:a},this.canIUseFolders&&n.createElement(im,{label:this.props.t("Can use folders"),actionName:M,level:3,rbacs:this.props.adminRbacContext.rbacs,rbacsUpdated:this.props.adminRbacContext.rbacsUpdated,roles:t,onChange:this.updateRbacControlFunction}),this.canIUseTags&&n.createElement(im,{label:this.props.t("Can use tags"),actionName:"Tags.use",level:3,rbacs:this.props.adminRbacContext.rbacs,rbacsUpdated:this.props.adminRbacContext.rbacsUpdated,roles:t,onChange:this.updateRbacControlFunction})),n.createElement(am,{label:this.props.t("Sharing"),level:2,rolesCount:a},n.createElement(im,{label:this.props.t("Can see with whom passwords are shared with"),actionName:"Share.viewList",level:3,rbacs:this.props.adminRbacContext.rbacs,rbacsUpdated:this.props.adminRbacContext.rbacsUpdated,roles:t,onChange:this.updateRbacControlFunction}),n.createElement(im,{label:this.props.t("Can share folders"),actionName:"Folders.share",level:3,rbacs:this.props.adminRbacContext.rbacs,rbacsUpdated:this.props.adminRbacContext.rbacsUpdated,roles:t,onChange:this.updateRbacControlFunction}))),n.createElement(am,{label:this.props.t("Users"),level:1,rolesCount:a},n.createElement(im,{label:this.props.t("Can see users workspace"),actionName:U,level:2,rbacs:this.props.adminRbacContext.rbacs,rbacsUpdated:this.props.adminRbacContext.rbacsUpdated,roles:t,onChange:this.updateRbacControlFunction})),(this.canIUseMobile||this.canIUseDesktop)&&n.createElement(am,{label:this.props.t("User settings"),level:1,rolesCount:a},this.canIUseMobile&&n.createElement(im,{label:this.props.t("Can see mobile setup"),actionName:"Mobile.transfer",level:2,rbacs:this.props.adminRbacContext.rbacs,rbacsUpdated:this.props.adminRbacContext.rbacsUpdated,roles:t,onChange:this.updateRbacControlFunction}),this.canIUseDesktop&&n.createElement(im,{label:this.props.t("Can see desktop application setup"),actionName:"Desktop.transfer",level:2,rbacs:this.props.adminRbacContext.rbacs,rbacsUpdated:this.props.adminRbacContext.rbacsUpdated,roles:t,onChange:this.updateRbacControlFunction})))))),e&&n.createElement("div",{className:"warning message"},n.createElement("div",null,n.createElement("p",null,n.createElement(f.x6,null,"Don't forget to save your settings to apply your modification."))))),n.createElement(em,null),Xa(n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"Need help?")),n.createElement("p",null,n.createElement(f.x6,null,"Check out the Role Based Access Control documentation.")),n.createElement("a",{className:"button",href:"https://passbolt.com/docs/admin/role-based-access-control/",target:"_blank",rel:"noopener noreferrer"},n.createElement(ps,null),n.createElement("span",null,n.createElement(f.x6,null,"Read RBAC doc")))),document.getElementById("administration-help-panel")))}}Fm.defaultProps={RoleApiService:rm,RbacApiService:Hc,UserApiService:Sn},Fm.propTypes={context:i().object,administrationWorkspaceContext:i().object,adminRbacContext:i().object,dialogContext:i().object,RoleApiService:i().func,RbacApiService:i().func,UserApiService:i().func,t:i().func};const jm=N(Xc(Ne(h(m((0,f.CI)("common")(Fm)))))),Lm=class{constructor(e={}){this.default_generator=e.provider,this.external_dictionary_check=e.policyPassphraseExternalServices,this.password_generator_settings={min_length:e.minLength??8,max_length:e.minLength??128,length:e.passwordLength,mask_upper:e.mask_upper,mask_lower:e.mask_lower,mask_digit:e.mask_digit,mask_parenthesis:e.mask_parenthesis,mask_char1:e.mask_char1,mask_char2:e.mask_char2,mask_char3:e.mask_char3,mask_char4:e.mask_char4,mask_char5:e.mask_char5,mask_emoji:e.mask_emoji,exclude_look_alike_chars:e.excludeLookAlikeCharacters},this.passphrase_generator_settings={min_words:e.minWords??4,max_words:e.maxWords??40,words:e.wordsCount,word_separator:e.wordsSeparator,word_case:e.wordCase},this.source=e.source}},qm=class{constructor(e={}){this.provider="passphrase"===e?.default_generator?"passphrase":"password",this.policyPassphraseExternalServices=Boolean(e?.external_dictionary_check),this.source=e?.source??"default";const t=e?.password_generator_settings;this.passwordLength=t?.length??18,this.mask_upper=t?.mask_upper??!1,this.mask_lower=t?.mask_lower??!1,this.mask_digit=t?.mask_digit??!1,this.mask_parenthesis=t?.mask_parenthesis??!1,this.mask_char1=t?.mask_char1??!1,this.mask_char2=t?.mask_char2??!1,this.mask_char3=t?.mask_char3??!1,this.mask_char4=t?.mask_char4??!1,this.mask_char5=t?.mask_char5??!1,this.mask_emoji=t?.mask_emoji??!1,this.excludeLookAlikeCharacters=t?.exclude_look_alike_chars??!1;const a=e?.passphrase_generator_settings;this.wordsCount=a?.words??9,this.wordsSeparator=a?.word_separator??" ",this.wordCase=a?.word_case??"lowercase"}};function zm(){return zm=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},getSettingsErrors:()=>{},setSettings:()=>{},hasSettingsChanges:()=>{},findSettings:()=>{},setProcessing:()=>{},isProcessing:()=>{},isDataValid:()=>{},clearContext:()=>{},save:()=>{},validateData:()=>{},getPasswordGeneratorMasks:()=>{},getEntropyForPassphraseConfiguration:()=>{},getEntropyForPasswordConfiguration:()=>{},getMinimalRequiredEntropy:()=>{},getMinimalAdvisedEntropy:()=>{},isSourceChanging:()=>{}});class Vm extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.hasDataBeenValidated=!1}get defaultState(){return{settings:new qm,errors:{},currentSettings:new qm,processing:!0,getSettings:this.getSettings.bind(this),getSettingsErrors:this.getSettingsErrors.bind(this),setSettings:this.setSettings.bind(this),findSettings:this.findSettings.bind(this),hasSettingsChanges:this.hasSettingsChanges.bind(this),isProcessing:this.isProcessing.bind(this),setProcessing:this.setProcessing.bind(this),clearContext:this.clearContext.bind(this),save:this.save.bind(this),validateData:this.validateData.bind(this),getPasswordGeneratorMasks:this.getPasswordGeneratorMasks.bind(this),getEntropyForPassphraseConfiguration:this.getEntropyForPassphraseConfiguration.bind(this),getEntropyForPasswordConfiguration:this.getEntropyForPasswordConfiguration.bind(this),getMinimalRequiredEntropy:this.getMinimalRequiredEntropy.bind(this),getMinimalAdvisedEntropy:this.getMinimalAdvisedEntropy.bind(this),isSourceChanging:this.isSourceChanging.bind(this)}}async findSettings(e=()=>{}){this.setProcessing(!0);const t=await this.props.context.port.request("passbolt.password-policies.get-admin-settings"),a=new qm(t);this.setState({currentSettings:a,settings:a},e),this.setProcessing(!1)}validateData(){this.hasDataBeenValidated=!0;let e=!0;const t={},a=this.state.settings;a.mask_upper||a.mask_lower||a.mask_digit||a.mask_parenthesis||a.mask_char1||a.mask_char2||a.mask_char3||a.mask_char4||a.mask_char5||a.mask_emoji||(e=!1,t.masks=this.props.t("At least 1 set of characters must be selected")),a.passwordLength<8&&(e=!1,t.passwordLength=this.props.t("The password length must be set to 8 at least")),a.wordsCount<4&&(e=!1,t.wordsCount=this.props.t("The passphrase word count must be set to 4 at least")),a.wordsSeparator.length>10&&(e=!1,t.wordsSeparator=this.props.t("The words separator should be at a maximum of 10 characters long"));const n=this.getMinimalRequiredEntropy();return this.getEntropyForPassphraseConfiguration(){this.hasDataBeenValidated&&this.validateData()})}isProcessing(){return this.state.processing}setProcessing(e){this.setState({processing:e})}hasSettingsChanges(){return JSON.stringify(this.state.currentSettings)!==JSON.stringify(this.state.settings)}isSourceChanging(){return"db"!==this.state.currentSettings?.source&&"default"!==this.state.currentSettings?.source}clearContext(){const{currentSettings:e,settings:t,processing:a}=this.defaultState;this.setState({currentSettings:e,settings:t,processing:a})}render(){return n.createElement(Km.Provider,{value:this.state},this.props.children)}}function Gm(e){return class extends n.Component{render(){return n.createElement(Km.Consumer,null,t=>n.createElement(e,zm({adminPasswordPoliciesContext:t},this.props)))}}}Vm.propTypes={context:i().any,children:i().any,t:i().any,actionFeedbackContext:i().object},N((0,f.CI)("common")(Vm));class Bm extends n.Component{constructor(e){super(e),this.bindCallbacks()}bindCallbacks(){this.handleSave=this.handleSave.bind(this)}get isActionEnabled(){return!this.props.adminPasswordPoliciesContext.isProcessing()}async handleSave(){if(this.isActionEnabled&&this.props.adminPasswordPoliciesContext.validateData())try{await this.props.adminPasswordPoliciesContext.save();const e=this.props.adminPasswordPoliciesContext.getSettings();this.props.passwordPoliciesContext.setPolicies(new Lm(e)),await this.handleSaveSuccess()}catch(e){await this.handleSaveError(e)}}async handleSaveSuccess(){await this.props.actionFeedbackContext.displaySuccess(this.props.t("The password policy settings were updated."))}async handleSaveError(e){console.error(e),await this.props.actionFeedbackContext.displayError(e.message)}render(){const e=!this.isActionEnabled;return n.createElement("div",{className:"actions-wrapper"},n.createElement("button",{type:"button",className:"button primary form",disabled:e,id:"save-settings",onClick:this.handleSave},n.createElement("span",null,n.createElement(f.x6,null,"Save"))))}}Bm.propTypes={adminPasswordPoliciesContext:i().object,passwordPoliciesContext:i().object,actionFeedbackContext:i().object,t:i().func};const Wm=Gm(or(m((0,f.CI)("common")(Bm)))),Hm={COLOR_1:$m("#BA2809"),COLOR_2:$m("#FFA724"),COLOR_3:$m("#0EAA00")};function $m(e){const t=new RegExp("^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$","i").exec(e.trim());return t?{red:parseInt(t[1],16),green:parseInt(t[2],16),blue:parseInt(t[3],16)}:null}class Ym extends n.Component{get entropy(){return(this.props.entropy||0).toFixed(1)}get tooltipMessage(){return n.createElement(n.Fragment,null,n.createElement(f.x6,null,"Entropy:")," ",this.entropy," bits")}get passwordStrengthLabel(){if(!this.hasEntropy()&&!this.hasError())return n.createElement(f.x6,null,"Quality");const e=Vi.strength(this.props.entropy);return n.createElement(n.Fragment,null,e.label)}hasEntropy(){return null!==this.props.entropy&&void 0!==this.props.entropy}hasError(){return this.props.error}getProgresseBarStyle(){const e=this.getRelativeEntropyPosition();return{width:`${e}%`,backgroundColor:this.colorGradient(e)}}colorGradient(e){let t,a,n=e/100*2;return n>=1?(n-=1,t=Hm.COLOR_2,a=Hm.COLOR_3):(t=Hm.COLOR_1,a=Hm.COLOR_2),`rgb(${Math.floor(t.red+(a.red-t.red)*n)},${Math.floor(t.green+(a.green-t.green)*n)},${Math.floor(t.blue+(a.blue-t.blue)*n)})`}getRelativeEntropyPosition(){return 100-99/(1+Math.pow(this.props.entropy/90,10))}render(){return n.createElement("div",{className:"password-complexity"},n.createElement("span",{className:"complexity-text"},n.createElement(Mt,{message:this.tooltipMessage},this.passwordStrengthLabel," ",n.createElement(jt,null))),n.createElement("span",{className:"progress"},n.createElement("span",{className:"progress-bar background"}),n.createElement("span",{className:"progress-bar foreground "+(this.hasError()?"error":""),style:this.hasEntropy()?this.getProgresseBarStyle(this.props.entropy):null})))}}Ym.defaultProps={entropy:null},Ym.propTypes={entropy:i().number,error:i().bool};const Zm=(0,f.CI)("common")(Ym);class Jm extends n.Component{constructor(e){super(e),this.state={showPasswordSection:!1,showPassphraseSection:!1},this.bindCallbacks()}async componentDidMount(){await this.props.adminPasswordPoliciesContext.findSettings()}componentWillUnmount(){this.props.adminPasswordPoliciesContext.clearContext()}bindCallbacks(){this.handleCheckboxInputChange=this.handleCheckboxInputChange.bind(this),this.handleMaskToggled=this.handleMaskToggled.bind(this),this.handlePasswordSectionToggle=this.handlePasswordSectionToggle.bind(this),this.handlePassphraseSectionToggle=this.handlePassphraseSectionToggle.bind(this),this.handleInputChange=this.handleInputChange.bind(this),this.handleSliderInputChange=this.handleSliderInputChange.bind(this),this.handleLengthChange=this.handleLengthChange.bind(this)}handlePasswordSectionToggle(){this.setState({showPasswordSection:!this.state.showPasswordSection})}handlePassphraseSectionToggle(){this.setState({showPassphraseSection:!this.state.showPassphraseSection})}get wordCaseList(){return[{value:"lowercase",label:this.props.t("Lower case")},{value:"uppercase",label:this.props.t("Upper case")},{value:"camelcase",label:this.props.t("Camel case")}]}get providerList(){return[{value:"password",label:this.props.t("Password")},{value:"passphrase",label:this.props.t("Passphrase")}]}handleCheckboxInputChange(e){const t=e.target.name;this.props.adminPasswordPoliciesContext.setSettings(t,e.target.checked)}handleSliderInputChange(e){const t=parseInt(e.target.value,10),a=e.target.name;this.props.adminPasswordPoliciesContext.setSettings(a,t)}handleInputChange(e){const t=e.target,a=t.value,n=t.name;this.props.adminPasswordPoliciesContext.setSettings(n,a)}handleLengthChange(e){const t=e.target,a=parseInt(t.value,10),n=t.name;this.props.adminPasswordPoliciesContext.setSettings(n,a)}handleMaskToggled(e){const t=!this.props.adminPasswordPoliciesContext.getSettings()[e];this.props.adminPasswordPoliciesContext.setSettings(e,t)}hasAllInputDisabled(){return this.props.adminPasswordPoliciesContext.isProcessing()}get settingsSource(){return this.props.adminPasswordPoliciesContext?.getSettings()?.source}get configurationSource(){return{legacyEnv:this.props.t("environment variables (legacy)"),env:this.props.t("environment variables"),legacyFile:this.props.t("file (legacy)"),file:this.props.t("file"),db:this.props.t("database"),default:this.props.t("default configuration")}[this.settingsSource]||this.props.t("unknown")}render(){const e=this.props.adminPasswordPoliciesContext,t=e.getSettings(),a=e.getSettingsErrors(),s=e.getMinimalAdvisedEntropy(),i=e.getEntropyForPasswordConfiguration(),r=e.getEntropyForPassphraseConfiguration(),o=e.getPasswordGeneratorMasks(),l=in.createElement("button",{type:"button",key:e,className:"button button-toggle "+(t[e]?"selected":""),onClick:()=>this.handleMaskToggled(e),disabled:this.hasAllInputDisabled()},a.label))),a.masks&&n.createElement("div",{id:"password-mask-error",className:"error-message"},a.masks),n.createElement("div",{className:"input checkbox"},n.createElement("input",{id:"configure-password-generator-form-exclude-look-alike",type:"checkbox",name:"excludeLookAlikeCharacters",checked:t.excludeLookAlikeCharacters,onChange:this.handleCheckboxInputChange,disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"configure-password-generator-form-exclude-look-alike"},n.createElement(f.x6,null,"Exclude look-alike characters"))),n.createElement("p",null,n.createElement(f.x6,null,"You can select the set of characters used for the passwords that are generated randomly by passbolt in the password generator.")))),n.createElement("div",{className:"accordion-header"},n.createElement("button",{id:"accordion-toggle-passphrase",className:"link no-border",type:"button",onClick:this.handlePassphraseSectionToggle},this.state.showPassphraseSection?n.createElement(Vt,{className:"caret-down"}):n.createElement(Wt,{className:"caret-right"}),n.createElement(f.x6,null,"Passphrase settings"))),this.state.showPassphraseSection&&n.createElement("div",{className:"passphrase-settings"},n.createElement("div",{className:"estimated-entropy input"},n.createElement("label",null,n.createElement(f.x6,null,"Estimated entropy")),n.createElement(Zm,{entropy:r}),a.passphraseMinimalRequiredEntropy&&n.createElement("div",{className:"error-message"},a.passphraseMinimalRequiredEntropy)),n.createElement("div",{className:"input text "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",{htmlFor:"configure-passphrase-generator-form-word-count"},n.createElement(f.x6,null,"Number of words")),n.createElement("div",{className:"slider"},n.createElement("input",{name:"wordsCount",min:"4",max:"40",value:t.wordsCount,type:"range",onChange:this.handleSliderInputChange,disabled:this.hasAllInputDisabled()}),n.createElement("input",{type:"number",id:"configure-passphrase-generator-form-word-count",name:"wordsCount",min:"4",max:"40",value:t.wordsCount,onChange:this.handleLengthChange,disabled:this.hasAllInputDisabled()})),a.wordsCount&&n.createElement("div",{id:"wordsCount-error",className:"error-message"},a.wordsCount)),n.createElement("p",null,n.createElement(f.x6,null,"You can set the default length for the passphrases that are generated randomly by passbolt in the password generator.")),n.createElement("div",{className:"input text "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",{htmlFor:"configure-passphrase-generator-form-words-separator"},n.createElement(f.x6,null,"Words separator")),n.createElement("input",{type:"text",id:"configure-passphrase-generator-form-words-separator",name:"wordsSeparator",value:t.wordsSeparator,onChange:this.handleInputChange,placeholder:this.props.t("Type one or more characters"),disabled:this.hasAllInputDisabled()}),a.wordsSeparator&&n.createElement("div",{className:"error-message"},a.wordsSeparator)),n.createElement("div",{className:"select-wrapper input "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",{htmlFor:"configure-passphrase-generator-form-words-case"},n.createElement(f.x6,null,"Words case")),n.createElement(pn,{id:"configure-passphrase-generator-form-words-case",name:"wordCase",items:this.wordCaseList,value:t.wordCase,onChange:this.handleInputChange,disabled:this.hasAllInputDisabled()}))),n.createElement("h4",{id:"password-policies-external-services-subtitle"},n.createElement("span",{className:"input toggle-switch form-element ready"},n.createElement("input",{id:"passphrase-policy-external-services-toggle-button",type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"policyPassphraseExternalServices",onChange:this.handleCheckboxInputChange,checked:t?.policyPassphraseExternalServices,disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"passphrase-policy-external-services-toggle-button"},n.createElement(f.x6,null,"External services")))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement(f.x6,null,"Allow passbolt to access external services to check if a password has been compromised.")))),m&&n.createElement("div",{className:"warning message"},e.isSourceChanging()&&n.createElement("div",{id:"password-policies-setting-source-changing-banner"},n.createElement("p",null,n.createElement(f.x6,null,"The current configuration comes from a file or environment variables. If you save them, they will be overwritten and come from the database instead."))),e.hasSettingsChanges()&&n.createElement("div",{id:"password-policies-setting-banner"},n.createElement("p",null,n.createElement(f.x6,null,"Don't forget to save your settings to apply your modification."))),l&&n.createElement("div",{id:"minimal-password-entropy-advised-banner"},n.createElement("p",null,n.createElement(f.x6,null,"The current password configuration generates passwords that are not strong enough."),n.createElement("br",null),n.createElement(f.x6,null,"Passbolt recommends a minimum of ",{minimalAdvisedEntropy:s}," bits to be safe."))),c&&n.createElement("div",{id:"minimal-passphrase-entropy-advised-banner"},n.createElement("p",null,n.createElement(f.x6,null,"The current passphrase configuration generates passphrases that are not strong enough."),n.createElement("br",null),n.createElement(f.x6,null,"Passbolt recommends a minimum of ",{minimalAdvisedEntropy:s}," bits to be safe."))))),n.createElement(Wm,null),Xa(n.createElement(n.Fragment,null,n.createElement("div",{className:"sidebar-help-section",id:"password-policies-source"},n.createElement("h3",null,n.createElement(f.x6,null,"Configuration source")),n.createElement("p",null,n.createElement(f.x6,null,"This current configuration source is: "),this.configurationSource,".")),n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"What is password policy?")),n.createElement("p",null,n.createElement(f.x6,null,"For more information about the password policy settings, checkout the dedicated page on the help website.")),n.createElement("a",{className:"button",href:"https://passbolt.com/docs/admin/password-configuration/password-policy/",target:"_blank",rel:"noopener noreferrer"},n.createElement(Er,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation"))))),document.getElementById("administration-help-panel")))}}Jm.propTypes={context:i().object,administrationWorkspaceContext:i().object,adminPasswordPoliciesContext:i().object,t:i().func};const Xm=N(Ne(Gm((0,f.CI)("common")(Jm))));class Qm extends n.Component{render(){return n.createElement("div",{className:"row"},n.createElement("div",{className:"password-policies-settings-teasing main-column"},n.createElement("div",{className:"main-content"},n.createElement("h3",{className:"title",id:"password-policies-settings-title"},n.createElement(f.x6,null,"Password Policy"),n.createElement(Ea,{className:"pro-teasing-icon"})),n.createElement("p",null,n.createElement(f.x6,null,"Ensure strong and consistent passwords entropy across your organisation.")),n.createElement("div",{className:"password-policies-info"},n.createElement("ul",{className:"password-policies-description"},n.createElement("li",null,n.createElement(fs,null),n.createElement(f.x6,null,"Reduce the risk of weak passwords.")),n.createElement("li",null,n.createElement(fs,null),n.createElement(f.x6,null,"Enforce complexity requirements.")),n.createElement("li",null,n.createElement(fs,null),n.createElement(f.x6,null,"Ensure compliance with internal security standards."))),n.createElement("div",null,n.createElement("a",{className:"button primary",href:"https://www.passbolt.com/ce-to-pro?utm_campaign=21060976-CE%20to%20Pro&utm_source=product",target:"_blank",rel:"noopener noreferrer"},n.createElement(f.x6,null,"Upgrade to Passbolt Pro")))))),Xa(n.createElement(n.Fragment,null,n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"Need some help?")),n.createElement("p",null,n.createElement(f.x6,null,"For more information about the password policy settings, checkout the dedicated page on the help website.")),n.createElement("a",{className:"button",href:"https://passbolt.com/docs/admin/password-configuration/password-policy/",target:"_blank",rel:"noopener noreferrer"},n.createElement(Er,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation"))))),document.getElementById("administration-help-panel")))}}Qm.propTypes={context:i().object,t:i().func};const ed=N((0,f.CI)("common")(Qm));class td extends se{constructor(e,t={}){super(ae.validate(td.ENTITY_NAME,e,td.getSchema()),t)}static getSchema(){return{type:"object",required:["entropy_minimum","external_dictionary_check"],properties:{id:{type:"string",format:"uuid"},entropy_minimum:{type:"integer",minimum:50,maximum:224},external_dictionary_check:{type:"boolean"},created:{type:"string",format:"date-time"},created_by:{type:"string",format:"uuid"},modified:{type:"string",format:"date-time"},modified_by:{type:"string",format:"uuid"}}}}static get ENTITY_NAME(){return"UserPassphrasePolicies"}static createFromDefault(e={}){const t=Object.assign({entropy_minimum:50,external_dictionary_check:!0},e);return new td(t)}}const ad=td;class nd{constructor(e={}){this.external_dictionary_check=e?.external_dictionary_check,this.entropy_minimum=e?.entropy_minimum}static getSchema(){const e=ad.getSchema();return{type:"object",required:["entropy_minimum","external_dictionary_check"],properties:{entropy_minimum:e.properties.entropy_minimum,external_dictionary_check:e.properties.external_dictionary_check}}}static fromEntityDto(e){const t={entropy_minimum:parseInt(e?.entropy_minimum,10)||50,external_dictionary_check:Boolean(e?.external_dictionary_check)};return new nd(t)}static isDataDifferent(e,t){return["entropy_minimum","external_dictionary_check"].some(a=>e[a]!==t[a])}toEntityDto(){return{entropy_minimum:this.entropy_minimum,external_dictionary_check:this.external_dictionary_check}}cloneWithMutation(e,t){const a={...this,[e]:t};return new nd(a)}validate(){const e=nd.getSchema();try{ae.validate(this.constructor.name,this,e)}catch(e){return e}return new X}}const sd=nd;function id(){return id=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},setSettings:()=>{},findSettings:()=>{},isProcessing:()=>{},validateData:()=>{},save:()=>{},getErrors:()=>{},hasSettingsChanges:()=>{}});class od extends n.Component{constructor(e){super(e),this.state=this.defaultState}get defaultState(){return{processing:!1,errors:null,hasBeenValidated:!1,isDataModified:!1,settings:new sd,findSettings:this.findSettings.bind(this),getSettings:this.getSettings.bind(this),setSettings:this.setSettings.bind(this),isProcessing:this.isProcessing.bind(this),validateData:this.validateData.bind(this),save:this.save.bind(this),getErrors:this.getErrors.bind(this),hasSettingsChanges:this.hasSettingsChanges.bind(this)}}async findSettings(){this.setState({processing:!0});const e=await this.props.context.port.request("passbolt.user-passphrase-policies.find"),t=sd.fromEntityDto(e);this.setState({settings:t,currentSettings:t,processing:!1})}getSettings(){return this.state.settings}setSettings(e,t){const a=this.state.settings.cloneWithMutation(e,t),n=sd.isDataDifferent(a,this.state.currentSettings);if(!this.state.hasBeenValidated)return void this.setState({settings:a,isDataModified:n});const s=a.validate();this.setState({errors:s,settings:a,isDataModified:n})}isProcessing(){return this.state.processing}validateData(){const e=this.state.settings.validate(),t=e.hasErrors(),a=t?e:null;return this.setState({errors:a,hasBeenValidated:!0}),!t}async save(){this.setState({processing:!0});try{const e=this.state.settings.toEntityDto(),t=await this.props.context.port.request("passbolt.user-passphrase-policies.save",e),a=sd.fromEntityDto(t);this.setState({settings:a,currentSettings:a,processing:!1,isDataModified:!1})}finally{this.setState({processing:!1})}}getErrors(){return this.state.errors}hasSettingsChanges(){return this.state.isDataModified}render(){return n.createElement(rd.Provider,{value:this.state},this.props.children)}}function ld(e){return class extends n.Component{render(){return n.createElement(rd.Consumer,null,t=>n.createElement(e,id({adminUserPassphrasePoliciesContext:t},this.props)))}}}od.propTypes={context:i().any,children:i().any,t:i().any},N((0,f.CI)("common")(od));class cd extends n.Component{constructor(e){super(e),this.bindCallbacks()}bindCallbacks(){this.handleSave=this.handleSave.bind(this)}get isActionEnabled(){return!this.props.adminUserPassphrasePoliciesContext.isProcessing()}async handleSave(){if(this.isActionEnabled&&this.props.adminUserPassphrasePoliciesContext.validateData())try{await this.props.adminUserPassphrasePoliciesContext.save(),await this.handleSaveSuccess()}catch(e){await this.handleSaveError(e)}}async handleSaveSuccess(){await this.props.actionFeedbackContext.displaySuccess(this.props.t("The user passphrase policies were updated."))}async handleSaveError(e){console.error(e),await this.props.actionFeedbackContext.displayError(e.message),this.props.dialogContext.open($t,{error:e})}render(){const e=!this.isActionEnabled;return n.createElement("div",{className:"actions-wrapper"},n.createElement("button",{type:"button",className:"button primary form",disabled:e,id:"save-settings",onClick:this.handleSave},n.createElement("span",null,n.createElement(f.x6,null,"Save"))))}}cd.propTypes={adminUserPassphrasePoliciesContext:i().object,actionFeedbackContext:i().object,dialogContext:i().any,t:i().func};const md=ld(m(h((0,f.CI)("common")(cd))));class dd extends n.PureComponent{constructor(e){super(e),this.bindHandlers()}bindHandlers(){this.handleRangeOptionClick=this.handleRangeOptionClick.bind(this),this.handleRangeChange=this.handleRangeChange.bind(this)}handleRangeOptionClick(e){this.props.disabled||this.props.onChange(this.props.id,e)}handleRangeChange(e){const t=e.target;this.props.onChange(t.name,this.values[t.value].value)}getComputedStyleForEntropyStep(e,t){return{left:e*(100/(t-1))+"%"}}getValueIndex(e){return this.values.findIndex(t=>t.value===e)}get values(){return[{label:"50 bits",value:50},{label:"64 bits",value:64},{label:"80 bits",value:80},{label:"96 bits",value:96},{label:"128 bits",value:128},{label:"160 bits",value:160},{label:"192 bits",value:192},{label:"224 bits",value:224}]}render(){const e=this.values,t=e.length,{id:a,value:s}=this.props;return n.createElement("div",{className:"range-wrapper"},n.createElement("div",{className:"range-labels"},n.createElement("label",{key:"min"},n.createElement(f.x6,null,"Weak")),n.createElement("label",{key:"max"},n.createElement(f.x6,null,"Secure"))),n.createElement("div",{className:"range-input-wrapper"},n.createElement("input",{type:"range",className:"range-input",id:a,name:a,min:0,max:e.length-1,value:this.getValueIndex(s),list:`${this.props.id}-values`,onChange:this.handleRangeChange,required:!0,disabled:this.props.disabled}),n.createElement("ul",{className:"range-options"},e.map((e,a)=>n.createElement("li",{key:`li-${a}`,onClick:()=>this.handleRangeOptionClick(e.value),style:this.getComputedStyleForEntropyStep(a,t),className:"range-option "+(s===e.value?"range-option--active":""),disabled:this.props.disabled},e.label)))))}}dd.propTypes={value:i().number.isRequired,id:i().string.isRequired,onChange:i().func,disabled:i().bool};const ud=(0,f.CI)("common")(dd);class pd extends n.PureComponent{constructor(e){super(e),this.state=this.defaultState,this.bindCallbacks()}get defaultState(){return{isReady:!1}}async componentDidMount(){await this.props.adminUserPassphrasePoliciesContext.findSettings(),this.setState({isReady:!0})}bindCallbacks(){this.handleMinimumEntropyChange=this.handleMinimumEntropyChange.bind(this),this.handleCheckboxInputChange=this.handleCheckboxInputChange.bind(this)}hasAllInputDisabled(){return this.props.adminUserPassphrasePoliciesContext.isProcessing()}handleMinimumEntropyChange(e,t){const a=parseInt(t,10)||0;this.props.adminUserPassphrasePoliciesContext.setSettings(e,a)}handleCheckboxInputChange(e){const t=e.target,a=t.name,n=Boolean(t.checked);this.props.adminUserPassphrasePoliciesContext.setSettings(a,n)}isWeakSettings(e){return e.entropy_minimum<80}get hasWarnings(){const e=this.props.adminUserPassphrasePoliciesContext,t=e.getSettings();return e.hasSettingsChanges()||this.isWeakSettings(t)}render(){if(!this.state.isReady)return null;const e=this.hasAllInputDisabled(),t=this.props.adminUserPassphrasePoliciesContext,a=t.getSettings();return n.createElement("div",{className:"row"},n.createElement("div",{className:"password-policies-settings main-column"},n.createElement("div",{className:"main-content"},n.createElement("h3",{id:"user-passphrase-policies-title",className:"title"},n.createElement(f.x6,null,"User Passphrase Policies")),n.createElement("form",null,n.createElement("h4",{id:"user-passphrase-policies-entropy-minimum"},n.createElement(f.x6,null,"User passphrase minimal entropy")),n.createElement("div",{className:"input range"},n.createElement(ud,{id:"entropy_minimum",onChange:this.handleMinimumEntropyChange,value:a.entropy_minimum,disabled:e})),n.createElement("div",null,n.createElement(f.x6,null,"You can set the minimal entropy for the users' private key passphrase.")," ",n.createElement(f.x6,null,"This is the passphrase that is asked during sign in or recover.")),n.createElement("h4",{id:"user-passphrase-policies-external-services-subtitle"},n.createElement("span",{className:"input toggle-switch form-element ready"},n.createElement("input",{id:"user-passphrase-policies-external-services-toggle-button",type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"external_dictionary_check",onChange:this.handleCheckboxInputChange,checked:a?.external_dictionary_check,disabled:e}),n.createElement("label",{htmlFor:"user-passphrase-policies-external-services-toggle-button"},n.createElement(f.x6,null,"External password dictionary check")))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement(f.x6,null,"Allow passbolt to access external services to check if the user passphrase has been compromised when the user creates it.")))),this.hasWarnings&&n.createElement("div",{className:"warning message"},t.hasSettingsChanges()&&n.createElement("div",{id:"user-passphrase-policies-save-banner"},n.createElement("p",null,n.createElement(f.x6,null,"Don't forget to save your settings to apply your modification."))),this.isWeakSettings(a)&&n.createElement("div",{id:"user-passphrase-policies-weak-settings-banner"},n.createElement("p",null,n.createElement(f.x6,null,"Passbolt recommends passphrase strength to be at minimum of ",{MINIMAL_ADVISED_ENTROPY:80}," bits to be safe."))))),n.createElement(md,null),Xa(n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"What is user passphrase policies?")),n.createElement("p",null,n.createElement(f.x6,null,"For more information about the user passphrase policies, checkout the dedicated page on the help website.")),n.createElement("a",{className:"button",href:"https://passbolt.com/docs/admin/authentication/user-passphrase-policies/",target:"_blank",rel:"noopener noreferrer"},n.createElement(Er,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}pd.propTypes={context:i().object,administrationWorkspaceContext:i().object,adminUserPassphrasePoliciesContext:i().object,t:i().func};const hd=N(Ne(ld((0,f.CI)("common")(pd))));class gd extends n.Component{render(){return n.createElement("div",{className:"row"},n.createElement("div",{className:"user-passphrase-policies-settings-teasing main-column"},n.createElement("div",{className:"main-content"},n.createElement("h3",{id:"user-passphrase-policies-title",className:"title"},n.createElement(f.x6,null,"User Passphrase Policies"),n.createElement(Ea,{className:"pro-teasing-icon"})),n.createElement("p",null,n.createElement(f.x6,null,"Enforce secure user passphrases to protect account access.")),n.createElement("div",{className:"user-passphrase-policies-info"},n.createElement("ul",{className:"user-passphrase-policies-description"},n.createElement("li",null,n.createElement(fs,null),n.createElement(f.x6,null,"Mitigate risks associated with weak passphrases.")),n.createElement("li",null,n.createElement(fs,null),n.createElement(f.x6,null,"Customise minimum length and complexity.")),n.createElement("li",null,n.createElement(fs,null),n.createElement(f.x6,null,"Improve overall user account security."))),n.createElement("div",null,n.createElement("a",{className:"button primary",href:"https://www.passbolt.com/ce-to-pro?utm_campaign=21060976-CE%20to%20Pro&utm_source=product",target:"_blank",rel:"noopener noreferrer"},n.createElement(f.x6,null,"Upgrade to Passbolt Pro")))))),Xa(n.createElement(n.Fragment,null,n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"Need some help?")),n.createElement("p",null,n.createElement(f.x6,null,"For more information about the user passphrase policies, checkout the dedicated page on the help website.")),n.createElement("a",{className:"button",href:"https://www.passbolt.com/docs/admin/authentication/user-passphrase-policies/",target:"_blank",rel:"noopener noreferrer"},n.createElement(Er,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation"))))),document.getElementById("administration-help-panel")))}}gd.propTypes={context:i().object,t:i().func};const yd=N((0,f.CI)("common")(gd));class bd extends se{constructor(e,t={}){super(ae.validate(bd.ENTITY_NAME,e,bd.getSchema()),t)}static getSchema(){return{type:"object",required:["automatic_expiry","automatic_update"],properties:{id:{type:"string",format:"uuid"},default_expiry_period:{type:"null"},policy_override:{type:"boolean"},automatic_expiry:{type:"boolean"},automatic_update:{type:"boolean"},created:{type:"string",format:"date-time"},created_by:{type:"string",format:"uuid"},modified:{type:"string",format:"date-time"},modified_by:{type:"string",format:"uuid"}}}}calculateDefaultResourceExpiryDate(){return null}get isFeatureEnabled(){return Boolean(this._props.id)}static get ENTITY_NAME(){return"PasswordExpirySettings"}static createFromDefault(e={}){const t={default_expiry_period:null,policy_override:!1,automatic_expiry:!1,automatic_update:!1,...e};return new bd(t)}}const fd=bd;class Ed extends se{constructor(e,t={}){super(ae.validate(Ed.ENTITY_NAME,e,Ed.getSchema()),t)}static getSchema(){return{type:"object",required:["automatic_expiry","automatic_update","policy_override"],properties:{id:{type:"string",format:"uuid"},default_expiry_period:{type:"integer",minimum:1,maximum:999,nullable:!0},policy_override:{type:"boolean"},automatic_expiry:{type:"boolean"},automatic_update:{type:"boolean"},created:{type:"string",format:"date-time"},created_by:{type:"string",format:"uuid"},modified:{type:"string",format:"date-time"},modified_by:{type:"string",format:"uuid"}}}}calculateDefaultResourceExpiryDate(){return this.isFeatureEnabled&&this._props.default_expiry_period?Ds.c9.utc().plus({days:this._props.default_expiry_period}).toISO():null}get isFeatureEnabled(){return Boolean(this._props.id)}static get ENTITY_NAME(){return"passwordExpiryProSettingsEntity"}static createFromDefault(e={}){const t={default_expiry_period:null,policy_override:!1,automatic_expiry:!0,automatic_update:!0,...e};return new Ed(t)}}const vd=Ed;class wd{constructor(e={}){this.automatic_update=Boolean(e?.automatic_update),this.policy_override=Boolean(e?.policy_override),this.automatic_expiry=Boolean(e?.automatic_expiry);const t=parseInt(e?.default_expiry_period,10);this.default_expiry_period=isNaN(t)?null:t,this.default_expiry_period_toggle=void 0!==e?.default_expiry_period_toggle?Boolean(e.default_expiry_period_toggle):Boolean(this.default_expiry_period),e?.id&&(this.id=e?.id)}static getSchema(e=!1){const t=e?vd.getSchema():fd.getSchema();return this.getDefaultSchema(t,e)}static getDefaultSchema(e,t=!1){const a={type:"object",required:["automatic_expiry","automatic_update"],properties:{id:e.properties.id,automatic_expiry:e.properties.automatic_expiry,automatic_update:e.properties.automatic_update,policy_override:e.properties.policy_override,default_expiry_period:e.properties.default_expiry_period}};return t&&a.required.push("policy_override"),a}static fromEntityDto(e){const t={automatic_expiry:Boolean(e?.automatic_expiry),automatic_update:Boolean(e?.automatic_update),policy_override:Boolean(e?.policy_override),default_expiry_period:null!==e?.default_expiry_period?parseInt(e?.default_expiry_period,10):null};return e?.id&&(t.id=e.id),new wd(t)}static isDataDifferent(e,t){return["automatic_expiry","automatic_update","policy_override","default_expiry_period"].some(a=>e[a]!==t[a])}toEntityDto(){const e=this.default_expiry_period_toggle?this.default_expiry_period:null;return{automatic_expiry:this.automatic_expiry,automatic_update:this.automatic_update,policy_override:this.policy_override,default_expiry_period:e}}cloneWithMutation(e,t){const a={...this,[e]:t};return new wd(a)}validate(e=!1){const t=new X,a=wd.getSchema(e);try{ae.validate(this.constructor.name,this,a),this.validateFormInput(t,e)}catch(t){if(!(t instanceof X))throw t;return this.validateFormInput(t,e),t}return t}validateFormInput(e,t){t&&this.default_expiry_period_toggle&&null===this.default_expiry_period&&e.addError("default_expiry_period","required","The default_expiry_period is required.")}get isSettingsDisabled(){return!this.id}}const kd=wd;function _d(){return _d=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},get:()=>{},setSettingsBulk:()=>{},findSettings:()=>{},isProcessing:()=>{},validateData:()=>{},save:()=>{},getErrors:()=>{},isFeatureToggleEnabled:()=>{},setFeatureToggle:()=>{},hasSettingsChanges:()=>{},isSubmitted:()=>{},setSubmitted:()=>{},setDefaultExpiryToggle:()=>{}});class Sd extends n.Component{constructor(e){super(e),this.state=this.defaultState}get defaultState(){return{processing:!1,errors:null,hasBeenValidated:!1,isDataModified:!1,submitted:!1,currentSettings:new kd,featureToggleEnabled:!1,settings:new kd,findSettings:this.findSettings.bind(this),getSettings:this.getSettings.bind(this),setSettingsBulk:this.setSettingsBulk.bind(this),isProcessing:this.isProcessing.bind(this),validateData:this.validateData.bind(this),save:this.save.bind(this),getErrors:this.getErrors.bind(this),hasSettingsChanges:this.hasSettingsChanges.bind(this),isFeatureToggleEnabled:this.isFeatureToggleEnabled.bind(this),setFeatureToggle:this.setFeatureToggle.bind(this),setDefaultExpiryToggle:this.setDefaultExpiryToggle.bind(this),isSubmitted:this.isSubmitted.bind(this),setSubmitted:this.setSubmitted.bind(this)}}async findSettings(){this.setState({processing:!0}),this.setState({submitted:!1});const e=await this.props.context.port.request("passbolt.password-expiry.get-or-find",!0),t=kd.fromEntityDto(e);this.setState({toggleEnabled:t?.id,settings:t,currentSettings:t,processing:!1})}setDefaultExpiryToggle(e){let t=this.state.settings.default_expiry_period;e&&null===this.state.settings.default_expiry_period&&(t=90),this.setSettingsBulk({default_expiry_period_toggle:e,default_expiry_period:t})}getSettings(){return this.state.settings}setSubmitted(e){this.setState({submitted:e})}isSubmitted(){return this.state.submitted}setSettingsBulk(e){let t=this.state.settings;const a=Object.keys(e);for(let n=0;nn.createElement(e,_d({adminPasswordExpiryContext:t},this.props)))}}}Sd.propTypes={context:i().any,children:i().any,t:i().any},N((0,f.CI)("common")(Sd));class Nd extends n.Component{constructor(e){super(e),this.bindCallbacks()}bindCallbacks(){this.handleSave=this.handleSave.bind(this)}get isActionEnabled(){return!this.props.adminPasswordExpiryContext.isProcessing()}async handleSave(){if(this.props.adminPasswordExpiryContext.setSubmitted(!0),this.isActionEnabled&&this.props.adminPasswordExpiryContext.validateData())try{await this.props.adminPasswordExpiryContext.save(),await this.handleSaveSuccess()}catch(e){await this.handleSaveError(e)}}async handleSaveSuccess(){await this.props.actionFeedbackContext.displaySuccess(this.props.t("The password expiry settings were updated."))}async handleSaveError(e){console.error(e),await this.props.actionFeedbackContext.displayError(e.message),this.props.dialogContext.open($t,{error:e})}render(){const e=!this.isActionEnabled;return n.createElement("div",{className:"actions-wrapper"},n.createElement("button",{type:"button",className:"button primary form",disabled:e,id:"save-settings",onClick:this.handleSave},n.createElement("span",null,n.createElement(f.x6,null,"Save"))))}}Nd.propTypes={adminPasswordExpiryContext:i().object,actionFeedbackContext:i().object,dialogContext:i().any,t:i().func};const Td=m(Cd(h((0,f.CI)("common")(Nd))));class Ad extends n.PureComponent{constructor(e){super(e),this.bindCallbacks()}bindCallbacks(){this.handleFormSubmit=this.handleFormSubmit.bind(this),this.handleInputChange=this.handleInputChange.bind(this),this.handleExpiryPeriodToggleClick=this.handleExpiryPeriodToggleClick.bind(this)}handleInputChange(e){const{type:t,checked:a,value:n,name:s}=e.target,i="checkbox"===t?a:parseInt(n,10);this.props.adminPasswordExpiryContext.setSettingsBulk({[s]:i})}handleExpiryPeriodToggleClick(e){const t=e.target.checked;this.props.adminPasswordExpiryContext.setDefaultExpiryToggle(t)}async handleFormSubmit(e){if(e.preventDefault(),this.props.adminPasswordExpiryContext.setSubmitted(!0),!this.props.adminPasswordExpiryContext.isProcessing()&&this.props.adminPasswordExpiryContext.validateData())try{await this.props.adminPasswordExpiryContext.save(),await this.handleSaveSuccess()}catch(e){await this.handleSaveError(e)}}async handleSaveSuccess(){await this.props.actionFeedbackContext.displaySuccess(this.props.t("The password expiry settings were updated."))}async handleSaveError(e){await this.props.actionFeedbackContext.displayError(e.message),this.props.dialogContext.open($t,{error:e})}hasAllInputDisabled(){return this.props.adminPasswordExpiryContext.isProcessing()}get settings(){return this.props.adminPasswordExpiryContext.getSettings()}get errors(){const e=this.props.adminPasswordExpiryContext.getErrors();return e?.details}render(){const e=this.props.adminPasswordExpiryContext.isSubmitted(),t=this.settings.default_expiry_period||"",a=Boolean(this.settings?.default_expiry_period_toggle);return n.createElement("div",{id:"password-expiry-form-advanced"},n.createElement("form",{className:"form",onSubmit:this.handleFormSubmit},n.createElement("h4",{className:"no-border",id:"expiry-policies-subtitle"},n.createElement(f.x6,null,"Expiry Policies")),n.createElement("p",{id:"expiry-policies-description"},n.createElement(f.x6,null,"In this section you can choose the default behaviour of password expiry policy for all users.")),n.createElement("div",{className:"togglelist-alt"},n.createElement("span",{id:"default-expiry-period",className:"input toggle-switch form-element "+(this.errors?.default_expiry_period&&e?"has-error":"")},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"defaultExpiryPeriodToggle",onChange:this.handleExpiryPeriodToggleClick,checked:a,disabled:this.hasAllInputDisabled(),id:"default-expiry-period-toggle"}),n.createElement("label",{htmlFor:"default-expiry-period-toggle"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Default password expiry period")),n.createElement("span",{className:"info-input"},n.createElement(f.x6,null,n.createElement("span",null,"When a user creates a resource, a default expiry date is set to "),n.createElement("input",{type:"text",className:"toggle-input",id:"default-expiry-period-input",name:"default_expiry_period",onChange:this.handleInputChange,maxLength:3,value:t,disabled:this.hasAllInputDisabled()||!a,placeholder:"90"}),n.createElement("span",null,"days"))))),this.errors?.default_expiry_period&&e&&n.createElement("div",{className:"input"},!this.errors.default_expiry_period.required&&n.createElement("div",{className:"default-expiry-period-gte error-message"},n.createElement(f.x6,null,"The default password expiry period should be a number between 1 and 999 days.")),this.errors?.default_expiry_period.required&&n.createElement("div",{className:"default-expiry-period-required error-message"},n.createElement(f.x6,null,"The default password expiry period should be a valid number.")))),n.createElement("div",{className:"togglelist-alt"},n.createElement("span",{className:"input toggle-switch form-element",id:"policy-override"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"policy_override",onChange:this.handleInputChange,checked:this.settings.policy_override,disabled:this.hasAllInputDisabled(),id:"policy-override-toggle"}),n.createElement("label",{htmlFor:"policy-override-toggle"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Policy Override")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"Allow users to override the default policy."))))),n.createElement("h4",{className:"no-border",id:"automatic-workflow-subtitle"},n.createElement(f.x6,null,"Automatic workflows")),n.createElement("p",{id:"automatic-workflow-description"},n.createElement(f.x6,null,"In this section you can choose automatic behaviours.")),n.createElement("div",{className:"togglelist-alt"},n.createElement("span",{className:"input toggle-switch form-element",id:"automatic-expiry"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"automatic_expiry",onChange:this.handleInputChange,checked:this.settings.automatic_expiry,disabled:this.hasAllInputDisabled(),id:"automatic-expiry-toggle"}),n.createElement("label",{htmlFor:"automatic-expiry-toggle"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Automatic Expiry")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"Password automatically expires when a user or group with a user who has accessed the password is removed from the permission list."))))),n.createElement("div",{className:"togglelist-alt"},n.createElement("span",{className:"input toggle-switch form-element",id:"automatic-update"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"automatic_update",onChange:this.handleInputChange,checked:this.settings.automatic_update,disabled:this.hasAllInputDisabled(),id:"automatic-update-toggle"}),n.createElement("label",{htmlFor:"automatic-update-toggle"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Automatic Update")),n.createElement("span",{className:"info"},a?n.createElement(f.x6,null,"Password expiry date is renewed based on the default password expiry period whenever a password is updated."):n.createElement(f.x6,null,"Password is no longer marked as expired whenever the password is updated.")))))))}}Ad.propTypes={context:i().object,adminPasswordExpiryContext:i().object,actionFeedbackContext:i().object,dialogContext:i().object,t:i().func};const Id=N(Cd(m(h((0,f.CI)("common")(Ad)))));class Rd extends n.PureComponent{constructor(e){super(e),this.state=this.defaultState}get defaultState(){return{isReady:!1}}async componentDidMount(){await this.props.adminPasswordExpiryContext.findSettings(),this.setState({isReady:!0})}hasAllInputDisabled(){return this.props.adminPasswordExpiryContext.isProcessing()}get canUseAdvancedSettings(){return this.props.context.siteSettings.canIUse("passwordExpiryPolicies")}render(){if(!this.state.isReady)return null;const e=this.props.adminPasswordExpiryContext,t=e.isFeatureToggleEnabled();return n.createElement("div",{className:"row"},n.createElement("div",{className:"password-expiry-settings main-column"},n.createElement("div",{className:"main-content"},n.createElement("h3",{id:"password-expiry-settings-title",className:"title"},n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"passwordExpirySettingsToggle",onChange:()=>e.setFeatureToggle(!t),checked:t,disabled:this.hasAllInputDisabled(),id:"passwordExpirySettingsToggle"}),n.createElement("label",{htmlFor:"passwordExpirySettingsToggle"},n.createElement(f.x6,null,"Password Expiry")))),!t&&n.createElement("p",{className:"description"},n.createElement(f.x6,null,"No Password Expiry is configured. Enable it to activate automatic password expiration and automatic password expiration reset workflows.")),t&&n.createElement(n.Fragment,null,this.canUseAdvancedSettings?n.createElement(Id,null):n.createElement("div",{id:"password-expiry-settings-form"},n.createElement("h4",{id:"password-expiry-settings-automatic-workflows",className:"title title--required no-border"},n.createElement(f.x6,null,"Automatic workflows")),n.createElement("div",{className:"radiolist-alt"},n.createElement("div",{className:"input radio"},n.createElement("label",{htmlFor:"passwordExpiryAutomaticExpiry"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Automatic expiry")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"Password automatically expires when a user or group with a user who has accessed the password is removed from the permission list.")))),n.createElement("div",{className:"input radio"},n.createElement("label",{htmlFor:"passwordExpiryAutomatiUpdate"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Automatic update")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"Password is no longer marked as expired whenever the password is updated.")))))))),e.hasSettingsChanges()&&n.createElement("div",{className:"warning message",id:"password-expiry-settings-save-banner"},n.createElement("div",null,n.createElement("p",null,n.createElement(f.x6,null,"Don't forget to save your settings to apply your modification."))))),n.createElement(Td,null),Xa(n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"About password expiry")),n.createElement("p",null,n.createElement(f.x6,null,"For more information about the password expiry, checkout the dedicated page on the help website.")),n.createElement("a",{className:"button",href:"https://passbolt.com/docs/admin/password-configuration/password-expiry",target:"_blank",rel:"noopener noreferrer"},n.createElement(Er,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}Rd.propTypes={context:i().object,administrationWorkspaceContext:i().object,adminPasswordExpiryContext:i().object,t:i().func};const Pd=N(Ne(Cd((0,f.CI)("common")(Rd))));class Dd extends n.Component{get errorTitle(){return{403:this.props.t("Whoops... access is denied"),404:this.props.t("Whoops... looks like you are lost.")}[this.props.errorCode]||""}get errorDescription(){return{403:this.props.t("Access is restricted to authorized users only."),404:this.props.t("We could not find the page you are looking for.")}[this.props.errorCode]||""}render(){return n.createElement("div",{className:"row"},n.createElement("div",{className:"http-error main-column"},n.createElement("div",{className:"main-content"},n.createElement("h3",null,this.props.errorCode),n.createElement("h4",null,this.errorTitle),n.createElement("div",null,n.createElement("p",null,this.errorDescription)))))}}Dd.propTypes={errorCode:i().number.isRequired,t:i().func};const Od=(0,f.CI)("common")(Dd),Md=class{constructor(e){this.apiClientOptions=e,this.initClient()}async fetchHealthcheck(){this.initClient();const e=await this.apiClient.findAll();return e?.body}initClient(){this.apiClientOptions.setResourceName("healthcheck"),this.apiClient=new pt(this.apiClientOptions)}};class Ud extends se{constructor(e,t={}){super(ae.validate(Ud.ENTITY_NAME,e,Ud.getSchema()),t)}static getSchema(){return{type:"object",required:["peerValid","hostValid","notSelfSigned"],properties:{peerValid:{type:"boolean"},hostValid:{type:"boolean"},notSelfSigned:{type:"boolean"},info:{type:"string"}}}}get peerValid(){return this._props.peerValid}get hostValid(){return this._props.hostValid}get notSelfSigned(){return this._props.notSelfSigned}get info(){return this._props.info}static get ENTITY_NAME(){return"ssl"}}const Fd=Ud;class jd extends se{constructor(e,t={}){super(ae.validate(jd.ENTITY_NAME,e,jd.getSchema()),t)}static getSchema(){return{type:"object",required:["tablesCount","info","connect","supportedBackend","defaultContent"],properties:{tablesCount:{type:"boolean"},info:{type:"object",required:["tablesCount"],properties:{tablesCount:{type:"number"}}},connect:{type:"boolean"},supportedBackend:{type:"boolean"},defaultContent:{type:"boolean"}}}}get tablesCount(){return this._props.tablesCount}get info(){return this._props.info}get connect(){return this._props.connect}get supportedBackend(){return this._props.supportedBackend}get defaultContent(){return this._props.defaultContent}static get ENTITY_NAME(){return"database"}}const Ld=jd;class qd extends se{constructor(e,t={}){super(ae.validate(qd.ENTITY_NAME,e,qd.getSchema()),t)}static getSchema(){return{type:"object",required:["info","latestVersion","schema","robotsIndexDisabled","sslForce","sslFullBaseUrl","seleniumDisabled","registrationClosed","configPath","hostAvailabilityCheckEnabled","jsProd","emailNotificationEnabled"],properties:{info:{type:"object",required:["remoteVersion","currentVersion"],properties:{remoteVersion:{type:"string",nullable:!0},currentVersion:{type:"string"}}},latestVersion:{type:"boolean",nullable:!0},schema:{type:"boolean"},robotsIndexDisabled:{type:"boolean"},sslForce:{type:"boolean"},sslFullBaseUrl:{type:"boolean"},seleniumDisabled:{type:"boolean"},configPath:{type:"string"},registrationClosed:{type:"object",required:["isSelfRegistrationPluginEnabled","selfRegistrationProvider","isRegistrationPublicRemovedFromPassbolt"],properties:{isSelfRegistrationPluginEnabled:{type:"boolean"},selfRegistrationProvider:{type:"string",nullable:!0},isRegistrationPublicRemovedFromPassbolt:{type:"boolean"}}},hostAvailabilityCheckEnabled:{type:"boolean"},jsProd:{type:"boolean"},emailNotificationEnabled:{type:"boolean"}}}}get info(){return this._props.info}get latestVersion(){return this._props.latestVersion}getSchema(){return this._props.getSchema}get robotsIndexDisabled(){return this._props.robotsIndexDisabled}get sslForce(){return this._props.sslForce}get sslFullBaseUrl(){return this._props.sslFullBaseUrl}get schema(){return this._props.schema}get currentVersion(){return this._props.currentVersion}get configPath(){return this._props.configPath}get seleniumDisabled(){return this._props.seleniumDisabled}get registrationClosed(){return this._props.registrationClosed}get hostAvailabilityCheckEnabled(){return this._props.hostAvailabilityCheckEnabled}get jsProd(){return this._props.jsProd}get emailNotificationEnabled(){return this._props.emailNotificationEnabled}static get ENTITY_NAME(){return"application"}}const zd=qd;class Kd extends se{constructor(e,t={}){super(ae.validate(Kd.ENTITY_NAME,e,Kd.getSchema()),t)}static getSchema(){return{type:"object",required:["canDecryptVerify","canVerify","gpgKeyPublicInKeyring","canEncrypt","canDecrypt","canEncryptSign","canSign","gpgHome","gpgKeyPrivateFingerprint","gpgKeyPublicFingerprint","gpgKeyPublicEmail","gpgKeyPublicReadable","gpgKeyPrivateReadable","gpgKey","lib","gpgKeyNotDefault","info","gpgHomeWritable","gpgKeyPublic","gpgKeyPublicBlock","gpgKeyPrivate","gpgKeyPrivateBlock","isPublicServerKeyGopengpgCompatible","isPrivateServerKeyGopengpgCompatible"],properties:{canDecryptVerify:{type:"boolean"},canVerify:{type:"boolean"},gpgKeyPublicInKeyring:{type:"boolean"},canEncrypt:{type:"boolean"},canDecrypt:{type:"boolean"},canEncryptSign:{type:"boolean"},canSign:{type:"boolean"},gpgHome:{type:"boolean"},gpgKeyPrivateFingerprint:{type:"boolean"},gpgKeyPublicFingerprint:{type:"boolean"},gpgKeyPublicEmail:{type:"boolean"},gpgKeyPublicReadable:{type:"boolean"},gpgKeyPrivateReadable:{type:"boolean"},gpgKey:{type:"boolean"},lib:{type:"boolean"},gpgKeyNotDefault:{type:"boolean"},gpgHomeWritable:{type:"boolean"},gpgKeyPublic:{type:"boolean"},gpgKeyPublicBlock:{type:"boolean"},gpgKeyPrivate:{type:"boolean"},gpgKeyPrivateBlock:{type:"boolean"},isPublicServerKeyGopengpgCompatible:{type:"boolean"},isPrivateServerKeyGopengpgCompatible:{type:"boolean"},info:{type:"object",required:["gpgHome","gpgKeyPrivate"],properties:{gpgHome:{type:"string"},gpgKeyPrivate:{type:"string"}}}}}}get canDecryptVerify(){return this._props.canDecryptVerify}get canVerify(){return this._props.canVerify}get gpgKeyPublicInKeyring(){return this._props.gpgKeyPublicInKeyring}get canEncrypt(){return this._props.canEncrypt}get canDecrypt(){return this._props.canDecrypt}get canEncryptSign(){return this._props.canEncryptSign}get canSign(){return this._props.canSign}get gpgHome(){return this._props.gpgHome}get gpgKeyPrivateFingerprint(){return this._props.gpgKeyPrivateFingerprint}get gpgKeyPublicFingerprint(){return this._props.gpgKeyPublicFingerprint}get gpgKeyPublicEmail(){return this._props.gpgKeyPublicEmail}get gpgKeyPublicReadable(){return this._props.gpgKeyPublicReadable}get gpgKeyPrivateReadable(){return this._props.gpgKeyPrivateReadable}get gpgKey(){return this._props.gpgKey}get lib(){return this._props.lib}get gpgKeyNotDefault(){return this._props.gpgKeyNotDefault}get info(){return this._props.info}get gpgHomeWritable(){return this._props.gpgHomeWritable}get gpgKeyPublic(){return this._props.gpgKeyPublic}get gpgKeyPublicBlock(){return this._props.gpgKeyPublicBlock}get gpgKeyPrivate(){return this._props.gpgKeyPrivate}get gpgKeyPrivateBlock(){return this._props.gpgKeyPrivateBlock}get isPublicServerKeyGopengpgCompatible(){return this._props.isPublicServerKeyGopengpgCompatible}get isPrivateServerKeyGopengpgCompatible(){return this._props.isPrivateServerKeyGopengpgCompatible}static get ENTITY_NAME(){return"gpg"}}const Vd=Kd;class Gd extends se{constructor(e,t={}){super(ae.validate(Gd.ENTITY_NAME,e,Gd.getSchema()),t)}static getSchema(){return{type:"object",required:["phpVersion","nextMinPhpVersion","pcre","mbstring","gnupg","intl","image","tmpWritable","logWritable"],properties:{phpVersion:{type:"boolean"},nextMinPhpVersion:{type:"boolean"},pcre:{type:"boolean"},mbstring:{type:"boolean"},gnupg:{type:"boolean"},intl:{type:"boolean"},image:{type:"boolean"},tmpWritable:{type:"boolean"},logWritable:{type:"boolean"},info:{type:"object",required:["phpVersion"],properties:{serverPhpVersion:{"type:":"string"}}}}}}get phpVersion(){return this._props.phpVersion}get nextMinPhpVersion(){return this._props.nextMinPhpVersion}get pcre(){return this._props.pcre}get mbstring(){return this._props.mbstring}get gnupg(){return this._props.gnupg}get intl(){return this._props.intl}get image(){return this._props.image}get tmpWritable(){return this._props.tmpWritable}get logWritable(){return this._props.logWritable}get info(){return this._props.info}get serverPhpVersion(){return this._props.phpVersion}static get ENTITY_NAME(){return"environment"}}const Bd=Gd;class Wd extends se{constructor(e,t={}){super(ae.validate(Wd.ENTITY_NAME,e,Wd.getSchema()),t)}static getSchema(){return{type:"object",required:["app","passbolt"],properties:{app:{type:"boolean"},passbolt:{type:"boolean"}}}}get app(){return this._props.app}get passbolt(){return this._props.passbolt}static get ENTITY_NAME(){return"configFile"}}const Hd=Wd;class $d extends se{constructor(e,t={}){super(ae.validate($d.ENTITY_NAME,e,$d.getSchema()),t)}static getSchema(){return{type:"object",required:["cache","debugDisabled","salt","fullBaseUrl","validFullBaseUrl","info","fullBaseUrlReachable"],properties:{cache:{type:"boolean"},debugDisabled:{type:"boolean"},salt:{type:"boolean"},fullBaseUrl:{type:"boolean"},validFullBaseUrl:{type:"boolean"},info:{type:"object",required:["fullBaseUrl"],properties:{fullBaseUrl:{type:"string",format:"uri"}}},fullBaseUrlReachable:{type:"boolean"}}}}get cache(){return this._props.cache}get debugDisabled(){return this._props.debugDisabled}get salt(){return this._props.salt}get fullBaseUrl(){return this._props.fullBaseUrl}get validFullBaseUrl(){return this._props.validFullBaseUrl}get info(){return this._props.info}get fullBaseUrlReachable(){return this._props.fullBaseUrlReachable}static get ENTITY_NAME(){return"core"}}const Yd=$d;class Zd extends se{constructor(e,t={}){super(ae.validate(Zd.ENTITY_NAME,e,Zd.getSchema()),t)}static getSchema(){return{type:"object",required:["isEnabled","areEndpointsDisabled","errorMessage","source","isInDb"],properties:{isEnabled:{type:"boolean"},areEndpointsDisabled:{type:"boolean"},errorMessage:{anyOf:[{type:"boolean"},{type:"string"}]},source:{type:"string"},isInDb:{type:"boolean"}}}}get isEnabled(){return this._props.isEnabled}get areEndpointsDisabled(){return this._props.areEndpointsDisabled}get errorMessage(){return this._props.errorMessage}get source(){return this._props.source}get isInDb(){return this._props.isInDb}static get ENTITY_NAME(){return"smtpSettings"}}const Jd=Zd;class Xd extends se{constructor(e,t={}){super(ae.validate(Xd.ENTITY_NAME,e,Xd.getSchema()),t)}static getSchema(){return{type:"object",required:["endpointsDisabled"],properties:{endpointsDisabled:{type:"boolean"}}}}get endpointsDisabled(){return this._props.endpointsDisabled}static get ENTITY_NAME(){return"directorySync"}}const Qd=Xd;class eu extends se{constructor(e,t={}){super(ae.validate(eu.ENTITY_NAME,e,eu.getSchema()),t)}static getSchema(){return{type:"object",required:["sslHostVerification"],properties:{sslHostVerification:{type:"boolean"}}}}get sslHostVerification(){return this._props.sslHostVerification}static get ENTITY_NAME(){return"sso"}}const tu=eu;class au extends se{constructor(e,t={}){super(ae.validate(au.ENTITY_NAME,e,au.getSchema()),t)}static getSchema(){return{type:"object",required:["canDecryptMetadataPrivateKey"],properties:{canDecryptMetadataPrivateKey:{type:"boolean"},canValidatePrivateMetadataKey:{type:"boolean"},isServerHasAccessToMetadataKey:{type:"boolean"},isServerMetadataKeyAccessInZeroKnowledgeMode:{type:"boolean"},noActiveMetadataKey:{type:"boolean"}}}}get canDecryptMetadataPrivateKey(){return this._props.canDecryptMetadataPrivateKey}get canValidatePrivateMetadataKey(){return this._props.canValidatePrivateMetadataKey}get isServerHasAccessToMetadataKey(){return this._props.isServerHasAccessToMetadataKey}get isServerMetadataKeyAccessInZeroKnowledgeMode(){return this._props.isServerMetadataKeyAccessInZeroKnowledgeMode}get noActiveMetadataKey(){return this._props.noActiveMetadataKey}static get ENTITY_NAME(){return"metadata"}}const nu=au;class su extends se{constructor(e,t={}){super(ae.validate(su.ENTITY_NAME,e,su.getSchema()),t),this._props.ssl&&(this._ssl=new Fd(this._props.ssl,{clone:!1}),delete this._props.ssl),this._props.database&&(this._database=new Ld(this._props.database,{clone:!1}),delete this._props.database),this._props.application&&(this._application=new zd(this._props.application,{clone:!1}),delete this._props.application),this._props.gpg&&(this._gpg=new Vd(this._props.gpg,{clone:!1}),delete this._props.gpg),this._props.environment&&(this._environment=new Bd(this._props.environment,{clone:!1}),delete this._props.environment),this._props.configFile&&(this._configFile=new Hd(this._props.configFile,{clone:!1}),delete this._props.configFile),this._props.core&&(this._core=new Yd(this._props.core,{clone:!1}),delete this._props.core),this._props.smtpSettings&&(this._smtpSettings=new Jd(this._props.smtpSettings,{clone:!1}),delete this._props.smtpSettings),this._props.directorySync&&(this._directorySync=new Qd(this._props.directorySync,{clone:!1}),delete this._props.directorySync),this._props.sso&&(this._sso=new tu(this._props.sso,{clone:!1}),delete this._props.sso),this._props.metadata&&(this._metadata=new nu(this._props.metadata,{clone:!1}),delete this._props.metadata)}static getSchema(){return{type:"object",required:["database","ssl","application","gpg","configFile","core","smtpSettings"],properties:{database:Ld.getSchema(),ssl:Fd.getSchema(),application:zd.getSchema(),gpg:Vd.getSchema(),environment:Bd.getSchema(),configFile:Hd.getSchema(),core:Yd.getSchema(),smtpSettings:Jd.getSchema(),directorySync:Qd.getSchema(),sso:tu.getSchema(),metadata:nu.getSchema()}}}isSSLValid(){const e=this._props.ssl;return e.peerValid&&e.hostValid&&!e.notSelfSigned}static get ENTITY_NAME(){return"healthcheck"}get ssl(){return this._ssl||null}get database(){return this._database||null}get application(){return this._application||null}get gpg(){return this._gpg||null}get environment(){return this._environment||null}get configFile(){return this._configFile||null}get core(){return this._core||null}get smtpSettings(){return this._smtpSettings||null}get directorySync(){return this._directorySync||null}get sso(){return this._sso||null}get metadata(){return this._metadata}}const iu=su;function ru(){return ru=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},isProcessing:()=>{},loadHealthcheckData:()=>{},clearContext:()=>{},isHealthcheckEndpointEnabled:()=>{}});class lu extends n.Component{constructor(e){super(e),this.state=this.defaultState;const t=e.context.getApiClientOptions();this.healthcheckService=new Md(t)}get defaultState(){return{healthcheckData:null,endpointEnabled:!0,processing:!1,isProcessing:this.isProcessing.bind(this),loadHealthcheckData:this.fetchHealthcheckData.bind(this),clearContext:this.clearContext.bind(this),isHealthcheckEndpointEnabled:this.isHealthcheckEndpointEnabled.bind(this)}}isHealthcheckEndpointEnabled(){return this.state.endpointEnabled}async fetchHealthcheckData(){if(this.isHealthcheckEndpointEnabled()){this.setProcessing(!0);try{const e=await this.healthcheckService.fetchHealthcheck();if(e){const t=new iu(e);this.setState({healthcheckData:t})}else this.props.actionFeedbackContext.displayError("No data received from the server")}catch(e){console.error(e),this.setState({endpointEnabled:!1}),this.props.actionFeedbackContext.displayError(e.message)}finally{this.setProcessing(!1)}}}clearContext(){this.setState(this.defaultState)}isProcessing(){return this.state.processing}setProcessing(e){this.setState({processing:e})}render(){return n.createElement(ou.Provider,{value:this.state},this.props.children)}}lu.propTypes={context:i().any,actionFeedbackContext:i().any,children:i().any};const cu=N(m(lu));function mu(e){return class extends n.Component{render(){return n.createElement(ou.Consumer,null,t=>n.createElement(e,ru({adminHealthcheckContext:t},this.props)))}}}var du,uu,pu;function hu(){return hu=Object.assign?Object.assign.bind():function(e){for(var t=1;t!0===e.database.connect&&!0===e.database.defaultContent?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"Some default content is present")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"No default content found"),n.createElement(Mt,{message:this.props.t("Run the install script to set the dafault content such as roles and permission types")},n.createElement(jt,{className:"baseline svg-icon"}))),a=()=>!0===e.core.cache?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"Cache is working")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"Cache is not working"),n.createElement(Mt,{message:this.props.t("Check the settings in config/app.php")},n.createElement(jt,{className:"baseline svg-icon"}))),s=()=>!0===e.core.salt?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"Unique value set for security.salt")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"Default value found for security.salt"),n.createElement(Mt,{message:this.props.t("Edit the security.salt in config/app.php")},n.createElement(jt,{className:"baseline svg-icon"}))),i=()=>!0===e.configFile.app?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The application config file is present")):n.createElement("span",{className:"healthcheck-warning"},n.createElement(Au,null),n.createElement(f.x6,null,"The application config file is missing"),n.createElement(Mt,{message:this.props.t("Copy config/app.default.php to config/app.php")},n.createElement(jt,{className:"baseline svg-icon"}))),r=()=>!0===e.configFile.passbolt?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The passbolt config file is present")):n.createElement("span",{className:"healthcheck-warning"},n.createElement(Au,null),n.createElement(f.x6,null,"The passbolt config file is missing"),n.createElement(Mt,{message:this.props.t("Copy config/passbolt.default.php to config/passbolt.php")},n.createElement(jt,{className:"baseline svg-icon"}))),o=()=>!0===e.environment.pcre?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"PCRE compiled with unicode support")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"PCRE has not been compiled with Unicode support"),n.createElement(Mt,{message:this.props.t("Recompile PCRE with Unicode support by adding --enable-unicode-properties when configuring.")},n.createElement(jt,{className:"baseline svg-icon"}))),l=()=>!0===e.environment.tmpWritable?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The temporary directory and its content are writable and not executable")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"The temporary directory and its content are not writable, or are executable"),n.createElement(Mt,{message:this.props.t("Ensure the temporary directory and its content are writable by the webserver user.")},n.createElement(jt,{className:"baseline svg-icon"}))),c=()=>!0===e.environment.logWritable?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The logs directory and its content are writable")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"The logs directory and its content are not writable"),n.createElement(Mt,{message:this.props.t("Ensure the temporary directory and its content are writable by the webserver user.")},n.createElement(jt,{className:"baseline svg-icon"}))),m=()=>{const t=e.gpg.info.gpgHome.toString();return!0===e.gpg.gpgHome&&e.gpg.info.gpgHome?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The environment variable GNUPGHOME is set to ",{gpgHomeDirectory:t})):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"The environment variable GNUPGHOME is set to ",{gpgHomeDirectory:t}," but the directory does not exist"),n.createElement(Mt,{message:this.props.t("Ensure the keyring location exists and is accessible by the webserver user.")},n.createElement(jt,{className:"baseline svg-icon"})))},d=()=>{const t=e.gpg.info.gpgHome.toString();return!0===e.gpg.gpgHomeWritable&&e.gpg.info.gpgHome?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The directory ",{gpgHomeDirectory:t}," containing the keyring is writable by the webserver user")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"The directory ",{gpgHomeDirectory:t}," containing the keyring is not writable by the webserver user"),n.createElement(Mt,{message:this.props.t("Ensure the keyring location exists and is accessible by the webserver user.")},n.createElement(jt,{className:"baseline svg-icon"})))},u=()=>{const t=e.application.configPath.toString();return!0===e.gpg.gpgKeyPrivateFingerprint&&!0===e.gpg.gpgKeyPublicFingerprint?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The server key fingerprint matches the one defined in ",{configurationFilePath:t})):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"The server key fingerprint doesn't matches the one defined in ",{configurationFilePath:t}),n.createElement(Mt,{message:this.props.t("Double check the key fingerprint")},n.createElement(jt,{className:"baseline svg-icon"})))},p=()=>{const t=e.application.configPath.toString();return!0===e.gpg.gpgKeyPublicInKeyring?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The server public key defined in the ",{configurationFilePath:t}," (or environment variables) is in the keyring")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"The server public key defined in the ",{configurationFilePath:t}," (or environment variables) is not in the keyring"),n.createElement(Mt,{message:this.props.t("Import the private server key in the keyring of the webserver user.")},n.createElement(jt,{className:"baseline svg-icon"})))},h=()=>!0===e.gpg.gpgKeyPublicEmail?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"There is a valid email id defined for the server key")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"The server key does not have a valid email id"),n.createElement(Mt,{message:this.props.t("Edit or generate another key with a valid email id.")},n.createElement(jt,{className:"baseline svg-icon"}))),g=()=>!0===e.application.registrationClosed.isSelfRegistrationPluginEnabled?n.createElement("span",{className:"healthcheck-info"},n.createElement(Cu,null),n.createElement(f.x6,null,"The Self Registration plugin is enabled")):n.createElement("span",{className:"healthcheck-info"},n.createElement(Cu,null),n.createElement(f.x6,null,"The Self Registration plugin is disabled"),n.createElement(Mt,{message:this.props.t("Enable the plugin in order to define self registration settings.")},n.createElement(jt,{className:"baseline svg-icon"}))),y=()=>{const t=e.application.configPath.toString();return!0===e.application.registrationClosed.isRegistrationPublicRemovedFromPassbolt?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The deprecated self registration public settings was not found in ",{configurationFilePath:t})):n.createElement("span",{className:"healthcheck-warning"},n.createElement(Au,null),n.createElement(f.x6,null,"The deprecated self registration public settings was found in ",{configurationFilePath:t}),n.createElement(Mt,{message:this.props.t("You may remove the passbolt.registration.public setting")},n.createElement(jt,{className:"baseline svg-icon"})))},b=()=>!0===e.application.hostAvailabilityCheckEnabled?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"Host availability will be checked")):n.createElement("span",{className:"healthcheck-warning"},n.createElement(Au,null),n.createElement(f.x6,null,"Host availability checking is disabled"),n.createElement(Mt,{message:this.props.t("Make sure the instance is not publicly available on the internet.")},n.createElement(jt,{className:"baseline svg-icon"}))),E=()=>{if(e.smtpSettings.source){const t=e.smtpSettings.source.toString();return!0===e.smtpSettings.isInDb?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The SMTP Settings source is: ",{smtpSettingsSource:t})):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"The SMTP Settings source is: ",{smtpSettingsSource:t}),n.createElement(Mt,{message:this.props.t("It is recommended to set the SMTP Settings in the database through the administration section.")},n.createElement(jt,{className:"baseline svg-icon"})))}},v=()=>!0===e.smtpSettings.areEndpointsDisabled?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The SMTP Settings plugin endpoints are disabled")):n.createElement("span",{className:"healthcheck-warning"},n.createElement(Au,null),n.createElement(f.x6,null,"The SMTP Settings plugin endpoints are enabled"),n.createElement(Mt,{message:this.props.t("It is recommended to disable the plugin endpoints.")},n.createElement(jt,{className:"baseline svg-icon"}))),w=()=>!0===e.directorySync.endpointsDisabled?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The endpoints for updating the users directory configurations are disabled.")):n.createElement("span",{className:"healthcheck-warning"},n.createElement(Au,null),n.createElement(f.x6,null,"The endpoints for updating the users directory configurations are enabled."),n.createElement(Mt,{message:this.props.t("It is recommended to disable endpoints for updating the users directory configurations.")},n.createElement(jt,{className:"baseline svg-icon"}))),k=()=>!0===e.sso.sslHostVerification?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"SSL certification validation for SSO instance is enabled.")):n.createElement("span",{className:"healthcheck-warning"},n.createElement(Au,null),n.createElement(f.x6,null,"SSL certification validation for SSO instance is disabled."),n.createElement(Mt,{message:this.props.t("Disabling the ssl verify check can lead to security attacks.")},n.createElement(jt,{className:"baseline svg-icon"}))),_=()=>!0===e.metadata.canDecryptMetadataPrivateKey?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The server is able to decrypt the metadata private key.")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"Unable to decrypt the metadata private key."),n.createElement(Mt,{message:this.props.t("For more information, please run the health check from the command line on the server.")},n.createElement(jt,{className:"baseline svg-icon"}))),x=()=>!0===e.metadata.canValidatePrivateMetadataKey?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The server metadata private key is valid.")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"The server metadata private key is not valid."),n.createElement(Mt,{message:this.props.t("For more information, please run the health check from the command line on the server.")},n.createElement(jt,{className:"baseline svg-icon"}))),S=()=>!0===e.metadata.isServerHasAccessToMetadataKey?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The server has access to the metadata keys or does not require access to it.")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"The server does not have access to metadata key."),n.createElement(Mt,{message:this.props.t("When zero-knowledge mode is off, the server must have access to the metadata key. Without having access, the server won't be able to share the metadata private key with the users.")},n.createElement(jt,{className:"baseline svg-icon"}))),C=()=>!0===e.metadata.noActiveMetadataKey?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"Active metadata key found or not required.")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"No active metadata key found."),n.createElement(Mt,{message:this.props.t("For more information, please run the health check from the command line on the server.")},n.createElement(jt,{className:"baseline svg-icon"}))),N=this.props.adminHealthcheckContext.isHealthcheckEndpointEnabled();return n.createElement("div",{className:"row"},n.createElement("div",{className:"healthcheck-settings main-column"},n.createElement("div",{className:"main-content"},n.createElement("h3",null,n.createElement(f.x6,null,"Passbolt API Status")),N?(()=>!e||this.props.adminHealthcheckContext.isProcessing()?n.createElement(En,null):n.createElement(n.Fragment,null,n.createElement("h4",{className:"no-border"},n.createElement(f.x6,null,"Environment")),n.createElement("div",{className:"healthcheck-environment-section"},n.createElement("div",null,(()=>{if(e.environment.info.phpVersion&&!0===e.environment.phpVersion){const t=e.environment.info.phpVersion.toString();return n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"PHP version ",{phpVersion:t}))}return n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"PHP version is too low, passbolt need PHP 7.4 or higher"))})()),n.createElement("div",null,o()),n.createElement("div",null,l()),n.createElement("div",null,c()),n.createElement("div",null,!0===e.environment.image?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"GD or Imagick extension is installed")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"You must enable the gd or imagick extensions to use Passbolt"),n.createElement(Mt,{message:n.createElement("span",null,n.createElement(f.x6,null,"See"," ",n.createElement("a",{href:"https://secure.php.net/manual/en/book.image.php",target:"_blank",rel:"noopener noreferrer"},"this guide")))},n.createElement(jt,{className:"baseline svg-icon"})))),n.createElement("div",null,!0===e.environment.intl?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"Intl extension is installed")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"You must enable the intl extension to use Passbolt"),n.createElement(Mt,{message:n.createElement("span",null,n.createElement(f.x6,null,"See"," ",n.createElement("a",{href:"https://secure.php.net/manual/en/book.intl.php",target:"_blank",rel:"noopener noreferrer"},"this guide")))},n.createElement(jt,{className:"baseline svg-icon"})))),n.createElement("div",null,!0===e.environment.mbstring?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"Mbstring extension is installed")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"You must enable the mbstring extension to use Passbolt"),n.createElement(Mt,{message:n.createElement("span",null,n.createElement(f.x6,null,"See"," ",n.createElement("a",{href:"https://secure.php.net/manual/en/book.mbstring.php",target:"_blank",rel:"noopener noreferrer"},"this guide")))},n.createElement(jt,{className:"baseline svg-icon"}))))),n.createElement("h4",null,n.createElement(f.x6,null,"Config files")),n.createElement("div",{className:"healthcheck-configFiles-section"},n.createElement("div",null,i()),n.createElement("div",null,r())),n.createElement("h4",null,n.createElement(f.x6,null,"Core config")),n.createElement("div",{className:"healthcheck-core-section"},n.createElement("div",null,(()=>{if(!1===e.core.debugDisabled){const t=e.application.configPath.toString();return n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"Debug mode is on"),n.createElement(Mt,{message:n.createElement(f.x6,null,"Set debug = false; in ",{configurationFilePath:t})},n.createElement(jt,{className:"baseline svg-icon"})))}})()),n.createElement("div",null,a()),n.createElement("div",null,s()),n.createElement("div",null,(()=>{if(!0===e.core.fullBaseUrl){const t=e.core.info.fullBaseUrl.toString();return n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"Full base url is set to ",{fullBaseUrl:t}))}{const t=e.application.configPath.toString();return n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"Full base url is not set"),n.createElement(Mt,{message:n.createElement(f.x6,null,"Edit App.fullBaseUrl in ",{configurationFilePath:t})},n.createElement(jt,{className:"baseline svg-icon"})))}})()),n.createElement("div",null,(()=>{if(!0===e.core.validFullBaseUrl)return n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"App.fullBaseUrl validation OK"));{const t=e.application.configPath.toString();return n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"App.fullBaseUrl does not validate"),n.createElement(Mt,{message:n.createElement(f.x6,null,"Edit App.fullBaseUrl in ",{configurationFilePath:t})},n.createElement(jt,{className:"baseline svg-icon"})))}})()),n.createElement("div",null,(()=>{if(!0===e.core.fullBaseUrlReachable)return n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"/healthcheck/status is reachable"));{const t=e.application.configPath.toString();return n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"Could not reach the /healthcheck/status with the url specified in App.fullBaseUrl"),n.createElement(Mt,{message:n.createElement(f.x6,null,"Check that the domain name is correct in ",{configurationFilePath:t})},n.createElement(jt,{className:"baseline svg-icon"})))}})())),n.createElement("h4",null,n.createElement(f.x6,null,"SSL Certificate")),n.createElement("div",{className:"healthcheck-ssl-section"},n.createElement("div",null,!0===e.ssl.peerValid?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"SSL peer certificate validates")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"SSL peer certificate does not validate"),n.createElement(Mt,{message:n.createElement("span",null,n.createElement(f.x6,null,"Check"," ",n.createElement("a",{href:"https://www.passbolt.com/docs/hosting/configure/tls/",target:"_blank",rel:"noopener noreferrer"},"this guide")))},n.createElement(jt,{className:"baseline svg-icon"})))),n.createElement("div",null,!0===e.ssl.hostValid?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"Hostname is matching SSL certificate")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"Hostname does not match when validating certificates"),n.createElement(Mt,{message:n.createElement("span",null,n.createElement(f.x6,null,"Check"," ",n.createElement("a",{href:"https://www.passbolt.com/docs/hosting/configure/tls/",target:"_blank",rel:"noopener noreferrer"},"this guide")))},n.createElement(jt,{className:"baseline svg-icon"})))),n.createElement("div",null,!0===e.ssl.notSelfSigned?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"Not using a self-signed certificate")):n.createElement("span",{className:"healthcheck-warning"},n.createElement(Au,null),n.createElement(f.x6,null,"Using a self-signed certificate")))),n.createElement("h4",null,n.createElement(f.x6,null,"Database")),n.createElement("div",{className:"healthcheck-database-section"},n.createElement("div",null,(()=>{if(!0===e.database.connect)return n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The application is able to connect to the database"));{const t=e.application.configPath.toString();return n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"The application is not able to connect to the database"),n.createElement(Mt,{message:n.createElement(f.x6,null,"Double check the host, database name, username and password in ",{configurationFilePath:t})},n.createElement(jt,{className:"baseline svg-icon"})))}})()),n.createElement("div",null,(()=>{if(!0===e.database.connect&&e.database.tablesCount){const t=e.database.info.tablesCount.toString();return n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,{count:t}," tables found"))}})()),n.createElement("div",null,t())),n.createElement("h4",null,n.createElement(f.x6,null,"GPG Configuration")),n.createElement("div",{className:"healthcheck-gpg-section"},n.createElement("div",null,!0===e.gpg.lib?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"PHP GPG Module is installed and loaded")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"PHP GPG Module is not installed or loaded"),n.createElement(Mt,{message:n.createElement("span",null,n.createElement(f.x6,null,"Install php-gnupg, see"," ",n.createElement("a",{href:"http://php.net/manual/en/gnupg.installation.php",target:"_blank",rel:"noopener noreferrer"},"this guide")))},n.createElement(jt,{className:"baseline svg-icon"})))),n.createElement("div",null,m()),n.createElement("div",null,d()),n.createElement("div",null,(()=>{const t=e.application.configPath.toString();return!0===e.gpg.gpgKeyPublic&&!0===e.gpg.gpgKeyPublicReadable&&e.gpg.gpgKeyPublicBlock?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The public key file is defined in ",{configurationFilePath:t}," and readable.")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"The public key file is not defined in ",{configurationFilePath:t}," or not readable."),n.createElement(Mt,{message:n.createElement(f.x6,null,"Ensure the public key file is defined by the variable passbolt.gpg.serverKey.public in"," ",{configurationFilePath:t})},n.createElement(jt,{className:"baseline svg-icon"})))})()),n.createElement("div",null,(()=>{const t=e.application.configPath.toString();return!0===e.gpg.gpgKeyPrivate&&!0===e.gpg.gpgKeyPrivateReadable&&e.gpg.gpgKeyPrivateBlock?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The private key file is defined in ",{configurationFilePath:t}," and readable.")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"The private key file is not defined in ",{configurationFilePath:t}," or not readable."),n.createElement(Mt,{message:n.createElement(f.x6,null,"Ensure the private key file is defined by the variable passbolt.gpg.serverKey.private in"," ",{configurationFilePath:t})},n.createElement(jt,{className:"baseline svg-icon"})))})()),n.createElement("div",null,u()),n.createElement("div",null,p()),n.createElement("div",null,h()),n.createElement("div",null,!0===e.gpg.canEncrypt?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The public key can be used to encrypt a message")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"The public key cannot be used to encrypt a message"))),n.createElement("div",null,!0===e.gpg.canSign?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The public key can be used to sign a message")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"The public key cannot be used to sign a message"))),n.createElement("div",null,!0===e.gpg.canEncryptSign?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The public and private keys can be used to encrypt and sign a message")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"The public and private keys cannot be used to encrypt and sign a message"))),n.createElement("div",null,!0===e.gpg.canDecryptVerify?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The private key can be used to decrypt and verify a message")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"The private key cannot be used to decrypt and verify a message"))),n.createElement("div",null,!0===e.gpg.canVerify?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The public key can be used to verify a signature")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"The public key cannot be used to verify a signature"))),n.createElement("div",null,!0===e.gpg.isPublicServerKeyGopengpgCompatible?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The server public key format is Gopengpg compatible")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"The server public key format is not Gopengpg compatible"))),n.createElement("div",null,!0===e.gpg.isPrivateServerKeyGopengpgCompatible?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The server private key format is Gopengpg compatible")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"The server private key format is not Gopengpg compatible")))),n.createElement("h4",null,n.createElement(f.x6,null,"Application configuration")),n.createElement("div",{className:"healthcheck-app-section"},n.createElement("div",null,(()=>{if(!0===e.application.latestVersion&&e.application.info.remoteVersion){const t=e.application.info.remoteVersion.toString();return n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"Using latest passbolt version (",{version:t},")"))}if(!1===e.application.latestVersion&&e.application.info.remoteVersion){const t=e.application.info.currentVersion.toString(),a=e.application.info.remoteVersion.toString();return n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"The installation is not up to date. Currently using ",{currentVersion:t}," and it should be"," ",{latestAvailableVersion:a}),n.createElement(Mt,{message:n.createElement("span",null,n.createElement(f.x6,null,"See"," ",n.createElement("a",{href:"https://www.passbolt.com/docs/hosting/update",target:"_blank",rel:"noopener noreferrer"},"this guide")))},n.createElement(jt,{className:"baseline svg-icon"})))}if(null===e.application.latestVersion&&"undefined"===e.application.info.remoteVersion)return n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"It seems that the server is not able to reach internet."),n.createElement(Mt,{message:n.createElement("span",null,n.createElement(f.x6,null,"To confirm that you are running the latest version, check"," ",n.createElement("a",{href:"https://www.passbolt.com/changelog/api-bext",target:"_blank",rel:"noopener noreferrer"},"all the releases notes")))},n.createElement(jt,{className:"baseline svg-icon"})))})()),n.createElement("div",null,(()=>{if(!0===e.application.sslForce)return n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"Passbolt is configured to force SSL use"));{const t=e.application.configPath.toString();return n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"Passbolt is not configured to force SSL use"),n.createElement(Mt,{message:n.createElement(f.x6,null,"Set passbolt.ssl.force to true in ",{configurationFilePath:t})},n.createElement(jt,{className:"baseline svg-icon"})))}})()),n.createElement("div",null,(()=>{if(!0===e.application.sslFullBaseUrl)return n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"App.fullBaseUrl is set to HTTPS"));{const t=e.application.configPath.toString();return n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"App.fullBaseUrl is not set to HTTPS"),n.createElement(Mt,{message:n.createElement(f.x6,null,"Check App.fullBaseUrl url scheme in ",{configurationFilePath:t})},n.createElement(jt,{className:"baseline svg-icon"})))}})()),n.createElement("div",null,(()=>{if(!0===e.application.seleniumDisabled)return n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"Selenium API endpoints are disabled"));{const t=e.application.configPath.toString();return n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"Selenium API endpoints are active. This setting should be used for testing only"),n.createElement(Mt,{message:n.createElement(f.x6,null,"Set passbolt.selenium.active to false in ",{configurationFilePath:t})},n.createElement(jt,{className:"baseline svg-icon"})))}})()),n.createElement("div",null,(()=>{if(!0===e.application.robotsIndexDisabled)return n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"Search engine robots are told not to index content"));{const t=e.application.configPath.toString();return n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"Search engine robots are not told not to index content"),n.createElement(Mt,{message:n.createElement(f.x6,null,"Set passbolt.meta.robots to false in ",{configurationFilePath:t})},n.createElement(jt,{className:"baseline svg-icon"})))}})()),n.createElement("div",null,g()),n.createElement("div",null,(()=>{if(null===e.application.registrationClosed.selfRegistrationProvider)return n.createElement("span",{className:"healthcheck-info"},n.createElement(Cu,null),n.createElement(f.x6,null,"Registration is closed, only administrators can add users"));{const t=e.application.registrationClosed.selfRegistrationProvider.toString();return n.createElement("span",{className:"healthcheck-info"},n.createElement(Cu,null),n.createElement(f.x6,null,"The Self Registration provider is: ",{selfRegistrationProvider:t}))}})()),n.createElement("div",null,y()),n.createElement("div",null,b()),n.createElement("div",null,(()=>{if(!0===e.application.jsProd)return n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"Serving the compiled version of the javascript app"));{const t=e.application.configPath.toString();return n.createElement("span",{className:"healthcheck-warning"},n.createElement(Au,null),n.createElement(f.x6,null,"Using non-compiled Javascript. Passbolt will be slower"),n.createElement(Mt,{message:n.createElement(f.x6,null,"Set passbolt.js.build in ",{configurationFilePath:t})},n.createElement(jt,{className:"baseline svg-icon"})))}})()),n.createElement("div",null,!0===e.application.emailNotificationEnabled?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"All email notifications will be sent")):n.createElement("span",{className:"healthcheck-warning"},n.createElement(Au,null),n.createElement(f.x6,null,"Some email notifications are disabled by the administrators")))),n.createElement("h4",null,n.createElement(f.x6,null,"SMTP Settings")),n.createElement("div",{className:"healthcheck-smtp-section"},n.createElement("div",null,!0===e.smtpSettings.isEnabled?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The SMTP Settings plugin is enabled")):n.createElement("span",{className:"healthcheck-warning"},n.createElement(Au,null),n.createElement(f.x6,null,"The SMTP Settings plugin is disabled"))),n.createElement("div",null,(()=>{if(!1===e.smtpSettings.errorMessage)return n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"SMTP Settings coherent. You may send a test email to validate them"));{const t=e.smtpSettings.errorMessage.toString();return n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"SMTP Settings errors: ",{errorMessage:t}))}})()),n.createElement("div",null,E()),n.createElement("div",null,v())),this.shouldDisplayUserDirectory&&n.createElement(n.Fragment,null,n.createElement("h4",null,n.createElement(f.x6,null,"Directory Sync")),n.createElement("div",{className:"healthcheck-directorySync-section"},n.createElement("div",null,w()))),this.shouldDisplaySSO&&n.createElement(n.Fragment,null,n.createElement("h4",null,n.createElement(f.x6,null,"SSO")),n.createElement("div",{className:"healthcheck-sso-section"},n.createElement("div",null,k()))),this.shouldDisplayMetadata&&n.createElement(n.Fragment,null,n.createElement("h4",null,n.createElement(f.x6,null,"Metadata")),n.createElement("div",{className:"healthcheck-metadata-section"},!0===e.metadata.isServerMetadataKeyAccessInZeroKnowledgeMode?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The server does not have access to the server metadata private key in Zero-knowledge mode.")):n.createElement(n.Fragment,null,n.createElement("div",null,_()),n.createElement("div",null,x()),n.createElement("div",null,S()),n.createElement("div",null,C()))))))():n.createElement("div",null,n.createElement(f.x6,null,"The health check API endpoint has been disabled in the server configuration."))),Xa(n.createElement(n.Fragment,null,n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"What is this page?")),n.createElement("p",null,n.createElement(f.x6,null,"This page is available to help administrators diagnose if something is wrong with a passbolt installation and help keeping it secure.")),n.createElement("p",null,n.createElement(f.x6,null,"The color is really important here so it's easier for you to spot what's not running as expected")),n.createElement("div",{className:"healthcheck-color-legends"},n.createElement("div",{className:"healthcheck-success"},n.createElement(vu,null)," ",n.createElement(f.x6,null,"Everything is running as expected.")),n.createElement("div",{className:"healthcheck-warning"},n.createElement(Au,null)," ",n.createElement(f.x6,null,"Something inside your configuration is not what we recommend, but you can skip it if it has been done on purpose.")),n.createElement("div",{className:"healthcheck-fail"},n.createElement(_u,null)," ",n.createElement(f.x6,null,"There is an error with the current configuration, you might want to resolve it.")),n.createElement("div",{className:"healthcheck-info"},n.createElement(Cu,null)," ",n.createElement(f.x6,null,"This is just an information shared, no action is required.")))),n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"Something wrong?")),n.createElement("p",null,n.createElement(f.x6,null,"Hang in there! Depending your installation, you might need to check the documentation in order to run the healthcheck from the CLI")),n.createElement("a",{className:"button",href:"https://www.passbolt.com/docs/admin/server-maintenance/passbolt-api-status/",target:"_blank",rel:"noopener noreferrer"},n.createElement(ps,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation"))))),document.getElementById("administration-help-panel"))))}}Iu.propTypes={context:i().object,adminHealthcheckContext:i().any,children:i().any,administrationWorkspaceContext:i().object,t:i().func};const Ru=N(Ne(mu((0,f.CI)("common")(Iu)))),Pu="v4",Du="v5";class Ou extends he{static getSchema(){return{type:"object",required:["default_resource_types","default_folder_type","default_tag_type","default_comment_type","allow_creation_of_v5_resources","allow_creation_of_v5_folders","allow_creation_of_v5_tags","allow_creation_of_v5_comments","allow_creation_of_v4_resources","allow_creation_of_v4_folders","allow_creation_of_v4_tags","allow_creation_of_v4_comments","allow_v4_v5_upgrade","allow_v5_v4_downgrade"],properties:{default_resource_types:{type:"string",enum:[Pu,Du]},default_folder_type:{type:"string",enum:[Pu,Du]},default_tag_type:{type:"string",enum:[Pu,Du]},default_comment_type:{type:"string",enum:[Pu,Du]},allow_creation_of_v5_resources:{type:"boolean"},allow_creation_of_v5_folders:{type:"boolean"},allow_creation_of_v5_tags:{type:"boolean"},allow_creation_of_v5_comments:{type:"boolean"},allow_creation_of_v4_resources:{type:"boolean"},allow_creation_of_v4_folders:{type:"boolean"},allow_creation_of_v4_tags:{type:"boolean"},allow_creation_of_v4_comments:{type:"boolean"},allow_v4_v5_upgrade:{type:"boolean"},allow_v5_v4_downgrade:{type:"boolean"}}}}static createFromV4Default(){return new Ou({default_resource_types:Pu,default_folder_type:Pu,default_tag_type:Pu,default_comment_type:Pu,allow_creation_of_v5_resources:!1,allow_creation_of_v5_folders:!1,allow_creation_of_v5_tags:!1,allow_creation_of_v5_comments:!1,allow_creation_of_v4_resources:!0,allow_creation_of_v4_folders:!0,allow_creation_of_v4_tags:!0,allow_creation_of_v4_comments:!0,allow_v4_v5_upgrade:!1,allow_v5_v4_downgrade:!1})}static createFromDefault(e={}){return new Ou({default_resource_types:Pu,default_folder_type:Pu,default_tag_type:Pu,default_comment_type:Pu,allow_creation_of_v5_resources:!1,allow_creation_of_v5_folders:!1,allow_creation_of_v5_tags:!1,allow_creation_of_v5_comments:!1,allow_creation_of_v4_resources:!0,allow_creation_of_v4_folders:!0,allow_creation_of_v4_tags:!0,allow_creation_of_v4_comments:!0,allow_v4_v5_upgrade:!1,allow_v5_v4_downgrade:!1,...e})}static createFromV5Default(e={}){return new Ou({default_resource_types:Du,default_folder_type:Pu,default_tag_type:Pu,default_comment_type:Pu,allow_creation_of_v5_resources:!0,allow_creation_of_v5_folders:!1,allow_creation_of_v5_tags:!1,allow_creation_of_v5_comments:!1,allow_creation_of_v4_resources:!1,allow_creation_of_v4_folders:!0,allow_creation_of_v4_tags:!0,allow_creation_of_v4_comments:!0,allow_v4_v5_upgrade:!1,allow_v5_v4_downgrade:!1,...e})}validateBuildRules(){let e;if(this.isDefaultResourceTypeV4&&!this.allowCreationOfV4Resources){e=e||new X;const t="Allow creation of v4 resources should be true when default resources is v4";e.addError("allow_creation_of_v4_resources","is_default",t),e.addError("default_resource_types","allow_create_v4",t)}else if(this.isDefaultResourceTypeV5&&!this.allowCreationOfV5Resources){e=e||new X;const t="Allow creation of v5 resources should be true when default resources is v5";e.addError("allow_creation_of_v5_resources","is_default",t),e.addError("default_resource_types","allow_create_v5",t)}if(e)throw e}get defaultResourceTypes(){return this._props.default_resource_types}get allowCreationOfV5Resources(){return this._props.allow_creation_of_v5_resources}get allowCreationOfV4Resources(){return this._props.allow_creation_of_v4_resources}get allowCreationOfV5Folders(){return this._props.allow_creation_of_v5_folders}get allowCreationOfV4Folders(){return this._props.allow_creation_of_v4_folders}get allowCreationOfV5Tags(){return this._props.allow_creation_of_v5_tags}get allowCreationOfV4Tags(){return this._props.allow_creation_of_v4_tags}get allowCreationOfV5Comments(){return this._props.allow_creation_of_v5_comments}get allowCreationOfV4Comments(){return this._props.allow_creation_of_v4_comments}get isDefaultResourceTypeV5(){return this._props.default_resource_types===Du}get isDefaultResourceTypeV4(){return this._props.default_resource_types===Pu}get allowV5V4Downgrade(){return this._props.allow_v5_v4_downgrade}get allowV4V5Upgrade(){return this._props.allow_v4_v5_upgrade}}const Mu=Ou,Uu="keepass-icon-set",Fu="passbolt-icon-set",ju="password-string",Lu="password-and-description",qu="password-description-totp",zu="totp",Ku="v5-default",Vu="v5-password-string",Gu="v5-default-with-totp",Bu="v5-totp-standalone",Wu="v5-custom-fields",Hu="v5-note",$u="v5-pin-code",Yu={resource:{type:"object",required:["name"],properties:{name:{type:"string",maxLength:255},username:{type:"string",maxLength:255,nullable:!0},description:{maxLength:1e4,nullable:!0,type:"string"},uri:{type:"string",maxLength:1024,nullable:!0}}},secret:{type:"string",maxLength:4096}},Zu={resource:{type:"object",required:["name"],properties:{name:{type:"string",maxLength:255},username:{type:"string",maxLength:255,nullable:!0},uri:{type:"string",maxLength:1024,nullable:!0}}},secret:{type:"object",required:["password"],properties:{password:{type:"string",maxLength:4096},description:{type:"string",maxLength:1e4,nullable:!0}}}},Ju={resource:{type:"object",required:["name"],properties:{name:{type:"string",maxLength:255},uri:{type:"string",maxLength:1024,nullable:!0}}},secret:{type:"object",required:["totp"],properties:{totp:{type:"object",required:["secret_key","digits","algorithm"],properties:{algorithm:{type:"string",minLength:4,maxLength:6},secret_key:{type:"string",maxLength:1024},digits:{type:"number",minimum:6,maximum:8},period:{type:"number"}}}}}},Xu={resource:{type:"object",required:["name"],properties:{name:{type:"string",maxLength:255},username:{type:"string",maxLength:255,nullable:!0},uri:{type:"string",maxLength:1024,nullable:!0}}},secret:{type:"object",required:["password","totp"],properties:{password:{type:"string",maxLength:4096},description:{type:"string",maxLength:1e4,nullable:!0},totp:Ju.secret.properties.totp}}},Qu={resource:{type:"object",required:["name"],properties:{name:{type:"string",maxLength:255},username:{type:"string",maxLength:255,nullable:!0},uris:{type:"array",items:{type:"string",maxLength:1024,nullable:!0},maxItems:32},description:{type:"string",maxLength:1e4,nullable:!0},icon:{type:"object",required:[],properties:{type:{type:"string",enum:[Uu,Fu]},value:{type:"number",minimum:0,nullable:!0},background_color:{type:"string",nullable:!0}}},custom_fields:{type:"array",maxItems:128,items:{type:"object",required:["id","type"],properties:{id:{type:"string",format:"uuid"},type:{type:"string",enum:["text","password","boolean","number","uri"]},metadata_key:{type:"string",maxLength:255,nullable:!0},metadata_value:{anyOf:[{type:"string",maxLength:2e4},{type:"number"},{type:"boolean"}],nullable:!0}}}}}},secret:{type:"object",required:["custom_fields","object_type"],properties:{object_type:{type:"string",enum:["PASSBOLT_SECRET_DATA"]},custom_fields:{type:"array",maxItems:128,items:{type:"object",required:["id","type"],properties:{id:{type:"string",format:"uuid"},type:{type:"string",enum:["text","password","boolean","number","uri"]},secret_key:{type:"string",maxLength:255,nullable:!0},secret_value:{anyOf:[{type:"string",maxLength:2e4},{type:"number"},{type:"boolean"}],nullable:!0}}}}}}},ep={resource:{type:"object",required:["name"],properties:{name:{type:"string",maxLength:255},username:{type:"string",maxLength:255,nullable:!0},uris:{type:"array",items:{type:"string",maxLength:1024,nullable:!0},maxItems:32},description:{type:"string",maxLength:1e4,nullable:!0},icon:{type:"object",required:[],properties:{type:{type:"string",enum:[Uu,Fu]},value:{type:"number",minimum:0,nullable:!0},background_color:{type:"string",nullable:!0}}},custom_fields:Qu.resource.properties.custom_fields}},secret:{type:"object",required:["password"],properties:{object_type:{type:"string",enum:["PASSBOLT_SECRET_DATA"]},password:{type:"string",maxLength:4096,nullable:!0},description:{type:"string",maxLength:5e4,nullable:!0},custom_fields:Qu.secret.properties.custom_fields}}},tp={resource:{type:"object",required:["name"],properties:{name:{type:"string",maxLength:255},username:{type:"string",maxLength:255,nullable:!0},uris:{type:"array",items:{type:"string",maxLength:1024,nullable:!0},maxItems:32},description:{type:"string",maxLength:1e4,nullable:!0},icon:{type:"object",required:[],properties:{type:{type:"string",enum:[Uu,Fu]},value:{type:"number",minimum:0,nullable:!0},background_color:{type:"string",nullable:!0}}}}},secret:{type:"string",maxLength:4096}},ap={resource:{type:"object",required:["name"],properties:{name:{type:"string",maxLength:255},username:{type:"string",maxLength:255,nullable:!0},uris:{type:"array",items:{type:"string",maxLength:1024,nullable:!0},maxItems:32},description:{type:"string",maxLength:1e4,nullable:!0},icon:{type:"object",required:[],properties:{type:{type:"string",enum:[Uu,Fu]},value:{type:"number",minimum:0,nullable:!0},background_color:{type:"string",nullable:!0}}},custom_fields:Qu.resource.properties.custom_fields}},secret:{type:"object",required:["password","totp"],properties:{object_type:{type:"string",enum:["PASSBOLT_SECRET_DATA"]},password:{type:"string",maxLength:4096,nullable:!0},description:{type:"string",maxLength:5e4,nullable:!0},totp:Ju.secret.properties.totp,custom_fields:Qu.secret.properties.custom_fields}}},np={resource:{type:"object",required:["name"],properties:{name:{type:"string",maxLength:255},uris:{type:"array",items:{type:"string",maxLength:1024,nullable:!0},maxItems:32},description:{type:"string",maxLength:1e4,nullable:!0},icon:{type:"object",required:[],properties:{type:{type:"string",enum:[Uu,Fu]},value:{type:"number",minimum:0,nullable:!0},background_color:{type:"string",nullable:!0}}}}},secret:{type:"object",required:["totp"],properties:{object_type:{type:"string",enum:["PASSBOLT_SECRET_DATA"]},totp:{type:"object",required:["secret_key","digits","algorithm"],properties:{algorithm:{type:"string",minLength:4,maxLength:6},secret_key:{type:"string",maxLength:1024},digits:{type:"number",minimum:6,maximum:8},period:{type:"number"}}}}}},sp={resource:{type:"object",required:["name"],properties:{name:{type:"string",maxLength:255},uris:{type:"array",items:{type:"string",maxLength:1024,nullable:!0},maxItems:32},description:{type:"string",maxLength:1e4,nullable:!0},icon:{type:"object",required:[],properties:{type:{type:"string",enum:[Uu,Fu]},value:{type:"number",minimum:0,nullable:!0},background_color:{type:"string",nullable:!0}}}}},secret:{type:"object",required:["description","object_type"],properties:{object_type:{type:"string",enum:["PASSBOLT_SECRET_DATA"]},description:{type:"string",maxLength:5e4}}}},ip={resource:{type:"object",required:["name"],properties:{name:{type:"string",maxLength:255},description:{type:"string",maxLength:1e4,nullable:!0},icon:{type:"object",required:[],properties:{type:{type:"string",enum:[Uu,Fu]},value:{type:"number",minimum:0,nullable:!0},background_color:{type:"string",nullable:!0}}}}},secret:{type:"object",required:["pin_code","object_type"],properties:{object_type:{type:"string",enum:["PASSBOLT_SECRET_DATA"]},pin_code:{type:"string",minLength:4,maxLength:12,pattern:"^\\d+$"},description:{type:"string",maxLength:5e4,nullable:!0}}}},rp={[ju]:Vu,[Lu]:Ku,[qu]:Gu,[zu]:Bu},op=new class{get SCHEMAS(){return{[ju]:Yu,[Lu]:Zu,[qu]:Xu,[zu]:Ju,[Ku]:ep,[Vu]:tp,[Gu]:ap,[Bu]:np,[Wu]:Qu,[Hu]:sp,[$u]:ip}}},lp=[ju,Lu,qu,Ku,Gu,Vu],cp=[qu,zu,Gu,Bu],mp=[zu,Bu],dp=[ju,Vu],up=[Lu,qu,Ku,Gu,Hu,$u],pp=[ju,Ku,Gu,Vu,Bu,Wu,Hu,$u],hp=[Ku,Vu,Gu,Bu,Wu,Hu],gp=[Ku,Gu,Wu];class yp extends he{marshall(){if("string"!=typeof this._props.slug||!(this._props.slug in op.SCHEMAS))return void delete this._props.definition;const e=op.SCHEMAS[this._props.slug],t=Object.assign({},e);this._props.definition=t}static getSchema(){return{type:"object",required:["id","name","slug","definition"],properties:{id:{type:"string",format:"uuid"},name:{type:"string",minLength:1,maxLength:255},slug:{type:"string",minLength:1,maxLength:64},definition:{type:"object"},description:{type:"string",maxLength:255,nullable:!0},icon:{type:"object",required:[],properties:{type:{type:"string",enum:[Uu,Fu]},value:{type:"number",minimum:0,nullable:!0},background_color:{type:"string",pattern:/^#(?:[0-9A-F]{6}|[0-9A-F]{8})$/i,nullable:!0}}},resources_count:{type:"integer"},created:{type:"string",format:"date-time"},modified:{type:"string",format:"date-time"},deleted:{type:"string",format:"date-time",nullable:!0}}}}get id(){return this._props.id}get slug(){return this._props.slug}get definition(){return this._props.definition}get resourcesCount(){return this._props.resources_count||null}set deleted(e){const t=yp.getSchema().properties.deleted;t?.nullable&&null===e||ae.validateProp("deleted",e,t),this._props.deleted=e}hasTotp(){return cp.includes(this.slug)}hasPassword(){return lp.includes(this.slug)}hasCustomFields(){return gp.includes(this.slug)}hasPinCode(){return $u===this.slug}isStandalonePinCode(){return this.hasPinCode()}isStandaloneTotp(){return mp.includes(this.slug)}isPasswordString(){return dp.includes(this.slug)}hasSecretDescription(){return up.includes(this.slug)}hasMetadataDescription(){return pp.includes(this.slug)}hasMetadataUris(){return hp.includes(this.slug)}get version(){return this.slug.startsWith("v5")?Du:Pu}isV5(){return this.version===Du}isV4(){return this.version===Pu}isDeleted(){return void 0!==this._props.deleted&&null!==this._props.deleted}}const bp=yp,fp=[ju,Lu,qu,zu,Ku,Gu,Vu,Bu,Wu,Hu,$u],Ep=class extends Bc{get entityClass(){return bp}constructor(e=[],t={}){super(e,t)}static getSchema(){return{type:"array",items:bp.getSchema()}}validateBuildRules(e,t={}){this.assertNotExist("id",e._props.id,{haystackSet:t?.uniqueIdsSetCache}),this.assertNotExist("slug",e._props.slug,{haystackSet:t?.uniqueSlugsSetCache})}isResourceTypeIdPresent(e){return this._items.some(t=>t.id===e)}filterByPasswordResourceTypes(){this.filterByPropertyValueIn("slug",lp)}filterByTOTPResourceTypes(){this.filterByPropertyValueIn("slug",cp)}filterByResourceTypeVersion(e){this.filterByCallback(t=>t.version===e)}getFirstById(e){return this.getFirst("id",e)}getFirstBySlug(e){return this.getFirst("slug",e)}hasOneWithSlug(e){return Boolean(this.getFirstBySlug(e))}hasSomePasswordResourceTypes(e=Pu){return this.items.some(t=>t.hasPassword()&&t.version===e)}hasSomeTotpResourceTypes(e=Pu){return this.items.some(t=>t.hasTotp()&&t.version===e)}hasSomeCustomFieldsResourceTypes(e=Pu){return this.items.some(t=>t.hasCustomFields()&&t.version===e)}hasSomeNoteResourceTypes(e=Pu){return this.items.some(t=>t.hasSecretDescription()&&t.version===e)}hasSomePinCodeResourceTypes(e=Pu){return this.items.some(t=>t.hasPinCode()&&t.version===e)}hasSomeMetadataDescriptionResourceTypes(e=Pu){return this.items.some(t=>t.hasMetadataDescription()&&t.version===e)}hasSomeOfVersion(e=Pu){return this.items.some(t=>t.version===e)}getResourceTypeMatchingResource(e,t=Pu){if((0,ie.A)(t),null==e?.secret||"object"!=typeof e.secret)throw new TypeError("The resource DTO is not an expected object");let a=null,n=null;const s=Object.keys(e.secret);for(const e of this.items){if(e.version!==t||e.isPasswordString())continue;const i=Object.keys(e.definition.secret.properties);if(s.every(e=>i.includes(e))){const t=i.filter(e=>!s.includes(e)).length;if(0===t)return e;(!n||n>t)&&(n=t,a=e)}}return a}pushMany(e,t={},a={}){const n=new Set(this.extract("id")),s=new Set(this.extract("slug"));a={onItemPushed:e=>{n.add(e.id),s.add(e.slug)},validateBuildRules:{...a?.validateBuildRules,uniqueIdsSetCache:n,uniqueSlugsSetCache:s},...a},super.pushMany(e,t,a)}push(e,t={},a={}){fp.includes(e?.slug)&&super.push(e,t,a)}},vp=class extends he{static getSchema(){return{type:"object",required:["user_id","armored_key"],properties:{id:{type:"string",format:"uuid"},user_id:{type:"string",format:"uuid"},fingerprint:{type:"string",minLength:40,maxLength:40},armored_key:{type:"string"},deleted:{type:"boolean"},type:{type:"string",nullable:!0},uid:{type:"string"},bits:{type:"integer",nullable:!0},key_id:{type:"string",minLength:8,maxLength:16},key_created:{type:"string",format:"date-time"},expires:{type:"string",format:"date-time",nullable:!0},created:{type:"string",format:"date-time"},modified:{type:"string",format:"date-time"}}}}get id(){return this._props.id||null}get userId(){return this._props.user_id}get armoredKey(){return this._props.armored_key}get fingerprint(){return this._props.fingerprint}get created(){return this._props.created||null}get modified(){return this._props.modified||null}get isDeleted(){return void 0===this._props.deleted?null:this._props.deleted}static get ENTITY_NAME(){return"gpgkey"}};class wp extends he{static getSchema(){return{type:"object",required:[wp.AVATAR_URL_SIZE_MEDIUM,wp.AVATAR_URL_SIZE_SMALL],properties:{medium:{type:"string"},small:{type:"string"}}}}get medium(){return this._props.medium}get small(){return this._props.small}static get ENTITY_NAME(){return"AvatarUrl"}static get AVATAR_URL_SIZE_MEDIUM(){return"medium"}static get AVATAR_URL_SIZE_SMALL(){return"small"}}const kp=wp,_p=class extends he{constructor(e={},t={}){super(e,t),this._props.url&&(this._url=new kp(this._props.url,{...t,clone:!1}),delete this._props.url)}static getSchema(){return{type:"object",required:["url"],properties:{id:{type:"string",format:"uuid"},created:{type:"string",format:"date-time"},modified:{type:"string",format:"date-time"},url:kp.getSchema()}}}get id(){return this._props.id||null}get urlMedium(){return this._url.medium}get urlSmall(){return this._url.small}get created(){return this._props.created||null}get modified(){return this._props.modified||null}toDto(e){const t=super.toDto(e);return t.url=this._url.toDto(),t}static get ENTITY_NAME(){return"Avatar"}static get AVATAR_URL_SIZE_MEDIUM(){return"medium"}static get AVATAR_URL_SIZE_SMALL(){return"small"}};class xp extends he{constructor(e={},t={}){super(e,t),this._props.avatar&&(this._avatar=new _p(this._props.avatar,{...t,clone:!1}),delete this._props.avatar)}static getSchema(){return{type:"object",required:["first_name","last_name"],properties:{id:{type:"string",format:"uuid"},user_id:{type:"string",format:"uuid"},first_name:{type:"string",minLength:1,maxLength:255},last_name:{type:"string",minLength:1,maxLength:255},created:{type:"string",format:"date-time"},modified:{type:"string",format:"date-time"},avatar:_p.getSchema()}}}toDto(e){const t=Object.assign({},this._props);return this.avatar&&e&&e.avatar&&(t.avatar=this.avatar.toDto()),t}toJSON(){return this.toDto(xp.ALL_CONTAIN_OPTIONS)}static get ENTITY_NAME(){return"Profile"}static get ALL_CONTAIN_OPTIONS(){return{avatar:!0}}get id(){return this._props.id||null}get name(){return`${this._props.first_name} ${this._props.last_name}`}get firstName(){return this._props.first_name}get lastName(){return this._props.last_name}get userId(){return this._props.user_id||null}get created(){return this._props.created||null}get modified(){return this._props.modified||null}get avatar(){return this._avatar||null}}const Sp=xp,Cp=class extends he{static getSchema(){return{type:"object",required:["user_id","is_admin"],properties:{id:{type:"string",format:"uuid"},user_id:{type:"string",format:"uuid"},group_id:{type:"string",format:"uuid"},is_admin:{type:"boolean"},created:{type:"string",format:"date-time"}}}}toDto(){return Object.assign({},this._props)}get id(){return this._props.id||null}get userId(){return this._props.user_id}get groupId(){return this._props.group_id||null}get isAdmin(){return this._props.is_admin}get created(){return this._props.created||null}set id(e){if(!ee().isUUID(e))throw new TypeError("The group user id should be a valid UUID.");this._props.id=e}static get ENTITY_NAME(){return"GroupUser"}static get ALL_CONTAIN_OPTIONS(){return{}}},Np=class extends Bc{get entityClass(){return Cp}static getSchema(){return{type:"array",items:Cp.getSchema()}}get groupsUsers(){return this._items}static get ENTITY_NAME(){return"GroupsUsers"}getGroupUserByUserId(e){return this.groupsUsers.find(t=>t.userId===e)}getById(e){return this.items.find(t=>t.id===e)}};class Tp extends se{constructor(e,t={}){super(ae.validate(Tp.ENTITY_NAME,e,Tp.getSchema()),t)}static getSchema(){return{type:"object",required:["recipient_foreign_model","recipient_fingerprint","data"],properties:{id:{type:"string",format:"uuid"},private_key_id:{type:"string",format:"uuid"},recipient_foreign_model:{type:"string",enum:[Tp.FOREIGN_MODEL_ORGANIZATION_KEY]},recipient_foreign_key:{type:"string",format:"uuid"},recipient_fingerprint:{type:"string",length:40},data:{type:"string"}}}}toDto(){return Object.assign({},this._props)}toJSON(){return this.toDto()}get id(){return this._props.id||null}get privateKeyId(){return this._props.private_key_id||null}get recipientForeignKey(){return this._props.recipient_foreign_key||null}get data(){return this._props.data}get recipientForeignModel(){return this._props.recipient_foreign_model}get recipientFingerprint(){return this._props.recipient_fingerprint}static get ENTITY_NAME(){return"AccountRecoveryPrivateKeyPassword"}static get FOREIGN_MODEL_ORGANIZATION_KEY(){return"AccountRecoveryOrganizationKey"}}const Ap=Tp;class Ip extends de{constructor(e,t={}){super(ae.validate(Ip.ENTITY_NAME,e,Ip.getSchema()),t),this._props.map(e=>e.id).sort().sort((e,t)=>{if(e===t)throw new ce(0,Ip.RULE_UNIQUE_ID,`AccountRecoveryPrivateKeyPassword id ${e} already exists.`)}),this._props.forEach(e=>{this._items.push(new Ap(e,{...t,clone:!1}))}),this._props=null}static getSchema(){return{type:"array",items:Ap.getSchema()}}get accountRecoveryPrivateKeyPasswords(){return this._items}get ids(){return this._items.map(e=>e.id)}static sanitizeDto(e){return Array.isArray(e)?((e,t)=>{if(!Array.isArray(e))throw new TypeError("deduplicateObjects first parameter should be an array.");if("string"!=typeof t)throw new TypeError("deduplicateObjects second parameter should be a string.");const a=e.filter(e=>Object.prototype.hasOwnProperty.call(e,t)).map(e=>e[t]).reduce((e,t,a)=>(e[t]=Object.prototype.hasOwnProperty.call(e,t)?e[t]:a,e),{});return e.filter((e,n)=>!Object.prototype.hasOwnProperty.call(e,t)||a[e[t]]===n)})(e,"id"):[]}assertUniqueId(e){if(!e.id)return;const t=this.accountRecoveryPrivateKeyPasswords.length;let a=0;for(;at.id===e);this.items.splice(t,1)}removeMany(e){for(const t in e)this.remove(e[t])}filterByForeignModel(e){return this.items.find(t=>t.recipientForeignModel===e)}static get ENTITY_NAME(){return"AccountRecoveryPrivateKeyPassword"}static get RULE_UNIQUE_ID(){return"unique_id"}}const Rp=Ip;class Pp extends se{constructor(e,t={}){if(super(ae.validate(Pp.ENTITY_NAME,e,Pp.getSchema()),t),this._props.account_recovery_private_key_passwords){const e=Rp.sanitizeDto(this._props.account_recovery_private_key_passwords);this._account_recovery_private_key_passwords=new Rp(e,{...t,clone:!1}),delete this._props.account_recovery_private_key_passwords}}static getSchema(){return{type:"object",required:[],properties:{id:{type:"string",format:"uuid"},user_id:{type:"string",format:"uuid"},data:{type:"string"},created:{type:"string",format:"date-time"},modified:{type:"string",format:"date-time"},created_by:{type:"string",format:"uuid"},modified_by:{type:"string",format:"uuid"},account_recovery_private_key_passwords:Rp.getSchema()}}}toDto(e){const t=Object.assign({},this._props);return e?(this._account_recovery_private_key_passwords&&e.account_recovery_private_key_passwords&&(t.account_recovery_private_key_passwords=this._account_recovery_private_key_passwords.toDto()),t):t}toJSON(){return this.toDto(Pp.ALL_CONTAIN_OPTIONS)}get id(){return this._props.id||null}get userId(){return this._props.user_id||null}get data(){return this._props.data||null}get accountRecoveryPrivateKeyPasswords(){return this._account_recovery_private_key_passwords||null}static get ENTITY_NAME(){return"AccountRecoveryPrivateKey"}static get ALL_CONTAIN_OPTIONS(){return{account_recovery_private_key_passwords:!0}}}const Dp=Pp;class Op extends se{constructor(e,t={}){super(ae.validate(Op.ENTITY_NAME,e,Op.getSchema()),t),this._props.account_recovery_private_key&&(this._account_recovery_private_key=new Dp(this._props.account_recovery_private_key,{...t,clone:!1}),delete this._props.account_recovery_private_key)}static getSchema(){return{type:"object",required:["status"],properties:{id:{type:"string",format:"uuid"},user_id:{type:"string",format:"uuid"},status:{type:"string",enum:[Op.STATUS_APPROVED,Op.STATUS_REJECTED]},created:{type:"string",format:"date-time"},modified:{type:"string",format:"date-time"},created_by:{type:"string",format:"uuid"},modified_by:{type:"string",format:"uuid"},account_recovery_private_key:Dp.getSchema()}}}toDto(e){const t=Object.assign({},this._props);return this._account_recovery_private_key&&e?.account_recovery_private_key&&(t.account_recovery_private_key=this._account_recovery_private_key.toDto(Dp.ALL_CONTAIN_OPTIONS)),t}toJSON(){return this.toDto()}get status(){return this._props.status}get isApproved(){return this.status===Op.STATUS_APPROVED}get isRejected(){return this.status===Op.STATUS_REJECTED}get accountRecoveryPrivateKey(){return this._account_recovery_private_key||null}static get ENTITY_NAME(){return"AccountRecoveryUserSetting"}static get ALL_CONTAIN_OPTIONS(){return{account_recovery_private_key:!0}}static get STATUS_APPROVED(){return"approved"}static get STATUS_REJECTED(){return"rejected"}}const Mp=Op;class Up extends se{constructor(e={},t={}){super(ae.validate(Up.ENTITY_NAME,e,Up.getSchema()),t)}static getSchema(){return{type:"object",required:["id","status"],properties:{id:{type:"string",format:"uuid"},status:{type:"string",enum:["pending"]},created:{type:"string",format:"date-time"},modified:{type:"string",format:"date-time"},created_by:{type:"string",format:"uuid"},modified_by:{type:"string",format:"uuid"}}}}get id(){return this._props.id}get status(){return this._props.status}static get ENTITY_NAME(){return"PendingAccountRecoveryRequest"}}const Fp=Up;class jp extends he{constructor(e,t={}){super(e,t),this._props.profile&&(this._profile=new Sp(this._props.profile,{...t,clone:!1}),delete this._props.profile),this._props.role&&(this._role=new ge(this._props.role,{...t,clone:!1}),delete this._props.role),this._props.gpgkey&&(this._gpgkey=new vp(this._props.gpgkey,{...t,clone:!1}),delete this._props.gpgkey),this._props.groups_users&&(this._groups_users=new Np(this._props.groups_users,{...t,clone:!1}),delete this._props.groups_users),this._props.account_recovery_user_setting&&(this._account_recovery_user_setting=new Mp(this._props.account_recovery_user_setting,{...t,clone:!1}),delete this._props.account_recovery_user_setting),this._props.pending_account_recovery_request&&(this._pending_account_recovery_request=new Fp(this._props.pending_account_recovery_request,{...t,clone:!1}),delete this._props.pending_account_recovery_request)}marshall(){""===this._props.last_logged_in&&(this._props.last_logged_in=null),super.marshall()}static getSchema(){return{type:"object",required:["username"],properties:{id:{type:"string",format:"uuid"},role_id:{type:"string",format:"uuid"},username:{type:"string"},active:{type:"boolean"},deleted:{type:"boolean"},disabled:{type:"string",format:"date-time",nullable:!0},missing_metadata_key_ids:{type:"array",items:{type:"string",format:"uuid"}},created:{type:"string",format:"date-time"},modified:{type:"string",format:"date-time"},last_logged_in:{type:"string",format:"date-time",nullable:!0},is_mfa_enabled:{type:"boolean",nullable:!0},locale:{type:"string",pattern:/^[a-z]{2}-[A-Z]{2}$/,nullable:!0},role:ge.getSchema(),profile:Sp.getSchema(),gpgkey:vp.getSchema(),groups_users:Np.getSchema(),account_recovery_user_setting:Mp.getSchema(),pending_account_recovery_request:Fp.getSchema()}}}toDto(e){const t=Object.assign({},this._props);return e?(this.role&&e.role&&(t.role=this.role.toDto()),this.profile&&e.profile&&(!0===e.profile?t.profile=this.profile.toDto():t.profile=this.profile.toDto(e.profile)),this.gpgkey&&e.gpgkey&&(t.gpgkey=this.gpgkey.toDto()),this.groupsUsers&&e.groups_users&&(t.groups_users=this.groupsUsers.toDto()),this.accountRecoveryUserSetting&&e.account_recovery_user_setting&&(t.account_recovery_user_setting=this.accountRecoveryUserSetting.toDto()),this.pendingAccountRecoveryUserRequest&&e.pending_account_recovery_request&&(t.pending_account_recovery_request=this.pendingAccountRecoveryUserRequest.toDto()),t):t}toJSON(){return this.toDto(jp.ALL_CONTAIN_OPTIONS)}get id(){return this._props.id||null}get roleId(){return this._props.role_id||null}get username(){return this._props.username}get isActive(){return void 0===this._props.active?null:this._props.active}get isDeleted(){return void 0===this._props.deleted?null:this._props.deleted}get missingMetadataKeysIds(){return this._props.missing_metadata_key_ids||[]}get created(){return this._props.created||null}get modified(){return this._props.modified||null}get lastLoggedIn(){return this._props.last_logged_in||null}get isMfaEnabled(){return void 0===this._props.is_mfa_enabled?null:this._props.is_mfa_enabled}get locale(){return this._props.locale||null}set locale(e){this._props.locale=e}getUserFormattedName(e=e=>e,t={withUsername:!1}){const a=this.profile;return a&&(Boolean(a.firstName)||Boolean(a.lastName))?t.withUsername?`${a.firstName} ${a.lastName} (${this.username})`:`${a.firstName} ${a.lastName}`:e("Unknown user")}get status(){return this.isDeleted?"deleted":Boolean(this._props.disabled&&new Date(this._props.disabled)<=new Date)?"suspended":"active"}set missingMetadataKeysIds(e){this._props.missing_metadata_key_ids=e}static get ALL_CONTAIN_OPTIONS(){return{profile:Sp.ALL_CONTAIN_OPTIONS,role:!0,gpgkey:!0,groups_users:!0,account_recovery_user_setting:!0,pending_account_recovery_request:!0}}static get ENTITY_NAME(){return"User"}get profile(){return this._profile||null}get role(){return this._role||null}get gpgkey(){return this._gpgkey||null}get groupsUsers(){return this._groups_users||null}get accountRecoveryUserSetting(){return this._account_recovery_user_setting||null}get pendingAccountRecoveryUserRequest(){return this._pending_account_recovery_request||null}}const Lp=jp,qp=class extends he{static getSchema(){return{type:"object",required:["object_type","domain","fingerprint","armored_key","passphrase"],properties:{object_type:{type:"string",enum:["PASSBOLT_METADATA_PRIVATE_KEY"]},domain:{type:"string",maxLength:1024},fingerprint:{type:"string",pattern:/^[a-f0-9]{40}$/im},armored_key:{type:"string",maxLength:1e4,pattern:/^-----BEGIN PGP PRIVATE KEY BLOCK-----\r?\n((?:[!-9;-~]+: [^\r\n]*\r?\n)*\r?\n)((?:[A-Za-z/-9+]{1,76}\r?\n)*)([A-Za-z/-9+]{1,76}={0,2}\r?\n)(=[A-Za-z/-9+]{4}\r?\n)-----END PGP PRIVATE KEY BLOCK-----\s*$/},passphrase:{type:"string",maxLength:1024}}}}get armoredKey(){return this._props.armored_key}get fingerprint(){return this._props.fingerprint}};class zp extends he{constructor(e,t={}){super(e,t),this._props.data&&"string"!=typeof this._props.data&&(this._data=new qp(this._props.data,{...t,clone:!1}),delete this._props.data)}static getSchema(){return{type:"object",required:["user_id","data"],properties:{id:{type:"string",format:"uuid",nullable:!0},metadata_key_id:{type:"string",format:"uuid",nullable:!0},user_id:{type:"string",format:"uuid",nullable:!0},data_signed_by_current_user:{type:"string",format:"date-time",nullable:!0},data:{anyOf:[{type:"string",maxLength:1e4,pattern:/^-----BEGIN PGP MESSAGE-----\r?\n((?:[!-9;-~]+: [^\r\n]*\r?\n)*\r?\n)((?:[A-Za-z/-9+]{1,76}\r?\n)*)([A-Za-z/-9+]{1,76}={0,2}\r?\n)(=[A-Za-z/-9+]{4}\r?\n)-----END PGP MESSAGE-----\s*$/},{type:"object"}]},created:{type:"string",format:"date-time"},created_by:{type:"string",format:"uuid",nullable:!0},modified:{type:"string",format:"date-time"},modified_by:{type:"string",format:"uuid",nullable:!0}}}}validateBuildRules(){if(Boolean(this._props.data)&&Boolean(this._data)){const e=new X,t="The property data and _data cannot be set at the same time";throw e.addError("data","only-one-defined",t),e}}toDto(e){const t=Object.assign({},this._props),a=this.data;return t.data=a instanceof qp?a.toDto():a,e?(this._creator&&e.creator&&(t.creator=this._creator.toDto(Lp.ALL_CONTAIN_OPTIONS)),t):t}toDataDto(){return{data:this.toDto().data}}toContentCodeConfirmTrustRequestDto(){const e=this.toDto();return delete e.data,e}toJSON(){return this.toDto(Lp.ALL_CONTAIN_OPTIONS)}cloneForSharing(e){const t={user_id:e,metadata_key_id:this.metadataKeyId,data:this.data};return new zp(t)}marshall(){}get data(){return this.isDecrypted?this._data:this._props.data}get id(){return this._props.id||null}get metadataKeyId(){return this._props.metadata_key_id||null}get isDecrypted(){return Boolean(this._data)}get userId(){return this._props.user_id}get dataSignedByCurrentUser(){return this._props.data_signed_by_current_user||null}get modifiedBy(){return this._props.modified_by}get modified(){return this._props.modified}set modified(e){this._props.modified=e}set modifiedBy(e){this._props.modifiedBy=e}set data(e){ae.validateProp("data",e,this.cachedSchema.properties.data),"string"==typeof e?(this._props.data=e,delete this._data):(this._data=new qp(e.toDto(),{clone:!0,validate:!1}),delete this._props.data)}set dataSignedByCurrentUser(e){ae.validateProp("data_signed_by_current_user",e,this.cachedSchema.properties.data_signed_by_current_user),this._props.data_signed_by_current_user=e}static get ALL_CONTAIN_OPTIONS(){return{creator:!0}}}const Kp=zp,Vp=class extends Bc{get entityClass(){return Kp}constructor(e=[],t={}){super(e,t)}static getSchema(){return{type:"array",items:Kp.getSchema()}}validateBuildRules(e,t={}){this.assertNotExist("id",e._props.id,{haystackSet:t?.uniqueIdsSetCache}),this.assertNotExist("user_id",e._props.user_id,{haystackSet:t?.uniqueUserIdsSetCache}),this.assertSameMetadataKeyId(e)}assertSameMetadataKeyId(e){if(!e.metadataKeyId)return;const t=this._items.find(e=>Boolean(e.metadataKeyId))?.metadataKeyId;if(!t)return;if(e.metadataKeyId===t)return;const a=new X;throw a.addError("metadata_key_id","same_metadata_key","The collection should not contain different metadata key ID."),a}hasDecryptedPrivateKeys(){return this._items.some(e=>e.isDecrypted)}hasEncryptedPrivateKeys(){return this._items.some(e=>!e.isDecrypted)}pushMany(e,t={},a={}){const n=new Set(this.extract("id")),s=new Set(this.extract("user_id"));a={onItemPushed:e=>{n.add(e._props.id),s.add(e._props.user_id)},validateBuildRules:{...a?.validateBuildRules,uniqueIdsSetCache:n,uniqueUserIdsSetCache:s},...a},super.pushMany(e,t,a)}},Gp=class extends he{constructor(e,t={}){super(e,t),this._props.metadata_private_keys&&(this._metadata_private_keys=new Vp(this._props.metadata_private_keys,{...t,clone:!1}),delete this._props.metadata_private_keys,this.assertSameMetadataKeyId()),this._props.creator&&(this._creator=new Lp(this._props.creator,{...t,clone:!1}),delete this._props.creator)}static getSchema(){return{type:"object",required:["fingerprint","armored_key"],properties:{id:{type:"string",format:"uuid",nullable:!0},fingerprint:{type:"string",pattern:/^[a-f0-9]{40}$/im},armored_key:{type:"string",maxLength:1e4,pattern:/^-----BEGIN PGP PUBLIC KEY BLOCK-----\r?\n((?:[!-9;-~]+: [^\r\n]*\r?\n)*\r?\n)((?:[A-Za-z/-9+]{1,76}\r?\n)*)([A-Za-z/-9+]{1,76}={0,2}\r?\n)(=[A-Za-z/-9+]{4}\r?\n)-----END PGP PUBLIC KEY BLOCK-----\s*$/},created:{type:"string",format:"date-time",nullable:!0},created_by:{type:"string",format:"uuid",nullable:!0},modified:{type:"string",format:"date-time",nullable:!0},modified_by:{type:"string",format:"uuid",nullable:!0},deleted:{type:"string",format:"date-time",nullable:!0},expired:{type:"string",format:"date-time",nullable:!0},metadata_private_keys:Vp.getSchema(),creator:Lp.getSchema()}}}validateBuildRules(){}assertSameMetadataKeyId(){if(0!==(this._metadata_private_keys?.length||0)&&this.id!==this._metadata_private_keys.items[0].metadataKeyId){const e=new X;throw e.addError("id:metadata_private_keys","same_id","`id` and the `metadata_private_keys.id` should be the same"),e}}assertFingerprintPublicAndPrivateKeysMatch(){0!==(this._metadata_private_keys?.length||0)&&this._metadata_private_keys.items.forEach((e,t)=>{if(e.isDecrypted&&e.data.fingerprint!==this.fingerprint){const e=new X;throw e.addError(`metadata_private_keys.${t}.fingerprint`,"fingerprint_match","The fingerprint of the metadata private key does not match the fingerprint of the metadata public key"),e}})}toDto(e){const t=Object.assign({},this._props);return e?(this._metadata_private_keys&&e.metadata_private_keys&&(t.metadata_private_keys=this._metadata_private_keys.toDto()),this._creator&&e.creator&&(t.creator=this._creator.toDto(Lp.ALL_CONTAIN_OPTIONS)),t):t}toContentCodeConfirmTrustRequestDto(){const e=this.toDto();return this._metadata_private_keys&&(e.metadata_private_keys=this._metadata_private_keys.items.map(e=>e.toContentCodeConfirmTrustRequestDto())),this._creator&&(e.creator=this._creator.toDto(Lp.ALL_CONTAIN_OPTIONS)),e}get armoredKey(){return this._props.armored_key}get id(){return this._props.id||null}get metadataPrivateKeys(){return this._metadata_private_keys||null}get created(){return this._props.created||null}get fingerprint(){return this._props.fingerprint}get expired(){return this._props.expired||null}get creator(){return this._creator||null}static get ALL_CONTAIN_OPTIONS(){return{metadata_private_keys:!0}}},Bp=class extends Bc{get entityClass(){return Gp}constructor(e=[],t={}){super(e,t)}static getSchema(){return{type:"array",items:Gp.getSchema()}}validateBuildRules(e,t={}){this.assertNotExist("id",e._props.id,{haystackSet:t?.uniqueIdsSetCache}),this.assertNotExist("fingerprint",e._props.fingerprint,{haystackSet:t?.uniqueFingerprintsSetCache})}assertFingerprintsPublicAndPrivateKeysMatch(){this._items.forEach((e,t)=>{try{e.assertFingerprintPublicAndPrivateKeysMatch(t)}catch(e){const a=new Z;throw a.addItemValidationError(t,e),a}})}getFirstByLatestCreated(){return this.length?this._items.reduce((e,t)=>e.created?t.created&&t.created>e.created?t:e:t):null}toDto(e={}){return this._items.map(t=>t.toDto(e))}hasDecryptedKeys(){return this._items.some(e=>e.metadataPrivateKeys?.hasDecryptedPrivateKeys())}hasEncryptedKeys(){return this._items.some(e=>e.metadataPrivateKeys?.hasEncryptedPrivateKeys())}filterOutMissingMetadataPrivateKeys(){this.filterByCallback(e=>e.metadataPrivateKeys?.length)}pushMany(e,t={},a={}){const n=new Set(this.extract("id")),s=new Set(this.extract("fingerprint"));a={onItemPushed:e=>{n.add(e._props.id),s.add(e._props.fingerprint)},validateBuildRules:{...a?.validateBuildRules,uniqueIdsSetCache:n,uniqueFingerprintsSetCache:s},...a},super.pushMany(e,t,a)}},Wp=["default_resource_types","allow_creation_of_v5_resources","allow_creation_of_v4_resources","allow_v4_v5_upgrade","allow_v5_v4_downgrade"],Hp=class extends Mu{toFormDto(){return Wp.reduce((e,t)=>(void 0!==this._props[t]&&(e[t]=this._props[t]),e),{})}verifyHealth(e,t){let a=null;if(void 0===e)return a;if(void 0===t)return a;if(!(e instanceof Ep))throw new TypeError("The parameter 'resourceTypes' is not a valid 'ResourceTypesCollection' type.");if(!(t instanceof Bp))throw new TypeError("The parameter 'metadataKeysCollection' is not a valid 'MetadataKeysCollection' type.");const n=e.hasSomeOfVersion(Pu),s=e.hasSomeOfVersion(Du);return this.allowCreationOfV4Resources&&!n&&(a=a||new X,a.addError("allow_creation_of_v4_resources","resource_types_deleted","Resource types v4 are deleted.")),this.isDefaultResourceTypeV4&&!n&&(a=a||new X,a.addError("default_resource_types","resource_types_v4_deleted","Resource types v4 are deleted.")),this.allowCreationOfV5Resources&&!s&&(a=a||new X,a.addError("allow_creation_of_v5_resources","resource_types_deleted","Resource types v5 are deleted.")),this.isDefaultResourceTypeV5&&!s&&(a=a||new X,a.addError("default_resource_types","resource_types_v5_deleted","Resource types v5 are deleted.")),this.allowV5V4Downgrade&&!n&&(a=a||new X,a.addError("allow_v5_v4_downgrade","resource_types_deleted","Resource types v4 are deleted.")),this.allowV5V4Downgrade&&!this.allowCreationOfV4Resources&&(a=a||new X,a.addError("allow_v5_v4_downgrade","allow_creation","Resource types v4 creation is not allowed.")),this.allowV4V5Upgrade&&!s&&(a=a||new X,a.addError("allow_v4_v5_upgrade","resource_types_deleted","Resource types v5 are deleted.")),this.allowV4V5Upgrade&&!this.allowCreationOfV5Resources&&(a=a||new X,a.addError("allow_v4_v5_upgrade","allow_creation","Resource types v5 creation is not allowed.")),0===t.items.filter(e=>!e.expired).length&&this.allowCreationOfV5Resources&&(a=a||new X,a.addError("allow_creation_of_v5_resources","active_metadata_key","No active metadata key defined.")),a}},$p=class extends Bc{get entityClass(){return Kp}constructor(e=[],t={}){super(e,t)}static getSchema(){return{type:"array",items:Kp.getSchema()}}validateBuildRules(e,t){this.assertUniqueMetadataKeyIdUserId(e,{haystackSet:t?.uniqueMetadataKeyIdUserIdSetCache})}assertUniqueMetadataKeyIdUserId(e,t){if(!e.userId||!e.metadataKeyId)return;let a=t?.haystackSet;a||(a=new Set(this.items.map(e=>`${e.metadataKeyId}:${e.userId}`)));const n=`${e.metadataKeyId}:${e.userId}`;if(a.has(n)){const e=new X,t=`The collection already includes an element that has a couple metadata_key_id:user_id (${n}) with an identical value.`;throw e.addError("metadata_key_id:user_id","unique",t),e}}pushMany(e,t={},a={}){const n=new Set(this.items.map(e=>`${e.metadataKeyId}:${e.userId}`));a={onItemPushed:e=>{n.add(`${e.metadataKeyId}:${e.userId}`)},validateBuildRules:{...a?.validateBuildRules,uniqueMetadataKeyIdUserIdSetCache:n},...a},super.pushMany(e,t,a)}hasDecryptedPrivateKeys(){return this._items.some(e=>e.isDecrypted)}hasEncryptedPrivateKeys(){return this._items.some(e=>!e.isDecrypted)}};class Yp extends he{static getSchema(){return{type:"object",required:["allow_usage_of_personal_keys","zero_knowledge_key_share"],properties:{allow_usage_of_personal_keys:{type:"boolean"},zero_knowledge_key_share:{type:"boolean"},metadata_private_keys:$p.getSchema()}}}static get associations(){return{metadata_private_keys:$p}}validateBuildRules(){if(this._props.zero_knowledge_key_share&&this.metadataPrivateKeys?.length>0){const e=new X,t="If the property zero_knowledge_key_share is true, metadata_private_keys cannot be set";throw e.addError("metadata_private_keys","not_defined_for_zero_knowledge",t),e}}static createFromDefault(e={}){return new Yp({allow_usage_of_personal_keys:!0,zero_knowledge_key_share:!1,...e})}toDto(e){const t=Object.assign({},this._props);return e?(this._metadataPrivateKeys&&e.metadata_private_keys&&(t.metadata_private_keys=this._metadataPrivateKeys.toDto()),t):t}get allowUsageOfPersonalKeys(){return this._props.allow_usage_of_personal_keys}get zeroKnowledgeKeyShare(){return this._props.zero_knowledge_key_share}get metadataPrivateKeys(){return this._metadataPrivateKeys||null}set metadataPrivateKeys(e){if(!(e instanceof $p))throw new TypeError("The metadataPrivateKeysCollection is not of MetadataPrivateKeysCollection type");this._metadataPrivateKeys=e}static get ALL_CONTAIN_OPTIONS(){return{metadata_private_keys:!0}}}const Zp=Yp,Jp=class{constructor(e){this.port=e}async findKeysSettings(){const e=await this.port.request("passbolt.metadata.find-metadata-keys-settings");return new Zp(e)}async findTypesSettings(){const e=await this.port.request("passbolt.metadata.find-metadata-types-settings");return new Mu(e)}async saveTypesSettings(e){if(!(e instanceof Mu))throw new TypeError("The 'settings' property should be of type 'MetadataTypesSettingsEntity'.");const t=await this.port.request("passbolt.metadata.save-metadata-types-settings",e.toDto());return new Mu(t)}async saveKeysSettings(e){if(!(e instanceof Zp))throw new TypeError("The 'settings' property should be of type 'MetadataKeysSettingsEntity'.");const t=await this.port.request("passbolt.metadata.save-metadata-keys-settings",e.toDto());return new Zp(t)}};class Xp extends n.Component{render(){return n.createElement("div",{className:"actions-wrapper"},n.createElement("button",{type:"button",className:"button primary form",disabled:this.props.isProcessing,onClick:this.props.onSaveRequested},n.createElement("span",null,n.createElement(f.x6,null,"Save"))))}}Xp.propTypes={isProcessing:i().bool,onSaveRequested:i().func,t:i().func};const Qp=(0,f.CI)("common")(Xp);function eh(){return eh=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},resourceTypes:null,updateLocalStorage:()=>{}});class ah extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.runningLocalStorageUpdatePromise=null,this.initEventHandlers()}get defaultState(){return{get:this.get.bind(this),resourceTypes:null,updateLocalStorage:this.updateLocalStorage.bind(this)}}initEventHandlers(){this.handleStorageChange=this.handleStorageChange.bind(this)}componentDidMount(){this.props.context.storage.onChanged.addListener(this.handleStorageChange)}componentWillUnmount(){this.props.context.storage.onChanged.removeListener(this.handleStorageChange)}handleStorageChange(e){e.resourceTypes&&this.set(e.resourceTypes.newValue)}set(e){const t=new Ep(e);this.setState({resourceTypes:t})}get(){return null===this.state.resourceTypes?(this.loadLocalStorage(),null):this.state.resourceTypes}async loadLocalStorage(){const e=await this.props.context.storage.local.get(["resourceTypes"]);e.resourceTypes?this.set(e.resourceTypes):this.updateLocalStorage()}async updateLocalStorage(){null===this.runningLocalStorageUpdatePromise?(this.runningLocalStorageUpdatePromise=this.props.context.port.request("passbolt.resource-type.get-or-find-all"),await this.runningLocalStorageUpdatePromise,this.runningLocalStorageUpdatePromise=null):await this.runningLocalStorageUpdatePromise}render(){return n.createElement(th.Provider,{value:this.state},this.props.children)}}function nh(e){return class extends n.Component{render(){return n.createElement(th.Consumer,null,t=>n.createElement(e,eh({resourceTypesLocalStorageContext:t,resourceTypes:t.get()},this.props)))}}}ah.propTypes={context:i().any,children:i().any},N(ah);class sh extends se{constructor(e,t={}){const a=sh.sanitizeDto(e);super(ae.validate(sh.ENTITY_NAME,a,sh.getSchema()),t)}static getSchema(){return{type:"object",required:["armored_key"],properties:{armored_key:{type:"string",minLength:1},key_id:{type:"string",minLength:8,maxLength:16},user_ids:{type:"array"},fingerprint:{type:"string",minLength:40,maxLength:40},expires:{anyOf:[{type:"string",format:"date-time"},{type:"string",pattern:"^Infinity$"},{}],nullable:!0},created:{type:"string",format:"date-time"},algorithm:{type:"string"},length:{type:"integer",minimum:1},curve:{type:"string",nullable:!0},private:{type:"boolean"},revoked:{type:"boolean"}}}}static sanitizeDto(e){const t=JSON.parse(JSON.stringify(e));if(e.key&&(t.armored_key=e.key,delete t.key),e.keyId&&(t.key_id=e.keyId,delete t.keyId),e.userIds&&(t.user_ids=e.userIds,delete t.userIds),e.created)try{const e=new Date(t.created);t.created=e.toISOString()}catch{delete t.created}if("Never"===e.expires)t.expires="Infinity";else if(e.expires&&"Infinity"!==e.expires)try{const e=new Date(t.expires);t.expires=e.toISOString()}catch{delete t.expires,console.error(`ExternalGpgKeyEntity::sanitizeDto Unable to sanitize the key for the user ${e.user_id}`)}return t}get armoredKey(){return this._props.armored_key}get keyId(){return this._props.key_id}get userIds(){return this._props.user_ids}get fingerprint(){return this._props.fingerprint}get expires(){return this._props.expires}get isValid(){return null!==this.expires}get created(){return this._props.created}get algorithm(){return this._props.algorithm}get length(){return this._props.length}get curve(){return this._props.curve}get revoked(){return this._props.revoked}get private(){return this._props.private}get isExpired(){const e=this.expires;if(null===e)return null;if("Infinity"===e)return!1;const t=Date.now();return new Date(e)this.formSettings?.validate());verifyDataHealth=(0,po.A)((e,t,a)=>this.formSettings?.verifyHealth(t,a));hasSettingsChanges=(0,po.A)((e,t,a)=>this.originalSettings?.hasDiffProps(this.formSettings));handleInputChange(e){if(this.hasAllInputDisabled())return;const{type:t,checked:a,value:n,name:s}=e.target,i="checkbox"===t?a:n;this.setFormPropertyValue(s,i)}setFormPropertyValue(e,t){this.formSettings.set(e,t,{validate:!1}),this.setState({settings:this.formSettings.toFormDto()})}hasAllInputDisabled(){return this.state.isProcessing}handleFormSubmit(e){e.preventDefault(),this.save()}async save(){if(this.state.isProcessing)return;const e=this.validateForm(this.state.settings);if(e?.hasErrors()){const e=!0;return void this.setState({hasAlreadyBeenValidated:e})}this.setState({isProcessing:!0});try{this.originalSettings=await this.metadataSettingsServiceWorkerService.saveTypesSettings(this.formSettings),this.formSettings=new Hp(this.originalSettings.toDto()),await this.props.actionFeedbackContext.displaySuccess(this.props.t("The encrypted metadata settings were updated."))}catch(e){this.props.dialogContext.open($t,{error:e})}this.setState({hasAlreadyBeenValidated:!0,isProcessing:!1,settings:this.formSettings.toDto()})}render(){const e=this.state.hasAlreadyBeenValidated?this.validateForm(this.state.settings):null,t=this.verifyDataHealth(this.state.settings,this.props.resourceTypes,this.metadataKeys),a=this.hasSettingsChanges(this.originalSettings,this.formSettings,this.state.settings),s=this.props.context.siteSettings.isFeatureBeta("metadata"),i=s||a;return n.createElement("div",{className:"row"},n.createElement("div",{id:"content-types-encrypted-metadata-settings",className:"main-column"},n.createElement("div",{className:"main-content"},n.createElement("form",{onSubmit:this.handleFormSubmit,"data-testid":"submit-form"},n.createElement("h3",{className:"title"},n.createElement("label",null,n.createElement(f.x6,null,"Encrypted metadata"))),n.createElement("p",{className:"description"},n.createElement(f.x6,null,"Encrypted metadata for resources is available.")," ",n.createElement(f.x6,null,"Define the strategy to manage and migrate the legacy items.")),n.createElement("h4",null,n.createElement(f.x6,null,"Supported metadata types")),n.createElement("p",{className:"description"},n.createElement(f.x6,null,"Define which metadata types are enabled for this instance.")),n.createElement("div",{className:`input toggle-switch form-element\n ${e?.hasError("allow_creation_of_v5_resources")?"error":""}\n ${t?.hasError("allow_creation_of_v5_resources")?"warning":""}`},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"allow_creation_of_v5_resources",id:"allowCreationOfV5ResourcesInput",onChange:this.handleInputChange,checked:this.state.settings.allow_creation_of_v5_resources,disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"allowCreationOfV5ResourcesInput"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Enable encrypted metadata (recommended)")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"Enable encrypted metadata for resources.")),e?.hasError("allow_creation_of_v5_resources","is_default")&&n.createElement("div",{className:"name error-message"},n.createElement(f.x6,null,"Encrypted metadata must be enabled to set it as the default type.")),!e?.hasError("allow_creation_of_v5_resources")&&n.createElement(n.Fragment,null,t?.hasError("allow_creation_of_v5_resources","resource_types_deleted")&&n.createElement("div",{className:"name warning-message"},n.createElement(f.x6,null,"All encrypted metadata resource types were previously disabled. Re-enable them if you want users to create resources of this type.")),t?.hasError("allow_creation_of_v5_resources","active_metadata_key")&&n.createElement("div",{className:"name warning-message"},n.createElement(f.x6,null,"A metadata key should be enabled to allow users to create resources of this type."))))),n.createElement("div",{className:`input toggle-switch form-element\n ${e?.hasError("allow_creation_of_v4_resources")?"error":""}\n ${t?.hasError("allow_creation_of_v4_resources")?"warning":""}`},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"allow_creation_of_v4_resources",id:"allowCreationOfV4ResourcesInput",onChange:this.handleInputChange,checked:this.state.settings.allow_creation_of_v4_resources,disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"allowCreationOfV4ResourcesInput"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Enable legacy cleartext metadata")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"Enable legacy cleartext metadata for resources.")),e?.hasError("allow_creation_of_v4_resources","is_default")&&n.createElement("div",{className:"name error-message"},n.createElement(f.x6,null,"Legacy cleartext metadata must be enabled to set it as the default type.")),!e?.hasError("allow_creation_of_v4_resources")&&t?.hasError("allow_creation_of_v4_resources","resource_types_deleted")&&n.createElement("div",{className:"name warning-message"},n.createElement(f.x6,null,"All legacy cleartext resource types were previously disabled. Re-enable them if you want users to create resources of this type.")))),n.createElement("h4",null,n.createElement(f.x6,null,"Default metadata type")),n.createElement("p",{className:"description"},n.createElement(f.x6,null,"Define which metadata type is used by default.")),n.createElement("div",{className:"radiolist-alt"},n.createElement("div",{className:`input radio\n ${"v5"===this.state.settings.default_resource_types?"checked":""}\n ${e?.hasError("default_resource_types","allow_create_v5")?"error":""}\n ${!e?.hasError("default_resource_types","allow_create_v5")&&t?.hasError("default_resource_types","resource_types_v5_deleted")?"warning":""}`},n.createElement("input",{type:"radio",value:"v5",onChange:this.handleInputChange,name:"default_resource_types",checked:"v5"===this.state.settings.default_resource_types,id:"defaultResourceTypesV5Input",disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"defaultResourceTypesV5Input"},n.createElement("span",{className:"name bold"},n.createElement(f.x6,null,"Encrypted metadata (recommended)")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"Users can create resources with encrypted metadata by default."),n.createElement("br",null)),e?.hasError("default_resource_types","allow_create_v5")&&n.createElement("div",{className:"name error-message"},n.createElement(f.x6,null,"Encrypted metadata must be enabled to set it as the default type.")),!e?.hasError("default_resource_types","allow_create_v5")&&t?.hasError("default_resource_types","resource_types_v5_deleted")&&n.createElement("div",{className:"name warning-message"},n.createElement(f.x6,null,"All encrypted metadata resource types were previously disabled. Re-enable them if you want users to create resources of this type.")))),n.createElement("div",{className:`input radio ${"v4"===this.state.settings.default_resource_types?"checked":""}\n ${e?.hasError("default_resource_types","allow_create_v4")?"error":""}\n ${!e?.hasError("default_resource_types","allow_create_v4")&&t?.hasError("default_resource_types","resource_types_v4_deleted")?"warning":""}`},n.createElement("input",{type:"radio",value:"v4",onChange:this.handleInputChange,name:"default_resource_types",checked:"v4"===this.state.settings.default_resource_types,id:"defaultResourceTypesV4Input",disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"defaultResourceTypesV4Input"},n.createElement("span",{className:"name bold"},n.createElement(f.x6,null,"Legacy cleartext metadata")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"Users can create legacy resources with cleartext metadata by default.")),e?.hasError("default_resource_types","allow_create_v4")&&n.createElement("div",{className:"name error-message"},n.createElement(f.x6,null,"Legacy cleartext metadata must be enabled to set it as the default type.")),!e?.hasError("default_resource_types","allow_create_v4")&&t?.hasError("default_resource_types","resource_types_v4_deleted")&&n.createElement("div",{className:"name warning-message"},n.createElement(f.x6,null,"All legacy cleartext resource types were previously disabled. Re-enable them if you want users to create resources of this type."))))),n.createElement("h4",{className:"no-border"},n.createElement(f.x6,null,"Self served migration")),n.createElement("div",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"allow_v4_v5_upgrade",id:"allowV4V5UpgradeInput",onChange:this.handleInputChange,checked:this.state.settings.allow_v4_v5_upgrade,disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"allowV4V5UpgradeInput",className:"text"},n.createElement(f.x6,null,"Allow users to upgrade their content from cleartext to encrypted metadata type."),t?.hasError("allow_v4_v5_upgrade","resource_types_deleted")&&n.createElement("div",{className:"name warning-message"},n.createElement(f.x6,null,"All encrypted metadata resource types were previously disabled. Re-enable them if you want users to upgrade their resources.")),t?.hasError("allow_v4_v5_upgrade","allow_creation")&&n.createElement("div",{className:"name warning-message"},n.createElement(f.x6,null,"Encrypted metadata should be enabled to allow users to upgrade their resources.")))))),i&&n.createElement("div",{className:"warning message"},s&&n.createElement("div",null,n.createElement("b",null,n.createElement(f.x6,null,"Warning:"))," ",n.createElement(f.x6,null,"Your current API version includes beta support for encrypted metadata and new resource types.")," ",n.createElement(f.x6,null,"To ensure stability and avoid potential issues, upgrade to the latest version before enabling these features.")),a&&n.createElement("div",{className:"form-banner"},n.createElement("p",null,n.createElement("b",null,n.createElement(f.x6,null,"Warning:"))," ",n.createElement(f.x6,null,"Don't forget to save your settings to apply your modification."))))),n.createElement(Qp,{onSaveRequested:this.save,isProcessing:this.state.isProcessing}),Xa(n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"Need help?")),n.createElement("p",null,n.createElement(f.x6,null,"For more information about the content type support and migration, checkout the dedicated page on the official website.")),n.createElement("a",{className:"button",target:"_blank",rel:"noopener noreferrer",href:"https://passbolt.com/docs/admin/metadata-encryption/encrypted-metadata/"},n.createElement(ps,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}ch.propTypes={context:i().object,actionFeedbackContext:i().object,dialogContext:i().object,createPortal:i().func,metadataSettingsServiceWorkerService:i().object,metadataKeysServiceWorkerService:i().object,resourceTypes:i().instanceOf(Ep),t:i().func};const mh=N(m(h(nh((0,f.CI)("common")(ch)))));var dh;function uh(){return uh=Object.assign?Object.assign.bind():function(e){for(var t=1;te.id).sort().sort((e,t)=>{if(e===t)throw new ce(0,fh.RULE_UNIQUE_ID,`Gpgkey fingerprint ${e} already exists.`)}),this._props.forEach(e=>{this._items.push(new ih(e,{clone:!1}))}),this._props=null}static getSchema(){return{type:"array",items:ih.getSchema()}}static get ENTITY_NAME(){return"externalGpgKey"}static get RULE_UNIQUE_ID(){return"fingerprint"}}const Eh=fh,vh=class{constructor(e){this.port=e}async keyInfo(e){const t=await this.port.request("passbolt.keyring.get-key-info",e);return new ih(t)}async keysInfo(e=[]){const t=[];for(const a of e){const e=await this.keyInfo(a);t.push(e)}return new Eh(t)}},wh=class extends Zp{constructor(e,t={}){super(e,t),this._props.generated_metadata_key&&(this._generated_metadata_key=new oh(this._props.generated_metadata_key,{...t,clone:!1}),delete this._props.generated_metadata_key)}static getSchema(){return{type:"object",required:["allow_usage_of_personal_keys","zero_knowledge_key_share"],properties:{...Zp.getSchema().properties,generated_metadata_key:oh.getSchema()}}}toDto(){return{...this._props,generated_metadata_key:this.generatedMetadataKey?.toDto({public_key:!0,private_key:!0})||null}}get generatedMetadataKey(){return this._generated_metadata_key||null}set generatedMetadataKey(e){if(null!==e&&!(e instanceof oh))throw new TypeError("The parameter `generatedMetadataKey` should be of type ExternalGpgKeyPairEntity.");this._generated_metadata_key=e}};class kh extends n.Component{render(){return n.createElement("div",{className:"actions-wrapper"},n.createElement("button",{type:"button",className:"button primary form "+(this.props.isProcessing?"processing":""),disabled:this.props.isDisabled,onClick:this.props.onSaveRequested},n.createElement("span",null,n.createElement(f.x6,null,"Save")),this.props.isProcessing&&n.createElement(En,null)))}}kh.propTypes={isProcessing:i().bool,isDisabled:i().bool,onSaveRequested:i().func,t:i().func};const _h=(0,f.CI)("common")(kh);class xh extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.bindCallbacks()}get defaultState(){return{processing:!1}}bindCallbacks(){this.handleConfirm=this.handleConfirm.bind(this),this.handleCancel=this.handleCancel.bind(this)}async handleConfirm(e){e.preventDefault(),this.props.onConfirm(),this.props.onClose()}async handleCancel(){this.props.onClose()}hasAllInputDisabled(){return this.state.processing}render(){const e=this.hasAllInputDisabled();return n.createElement(qt,{className:"confirm-metadata-key-rotation-dialog",title:this.props.t("Please confirm"),onClose:this.handleCancel,disabled:e},n.createElement("div",{className:"form-content"},n.createElement("label",null,n.createElement(f.x6,null,"New shared Metadata key")),n.createElement("div",{className:"metadata-key-info"},n.createElement("table",{className:"table-info"},n.createElement("tbody",null,n.createElement("tr",{className:"fingerprint"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Fingerprint")),n.createElement("td",{className:"value"},n.createElement(bh,{fingerprint:this.props.metadataKeyInfo.fingerprint}))),n.createElement("tr",{className:"algorithm"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Algorithm")),n.createElement("td",{className:"value"},this.props.metadataKeyInfo.algorithm)),n.createElement("tr",{className:"created"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Created")),this.props.metadataKeyInfo.created&&n.createElement("td",{className:"value",title:this.props.metadataKeyInfo.created},Hs(this.props.metadataKeyInfo.created,this.props.t,this.props.context.locale)),!this.props.metadataKeyInfo.created&&n.createElement("td",{className:"empty-value"},n.createElement(f.x6,null,"Pending")))))),n.createElement("p",null,n.createElement(f.x6,null,"This operation may take a few minutes."))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement("button",{type:"button",className:"link cancel",onClick:this.handleCancel,disabled:e},n.createElement(f.x6,null,"Cancel")),n.createElement("button",{type:"button",className:"button primary form",onClick:this.handleConfirm,disabled:e},n.createElement(f.x6,null,"Rotate key"))))}}xh.propTypes={context:i().object,metadataKeyInfo:i().object,onConfirm:i().func,onClose:i().func,t:i().func};const Sh=N((0,f.CI)("common")(xh));class Ch extends n.Component{originalSettings=null;formSettings=null;constructor(e){super(e),this.metadataSettingsServiceWorkerService=e.metadataSettingsServiceWorkerService??new Jp(e.context.port),this.metadataKeysServiceWorkerService=e.metadataKeysServiceWorkerService??new lh(e.context.port),this.gpgServiceWorkerService=e.gpgServiceWorkerService??new vh(e.context.port),this.state=this.defaultState,this.bindCallbacks()}get defaultState(){return{isProcessing:!0,hasAlreadyBeenValidated:!1,settings:{allow_usage_of_personal_keys:!0,zero_knowledge_key_share:!1,generated_metadata_key:null},activeMetadataKeys:null,expiredMetadataKeys:null}}bindCallbacks(){this.handleFormSubmit=this.handleFormSubmit.bind(this),this.handleInputChange=this.handleInputChange.bind(this),this.generateMetadataKey=this.generateMetadataKey.bind(this),this.save=this.save.bind(this)}async componentDidMount(){await this.loadKeysSettings(),await this.loadKeys(),this.setState({isProcessing:!1})}async loadKeysSettings(){try{const e=await this.metadataSettingsServiceWorkerService.findKeysSettings();this.originalSettings=new wh(e.toDto(),{validate:!1}),this.formSettings=new wh(e.toDto(),{validate:!1}),this.setState({settings:this.formSettings.toDto()})}catch(e){await this.handleUnexpectedError(e)}}handleUnexpectedError(e){if(console.error(e),"UserAbortsOperationError"!==e.name)return this.props.dialogContext.open($t,{error:e})}async loadKeys(){try{const e=await this.metadataKeysServiceWorkerService.findAll();e.items.sort((e,t)=>Ds.c9.fromISO(t.created)!e.expired);const a=new Bp(e);a.filterByCallback(e=>e.expired);const n=e.items.map(e=>e.armoredKey),s=await this.gpgServiceWorkerService.keysInfo(n);this.setState({activeMetadataKeys:t,expiredMetadataKeys:a,metadataKeysInfo:s})}catch(e){await this.handleUnexpectedError(e)}}hasSettingsChanges=(0,po.A)((e,t,a)=>e?.hasDiffProps(t)||e?.generatedMetadataKey!==t?.generatedMetadataKey);handleInputChange(e){if(this.hasAllInputDisabled())return;const{type:t,checked:a,value:n,name:s}=e.target;let i=n;"checkbox"===t&&(i=a),"allow_usage_of_personal_keys"!==s&&"zero_knowledge_key_share"!==s||(i="true"===n),this.setFormPropertyValue(s,i)}setFormPropertyValue(e,t){this.formSettings.set(e,t,{validate:!1}),this.setState({settings:this.formSettings.toDto()})}hasAllInputDisabled(){return this.state.isProcessing||this.hasMissingMetadataKeys}async generateMetadataKey(){const e=this.state.metadataKeysInfo,t=this.state.activeMetadataKeys;this.setState({isProcessing:!0});try{const a=await this.metadataKeysServiceWorkerService.generateKeyPair(),n=await this.gpgServiceWorkerService.keyInfo(a.publicKey.armoredKey);e.push(n);const s=new Gp({armored_key:a.publicKey.armoredKey,fingerprint:n.fingerprint});t.push(s),this.formSettings.generatedMetadataKey=a,this.setState({activeMetadataKeys:t,metadataKeysInfo:e,settings:this.formSettings.toDto()})}catch(e){await this.handleUnexpectedError(e)}this.setState({isProcessing:!1})}async rotateMetadataKey(e){this.setState({isProcessing:!0});try{const t=await this.metadataKeysServiceWorkerService.generateKeyPair(),a=await this.gpgServiceWorkerService.keyInfo(t.publicKey.armoredKey);this.props.dialogContext.open(Sh,{metadataKeyInfo:a,onConfirm:()=>this.handleRotateKeyConfirmation(t,e)})}catch(e){await this.handleUnexpectedError(e)}finally{this.setState({isProcessing:!1})}}async handleRotateKeyConfirmation(e,t){try{await this.metadataKeysServiceWorkerService.rotate(e,t.id),await this.loadKeys(),await this.props.actionFeedbackContext.displaySuccess(this.props.t("The metadata key has been rotated."))}catch(e){await this.handleUnexpectedError(e),await this.loadKeys()}}async resumeRotationMetadataKey(e){this.setState({isProcessing:!0});try{await this.metadataKeysServiceWorkerService.resumeRotation(e),await this.loadKeys(),await this.props.actionFeedbackContext.displaySuccess(this.props.t("The metadata key has been rotated."))}catch(e){await this.handleUnexpectedError(e),await this.loadKeys()}finally{this.setState({isProcessing:!1})}}handleFormSubmit(e){e.preventDefault(),this.save()}async save(){if(this.state.isProcessing)return;this.setState({isProcessing:!0});const e=this.validateForm(this.state.settings);if(e?.hasErrors())this.setState({isProcessing:!1,hasAlreadyBeenValidated:!0});else{try{await this.saveMetadataKeysSettings(),await this.createMetadataKey(),await this.props.actionFeedbackContext.displaySuccess(this.props.t("The metadata key settings were updated."))}catch(e){await this.handleUnexpectedError(e)}this.setState({isProcessing:!1,settings:this.formSettings.toDto()})}}validateForm=(0,po.A)(e=>{if(!this.formSettings)return null;let t=this.formSettings.validate();return this.state.activeMetadataKeys.length||(t=t||new X,t.addError("generated_metadata_key","required",this.props.t("A shared metadata key is required."))),t});async saveMetadataKeysSettings(){const e=new Zp(this.formSettings.toDto()),t=await this.metadataSettingsServiceWorkerService.saveKeysSettings(e);this.originalSettings=new wh({...this.originalSettings.toDto(),...t.toDto()}),this.formSettings=new wh({...this.formSettings.toDto(),...t.toDto()})}async createMetadataKey(){if(!this.formSettings.generatedMetadataKey)return;const e=await this.metadataKeysServiceWorkerService.createKey(this.formSettings.generatedMetadataKey);this.state.activeMetadataKeys.pushOrReplace(e,{},{replacePropertyName:"fingerprint"}),this.formSettings.generatedMetadataKey=null}get hasMissingMetadataKeys(){return this.props.context.loggedInUser.missing_metadata_key_ids?.length>0}render(){const e=this.state.hasAlreadyBeenValidated?this.validateForm(this.state.settings):null,t=this.hasSettingsChanges(this.originalSettings,this.formSettings,this.state.settings),a=this.props.context.siteSettings.isFeatureBeta("metadata"),s=a||t||e?.hasError("generated_metadata_key","required")||this.hasMissingMetadataKeys;return n.createElement("div",{className:"row"},n.createElement("div",{id:"content-types-metadata-key-settings",className:"main-column"},n.createElement("div",{className:"main-content"},n.createElement("form",{onSubmit:this.handleFormSubmit,"data-testid":"submit-form"},n.createElement("h3",{className:"title"},n.createElement("label",null,n.createElement(f.x6,null,"Metadata key"))),n.createElement("p",{className:"description"},n.createElement(f.x6,null,"This section controls the layer of encryption that is used to protect metadata such as the name of a resource, URIs, etc.")),n.createElement("h4",{className:"no-border"},n.createElement(f.x6,null,"Metadata key policy")),n.createElement("p",{className:"description"},n.createElement(f.x6,null,"It is possible for users to use their personal keys to encrypt resources metadata for more security. However you can elect to enforce the use of the shared metadata keys for all resources metadata for auditing purposes. Secrets such as passwords will always be encrypted using the user personal keys.")),n.createElement("div",{className:"radiolist-alt"},n.createElement("div",{className:`input radio ${!0===this.state.settings.allow_usage_of_personal_keys?"checked":""} ${this.hasAllInputDisabled()&&"disabled"}`},n.createElement("input",{type:"radio",value:"true",onChange:this.handleInputChange,name:"allow_usage_of_personal_keys",checked:!0===this.state.settings.allow_usage_of_personal_keys,id:"allowUsageOfPersonalKeysInput",disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"allowUsageOfPersonalKeysInput"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Allow the use of personal keys. (Recommended)")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"Users can use shared and personal keys. By default personal resources that are not shared will be encrypted with the users personal keys."),n.createElement("br",null)))),n.createElement("div",{className:`input radio ${!1===this.state.settings.allow_usage_of_personal_keys?"checked":""} ${this.hasAllInputDisabled()&&"disabled"}`},n.createElement("input",{type:"radio",value:"false",onChange:this.handleInputChange,name:"allow_usage_of_personal_keys",checked:!1===this.state.settings.allow_usage_of_personal_keys,id:"disallowUsageOfPersonalKeysInput",disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"disallowUsageOfPersonalKeysInput"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Enforce the use of shared metadata keys.")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"By default, metadata wil be encrypted with the shared keys. It is not possible to use personal keys to encrypt metadata."),n.createElement("br",null))))),n.createElement("h4",null,n.createElement(f.x6,null,"Zero knowledge")),n.createElement("p",{className:"description"},n.createElement(f.x6,null,"This section defines how the shared metadata key is shared with users.")),n.createElement("div",{className:"radiolist-alt"},n.createElement("div",{className:`input radio ${!1===this.state.settings.zero_knowledge_key_share?"checked":""} ${this.hasAllInputDisabled()&&"disabled"}`},n.createElement("input",{type:"radio",value:"false",onChange:this.handleInputChange,name:"zero_knowledge_key_share",checked:!1===this.state.settings.zero_knowledge_key_share,id:"disableZeroKnowledgeKeyShareInput",disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"disableZeroKnowledgeKeyShareInput"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"User-friendly mode (Better on-boarding)")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"The shared metadata key is accessible to the server and can be shared by the server when a user completes the setup. In practice, an attacker with full server access can see the shared metadata."),n.createElement("br",null)))),n.createElement("div",{className:`input radio ${!0===this.state.settings.zero_knowledge_key_share?"checked":""} ${this.hasAllInputDisabled()&&"disabled"}`},n.createElement("input",{type:"radio",value:"true",onChange:this.handleInputChange,name:"zero_knowledge_key_share",checked:!0===this.state.settings.zero_knowledge_key_share,id:"enableZeroKnowledgeKeyShareInput",disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"enableZeroKnowledgeKeyShareInput"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Zero-knowledge mode (More secure)")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"The shared metadata key is not available to the server and must be shared with users by the admins. New users are not allowed to create or access shared content until they are provided the metadata key. It is recommended to rotate the key if you switch to that mode."),n.createElement("br",null))))),n.createElement("h4",null,n.createElement(f.x6,null,"Shared metadata keys")),n.createElement("div",{className:`metadata-key-info ${e?.hasError("generated_metadata_key","required")&&"error"}`},this.state.activeMetadataKeys?.length>0&&n.createElement("div",{id:"metadata-active-keys"},this.state.activeMetadataKeys?.items.map((e,t)=>{const a=this.state.metadataKeysInfo?.getFirst("fingerprint",e.fingerprint);return n.createElement("table",{key:e.fingerprint,className:"table-info"},n.createElement("tbody",null,n.createElement("tr",{className:"fingerprint"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Fingerprint")),n.createElement("td",{className:"value"},n.createElement(bh,{fingerprint:e.fingerprint})),n.createElement("td",{className:"table-button"},1===this.state.activeMetadataKeys.length&&0===this.state.expiredMetadataKeys?.length&&n.createElement("button",{className:"button primary medium form",type:"button",disabled:this.hasAllInputDisabled(),onClick:()=>this.rotateMetadataKey(e)},n.createElement(f.x6,null,"Rotate key")),t>=1&&n.createElement("button",{className:"button primary medium form",type:"button",disabled:this.hasAllInputDisabled(),onClick:()=>this.resumeRotationMetadataKey(e)},n.createElement(f.x6,null,"Resume rotation")))),n.createElement("tr",{className:"algorithm"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Algorithm")),n.createElement("td",{className:"value"},a?.algorithm," ",a?.curve)),n.createElement("tr",{className:"key-length"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Key length")),n.createElement("td",{className:"value"},a?.length)),n.createElement("tr",{className:"created"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Created")),e.created&&n.createElement("td",{className:"value"},n.createElement("span",{title:e.created},Hs(e.created,this.props.t,this.props.context.locale))),!e.created&&n.createElement("td",{className:"empty-value"},n.createElement(f.x6,null,"Pending"))),n.createElement("tr",{className:"status"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Status")),n.createElement("td",{className:"value"},n.createElement("span",{title:"Active"},n.createElement(f.x6,null,"Active"))))))})),!this.state.activeMetadataKeys?.length&&n.createElement("div",{id:"no-metadata-active-keys"},n.createElement("table",{className:"table-info"},n.createElement("tbody",null,n.createElement("tr",null,n.createElement("td",{className:"empty-value"},n.createElement(f.x6,null,"You need to generate a new shared key to enable encrypted metadata.")),n.createElement("td",{className:"table-button"},n.createElement("button",{className:"button primary medium form",type:"button",disabled:this.hasAllInputDisabled(),onClick:this.generateMetadataKey,"data-testid":"generate-key-buton"},n.createElement(f.x6,null,"Generate key")))),e?.hasError("generated_metadata_key","required")&&n.createElement("tr",{className:"error-message"},n.createElement(f.x6,null,"A shared metadata key is required."))))),this.state.expiredMetadataKeys?.length>0&&n.createElement(n.Fragment,null,n.createElement("h4",null,n.createElement(f.x6,null,"Previous keys")),n.createElement("div",{id:"metadata-expired-keys"},this.state.expiredMetadataKeys?.items.map(e=>{const t=this.state.metadataKeysInfo.getFirst("fingerprint",e.fingerprint);return n.createElement("table",{key:e.fingerprint,className:"table-info"},n.createElement("tbody",null,n.createElement("tr",{className:"fingerprint"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Fingerprint")),n.createElement("td",{className:"value"},n.createElement(bh,{fingerprint:e.fingerprint})),n.createElement("td",{className:"table-button"},this.state.activeMetadataKeys.length>0&&null===this.formSettings.generatedMetadataKey&&n.createElement("button",{className:"button primary medium form",type:"button",disabled:this.hasAllInputDisabled(),onClick:()=>this.resumeRotationMetadataKey(e)},n.createElement(f.x6,null,"Resume rotation")))),n.createElement("tr",{className:"algorithm"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Algorithm")),n.createElement("td",{className:"value"},t?.algorithm," ",t?.curve)),n.createElement("tr",{className:"key-length"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Key length")),n.createElement("td",{className:"value"},t?.length)),n.createElement("tr",{className:"created"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Created")),n.createElement("td",{className:"value"},n.createElement("span",{title:e.created},Hs(e.created,this.props.t,this.props.context.locale)))),n.createElement("tr",{className:"status"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Status")),n.createElement("td",{className:"value"},n.createElement("span",{title:e.expired},this.props.t("Expired {{expiredDate}}",{expiredDate:Hs(e.expired,this.props.t,this.props.context.locale)}))))))})))))),s&&n.createElement("div",{className:"warning message"},a&&n.createElement("div",{className:"form-banner"},n.createElement("b",null,n.createElement(f.x6,null,"Warning:"))," ",n.createElement(f.x6,null,"Your current API version includes beta support for encrypted metadata and new resource types.")," ",n.createElement(f.x6,null,"To ensure stability and avoid potential issues, upgrade to the latest version before enabling these features.")),t&&n.createElement("div",{className:"form-banner"},n.createElement("p",null,n.createElement("b",null,n.createElement(f.x6,null,"Warning:"))," ",n.createElement(f.x6,null,"Don't forget to save your settings to apply your modification."))),e?.hasError("generated_metadata_key","required")&&n.createElement("div",{className:"form-banner"},n.createElement("p",null,n.createElement("b",null,n.createElement(f.x6,null,"Warning:"))," ",n.createElement(f.x6,null,"A shared metadata key is required to save the metadata keys settings."))),this.hasMissingMetadataKeys&&n.createElement("div",{className:"form-banner"},n.createElement("p",null,n.createElement("b",null,n.createElement(f.x6,null,"Warning:"))," ",n.createElement(f.x6,null,"You are missing shared metadata keys.")," ",n.createElement(f.x6,null,"Ask another administrator to share them with you to update the metadata keys settings."))))),n.createElement(_h,{onSaveRequested:this.save,isProcessing:this.state.isProcessing,isDisabled:this.hasAllInputDisabled()}),Xa(n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"Need help?")),n.createElement("p",null,n.createElement(f.x6,null,"For more information about the content type support and migration, checkout the dedicated page on the official website.")),n.createElement("a",{className:"button",target:"_blank",rel:"noopener noreferrer",href:"https://passbolt.com/docs/admin/metadata-encryption/manage-metadata-key/"},n.createElement(ps,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}Ch.propTypes={context:i().object,actionFeedbackContext:i().object,dialogContext:i().object,createPortal:i().func,metadataSettingsServiceWorkerService:i().object,metadataKeysServiceWorkerService:i().object,gpgServiceWorkerService:i().object,t:i().func};const Nh=N(h(m((0,f.CI)("common")(Ch))));var Th,Ah;function Ih(){return Ih=Object.assign?Object.assign.bind():function(e){for(var t=1;t!e.expired).length>0)return null;const t=new X;return t.addError("global_form","active_metadata_key","No active metadata key defined."),t}_verifyMigrateResourcesToV5Health(e,t,a){this._props.migrate_resources_to_v5&&!a.allowCreationOfV5Resources&&(e=e||new X).addError("migrate_resources_to_v5","allow_creation_of_v5_resources","Resource types v5 creation is not allowed.");const n=t.hasSomeOfVersion(Du);if(this._props.migrate_resources_to_v5&&!n)return(e=e||new X).addError("migrate_resources_to_v5","resource_types_v5_deleted","Resource types v5 are deleted."),e;const s=t.items.filter(e=>e.version===Pu).every(e=>t.hasOneWithSlug(rp[e.slug]));return this._props.migrate_resources_to_v5&&!s&&(e=e||new X).addError("migrate_resources_to_v5","resource_types_v5_partially_deleted","Some resource types v5 are missing."),e}_verifyMigrateFoldersToV5Health(e,t){return this._props.migrate_folders_to_v5&&!t.allowV4V5Upgrade&&(e=e||new X).addError("migrate_folders_to_v5","allow_v4_v5_upgrade","Folders v5 creation is not allowed."),this._props.migrate_folders_to_v5&&!t.allowCreationOfV5Folders&&(e=e||new X).addError("migrate_folders_to_v5","allow_creation_of_v5_folders","Folders v5 creation is not allowed."),e}_verifyMigrateTagsToV5Health(e,t){return this._props.migrate_tags_to_v5&&!t.allowV4V5Upgrade&&(e=e||new X).addError("migrate_tags_to_v5","allow_v4_v5_upgrade","Tags v5 creation is not allowed."),this._props.migrate_tags_to_v5&&!t.allowCreationOfV5Folders&&(e=e||new X).addError("migrate_tags_to_v5","allow_creation_of_v5_tags","Tags v5 creation is not allowed."),e}_verifyMigrateCommentsToV5Health(e,t){return this._props.migrate_comments_to_v5&&!t.allowV4V5Upgrade&&(e=e||new X).addError("migrate_comments_to_v5","allow_v4_v5_upgrade","Comments v5 creation is not allowed."),this._props.migrate_comments_to_v5&&!t.allowCreationOfV5Folders&&(e=e||new X).addError("migrate_comments_to_v5","allow_creation_of_v5_comments","Comments v5 creation is not allowed."),e}},ag=class{constructor(e){this.port=e}async findCountMetadataMigrateResources(e=!1){const t=await this.port.request("passbolt.metadata.find-metadata-migrate-resources-details",e);return new ia(t)}async migrate(e,t){await this.port.request("passbolt.metadata.migrate-resources-metadata",e,t)}};class ng extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.bindCallbacks()}get defaultState(){return{processing:!1}}bindCallbacks(){this.handleConfirm=this.handleConfirm.bind(this),this.handleCancel=this.handleCancel.bind(this)}async handleConfirm(e){e.preventDefault(),this.props.confirm(),this.props.onClose()}async handleCancel(){this.props.cancel(),this.props.onClose()}hasAllInputDisabled(){return this.state.processing}render(){const e=this.hasAllInputDisabled();return n.createElement(qt,{className:"confirm-migrate-metadata-dialog",title:this.props.t("Please confirm"),onClose:this.handleCancel,disabled:e},n.createElement("div",{className:"form-content"},n.createElement("p",null,n.createElement("strong",null,n.createElement(f.x6,null,"Are you sure you want to migrate the selected items to use encrypted metadata?"))),n.createElement("p",null,n.createElement(f.x6,null,"If you have integrations, you will have to make sure they are updated before triggering the migration.")),n.createElement("p",null,n.createElement(f.x6,null,"The operation may take a few minutes."))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement("button",{type:"button",className:"link cancel",onClick:this.handleCancel,disabled:e},n.createElement(f.x6,null,"Cancel")),n.createElement("button",{type:"button",className:"button primary form",onClick:this.handleConfirm,disabled:e},n.createElement(f.x6,null,"Migrate"))))}}ng.propTypes={cancel:i().func,confirm:i().func,onClose:i().func,t:i().func};const sg=(0,f.CI)("common")(ng);class ig extends n.Component{formSettings=void 0;metadataTypesSettings=void 0;metadataKeys=void 0;migrationCountDetails=void 0;migrationCountDetailsShared=void 0;constructor(e){super(e),this.formSettings=new tg({}),this.metadataSettingsServiceWorkerService=e.metadataSettingsServiceWorkerService??new Jp(e.context.port),this.metadataKeysServiceWorkerService=e.metadataKeysServiceWorkerService??new lh(e.context.port),this.metadataMigrateContentServiceWorkerService=e.metadataMigrateContentServiceWorkerService??new ag(e.context.port),this.state=this.defaultState,this.bindCallbacks()}get defaultState(){return{isReady:!1,isProcessing:!1,hasAlreadyBeenValidated:!1,hasMigrationRunOnce:!1,settings:this.formSettings.toDto()}}bindCallbacks(){this.handleFormSubmit=this.handleFormSubmit.bind(this),this.handleInputChange=this.handleInputChange.bind(this),this.handleMigrateScopeInputChange=this.handleMigrateScopeInputChange.bind(this),this.runMigration=this.runMigration.bind(this),this.askForMigrationConfirmation=this.askForMigrationConfirmation.bind(this)}async componentDidMount(){await this.initData()}async initData(){this.metadataTypesSettings=await this.metadataSettingsServiceWorkerService.findTypesSettings(),this.metadataKeys=await this.metadataKeysServiceWorkerService.findAll(),this.migrationCountDetailsShared=await this.metadataMigrateContentServiceWorkerService.findCountMetadataMigrateResources(!0),this.migrationCountDetails=await this.metadataMigrateContentServiceWorkerService.findCountMetadataMigrateResources(),this.setState({settings:this.formSettings.toDto(),isProcessing:!1,isReady:!0})}validateForm=(0,po.A)(e=>this.formSettings?.validate());verifyDataHealth=(0,po.A)((e,t,a,n)=>this.formSettings?.verifyHealth(t,a,n));handleInputChange(e){if(this.hasAllInputDisabled())return;const{type:t,checked:a,value:n,name:s}=e.target,i="checkbox"===t?a:n;this.setFormPropertyValue(s,i)}handleMigrateScopeInputChange(e){const{value:t,name:a}=e.target;this.setFormPropertyValue(a,"all-content"===t)}setFormPropertyValue(e,t){this.formSettings.set(e,t,{validate:!1}),this.setState({settings:this.formSettings.toDto()})}get hasMissingMetadataKeys(){return this.props.context.loggedInUser.missing_metadata_key_ids?.length>0}hasAllInputDisabled(){return this.state.isProcessing}handleFormSubmit(e){e.preventDefault(),this.askForMigrationConfirmation()}get hasPendingMigration(){return this.hasPendingResourcesMigration||this.hasPendingFoldersMigration||this.hasPendingCommentsMigration||this.hasPendingTagsMigration}get totalResources(){return this.totalSharedResources+this.totalPersonalResources}get totalSharedResources(){return this.migrationCountDetailsShared?.count}get totalPersonalResources(){return this.migrationCountDetailsPersonal?.count}get migrationCountDetailsPersonal(){return{...this.migrationCountDetails,count:this.migrationCountDetails?.count-this.migrationCountDetailsShared?.count}}get hasPendingResourcesMigration(){return this.totalResources>0}get hasPendingFoldersMigration(){return this.totalFolders>0}get hasPendingTagsMigration(){return this.totalTags>0}get hasPendingCommentsMigration(){return this.totalComments>0}get migrationStatus(){return this.hasPendingMigration?this.state.hasMigrationRunOnce?this.props.t("Pending"):this.props.t("Required"):this.props.t("Done")}hasElementsToMigrate(){return this.totalResources>0}hasGlobalError(e){return e?.hasError("global_form")||!1}askForMigrationConfirmation(){this.props.dialogContext.open(sg,{confirm:this.runMigration,cancel:()=>{}})}async runMigration(){if(this.state.isProcessing)return;const e=this.validateForm(this.state.settings),t=this.verifyDataHealth(this.state.settings,this.props.resourceTypes,this.metadataTypesSettings,this.metadataKeys);if(e?.hasErrors()||this.hasGlobalError(t))this.setState({hasAlreadyBeenValidated:!0});else{this.setState({isProcessing:!0});try{const e=this.formSettings.sharedContentOnly?this.migrationCountDetailsShared:this.migrationCountDetails;await this.metadataMigrateContentServiceWorkerService.migrate(this.formSettings.toDto(),e),await this.initData(),this.hasElementsToMigrate()?this.props.actionFeedbackContext.displayWarning(this.props.t("Encrypted metadata were partially migrated.")):this.props.actionFeedbackContext.displaySuccess(this.props.t("The encrypted metadata were migrated."))}catch(e){this.props.dialogContext.open($t,{error:e})}this.setState({hasAlreadyBeenValidated:!0,hasMigrationRunOnce:!0})}}render(){const e=this.verifyDataHealth(this.state.settings,this.props.resourceTypes,this.metadataTypesSettings,this.metadataKeys),t=this.hasGlobalError(e),a=this.props.context.siteSettings.isFeatureBeta("metadata"),s=!t&&(a||!this.hasMissingMetadataKeys&&this.hasPendingMigration);return n.createElement("div",{className:"row"},n.createElement("div",{id:"migrate-metadata-settings",className:"main-column"},n.createElement("div",{className:"main-content"},n.createElement("form",{onSubmit:this.handleFormSubmit,"data-testid":"submit-form"},n.createElement("h3",{className:"title"},n.createElement("label",null,n.createElement(f.x6,null,"Migrate metadata"))),n.createElement("p",{className:"description"},n.createElement(f.x6,null,"Initiate a migration to convert cleartext metadata to encrypted metadata.")),n.createElement("h4",null,n.createElement(f.x6,null,"Summary")),n.createElement("div",{className:"feedback-card"},this.state.isReady&&this.hasPendingMigration&&n.createElement(Qh,{name:"warning"}),this.state.isReady&&!this.hasPendingMigration&&n.createElement(Qh,{name:"success"}),n.createElement("div",{className:"migration-status-information"},n.createElement("ul",null,n.createElement("li",{className:"migration-status"},n.createElement("span",{className:"label"},n.createElement(f.x6,null,"Migration status")),n.createElement("span",{className:"value"},this.migrationStatus)),n.createElement("li",{className:"migration-resources-count"},n.createElement("span",{className:"label"},n.createElement(f.x6,null,"Resources")),n.createElement("span",{className:"value"},this.hasPendingResourcesMigration?n.createElement(n.Fragment,null,this.props.t("{{count}} to be migrated",{count:this.totalResources})," (",this.props.t("{{count}} shared resources",{count:this.totalSharedResources}),","," ",this.props.t("{{count}} personal resources",{count:this.totalPersonalResources}),")"):n.createElement(f.x6,null,"All migrated")))))),n.createElement("h4",null,n.createElement(f.x6,null,"Items to migrate")),n.createElement("div",{className:"togglelist"},n.createElement("span",{className:`input toggle-switch form-element ${!t&&e?.hasError("migrate_resources_to_v5")&&"warning"}`},n.createElement("input",{id:"migrateResourcesInput",type:"checkbox",name:"migrate_resources_to_v5",className:"toggle-switch-checkbox checkbox",onChange:this.handleInputChange,checked:this.state.settings.migrate_resources_to_v5,disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"migrateResourcesInput"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Resources:")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"Name, Username, URI, Cleartext description.")),!t&&e?.hasError("migrate_resources_to_v5")&&n.createElement("div",{className:"warning"},e?.hasError("migrate_resources_to_v5","allow_creation_of_v5_resources")&&n.createElement("div",{className:"warning-message"},n.createElement(f.x6,null,"Resource types v5 creation is not allowed.")),e?.hasError("migrate_resources_to_v5","resource_types_v5_deleted")&&n.createElement("div",{className:"warning-message"},n.createElement(f.x6,null,"Resources will not be migrated as no content types with encrypted metadata is allowed.")),e?.hasError("migrate_resources_to_v5","resource_types_v5_partially_deleted")&&n.createElement("div",{className:"warning-message"},n.createElement(f.x6,null,"Not all resources will be migrated, some corresponding content types are not active.")))))),n.createElement("h4",null,n.createElement(f.x6,null,"Migration scope")),n.createElement("div",{className:"radiolist-alt"},n.createElement("div",{className:`input radio ${this.state.settings.migrate_personal_content&&"checked"} ${this.hasAllInputDisabled()&&"disabled"}`},n.createElement("input",{type:"radio",value:"all-content",onChange:this.handleMigrateScopeInputChange,name:"migrate_personal_content",checked:this.state.settings.migrate_personal_content,id:"migrateScopeAllContentInput",disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"migrateScopeAllContentInput"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"All content")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"All resources including the private ones.")))),n.createElement("div",{className:`input radio ${!this.state.settings.migrate_personal_content&&"checked"} ${this.hasAllInputDisabled()&&"disabled"}`},n.createElement("input",{type:"radio",value:"shared-only",onChange:this.handleMigrateScopeInputChange,name:"migrate_personal_content",checked:!this.state.settings.migrate_personal_content,id:"migrateScopeSharedContentInput",disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"migrateScopeSharedContentInput"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Shared content only")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"Only shared resources are migrated."))))))),t&&this.hasPendingMigration&&n.createElement("div",{className:"error message"},n.createElement("div",null,n.createElement(f.x6,null,"No active metadata keys available."))),!t&&this.hasMissingMetadataKeys&&n.createElement("div",{className:"error message"},n.createElement("div",null,n.createElement(f.x6,null,"You lack access to the shared metadata key.")," ",n.createElement(f.x6,null,"Please ask another administrator to share it with you."))),s&&n.createElement("div",{className:"warning message"},a&&n.createElement("div",{className:"form-banner"},n.createElement("b",null,n.createElement(f.x6,null,"Warning:"))," ",n.createElement(f.x6,null,"Your current API version includes beta support for encrypted metadata and new resource types.")," ",n.createElement(f.x6,null,"To ensure stability and avoid potential issues, upgrade to the latest version before enabling these features.")),!this.hasMissingMetadataKeys&&this.hasPendingMigration&&n.createElement("div",null,n.createElement("p",null,n.createElement("b",null,n.createElement(f.x6,null,"Warning:"))," ",n.createElement(f.x6,null,"If you have integrations, you will have to make sure they are updated before triggering the migration."))))),n.createElement("div",{className:"actions-wrapper"},n.createElement("button",{type:"button",className:"button primary",disabled:this.state.isProcessing||t||this.hasMissingMetadataKeys,onClick:this.handleFormSubmit},n.createElement("span",null,n.createElement(f.x6,null,"Migrate")))),Xa(n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"Need help?")),n.createElement("p",null,n.createElement(f.x6,null,"For more information about the content type support and migration, checkout the dedicated page on the official website.")),n.createElement("a",{className:"button",target:"_blank",rel:"noopener noreferrer",href:"https://passbolt.com/docs/admin/metadata-encryption/migrate-metadata/"},n.createElement(jt,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}ig.propTypes={context:i().object,actionFeedbackContext:i().object,dialogContext:i().object,createPortal:i().func,metadataSettingsServiceWorkerService:i().object,metadataKeysServiceWorkerService:i().object,metadataMigrateContentServiceWorkerService:i().object,resourceTypes:i().instanceOf(Ep),t:i().func};const rg=N(m(h(nh(h((0,f.CI)("common")(ig)))))),og={passwordV4:[ju,Lu],totpV4:[zu],passwordV5:[Ku,Vu],totpV5:[Bu],customFieldsV5:[Wu],noteV5:[Hu],pinCodeV5:[$u]},lg={passwordV4:[ju,Lu,qu],totpV4:[zu,qu],passwordV5:[Ku,Vu,Gu],totpV5:[Bu,Gu],customFieldsV5:[Wu],noteV5:[Hu],pinCodeV5:[$u]};class cg extends he{constructor(e,t){super(e,t),this._props.resource_types&&(this._resource_types=new Ep(this._props.resource_types))}static getSchema(){return{type:"object",required:["password_v4","password_v5","totp_v4","totp_v5","custom_fields_v5","note_v5","pin_code_v5","password_v4_count","password_v5_count","totp_v4_count","totp_v5_count","custom_fields_v5_count","note_v5_count","pin_code_v5_count","resource_types","has_v4_resource_types","has_v5_resource_types"],properties:{password_v4:{type:"boolean"},password_v5:{type:"boolean"},totp_v4:{type:"boolean"},totp_v5:{type:"boolean"},custom_fields_v5:{type:"boolean"},note_v5:{type:"boolean"},pin_code_v5:{type:"boolean"},password_v4_count:{type:"integer"},password_v5_count:{type:"integer"},totp_v4_count:{type:"integer"},totp_v5_count:{type:"integer"},custom_fields_v5_count:{type:"integer"},note_v5_count:{type:"integer"},pin_code_v5_count:{type:"integer"},has_v4_resource_types:{type:"boolean"},has_v5_resource_types:{type:"boolean"},resource_types:Ep.getSchema()}}}static createFormResourcesTypesCollection(e){if(!(e instanceof Ep))throw new TypeError("The parameter 'resource_types' is not a valid 'ResourceTypesCollection' type.");const t=e.items.filter(e=>!e.isDeleted()),a=new Ep(t),n=this._areAllResourceTypesAvailable(og.passwordV4,a),s=this._areAllResourceTypesAvailable(og.passwordV5,a),i=this._areAllResourceTypesAvailable(og.totpV4,a),r=this._areAllResourceTypesAvailable(og.totpV5,a),o=this._areAllResourceTypesAvailable(og.customFieldsV5,a),l=this._areAllResourceTypesAvailable(og.noteV5,a),c=this._areAllResourceTypesAvailable(og.pinCodeV5,a),m=this._getResourcesCountForResourceTypeFamily(lg.passwordV4,e),d=this._getResourcesCountForResourceTypeFamily(lg.passwordV5,e),u=this._getResourcesCountForResourceTypeFamily(lg.totpV4,e),p=this._getResourcesCountForResourceTypeFamily(lg.totpV5,e),h=this._getResourcesCountForResourceTypeFamily(lg.customFieldsV5,a),g=this._getResourcesCountForResourceTypeFamily(lg.noteV5,e),y=this._getResourcesCountForResourceTypeFamily(lg.pinCodeV5,e),b=e.hasSomeOfVersion("v4"),f=e.hasSomeOfVersion("v5");return new cg({password_v4:n,password_v5:s,totp_v4:i,totp_v5:r,custom_fields_v5:o,note_v5:l,pin_code_v5:c,password_v4_count:m,password_v5_count:d,totp_v4_count:u,totp_v5_count:p,note_v5_count:g,pin_code_v5_count:y,custom_fields_v5_count:h,has_v4_resource_types:b,has_v5_resource_types:f,resource_types:e})}static _getResourcesCountForResourceTypeFamily(e,t){let a=0;for(let n=0;nt.hasOneWithSlug(e))}validateBuildRules(){let e=null;if(!this._props.password_v4&&this._props.password_v4_count>0&&(e=e||new X,e.addError("password_v4","has_content","Password content type is disabled but there are existing password resources.")),!this._props.totp_v4&&this._props.totp_v4_count>0&&(e=e||new X,e.addError("totp_v4","has_content","TOTP content type is disabled but there are existing TOTP resources.")),!this._props.password_v5&&this._props.password_v5_count>0&&(e=e||new X,e.addError("password_v5","has_content","Password content type is disabled but there are existing password resources.")),!this._props.totp_v5&&this._props.totp_v5_count>0&&(e=e||new X,e.addError("totp_v5","has_content","TOTP content type is disabled but there are existing TOTP resources.")),!this._props.custom_fields_v5&&this._props.custom_fields_v5_count>0&&(e=e||new X,e.addError("custom_fields_v5","has_content","Custom fields content type is disabled but there are existing custom fields resources.")),!this._props.note_v5&&this._props.note_v5_count>0&&(e=e||new X,e.addError("note_v5","has_content","Note content type is disabled but there are existing note resources.")),!this._props.pin_code_v5&&this._props.pin_code_v5_count>0&&(e=e||new X,e.addError("pin_code_v5","has_content","Pin code content type is disabled but there are existing pin code resources.")),!(this._props.password_v4||this._props.totp_v4||this._props.password_v5||this._props.totp_v5||this._props.note_v5||this._props.pin_code_v5)){const t="At least one content type should be allowed",a="minimum_requirement";e=e||new X,e.addError("password_v4",a,t),e.addError("totp_v4",a,t),e.addError("password_v5",a,t),e.addError("totp_v5",a,t),e.addError("custom_fields_v5",a,t),e.addError("note_v5",a,t),e.addError("pin_code_v5",a,t)}if(e)throw e}verifyHealth(e,t){if(void 0===e)return null;if(void 0===t)return null;if(!(e instanceof Mu))throw new TypeError("The parameter 'metadataTypesSettings' is not a valid 'MetadataTypesSettingsEntity' type.");if(!(t instanceof Bp))throw new TypeError("The parameter 'metadataKeysCollection' is not a valid 'MetadataKeysCollection' type.");let a=null;!e.allowCreationOfV4Resources||this._props.password_v4||this._props.totp_v4||(a=new X,a.addError("password_v4","is_creation_alowed","V4 resource creation is enabled but password content type is disabled."),a.addError("totp_v4","is_creation_alowed","V4 resource creation is enabled but TOTP content type is disabled.")),!e.allowCreationOfV4Resources&&this._props.password_v4&&(a=a||new X,a.addError("password_v4","is_creation_not_alowed","Creation of resource type v4 is not allowed.")),!e.allowCreationOfV4Resources&&this._props.totp_v4&&(a=a||new X,a.addError("totp_v4","is_creation_not_alowed","Creation of resource type v4 is not allowed.")),!e.allowCreationOfV5Resources||this._props.password_v5||this._props.totp_v5||this._props.custom_fields_v5||this._props.note_v5||this._props.pin_code_v5||(a=a||new X,a.addError("password_v5","is_creation_alowed","V5 resource creation is enabled but password content type is disabled."),a.addError("totp_v5","is_creation_alowed","V5 resource creation is enabled but TOTP content type is disabled."),a.addError("custom_fields_v5","is_creation_alowed","V5 resource creation is enabled but custom fields content type is disabled."),a.addError("note_v5","is_creation_alowed","V5 resource creation is enabled but note content type is disabled."),a.addError("pin_code_v5","is_creation_alowed","V5 resource creation is enabled but pin code content type is disabled.")),!e.allowCreationOfV5Resources&&this._props.password_v5&&(a=a||new X,a.addError("password_v5","is_creation_not_alowed","Creation of resource type v5 is not allowed.")),!e.allowCreationOfV5Resources&&this._props.totp_v5&&(a=a||new X,a.addError("totp_v5","is_creation_not_alowed","Creation of resource type v5 is not allowed.")),!e.allowCreationOfV5Resources&&this._props.note_v5&&(a=a||new X,a.addError("note_v5","is_creation_not_alowed","Creation of resource type v5 is not allowed.")),!e.allowCreationOfV5Resources&&this._props.custom_fields_v5&&(a=a||new X,a.addError("custom_fields_v5","is_creation_not_alowed","Creation of resource type v5 is not allowed.")),!e.allowCreationOfV5Resources&&this._props.pin_code_v5&&(a=a||new X,a.addError("pin_code_v5","is_creation_not_alowed","Creation of resource type v5 is not allowed."));const n=t.items.filter(e=>!e.expired);return 0===n.length&&this._props.password_v5&&(a=a||new X,a.addError("password_v5","active_metadata_key","No active metadata key defined.")),0===n.length&&this._props.totp_v5&&(a=a||new X,a.addError("totp_v5","active_metadata_key","No active metadata key defined.")),0===n.length&&this._props.custom_fields_v5&&(a=a||new X,a.addError("custom_fields_v5","active_metadata_key","No active metadata key defined.")),0===n.length&&this._props.note_v5&&(a=a||new X,a.addError("note_v5","active_metadata_key","No active metadata key defined.")),0===n.length&&this._props.pin_code_v5&&(a=a||new X,a.addError("pin_code_v5","active_metadata_key","No active metadata key defined.")),a}toFormDto(){return{password_v4:this._props.password_v4,password_v5:this._props.password_v5,totp_v4:this._props.totp_v4,totp_v5:this._props.totp_v5,custom_fields_v5:this._props.custom_fields_v5,note_v5:this._props.note_v5,pin_code_v5:this._props.pin_code_v5,password_v4_count:this._props.password_v4_count,password_v5_count:this._props.password_v5_count,totp_v4_count:this._props.totp_v4_count,totp_v5_count:this._props.totp_v5_count,custom_fields_v5_count:this._props.custom_fields_v5_count,note_v5_count:this._props.note_v5_count,pin_code_v5_count:this._props.pin_code_v5_count,has_v4_resource_types:this._props.has_v4_resource_types,has_v5_resource_types:this._props.has_v5_resource_types,resource_types:this._resource_types}}toResourceTypesCollection(){const e=this._resource_types.items.filter(e=>this._props.password_v4&&e.isV4()&&e.hasPassword()&&!e.hasTotp()||this._props.totp_v4&&e.isV4()&&!e.hasPassword()&&e.hasTotp()||this._props.totp_v4&&this._props.password_v4&&e.isV4()&&e.hasPassword()&&e.hasTotp()||this._props.password_v5&&e.isV5()&&e.hasPassword()&&!e.hasTotp()||this._props.totp_v5&&e.isV5()&&!e.hasPassword()&&e.hasTotp()||this._props.totp_v5&&this._props.password_v5&&e.isV5()&&e.hasPassword()&&e.hasTotp()||this._props.custom_fields_v5&&e.slug===Wu||this._props.note_v5&&e.slug===Hu||this._props.pin_code_v5&&e.slug===$u),t=this._resource_types.items.filter(t=>!e.some(e=>t.id===e.id)),a=e.filter(e=>e.isDeleted()),n=t.filter(e=>!e.isDeleted()),s=Ds.c9.now().toISO();for(let e=0;ethis.formSettings?.validate());verifyDataHealth=(0,po.A)((e,t,a)=>this.formSettings?.verifyHealth(t,a));hasSettingsChanges=(0,po.A)((e,t,a)=>this.originalSettings?.hasDiffProps(this.formSettings));handleInputChange(e){if(this.hasAllInputDisabled())return;const{type:t,checked:a,value:n,name:s}=e.target,i="checkbox"===t?a:n;this.setFormPropertyValue(s,i)}setFormPropertyValue(e,t){this.formSettings.set(e,t,{validate:!1}),this.setState({settings:this.formSettings.toFormDto()})}hasAllInputDisabled(){return this.state.isProcessing}handleFormSubmit(e){e.preventDefault(),this.save()}isInputDisabled(e,t){return this.hasAllInputDisabled()||e>0&&t}async save(){if(this.state.isProcessing)return;const e=this.validateForm(this.state.settings);if(e?.hasErrors())this.setState({hasAlreadyBeenValidated:!0});else{this.setState({isProcessing:!0});try{const e=this.formSettings.toResourceTypesCollection();await this.resourceTypesServiceWorkerService.updateAllDeletedStatus(e);const t=await this.resourceTypesServiceWorkerService.findAllByDeletedAndNonDeleted();this.originalSettings=mg.createFormResourcesTypesCollection(t),this.formSettings=new mg(this.originalSettings.toFormDto()),await this.props.actionFeedbackContext.displaySuccess(this.props.t("The allowed content types were updated."))}catch(e){console.error(e),this.props.dialogContext.open($t,{error:e})}this.setState({hasAlreadyBeenValidated:!0,isProcessing:!1,settings:this.formSettings.toFormDto()})}}addTooltipOnDisabledElement(e,t){return t?n.createElement(Mt,{message:"You cannot disable a content type that is in use.",direction:"right"},e):n.createElement(n.Fragment,null,e)}render(){const e=this.state.hasAlreadyBeenValidated?this.validateForm(this.state.settings):null,t=this.verifyDataHealth(this.state.settings,this.metadataTypesSettings,this.metadataKeys),a=this.hasSettingsChanges(this.originalSettings,this.formSettings,this.state.settings),s=this.props.context.siteSettings.isFeatureBeta("metadata"),i=s||a;return n.createElement("div",{className:"row"},n.createElement("div",{id:"allow-content-types",className:"main-column"},n.createElement("div",{className:"main-content"},n.createElement("form",{onSubmit:this.handleFormSubmit,"data-testid":"submit-form"},n.createElement("h3",{className:"title"},n.createElement("label",null,n.createElement(f.x6,null,"Allow content types"))),this.state.settings.has_v5_resource_types&&n.createElement(n.Fragment,null,n.createElement("h4",{className:"no-border"},n.createElement(f.x6,null,"Encrypted metadata")),n.createElement("p",{className:"description"},n.createElement(f.x6,null,"Select which content type with encrypted metadata is available for your whole organisation.")),n.createElement("div",{className:"checkboxlist"},n.createElement("span",{className:`input checkbox form-element ${e?.hasError("password_v5")&&"error"} ${!e?.hasError("password_v5")&&t?.hasError("password_v5")&&"warning"}`},n.createElement("input",{type:"checkbox",id:"passwordV5Input",className:"checkbox",name:"password_v5",onChange:this.handleInputChange,checked:this.state.settings.password_v5,disabled:this.isInputDisabled(this.state.settings.password_v5_count,this.state.settings.password_v5)}),n.createElement("label",{htmlFor:"passwordV5Input"},this.addTooltipOnDisabledElement(n.createElement("div",{className:"allow-content-type-item"},n.createElement(hg,null),n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Password")),n.createElement("span",{className:"info"},this.props.t("({{count}} resources)",{count:this.state.settings.password_v5_count}))),this.isInputDisabled(this.state.settings.password_v5_count,this.state.settings.password_v5)),e?.hasError("password_v5","has_content")&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"Password content type is disabled but there are existing password resources.")),e?.hasError("password_v5","minimum_requirement")&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"At least one content type should be allowed")),!e?.hasError("password_v5")&&n.createElement(n.Fragment,null,t?.hasError("password_v5","is_creation_alowed")&&n.createElement("div",{className:"warning-message"},n.createElement(f.x6,null,"V5 resource creation is enabled but password content type is disabled.")),t?.hasError("password_v5","active_metadata_key")&&n.createElement("div",{className:"warning-message"},n.createElement(f.x6,null,"No active metadata key defined.")),t?.hasError("password_v5","is_creation_not_alowed")&&n.createElement("div",{className:"warning-message"},n.createElement(f.x6,null,"Creation of content type v5 is not allowed."))))),n.createElement("span",{className:`input checkbox form-element ${e?.hasError("totp_v5")&&"error"} ${!e?.hasError("totp_v5")&&t?.hasError("totp_v5")&&"warning"}`},n.createElement("input",{type:"checkbox",id:"totpV5Input",className:"checkbox",name:"totp_v5",onChange:this.handleInputChange,checked:this.state.settings.totp_v5,disabled:this.isInputDisabled(this.state.settings.totp_v5_count,this.state.settings.totp_v5)}),n.createElement("label",{htmlFor:"totpV5Input"},this.addTooltipOnDisabledElement(n.createElement("div",{className:"allow-content-type-item"},n.createElement(fg,null),n.createElement("span",{className:"name"},n.createElement(f.x6,null,"TOTP")),n.createElement("span",{className:"info"},this.props.t("({{count}} resources)",{count:this.state.settings.totp_v5_count}))),this.isInputDisabled(this.state.settings.totp_v5_count,this.state.settings.totp_v5)),e?.hasError("totp_v5","has_content")&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"TOTP content type is disabled but there are existing TOTP resources.")),e?.hasError("totp_v5","minimum_requirement")&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"At least one content type should be allowed")),!e?.hasError("totp_v5")&&n.createElement(n.Fragment,null,t?.hasError("totp_v5","is_creation_alowed")&&n.createElement("div",{className:"warning-message"},n.createElement(f.x6,null,"V5 resource creation is enabled but TOTP content type is disabled.")),t?.hasError("totp_v5","active_metadata_key")&&n.createElement("div",{className:"warning-message"},n.createElement(f.x6,null,"No active metadata key defined.")),t?.hasError("totp_v5","is_creation_not_alowed")&&n.createElement("div",{className:"warning-message"},n.createElement(f.x6,null,"Creation of content type v5 is not allowed."))))),n.createElement("span",{className:`input checkbox form-element ${e?.hasError("custom_fields_v5")&&"error"} ${!e?.hasError("custom_fields_v5")&&t?.hasError("custom_fields_v5")&&"warning"}`},n.createElement("input",{type:"checkbox",id:"customFieldsV5Input",className:"checkbox",name:"custom_fields_v5",onChange:this.handleInputChange,checked:this.state.settings.custom_fields_v5,disabled:this.isInputDisabled(this.state.settings.custom_fields_v5_count,this.state.settings.custom_fields_v5)}),n.createElement("label",{htmlFor:"customFieldsV5Input"},this.addTooltipOnDisabledElement(n.createElement("div",{className:"allow-content-type-item"},n.createElement(wg,null),n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Custom fields")),n.createElement("span",{className:"info"},this.props.t("({{count}} resources)",{count:this.state.settings.custom_fields_v5_count}))),this.isInputDisabled(this.state.settings.custom_fields_v5_count,this.state.settings.custom_fields_v5)),e?.hasError("custom_fields_v5","has_content")&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"Custom fields content type is disabled but there are existing custom fields resources.")),e?.hasError("custom_fields_v5","minimum_requirement")&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"At least one content type should be allowed")),!e?.hasError("custom_fields_v5")&&n.createElement(n.Fragment,null,t?.hasError("custom_fields_v5","is_creation_alowed")&&n.createElement("div",{className:"warning-message"},n.createElement(f.x6,null,"V5 resource creation is enabled but custom fields content type is disabled.")),t?.hasError("custom_fields_v5","active_metadata_key")&&n.createElement("div",{className:"warning-message"},n.createElement(f.x6,null,"No active metadata key defined.")),t?.hasError("custom_fields_v5","is_creation_not_alowed")&&n.createElement("div",{className:"warning-message"},n.createElement(f.x6,null,"Creation of content type v5 is not allowed."))))),n.createElement("span",{className:`input checkbox form-element ${e?.hasError("note_v5")&&"error"} ${!e?.hasError("note_v5")&&t?.hasError("note_v5")&&"warning"}`},n.createElement("input",{type:"checkbox",id:"noteV5Input",className:"checkbox",name:"note_v5",onChange:this.handleInputChange,checked:this.state.settings.note_v5,disabled:this.isInputDisabled(this.state.settings.note_v5_count,this.state.settings.note_v5)}),n.createElement("label",{htmlFor:"noteV5Input"},this.addTooltipOnDisabledElement(n.createElement("div",{className:"allow-content-type-item"},n.createElement(xg,null),n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Note")),n.createElement("span",{className:"info"},this.props.t("({{count}} resources)",{count:this.state.settings.note_v5_count}))),this.isInputDisabled(this.state.settings.note_v5_count,this.state.settings.note_v5)),e?.hasError("note_v5","has_content")&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"Note content type is disabled but there are existing note resources.")),e?.hasError("note_v5","minimum_requirement")&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"At least one content type should be allowed")),!e?.hasError("note_v5")&&n.createElement(n.Fragment,null,t?.hasError("note_v5","is_creation_alowed")&&n.createElement("div",{className:"warning-message"},n.createElement(f.x6,null,"V5 resource creation is enabled but note content type is disabled.")),t?.hasError("note_v5","active_metadata_key")&&n.createElement("div",{className:"warning-message"},n.createElement(f.x6,null,"No active metadata key defined.")),t?.hasError("note_v5","is_creation_not_alowed")&&n.createElement("div",{className:"warning-message"},n.createElement(f.x6,null,"Creation of content type v5 is not allowed."))))),n.createElement("span",{className:`input checkbox form-element ${e?.hasError("pin_code_v5")&&"error"} ${!e?.hasError("pin_code_v5")&&t?.hasError("pin_code_v5")&&"warning"}`},n.createElement("input",{type:"checkbox",id:"pinCodeV5Input",className:"checkbox",name:"pin_code_v5",onChange:this.handleInputChange,checked:this.state.settings.pin_code_v5,disabled:this.isInputDisabled(this.state.settings.pin_code_v5_count,this.state.settings.pin_code_v5)}),n.createElement("label",{htmlFor:"pinCodeV5Input"},this.addTooltipOnDisabledElement(n.createElement("div",{className:"allow-content-type-item"},n.createElement(Ng,null),n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Pin code")),n.createElement("span",{className:"info"},this.props.t("({{count}} resources)",{count:this.state.settings.pin_code_v5_count}))),this.isInputDisabled(this.state.settings.pin_code_v5_count,this.state.settings.pin_code_v5)),e?.hasError("pin_code_v5","has_content")&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"PIN code content type is disabled but there are existing PIN code resources.")),e?.hasError("pin_code_v5","minimum_requirement")&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"At least one content type should be allowed")),!e?.hasError("pin_code_v5")&&n.createElement(n.Fragment,null,t?.hasError("pin_code_v5","is_creation_alowed")&&n.createElement("div",{className:"warning-message"},n.createElement(f.x6,null,"V5 resource creation is enabled but PIN code content type is disabled.")),t?.hasError("pin_code_v5","active_metadata_key")&&n.createElement("div",{className:"warning-message"},n.createElement(f.x6,null,"No active metadata key defined.")),t?.hasError("pin_code_v5","is_creation_not_alowed")&&n.createElement("div",{className:"warning-message"},n.createElement(f.x6,null,"Creation of content type v5 is not allowed."))))))),this.state.settings.has_v4_resource_types&&n.createElement(n.Fragment,null,n.createElement("h4",{className:`${!this.state.settings.has_password_v5&&"no-border"}`},n.createElement(f.x6,null,"Legacy cleartext metadata")),n.createElement("p",{className:"description"},n.createElement(f.x6,null,"Select which content type with cleartext metadata is available for your whole organisation.")),n.createElement("div",{className:"checkboxlist"},n.createElement("span",{className:`input checkbox form-element ${e?.hasError("password_v4")&&"error"} ${!e?.hasError("password_v4")&&t?.hasError("password_v4")&&"warning"}`},n.createElement("input",{type:"checkbox",id:"passwordV4Input",className:"checkbox",name:"password_v4",onChange:this.handleInputChange,checked:this.state.settings.password_v4,disabled:this.isInputDisabled(this.state.settings.password_v4_count,this.state.settings.password_v4)}),n.createElement("label",{htmlFor:"passwordV4Input"},this.addTooltipOnDisabledElement(n.createElement("div",{className:"allow-content-type-item"},n.createElement(hg,null),n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Password")),n.createElement("span",{className:"info"},this.props.t("({{count}} resources)",{count:this.state.settings.password_v4_count}))),this.isInputDisabled(this.state.settings.password_v4_count,this.state.settings.password_v4)),e?.hasError("password_v4","has_content")&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"Password content type is disabled but there are existing password resources.")),e?.hasError("password_v4","minimum_requirement")&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"At least one content type should be allowed")),!e?.hasError("password_v4")&&n.createElement(n.Fragment,null,t?.hasError("password_v4","is_creation_alowed")&&n.createElement("div",{className:"warning-message"},n.createElement(f.x6,null,"V4 resource creation is enabled but password content type is disabled.")),t?.hasError("password_v4","is_creation_not_alowed")&&n.createElement("div",{className:"warning-message"},n.createElement(f.x6,null,"Creation of content type v4 is not allowed."))))),n.createElement("span",{className:`input checkbox form-element ${e?.hasError("totp_v4")&&"error"} ${!e?.hasError("totp_v4")&&t?.hasError("totp_v4")&&"warning"}`},n.createElement("input",{type:"checkbox",id:"totpV4Input",className:"checkbox",name:"totp_v4",onChange:this.handleInputChange,checked:this.state.settings.totp_v4,disabled:this.isInputDisabled(this.state.settings.totp_v4_count,this.state.settings.totp_v4)}),n.createElement("label",{htmlFor:"totpV4Input"},this.addTooltipOnDisabledElement(n.createElement("div",{className:"allow-content-type-item"},n.createElement(fg,null),n.createElement("span",{className:"name"},n.createElement(f.x6,null,"TOTP")),n.createElement("span",{className:"info"},this.props.t("({{count}} resources)",{count:this.state.settings.totp_v4_count}))),this.isInputDisabled(this.state.settings.totp_v4_count,this.state.settings.totp_v4)),e?.hasError("totp_v4","has_content")&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"TOTP content type is disabled but there are existing TOTP resources.")),e?.hasError("totp_v4","minimum_requirement")&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"At least one content type should be allowed")),!e?.hasError("totp_v4")&&n.createElement(n.Fragment,null,t?.hasError("totp_v4","is_creation_alowed")&&n.createElement("div",{className:"warning-message"},n.createElement(f.x6,null,"V4 resource creation is enabled but TOTP content type is disabled.")),t?.hasError("totp_v4","is_creation_not_alowed")&&n.createElement("div",{className:"warning-message"},n.createElement(f.x6,null,"Creation of content type v4 is not allowed."))))))))),i&&n.createElement("div",{className:"warning message"},s&&n.createElement("div",{className:"form-banner"},n.createElement("b",null,n.createElement(f.x6,null,"Warning:"))," ",n.createElement(f.x6,null,"Your current API version includes beta support for encrypted metadata and new resource types.")," ",n.createElement(f.x6,null,"To ensure stability and avoid potential issues, upgrade to the latest version before enabling these features.")),a&&n.createElement("div",null,n.createElement("p",null,n.createElement("b",null,n.createElement(f.x6,null,"Warning:"))," ",n.createElement(f.x6,null,"Don't forget to save your settings to apply your modification."))))),n.createElement("div",{className:"actions-wrapper"},n.createElement("button",{type:"button",className:"button primary",disabled:this.state.isProcessing,onClick:this.handleFormSubmit},n.createElement("span",null,n.createElement(f.x6,null,"Save")))),Xa(n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"Need help?")),n.createElement("p",null,n.createElement(f.x6,null,"For more information about the content type support and migration, checkout the dedicated page on the official website.")),n.createElement("a",{className:"button",target:"_blank",rel:"noopener noreferrer",href:"https://passbolt.com/docs/admin/metadata-encryption/allowed-content-types/"},n.createElement(jt,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}Tg.propTypes={context:i().object,dialogContext:i().object,actionFeedbackContext:i().object,createPortal:i().func,resourceTypesServiceWorkerService:i().object,metadataKeysServiceWorkerService:i().object,metadataSettingsServiceWorkerService:i().object,t:i().func};const Ag=N(m(h((0,f.CI)("common")(Tg))));class Ig extends n.PureComponent{get pill(){return this.props.isBeta?n.createElement("span",{className:"chips beta"},"beta"):this.props.isNew?n.createElement("span",{className:"chips new"},"new"):n.createElement(n.Fragment,null)}get hasAPill(){return Boolean(this.props.isBeta||this.props.isNew)}render(){return n.createElement("button",{type:"button",className:"button-transparent card",onClick:this.props.onClick},this.props.icon,n.createElement("div",{className:"card-information"},n.createElement("span",{className:`title-wrapper ${this.hasAPill&&"with-pill"}`},n.createElement("span",{className:"title",title:this.props.title},this.props.title,this.pill),this.props.proTeasing&&n.createElement(Ea,null)),this.props.description&&n.createElement("span",{className:"info",title:this.props.description},this.props.description)))}}Ig.defaultProps={isBeta:!1,proTeasing:!1},Ig.propTypes={icon:i().object.isRequired,title:i().string.isRequired,description:i().string,isBeta:i().bool.isRequired,isNew:i().bool,onClick:i().func,proTeasing:i().bool.isRequired};const Rg=Ig;var Pg;function Dg(){return Dg=Object.assign?Object.assign.bind():function(e){for(var t=1;tn.createElement(Rg,{key:e.title,icon:e.icon,title:e.title,description:e.description,onClick:()=>this.handleClickOn(e),isBeta:this.isDisplayedAsBeta(e),isNew:Boolean(e.isNew),proTeasing:e.displayProTeasingIcon}))))))}}mb.propTypes={context:i().object,navigationContext:i().object,administrationEncryptedMetadataGettingStartedContext:i().object,metadataGettingStartedSettings:i().object,t:i().func};const db=N(ga(Ke((0,f.CI)("common")(mb))));var ub;function pb(){return pb=Object.assign?Object.assign.bind():function(e){for(var t=1;t{const n=e?.profile;return n&&(Boolean(n.first_name)||Boolean(n.last_name))?a.withUsername?`${n.first_name} ${n.last_name} (${e.username})`:`${n.first_name} ${n.last_name}`:t("Unknown user")};class Fb extends n.Component{render(){return n.createElement(n.Fragment,null,this.props.shouldDisplayWarning&&n.createElement("div",{className:"sidebar-help-section warning message"},n.createElement("div",{className:"form-banner"},n.createElement("p",null,n.createElement("b",null,n.createElement(f.x6,null,"Warning:"))," ",n.createElement(f.x6,null,"if you think the secret has been compromised please regenerate and update it in your provider settings.")))),n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"Need help?")),n.createElement("p",null,n.createElement(f.x6,null,"For more information about SCIM, checkout the dedicated page on the official website.")),n.createElement("a",{className:"button",target:"_blank",rel:"noopener noreferrer",href:"https://www.passbolt.com/docs/admin/user-provisioning/scim"},n.createElement(jt,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))))}}Fb.propTypes={shouldDisplayWarning:i().bool.isRequired};const jb=Fb;class Lb{constructor(e){this.port=e}async findAll(){const e=await this.port.request("passbolt.role.get-all");return new nm(e)}async updateResourceLocalStorage(){await this.port.request("passbolt.role.update-local-storage")}}function qb(){return qb=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},getAllRoles:()=>{},refreshRoles:()=>{}});class Kb extends n.Component{constructor(e){super(e),this.state=this.defaultState(),this.runningLocalStorageUpdatePromise=null,this.roleServiceWorkerService=new Lb(e.context.port),this.initEventHandlers()}defaultState(){return{rolesCollection:null,getRole:this.getRole.bind(this),getAllRoles:this.getAllRoles.bind(this),refreshRoles:this.refreshRoles.bind(this)}}componentDidMount(){this.props.context.storage.onChanged.addListener(this.handleStorageChange)}componentWillUnmount(){this.props.context.storage.onChanged.removeListener(this.handleStorageChange)}initEventHandlers(){this.handleStorageChange=this.handleStorageChange.bind(this)}handleStorageChange(e){e[this.storageKey]&&this.set(e[this.storageKey].newValue)}set(e){const t=new nm(e);this.setState({rolesCollection:t})}get storageKey(){return"roles"}getRole(e){const t=this.state.rolesCollection?.getById(e);return t||(this.refreshRoles(),null)}async loadLocalStorage(){const e=await this.props.context.storage.local.get([this.storageKey]);e[this.storageKey]?this.set(e[this.storageKey]):this.refreshRoles()}getAllRoles(){return this.state.rolesCollection?this.state.rolesCollection:(this.loadLocalStorage(),null)}async refreshRoles(){null===this.runningLocalStorageUpdatePromise?(this.runningLocalStorageUpdatePromise=this.roleServiceWorkerService.updateResourceLocalStorage(),await this.runningLocalStorageUpdatePromise,this.runningLocalStorageUpdatePromise=null):await this.runningLocalStorageUpdatePromise}render(){return n.createElement(zb.Provider,{value:this.state},this.props.children)}}Kb.propTypes={context:i().any,children:i().any},Kb.displayName="RoleContextProvider",N(Kb);class Vb extends n.Component{originalSettings=null;formSettings=null;scimSettingsService=null;constructor(e){super(e),this.state=this.defaultState,this.bindCallbacks(),this.scimSettingsService=e.scimSettingsServiceWorkerService??new Mb(this.props.context.port)}get defaultState(){return{isProcessing:!0,hasAlreadyBeenValidated:!1,enabled:!1,settings:null}}bindCallbacks(){this.handleFormSubmit=this.handleFormSubmit.bind(this),this.handleInputChange=this.handleInputChange.bind(this),this.save=this.save.bind(this),this.handleToggleEnabled=this.handleToggleEnabled.bind(this),this.handleCopyScimUrl=this.handleCopyScimUrl.bind(this),this.handleCopySecretToken=this.handleCopySecretToken.bind(this),this.handleRegenerateSecretToken=this.handleRegenerateSecretToken.bind(this)}async componentDidMount(){this.props.context.users||await this.props.context.port.request("passbolt.users.update-local-storage"),await this.findScimSettings(),this.setState({isProcessing:!1})}componentWillUnmount(){this.clearContext()}get adminUsers(){const e=this.props.roles.items.filter(e=>e.isAdmin())?.[0]||null,t=this.props.context.users;return null!==t&&e?t.filter(t=>!0===t.active&&t.role_id===e.id):[]}get adminUsersForSelect(){return this.adminUsers&&this.adminUsers.map(e=>({value:e.id,label:Ub(e,this.props.t,{withUsername:!0})}))}async findScimSettings(){this.setState({isProcessing:!0});try{const e=await this.scimSettingsService.findSettings();e&&(this.originalSettings=new Ob(e,{validate:!1}),this.formSettings=new Ob(e,{validate:!1}),this.setState({settings:this.formSettings.toDto(),enabled:!0}))}catch(e){await this.handleUnexpectedError(e),this.setDefaultSettings()}this.setState({isProcessing:!1})}setDefaultSettings(){this.formSettings=Ob.createFromDefault(this.adminUsers[0].id),this.setState({settings:this.formSettings.toDto()})}handleToggleEnabled(){this.state.enabled||(this.formSettings=Ob.createFromDefault(this.adminUsers[0].id),this.setState({settings:this.formSettings.toDto()})),this.setState({enabled:!this.state.enabled})}hasSettingsChanges=(0,po.A)((e,t,a)=>e?.hasDiffProps(t)||!1);handleInputChange(e){if(this.hasAllInputDisabled())return;const{type:t,checked:a,name:n}=e.target,s="checkbox"===t?a:e.target.value;this.setFormPropertyValue(n,s)}setFormPropertyValue(e,t){this.formSettings.set(e,t,{validate:!1}),this.setState({settings:this.formSettings.toDto()})}hasAllInputDisabled(){return this.state.isProcessing}async handleCopyScimUrl(){await this.props.clipboardContext.copy(this.scimUrl,this.props.t("The SCIM URL has been copied to the clipboard."))}async handleCopySecretToken(){await this.props.clipboardContext.copy(this.state.settings.secret_token,this.props.t("The SCIM secret token has been copied to the clipboard."))}handleRegenerateSecretToken(){const e=Pb.generateScimSecretToken();this.setFormPropertyValue("secret_token",e)}handleFormSubmit(e){e.preventDefault(),this.save()}async save(){if(this.state.isProcessing)return;this.setState({isProcessing:!0});const e=this.validateForm();if(e?.hasErrors())this.setState({isProcessing:!1,hasAlreadyBeenValidated:!0});else{try{const e=await this.saveScimSettings();this.formSettings=e?new Ob(e,{validate:!1}):null,this.originalSettings=e?new Ob(this.formSettings.toDto(),{validate:!1}):null,this.setState({settings:e?this.formSettings.toDto():null,enabled:null!==e}),await this.props.actionFeedbackContext.displaySuccess(this.props.t("The SCIM settings were updated."))}catch(e){await this.handleUnexpectedError(e)}this.setState({isProcessing:!1})}}validateForm(){return this.formSettings?this.formSettings.validate():null}async saveScimSettings(){if(this.state.enabled){let e;return e=this.originalSettings?await this.scimSettingsService.updateSettings(this.formSettings,this.originalSettings.id):await this.scimSettingsService.createSettings(this.formSettings),e}return this.originalSettings&&await this.scimSettingsService.disableSettings(this.originalSettings.id),null}handleUnexpectedError(e){if(console.error(e),"UserAbortsOperationError"!==e.name)return this.props.dialogContext.open($t,{error:e})}clearContext(){this.setState(this.defaultState)}isSecretTokenExpired(){const e=this.state.settings?.expired;return!!e&&Ds.c9.fromISO(e)n.createElement(e,qb({roleContext:t,roles:t.getAllRoles()},this.props)))}}}((0,f.CI)("common")(Vb)))))));class Bb extends n.Component{render(){return n.createElement("div",{className:"row"},n.createElement("div",{className:"scim-teasing main-column"},n.createElement("div",{className:"main-content"},n.createElement("h3",{className:"title",id:"scim-title"},n.createElement(f.x6,null,"SCIM"),n.createElement(Ea,{className:"pro-teasing-icon"})),n.createElement("p",null,n.createElement(f.x6,null,"Automate user identity management and provisioning via standardised SCIM integration.")),n.createElement("div",{className:"scim-info"},n.createElement("ul",{className:"scim-description"},n.createElement("li",null,n.createElement(fs,null),n.createElement(f.x6,null,"Efficiently manage user identities in the cloud.")),n.createElement("li",null,n.createElement(fs,null),n.createElement(f.x6,null,"Simplify onboarding and offboarding processes.")),n.createElement("li",null,n.createElement(fs,null),n.createElement(f.x6,null,"Reduce manual administrative overhead and errors."))),n.createElement("div",null,n.createElement("a",{className:"button primary",href:"https://www.passbolt.com/ce-to-pro?utm_campaign=21060976-CE%20to%20Pro&utm_source=product",target:"_blank",rel:"noopener noreferrer"},n.createElement(f.x6,null,"Upgrade to Passbolt Pro")))))))}}Bb.propTypes={context:i().object,t:i().func};const Wb=N((0,f.CI)("common")(Bb));class Hb extends he{static getSchema(){return{type:"object",required:["max_revisions","allow_sharing_revisions"],properties:{id:{type:"string",format:"uuid"},max_revisions:{type:"integer",minimum:1},allow_sharing_revisions:{type:"boolean"}}}}static createFromDefault(e={}){return new Hb({max_revisions:1,allow_sharing_revisions:!1,...e})}get id(){return this._props.id}get maxRevisions(){return this._props.max_revisions}get allowSharingRevisions(){return this._props.allow_sharing_revisions}get isFeatureEnabled(){return this.maxRevisions>1}}const $b=Hb;class Yb{constructor(e){this.port=e}async findSettings(){const e=await this.port.request("passbolt.secret-revisions.find-settings");return new $b(e)}async saveSettings(e){if(!(e instanceof $b))throw new TypeError("The parameter `secretRevisionSettingsEntity` should be of type SecretRevisionsSettingsEntity.");const t=await this.port.request("passbolt.secret-revisions.save-settings",e);return new $b(t)}async deleteSettings(){await this.port.request("passbolt.secret-revisions.delete-settings")}}class Zb extends n.Component{originalSettings=null;formSettings=null;constructor(e){super(e),this.secretRevisionsSettingsServiceWorkerService=new Yb(e.context.port),this.state=this.defaultState,this.bindCallbacks()}get defaultState(){return{isProcessing:!0,hasAlreadyBeenValidated:!1,isFeatureEnabled:!1,settings:{}}}bindCallbacks(){this.handleFormSubmit=this.handleFormSubmit.bind(this),this.handleInputChange=this.handleInputChange.bind(this),this.handleEnableFeature=this.handleEnableFeature.bind(this),this.save=this.save.bind(this)}async componentDidMount(){this.originalSettings=await this.secretRevisionsSettingsServiceWorkerService.findSettings(),this.formSettings=new $b(this.originalSettings.toDto(),{validate:!1});const e=this.formSettings.toDto();this.setState({settings:e,isFeatureEnabled:this.originalSettings.isFeatureEnabled,isProcessing:!1})}validateForm=(0,po.A)(e=>this.formSettings?.validate());hasSettingsChanges=(0,po.A)((e,t)=>this.originalSettings?.hasDiffProps(this.formSettings)||this.originalSettings?.isFeatureEnabled!==t);handleInputChange(e){const{value:t,name:a}=e.target,n=parseInt(t,10)+1;this.setFormPropertyValue(a,n)}setFormPropertyValue(e,t){this.formSettings.set(e,t,{validate:!1}),this.setState({settings:this.formSettings.toDto()})}get maxRevisionsLimit(){return this.props.context.siteSettings.getPluginSettings("secretRevisions")?.maxRevisionsLimit||11}get maxRevisionsLimitToDisplay(){return(this.maxRevisionsLimit-1).toString()}handleEnableFeature(e){const{checked:t}=e.target;t&&1===this.state.settings.max_revisions&&this.setFormPropertyValue("max_revisions",2),this.setState({isFeatureEnabled:t})}hasAllInputDisabled(){return this.state.isProcessing}async handleFormSubmit(e){e.preventDefault(),await this.save()}get hasMaxRevisionsError(){return this.state.settings.max_revisions<2||this.state.settings.max_revisions>this.maxRevisionsLimit}async save(){if(this.state.isProcessing)return;const e=this.validateForm(this.state.settings);if(e?.hasErrors()||this.hasMaxRevisionsError)this.setState({hasAlreadyBeenValidated:!0});else{this.setState({isProcessing:!0});try{this.state.isFeatureEnabled?this.state.isFeatureEnabled&&await this.saveSettings():await this.deleteSettings(),await this.props.actionFeedbackContext.displaySuccess(this.props.t("The secret history settings were updated."))}catch(e){console.error(e),this.props.dialogContext.open($t,{error:e})}this.setState({hasAlreadyBeenValidated:!0,isProcessing:!1,settings:this.formSettings.toDto()})}}async deleteSettings(){await this.secretRevisionsSettingsServiceWorkerService.deleteSettings(),this.originalSettings=$b.createFromDefault(),this.formSettings=new $b(this.originalSettings.toDto(),{validate:!1})}async saveSettings(){const e=this.formSettings.toDto();this.originalSettings=new $b(e,{validate:!1}),this.originalSettings=await this.secretRevisionsSettingsServiceWorkerService.saveSettings(new $b(e)),this.formSettings=new $b(this.originalSettings.toDto(),{validate:!1})}render(){const e=this.maxRevisionsLimitToDisplay,t=this.state.hasAlreadyBeenValidated?this.validateForm(this.state.settings):null,a=this.hasSettingsChanges(this.state.settings,this.state.isFeatureEnabled),s=t?.hasError("max_revisions")||this.state.hasAlreadyBeenValidated&&this.hasMaxRevisionsError;return n.createElement("div",{className:"row"},n.createElement("div",{id:"secret-history",className:"main-column"},n.createElement("div",{className:"main-content"},n.createElement("form",{onSubmit:this.handleFormSubmit},n.createElement("h3",{id:"secret-history-settings-title",className:"title"},n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"secretHistorySettingsToggle",onChange:this.handleEnableFeature,checked:this.state.isFeatureEnabled,disabled:this.hasAllInputDisabled(),id:"passwordExpirySettingsToggle"}),n.createElement("label",{htmlFor:"passwordExpirySettingsToggle"},n.createElement(f.x6,null,"Secret history")))),!this.state.isFeatureEnabled&&n.createElement("p",{className:"description"},n.createElement(f.x6,null,"No secret history is configured. Enable it to activate and set the number of passwords revisions.")),this.state.isFeatureEnabled&&n.createElement(n.Fragment,null,n.createElement("p",{className:"description"},n.createElement(f.x6,null,"Control how many revisions are retained, enabling users to view and restore historical data.")),n.createElement("div",{className:"input text "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("h4",null,n.createElement("label",{htmlFor:"configure-secret-history-form-length"},n.createElement(f.x6,null,"History length"))),n.createElement("div",{className:"slider"},n.createElement("input",{name:"max_revisions",min:"1",max:this.maxRevisionsLimit-1,value:this.state.settings.max_revisions-1,step:"1",type:"range",onChange:this.handleInputChange,disabled:this.hasAllInputDisabled()}),n.createElement("input",{id:"configure-secret-history-form-length",type:"number",name:"max_revisions",min:"1",max:this.maxRevisionsLimit-1,value:this.state.settings.max_revisions-1,onChange:this.handleInputChange,disabled:this.hasAllInputDisabled()})),n.createElement("p",{className:"description"},n.createElement(f.x6,null,"This is the number of revisions kept once users have access.")),s&&n.createElement("div",{id:"maxRevisions-error",className:"error-message"},n.createElement(f.x6,null,"The history length must be between 1 and ",{maxRevisionsLimitToDisplay:e},".")))))),a&&n.createElement("div",{className:"warning message"},n.createElement("div",null,n.createElement("p",null,n.createElement("b",null,n.createElement(f.x6,null,"Warning:"))," ",n.createElement(f.x6,null,"Don't forget to save your settings to apply your modification."))))),n.createElement("div",{className:"actions-wrapper"},n.createElement("button",{type:"button",className:"button primary",disabled:this.state.isProcessing,onClick:this.handleFormSubmit},n.createElement("span",null,n.createElement(f.x6,null,"Save")))))}}Zb.propTypes={context:i().object,dialogContext:i().object,actionFeedbackContext:i().object,t:i().func};const Jb=N(m(h((0,f.CI)("common")(Zb))));function Xb(){return Xb=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},close:()=>{}});class ef extends n.Component{constructor(e){super(e),this.state=this.defaultState}get defaultState(){return{announcements:[],show:(e,t)=>{const a=(0,r.A)();return this.setState({announcements:[...this.state.announcements,{key:a,Announcement:e,AnnouncementProps:t}]}),a},close:async e=>await this.setState({announcements:this.state.announcements.filter(t=>e!==t.key)})}}render(){return n.createElement(Qb.Provider,{value:this.state},this.props.children)}}function tf(e){return class extends n.Component{render(){return n.createElement(Qb.Consumer,null,t=>n.createElement(e,Xb({announcementContext:t},this.props)))}}}function af(){return af=Object.assign?Object.assign.bind():function(e){for(var t=1;tn.createElement(t,af({key:e,onClose:()=>this.close(e)},a))),this.props.children)}}nf.propTypes={announcementContext:i().any,children:i().any};const sf=tf(nf);class rf extends n.Component{constructor(e){super(e),this.bindCallbacks()}bindCallbacks(){this.handleGoBack=this.handleGoBack.bind(this)}isCommunityEdition(){return this.props.context.siteSettings.isCommunityEdition}isHomePageSelected(){return Te.HOME===this.props.administrationWorkspaceContext.selectedAdministration||Te.NONE===this.props.administrationWorkspaceContext.selectedAdministration}isMfaSelected(){return Te.MFA===this.props.administrationWorkspaceContext.selectedAdministration}isMfaPolicySelected(){return Te.MFA_POLICY===this.props.administrationWorkspaceContext.selectedAdministration}isPasswordPoliciesSelected(){return Te.PASSWORD_POLICIES===this.props.administrationWorkspaceContext.selectedAdministration}isUserDirectorySelected(){return Te.USER_DIRECTORY===this.props.administrationWorkspaceContext.selectedAdministration}isEmailNotificationsSelected(){return Te.EMAIL_NOTIFICATION===this.props.administrationWorkspaceContext.selectedAdministration}isSubscriptionSelected(){return Te.SUBSCRIPTION===this.props.administrationWorkspaceContext.selectedAdministration}isInternationalizationSelected(){return Te.INTERNATIONALIZATION===this.props.administrationWorkspaceContext.selectedAdministration}isAccountRecoverySelected(){return Te.ACCOUNT_RECOVERY===this.props.administrationWorkspaceContext.selectedAdministration}isSmtpSettingsSelected(){return Te.SMTP_SETTINGS===this.props.administrationWorkspaceContext.selectedAdministration}isSelfRegistrationSelected(){return Te.SELF_REGISTRATION===this.props.administrationWorkspaceContext.selectedAdministration}isSsoSelected(){return Te.SSO===this.props.administrationWorkspaceContext.selectedAdministration}isRbacSelected(){return Te.RBAC===this.props.administrationWorkspaceContext.selectedAdministration}isUserPassphrasePoliciesSelected(){return Te.USER_PASSPHRASE_POLICIES===this.props.administrationWorkspaceContext.selectedAdministration}isPasswordExpirySelected(){return Te.PASSWORD_EXPIRY===this.props.administrationWorkspaceContext.selectedAdministration}isContentTypesEncryptedMetadataSelected(){return Te.CONTENT_TYPES_ENCRYPTED_METADATA===this.props.administrationWorkspaceContext.selectedAdministration}isContentTypesMetadataKeySelected(){return Te.CONTENT_TYPES_METADATA_KEY===this.props.administrationWorkspaceContext.selectedAdministration}isMigrateMetadataSelected(){return Te.MIGRATE_METADATA===this.props.administrationWorkspaceContext.selectedAdministration}isAllowContentTypesSelected(){return Te.ALLOW_CONTENT_TYPES===this.props.administrationWorkspaceContext.selectedAdministration}isGetStartedMetadataSelected(){return Te.METADATA_GETTING_STARTED===this.props.administrationWorkspaceContext.selectedAdministration}isScimSelected(){return Te.SCIM===this.props.administrationWorkspaceContext.selectedAdministration}isSecretHistorySelected(){return Te.SECRET_HISTORY===this.props.administrationWorkspaceContext.selectedAdministration}handleGoBack(){this.props.navigationContext.onGoToPasswordsRequested()}get isHttpError403(){return Te.HTTP_403_ACCESS_DENIED===this.props.administrationWorkspaceContext.selectedAdministration}get isHttpError404(){return Te.HTTP_404_NOT_FOUND===this.props.administrationWorkspaceContext.selectedAdministration}isHealthcheckSelected(){return Te.HEALTHCHECK===this.props.administrationWorkspaceContext.selectedAdministration}render(){return n.createElement("div",{id:"container",className:"page administration"},n.createElement("div",{id:"app",className:"app"},n.createElement(sf,null),n.createElement("div",{className:"panel main"},n.createElement("div",{className:"panel left"},!this.isHttpError403&&n.createElement("div",{className:"sidebar-content"},n.createElement("div",{className:"top-bar-left-navigation"},n.createElement("div",{className:"navigation"},n.createElement("button",{type:"button",className:"button-transparent back",onClick:this.handleGoBack},n.createElement(ph,null)),n.createElement("span",{className:"title administration"},n.createElement(f.x6,null,"Organisation settings")))),n.createElement("div",{className:"sidebar-content-left"},n.createElement(wa,null)))),n.createElement("div",{className:"panel middle"},n.createElement("div",{className:"header"},!this.isHttpError403&&n.createElement(n.Fragment,null,n.createElement("div",{className:"header-left"}),n.createElement("div",{className:"header-right"},n.createElement(Cb,{isUserAdmin:!0,isUserWorkspaceVisible:!0,currentWorkspace:xb}),n.createElement(Zt,{baseUrl:this.props.context.trustedDomain||this.props.context.userSettings.getTrustedDomain(),user:this.props.context.loggedInUser})))),n.createElement("div",{className:"middle-right"},n.createElement("div",{className:"breadcrumbs-and-grid"},n.createElement("div",{className:"top-bar"},n.createElement(on,null)),n.createElement("div",{className:"main-page"},this.isHttpError403&&n.createElement(Od,{errorCode:403}),this.isHttpError404&&n.createElement(Od,{errorCode:404}),this.isHomePageSelected()&&n.createElement(db,null),this.isMfaSelected()&&n.createElement(en,null),this.isMfaPolicySelected()&&(this.isCommunityEdition()?n.createElement(Fc,null):n.createElement(Mc,null)),this.isPasswordPoliciesSelected()&&(this.isCommunityEdition()?n.createElement(ed,null):n.createElement(Xm,null)),this.isUserDirectorySelected()&&(this.isCommunityEdition()?n.createElement(vs,null):n.createElement(gs,null)),this.isEmailNotificationsSelected()&&n.createElement(Ps,null),this.isSubscriptionSelected()&&n.createElement(ti,null),this.isInternationalizationSelected()&&n.createElement(hi,null),this.isAccountRecoverySelected()&&(this.isCommunityEdition()?n.createElement(_r,null):n.createElement(wr,null)),this.isSmtpSettingsSelected()&&n.createElement(jo,null),this.isSelfRegistrationSelected()&&n.createElement(pl,null),this.isSsoSelected()&&(this.isCommunityEdition()?n.createElement(xc,null):n.createElement(kc,null)),this.isRbacSelected()&&n.createElement(jm,null),this.isUserPassphrasePoliciesSelected()&&(this.isCommunityEdition()?n.createElement(yd,null):n.createElement(hd,null)),this.isPasswordExpirySelected()&&n.createElement(Pd,null),this.isHealthcheckSelected()&&n.createElement(Ru,null),this.isContentTypesEncryptedMetadataSelected()&&n.createElement(mh,null),this.isContentTypesMetadataKeySelected()&&n.createElement(Nh,null),this.isMigrateMetadataSelected()&&n.createElement(rg,null),this.isAllowContentTypesSelected()&&n.createElement(Ag,null),this.isGetStartedMetadataSelected()&&n.createElement(Ab,null),this.isScimSelected()&&(this.isCommunityEdition()?n.createElement(Wb,null):n.createElement(Gb,null)),this.isSecretHistorySelected()&&n.createElement(Jb,null))),n.createElement(x.Switch,null,n.createElement(x.Route,{exact:!0,path:["/app/administration","/app/administration/scim-teasing","/app/administration/secret-history"]}),n.createElement(x.Route,null,n.createElement("div",{className:"help-panel"},n.createElement("div",{className:"sidebar-help",id:"administration-help-panel"}),n.createElement(gh,null)))))))))}}rf.propTypes={context:i().any,administrationWorkspaceContext:i().object,navigationContext:i().any};const of=N(Ke(Ne(rf)));class lf extends n.Component{constructor(e){super(e),this.initEventHandlers(),this.createReferences()}initEventHandlers(){this.handleCloseClick=this.handleCloseClick.bind(this),this.handleSignInClick=this.handleSignInClick.bind(this)}createReferences(){this.loginLinkRef=n.createRef()}handleCloseClick(){this.goToLogin()}handleSignInClick(){this.goToLogin()}goToLogin(){this.props.context.port.request("passbolt.tab.reload")}render(){return n.createElement(qt,{title:this.props.t("Session Expired"),onClose:this.handleCloseClick,className:"session-expired-dialog"},n.createElement("div",{className:"form-content"},n.createElement("p",null,n.createElement(f.x6,null,"Your session has expired, you need to sign in."))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement("a",{ref:this.loginLinkRef,onClick:this.handleSignInClick,className:"primary button form",target:"_parent",role:"button",rel:"noopener noreferrer"},n.createElement(f.x6,null,"Sign in"))))}}lf.propTypes={context:i().any,t:i().func};const cf=N((0,x.withRouter)((0,f.CI)("common")(lf)));class mf extends n.Component{constructor(e){super(e),this.bindCallbacks()}bindCallbacks(){this.handleSessionExpiredEvent=this.handleSessionExpiredEvent.bind(this)}componentDidMount(){this.props.context.onExpiredSession(this.handleSessionExpiredEvent)}handleSessionExpiredEvent(){this.props.dialogContext.closeAll(),this.props.dialogContext.open(cf)}render(){return n.createElement(n.Fragment,null)}}mf.propTypes={context:i().any,dialogContext:i().any};const df=N(h(mf));class uf extends n.Component{constructor(e){super(e),this.bindCallbacks()}bindCallbacks(){this.handleClose=this.handleClose.bind(this)}handleClose(){this.props.onClose()}render(){return n.createElement("div",{className:`${this.props.className} announcement`},n.createElement("div",{className:"announcement-content"},this.props.canClose&&n.createElement("button",{type:"button",className:"announcement-close dialog-close button-transparent",onClick:this.handleClose},n.createElement(Rt,{className:"svg-icon"}),n.createElement("span",{className:"visually-hidden"},n.createElement(f.x6,null,"Close"))),this.props.children))}}uf.propTypes={children:i().node,className:i().string,canClose:i().bool,onClose:i().func};const pf=(0,f.CI)("common")(uf);class hf extends n.Component{render(){return n.createElement(pf,{className:"subscription",onClose:this.props.onClose,canClose:!0},n.createElement("p",null,n.createElement(f.x6,null,"Warning:")," ",n.createElement(f.x6,null,"your subscription key will expire")," ",n.createElement("span",{title:this.props.expiry},Hs(this.props.expiry,this.props.t,this.props.context.locale)),".",n.createElement("button",{className:"link",type:"button",onClick:this.props.navigationContext.onGoToAdministrationSubscriptionRequested},n.createElement(f.x6,null,"Manage Subscription"))))}}hf.propTypes={context:i().any,expiry:i().string,navigationContext:i().any,onClose:i().func,t:i().func};const gf=N(Ke(tf((0,f.CI)("common")(hf))));class yf extends n.Component{render(){return n.createElement(pf,{className:"subscription",onClose:this.props.onClose,canClose:!1},n.createElement("p",null,n.createElement(f.x6,null,"Warning:")," ",n.createElement(f.x6,null,"your subscription requires your attention. The stability of the application is at risk."),n.createElement("button",{className:"link",type:"button",onClick:this.props.navigationContext.onGoToAdministrationSubscriptionRequested},n.createElement(f.x6,null,"Manage Subscription"))))}}yf.propTypes={navigationContext:i().any,onClose:i().func,i18n:i().any};const bf=Ke(tf((0,f.CI)("common")(yf)));class ff extends n.Component{render(){return n.createElement(pf,{className:"subscription",onClose:this.props.onClose,canClose:!1},n.createElement("p",null,n.createElement(f.x6,null,"Warning:")," ",n.createElement(f.x6,null,"your subscription key is not valid. The stability of the application is at risk."),n.createElement("button",{className:"link",type:"button",onClick:this.props.navigationContext.onGoToAdministrationSubscriptionRequested},n.createElement(f.x6,null,"Manage Subscription"))))}}ff.propTypes={navigationContext:i().any,onClose:i().func,i18n:i().any};const Ef=Ke(tf((0,f.CI)("common")(ff)));class vf extends n.Component{constructor(e){super(e),this.bindCallbacks()}bindCallbacks(){this.handleAnnouncementSubscriptionEvent=this.handleAnnouncementSubscriptionEvent.bind(this)}componentDidMount(){this.handleAnnouncementSubscriptionEvent()}componentDidUpdate(e){this.handleRefreshSubscriptionAnnouncement(e.context.refreshSubscriptionAnnouncement)}async handleRefreshSubscriptionAnnouncement(e){this.props.context.refreshSubscriptionAnnouncement!==e&&this.props.context.refreshSubscriptionAnnouncement&&(await this.handleAnnouncementSubscriptionEvent(),this.props.context.setContext({refreshSubscriptionAnnouncement:null}))}async handleAnnouncementSubscriptionEvent(){this.hideSubscriptionAnnouncement();try{const e=await this.props.context.onGetSubscriptionKeyRequested();this.isSubscriptionGoingToExpire(e.expiry)&&this.props.announcementContext.show(gf,{expiry:e.expiry})}catch(e){"PassboltSubscriptionError"===e.name?this.props.announcementContext.show(bf):this.props.announcementContext.show(Ef)}}hideSubscriptionAnnouncement(){const e=[gf,bf,Ef];this.props.announcementContext.announcements.forEach(t=>{e.some(e=>e===t.Announcement)&&this.props.announcementContext.close(t.key)})}isSubscriptionGoingToExpire(e){return Ds.c9.fromISO(e)e.startsWith("csrfToken"))?.split("=");return e&&2===e.length?e[1]:null}const e=this.baseUrl.toString(),t="/"===e.slice(-1)?e:`${e}/`,a=await browser.cookies.get({name:"csrfToken",url:t});return a?.value||null}}class _f extends Error{constructor(e,t={}){super(e),this.name="PassboltSubscriptionError",this.subscription=t}}const xf=_f,Sf=class{constructor(e){e.setResourceName("auth"),this.apiClient=new pt(e)}async logout(){const e=this.apiClient.buildUrl(`${this.apiClient.baseUrl}/logout`,{}),t=await this.apiClient.sendRequest("POST",e,null,{redirect:"manual"});if(!t.ok&&0!==t.status)return this._logoutLegacy()}async _logoutLegacy(){const e=this.apiClient.buildUrl(`${this.apiClient.baseUrl}/logout`,{}),t=await this.apiClient.sendRequest("GET",e,null,{redirect:"manual"});if(!t.ok&&0!==t.status)throw new ot("An unexpected error happened during the legacy logout process",{code:t.status})}};class Cf extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.authLogoutService=new Sf(this.getApiClientOptions())}async componentDidMount(){await this.getLoggedInUser();const e=await this.getSiteSettings();await this.getRbacs(e),this.initLocale(),this.removeSplashScreen();const t=document.querySelector(".temporary.skeleton");t&&t.remove()}componentWillUnmount(){clearTimeout(this.scheduledCheckIsAuthenticatedTimeout)}get defaultState(){return{name:"api",loggedInUser:null,rbacs:null,siteSettings:null,trustedDomain:this.baseUrl,basename:new URL(this.baseUrl).pathname,getApiClientOptions:this.getApiClientOptions.bind(this),locale:null,displayTestUserDirectoryDialogProps:{userDirectoryTestResult:null},setContext:e=>{this.setState(e)},onLogoutRequested:()=>this.onLogoutRequested(),onCheckIsAuthenticatedRequested:()=>this.onCheckIsAuthenticatedRequested(),onExpiredSession:this.onExpiredSession.bind(this),onGetSubscriptionKeyRequested:()=>this.onGetSubscriptionKeyRequested(),onRefreshLocaleRequested:this.onRefreshLocaleRequested.bind(this)}}get isReady(){return null!==this.state.loggedInUser&&null!==this.state.rbacs&&null!==this.state.siteSettings&&null!==this.state.locale}get baseUrl(){const e=document.getElementsByTagName("base")&&document.getElementsByTagName("base")[0];return e?e.attributes.href.value.replace(/\/*$/g,""):(console.error("Unable to retrieve the page base tag"),"")}getApiClientOptions(){return(new kf).setBaseUrl(this.state.trustedDomain)}async getLoggedInUser(){const e=this.getApiClientOptions().setResourceName("users"),t=new pt(e),a=(await t.get("me",{"contain[account_recovery_user_setting]":"1"})).body;this.setState({loggedInUser:a})}async getRbacs(e){if(!e.canIUse("rbacs"))return void this.setState({rbacs:new Wc});const t=this.getApiClientOptions(),a=new Hc(t),n=(await a.findMe({ui_action:!0,action:!0})).body,s=new Wc(n,!0);this.setState({rbacs:s})}async getSiteSettings(){const e=this.getApiClientOptions().setResourceName("settings"),t=new pt(e),a=await t.findAll(),n=new er(a.body);return this.setState({siteSettings:n}),n}async initLocale(){const e=await this.getUserLocale();if(e)return this.setState({locale:e.locale});const t=this.state.siteSettings.locale;return this.setState({locale:t})}async getUserLocale(){const e=(await this.getUserSettings()).find(e=>"locale"===e.property);if(e)return this.state.siteSettings.supportedLocales.find(t=>t.locale===e.value)}async getUserSettings(){const e=this.getApiClientOptions().setResourceName("account/settings"),t=new pt(e);return(await t.findAll()).body}removeSplashScreen(){document.getElementsByTagName("html")[0].classList.remove("launching")}async onLogoutRequested(){await this.authLogoutService.logout(),window.location.href=this.state.trustedDomain}async onCheckIsAuthenticatedRequested(){try{const e=this.getApiClientOptions().setResourceName("auth"),t=new pt(e);return await t.get("is-authenticated"),!0}catch(e){if(e instanceof ot&&401===e.data.code)return!1;throw e}}onExpiredSession(e){this.scheduledCheckIsAuthenticatedTimeout=setTimeout(async()=>{await this.onCheckIsAuthenticatedRequested()?this.onExpiredSession(e):e()},6e4)}async onGetSubscriptionKeyRequested(){try{const e=this.getApiClientOptions().setResourceName("ee/subscription"),t=new pt(e);return(await t.get("key")).body}catch(e){if(e instanceof ot&&e.data&&402===e.data.code){const t=e.data.body;throw new xf(e.message,t)}throw e}}onRefreshLocaleRequested(e){this.state.siteSettings.setLocale(e),this.initLocale()}render(){return n.createElement(T.Provider,{value:this.state},this.isReady&&this.props.children)}}Cf.propTypes={children:i().any};const Nf=Cf;var Tf=a(2635),Af=a(1347);class If extends n.Component{constructor(e){super(e),this.state=this.defaultState}get defaultState(){return{ready:!1}}async componentDidMount(){await(0,Tf.Yx)(f.r9).use(Af.A).init({lng:this.locale,load:"currentOnly",interpolation:{escapeValue:!1},react:{useSuspense:!1},backend:{loadPath:(e,t)=>this.getTranslationPath(e,t)},supportedLngs:this.supportedLocales,fallbackLng:!1,ns:["common"],defaultNS:"common",keySeparator:!1,nsSeparator:!1,debug:!1}),this.setState({ready:!0})}getTranslationPath(e,t){const a=e[0],n=t[0],s="en-GB"===a?"en-UK":a;return(this.props.loadingPath||"/locales/{{lng}}/{{ns}}.json").replace("{{lng}}",s).replace("{{ns}}",n)}get supportedLocales(){let e=[];return this.props.context.siteSettings?.supportedLocales?e=this.props.context.siteSettings?.supportedLocales.map(e=>e.locale):e.push(this.locale),e.includes("en-UK")&&e.push("en-GB"),e}get locale(){return this.props.context.locale}async componentDidUpdate(e){await this.handleLocaleChange(e.context.locale)}async handleLocaleChange(e){this.locale!==e&&await(0,Tf.v2)(this.locale)}get isReady(){return this.state.ready}render(){return n.createElement(n.Fragment,null,this.isReady&&this.props.children)}}If.propTypes={context:i().any,loadingPath:i().any,children:i().any};const Rf=N(If);class Pf{constructor(){this.baseUrl=this.getBaseUrl()}async getOrganizationAccountRecoverySettings(){const e=this.getApiClientOptions().setResourceName("account-recovery/organization-policies"),t=new pt(e);return(await t.findAll()).body}getBaseUrl(){const e=document.getElementsByTagName("base")&&document.getElementsByTagName("base")[0];return e?e.attributes.href.value.replace(/\/*$/g,""):(console.error("Unable to retrieve the page base tag"),"")}getApiClientOptions(){return(new kf).setBaseUrl(this.baseUrl)}getCsrfToken(){const e=document.cookie;if(!e)return;const t=e.split("; ");if(!t)return;const a=t.find(e=>e.startsWith("csrfToken"));if(!a)return;const n=a.split("=");return n&&2===n.length?n[1]:void 0}}class Df extends n.Component{render(){const e=new Pf;return n.createElement(Nf,null,n.createElement(T.Consumer,null,t=>n.createElement(Rf,{loadingPath:`${t.trustedDomain}/locales/{{lng}}/{{ns}}.json`},n.createElement(ve,null,n.createElement(We,{accountRecoveryUserService:e},n.createElement(vt,null,n.createElement(c,null,n.createElement(p,null,n.createElement(ef,null,n.createElement(b,null,n.createElement(k,null),n.createElement(df,null),t.loggedInUser&&"admin"===t.loggedInUser.role.name&&t.siteSettings.canIUse("ee")&&n.createElement(wf,null),n.createElement(_.Kd,{basename:t.basename},n.createElement(ze,null,n.createElement(x.Switch,null,n.createElement(x.Route,{exact:!0,path:["/app/administration/subscription","/app/administration/account-recovery","/app/administration/password-policies","/app/administration/user-passphrase-policies","/app/administration/password-expiry","/app/administration/content-types/metadata","/app/administration/content-types/metadata-key","/app/administration/content-types/metadata-getting-started","/app/administration/subscription-teasing","/app/administration/account-recovery-teasing","/app/administration/password-policies-teasing","/app/administration/user-passphrase-policies-teasing","/app/administration/scim-teasing","/app/administration/secret-history"]}),n.createElement(x.Route,{path:"/app/administration"},n.createElement(Se,null,n.createElement(bo,null,n.createElement(Fe,null),n.createElement(Mn,null,n.createElement(Jo,null,n.createElement(Oe,null),n.createElement(Ua,null,n.createElement(Ic,null,n.createElement(Ns,null,n.createElement(ci,null,n.createElement(Jc,null,n.createElement(cu,null,n.createElement(ha,{service:new ca(t.getApiClientOptions())},n.createElement(of,null))))))))))))))))))))))))))}}const Of=Df;var Mf=a(5338);const Uf=document.createElement("div");document.body.appendChild(Uf),(0,Mf.H)(Uf).render(n.createElement(Of,null))}},s={};function i(e){var t=s[e];if(void 0!==t)return t.exports;var a=s[e]={exports:{}};return n[e].call(a.exports,a,a.exports,i),a.exports}i.m=n,e=[],i.O=(t,a,n,s)=>{if(!a){var r=1/0;for(m=0;m=s)&&Object.keys(i.O).every(e=>i.O[e](a[l]))?a.splice(l--,1):(o=!1,s0&&e[m-1][2]>s;m--)e[m]=e[m-1];e[m]=[a,n,s]},i.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return i.d(t,{a:t}),t},a=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,i.t=function(e,n){if(1&n&&(e=this(e)),8&n)return e;if("object"==typeof e&&e){if(4&n&&e.__esModule)return e;if(16&n&&"function"==typeof e.then)return e}var s=Object.create(null);i.r(s);var r={};t=t||[null,a({}),a([]),a(a)];for(var o=2&n&&e;("object"==typeof o||"function"==typeof o)&&!~t.indexOf(o);o=a(o))Object.getOwnPropertyNames(o).forEach(t=>r[t]=()=>e[t]);return r.default=()=>e,i.d(s,r),s},i.d=(e,t)=>{for(var a in t)i.o(t,a)&&!i.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:t[a]})},i.e=()=>Promise.resolve(),i.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),i.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),i.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.j=815,(()=>{var e={815:0};i.O.j=t=>0===e[t];var t=(t,a)=>{var n,s,[r,o,l]=a,c=0;if(r.some(t=>0!==e[t])){for(n in o)i.o(o,n)&&(i.m[n]=o[n]);if(l)var m=l(i)}for(t&&t(a);ci(3652));r=i.O(r)})(); \ No newline at end of file +(()=>{"use strict";var e,t,a,n={3652(e,t,a){var n=a(6540),s=a(5556),i=a.n(s),r=a(4296);function o(){return o=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},displayWarning:()=>{},displayError:()=>{},remove:()=>{}});class c extends n.Component{constructor(e){super(e),this.state=this.defaultState}get defaultState(){return{feedbacks:[],displaySuccess:this.displaySuccess.bind(this),displayWarning:this.displayWarning.bind(this),displayError:this.displayError.bind(this),remove:this.remove.bind(this)}}displaySuccess(e){this.setState({feedbacks:[...this.state.feedbacks,{id:(0,r.A)(),type:"success",message:e}]})}displayWarning(e){this.setState({feedbacks:[...this.state.feedbacks,{id:(0,r.A)(),type:"warning",message:e}]})}displayError(e){this.setState({feedbacks:[...this.state.feedbacks,{id:(0,r.A)(),type:"error",message:e}]})}remove(e){this.setState(t=>({feedbacks:t.feedbacks.filter(t=>e.id!==t.id)}))}render(){return n.createElement(l.Provider,{value:this.state},this.props.children)}}function m(e){return class extends n.Component{render(){return n.createElement(l.Consumer,null,t=>n.createElement(e,o({actionFeedbackContext:t},this.props)))}}}function d(){return d=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},close:()=>{}});class p extends n.Component{constructor(e){super(e),this.state=this.defaultState}get defaultState(){return{dialogs:[],open:(e,t)=>{const a=(0,r.A)();return this.setState(n=>({dialogs:[...n.dialogs,{key:a,Dialog:e,DialogProps:t}]})),a},close:e=>{this.setState(t=>({dialogs:t.dialogs.filter(t=>e!==t.key)}))},closeAll:()=>this.setState({dialogs:[]})}}render(){return n.createElement(u.Provider,{value:this.state},this.props.children)}}function h(e){return class extends n.Component{render(){return n.createElement(u.Consumer,null,t=>n.createElement(e,d({dialogContext:t},this.props)))}}}function g(){return g=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},hide:()=>{}});class b extends n.Component{constructor(e){super(e),this.state=this.defaultState}get defaultState(){return{contextualMenus:[],show:(e,t)=>this.setState({contextualMenus:[...this.state.contextualMenus,{ContextualMenuComponent:e,componentProps:t}]}),hide:e=>this.setState({contextualMenus:this.state.contextualMenus.filter((t,a)=>a!==e)})}}render(){return n.createElement(y.Provider,{value:this.state},this.props.children)}}b.displayName="ContextualMenuContextProvider",b.propTypes={children:i().any};var f=a(2389);class E extends n.Component{static get DEFAULT_WAIT_TO_CLOSE_TIME_IN_MS(){return 500}constructor(e){super(e),this.state=this.defaultState,this.bindCallbacks()}get defaultState(){return{shouldRender:!0,isPersisted:!1,timeoutId:null}}componentDidMount(){this.displayWithTimer(this.props.displayTimeInMs)}componentDidUpdate(e){const t=e&&e.feedback.id!==this.props.feedback.id,a=e&&this.props.displayTimeInMs&&e.displayTimeInMs!==this.props.displayTimeInMs;t?(this.setState({shouldRender:!0}),this.displayWithTimer(this.props.displayTimeInMs)):a&&this.updateTimer(this.props.displayTimeInMs)}componentWillUnmount(){this.state.timeoutId&&clearTimeout(this.state.timeoutId)}bindCallbacks(){this.persist=this.persist.bind(this),this.displayWithTimer=this.displayWithTimer.bind(this),this.close=this.close.bind(this)}displayWithTimer(e){this.state.timeoutId&&clearTimeout(this.state.timeoutId);const t=setTimeout(this.close,e),a=Date.now();this.setState({timeoutId:t,time:a})}updateTimer(e){const t=e-(Date.now()-this.state.time);t>0?this.displayWithTimer(t):(clearTimeout(this.state.timeoutId),this.close())}persist(){this.state.timeoutId&&!this.state.isPersisted&&(clearTimeout(this.state.timeoutId),this.setState({isPersisted:!0}))}close(){this.setState({shouldRender:!1}),setTimeout(this.props.onClose,E.DEFAULT_WAIT_TO_CLOSE_TIME_IN_MS)}render(){return n.createElement("div",{className:"notification",onMouseOver:this.persist,onMouseLeave:this.displayWithTimer,onClick:this.close},n.createElement("div",{className:`message animated ${this.state.shouldRender?"fadeInUp":"fadeOutUp"} ${this.props.feedback.type}`},n.createElement("span",{className:"content"},n.createElement("strong",null,"success"===this.props.feedback.type&&n.createElement(n.Fragment,null,n.createElement(f.x6,null,"Success"),":"," "),"error"===this.props.feedback.type&&n.createElement(n.Fragment,null,n.createElement(f.x6,null,"Error"),":"," "),"warning"===this.props.feedback.type&&n.createElement(n.Fragment,null,n.createElement(f.x6,null,"Warning"),":"," ")),this.props.feedback.message)))}}E.propTypes={feedback:i().object,onClose:i().func,displayTimeInMs:i().number};const v=(0,f.CI)("common")(E);class w extends n.Component{constructor(e){super(e),this.bindCallbacks()}static get DEFAULT_DISPLAY_TIME_IN_MS(){return 5e3}static get DEFAULT_DISPLAY_MIN_TIME_IN_MS(){return 1200}bindCallbacks(){this.close=this.close.bind(this)}get feedbackToDisplay(){return this.props.actionFeedbackContext.feedbacks[0]}get length(){return this.props.actionFeedbackContext.feedbacks.length}get hasFeedbacks(){return this.length>0}async close(e){await this.props.actionFeedbackContext.remove(e)}render(){const e=this.length>1?w.DEFAULT_DISPLAY_MIN_TIME_IN_MS:w.DEFAULT_DISPLAY_TIME_IN_MS;return n.createElement(n.Fragment,null,this.hasFeedbacks&&n.createElement("div",{className:"notification-container"},n.createElement(v,{feedback:this.feedbackToDisplay,onClose:()=>this.close(this.feedbackToDisplay),displayTimeInMs:e})))}}w.propTypes={actionFeedbackContext:i().any};const k=m(w);var _=a(4625),x=a(6347);function S(){return S=Object.assign?Object.assign.bind():function(e){for(var t=1;tn.createElement(e,S({context:t},this.props)))}}}const T=C;function A(){return A=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},remove:()=>{}});class R extends n.Component{constructor(e){super(e),this.state=this.defaultState}get defaultState(){return{counter:0,add:()=>{this.setState(e=>({counter:e.counter+1}))},remove:()=>{this.setState(e=>({counter:Math.min(e.counter-1,0)}))}}}render(){return n.createElement(I.Provider,{value:this.state},this.props.children)}}R.propTypes={children:i().any};class P{}class D extends P{static execute(){return!0}}class O extends P{static execute(){return!1}}const M="Folders.use",U="Users.viewWorkspace",F="Administration.viewWorkspace",j="GroupsAdd.addPost",L="AccountRecoveryRequestsView.view",q="AccountRecoveryRequestsIndex.index",z="AccountRecoveryResponsesCreate.post",K="Allow",V="Deny",G="AllowIfGroupManagerInOneGroup",B={[K]:D,[V]:O,[G]:class extends P{static execute(e){return e.groups_users.some(e=>e.is_admin)}}},W={[M]:B[K]},H={[F]:B[V],[j]:B[V],[L]:B[V],[q]:B[V],[z]:B[V]};class ${static getByRbac(e){return B[e.controlFunction]||(console.warn(`Could not find control function for the given rbac entity (${e.id})`),O)}static getDefaultForAdminAndAction(e){return W[e]||D}static getDefaultForUserAndAction(e){return H[e]||D}}class Y extends Error{constructor(e="Collection validation error."){super(e),this.name="CollectionValidationError",this.errors=[]}addItemValidationError(e,t){if(!Number.isInteger(e))throw new TypeError('CollectionValidationError::addEntityValidationError expects "position" to be an integer.');if(!(t instanceof X||t instanceof Y))throw new TypeError('CollectionValidationError::addEntityValidationError expects "entityValidationError" to be an instance of EntityValidationError or CollectionValidationError.');this.errors[e]=t}addCollectionValidationError(e,t){if("string"!=typeof e)throw new TypeError('CollectionValidationError::addCollectionValidationError expects "rule" to be a string.');if("string"!=typeof t)throw new TypeError('CollectionValidationError::addCollectionValidationError expects "error" to be a string.');this.errors[e]=t}hasErrors(){return this.errors.some(e=>Object.keys(e.details).length>0)}get details(){const e={};for(const t in this.errors)this.errors[t]instanceof X||this.errors[t]instanceof Y?e[t]=this.errors[t].details:e[t]=this.errors[t];return e}}const Z=Y;class J extends Error{constructor(e="Entity validation error."){super(e),this.name="EntityValidationError",this.details={}}addError(e,t,a){if("string"!=typeof e)throw new TypeError("EntityValidationError addError property should be a string.");if("string"!=typeof t)throw new TypeError("EntityValidationError addError rule should be a string.");if("string"!=typeof a)throw new TypeError("EntityValidationError addError message should be a string.");Object.prototype.hasOwnProperty.call(this.details,e)||(this.details[e]={}),this.details[e][t]=a}addAssociationError(e,t){if("string"!=typeof e)throw new TypeError("EntityValidationError addAssociationError associationName should be a string.");if(!(t instanceof J||t instanceof Z))throw new TypeError("EntityValidationError addAssociationError errorDetails should be an object.");this.details[e]=t}getError(e,t){if(!this.hasError(e,t))return null;const a=this.details[e];return t?a[t]:a}hasError(e,t){if("string"!=typeof e)throw new TypeError("EntityValidationError hasError property should be a string.");const a=this.details&&Object.prototype.hasOwnProperty.call(this.details,e);if(!a)return!1;if(!t)return a;if("string"!=typeof t)throw new TypeError("EntityValidationError hasError rule should be a string.");return Object.prototype.hasOwnProperty.call(this.details[e],t)}hasErrors(){return Object.keys(this.details).length>0}getFirstRuleErrorByField(e){if(!this.hasError(e))return null;const t=this.details[e];return t[Object.keys(t)[0]]}}const X=J;var Q=a(7761),ee=a.n(Q);class te{static validateSchema(e,t){if(!t)throw new TypeError(`Could not validate entity ${e}. No schema for entity ${e}.`);if(!t.type)throw new TypeError(`Could not validate entity ${e}. Type missing.`);if("array"!==t.type){if("object"===t.type){if(!t.required||!Array.isArray(t.required))throw new TypeError(`Could not validate entity ${e}. Schema error: no required properties.`);if(!t.properties||!Object.keys(t).length)throw new TypeError(`Could not validate entity ${e}. Schema error: no properties.`);const a=t.properties;for(const e in a){if(!Object.prototype.hasOwnProperty.call(a,e)||!a[e].type&&!a[e].anyOf)throw TypeError(`Invalid schema. Type missing for ${e}...`);if(a[e].anyOf&&(!Array.isArray(a[e].anyOf)||!a[e].anyOf.length))throw new TypeError(`Invalid schema, prop ${e} anyOf should be an array`)}}}else if(!t.items)throw new TypeError(`Could not validate entity ${e}. Schema error: missing item definition.`)}static validate(e,t,a){if(!e||!t||!a)throw new TypeError(`Could not validate entity ${e}. No data provided.`);switch(a.type){case"object":return te.validateObject(e,t,a);case"array":return te.validateArray(e,t,a);default:throw new TypeError(`Could not validate entity ${e}. Unsupported type.`)}}static validateArray(e,t,a){let n;const s=te.validateProp("items",t,a);if("number"==typeof a.minItems&&(te.isGreaterThanOrEqual(t.length,a.minItems)||(n=te.handleCollectionValidationError("minItems",`The items array should contain at least ${a.minItems} item(s).`,n))),"number"==typeof a.maxItems&&(te.isLessThanOrEqual(t.length,a.maxItems)||(n=te.handleCollectionValidationError("maxItems",`The items array should contain at maximum ${a.maxItems} item(s).`,n))),n)throw n;return s}static validateObject(e,t,a){const n=a.required,s=a.properties,i={};let r;for(const a in s)if(Object.prototype.hasOwnProperty.call(s,a))if(null!==t?.[a]||!0!==s[a]?.nullable){if(n.includes(a)){if(!Object.prototype.hasOwnProperty.call(t,a)){r=te.getOrInitEntityValidationError(e,r),r.addError(a,"required",`The ${a} is required.`);continue}}else if(!Object.prototype.hasOwnProperty.call(t,a))continue;try{i[a]=te.validateProp(a,t[a],s[a])}catch(t){if(!(t instanceof X))throw t;r=te.getOrInitEntityValidationError(e,r),r.details[a]=t.details[a]}}else i[a]=null;if(r)throw r;return i}static getOrInitEntityValidationError(e,t){return t||new X(`Could not validate entity ${e}.`)}static validateProp(e,t,a){if(a.anyOf)return te.validateAnyOf(e,t,a.anyOf),t;if(!0===a.nullable&&null===t)return t;if(te.validatePropType(e,t,a),a.enum)return te.validatePropEnum(e,t,a),t;switch(a.type){case"string":te.validatePropTypeString(e,t,a);break;case"integer":case"number":te.validatePropTypeNumber(e,t,a);break;case"array":te.validatePropTypeArray(e,t,a);break;case"object":case"boolean":case"blob":case"null":break;case"x-custom":te.validatePropCustom(e,t,a);break;default:throw new TypeError(`Could not validate property ${e}. Unsupported prop type ${a.type}`)}return t}static validatePropType(e,t,a){if(!te.isValidPropType(t,a.type))throw te.handlePropertyValidationError(e,"type",`The ${e} is not a valid ${a.type}.`)}static validatePropCustom(e,t,a){try{a.validationCallback(t)}catch(t){throw te.handlePropertyValidationError(e,"custom",`The ${e} is not valid: ${t.message}`)}}static validatePropTypeString(e,t,a){let n;if(a.format&&(te.isValidStringFormat(t,a.format)||(n=te.handlePropertyValidationError(e,"format",`The ${e} is not a valid ${a.format}.`,n))),a.length&&(te.isValidStringLength(t,a.length,a.length)||(n=te.handlePropertyValidationError(e,"length",`The ${e} should be ${a.length} character in length.`,n))),a.minLength&&(te.isValidStringLength(t,a.minLength)||(n=te.handlePropertyValidationError(e,"minLength",`The ${e} should be ${a.minLength} character in length minimum.`,n))),a.maxLength&&(te.isValidStringLength(t,0,a.maxLength)||(n=te.handlePropertyValidationError(e,"maxLength",`The ${e} should be ${a.maxLength} character in length maximum.`,n))),a.pattern&&(ee().matches(t,a.pattern)||(n=te.handlePropertyValidationError(e,"pattern",`The ${e} is not valid.`,n))),a.custom&&(a.custom(t)||(n=te.handlePropertyValidationError(e,"custom",`The ${e} is not valid.`,n))),n)throw n}static handlePropertyValidationError(e,t,a,n=null){return(n=n||new X(`Could not validate property ${e}.`)).addError(e,t,a),n}static handleCollectionValidationError(e,t,a=null){return(a=a||new Z("Could not validate collection.")).addCollectionValidationError(e,t),a}static validatePropTypeNumber(e,t,a){let n;if("number"==typeof a.minimum&&(te.isGreaterThanOrEqual(t,a.minimum)||(n=te.handlePropertyValidationError(e,"minimum",`The ${e} should be greater or equal to ${a.minimum}.`,n))),"number"==typeof a.maximum&&(te.isLesserThanOrEqual(t,a.maximum)||(n=te.handlePropertyValidationError(e,"maximum",`The ${e} should be lesser or equal to ${a.maximum}.`,n))),n)throw n}static validatePropTypeArray(e,t,a){let n;if(a?.items&&"object"==typeof a.items){for(let s=0;s=t}static isLessThanOrEqual(e,t){return e<=t}static isLesserThanOrEqual(e,t){return e<=t}}const ae=te;class ne{constructor(e,t={}){(t?.clone??!0)&&(e=JSON.parse(JSON.stringify(e))),this._props=e}toDto(){return JSON.parse(JSON.stringify(this))}toJSON(){return this._props}_hasProp(e){if(!e.includes(".")){const t=ne._normalizePropName(e);return Object.prototype.hasOwnProperty.call(this._props,t)}try{return this._getPropByPath(e),!0}catch(t){return console.error(`Failed to check if property "${e}" is set:`,t),!1}}_getPropByPath(e){return ne._normalizePropName(e).split(".").reduce((e,t)=>{if(Object.prototype.hasOwnProperty.call(e,t))return e[t];throw new Error},this._props)}static _normalizePropName(e){return e.replace(/([A-Z])/g,(e,t)=>`_${t.toLowerCase()}`).replace(/\._/,".").replace(/^_/,"").replace(/^\./,"")}}const se=ne;var ie=a(5648);const re=e=>e?.replace(/_([a-z])/g,(e,t)=>t.toUpperCase()),oe=e=>e?e.charAt(0).toLocaleUpperCase()+e.slice(1):e;class le extends Error{constructor(e,t,a){if(super(a=a||"Entity collection error."),"number"!=typeof e)throw new TypeError("EntityCollectionError requires a valid position");if(!t||"string"!=typeof t)throw new TypeError("EntityCollectionError requires a valid rule");if(!a||"string"!=typeof a)throw new TypeError("EntityCollectionError requires a valid message");this.position=e,this.rule=t}}const ce=le;class me{constructor(e=[],t={}){const a=t?.clone??!0;this._items=[],a&&(e=JSON.parse(JSON.stringify(e))),this._props=e}toDto(){return JSON.parse(JSON.stringify(this._items))}toJSON(){return this.toDto()}get items(){return this._items}get length(){return this._items.length}[Symbol.iterator](){let e=0;return{next:()=>eObject.prototype.hasOwnProperty.call(a._props,e)&&a._props[e]===t)}getFirst(e,t){if("string"!=typeof e||"string"!=typeof t)throw new TypeError("EntityCollection getFirst by expect propName and search to be strings");const a=this.getAll(e,t);if(a&&a.length)return a[0]}extract(e){if("string"!=typeof e)throw new TypeError("EntityCollection extract expects propName to be a string.");return this._items.reduce((t,a)=>(void 0!==a._props[e]&&t.push(a._props[e]),t),[])}push(e){return this._items.push(e),this._items.length}unshift(e){return this._items.unshift(e),this._items.length}filterByPropertyValueIn(e,t,a=!0){if("string"!=typeof e)throw new TypeError("EntityCollection filterByPropertyValueIn expects propName to be a string.");if(!Array.isArray(t))throw new TypeError("EntityCollection filterByPropertyValueIn expects needles to be an array.");this.filterByCallback(n=>{const s=Object.prototype.hasOwnProperty.call(n._props,e);return!(a&&!s||s&&!t.includes(n._props[e]))})}filterByCallback(e){if("function"!=typeof e)throw new TypeError("EntityCollection filterByCallback expects callback to be a function.");for(let t=this._items.length-1;t>=0;t--)e(this._items[t])||this._items.splice(t,1)}assertUniqueByProperty(e,t){const a=`unique_${e}`,n=this.extract(e),s=new Set;t=t||`The collection should only contain items with unique values for the property: ${e}.`,n.forEach((e,n)=>{if(s.add(e),n!==s.size-1)throw new ce(n,a,t)})}assertNotExist(e,t,a={}){if(void 0===t)return;let n=a?.haystackSet;if(!n){const t=this.extract(e);n=new Set(t)}if(n.has(t)){const t=new X,n=a?.message||`The collection already includes an element that has a property (${e}) with an identical value.`;throw t.addError(e,"unique",n),t}}}const de=me,ue=["string","number","integer","boolean"];class pe extends se{static _cachedSchema={};constructor(e={},t={}){const a=t?.validate??!0;super(e,t),this.marshall(),a&&this.validateSchema({schema:t?.schema,skipSchemaAssociationValidation:t?.skipSchemaAssociationValidation}),this.createAssociations(t),a&&this.validateBuildRules(t?.validateBuildRules)}marshall(){}validate(e={}){try{this.validateSchema({schema:e?.schema,skipSchemaAssociationValidation:e?.skipSchemaAssociationValidation}),this.validateBuildRules(e?.validateBuildRules),this.validateAssociations(e)}catch(e){if(!(e instanceof X))throw e;return e}return null}validateSchema(e=null){let t=e?.schema??this.cachedSchema;if(e?.skipSchemaAssociationValidation){t={...t};const e=Object.keys(this.constructor.associations),a=t.required.filter(t=>!e.includes(t));t.required=a}this._props=ae.validate(this.constructor.name,this._props,t)}get cachedSchema(){return this.constructor._cachedSchema[this.constructor.name]||(this.constructor._cachedSchema[this.constructor.name]=this.constructor.getSchema()),this.constructor._cachedSchema[this.constructor.name]}static getSchema(){throw new Error("The entity class should declare its schema.")}validateBuildRules(e={}){}createAssociations(e={}){if(Object.keys(this.constructor.associations).length>0){const t=new X;for(const[a,n]of Object.entries(this.constructor.associations))try{this._props[a]&&(this[`_${re(a)}`]=new n(this._props[a],{...e,clone:!1}),delete this._props[a])}catch(e){if(!(e instanceof X))throw e;t.addAssociationError(a,e)}if(t.hasErrors())throw t}}static get associations(){return{}}get(e){(0,ie.A)(e);const t=this.constructor.getSchema().properties[e];if(!t)throw new Error(`The property "${e}" has no schema definition.`);if(!ue.includes(t?.type))throw new Error('The property "associated_entity" should reference scalar properties only.');return this._props[e]}set(e,t,a={}){(0,ie.A)(e);const n=a?.validate??!0;if(this.isAssociation(e))this.setAssociation(e,t,a);else{const s=e.split(".")[0],i=this.constructor.getSchema().properties[s];if(!i)throw new Error(`The property "${s}" has no schema definition.`);if("array"===i?.type)this.setArrayProp(e,t,a);else{if(i?.type&&!ue.includes(i?.type))throw new Error('The property "associated_entity" should reference scalar properties only.');if(i?.anyOf?.some(e=>!ue.includes(e.type)))throw new Error('The property "associated_entity" should reference scalar properties only.');n&&ae.validateProp(s,t,i),this._props[s]=t}}}setArrayProp(e,t,a){(0,ie.A)(e);const n=e.split("."),s=n[0];let i=null;const r=this.constructor.getSchema().properties[s],o=a?.validate??!0;if(2!==n.length)throw new Error(`The property "${n[0]}" has no index passed.`);{const e=n[1].match(/^(\d+)$/);if(!e)throw new Error(`The property "${n[0]}" has an invalid index format. Expected format: digits.`);i=parseInt(e[1],10)}if(!ue.includes(r.items.type))throw new Error('The property "associated_entity" with array type should reference scalar properties only.');o&&ae.validateProp(s,t,r.items),this._props[s]||(this._props[s]=[]),null!=t?this._props[s][i]=t:this._props[s].splice(i,1)}setCollection(e,t,a){(0,ie.A)(e);const n=e.split("."),s=n[0];let i=null;if(1===n.length)t instanceof this.constructor.associations[e]?this[`_${s}`]=t:this[`_${s}`]=new this.constructor.associations[e](t,a);else{if(!(n.length>1))throw new Error(`The property "${n[0]}" has no index passed.`);{const e=n[1].match(/^(\d+)$/);if(!e)throw new Error(`The property "${n[0]}" has an invalid index format. Expected format: digits.`);i=parseInt(e[1],10)}}if(!this[`_${s}`])throw new Error(`The collection "${n[0]}" has no item".`);if(null!=t)if(n.length>2){if(!this[`_${s}`]._items[i])throw new Error(`The collection "${n[0]}" has no item at the index "${n[1]}".`);const e=n.slice(2).join(".");this[`_${s}`]._items[i].set(e,t,a)}else this[`_${s}`].push(t,a,a);else this[`_${s}`].items.splice(i,1)}setAssociation(e,t,a={}){if((0,ie.A)(e),this.isAssociation(e)){const n=e.split("."),s=re(n[0]);if(n.length>1)if(this[`_${s}`]||(this[`_${s}`]=new this.constructor.associations[n[0]]({},{validate:!1})),this[`_${s}`]instanceof de){const e=n.toSpliced(0,1,s).join(".");this.setCollection(e,t,a)}else{const e=n.slice(1).join(".");this[`_${s}`].set(e,t,a)}else t instanceof this.constructor.associations[e]?this[`_${s}`]=t:this[`_${s}`]=new this.constructor.associations[e](t,a)}}validateAssociations(e={}){const t=new X;if(Object.keys(this.constructor.associations).length>0&&Object.keys(this.constructor.associations).forEach(a=>{const n=re(a);if(this[`_${n}`]){const s=this[n].validate(e);s&&t.addAssociationError(a,s)}}),t.hasErrors())throw t}diffProps(e){if(!(e instanceof pe))throw new TypeError('The property "compareEntity" should be of "EntityV2" type.');const t={},a=this.constructor.getSchema(),n=Object.keys(a.properties).filter(e=>ue.includes(a.properties[e].type));for(const a of n){const n=this.get(a),s=e.get(a);n!==s&&(t[a]=s)}return t}hasDiffProps(e){const t=this.diffProps(e);return Object.keys(t).length>0}isAssociation(e){const t=e.split(".")[0];return Boolean(this.constructor.associations?.[t])}}const he=pe;class ge extends he{static getSchema(){return{type:"object",required:["name"],properties:{id:{type:"string",format:"uuid"},name:{type:"string",minLength:1,maxLength:50},description:{type:"string",maxLength:255,nullable:!0},created:{type:"string",format:"date-time"},modified:{type:"string",format:"date-time"}}}}validateBuildRules(){this.assertNoTrailingSpaces("name",this._props.name)}get id(){return this._props.id||null}get name(){return this._props.name}isAdmin(){return this.name.toLowerCase()===ge.ROLE_ADMIN}isUser(){return this.name.toLowerCase()===ge.ROLE_USER}isGuest(){return this.name.toLowerCase()===ge.ROLE_GUEST}isAReservedRole(){return this.isAdmin()||this.isUser()||this.isGuest()}verifyHealth(){let e=null;return 50===this.name.length&&(e=new X,e.addError("name","maxLength","name reached maximum length limit")),e}assertNoTrailingSpaces(e,t){if(t.trim()!==t){const t=new X;throw t.addError(e,"trailing-spaces",`The property (${e}) contains forbidden trailing spaces.`),t}}static get ENTITY_NAME(){return"Role"}static get ROLE_ADMIN(){return"admin"}static get ROLE_USER(){return"user"}static get ROLE_GUEST(){return"guest"}static get ROLE_NAME_MAX_LENGTH(){return 50}toUpdateDto(){return{name:this.name}}}class ye{static canRoleUseAction(e,t,a){if(window.chrome?.webview){const n=t.findRbacByActionName(a);if(n)return $.getByRbac(n).execute(e)}const n=new ge(e.role);if(n.isAdmin())return $.getDefaultForAdminAndAction(a).execute();const s=t.findRbacByRoleAndActionName(n,a);return this.getByRbacOrDefault(s,a,e)}static getByRbacOrDefault(e,t,a){return e?$.getByRbac(e).execute(a):$.getDefaultForUserAndAction(t).execute()}}function be(){return be=Object.assign?Object.assign.bind():function(e){for(var t=1;t{}});class Ee extends n.Component{constructor(e){super(e),this.state=this.defaultState}get defaultState(){return{canIUseAction:this.canIUseAction.bind(this)}}canIUseAction(e){return ye.canRoleUseAction(this.props.context.loggedInUser,this.props.context.rbacs,e)}render(){return n.createElement(fe.Provider,{value:this.state},this.props.children)}}Ee.propTypes={context:i().any,children:i().any};const ve=N(Ee);function we(e){return class extends n.Component{render(){return n.createElement(fe.Consumer,null,t=>n.createElement(e,be({rbacContext:t},this.props)))}}}function ke(){return ke=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},resetDisplayAdministrationWorkspaceAction:()=>{},onUpdateSubscriptionKeyRequested:()=>{},onSaveEnabled:()=>{},onMustSaveSettings:()=>{},onMustEditSubscriptionKey:()=>{},onMustRefreshSubscriptionKey:()=>{},onResetActionsSettings:()=>{}});class xe extends n.Component{constructor(e){super(e),this.state=this.defaultState}get defaultState(){return{selectedAdministration:Te.NONE,can:{save:!1},must:{save:!1,editSubscriptionKey:!1,refreshSubscriptionKey:!1},administrationWorkspaceAction:()=>n.createElement(n.Fragment,null),setDisplayAdministrationWorkspaceAction:this.setDisplayAdministrationWorkspaceAction.bind(this),resetDisplayAdministrationWorkspaceAction:this.resetDisplayAdministrationWorkspaceAction.bind(this),onSaveEnabled:this.handleSaveEnabled.bind(this),onMustSaveSettings:this.handleMustSaveSettings.bind(this),onMustEditSubscriptionKey:this.handleMustEditSubscriptionKey.bind(this),onMustRefreshSubscriptionKey:this.handleMustRefreshSubscriptionKey.bind(this),onResetActionsSettings:this.handleResetActionsSettings.bind(this)}}componentDidMount(){this.handleAdministrationMenuRouteChange()}componentDidUpdate(e){this.handleRouteChange(e.location)}handleSaveEnabled(){this.setState({can:{...this.state.can,save:!0}})}handleMustSaveSettings(){this.setState({must:{...this.state.must,save:!0}})}handleMustEditSubscriptionKey(){this.setState({must:{...this.state.must,editSubscriptionKey:!0}})}handleMustRefreshSubscriptionKey(){this.setState({must:{...this.state.must,refreshSubscriptionKey:!0}})}handleResetActionsSettings(){this.setState({must:{save:!1,test:!1,synchronize:!1,editSubscriptionKey:!1,refreshSubscriptionKey:!1}})}handleRouteChange(e){this.props.location.key!==e.key&&this.handleAdministrationMenuRouteChange()}handleAdministrationMenuRouteChange(){const e={can:{save:!1,test:!1,synchronize:!1},must:{save:!1,test:!1,synchronize:!1,editSubscriptionKey:!1,refreshSubscriptionKey:!1}};if(!this.props.rbacContext.canIUseAction(F))return e.selectedAdministration=Te.HTTP_403_ACCESS_DENIED,void this.setState(e);const t=this.props.location.pathname,a=Ie.homePage.test(t),n=Ie.mfa.test(t),s=Ie.mfaPolicy.test(t),i=Ie.passwordPolicies.test(t),r=Ie.usersDirectory.test(t),o=Ie.emailNotification.test(t),l=Ie.subscription.test(t),c=Ie.internationalization.test(t),m=Ie.accountRecovery.test(t),d=Ie.smtpSettings.test(t),u=Ie.selfRegistration.test(t),p=Ie.sso.test(t),h=Ie.rbac.test(t),g=Ie.userPassphrasePolicies.test(t),y=Ie.passwordExpirySettings.test(t),b=Ie.healthcheck.test(t),f=Ie.contentTypesEncryptedMetadata.test(t),E=Ie.contentTypesMetadataKey.test(t),v=Ie.migrateEncryptedMetadata.test(t),w=Ie.allowContentTypes.test(t),k=Ie.gettingStarted.test(t),_=Ie.scim.test(t),x=Ie.secretHistory.test(t),S=Ie.mfaPolicyTeasing.test(t),C=Ie.passwordPoliciesTeasing.test(t),N=Ie.usersDirectoryTeasing.test(t),T=Ie.subscriptionTeasing.test(t),A=Ie.accountRecoveryTeasing.test(t),I=Ie.userPassphrasePoliciesTeasing.test(t),R=Ie.ssoTeasing.test(t),P=Ie.scimTeasing.test(t);let D;if(a?D=Te.HOME:s||S?D=Te.MFA_POLICY:i||C?D=Te.PASSWORD_POLICIES:n?D=Te.MFA:r||N?D=Te.USER_DIRECTORY:o?D=Te.EMAIL_NOTIFICATION:l||T?D=Te.SUBSCRIPTION:c?D=Te.INTERNATIONALIZATION:m||A?D=Te.ACCOUNT_RECOVERY:d?D=Te.SMTP_SETTINGS:u?D=Te.SELF_REGISTRATION:p||R?D=Te.SSO:h?D=Te.RBAC:g||I?D=Te.USER_PASSPHRASE_POLICIES:y?D=Te.PASSWORD_EXPIRY:b?D=Te.HEALTHCHECK:f?D=Te.CONTENT_TYPES_ENCRYPTED_METADATA:E?D=Te.CONTENT_TYPES_METADATA_KEY:v?D=Te.MIGRATE_METADATA:w?D=Te.ALLOW_CONTENT_TYPES:k?D=Te.METADATA_GETTING_STARTED:_||P?D=Te.SCIM:x&&(D=Te.SECRET_HISTORY),!D)return e.selectedAdministration=Te.HTTP_404_NOT_FOUND,void this.setState(e);const O=Ae?.[D];e.selectedAdministration=O&&!(this.props.context.siteSettings.canIUse(O)||Re.includes(D)&&this.props.context.siteSettings.isCommunityEdition)?Te.HTTP_404_NOT_FOUND:D,this.setState(e)}setDisplayAdministrationWorkspaceAction(e){this.setState({administrationWorkspaceAction:e})}resetDisplayAdministrationWorkspaceAction(){this.setState({administrationWorkspaceAction:()=>n.createElement(n.Fragment,null)})}render(){return n.createElement(_e.Provider,{value:this.state},this.props.children)}}xe.displayName="AdministrationWorkspaceContextProvider",xe.propTypes={context:i().object,children:i().any,location:i().object,match:i().object,history:i().object,loadingContext:i().object,rbacContext:i().object};const Se=(0,x.withRouter)(N(we((Ce=xe,class extends n.Component{render(){return n.createElement(I.Consumer,null,e=>n.createElement(Ce,A({loadingContext:e},this.props)))}}))));var Ce;function Ne(e){return class extends n.Component{render(){return n.createElement(_e.Consumer,null,t=>n.createElement(e,ke({administrationWorkspaceContext:t},this.props)))}}}const Te={NONE:"NONE",HOME:"HOME",MFA:"MFA",MFA_POLICY:"MFA-POLICY",PASSWORD_POLICIES:"PASSWORD-POLICIES",USER_DIRECTORY:"USER-DIRECTORY",EMAIL_NOTIFICATION:"EMAIL-NOTIFICATION",SUBSCRIPTION:"SUBSCRIPTION",INTERNATIONALIZATION:"INTERNATIONALIZATION",ACCOUNT_RECOVERY:"ACCOUNT-RECOVERY",SMTP_SETTINGS:"SMTP-SETTINGS",SELF_REGISTRATION:"SELF-REGISTRATION",SSO:"SSO",RBAC:"RBAC",USER_PASSPHRASE_POLICIES:"USER-PASSPHRASE-POLICIES",PASSWORD_EXPIRY:"PASSWORD-EXPIRY",HTTP_403_ACCESS_DENIED:"403-ACCESS-DENIED",HTTP_404_NOT_FOUND:"404-NOT-FOUND",HEALTHCHECK:"HEALTHCHECK",CONTENT_TYPES_ENCRYPTED_METADATA:"CONTENT_TYPES_ENCRYPTED_METADATA",CONTENT_TYPES_METADATA_KEY:"CONTENT_TYPES_METADATA_KEY",MIGRATE_METADATA:"MIGRATE_METADATA",ALLOW_CONTENT_TYPES:"ALLOW_CONTENT_TYPES",METADATA_GETTING_STARTED:"METADATA_GETTING_STARTED",SCIM:"SCIM",SECRET_HISTORY:"SECRET_HISTORY"},Ae={[Te.MFA]:"multiFactorAuthentication",[Te.MFA_POLICY]:"mfaPolicies",[Te.PASSWORD_POLICIES]:"passwordPoliciesUpdate",[Te.USER_DIRECTORY]:"directorySync",[Te.SUBSCRIPTION]:"ee",[Te.INTERNATIONALIZATION]:"locale",[Te.ACCOUNT_RECOVERY]:"accountRecovery",[Te.SMTP_SETTINGS]:"smtpSettings",[Te.SELF_REGISTRATION]:"selfRegistration",[Te.SSO]:"sso",[Te.RBAC]:"rbacs",[Te.USER_PASSPHRASE_POLICIES]:"userPassphrasePolicies",[Te.PASSWORD_EXPIRY]:"passwordExpiry",[Te.HEALTHCHECK]:"healthcheckUi",[Te.CONTENT_TYPES_ENCRYPTED_METADATA]:"metadata",[Te.CONTENT_TYPES_METADATA_KEY]:"metadata",[Te.MIGRATE_METADATA]:"metadata",[Te.ALLOW_CONTENT_TYPES]:"metadata",[Te.METADATA_GETTING_STARTED]:"metadata",[Te.SCIM]:"scim",[Te.SECRET_HISTORY]:"secretRevisions"},Ie={homePage:/^\/app\/administration\/?$/,mfa:/^\/app\/administration\/mfa\/?$/,mfaPolicy:/^\/app\/administration\/mfa-policy\/?$/,mfaPolicyTeasing:/^\/app\/administration\/mfa-policy-teasing\/?$/,passwordPolicies:/^\/app\/administration\/password-policies\/?$/,passwordPoliciesTeasing:/^\/app\/administration\/password-policies-teasing\/?$/,usersDirectory:/^\/app\/administration\/users-directory\/?$/,usersDirectoryTeasing:/^\/app\/administration\/users-directory-teasing\/?$/,emailNotification:/^\/app\/administration\/email-notification\/?$/,subscription:/^\/app\/administration\/subscription\/?$/,subscriptionTeasing:/^\/app\/administration\/subscription-teasing\/?$/,internationalization:/^\/app\/administration\/internationalization\/?$/,accountRecovery:/^\/app\/administration\/account-recovery\/?$/,accountRecoveryTeasing:/^\/app\/administration\/account-recovery-teasing\/?$/,smtpSettings:/^\/app\/administration\/smtp-settings\/?$/,selfRegistration:/^\/app\/administration\/self-registration\/?$/,sso:/^\/app\/administration\/sso\/?$/,ssoTeasing:/^\/app\/administration\/sso-teasing\/?$/,rbac:/^\/app\/administration\/rbacs\/?$/,userPassphrasePolicies:/^\/app\/administration\/user-passphrase-policies\/?$/,userPassphrasePoliciesTeasing:/^\/app\/administration\/user-passphrase-policies-teasing\/?$/,passwordExpirySettings:/^\/app\/administration\/password-expiry\/?$/,healthcheck:/^\/app\/administration\/healthcheck\/?$/,contentTypesEncryptedMetadata:/^\/app\/administration\/content-types\/metadata\/?$/,contentTypesMetadataKey:/^\/app\/administration\/content-types\/metadata-key\/?$/,migrateEncryptedMetadata:/^\/app\/administration\/migrate-metadata\/?$/,allowContentTypes:/^\/app\/administration\/allow-content-types\/?$/,gettingStarted:/^\/app\/administration\/content-types\/metadata-getting-started\/?$/,scim:/^\/app\/administration\/user-provisionning\/scim\/?$/,scimTeasing:/^\/app\/administration\/scim-teasing\/?$/,secretHistory:/^\/app\/administration\/secret-history\/?$/},Re=[Te.SUBSCRIPTION,Te.PASSWORD_POLICIES,Te.USER_PASSPHRASE_POLICIES,Te.ACCOUNT_RECOVERY,Te.SSO,Te.MFA_POLICY,Te.USER_DIRECTORY,Te.SCIM];function Pe(){return Pe=Object.assign?Object.assign.bind():function(e){for(var t=1;tt===e);t?.DialogProps?.onClose&&t.DialogProps.onClose(),this.props.dialogContext.close(e)}render(){return n.createElement(n.Fragment,null,this.props.dialogContext.dialogs.map(({key:e,Dialog:t,DialogProps:a})=>n.createElement(t,Pe({key:e},a,{onClose:()=>this.close(e)}))),this.props.children)}}De.propTypes={dialogContext:i().any,children:i().any};const Oe=h(De);function Me(){return Me=Object.assign?Object.assign.bind():function(e){for(var t=1;tn.createElement(e.ContextualMenuComponent,Me({key:t,hide:()=>this.handleHide(t)},e.componentProps))))}}Ue.propTypes={contextualMenuContext:i().any};const Fe=function(e){return class extends n.Component{render(){return n.createElement(y.Consumer,null,t=>n.createElement(e,g({contextualMenuContext:t},this.props)))}}}(Ue);function je(){return je=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},onGoToAdministrationSelfRegistrationRequested:()=>{},onGoToAdministrationMfaRequested:()=>{},onGoToAdministrationUsersDirectoryRequested:()=>{},onGoToAdministrationEmailNotificationsRequested:()=>{},onGoToAdministrationSubscriptionRequested:()=>{},onGoToAdministrationInternationalizationRequested:()=>{},onGoToAdministrationAccountRecoveryRequested:()=>{},onGoToAdministrationSmtpSettingsRequested:()=>{},onGoToAdministrationSsoRequested:()=>{},onGoToAdministrationPasswordPoliciesRequested:()=>{},onGoToAdministrationSecretHistoryRequested:()=>{},onGoToAdministrationUserPassphrasePoliciesRequested:()=>{},onGoToAdministrationPasswordExpirySettingsRequested:()=>{},onGoToAdministrationHealthcheckRequested:()=>{},onGoToPasswordsRequested:()=>{},onGoToUsersRequested:()=>{},onGoToHelpRequested:()=>{},onGoToUserSettingsProfileRequested:()=>{},onGoToUserSettingsPassphraseRequested:()=>{},onGoToUserSettingsSecurityTokenRequested:()=>{},onGoToUserSettingsThemeRequested:()=>{},onGoToUserSettingsMfaRequested:()=>{},onGoToUserSettingsKeysRequested:()=>{},onGoToUserSettingsMobileRequested:()=>{},onGoToUserSettingsDesktopRequested:()=>{},onGoToUserSettingsAccountRecoveryRequested:()=>{},onGoToNewTab:()=>{},onGoToAdministrationRbacsRequested:()=>{},onGoToAdministrationMigrateMetadataRequested:()=>{},onGoToAdministrationAllowContentTypesRequested:()=>{},onGoToAdministrationMetadataGettingStartedRequested:()=>{},onGoToAdministrationSubscriptionRequestedTeasing:()=>{},onGoToAdministrationPasswordPoliciesRequestedTeasing:()=>{},onGoToAdministrationUserPassphrasePoliciesRequestedTeasing:()=>{},onGoToAdministrationAccountRecoveryRequestedTeasing:()=>{},onGoToAdministrationSsoRequestedTeasing:()=>{},onGoToAdministrationMfaPolicyRequestedTeasing:()=>{},onGoToAdministrationUsersDirectoryRequestedTeasing:()=>{},onGoToAdministrationScimRequestedTeasing:()=>{},onGoToAdministrationScimRequested:()=>{}});class qe extends n.Component{constructor(e){super(e),this.state=this.defaultState}get defaultState(){return{onGoToNewTab:this.onGoToNewTab.bind(this),onGoToAdministrationRequested:this.onGoToAdministrationRequested.bind(this),onGoToAdministrationMfaRequested:this.onGoToAdministrationMfaRequested.bind(this),onGoToAdministrationUsersDirectoryRequested:this.onGoToAdministrationUsersDirectoryRequested.bind(this),onGoToAdministrationEmailNotificationsRequested:this.onGoToAdministrationEmailNotificationsRequested.bind(this),onGoToAdministrationSubscriptionRequested:this.onGoToAdministrationSubscriptionRequested.bind(this),onGoToAdministrationInternationalizationRequested:this.onGoToAdministrationInternationalizationRequested.bind(this),onGoToAdministrationAccountRecoveryRequested:this.onGoToAdministrationAccountRecoveryRequested.bind(this),onGoToAdministrationSmtpSettingsRequested:this.onGoToAdministrationSmtpSettingsRequested.bind(this),onGoToAdministrationSelfRegistrationRequested:this.onGoToAdministrationSelfRegistrationRequested.bind(this),onGoToAdministrationSsoRequested:this.onGoToAdministrationSsoRequested.bind(this),onGoToAdministrationMfaPolicyRequested:this.onGoToAdministrationMfaPolicyRequested.bind(this),onGoToAdministrationPasswordPoliciesRequested:this.onGoToAdministrationPasswordPoliciesRequested.bind(this),onGoToAdministrationSecretHistoryRequested:this.onGoToAdministrationSecretHistoryRequested.bind(this),onGoToAdministrationUserPassphrasePoliciesRequested:this.onGoToAdministrationUserPassphrasePoliciesRequested.bind(this),onGoToAdministrationPasswordExpirySettingsRequested:this.onGoToAdministrationPasswordExpirySettingsRequested.bind(this),onGoToAdministrationHealthcheckRequested:this.onGoToAdministrationHealthcheckRequested.bind(this),onGoToAdministrationContentTypesEncryptedMetadataRequested:this.onGoToAdministrationContentTypesEncryptedMetadataRequested.bind(this),onGoToAdministrationContentTypesMetadataKeyRequested:this.onGoToAdministrationContentTypesMetadataKeyRequested.bind(this),onGoToAdministrationMigrateMetadataRequested:this.onGoToAdministrationMigrateMetadataRequested.bind(this),onGoToAdministrationAllowContentTypesRequested:this.onGoToAdministrationAllowContentTypesRequested.bind(this),onGoToPasswordsRequested:this.onGoToPasswordsRequested.bind(this),onGoToUsersRequested:this.onGoToUsersRequested.bind(this),onGoToHelpRequested:this.onGoToHelpRequested.bind(this),onGoToUserSettingsProfileRequested:this.onGoToUserSettingsProfileRequested.bind(this),onGoToUserSettingsPassphraseRequested:this.onGoToUserSettingsPassphraseRequested.bind(this),onGoToUserSettingsSecurityTokenRequested:this.onGoToUserSettingsSecurityTokenRequested.bind(this),onGoToUserSettingsThemeRequested:this.onGoToUserSettingsThemeRequested.bind(this),onGoToUserSettingsMfaRequested:this.onGoToUserSettingsMfaRequested.bind(this),onGoToUserSettingsKeysRequested:this.onGoToUserSettingsKeysRequested.bind(this),onGoToUserSettingsMobileRequested:this.onGoToUserSettingsMobileRequested.bind(this),onGoToUserSettingsDesktopRequested:this.onGoToUserSettingsDesktopRequested.bind(this),onGoToUserSettingsAccountRecoveryRequested:this.onGoToUserSettingsAccountRecoveryRequested.bind(this),onGoToAdministrationRbacsRequested:this.onGoToAdministrationRbacsRequested.bind(this),onGoToAdministrationMetadataGettingStartedRequested:this.onGoToAdministrationMetadataGettingStartedRequested.bind(this),onGoToAdministrationSubscriptionRequestedTeasing:this.onGoToAdministrationSubscriptionRequestedTeasing.bind(this),onGoToAdministrationPasswordPoliciesRequestedTeasing:this.onGoToAdministrationPasswordPoliciesRequestedTeasing.bind(this),onGoToAdministrationUserPassphrasePoliciesRequestedTeasing:this.onGoToAdministrationUserPassphrasePoliciesRequestedTeasing.bind(this),onGoToAdministrationAccountRecoveryRequestedTeasing:this.onGoToAdministrationAccountRecoveryRequestedTeasing.bind(this),onGoToAdministrationSsoRequestedTeasing:this.onGoToAdministrationSsoRequestedTeasing.bind(this),onGoToAdministrationMfaPolicyRequestedTeasing:this.onGoToAdministrationMfaPolicyRequestedTeasing.bind(this),onGoToAdministrationUsersDirectoryRequestedTeasing:this.onGoToAdministrationUsersDirectoryRequestedTeasing.bind(this),onGoToAdministrationScimRequestedTeasing:this.onGoToAdministrationScimRequestedTeasing.bind(this),onGoToAdministrationScimRequested:this.onGoToAdministrationScimRequested.bind(this)}}async goTo(e,t){if(e===this.props.context.name)return void await this.props.history.push({pathname:t});if("api"===e)return void await this.props.context.port.request("passbolt.tabs.open-admin-page",t);const a=`${this.props.context.userSettings?this.props.context.userSettings.getTrustedDomain():this.props.context.trustedDomain}${t}`;window.open(a,"_parent","noopener,noreferrer")}onGoToNewTab(e){window.open(e,"_blank","noopener,noreferrer")}async onGoToAdministrationRequested(){await this.goTo("browser-extension","/app/administration")}async onGoToAdministrationMfaRequested(){await this.goTo("api","/app/administration/mfa")}async onGoToAdministrationMfaPolicyRequested(){await this.goTo("api","/app/administration/mfa-policy")}async onGoToAdministrationPasswordPoliciesRequested(){await this.goTo("browser-extension","/app/administration/password-policies")}async onGoToAdministrationSecretHistoryRequested(){await this.goTo("browser-extension","/app/administration/secret-history")}async onGoToAdministrationSelfRegistrationRequested(){await this.goTo("api","/app/administration/self-registration")}async onGoToAdministrationUsersDirectoryRequested(){await this.goTo("api","/app/administration/users-directory")}async onGoToAdministrationHealthcheckRequested(){await this.goTo("api","/app/administration/healthcheck")}async onGoToAdministrationEmailNotificationsRequested(){await this.goTo("api","/app/administration/email-notification")}async onGoToAdministrationSmtpSettingsRequested(){await this.goTo("api","/app/administration/smtp-settings")}async onGoToAdministrationSubscriptionRequested(){await this.goTo("browser-extension","/app/administration/subscription")}async onGoToAdministrationInternationalizationRequested(){await this.goTo("api","/app/administration/internationalization")}async onGoToAdministrationAccountRecoveryRequested(){await this.goTo("browser-extension","/app/administration/account-recovery")}async onGoToAdministrationSsoRequested(){await this.goTo("browser-extension","/app/administration/sso")}async onGoToAdministrationRbacsRequested(){await this.goTo("api","/app/administration/rbacs")}async onGoToAdministrationMetadataGettingStartedRequested(){await this.goTo("browser-extension","/app/administration/content-types/metadata-getting-started")}async onGoToAdministrationScimRequested(){await this.goTo("browser-extension","/app/administration/user-provisionning/scim")}async onGoToAdministrationUserPassphrasePoliciesRequested(){await this.goTo("browser-extension","/app/administration/user-passphrase-policies")}async onGoToAdministrationPasswordExpirySettingsRequested(){await this.goTo("browser-extension","/app/administration/password-expiry")}async onGoToAdministrationContentTypesEncryptedMetadataRequested(){await this.goTo("browser-extension","/app/administration/content-types/metadata")}async onGoToAdministrationContentTypesMetadataKeyRequested(){await this.goTo("browser-extension","/app/administration/content-types/metadata-key")}async onGoToAdministrationMigrateMetadataRequested(){await this.goTo("browser-extension","/app/administration/migrate-metadata")}async onGoToAdministrationAllowContentTypesRequested(){await this.goTo("browser-extension","/app/administration/allow-content-types")}async onGoToAdministrationSubscriptionRequestedTeasing(){await this.goTo("browser-extension","/app/administration/subscription-teasing")}async onGoToAdministrationPasswordPoliciesRequestedTeasing(){await this.goTo("browser-extension","/app/administration/password-policies-teasing")}async onGoToAdministrationUserPassphrasePoliciesRequestedTeasing(){await this.goTo("browser-extension","/app/administration/user-passphrase-policies-teasing")}async onGoToAdministrationAccountRecoveryRequestedTeasing(){await this.goTo("browser-extension","/app/administration/account-recovery-teasing")}async onGoToAdministrationSsoRequestedTeasing(){await this.goTo("browser-extension","/app/administration/sso-teasing")}async onGoToAdministrationMfaPolicyRequestedTeasing(){await this.goTo("browser-extension","/app/administration/mfa-policy-teasing")}async onGoToAdministrationUsersDirectoryRequestedTeasing(){await this.goTo("browser-extension","/app/administration/users-directory-teasing")}async onGoToAdministrationScimRequestedTeasing(){await this.goTo("browser-extension","/app/administration/scim-teasing")}get isMfaEnabled(){const e=this.props.context.siteSettings;return e&&e.canIUse("multiFactorAuthentication")}get isUserDirectoryEnabled(){const e=this.props.context.siteSettings;return e&&e.canIUse("directorySync")}get isSmtpSettingsEnable(){const e=this.props.context.siteSettings;return e&&e.canIUse("smtpSettings")}get isSelfRegistrationEnable(){const e=this.props.context.siteSettings;return e&&e.canIUse("selfRegistration")}get isPasswordPoliciesEnable(){const e=this.props.context.siteSettings;return e&&e.canIUse("passwordPoliciesUpdate")}get isUserPassphrasePoliciesEnable(){const e=this.props.context.siteSettings;return e&&e.canIUse("userPassphrasePolicies")}get isPasswordExpiryEnable(){const e=this.props.context.siteSettings;return e&&e.canIUse("passwordExpiry")}async onGoToPasswordsRequested(){await this.goTo("browser-extension","/app/passwords")}async onGoToUsersRequested(){await this.goTo("browser-extension","/app/users")}async onGoToHelpRequested(){await this.onGoToNewTab("https://www.passbolt.com/docs/")}async onGoToUserSettingsProfileRequested(){await this.goTo("browser-extension","/app/settings/profile")}async onGoToUserSettingsPassphraseRequested(){await this.goTo("browser-extension","/app/settings/passphrase")}async onGoToUserSettingsSecurityTokenRequested(){await this.goTo("browser-extension","/app/settings/security-token")}async onGoToUserSettingsThemeRequested(){await this.goTo("browser-extension","/app/settings/theme")}async onGoToUserSettingsMfaRequested(){await this.goTo("browser-extension","/app/settings/mfa")}async onGoToUserSettingsDuoSetupRequested(){let e="api";window.chrome?.webview&&(e="browser-extension"),await this.goTo(e,"/app/settings/mfa")}async onGoToUserSettingsKeysRequested(){await this.goTo("browser-extension","/app/settings/keys")}async onGoToUserSettingsMobileRequested(){await this.goTo("browser-extension","/app/settings/mobile")}async onGoToUserSettingsDesktopRequested(){await this.goTo("browser-extension","/app/settings/desktop")}async onGoToUserSettingsAccountRecoveryRequested(){await this.goTo("browser-extension","/app/settings/account-recovery")}render(){return n.createElement(Le.Provider,{value:this.state},this.props.children)}}qe.displayName="NavigationContextProvider",qe.propTypes={context:i().object,children:i().any,location:i().object,match:i().object,history:i().object};const ze=(0,x.withRouter)(N(qe));function Ke(e){return class extends n.Component{render(){return n.createElement(Le.Consumer,null,t=>n.createElement(e,je({navigationContext:t},this.props)))}}}function Ve(){return Ve=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},getOrganizationPolicy:()=>{},getRequestor:()=>{},getRequestedDate:()=>{},getPolicy:()=>{},getUserAccountRecoverySubscriptionStatus:()=>{},isAccountRecoveryChoiceRequired:()=>{},isPolicyEnabled:()=>{},loadAccountRecoveryPolicy:()=>{},reloadAccountRecoveryPolicy:()=>{},isReady:()=>{}});class Be extends n.Component{constructor(e){super(e),this.state=this.defaultState}get defaultState(){return{accountRecoveryOrganizationPolicy:null,status:null,isDataLoaded:!1,findAccountRecoveryPolicy:this.findAccountRecoveryPolicy.bind(this),getOrganizationPolicy:this.getOrganizationPolicy.bind(this),getRequestor:this.getRequestor.bind(this),getRequestedDate:this.getRequestedDate.bind(this),getPolicy:this.getPolicy.bind(this),getUserAccountRecoverySubscriptionStatus:this.getUserAccountRecoverySubscriptionStatus.bind(this),setUserAccountRecoveryStatus:this.setUserAccountRecoveryStatus.bind(this),isAccountRecoveryChoiceRequired:this.isAccountRecoveryChoiceRequired.bind(this),isPolicyEnabled:this.isPolicyEnabled.bind(this),loadAccountRecoveryPolicy:this.loadAccountRecoveryPolicy.bind(this),reloadAccountRecoveryPolicy:this.reloadAccountRecoveryPolicy.bind(this),isReady:this.isReady.bind(this)}}async loadAccountRecoveryPolicy(){this.state.isDataLoaded||await this.findAccountRecoveryPolicy()}async reloadAccountRecoveryPolicy(){await this.findAccountRecoveryPolicy()}async findAccountRecoveryPolicy(){if(!this.props.context.siteSettings.canIUse("accountRecovery"))return;const e=this.props.context.loggedInUser;if(!e)return;const t=await this.props.accountRecoveryUserService.getOrganizationAccountRecoverySettings(),a=e.account_recovery_user_setting?.status||Be.STATUS_PENDING;this.setState({accountRecoveryOrganizationPolicy:t,status:a,isDataLoaded:!0})}isReady(){return this.state.isDataLoaded}getOrganizationPolicy(){return this.state.accountRecoveryOrganizationPolicy}getRequestedDate(){return this.getOrganizationPolicy()?.modified}getRequestor(){return this.getOrganizationPolicy()?.creator}getPolicy(){return this.getOrganizationPolicy()?.policy}getUserAccountRecoverySubscriptionStatus(){return this.state.status}setUserAccountRecoveryStatus(e){this.setState({status:e})}isAccountRecoveryChoiceRequired(){if(null===this.getOrganizationPolicy())return!1;const e=this.getPolicy();return this.state.status===Be.STATUS_PENDING&&e!==Be.POLICY_DISABLED}isPolicyEnabled(){const e=this.getPolicy();return e&&e!==Be.POLICY_DISABLED}static get STATUS_PENDING(){return"pending"}static get POLICY_DISABLED(){return"disabled"}static get POLICY_MANDATORY(){return"mandatory"}static get POLICY_OPT_OUT(){return"opt-out"}static get STATUS_APPROVED(){return"approved"}render(){return n.createElement(Ge.Provider,{value:this.state},this.props.children)}}Be.propTypes={context:i().any.isRequired,children:i().any,accountRecoveryUserService:i().object.isRequired};const We=N(Be);function He(e){return class extends n.Component{render(){return n.createElement(Ge.Consumer,null,t=>n.createElement(e,Ve({accountRecoveryContext:t},this.props)))}}}var $e,Ye,Ze;function Je(){return Je=Object.assign?Object.assign.bind():function(e){for(var t=1;t-1?"firefox":e.indexOf("samsungbrowser")>-1?"samsung":e.indexOf("opera")>-1||e.indexOf("opr")>-1?"opera":e.indexOf("trident")>-1?"internet-explorer":e.indexOf("edg")>-1?"edge":e.indexOf("chrome")>-1?"chrome":e.indexOf("safari")>-1?at:"unknown",t}()===at}shouldDisplayDefaultAvatar(){if(this.isRunningUnderSafari())return!0;const e=Boolean(this.getAvatarSrc());return this.state.error||!this.props.user||this.isDefaultAvatarUrlFromApi()||!e}getAvatarSrc(){return this.propsHasUrl()?this.propsUrlHasProtocol()?this.avatarUrl:this.formatUrl(this.avatarUrl):null}handleError(){console.error(`Could not load avatar image url: ${this.getAvatarSrc()}`),this.setState({error:!0})}handleLoaded(){this.setState({isLoading:!1})}getAltText(){const e=this.props?.user;return e?.first_name&&e?.last_name?this.props.t("Avatar of user {{first_name}} {{last_name}}.",{firstname:e.first_name,lastname:e.last_name}):"..."}render(){const e=this.shouldDisplayDefaultAvatar();return n.createElement("div",{className:`${this.props.className}`},n.createElement("div",{className:"default-avatar"},(e||this.state.isLoading)&&n.createElement(Xe,null),!e&&n.createElement("img",{src:this.getAvatarSrc(),className:this.state.isLoading?"is-loading":"",onError:this.handleError,onLoad:this.handleLoaded,alt:this.getAltText()})),this.props.attentionRequired&&n.createElement(tt,{className:"attention-required"}))}}st.defaultProps={className:"avatar user-avatar"},st.propTypes={baseUrl:i().string,user:i().object,attentionRequired:i().bool,className:i().string,t:i().func};const it=(0,f.CI)("common")(st);class rt extends Error{constructor(e,t){super(e),this.name="PassboltApiFetchError",this.data=t||{}}}const ot=rt;class lt extends Error{constructor(){super("An internal error occurred. The server response could not be parsed. Please contact your administrator."),this.name="PassboltBadResponseError"}}const ct=lt;class mt extends Error{constructor(e){super(e=e||"The service is unavailable"),this.name="PassboltServiceUnavailableError"}}const dt=mt,ut=["GET","POST","PUT","DELETE"];class pt{constructor(e){if(this.options=e,!this.options.getBaseUrl())throw new TypeError("ApiClient constructor error: baseUrl is required.");if(!this.options.getResourceName())throw new TypeError("ApiClient constructor error: resourceName is required.");try{let e=this.options.getBaseUrl().toString();e.endsWith("/")&&(e=e.slice(0,-1));let t=this.options.getResourceName();t.startsWith("/")&&(t=t.slice(1)),t.endsWith("/")&&(t=t.slice(0,-1)),this.baseUrl=`${e}/${t}`,this.baseUrl=new URL(this.baseUrl)}catch(e){throw new TypeError("ApiClient constructor error: b.",{cause:e})}this.apiVersion="api-version=v2"}getDefaultHeaders(){return{Accept:"application/json","content-type":"application/json"}}async buildFetchOptions(){const e=await this.options.getHeaders();return{credentials:"include",headers:{...this.getDefaultHeaders(),...e}}}async get(e,t){this.assertValidId(e);const a=this.buildUrl(`${this.baseUrl}/${e}`,t||{});return this.fetchAndHandleResponse("GET",a)}async delete(e,t,a,n){let s;this.assertValidId(e),void 0===n&&(n=!1),s=n?this.buildUrl(`${this.baseUrl}/${e}/dry-run`,a||{}):this.buildUrl(`${this.baseUrl}/${e}`,a||{});let i=null;return t&&(i=this.buildBody(t)),this.fetchAndHandleResponse("DELETE",s,i)}async findAll(e){const t=this.buildUrl(this.baseUrl.toString(),e||{});return this.fetchAndHandleResponse("GET",t)}async create(e,t){const a=this.buildUrl(this.baseUrl.toString(),t||{}),n=this.buildBody(e);return this.fetchAndHandleResponse("POST",a,n)}async update(e,t,a,n){let s;this.assertValidId(e),void 0===n&&(n=!1),s=n?this.buildUrl(`${this.baseUrl}/${e}/dry-run`,a||{}):this.buildUrl(`${this.baseUrl}/${e}`,a||{});let i=null;return t&&(i=this.buildBody(t)),this.fetchAndHandleResponse("PUT",s,i)}async updateAll(e,t={}){const a=this.buildUrl(this.baseUrl.toString(),t),n=e?this.buildBody(e):null;return this.fetchAndHandleResponse("PUT",a,n)}assertValidId(e){if(!e)throw new TypeError("ApiClient.assertValidId error: id cannot be empty");if("string"!=typeof e)throw new TypeError("ApiClient.assertValidId error: id should be a string")}assertMethod(e){if("string"!=typeof e)throw new TypeError("ApiClient.assertValidMethod method should be a string.");if(ut.indexOf(e.toUpperCase())<0)throw new TypeError(`ApiClient.assertValidMethod error: method ${e} is not supported.`)}assertUrl(e){if(!e)throw new TypeError("ApliClient.assertUrl error: url is required.");if(!(e instanceof URL))throw new TypeError("ApliClient.assertUrl error: url should be a valid URL object.");if("https:"!==e.protocol&&"http:"!==e.protocol)throw new TypeError("ApliClient.assertUrl error: url protocol should only be https or http.")}assertBody(e){if(!(e instanceof FormData)&&"string"!=typeof e)throw new TypeError("ApiClient.assertBody error: body should be a string or a FormData.")}buildBody(e){return JSON.stringify(e)}buildUrl(e,t){if("string"!=typeof e)throw new TypeError("ApiClient.buildUrl error: url should be a string.");const a=new URL(`${e}.json?${this.apiVersion}`);t=t||{};for(const[e,n]of Object.entries(t)){if("string"!=typeof e)throw new TypeError("ApiClient.buildUrl error: urlOptions key should be a string.");if("string"==typeof n)a.searchParams.append(e,n);else{if(!Array.isArray(n))throw new TypeError("ApiClient.buildUrl error: urlOptions value should be a string or array.");n.forEach(t=>{a.searchParams.append(e,t)})}}return a}async sendRequest(e,t,a,n){this.assertUrl(t),this.assertMethod(e),a&&this.assertBody(a);const s="undefined"!=typeof customApiClientFetch?customApiClientFetch:fetch,i={...await this.buildFetchOptions(),...n};i.method=e,a&&(i.body=a);try{return await s(t.toString(),i)}catch(e){throw console.error(e),navigator.onLine?new dt("Unable to reach the server, an unexpected error occurred"):new dt("Unable to reach the server, you are not connected to the network")}}async fetchAndHandleResponse(e,t,a,n){const s=await this.sendRequest(e,t,a,n);return this.parseResponseJson(s)}async parseResponseJson(e){let t;try{t=await e.json()}catch(t){throw console.debug(e.url.toString(),t),new ct(t,e)}if(!e.ok){const a=t.header.message;throw new ot(a,{code:e.status,body:t.body})}return t}}const ht=class{constructor(e){e.setResourceName("mfa-policies/settings"),this.apiClient=new pt(e)}async find(){return(await this.apiClient.findAll()).body}async save(e){await this.apiClient.create(e)}},gt=class{constructor(e){this.apiClientOptions=e}async findAllSettings(){return this.initClient(),(await this.apiClient.findAll()).body}async save(e){return this.initClient(),(await this.apiClient.create(e)).body}async getUserSettings(){return this.initClient("setup/select"),(await this.apiClient.findAll()).body}initClient(e="settings"){this.apiClientOptions.setResourceName(`mfa/${e}`),this.apiClient=new pt(this.apiClientOptions)}};function yt(){return yt=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},getMfaOrganisationSettings:()=>{},getMfaUserSettings:()=>{},findPolicy:()=>{},setProcessing:()=>{},isProcessing:()=>{},clearContext:()=>{},isMfaChoiceRequired:()=>{},checkMfaChoiceRequired:()=>{},hasMfaUserSettings:()=>{},navigate:()=>{},setProvider:()=>{},goToProviderList:()=>{},validateTotpCode:()=>{},removeProvider:()=>{},validateYubikeyCode:()=>{}});class Et extends n.Component{constructor(e){super(e),this.state=this.defaultState}get defaultState(){return{state:bt,setup:null,policy:null,provider:null,processing:!0,mfaUserSettings:null,mfaOrganisationSettings:null,mfaChoiceRequired:!1,getPolicy:this.getPolicy.bind(this),getMfaOrganisationSettings:this.getMfaOrganisationSettings.bind(this),getMfaUserSettings:this.getMfaUserSettings.bind(this),findPolicy:this.findPolicy.bind(this),findMfaSettings:this.findMfaSettings.bind(this),isProcessing:this.isProcessing.bind(this),setProcessing:this.setProcessing.bind(this),hasMfaOrganisationSettings:this.hasMfaOrganisationSettings.bind(this),hasMfaUserSettings:this.hasMfaUserSettings.bind(this),clearContext:this.clearContext.bind(this),checkMfaChoiceRequired:this.checkMfaChoiceRequired.bind(this),isMfaChoiceRequired:this.isMfaChoiceRequired.bind(this),navigate:this.navigate.bind(this),setProvider:this.setProvider.bind(this),goToProviderList:this.goToProviderList.bind(this),validateTotpCode:this.validateTotpCode.bind(this),removeProvider:this.removeProvider.bind(this),validateYubikeyCode:this.validateYubikeyCode.bind(this),handleGetStartedWithDuo:this.handleGetStartedWithDuo.bind(this)}}async findPolicy(){const{policy:e}=this.state;if(null!==e)return e;let t;if(this.setProcessing(!0),this.props.context.port)t=await this.props.context.port.request("passbolt.mfa-policy.get-policy");else{const e=new ht(this.props.context.getApiClientOptions());t=await e.find()}const a=t?t.policy:null;return this.setState({policy:a}),this.setProcessing(!1),a}async findMfaSettings(){let e;if(this.setProcessing(!0),this.props.context.port)e=await this.props.context.port.request("passbolt.mfa-policy.get-mfa-settings");else{const t=new gt(this.props.context.getApiClientOptions());e=await t.getUserSettings()}const t=e.MfaAccountSettings,a=e.MfaOrganizationSettings;return this.setState({mfaUserSettings:t,mfaOrganisationSettings:a}),this.setProcessing(!1),{mfaUserSettings:t,mfaOrganisationSettings:a}}getPolicy(){return this.state.policy}getMfaOrganisationSettings(){return this.state.mfaOrganisationSettings}getMfaUserSettings(){return this.state.mfaUserSettings}hasMfaOrganisationSettings(){return this.state.mfaOrganisationSettings&&Object.values(this.state.mfaOrganisationSettings).some(e=>e)}hasMfaUserSettings(){return this.state.mfaUserSettings&&Object.values(this.state.mfaUserSettings).some(e=>e)}isProcessing(){return this.state.processing}setProcessing(e){this.setState({processing:e})}clearContext(){const{policy:e,processing:t}=this.defaultState;this.setState({policy:e,processing:t})}async checkMfaChoiceRequired(){const e=await this.findPolicy();if(null===e||"mandatory"!==e)return!1;const{mfaUserSettings:t,mfaOrganisationSettings:a}=await this.findMfaSettings(),n=a&&Object.values(a).some(e=>e),s=t&&Object.values(t).some(e=>e);this.setState({mfaChoiceRequired:n&&!s})}isMfaChoiceRequired(){return this.state.mfaChoiceRequired}navigate(e){this.setState({state:e})}goToProviderList(){this.setState({state:bt,provider:null})}setProvider(e){this.setState({provider:e})}async validateTotpCode(e,t){try{this.setProcessing(!0),await this.props.context.port.request("passbolt.mfa-setup.verify-totp-code",{otpProvisioningUri:e,totp:t})}catch(e){throw console.error(e),e}finally{this.setProcessing(!1)}}async validateYubikeyCode(e){try{this.setProcessing(!0),await this.props.context.port.request("passbolt.mfa-setup.verify-yubikey-code",{hotp:e})}catch(e){throw console.error(e),e}finally{this.setProcessing(!1)}}async removeProvider(){try{this.setProcessing(!0),await this.props.context.port.request("passbolt.mfa-setup.remove-provider",{provider:this.state.provider})}catch(e){throw console.error(e),e}finally{this.setProcessing(!1)}}async handleGetStartedWithDuo(){await this.props.context.port.request("passbolt.mfa-setup.start-with-duo")}render(){return n.createElement(ft.Provider,{value:this.state},this.props.children)}}Et.propTypes={context:i().any,children:i().any};const vt=N(Et);var wt,kt,_t;function xt(){return xt=Object.assign?Object.assign.bind():function(e){for(var t=1;tn.createElement(e,yt({mfaContext:t},this.props)))}}}((0,f.CI)("common")(Yt)))))));class Jt extends he{static getSchema(){return{type:"object",required:["enabled"],properties:{enabled:{type:"boolean"}}}}static createFromDefault(e={}){const t={enabled:!1,...e};return new Jt(t)}get enabled(){return this._props.enabled}}var Xt=a(3050),Qt=a.n(Xt);const ea=/^[a-f0-9]{8}-[a-f0-9]{4}-[0-5][a-f0-9]{3}-[089ab][a-f0-9]{3}-[a-f0-9]{12}$/i,ta=e=>new(Qt())(ea).test(e),aa=(e,t="The given parameter is not a valid number")=>{if(void 0!==e&&"number"!=typeof e)throw new TypeError(t)},na="desc",sa=class{constructor(e,t){e.setResourceName(t),this.apiClient=new pt(e)}formatContainOptions(e,t){const a={};for(const n in e){if("string"!=typeof n){const t=JSON.stringify(e);throw new TypeError(`Invalid contain ${t}, items should be a string.`)}t.includes(n)&&(a[`contain[${n}]`]=e[n]?"1":"0")}return a}formatFilterOptions(e,t){const a={};for(const n in e)if(Object.prototype.hasOwnProperty.call(e,n)&&t.includes(n))if("boolean"==typeof e[n])a[`filter[${n}]`]=e[n]?"1":"0";else if("string"==typeof e[n])a[`filter[${n}]`]=e[n];else{if(!Array.isArray(e[n]))throw new TypeError("Service error. Filter option should be an array or a string.");a[`filter[${n}][]`]=e[n]}return a}formatOrderOptions(e,t){const a={};for(const n in e)t.includes(n)&&(a["order[]"]=n);return a}formatPageOptions(e,t){const a={};if(e.limit){if(aa(e.limit),e.limit<1)throw new Error("The 'limit' parameter must be an integer greater than or equal to 1");a.limit=e.limit.toString()}if(e.page&&a.limit){if(aa(e.page),e.page<1)throw new Error("The 'page' parameter must be an integer greater than or equal to 1");a.page=e.page.toString()}return e.sorts&&Object.keys(e.sorts).forEach(n=>{if(!t.includes(n))return;const s=e.sorts[n]===na?na:"asc";a[`sort[${n}]`]=s}),a}assertValidId(e){if(!e||"string"!=typeof e||!ee().isUUID(e))throw new TypeError(`Service error. The id '${e}' is not a valid uuid.`)}assertNonEmptyData(e){if(!e)throw new TypeError("Service error. Data cannot be empty.")}},ia=class extends he{static getSchema(){return{type:"object",required:["count","limit","page"],properties:{count:{type:"integer",minimum:0},limit:{type:"integer",minimum:0,nullable:!0},page:{type:"integer",minimum:0}}}}get count(){return this._props.count}get limit(){return this._props.limit}get page(){return this._props.page}get pageCount(){const e=parseInt(this._props.count,10),t=parseInt(this._props.limit,10);return Math.ceil(e/t)}},ra=class extends he{constructor(e,t={}){super(e,t),this._props.pagination&&(this._pagination=new ia(this._props.pagination,t),delete this._props.pagination)}static getSchema(){return{type:"object",required:[],properties:{pagination:{type:"object"}}}}get pagination(){return this._pagination||null}toDto(){const e=Object.assign({},this._props);return this._pagination&&(e.pagination=this._pagination.toDto()),e}},oa=class extends he{constructor(e,t={}){super(e,t),this._props.header&&(this._header=new ra(this._props.header,t),delete this._props.header)}static getSchema(){return{type:"object",required:["header","body"],properties:{header:{type:"object"},body:{anyOf:[{type:"string"},{type:"object"}],nullable:!0}}}}get header(){return this._header}get body(){return this._props.body}};class la extends sa{constructor(e){super(e,"metadata/settings/")}async get(){const e=await this.apiClient.get("getting-started");return new oa(e)}}class ca{constructor(e){this.metadataGettingStartedSettingsApiService=new la(e)}async findGettingStartedSettings(){try{const e=await this.metadataGettingStartedSettingsApiService.get();return new Jt(e.body)}catch(e){return console.error(e),Jt.createFromDefault()}}}class ma{constructor(e){this.port=e}async enableEncryptedMetadata(){await this.port.request("passbolt.metadata.enable-encrypted-metadata-for-existing-instance")}async keepLegacyClearTextMetadata(){await this.port.request("passbolt.metadata.keep-cleartext-metadata-for-existing-instance")}async findGettingStartedSettings(){const e=await this.port.request("passbolt.metadata.find-getting-started-settings");return new Jt(e)}}function da(){return da=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},metadataGettingStartedSettings:null,update:()=>{}});class pa extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.runningUpdatePromise=null}get defaultState(){return{get:this.get.bind(this),metadataGettingStartedSettings:null,update:this.update.bind(this)}}set(e){this.setState({metadataGettingStartedSettings:e})}get(){return null===this.state.metadataGettingStartedSettings?(this.update(),null):this.state.metadataGettingStartedSettings}async update(){if(null===this.runningUpdatePromise){this.runningUpdatePromise=this.props.service.findGettingStartedSettings();const e=await this.runningUpdatePromise;this.set(e),this.runningUpdatePromise=null}else await this.runningUpdatePromise}render(){return n.createElement(ua.Provider,{value:this.state},this.props.children)}}pa.propTypes={service:i().oneOfType([i().instanceOf(ca),i().instanceOf(ma)]),children:i().any};const ha=pa;function ga(e){return class extends n.Component{render(){return n.createElement(ua.Consumer,null,t=>n.createElement(e,da({administrationEncryptedMetadataGettingStartedContext:t,metadataGettingStartedSettings:t.get()},this.props)))}}}var ya,ba;function fa(){return fa=Object.assign?Object.assign.bind():function(e){for(var t=1;tthis.handleSubmenuClick("isContentTypesOpened")},this.state.isContentTypesOpened?n.createElement(Vt,null):n.createElement(Wt,null),n.createElement("span",null,n.createElement(f.x6,null,"Resource types")))))),this.state.isContentTypesOpened&&n.createElement("ul",{id:"administration-sub-menu-content-type",className:"menu"},this.shouldShowGettingStartedMenu&&n.createElement("li",{id:"metadata_getting_started_menu"},n.createElement("div",{className:"row "+(this.isMetadataGettingStartedSelected()?"selected":"")},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:this.handleMetadataGettingStartedClick},n.createElement("span",null,n.createElement(f.x6,null,"Getting started")),n.createElement("span",{className:"chips new"},"new")))))),!this.shouldShowGettingStartedMenu&&n.createElement(n.Fragment,null,n.createElement("li",{id:"metadata_key_menu"},n.createElement("div",{className:"row "+(this.isContentTypesMetadataKeySelected()?"selected":"")},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:this.handleContentTypesMetadataKeyClick},n.createElement("span",null,n.createElement(f.x6,null,"Metadata key")),this.isBeta("metadata")&&n.createElement("span",{className:"chips beta"},"beta")))))),n.createElement("li",{id:"encrypted_metadata_menu"},n.createElement("div",{className:"row "+(this.isContentTypesEncryptedMetadataSelected()?"selected":"")},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:this.handleContentTypesEncryptedMetadataClick},n.createElement("span",null,n.createElement(f.x6,null,"Encrypted metadata")),this.isBeta("metadata")&&n.createElement("span",{className:"chips beta"},"beta")))))),n.createElement("li",{id:"migrate_metadata_menu"},n.createElement("div",{className:"row "+(this.isMigrateMetadataSelected()?"selected":"")},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:this.handleMigrateMetadataClick},n.createElement("span",null,n.createElement(f.x6,null,"Migrate metadata")),this.isBeta("metadata")&&n.createElement("span",{className:"chips beta"},"beta")))))),n.createElement("li",{id:"allowed_content_type_menu"},n.createElement("div",{className:"row "+(this.isAllowedContentTypesSelected()?"selected":"")},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:this.handleAllowedContentTypesClick},n.createElement("span",null,n.createElement(f.x6,null,"Allow content types")),this.isBeta("metadata")&&n.createElement("span",{className:"chips beta"},"beta"))))))))),this.canSeeResourceConfiguration()&&n.createElement("li",{id:"password-configuration",className:"accordion-header"},n.createElement("div",{className:"row"},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:()=>this.handleSubmenuClick("isResourceConfigurationOpened")},this.state.isResourceConfigurationOpened?n.createElement(Vt,null):n.createElement(Wt,null),n.createElement("span",null,n.createElement(f.x6,null,"Resource policies")))))),this.state.isResourceConfigurationOpened&&n.createElement("ul",null,this.canIUsePasswordExpiry&&n.createElement("li",{id:"password_expiry_menu"},n.createElement("div",{className:"row "+(this.isPasswordExpirySettingsSelected()?"selected":"")},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:this.handlePasswordExpirySettingsClick},n.createElement("span",null,n.createElement(f.x6,null,"Password Expiry"))))))),this.canIUsePasswordPolicies&&n.createElement("li",{id:"password_policy_menu"},n.createElement("div",{className:"row "+(this.isPasswordPoliciesSelected()?"selected":"")},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:this.handlePasswordPoliciesClick},n.createElement("span",null,n.createElement(f.x6,null,"Password Policy")),this.isCommunityEdition()&&n.createElement(Ea,{className:"pro-teasing-icon"})))))),this.canIUseSecretHistory&&n.createElement("li",{id:"secret_history_menu"},n.createElement("div",{className:"row "+(this.isSecretHistorySelected()?"selected":"")},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:this.handleSecretHistoryClick},n.createElement("span",null,n.createElement(f.x6,null,"Secret history")),this.isBeta("secretRevisions")&&n.createElement("span",{className:"chips beta"},"beta")))))))),this.canSeeAuthentication()&&n.createElement("li",{id:"authentication",className:"accordion-header"},n.createElement("div",{className:"row"},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:()=>this.handleSubmenuClick("isAuthenticationOpened")},this.state.isAuthenticationOpened?n.createElement(Vt,null):n.createElement(Wt,null),n.createElement("span",null,n.createElement(f.x6,null,"Authentication")))))),this.state.isAuthenticationOpened&&n.createElement("ul",null,this.canIUseUserPassphrasePolicies&&n.createElement("li",{id:"user_passphrase_policies_menu"},n.createElement("div",{className:"row "+(this.isUserPassphrasePoliciesSelected()?"selected":"")},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:this.handleUserPassphrasePoliciesClick},n.createElement("span",null,n.createElement(f.x6,null,"User Passphrase Policies")),this.isCommunityEdition()&&n.createElement(Ea,{className:"pro-teasing-icon"})))))),this.canIUseAccountRecovery&&n.createElement("li",{id:"account_recovery_menu"},n.createElement("div",{className:"row "+(this.isAccountRecoverySelected()?"selected":"")},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:this.handleAccountRecoveryClick},n.createElement("span",null,n.createElement(f.x6,null,"Account Recovery")),this.isCommunityEdition()&&n.createElement(Ea,{className:"pro-teasing-icon"})))))),this.canIUseSso&&n.createElement("li",{id:"sso_menu"},n.createElement("div",{className:"row "+(this.isSsoSelected()?"selected":"")},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:this.handleSsoClick},n.createElement("span",null,n.createElement(f.x6,null,"Single Sign-On")),this.isCommunityEdition()&&n.createElement(Ea,{className:"pro-teasing-icon"})))))),this.canIUseMfaPolicy&&n.createElement("li",{id:"mfa_policy_menu"},n.createElement("div",{className:"row "+(this.isMfaPolicySelected()?"selected":"")},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:this.handleMfaPolicyClick},n.createElement("span",null,n.createElement(f.x6,null,"MFA Policy")),this.isCommunityEdition()&&n.createElement(Ea,{className:"pro-teasing-icon"})))))),this.isMfaEnabled&&n.createElement("li",{id:"mfa_menu"},n.createElement("div",{className:"row "+(this.isMfaSelected()?"selected":"")},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:this.handleMfaClick},n.createElement("span",null,n.createElement(f.x6,null,"Multi Factor Authentication"))))))))),this.canSeeUserProvisionning()&&n.createElement("li",{id:"user-provisionning",className:"accordion-header"},n.createElement("div",{className:"row"},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:()=>this.handleSubmenuClick("isUserProvisionningOpened")},this.state.isUserProvisionningOpened?n.createElement(Vt,null):n.createElement(Wt,null),n.createElement("span",null,n.createElement(f.x6,null,"User provisionning")))))),this.state.isUserProvisionningOpened&&n.createElement("ul",null,this.canIUseScim&&n.createElement("li",{id:"scim_menu"},n.createElement("div",{className:"row "+(this.isScimSelected()?"selected":"")},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:this.handleScimClick},n.createElement("span",null,n.createElement(f.x6,null,"SCIM")),this.isBeta("scim")&&n.createElement("span",{className:"chips beta"},"beta"),this.isCommunityEdition()&&n.createElement(Ea,{className:"pro-teasing-icon"})))))),this.isUserDirectoryEnabled&&n.createElement("li",{id:"user_directory_menu"},n.createElement("div",{className:"row "+(this.isUserDirectorySelected()?"selected":"")},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:this.handleUserDirectoryClick},n.createElement("span",null,n.createElement(f.x6,null,"Users Directory")),this.isCommunityEdition()&&n.createElement(Ea,{className:"pro-teasing-icon"})))))),this.canIUseSelfRegistrationSettings&&n.createElement("li",{id:"self_registration_menu"},n.createElement("div",{className:"row "+(this.isSelfRegistrationSettingsSelected()?"selected":"")},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:this.handleSelfRegistrationClick},n.createElement("span",null,n.createElement(f.x6,null,"Self Registration"))))))))),n.createElement("li",{id:"emails",className:"accordion-header"},n.createElement("div",{className:"row"},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:()=>this.handleSubmenuClick("isEmailsOpened")},this.state.isEmailsOpened?n.createElement(Vt,null):n.createElement(Wt,null),n.createElement("span",null,n.createElement(f.x6,null,"Emails")))))),this.state.isEmailsOpened&&n.createElement("ul",null,this.canIUseSmtpSettings&&n.createElement("li",{id:"smtp_settings_menu"},n.createElement("div",{className:"row "+(this.isSmtpSettingsSelected()?"selected":"")},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:this.handleSmtpSettingsClick},n.createElement("span",null,n.createElement(f.x6,null,"Email server"))))))),n.createElement("li",{id:"email_notification_menu"},n.createElement("div",{className:"row "+(this.isEmailNotificationsSelected()?"selected":"")},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:this.handleEmailNotificationsClick},n.createElement("span",null,n.createElement(f.x6,null,"Email Notifications"))))))))),this.canIUseRbacs&&n.createElement("li",{id:"rbacs_menu"},n.createElement("div",{className:"row "+(this.isRbacSelected()?"selected":"")},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:this.handleRbacsClick},n.createElement("span",null,n.createElement(f.x6,null,"Role-Based Access Control"))))))),this.canIUseLocale&&n.createElement("li",{id:"internationalization_menu"},n.createElement("div",{className:"row "+(this.isInternationalizationSelected()?"selected":"")},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:this.handleInternationalizationClick},n.createElement("span",null,n.createElement(f.x6,null,"Internationalisation"))))))),this.canIUseHealthcheck&&n.createElement("li",{id:"healthcheck_menu"},n.createElement("div",{className:"row "+(this.isHealthcheckSelected()?"selected":"")},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},n.createElement("button",{className:"link no-border",type:"button",onClick:this.handleHealthcheckClick},n.createElement("span",null,n.createElement(f.x6,null,"Passbolt API Status"))))))))))}}va.propTypes={context:i().object,administrationWorkspaceContext:i().object,history:i().object,navigationContext:i().any,metadataGettingStartedSettings:i().instanceOf(Jt)};const wa=(0,x.withRouter)(N(Ke(Ne(ga((0,f.CI)("common")(va))))));var ka,_a;function xa(){return xa=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},getSettings:()=>{},setSettings:()=>{},hasSettingsChanges:()=>{},findMfaSettings:()=>{},save:()=>{},setProcessing:()=>{},isProcessing:()=>{},getErrors:()=>{},setError:()=>{},isSubmitted:()=>{},setSubmitted:()=>{},setErrors:()=>{},clearContext:()=>{}});class Ma extends n.Component{constructor(e){super(e),this.state=this.defaultState;const t=e.context.getApiClientOptions();this.mfaService=new gt(t)}get defaultState(){return{errors:this.initErrors(),currentSettings:null,settings:new Aa,submitted:!1,processing:!0,getCurrentSettings:this.getCurrentSettings.bind(this),getSettings:this.getSettings.bind(this),setSettings:this.setSettings.bind(this),findMfaSettings:this.findMfaSettings.bind(this),hasSettingsChanges:this.hasSettingsChanges.bind(this),isProcessing:this.isProcessing.bind(this),isSubmitted:this.isSubmitted.bind(this),setSubmitted:this.setSubmitted.bind(this),setProcessing:this.setProcessing.bind(this),save:this.save.bind(this),getErrors:this.getErrors.bind(this),setError:this.setError.bind(this),setErrors:this.setErrors.bind(this),clearContext:this.clearContext.bind(this)}}initErrors(){return{yubikeyClientIdentifierError:null,yubikeySecretKeyError:null,duoHostnameError:null,duoClientIdError:null,duoClientSecretError:null}}async findMfaSettings(){this.setProcessing(!0);const e=await this.mfaService.findAllSettings(),t=new Aa(e);this.setState({currentSettings:t}),this.setState({settings:Object.assign({},t)}),this.setProcessing(!1)}getCurrentSettings(){return this.state.currentSettings}getSettings(){return this.state.settings}setSettings(e,t){const a=Object.assign({},this.state.settings,{[e]:t});this.setState({settings:a})}isProcessing(){return this.state.processing}setProcessing(e){this.setState({processing:e})}hasSettingsChanges(){return JSON.stringify(this.state.currentSettings)!==JSON.stringify(this.state.settings)}isSubmitted(){return this.state.submitted}setSubmitted(e){this.setState({submitted:e})}clearContext(){const{currentSettings:e,settings:t,processing:a}=this.defaultState;this.setState({currentSettings:e,settings:t,processing:a})}async save(){this.setProcessing(!0);const e=new Pa(this.state.settings);await this.mfaService.save(e),await this.findMfaSettings()}getErrors(){return this.state.errors}setError(e,t){const a=Object.assign({},this.state.errors,{[e]:t});this.setState({errors:a})}setErrors(e,t=()=>{}){const a=Object.assign({},this.state.errors,e);this.setState({errors:a},t)}render(){return n.createElement(Oa.Provider,{value:this.state},this.props.children)}}Ma.propTypes={context:i().any,children:i().any};const Ua=N(Ma);function Fa(e){return class extends n.Component{render(){return n.createElement(Oa.Consumer,null,t=>n.createElement(e,Da({adminMfaContext:t},this.props)))}}}class ja{constructor(e,t){this.context=e,this.translation=t}static getInstance(e,t){return this.instance||(this.instance=new ja(e,t)),this.instance}static killInstance(){this.instance=null}validateInput(e,t,a){const n=e.trim();return n.length?Qt()(t).test(n)?null:this.translation(a.regex):this.translation(a.required)}validateYubikeyClientIdentifier(e){const t=this.validateInput(e,"^[0-9]{1,64}$",{required:"A client identifier is required.",regex:"The client identifier should be an integer."});return this.context.setError("yubikeyClientIdentifierError",t),t}validateYubikeySecretKey(e){const t=this.validateInput(e,"^[a-zA-Z0-9\\/=+]{10,128}$",{required:"A secret key is required.",regex:"This secret key is not valid."});return this.context.setError("yubikeySecretKeyError",t),t}validateDuoHostname(e){const t=this.validateInput(e,"^api-[a-fA-F0-9]{8,16}\\.duosecurity\\.com$",{required:"A hostname is required.",regex:"This is not a valid hostname."});return this.context.setError("duoHostnameError",t),t}validateDuoClientId(e){const t=this.validateInput(e,"^[a-zA-Z0-9]{16,32}$",{required:"A client id is required.",regex:"This is not a valid client id."});return this.context.setError("duoClientIdError",t),t}validateDuoClientSecret(e){const t=this.validateInput(e,"^[a-zA-Z0-9]{32,128}$",{required:"A client secret is required.",regex:"This is not a valid client secret."});return this.context.setError("duoClientSecretError",t),t}validateYubikeyInputs(){let e=null,t=null;const a=this.context.getSettings();let n={};return a.yubikeyToggle&&(e=this.validateYubikeyClientIdentifier(a.yubikeyClientIdentifier),t=this.validateYubikeySecretKey(a.yubikeySecretKey),n={yubikeyClientIdentifierError:e,yubikeySecretKeyError:t}),n}validateDuoInputs(){let e=null,t=null,a=null,n={};const s=this.context.getSettings();return s.duoToggle&&(e=this.validateDuoHostname(s.duoHostname),t=this.validateDuoClientId(s.duoClientId),a=this.validateDuoClientSecret(s.duoClientSecret),n={duoHostnameError:e,duoClientIdError:t,duoClientSecretError:a}),n}async validate(){const e=Object.assign(this.validateYubikeyInputs(),this.validateDuoInputs());return await this.context.setErrors(e),0===Object.values(e).filter(e=>e).length}}const La=ja;class qa extends n.Component{constructor(e){super(e),this.bindCallbacks(),this.mfaFormService=La.getInstance(this.props.adminMfaContext,this.props.t)}async handleSaveClick(){try{await this.mfaFormService.validate()&&(await this.props.adminMfaContext.save(),this.handleSaveSuccess())}catch(e){this.handleSaveError(e)}finally{this.props.adminMfaContext.setSubmitted(!0),this.props.adminMfaContext.setProcessing(!1)}}isSaveEnabled(){return!this.props.adminMfaContext.isProcessing()&&this.props.adminMfaContext.hasSettingsChanges()}bindCallbacks(){this.handleSaveClick=this.handleSaveClick.bind(this)}async handleSaveSuccess(){await this.props.actionFeedbackContext.displaySuccess(this.props.t("The multi factor authentication settings for the organization were updated."))}async handleSaveError(e){"UserAbortsOperationError"!==e.name&&(console.error(e),await this.handleError(e))}async handleError(e){await this.props.actionFeedbackContext.displayError(e.message)}render(){return n.createElement("div",{className:"actions-wrapper"},n.createElement("button",{id:"save-settings",className:"button primary form",type:"button",disabled:!this.isSaveEnabled(),onClick:this.handleSaveClick},n.createElement("span",null,n.createElement(f.x6,null,"Save"))))}}qa.propTypes={adminMfaContext:i().object,actionFeedbackContext:i().object,t:i().func};const za=Fa(m((0,f.CI)("common")(qa)));var Ka,Va;function Ga(){return Ga=Object.assign?Object.assign.bind():function(e){for(var t=1;t>16&255)+.587*(a>>8&255)+.114*(255&a))/255>.5?"var(--Token-Token-text-and-icon)":"var(--Token-Token-text-and-icon-reversed)"}handleMouseDown(){this.setState({isPassphraseActive:!0})}handleMouseUp(){this.setState({isPassphraseActive:!1})}render(){return n.createElement("div",{className:`input password ${this.props.disabled?"disabled":""} ${this.state.hasPassphraseFocus?"":"no-focus"} ${this.state.isPassphraseActive?"active":""} ${this.props.securityToken?"security":""}`,style:this.props.securityToken?this.passphraseInputStyle:void 0},n.createElement("input",{id:this.props.id,name:this.props.name,maxLength:this.props.maxLength,placeholder:this.props.placeholder,type:this.state.viewPassword&&!this.props.disabled?"text":"password",onKeyUp:this.props.onKeyUp,value:this.props.value,onFocus:this.handlePasswordInputFocus,onBlur:this.handlePasswordInputBlur,onChange:this.handleInputChange,disabled:this.props.disabled,readOnly:this.props.readOnly,autoComplete:this.props.autoComplete,onMouseDown:this.handleMouseDown,onMouseUp:this.handleMouseUp,"aria-required":!0,ref:this.props.inputRef}),this.props.preview&&n.createElement("div",{className:"password-view-wrapper"},n.createElement("button",{type:"button",onClick:this.handleViewPasswordButtonClick,style:this.props.securityToken?this.previewStyle:void 0,className:"password-view infield button-transparent "+(this.props.disabled?"disabled":"")},!this.state.viewPassword&&n.createElement(Ba,{className:"svg-icon eye-open"}),this.state.viewPassword&&n.createElement($a,{className:"svg-icon eye-close"}),n.createElement("span",{className:"visually-hidden"},n.createElement(f.x6,null,"View")))),this.props.securityToken&&n.createElement("div",{className:"security-token-wrapper"},n.createElement("span",{className:"security-token",style:this.securityTokenStyle},this.props.securityToken.code)))}}Ya.defaultProps={id:"",name:"",autoComplete:"off",maxLength:4096},Ya.propTypes={context:i().any,id:i().string,name:i().string,value:i().string,placeholder:i().string,autoComplete:i().string,inputRef:i().object,disabled:i().bool,readOnly:i().bool,preview:i().bool,onChange:i().func,onKeyUp:i().func,securityToken:i().shape({code:i().string,backgroundColor:i().string,textColor:i().string}),maxLength:i().number};const Za=(0,f.CI)("common")(Ya);var Ja=a(961);function Xa(e,t,a){return n.createElement(n.Fragment,null,t&&(0,Ja.createPortal)(e,t,a))}class Qa extends n.Component{constructor(e){super(e),this.mfaFormService=La.getInstance(this.props.adminMfaContext,this.props.t),this.bindCallbacks()}async componentDidMount(){this.props.administrationWorkspaceContext.setDisplayAdministrationWorkspaceAction(za),this.isRunningUnderHttps&&this.props.adminMfaContext.findMfaSettings()}componentWillUnmount(){this.props.administrationWorkspaceContext.resetDisplayAdministrationWorkspaceAction(),this.props.adminMfaContext.clearContext(),La.killInstance(),this.mfaFormService=null}bindCallbacks(){this.handleInputChange=this.handleInputChange.bind(this)}handleInputChange(e){const t=e.target,a="checkbox"===t.type?t.checked:t.value,n=t.name;this.props.adminMfaContext.setSettings(n,a),this.validateInput(n,a)}validateInput(e,t){switch(e){case"yubikeyClientIdentifier":this.mfaFormService.validateYubikeyClientIdentifier(t);break;case"yubikeySecretKey":this.mfaFormService.validateYubikeySecretKey(t);break;case"duoHostname":this.mfaFormService.validateDuoHostname(t);break;case"duoClientId":this.mfaFormService.validateDuoClientId(t);break;case"duoClientSecret":this.mfaFormService.validateDuoClientSecret(t)}}get isRunningUnderHttps(){const e=this.props.context.trustedDomain;return"https:"===new URL(e).protocol}hasAllInputDisabled(){return this.props.adminMfaContext.isProcessing()}render(){const e=this.props.adminMfaContext.isSubmitted(),t=this.props.adminMfaContext.getSettings(),a=this.props.adminMfaContext.getErrors(),s=null!==this.props.adminMfaContext.getCurrentSettings()&&this.props.adminMfaContext.hasSettingsChanges();return n.createElement("div",{className:"row"},n.createElement("div",{className:"mfa-settings main-column"},n.createElement("div",{className:"main-content"},n.createElement("h3",{className:"title"},"Multi Factor Authentication"),!this.isRunningUnderHttps&&n.createElement("p",null,n.createElement(f.x6,null,"Sorry the multi factor authentication feature is only available in a secure context (HTTPS).")),this.isRunningUnderHttps&&n.createElement(n.Fragment,null,n.createElement("p",null,n.createElement(f.x6,null,"In this section you can choose which multi factor authentication will be available.")),n.createElement("div",{className:"provider-section"},n.createElement("h4",{className:"no-border"},n.createElement("span",{className:"input toggle-switch form-element ready"},n.createElement("input",{id:"totp-provider-toggle-button",type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"totpProviderToggle",onChange:this.handleInputChange,checked:t.totpProviderToggle,disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"totp-provider-toggle-button"},n.createElement(f.x6,null,"Time-based One Time Password")))),!t.totpProviderToggle&&n.createElement("p",{className:"description"},n.createElement(f.x6,null,"The Time-based One Time Password provider is disabled for all users.")),t.totpProviderToggle&&n.createElement("p",{className:"description"},n.createElement(f.x6,null,"The Time-based One Time Password provider is enabled for all users. They can setup this provider in their profile and use it as second factor authentication."))),n.createElement("div",{className:"provider-section"},n.createElement("h4",null,n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{id:"yubikey-provider-toggle-button",type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"yubikeyToggle",onChange:this.handleInputChange,checked:t.yubikeyToggle,disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"yubikey-provider-toggle-button"},"Yubikey"))),!t.yubikeyToggle&&n.createElement("p",{className:"description"},n.createElement(f.x6,null,"The Yubikey provider is disabled for all users.")),t.yubikeyToggle&&n.createElement(n.Fragment,null,n.createElement("p",{className:"description"},n.createElement(f.x6,null,"The Yubikey provider is enabled for all users. They can setup this provider in their profile and use it as second factor authentication.")),n.createElement("div",{className:`input text required yubikey ${a.yubikeyClientIdentifierError&&e?"error":""} ${this.hasAllInputDisabled()?"disabled":""}`},n.createElement("label",null,n.createElement(f.x6,null,"Client identifier")),n.createElement("input",{id:"yubikeyClientIdentifier",name:"yubikeyClientIdentifier",className:"required fluid form-element ready",type:"text","aria-required":!0,onChange:this.handleInputChange,value:t.yubikeyClientIdentifier,placeholder:"123456789",disabled:this.hasAllInputDisabled()}),a.yubikeyClientIdentifierError&&e&&n.createElement("div",{className:"yubikey_client_identifier error-message"},a.yubikeyClientIdentifierError)),n.createElement("div",{className:`input required input-secret ${a.yubikeySecretKeyError&&e?"error":""} ${this.hasAllInputDisabled()?"disabled":""}`},n.createElement("label",null,n.createElement(f.x6,null,"Secret key")),n.createElement(Za,{id:"yubikeySecretKey",onChange:this.handleInputChange,autoComplete:"off",name:"yubikeySecretKey",placeholder:"**********",disabled:this.hasAllInputDisabled(),value:t.yubikeySecretKey,preview:!0}),a.yubikeySecretKeyError&&e&&n.createElement("div",{className:"yubikey_secret_key error-message"},a.yubikeySecretKeyError)))),n.createElement("div",{className:"provider-section"},n.createElement("h4",null,n.createElement("span",{className:"input toggle-switch form-element ready"},n.createElement("input",{id:"duo-provider-toggle-button",type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"duoToggle",onChange:this.handleInputChange,checked:t.duoToggle,disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"duo-provider-toggle-button"},"Duo"))),!t.duoToggle&&n.createElement("p",{className:"description"},n.createElement(f.x6,null,"The Duo provider is disabled for all users.")),t.duoToggle&&n.createElement(n.Fragment,null,n.createElement("p",{className:"description enabled"},n.createElement(f.x6,null,"The Duo provider is enabled for all users. They can setup this provider in their profile and use it as second factor authentication.")),n.createElement("div",{className:`input text required ${a.duoHostnameError&&e?"error":""} ${this.hasAllInputDisabled()?"disabled":""}`},n.createElement("label",null,n.createElement(f.x6,null,"Hostname")),n.createElement("input",{id:"duoHostname",type:"text",name:"duoHostname","aria-required":!0,className:"required fluid form-element ready",placeholder:"api-24zlkn4.duosecurity.com",value:t.duoHostname,onChange:this.handleInputChange,disabled:this.hasAllInputDisabled()}),a.duoHostnameError&&e&&n.createElement("div",{className:"duo_hostname error-message"},a.duoHostnameError)),n.createElement("div",{className:`input text required ${a.duoClientIdError&&e?"error":""} ${this.hasAllInputDisabled()?"disabled":""}`},n.createElement("label",null,n.createElement(f.x6,null,"Client id")),n.createElement("input",{id:"duoClientId",type:"text",name:"duoClientId","aria-required":!0,className:"required fluid form-element ready",placeholder:"HASJKDSQJO213123KQSLDF",value:t.duoClientId,onChange:this.handleInputChange,disabled:this.hasAllInputDisabled()}),a.duoClientIdError&&e&&n.createElement("div",{className:"duo_client_id error-message"},a.duoClientIdError)),n.createElement("div",{className:`input text required ${a.duoClientSecretError&&e?"error":""} ${this.hasAllInputDisabled()?"disabled":""}`},n.createElement("label",null,n.createElement(f.x6,null,"Client secret")),n.createElement(Za,{id:"duoClientSecret",onChange:this.handleInputChange,autoComplete:"off",name:"duoClientSecret",placeholder:"**********",disabled:this.hasAllInputDisabled(),value:t.duoClientSecret,preview:!0}),a.duoClientSecretError&&e&&n.createElement("div",{className:"duo_client_secret error-message"},a.duoClientSecretError)))))),s&&n.createElement("div",{className:"warning message"},n.createElement("div",null,n.createElement("p",null,n.createElement(f.x6,null,"Don't forget to save your settings to apply your modification."))))),n.createElement(za,null),Xa(n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"Need some help?")),n.createElement("p",null,n.createElement(f.x6,null,"Check out our Multi Factor Authentication configuration guide.")),n.createElement("a",{className:"button",href:"https://passbolt.com/docs/admin/authentication/mfa/",target:"_blank",rel:"noopener noreferrer"},n.createElement(Sa,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}Qa.propTypes={context:i().object,adminMfaContext:i().object,createPortal:i().func,administrationWorkspaceContext:i().object,t:i().func};const en=N(Fa(Ne((0,f.CI)("common")(Qa))));class tn extends n.Component{render(){let e=0;return n.createElement("div",{className:"breadcrumbs"},n.createElement("ul",{className:"menu"},this.props.items&&this.props.items.map(t=>(e++,n.createElement("li",{key:e},t)))),this.props.children)}}tn.propTypes={items:i().array,children:i().any};const an=tn;class nn extends n.Component{render(){return n.createElement("button",{type:"button",className:"link no-border inline ellipsis",onClick:this.props.onClick},this.props.name)}}nn.propTypes={name:i().string,onClick:i().func};const sn=nn;class rn extends n.Component{get items(){switch(this.props.administrationWorkspaceContext.selectedAdministration){case Te.NONE:return[];case Te.HOME:return[n.createElement(sn,{key:"bread-2",name:this.translate("Home"),onClick:this.onLastBreadcrumbClick.bind(this)})];default:return[n.createElement(sn,{key:"bread-3",name:this.translate("Home"),onClick:this.props.navigationContext.onGoToAdministrationRequested}),n.createElement(sn,{key:"bread-2",name:this.getLastBreadcrumbItemName(),onClick:this.onLastBreadcrumbClick.bind(this)})]}}getLastBreadcrumbItemName(){switch(this.props.administrationWorkspaceContext.selectedAdministration){case Te.MFA:return this.translate("Multi Factor Authentication");case Te.USER_DIRECTORY:return this.translate("Users Directory");case Te.EMAIL_NOTIFICATION:return this.translate("Email Notification");case Te.SUBSCRIPTION:return this.translate("Subscription");case Te.INTERNATIONALIZATION:return this.translate("Internationalisation");case Te.ACCOUNT_RECOVERY:return this.translate("Account Recovery");case Te.SMTP_SETTINGS:return this.translate("Email server");case Te.SELF_REGISTRATION:return this.translate("Self Registration");case Te.SSO:return this.translate("Single Sign-On");case Te.MFA_POLICY:return this.translate("MFA Policy");case Te.RBAC:return this.translate("Role-Based Access Control");case Te.PASSWORD_POLICIES:return this.translate("Password Policy");case Te.USER_PASSPHRASE_POLICIES:return this.translate("User Passphrase Policies");case Te.PASSWORD_EXPIRY:return this.translate("Password Expiry");case Te.HEALTHCHECK:return this.translate("Passbolt API Status");case Te.CONTENT_TYPES_ENCRYPTED_METADATA:return this.translate("Encrypted metadata");case Te.CONTENT_TYPES_METADATA_KEY:return this.translate("Metadata key");case Te.MIGRATE_METADATA:return this.translate("Migrate metadata");case Te.ALLOW_CONTENT_TYPES:return this.translate("Allow content types");case Te.METADATA_GETTING_STARTED:return this.translate("Getting started");case Te.SCIM:return this.translate("SCIM");case Te.SECRET_HISTORY:return this.translate("Secret history");default:return""}}async onLastBreadcrumbClick(){const e=this.props.location.pathname;this.props.history.push({pathname:e})}get translate(){return this.props.t}render(){return n.createElement(an,{items:this.items})}}rn.propTypes={administrationWorkspaceContext:i().object,location:i().object,history:i().object,navigationContext:i().any,t:i().func};const on=(0,x.withRouter)(Ke(Ne((0,f.CI)("common")(rn)))),ln=new class{allPropTypes=(...e)=>(...t)=>{const a=e.map(e=>e(...t)).filter(Boolean);if(0===a.length)return;const n=a.map(e=>e.message).join("\n");return new Error(n)}};var cn;function mn(){return mn=Object.assign?Object.assign.bind():function(e){for(var t=1;te.value!==this.state.selectedValue);return this.props.search&&""!==this.state.search?this.getItemsMatch(e,this.state.search):e}get selectedItemLabel(){const e=this.props.items&&this.props.items.find(e=>e.value===this.state.selectedValue);return e&&e.label||n.createElement(n.Fragment,null," ")}static getDerivedStateFromProps(e,t){return void 0!==e.value&&e.value!==t.selectedValue?{selectedValue:e.value}:null}bindCallback(){this.handleDocumentClickEvent=this.handleDocumentClickEvent.bind(this),this.handleDocumentContextualMenuEvent=this.handleDocumentContextualMenuEvent.bind(this),this.handleDocumentDragStartEvent=this.handleDocumentDragStartEvent.bind(this),this.handleDocumentScrollEvent=this.handleDocumentScrollEvent.bind(this),this.handleSelectClick=this.handleSelectClick.bind(this),this.handleInputChange=this.handleInputChange.bind(this),this.handleItemClick=this.handleItemClick.bind(this),this.handleSelectKeyDown=this.handleSelectKeyDown.bind(this),this.handleItemKeyDown=this.handleItemKeyDown.bind(this),this.handleBlur=this.handleBlur.bind(this)}createRefs(){this.selectedItemRef=n.createRef(),this.selectItemsRef=n.createRef(),this.itemsRef=n.createRef()}componentDidMount(){document.addEventListener("click",this.handleDocumentClickEvent,{capture:!0}),document.addEventListener("contextmenu",this.handleDocumentContextualMenuEvent,{capture:!0}),document.addEventListener("dragstart",this.handleDocumentDragStartEvent,{capture:!0}),document.addEventListener("scroll",this.handleDocumentScrollEvent,{capture:!0})}componentWillUnmount(){document.removeEventListener("click",this.handleDocumentClickEvent,{capture:!0}),document.removeEventListener("contextmenu",this.handleDocumentContextualMenuEvent,{capture:!0}),document.removeEventListener("dragstart",this.handleDocumentDragStartEvent,{capture:!0}),document.removeEventListener("scroll",this.handleDocumentScrollEvent,{capture:!0})}handleDocumentClickEvent(e){this.selectedItemRef.current.contains(e.target)||this.selectItemsRef.current.contains(e.target)||this.closeSelect()}handleDocumentContextualMenuEvent(e){this.selectedItemRef.current.contains(e.target)||this.selectItemsRef.current.contains(e.target)||this.closeSelect()}handleDocumentDragStartEvent(){this.closeSelect()}handleDocumentScrollEvent(e){this.itemsRef.current.contains(e.target)||this.selectItemsRef.current.contains(e.target)||this.closeSelect()}handleSelectClick(){if(this.props.disabled)this.closeSelect();else{const e=!this.state.open;e?this.forceVisibilitySelect():this.resetStyleSelect(),this.setState({open:e})}}getFirstParentWithTransform(){let e=this.selectedItemRef.current.parentElement;for(;null!==e&&""===e.style.getPropertyValue("transform");)e=e.parentElement;return e}forceVisibilitySelect(){const e=this.selectedItemRef.current.getBoundingClientRect(),{width:t,height:a}=e;let{top:n,left:s}=e;const i=this.getFirstParentWithTransform();if(i){const e=i.getBoundingClientRect();n-=e.top,s-=e.left}const r={position:"fixed",zIndex:1,width:t,height:a,top:n,left:s};this.setState({style:r})}handleBlur(e){e.currentTarget.contains(e.relatedTarget)||this.closeSelect()}closeSelect(){this.resetStyleSelect(),this.setState({open:!1})}resetStyleSelect(){this.setState({style:void 0})}handleInputChange(e){const t=e.target,a=t.value,n=t.name;this.setState({[n]:a})}handleItemClick(e){if(this.setState({selectedValue:e.value,open:!1}),"function"==typeof this.props.onChange){const t={target:{value:e.value,name:this.props.name}};this.props.onChange(t)}this.closeSelect()}getItemsMatch(e,t){const a=t&&t.split(/\s+/)||[""];return e.filter(e=>a.every(t=>((e,t)=>(e=>new RegExp((e=>e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"))(e),"i"))(e).test(t))(t,e.label)))}handleSelectKeyDown(e){switch(e.keyCode){case 13:return e.stopPropagation(),void this.handleSelectClick();case 40:return e.preventDefault(),e.stopPropagation(),void(this.state.open?this.focusItem(0):this.handleSelectClick());case 38:return e.preventDefault(),e.stopPropagation(),void(this.state.open?this.focusItem(this.listItemsFiltered.length-1):this.handleSelectClick());case 27:return e.stopPropagation(),void this.closeSelect();default:return}}focusItem(e){this.itemsRef.current.childNodes[e]?.focus()}handleItemKeyDown(e,t){switch(e.keyCode){case 13:return e.stopPropagation(),void this.handleItemClick(t);case 40:return e.stopPropagation(),e.preventDefault(),void(e.target.nextSibling?e.target.nextSibling.focus():this.focusItem(0));case 38:return e.stopPropagation(),e.preventDefault(),void(e.target.previousSibling?e.target.previousSibling.focus():this.focusItem(this.listItemsFiltered.length-1));default:return}}hasFilteredItems(){return this.listItemsFiltered.length>0}render(){return n.createElement("div",{className:`select-container ${this.props.className}`,style:{width:this.state.style?.width,height:this.state.style?.height}},n.createElement("div",{onKeyDown:this.handleSelectKeyDown,onBlur:this.handleBlur,id:this.props.id,className:`select ${this.props.direction} ${this.state.open?"open":""}`,style:this.state.style},n.createElement("div",{ref:this.selectedItemRef,className:"selected-value "+(this.props.disabled?"disabled":""),tabIndex:this.props.disabled?-1:0,onClick:this.handleSelectClick},n.createElement("span",{className:"value"},this.selectedItemLabel),n.createElement(Vt,null)),n.createElement("div",{ref:this.selectItemsRef,className:"select-items "+(this.state.open?"visible":"")},this.props.search&&n.createElement(n.Fragment,null,n.createElement("input",{className:"search-input",name:"search",value:this.state.search,onChange:this.handleInputChange,type:"text"}),n.createElement(dn,{className:"search"})),n.createElement("ul",{ref:this.itemsRef,className:"items"},this.hasFilteredItems()&&this.listItemsFiltered.map(e=>n.createElement("li",{tabIndex:e.disabled?-1:0,key:e.value,title:e.title,className:`option ${e.value}`,onKeyDown:t=>this.handleItemKeyDown(t,e),onClick:()=>this.handleItemClick(e)},e.label)),!this.hasFilteredItems()&&this.props.search&&n.createElement("li",{className:"option no-results"},n.createElement(f.x6,null,"No results match")," ",n.createElement("span",null,this.state.search))))))}}un.defaultProps={id:"",name:"select",className:"",direction:"bottom"},un.propTypes={id:i().string,name:i().string,className:i().string,direction:i().oneOf(Object.values({top:"top",bottom:"bottom",left:"left",right:"right"})),search:i().bool,items:i().array,value:ln.allPropTypes(i().oneOfType([i().string,i().number,i().bool]),(e,t,a)=>{const n=e[t],s=e.items;if(null!==n&&s.length>0&&s.every(e=>e.value!==n))return new Error(`Invalid prop ${t} passed to ${a}. Expected the value ${n} in items.`)}),disabled:i().bool,onChange:i().func};const pn=(0,f.CI)("common")(un);class hn extends n.Component{constructor(e){super(e),this.bindCallbacks()}bindCallbacks(){this.handleClick=this.handleClick.bind(this)}handleClick(){this.props.disabled||this.props.onClick()}render(){return n.createElement("button",{type:"button",disabled:this.props.disabled,className:"link cancel",onClick:this.handleClick},this.props.value)}}hn.defaultProps={value:n.createElement(f.x6,null,"Cancel")},hn.propTypes={disabled:i().bool,onClick:i().func,value:i().oneOfType([i().arrayOf(i().node),i().node,i().string])};const gn=(0,f.CI)("common")(hn);var yn,bn;function fn(){return fn=Object.assign?Object.assign.bind():function(e){for(var t=1;t{const e=this.state.infiniteTimer+2;this.setState({infiniteTimer:e})},500)}calculateInfiniteProgress(){return 100-100/Math.pow(1.1,this.state.infiniteTimer)}handleClose(){this.props.onClose()}render(){const e=this.calculateInfiniteProgress(),t={width:`${e}%`};return n.createElement(qt,{className:"loading-dialog",title:this.props.title,onClose:this.handleClose,disabled:!0},n.createElement("div",{className:"form-content"},n.createElement("label",null,n.createElement(f.x6,null,"Take a deep breath and enjoy being in the present moment...")),n.createElement("div",{className:"progress-bar-wrapper"},n.createElement("span",{className:"progress-bar"},n.createElement("span",{className:"progress "+(100===e?"completed":""),style:t})))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement("button",{type:"submit",disabled:!0,className:"processing"},"Submit",n.createElement(En,null))))}}vn.propTypes={onClose:i().func,title:i().string};const wn=(0,f.CI)("common")(vn),kn="directorysync",_n=class{constructor(e){this.apiClientOptions=e,e.setResourceName(`${kn}`)}async findAll(){this.apiClientOptions.setResourceName(`${kn}/settings`);const e=new pt(this.apiClientOptions);return(await e.findAll()).body}async update(e){this.apiClientOptions.setResourceName(`${kn}`);const t=new pt(this.apiClientOptions);return(await t.update("settings",e)).body}async delete(){return this.apiClientOptions.setResourceName(`${kn}`),new pt(this.apiClientOptions).delete("settings")}async test(e){return this.apiClientOptions.setResourceName(`${kn}/settings/test`),new pt(this.apiClientOptions).create(e)}async simulate(){this.apiClientOptions.setResourceName(`${kn}`);const e=new pt(this.apiClientOptions);return(await e.get("synchronize/dry-run")).body}async synchronize(){this.apiClientOptions.setResourceName(`${kn}/synchronize`);const e=new pt(this.apiClientOptions);return(await e.create({})).body}};class xn extends sa{constructor(e){super(e,xn.RESOURCE_NAME)}static get RESOURCE_NAME(){return"users"}static getSupportedContainOptions(){return["LastLoggedIn","is_mfa_enabled","last_logged_in","gpgkey","groups_users","profile","role","account_recovery_user_setting","pending_account_recovery_request","missing_metadata_key_ids"]}static getSupportedFiltersOptions(){return["search","has-groups","has-access","is-admin","is-active","has-role-id"]}static getSupportedOrdersOptions(){return["Profile.first_name DESC","Profile.first_name ASC","Profile.last_name DESC","Profile.last_name ASC","Profile.created DESC","Profile.created ASC","Profile.modified DESC","Profile.modified ASC"]}async get(e,t){this.assertValidId(e),t=t?this.formatContainOptions(t,xn.getSupportedContainOptions()):null;const a={...t};return(await this.apiClient.get(e,a)).body}async findAll(e,t,a){const n=xn.remapToLegacyContain(e);e=e?this.formatContainOptions(n,xn.getSupportedContainOptions()):null,t=t?this.formatFilterOptions(t,xn.getSupportedFiltersOptions()):null,a=a?this.formatOrderOptions(a,xn.getSupportedOrdersOptions()):null;const s={...e,...t,...a},i=await this.apiClient.findAll(s);return new oa(i)}async findByRoleId(e){return this.assertValidId(e),this.findAll({},{"has-role-id":e})}static remapToLegacyContain(e){if(e)return Object.prototype.hasOwnProperty.call(e,"last_logged_in")&&(e.LastLoggedIn=e.last_logged_in,delete e.last_logged_in),e}async create(e){return this.assertNonEmptyData(e),(await this.apiClient.create(e)).body}async update(e,t){return this.assertValidId(e),this.assertNonEmptyData(t),(await this.apiClient.update(e,t)).body}async updateAvatar(e,t,a){this.assertValidId(e),this.assertNonEmptyData(t),this.assertNonEmptyData(a);const n=this.apiClient.buildUrl(`${this.apiClient.baseUrl}/${e}`),s=new FormData;s.append("profile[avatar][file]",t,a);const i=await this.apiClient.buildFetchOptions();return delete i.headers["content-type"],(await this.apiClient.fetchAndHandleResponse("POST",n,s,i)).body}async delete(e,t,a){this.assertValidId(e);const n=t?{transfer:t}:{};return(await this.apiClient.delete(e,n,{},a)).body}async resendInvite(e){const t=this.apiClient.buildUrl(`${this.apiClient.baseUrl}/recover`),a={username:e},n=this.apiClient.buildBody(a);return this.apiClient.fetchAndHandleResponse("POST",t,n)}async keepSessionAlive(){const e=this.apiClient.buildUrl(`${this.apiClient.baseUrl}/me`,{});return await this.apiClient.fetchAndHandleResponse("GET",e),!0}async requestHelpCredentialsLost(e){const t=this.apiClient.buildBody(e),a=this.apiClient.buildUrl(`${this.apiClient.baseUrl}/recover`,{});return(await this.apiClient.fetchAndHandleResponse("POST",a,t)).body}}const Sn=xn,Cn="mail",Nn="uniqueMember";class Tn{constructor(e=[],t=""){if(!e||0===e?.length)return void this.setDefaut(t);const a=e.domains?.org_domain;this.openCredentials=!0,this.openDirectoryConfiguration=!1,this.openSynchronizationOptions=!1,this.source=e.source,this.authenticationType=a?.authentication_type||"basic",this.directoryType=a?.directory_type||"ad",this.connectionType=a?.connection_type||"plain",this.host=a?.hosts?.length>0?a?.hosts[0]:"",this.hostError=null,this.port=a?.port?.toString()||"389",this.portError=null,this.username=a?.username||"",this.password=a?.password||"",this.domain=a?.domain_name||"",this.domainError=null,this.baseDn=a?.base_dn||"",this.groupPath=e.group_path||"",this.userPath=e.user_path||"",this.groupCustomFilters=e.group_custom_filters||"",this.userCustomFilters=e.user_custom_filters||"",this.groupObjectClass=e.group_object_class||"",this.userObjectClass=e.user_object_class||"",this.useEmailPrefix=e.use_email_prefix_suffix||!1,this.emailPrefix=e.email_prefix||"",this.emailSuffix=e.email_suffix||"",this.fieldsMapping=Tn.defaultFieldsMapping(e.fields_mapping),this.fallbackFields=Tn.defaultFallbackFields(e.field_fallbacks),this.defaultAdmin=e.default_user||t,this.defaultGroupAdmin=e.default_group_admin_user||t,this.groupsParentGroup=e.groups_parent_group||"",this.usersParentGroup=e.users_parent_group||"",this.enabledUsersOnly=Boolean(e.enabled_users_only),this.createUsers=Boolean(e.sync_users_create),this.deleteUsers=Boolean(e.sync_users_delete),this.updateUsers=Boolean(e.sync_users_update),this.createGroups=Boolean(e.sync_groups_create),this.deleteGroups=Boolean(e.sync_groups_delete),this.updateGroups=Boolean(e.sync_groups_update),this.deleteUserBehavior=e.delete_user_behavior||"delete",this.userDirectoryToggle=Boolean(this.port)&&Boolean(this.host)&&e?.enabled}setDefaut(e){this.openCredentials=!0,this.openDirectoryConfiguration=!1,this.openSynchronizationOptions=!1,this.source="default",this.authenticationType="basic",this.directoryType="ad",this.connectionType="plain",this.host="",this.hostError=null,this.port="389",this.portError=null,this.username="",this.password="",this.domain="",this.domainError=null,this.baseDn="",this.groupPath="",this.userPath="",this.groupCustomFilters="",this.userCustomFilters="",this.groupObjectClass="",this.userObjectClass="",this.useEmailPrefix=!1,this.emailPrefix="",this.emailSuffix="",this.fieldsMapping=Tn.defaultFieldsMapping(),this.fallbackFields=Tn.defaultFallbackFields(),this.defaultAdmin=e,this.defaultGroupAdmin=e,this.groupsParentGroup="",this.usersParentGroup="",this.enabledUsersOnly=!1,this.createUsers=!0,this.deleteUsers=!0,this.updateUsers=!0,this.createGroups=!0,this.deleteGroups=!0,this.updateGroups=!0,this.deleteUserBehavior="delete",this.userDirectoryToggle=!1}static defaultFieldsMapping(e={}){return{ad:{user:Object.assign({id:"objectGuid",firstname:"givenName",lastname:"sn",username:Cn,created:"whenCreated",modified:"whenChanged",groups:"memberOf",enabled:"userAccountControl"},e?.ad?.user),group:Object.assign({id:"objectGuid",name:"cn",created:"whenCreated",modified:"whenChanged",users:"member"},e?.ad?.group)},openldap:{user:Object.assign({id:"entryUuid",firstname:"givenname",lastname:"sn",username:"mail",created:"createtimestamp",modified:"modifytimestamp"},e?.openldap?.user),group:Object.assign({id:"entryUuid",name:"cn",created:"createtimestamp",modified:"modifytimestamp",users:Nn},e?.openldap?.group)}}}static defaultFallbackFields(e={}){return{ad:Object.assign({username:""},e?.ad)}}static get DEFAULT_AD_FIELDS_MAPPING_USER_USERNAME_VALUE(){return Cn}static get DEFAULT_OPENLDAP_FIELDS_MAPPING_GROUP_USERS_VALUE(){return Nn}}const An=Tn,In=class{constructor(e){const t=e.directoryType,a=!e.authenticationType||"basic"===e.authenticationType;this.enabled=e.userDirectoryToggle,this.group_path=e.groupPath,this.user_path=e.userPath,this.group_custom_filters=e.groupCustomFilters,this.user_custom_filters=e.userCustomFilters,this.group_object_class="openldap"===t?e.groupObjectClass:"",this.user_object_class="openldap"===t?e.userObjectClass:"",this.use_email_prefix_suffix="openldap"===t&&e.useEmailPrefix,this.email_prefix="openldap"===t&&this.useEmailPrefix?e.emailPrefix:"",this.email_suffix="openldap"===t&&this.useEmailPrefix?e.emailSuffix:"",this.default_user=e.defaultAdmin,this.default_group_admin_user=e.defaultGroupAdmin,this.groups_parent_group=e.groupsParentGroup,this.users_parent_group=e.usersParentGroup,this.enabled_users_only=e.enabledUsersOnly,this.sync_users_create=e.createUsers,this.sync_users_delete=e.deleteUsers,this.sync_users_update=e.updateUsers,this.sync_groups_create=e.createGroups,this.sync_groups_delete=e.deleteGroups,this.sync_groups_update=e.updateGroups,this.fields_mapping=e.fieldsMapping,this.field_fallbacks=e.fallbackFields,this.delete_user_behavior=e.deleteUserBehavior,this.domains={org_domain:{connection_type:e.connectionType,authentication_type:e.authenticationType,directory_type:t,domain_name:e.domain,username:a?e.username:void 0,password:a?e.password:void 0,base_dn:e.baseDn,hosts:[e.host],port:parseInt(e.port,10)}}}};function Rn(){return Rn=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},getSettings:()=>{},setSettings:()=>{},setAdUserFieldsMappingSettings:()=>{},setOpenLdapGroupFieldsMappingSettings:()=>{},setAdFallbackFieldsSettings:()=>{},hadDisabledSettings:()=>{},getUsers:()=>{},hasSettingsChanges:()=>{},findUserDirectorySettings:()=>{},save:()=>{},delete:()=>{},test:()=>{},setProcessing:()=>{},isProcessing:()=>{},getErrors:()=>{},setError:()=>{},simulateUsers:()=>{},requestSynchronization:()=>{},mustOpenSynchronizePopUp:()=>{},synchronizeUsers:()=>{},isSubmitted:()=>{},setSubmitted:()=>{},setErrors:()=>{},clearContext:()=>{}});class On extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.userDirectoryService=new _n(e.context.getApiClientOptions()),this.userApiService=new Sn(e.context.getApiClientOptions())}get defaultState(){return{users:[],errors:this.initErrors(),mustSynchronize:!1,currentSettings:null,settings:new An,submitted:!1,processing:!0,getCurrentSettings:this.getCurrentSettings.bind(this),getSettings:this.getSettings.bind(this),setSettings:this.setSettings.bind(this),setAdUserFieldsMappingSettings:this.setAdUserFieldsMappingSettings.bind(this),setOpenLdapGroupFieldsMappingSettings:this.setOpenLdapGroupFieldsMappingSettings.bind(this),setAdFallbackFieldsSettings:this.setAdFallbackFieldsSettings.bind(this),hadDisabledSettings:this.hadDisabledSettings.bind(this),findUserDirectorySettings:this.findUserDirectorySettings.bind(this),hasSettingsChanges:this.hasSettingsChanges.bind(this),isProcessing:this.isProcessing.bind(this),isSubmitted:this.isSubmitted.bind(this),setSubmitted:this.setSubmitted.bind(this),setProcessing:this.setProcessing.bind(this),simulateUsers:this.simulateUsers.bind(this),synchronizeUsers:this.synchronizeUsers.bind(this),save:this.save.bind(this),delete:this.delete.bind(this),test:this.test.bind(this),getErrors:this.getErrors.bind(this),setError:this.setError.bind(this),setErrors:this.setErrors.bind(this),getUsers:this.getUsers.bind(this),requestSynchronization:this.requestSynchronization.bind(this),mustOpenSynchronizePopUp:this.mustOpenSynchronizePopUp.bind(this),clearContext:this.clearContext.bind(this)}}initErrors(){return{hostError:null,portError:null,domainError:null}}async findUserDirectorySettings(){this.setProcessing(!0);let e=[];try{e=await this.userDirectoryService.findAll()}catch(e){this.handleError(e)}const t=(await this.userApiService.findAll()).body,a=t.find(e=>this.props.context.loggedInUser.id===e.id),n=new An(e,a.id);this.setState({users:this.sortUsers(t),currentSettings:n,settings:Object.assign({},n),processing:!1})}sortUsers(e){const t=e=>`${e.profile.first_name} ${e.profile.last_name}`;return e.sort((e,a)=>t(e).localeCompare(t(a)))}getCurrentSettings(){return this.state.currentSettings}getSettings(){return this.state.settings}requestSynchronization(e){this.setState({mustSynchronize:e})}mustOpenSynchronizePopUp(){return this.state.mustSynchronize}setSettings(e,t){const a=Object.assign({},this.state.settings,{[e]:t});this.isAdFieldsMappingUserUsernameResetNeeded(e,t)&&(a.fieldsMapping.ad.user.username=An.DEFAULT_AD_FIELDS_MAPPING_USER_USERNAME_VALUE,this.setError("fieldsMappingAdUserUsernameError",null),this.setError("fieldsMappingAdUserUsernameFallbackeError",null)),this.isOpenLdapFieldsMappingGroupUsersResetNeeded(e,t)&&(a.fieldsMapping.openldap.group.users=An.DEFAULT_OPENLDAP_FIELDS_MAPPING_GROUP_USERS_VALUE,this.setError("fieldsMappingOpenLdapGroupUsersError",null)),this.setState({settings:a})}isAdFieldsMappingUserUsernameResetNeeded(e,t){return e===Pn&&"openldap"===t}isOpenLdapFieldsMappingGroupUsersResetNeeded(e,t){return e===Pn&&"ad"===t}setAdUserFieldsMappingSettings(e,t){const a=Object.assign({},this.state.settings);a.fieldsMapping.ad.user[e]=t,this.setState({settings:a})}setOpenLdapGroupFieldsMappingSettings(e,t){const a=Object.assign({},this.state.settings);a.fieldsMapping.openldap.group[e]=t,this.setState({settings:a})}setAdFallbackFieldsSettings(e,t){const a=Object.assign({},this.state.settings);a.fallbackFields.ad[e]=t,this.setState({settings:a})}hadDisabledSettings(){const e=this.getCurrentSettings();return Boolean(e?.port)&&Boolean(e?.host)&&!e?.userDirectoryToggle}isProcessing(){return this.state.processing}setProcessing(e){this.setState({processing:e})}hasSettingsChanges(){return JSON.stringify(this.state.currentSettings)!==JSON.stringify(this.state.settings)}isSubmitted(){return this.state.submitted}setSubmitted(e){this.setState({submitted:e})}clearContext(){const{currentSettings:e,settings:t,processing:a}=this.defaultState;this.setState({currentSettings:e,settings:t,processing:a})}async save(){this.setProcessing(!0);const e=new In(this.state.settings);await this.userDirectoryService.update(e),await this.findUserDirectorySettings()}async delete(){this.setProcessing(!0),await this.userDirectoryService.delete(),await this.findUserDirectorySettings()}async test(){this.setProcessing(!0);const e=new In(this.state.settings),t=await this.userDirectoryService.test(e);return this.setProcessing(!1),t}async simulateUsers(){return this.userDirectoryService.simulate()}async synchronizeUsers(){return this.userDirectoryService.synchronize()}getErrors(){return this.state.errors}setError(e,t){const a=Object.assign({},this.state.errors,{[e]:t});this.setState({errors:a})}getUsers(){return this.state.users}setErrors(e,t=()=>{}){const a=Object.assign({},this.state.errors,e);this.setState({errors:a},t)}handleError(e){const t={error:e};this.props.dialogContext.open($t,t)}render(){return n.createElement(Dn.Provider,{value:this.state},this.props.children)}}On.propTypes={context:i().any,children:i().any,dialogContext:i().object};const Mn=N(h(On));function Un(e){return class extends n.Component{render(){return n.createElement(Dn.Consumer,null,t=>n.createElement(e,Rn({adminUserDirectoryContext:t},this.props)))}}}var Fn=a(8140),jn=a.n(Fn);class Ln extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.bindEventHandlers()}get defaultState(){return{loading:!0,openFullReport:!1,userDirectorySimulateSynchronizeResult:null}}bindEventHandlers(){this.handleFullReportClicked=this.handleFullReportClicked.bind(this),this.handleClose=this.handleClose.bind(this),this.handleSynchronize=this.handleSynchronize.bind(this),this.handleDownloadFullReport=this.handleDownloadFullReport.bind(this)}async componentDidMount(){try{const e=await this.props.adminUserDirectoryContext.simulateUsers();this.setState({loading:!1,userDirectorySimulateSynchronizeResult:e})}catch(e){await this.handleError(e)}}async handleError(e){console.error(e),await this.props.actionFeedbackContext.displayError(e.message),this.handleClose()}handleFullReportClicked(){this.setState({openFullReport:!this.state.openFullReport})}handleClose(){this.props.onClose()}handleSynchronize(){this.props.adminUserDirectoryContext.requestSynchronization(!0),this.handleClose()}isLoading(){return this.state.loading}get users(){return this.state.userDirectorySimulateSynchronizeResult?.users}get groups(){return this.state.userDirectorySimulateSynchronizeResult?.groups}get usersSuccess(){return this.users.filter(e=>"success"===e.status)}get groupsSuccess(){return this.groups.filter(e=>"success"===e.status)}get usersWarning(){return this.users.filter(e=>"warning"===e.status)}get groupsWarning(){return this.groups.filter(e=>"warning"===e.status)}get usersError(){return this.users.filter(e=>"error"===e.status)}get groupsError(){return this.groups.filter(e=>"error"===e.status)}get usersIgnored(){return this.users.filter(e=>"ignore"===e.status)}get groupsIgnored(){return this.groups.filter(e=>"ignore"===e.status)}hasSuccessResource(){return this.usersSuccess.length>0||this.groupsSuccess.length>0}hasSuccessUserResource(){return this.usersSuccess.length>0}hasSuccessGroupResource(){return this.groupsSuccess.length>0}hasErrorOrIgnoreResource(){return this.usersError.length>0||this.groupsError.length>0||this.usersWarning.length>0||this.groupsWarning.length>0||this.usersIgnored.length>0||this.groupsIgnored.length>0}getFullReport(){let e="";return e=e.concat(this.getUsersFullReport()),e=e.concat(this.getGroupsFullReport()),e}handleDownloadFullReport(e,t){e.preventDefault();const a=`passbolt-user-directory-simulate-synchronization-report-${(new Date).toISOString().slice(0,19).replace("T","_").replace(/:/g,"-")}.txt`;jn()(t,a,"text/plain")}getUsersFullReport(){if(!(this.usersSuccess.length>0||this.usersWarning.length>0||this.usersError.length>0||this.usersIgnored.length>0))return"";let e="";const t=`-----------------------------------------------\n${this.props.t("Users")}\n-----------------------------------------------\n`;e=e.concat(t);const a=t=>e=e.concat(`- ${t.message}\n`);return this.usersSuccess.length>0&&(e=e.concat(`\n${this.props.t("Success:")}\n`),this.usersSuccess.map(a)),this.usersWarning.length>0&&(e=e.concat(`\n${this.props.t("Warning:")}\n`),this.usersWarning.map(a)),this.usersError.length>0&&(e=e.concat(`\n${this.props.t("Errors:")}\n`),this.usersError.map(a)),this.usersIgnored.length>0&&(e=e.concat(`\n${this.props.t("Ignored:")}\n`),this.usersIgnored.map(a)),e.concat("\n")}getGroupsFullReport(){if(!(this.groupsSuccess.length>0||this.groupsWarning.length>0||this.groupsError.length>0||this.groupsIgnored.length>0))return"";let e="";const t=`-----------------------------------------------\n${this.props.t("Groups")}\n-----------------------------------------------\n`;e=e.concat(t);const a=t=>e=e.concat(`- ${t.message}\n`);return this.groupsSuccess.length>0&&(e=e.concat(`\n${this.props.t("Success:")}\n`),this.groupsSuccess.map(a)),this.groupsWarning.length>0&&(e=e.concat(`\n${this.props.t("Warning:")}\n`),this.groupsWarning.map(a)),this.groupsError.length>0&&(e=e.concat(`\n${this.props.t("Errors:")}\n`),this.groupsError.map(a)),this.groupsIgnored.length>0&&(e=e.concat(`\n${this.props.t("Ignored:")}\n`),this.groupsIgnored.map(a)),e}get translate(){return this.props.t}render(){const e=this.users?String(this.getFullReport()):"";return n.createElement("div",null,this.isLoading()&&n.createElement(wn,{onClose:this.handleClose,title:this.props.t("Synchronize simulation")}),!this.isLoading()&&n.createElement(qt,{className:"ldap-simulate-synchronize-dialog",title:this.props.t("Synchronize simulation report"),onClose:this.handleClose,disabled:this.isLoading()},n.createElement("div",{className:"form-content",onSubmit:this.handleFormSubmit},n.createElement("p",null,n.createElement("strong",null,n.createElement(f.x6,null,"The operation was successful."))),e&&n.createElement(n.Fragment,null,this.hasSuccessResource()&&n.createElement("p",{id:"resources-synchronize"},this.hasSuccessUserResource()&&n.createElement(n.Fragment,null,this.props.t("{{count}} user will be synchronized.",{count:this.usersSuccess.length})),this.hasSuccessUserResource()&&this.hasSuccessGroupResource()&&n.createElement("br",null),this.hasSuccessGroupResource()&&n.createElement(n.Fragment,null,this.props.t("{{count}} group will be synchronized.",{count:this.groupsSuccess.length}))),!this.hasSuccessResource()&&n.createElement("p",{id:"no-resources"}," ",n.createElement(f.x6,null,"No resources will be synchronized.")," "),n.createElement("div",{className:"accordion operation-details "+(this.state.openFullReport?"":"closed")},n.createElement("div",{className:"accordion-header",onClick:this.handleFullReportClicked},n.createElement("button",{type:"button",className:"link no-border"},n.createElement("span",null,n.createElement(f.x6,null,"Full report")),this.state.openFullReport?n.createElement(Vt,{className:"baseline svg-icon"}):n.createElement(Wt,{className:"baseline svg-icon"}))),n.createElement("div",{className:"accordion-content"},n.createElement("div",{className:"input text"},n.createElement("textarea",{className:"full_report",readOnly:!0,value:e}))),n.createElement("button",{type:"button",className:"link download-full-report",onClick:t=>this.handleDownloadFullReport(t,e)},n.createElement(f.x6,null,"Download the Full Report")))),!e&&n.createElement("p",{id:"no-report-message"},n.createElement("span",null,n.createElement(f.x6,null,"There is nothing to synchronize"))),this.hasErrorOrIgnoreResource()&&n.createElement("div",{className:"warning message no-margin"},n.createElement("p",null,n.createElement(f.x6,null,"Some resources will not be synchronized and will require your attention, see the full report.")))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement("a",{className:"button",target:"_blank",rel:"noopener noreferrer",href:"https://www.passbolt.com/docs/admin/user-provisioning/users-directory/advanced-directory-options/"}," ",n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation"))),e&&n.createElement(n.Fragment,null,n.createElement(gn,{disabled:this.isLoading(),onClick:this.handleClose}),n.createElement("button",{type:"submit",disabled:this.isLoading(),className:"primary button form",onClick:this.handleSynchronize},n.createElement(f.x6,null,"Synchronize"))),!e&&n.createElement("button",{disabled:this.isLoading(),className:"primary button form",type:"button",onClick:this.handleClose},n.createElement(f.x6,null,"Ok")))))}}Ln.propTypes={onClose:i().func,dialogContext:i().object,actionFeedbackContext:i().any,adminUserDirectoryContext:i().object,t:i().func};const qn=m(Un((0,f.CI)("common")(Ln)));class zn extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.bindEventHandlers()}get defaultState(){return{loading:!0,openFullReport:!1,userDirectorySynchronizeResult:null}}bindEventHandlers(){this.handleFullReportClicked=this.handleFullReportClicked.bind(this),this.handleClose=this.handleClose.bind(this),this.handleSynchronize=this.handleSynchronize.bind(this),this.handleDownloadFullReport=this.handleDownloadFullReport.bind(this)}async componentDidMount(){try{const e=await this.props.adminUserDirectoryContext.synchronizeUsers();this.setState({loading:!1,userDirectorySynchronizeResult:e})}catch(e){await this.handleError(e)}}async handleError(e){console.error(e),await this.props.actionFeedbackContext.displayError(e.message),this.handleClose()}handleFullReportClicked(){this.setState({openFullReport:!this.state.openFullReport})}handleClose(){this.props.onClose()}handleSynchronize(){this.handleClose()}isLoading(){return this.state.loading}get users(){return this.state.userDirectorySynchronizeResult?.users}get groups(){return this.state.userDirectorySynchronizeResult?.groups}get usersSuccess(){return this.users.filter(e=>"success"===e.status)}get groupsSuccess(){return this.groups.filter(e=>"success"===e.status)}get usersWarning(){return this.users.filter(e=>"warning"===e.status)}get groupsWarning(){return this.groups.filter(e=>"warning"===e.status)}get usersError(){return this.users.filter(e=>"error"===e.status)}get groupsError(){return this.groups.filter(e=>"error"===e.status)}get usersIgnored(){return this.users.filter(e=>"ignore"===e.status)}get groupsIgnored(){return this.groups.filter(e=>"ignore"===e.status)}hasSuccessResource(){return this.usersSuccess.length>0||this.groupsSuccess.length>0}hasSuccessUserResource(){return this.usersSuccess.length>0}hasSuccessGroupResource(){return this.groupsSuccess.length>0}hasErrorOrIgnoreResource(){return this.usersError.length>0||this.groupsError.length>0||this.usersWarning.length>0||this.groupsWarning.length>0||this.usersIgnored.length>0||this.groupsIgnored.length>0}getFullReport(){let e="";return e=e.concat(this.getUsersFullReport()),e=e.concat(this.getGroupsFullReport()),e}handleDownloadFullReport(e,t){e.preventDefault();const a=`passbolt-user-directory-synchronization-report-${(new Date).toISOString().slice(0,19).replace("T","_").replace(/:/g,"-")}.txt`;jn()(t,a,"text/plain")}getUsersFullReport(){if(!(this.usersSuccess.length>0||this.usersWarning.length>0||this.usersError.length>0||this.usersIgnored.length>0))return"";let e="";const t=`-----------------------------------------------\n${this.translate("Users")}\n-----------------------------------------------\n`;e=e.concat(t);const a=t=>e=e.concat(`- ${t.message}\n`);return this.usersSuccess.length>0&&(e=e.concat(`\n${this.translate("Success:")}\n`),this.usersSuccess.map(a)),this.usersWarning.length>0&&(e=e.concat(`\n${this.translate("Warning:")}\n`),this.usersWarning.map(a)),this.usersError.length>0&&(e=e.concat(`\n${this.translate("Errors:")}\n`),this.usersError.map(a)),this.usersIgnored.length>0&&(e=e.concat(`\n${this.translate("Ignored:")}\n`),this.usersIgnored.map(a)),e.concat("\n")}getGroupsFullReport(){if(!(this.groupsSuccess.length>0||this.groupsWarning.length>0||this.groupsError.length>0||this.groupsIgnored.length>0))return"";let e="";const t=`-----------------------------------------------\n${this.translate("Groups")}\n-----------------------------------------------\n`;e=e.concat(t);const a=t=>e=e.concat(`- ${t.message}\n`);return this.groupsSuccess.length>0&&(e=e.concat(`\n${this.translate("Success:")}\n`),this.groupsSuccess.map(a)),this.groupsWarning.length>0&&(e=e.concat(`\n${this.translate("Warning:")}\n`),this.groupsWarning.map(a)),this.groupsError.length>0&&(e=e.concat(`\n${this.translate("Errors:")}\n`),this.groupsError.map(a)),this.groupsIgnored.length>0&&(e=e.concat(`\n${this.translate("Ignored:")}\n`),this.groupsIgnored.map(a)),e}get translate(){return this.props.t}render(){const e=this.users?String(this.getFullReport()):"";return n.createElement("div",null,this.isLoading()&&n.createElement(wn,{onClose:this.handleClose,title:this.translate("Synchronize")}),!this.isLoading()&&n.createElement(qt,{className:"ldap-simulate-synchronize-dialog",title:this.translate("Synchronize report"),onClose:this.handleClose,disabled:this.isLoading()},n.createElement("div",{className:"form-content",onSubmit:this.handleFormSubmit},n.createElement("p",null,n.createElement("strong",null,n.createElement(f.x6,null,"The operation was successful."))),e&&n.createElement(n.Fragment,null,this.hasSuccessResource()&&n.createElement("p",{id:"resources-synchronize"},this.hasSuccessUserResource()&&n.createElement(n.Fragment,null,this.translate("{{count}} user has been synchronized.",{count:this.usersSuccess.length})),this.hasSuccessUserResource()&&this.hasSuccessGroupResource()&&n.createElement("br",null),this.hasSuccessGroupResource()&&n.createElement(n.Fragment,null,this.translate("{{count}} group has been synchronized.",{count:this.groupsSuccess.length}))),!this.hasSuccessResource()&&n.createElement("p",{id:"no-resources"}," ",n.createElement(f.x6,null,"No resources have been synchronized.")," "),n.createElement("div",{className:"accordion operation-details "+(this.state.openFullReport?"":"closed")},n.createElement("div",{className:"accordion-header",onClick:this.handleFullReportClicked},n.createElement("button",{type:"button",className:"link no-border"},n.createElement("span",null,n.createElement(f.x6,null,"Full report")),this.state.openFullReport?n.createElement(Vt,{className:"baeline svg-icon"}):n.createElement(Wt,{className:"baeline svg-icon"}))),n.createElement("div",{className:"accordion-content"},n.createElement("div",{className:"input text"},n.createElement("textarea",{className:"full_report",readOnly:!0,value:e}))),n.createElement("button",{type:"button",className:"link download-full-report",onClick:t=>this.handleDownloadFullReport(t,e)},n.createElement(f.x6,null,"Download the Full Report")))),!e&&n.createElement("p",{id:"no-report-message"},n.createElement("span",null,n.createElement(f.x6,null,"There is nothing to synchronize"))),this.hasErrorOrIgnoreResource()&&n.createElement("div",{className:"warning message no-margin"},n.createElement("p",null,n.createElement(f.x6,null,"Some resources will not be synchronized and will require your attention, see the full report.")))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement("a",{className:"button",target:"_blank",rel:"noopener noreferrer",href:"https://www.passbolt.com/docs/admin/user-provisioning/users-directory/advanced-directory-options/"}," ",n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation"))),n.createElement("button",{disabled:this.isLoading(),className:"primary button form",type:"button",onClick:this.handleClose},n.createElement(f.x6,null,"Ok")))))}}zn.propTypes={onClose:i().func,actionFeedbackContext:i().any,adminUserDirectoryContext:i().object,t:i().func};const Kn=m(Un((0,f.CI)("common")(zn)));class Vn{constructor(e,t){this.context=e,this.translate=t}static getInstance(e,t){return this.instance||(this.instance=new Vn(e,t)),this.instance}static killInstance(){this.instance=null}validate(){const e={hostError:this.validateHostInput(),portError:this.validatePortInput(),domainError:this.validateDomainInput(),fieldsMappingAdUserUsernameError:this.validateFieldsMappingAdUserUsernameInput(),fieldsMappingOpenLdapGroupUsersError:this.validateOpenLdapFieldsMappingGroupUsersInput()};return this.context.setErrors(e),0===Object.values(e).filter(e=>null!==e).length}validateHostInput(){const e=this.context.getSettings(),t=e.host?.trim();return t.length?null:this.translate("A host is required.")}validatePortInput(){let e=null;const t=this.context.getSettings().port.trim();return t.length?Qt()("^[0-9]+").test(t)||(e=this.translate("Only numeric characters allowed.")):e=this.translate("A port is required."),e}validateFieldsMappingAdUserUsernameInput(){const e=this.context.getSettings().fieldsMapping.ad.user.username;let t=null;return e&&""!==e.trim()?e.length>128&&(t=this.translate("The user username field mapping cannot exceed 128 characters.")):t=this.translate("The user username field mapping cannot be empty"),t}validateOpenLdapFieldsMappingGroupUsersInput(){const e=this.context.getSettings().fieldsMapping.openldap.group.users;let t=null;return e&&""!==e.trim()?e.length>128&&(t=this.translate("The group users field mapping cannot exceed 128 characters.")):t=this.translate("The group users field mapping cannot be empty"),t}validateDomainInput(){let e=null;return this.context.getSettings().domain.trim().length||(e=this.translate("A domain name is required.")),e}}const Gn=Vn;class Bn extends n.Component{hasChildren(){return this.props.node.group.groups.length>0}displayUserName(e){return`${e.profile.first_name} ${e.profile.last_name}`}get node(){return this.props.node}render(){return n.createElement("ul",{key:this.node.id},"group"===this.node.type&&n.createElement("li",{className:"group"},this.node.group.name,n.createElement("ul",null,Object.values(this.node.group.users).map(e=>n.createElement("li",{className:"user",key:e.id},e.errors&&n.createElement("span",{className:"error"},e.directory_name),!e.errors&&n.createElement("span",null,this.displayUserName(e.user)," ",n.createElement("em",null,"(",e.user.username,")")))),Object.values(this.node.group.groups).map(e=>n.createElement(Bn,{key:`tree-${e.id}`,node:e})))),"user"===this.node.type&&n.createElement("li",{className:"user"},this.node.errors&&n.createElement("span",{className:"error"},this.node.directory_name),!this.node.errors&&n.createElement("span",null,this.displayUserName(this.node.user)," ",n.createElement("em",null,"(",this.node.user.username,")"))))}}Bn.propTypes={node:i().object};const Wn=Bn;class Hn extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.bindEventHandlers()}get defaultState(){return{loading:!0,openListGroupsUsers:!1,openStructureGroupsUsers:!1,openErrors:!1}}bindEventHandlers(){this.handleListGroupsUsersClicked=this.handleListGroupsUsersClicked.bind(this),this.handleStructureGroupsUsersClicked=this.handleStructureGroupsUsersClicked.bind(this),this.handleErrorsClicked=this.handleErrorsClicked.bind(this),this.handleClose=this.handleClose.bind(this)}componentDidMount(){this.setState({loading:!1})}handleListGroupsUsersClicked(){this.setState({openListGroupsUsers:!this.state.openListGroupsUsers})}handleStructureGroupsUsersClicked(){this.setState({openStructureGroupsUsers:!this.state.openStructureGroupsUsers})}handleErrorsClicked(){this.setState({openErrors:!this.state.openErrors})}handleClose(){this.props.onClose(),this.props.context.setContext({displayTestUserDirectoryDialogProps:null})}hasAllInputDisabled(){return this.state.loading}displayUserName(e){return`${e.profile.first_name} ${e.profile.last_name}`}get users(){return this.props.context.displayTestUserDirectoryDialogProps.userDirectoryTestResult.users}get groups(){return this.props.context.displayTestUserDirectoryDialogProps.userDirectoryTestResult.groups}get tree(){return this.props.context.displayTestUserDirectoryDialogProps.userDirectoryTestResult.tree}get errors(){return this.props.context.displayTestUserDirectoryDialogProps.userDirectoryTestResult.errors}get translate(){return this.props.t}render(){return n.createElement(qt,{className:"ldap-test-settings-dialog",title:this.translate("Test settings report"),onClose:this.handleClose,disabled:this.hasAllInputDisabled()},n.createElement("div",{className:"form-content"},n.createElement("p",null,n.createElement("strong",null,n.createElement(f.x6,null,"A connection could be established. Well done!"))),n.createElement("div",{className:"ldap-test-settings-report"},n.createElement("p",null,this.users.length>0&&n.createElement(n.Fragment,null,this.translate("{{count}} user has been found.",{count:this.users.length})),this.users.length>0&&this.groups.length>0&&n.createElement("br",null),this.groups.length>0&&n.createElement(n.Fragment,null,this.translate("{{count}} group has been found.",{count:this.groups.length}))),n.createElement("div",{className:"accordion directory-list "+(this.state.openListGroupsUsers?"":"closed")},n.createElement("div",{className:"accordion-header",onClick:this.handleListGroupsUsersClicked},n.createElement("button",{type:"button",className:"link no-border"},n.createElement("span",null,n.createElement(f.x6,null,"See list")),this.state.openListGroupsUsers?n.createElement(Vt,{className:"baseline svg-icon"}):n.createElement(Wt,{className:"baseline svg-icon"}))),n.createElement("div",{className:"accordion-content"},n.createElement("div",{className:"directory-list-content"},n.createElement("table",null,n.createElement("tbody",null,n.createElement("tr",null,n.createElement("td",null,n.createElement(f.x6,null,"Groups")),n.createElement("td",null,n.createElement(f.x6,null,"Users"))),n.createElement("tr",null,n.createElement("td",null,this.groups.map(e=>e.errors&&n.createElement("div",{key:e.id},n.createElement("span",{className:"error"},e.directory_name))||n.createElement("div",{key:e.id},e.group.name))),n.createElement("td",null,this.users.map(e=>e.errors&&n.createElement("div",{key:e.id},n.createElement("span",{className:"error"},e.directory_name))||n.createElement("div",{key:e.id},this.displayUserName(e.user)," ",n.createElement("em",null,"(",e.user.username,")")))))))))),n.createElement("div",{className:"accordion accordion-directory-structure "+(this.state.openStructureGroupsUsers?"":"closed")},n.createElement("div",{className:"accordion-header",onClick:this.handleStructureGroupsUsersClicked},n.createElement("button",{type:"button",className:"link no-border"},n.createElement("span",null,n.createElement(f.x6,null,"See structure")),this.state.openStructureGroupsUsers?n.createElement(Vt,{className:"baseline svg-icon"}):n.createElement(Wt,{className:"baseline svg-icon"}))),n.createElement("div",{className:"accordion-content"},n.createElement("div",{className:"directory-structure"},n.createElement("ul",null,n.createElement("li",{className:"group"},"Root",Object.values(this.tree).map(e=>n.createElement(Wn,{key:`tree-${e.id}`,node:e}))))))),this.errors.length>0&&n.createElement(n.Fragment,null,n.createElement("div",{className:"accordion accordion-directory-errors "+(this.state.openErrors?"":"closed")},n.createElement("div",{className:"accordion-header",onClick:this.handleErrorsClicked},n.createElement("button",{type:"button",className:"link no-border"},n.createElement("span",null,n.createElement(f.x6,null,"See error details")),this.state.openErrors?n.createElement(Vt,{className:"baseline svg-icon"}):n.createElement(Wt,{className:"baseline svg-icon"}))),n.createElement("div",{className:"accordion-content"},n.createElement("div",{className:"directory-errors"},n.createElement("textarea",{value:JSON.stringify(this.errors,null," "),readOnly:!0})))),n.createElement("div",{className:"warning message no-margin"},n.createElement("p",{className:""},this.translate("{{count}} entry had errors and will be ignored during synchronization.",{count:this.errors.length})))))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement("button",{type:"button",disabled:this.hasAllInputDisabled(),className:"primary button form",onClick:this.handleClose},n.createElement(f.x6,null,"Ok"))))}}Hn.propTypes={context:i().any,onClose:i().func,t:i().func};const $n=N((0,f.CI)("common")(Hn));var Yn;function Zn(){return Zn=Object.assign?Object.assign.bind():function(e){for(var t=1;tthis.handleFormSubmit("test")},n.createElement(Jn,null),n.createElement("span",null,n.createElement(f.x6,null,"Test settings"))),n.createElement("button",{type:"button",className:"button secondary ",disabled:!this.isSynchronizeEnabled(),onClick:this.handleSimulateSynchronizeClick},n.createElement(ns,null),n.createElement("span",null,n.createElement(f.x6,null,"Simulate synchronize"))),n.createElement("button",{type:"button",className:"button secondary",disabled:!this.isSynchronizeEnabled(),onClick:this.handleSynchronizeClick},n.createElement(os,null),n.createElement("span",null,n.createElement(f.x6,null,"Synchronize")))),n.createElement("button",{type:"button",className:"button primary form",disabled:!this.isSaveEnabled(),onClick:()=>this.handleFormSubmit("save")},n.createElement("span",null,n.createElement(f.x6,null,"Save"))))}}ls.propTypes={context:i().object,dialogContext:i().object,adminUserDirectoryContext:i().object,actionFeedbackContext:i().object,t:i().func};const cs=N(m(h(Un((0,f.CI)("common")(ls)))));var ms,ds;function us(){return us=Object.assign?Object.assign.bind():function(e){for(var t=1;t!0===e.active&&"admin"===e.role.name);return t&&t.map(e=>({value:e.id,label:this.displayUser(e)}))}return[]}getUsersAllowedToBeDefaultGroupAdmin(){const e=this.props.adminUserDirectoryContext.getUsers();if(null!==e){const t=e.filter(e=>!0===e.active);return t&&t.map(e=>({value:e.id,label:this.displayUser(e)}))}return[]}displayUser(e){return`${e.profile.first_name} ${e.profile.last_name} (${e.username})`}shouldShowSourceWarningMessage(){const e=this.props.adminUserDirectoryContext;return"file"===e?.getCurrentSettings()?.source&&e?.hasSettingsChanges()}get settingsSource(){return this.props.adminUserDirectoryContext?.getCurrentSettings()?.source}get configurationSource(){return{env:this.props.t("environment variables"),file:this.props.t("file"),db:this.props.t("database"),default:this.props.t("default")}[this.settingsSource]||this.props.t("unknown")}get connectionType(){return[{value:"plain",label:"ldap://"},{value:"ssl",label:"ldaps:// (ssl)"},{value:"tls",label:"ldaps:// (tls)"}]}get supportedAuthenticationMethod(){return[{value:"basic",label:this.props.t("Basic")},{value:"sasl",label:"SASL (EE)"}]}render(){const e=this.props.adminUserDirectoryContext.getSettings(),t=this.props.adminUserDirectoryContext.getErrors(),a=this.props.adminUserDirectoryContext.isSubmitted(),s=this.props.adminUserDirectoryContext.hadDisabledSettings(),i=null!==this.props.adminUserDirectoryContext.getCurrentSettings()&&this.props.adminUserDirectoryContext.hasSettingsChanges(),r=this.shouldShowSourceWarningMessage()||!this.isUserDirectoryChecked()||i;return n.createElement("div",{className:"row"},n.createElement("div",{className:"ldap-settings main-column"},n.createElement("div",{className:"main-content"},n.createElement("h3",{className:"title"},n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"userDirectoryToggle",onChange:this.handleInputChange,checked:e.userDirectoryToggle,disabled:this.hasAllInputDisabled(),id:"userDirectoryToggle"}),n.createElement("label",{htmlFor:"userDirectoryToggle"},n.createElement(f.x6,null,"Users Directory")))),this.isUserDirectoryChecked()&&n.createElement(n.Fragment,null,n.createElement("p",{className:"description"},n.createElement(f.x6,null,"A Users Directory is configured. The users and groups of passbolt will synchronize with it.")),n.createElement("div",{className:"accordion section-general "+(e.openCredentials?"":"closed")},n.createElement("h4",{className:"accordion-header"},n.createElement("button",{type:"button",className:"link no-border",onClick:this.handleCredentialTitleClicked},e.openCredentials?n.createElement(Vt,{className:"caret-down"}):n.createElement(Wt,{className:"caret-right"}),n.createElement(f.x6,null,"Credentials"))),n.createElement("div",{className:"accordion-content"},n.createElement("div",{className:"radiolist required"},n.createElement("label",null,n.createElement(f.x6,null,"Directory type")),n.createElement("div",{className:"input radio ad openldap form-element "},n.createElement("div",{className:"input radio"},n.createElement("input",{type:"radio",value:"ad",onChange:this.handleInputChange,name:"directoryType",checked:this.isActiveDirectoryChecked(),id:"directoryTypeAd",disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"directoryTypeAd"},n.createElement(f.x6,null,"Active Directory"))),n.createElement("div",{className:"input radio"},n.createElement("input",{type:"radio",value:"openldap",onChange:this.handleInputChange,name:"directoryType",checked:this.isOpenLdapChecked(),id:"directoryTypeOpenLdap",disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"directoryTypeOpenLdap"},n.createElement(f.x6,null,"Open Ldap"))))),n.createElement("div",{className:"input text required ad openldap "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Server url")),n.createElement("div",{className:`input text singleline connection_info ad openldap ${this.hasAllInputDisabled()?"disabled":""} ${this.state.hasFieldFocus?"no-focus":""}`},n.createElement("input",{id:"server-input",type:"text","aria-required":!0,className:"required host ad openldap form-element",name:"host",value:e.host,onChange:this.handleInputChange,placeholder:this.props.t("host"),disabled:this.hasAllInputDisabled()}),n.createElement("div",{className:"protocol",onBlur:this.handleFieldBlur,onFocus:this.handleFieldFocus},n.createElement(pn,{className:"inline",name:"connectionType",items:this.connectionType,value:e.connectionType,onChange:this.handleInputChange,disabled:this.hasAllInputDisabled()})),n.createElement("div",{className:"port ad openldap"},n.createElement("input",{id:"port-input",type:"number","aria-required":!0,className:"required in-field form-element",name:"port",value:e.port,onChange:this.handleInputChange,onBlur:this.handleFieldBlur,onFocus:this.handleFieldFocus,disabled:this.hasAllInputDisabled()}))),t.hostError&&a&&n.createElement("div",{id:"server-input-feedback",className:"error-message"},t.hostError),t.portError&&a&&n.createElement("div",{id:"port-input-feedback",className:"error-message"},t.portError)),n.createElement("div",{className:"select-wrapper input required ad openldap "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Authentication method")),n.createElement(pn,{items:this.supportedAuthenticationMethod,id:"authentication-type-select",name:"authenticationType",value:e.authenticationType,onChange:this.handleInputChange,disabled:this.hasAllInputDisabled()})),"basic"===e.authenticationType&&n.createElement("div",{className:"singleline clearfix"},n.createElement("div",{className:"input text first-field ad openldap "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Username")),n.createElement("input",{id:"username-input",type:"text",className:"fluid form-element",name:"username",value:e.username,onChange:this.handleInputChange,placeholder:this.props.t("Username"),disabled:this.hasAllInputDisabled()})),n.createElement("div",{className:"input text last-field ad openldap "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Password")),n.createElement("input",{id:"password-input",className:"fluid form-element",name:"password",value:e.password,onChange:this.handleInputChange,placeholder:this.props.t("Password"),type:"password",disabled:this.hasAllInputDisabled()}))),n.createElement("div",{className:"input text required ad openldap "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Domain")),n.createElement("input",{id:"domain-name-input","aria-required":!0,type:"text",name:"domain",value:e.domain,onChange:this.handleInputChange,className:"required fluid form-element",placeholder:"domain.ext",disabled:this.hasAllInputDisabled()}),t.domainError&&a&&n.createElement("div",{id:"domain-name-input-feedback",className:"error-message"},t.domainError)),n.createElement("div",{className:"input text ad openldap "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Base DN")),n.createElement("input",{id:"base-dn-input",type:"text",name:"baseDn",value:e.baseDn,onChange:this.handleInputChange,className:"fluid form-element",placeholder:"OU=OrgUsers,DC=mydomain,DC=local",disabled:this.hasAllInputDisabled()}),n.createElement("div",{className:"help-message"},n.createElement(f.x6,null,"The base DN (default naming context) for the domain.")," ",n.createElement(f.x6,null,"If this is empty then it will be queried from the RootDSE."))))),n.createElement("div",{className:"accordion section-directory-configuration "+(e.openDirectoryConfiguration?"":"closed")},n.createElement("h4",{className:"accordion-header"},n.createElement("button",{type:"button",className:"link no-border",onClick:this.handleDirectoryConfigurationTitleClicked},e.openDirectoryConfiguration?n.createElement(Vt,{className:"caret-down"}):n.createElement(Wt,{className:"caret-right"}),n.createElement(f.x6,null,"Directory configuration"))),n.createElement("div",{className:"accordion-content"},n.createElement("div",{className:"input text ad openldap "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Group path")),n.createElement("input",{id:"group-path-input",type:"text","aria-required":!0,name:"groupPath",value:e.groupPath,onChange:this.handleInputChange,className:"required fluid form-element",placeholder:this.props.t("Group path"),disabled:this.hasAllInputDisabled()}),n.createElement("div",{className:"help-message"},n.createElement(f.x6,null,"Group path is used in addition to the base DN while searching groups.")," ",n.createElement(f.x6,null,"Leave empty if users and groups are in the same DN."))),n.createElement("div",{className:"input text ad openldap "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"User path")),n.createElement("input",{id:"user-path-input",type:"text","aria-required":!0,name:"userPath",value:e.userPath,onChange:this.handleInputChange,className:"required fluid form-element",placeholder:this.props.t("User path"),disabled:this.hasAllInputDisabled()}),n.createElement("div",{className:"help-message"},n.createElement(f.x6,null,"User path is used in addition to base DN while searching users."))),n.createElement("div",{className:"input text ad openldap "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Group custom filters")),n.createElement("input",{id:"group-custom-filters-input",type:"text",name:"groupCustomFilters",value:e.groupCustomFilters,onChange:this.handleInputChange,className:"required fluid form-element",placeholder:this.props.t("Group custom filters"),disabled:this.hasAllInputDisabled()}),n.createElement("div",{className:"help-message"},n.createElement(f.x6,null,"Group custom filters are used in addition to the base DN and group path while searching groups.")," ",n.createElement(f.x6,null,"Leave empty if no additional filter is required."))),n.createElement("div",{className:"input text ad openldap "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"User custom filters")),n.createElement("input",{id:"user-custom-filters-input",type:"text",name:"userCustomFilters",value:e.userCustomFilters,onChange:this.handleInputChange,className:"required fluid form-element",placeholder:this.props.t("User custom filters"),disabled:this.hasAllInputDisabled()}),n.createElement("div",{className:"help-message"},n.createElement(f.x6,null,"User custom filters are used in addition to the base DN and user path while searching users.")," ",n.createElement(f.x6,null,"Leave empty if no additional filter is required."))),this.isOpenLdapChecked()&&n.createElement("div",null,n.createElement("div",{className:"input text ad openldap "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Group object class")),n.createElement("input",{id:"group-object-class-input",type:"text","aria-required":!0,name:"groupObjectClass",value:e.groupObjectClass,onChange:this.handleInputChange,className:"required fluid",placeholder:"GroupObjectClass",disabled:this.hasAllInputDisabled()}),n.createElement("div",{className:"help-message"},n.createElement(f.x6,null,"For Openldap only. Defines which group object to use.")," (",n.createElement(f.x6,null,"Default"),": groupOfUniqueNames)")),n.createElement("div",{className:"input text ad openldap "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"User object class")),n.createElement("input",{id:"user-object-class-input",type:"text","aria-required":!0,name:"userObjectClass",value:e.userObjectClass,onChange:this.handleInputChange,className:"required fluid form-element",placeholder:"UserObjectClass",disabled:this.hasAllInputDisabled()}),n.createElement("div",{className:"help-message"},n.createElement(f.x6,null,"For Openldap only. Defines which user object to use.")," (",n.createElement(f.x6,null,"Default"),": inetOrgPerson)")),n.createElement("div",{className:"input text openldap "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Use email prefix / suffix?")),n.createElement("div",{className:"input toggle-switch openldap form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"useEmailPrefix",value:e.useEmailPrefix,onChange:this.handleInputChange,id:"use-email-prefix-suffix-toggle-button",disabled:this.hasAllInputDisabled()}),n.createElement("label",{className:"text",htmlFor:"use-email-prefix-suffix-toggle-button"},n.createElement(f.x6,null,"Build email based on a prefix and suffix?"))),n.createElement("div",{className:"help-message"},n.createElement(f.x6,null,"Use this option when user entries do not include an email address by default"))),this.isUseEmailPrefixChecked()&&n.createElement("div",{className:"singleline clearfix",id:"use-email-prefix-suffix-options"},n.createElement("div",{className:"input text first-field openldap "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Email prefix")),n.createElement("input",{id:"email-prefix-input",type:"text","aria-required":!0,name:"emailPrefix",checked:e.emailPrefix,onChange:this.handleInputChange,className:"required fluid form-element",placeholder:this.props.t("Username"),disabled:this.hasAllInputDisabled()}),n.createElement("div",{className:"help-message"},n.createElement(f.x6,null,"The attribute you would like to use for the first part of the email (usually username)."))),n.createElement("div",{className:"input text last-field openldap "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Email suffix")),n.createElement("input",{id:"email-suffix-input",type:"text","aria-required":!0,name:"emailSuffix",value:e.emailSuffix,onChange:this.handleInputChange,className:"required form-element",placeholder:this.props.t("@your-domain.com"),disabled:this.hasAllInputDisabled()}),n.createElement("div",{className:"help-message"},n.createElement(f.x6,null,"The domain name part of the email (@your-domain-name).")))),n.createElement("div",{className:"input text ad openldap "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Group users field mapping")),n.createElement("input",{id:"field-mapping-openldap-group-users-input",type:"text","aria-required":!0,name:"users",value:e.fieldsMapping.openldap.group.users,onChange:this.handleOpenLdapGroupFieldsMappingInputChange,className:"fluid form-element",placeholder:this.props.t("Group users field mapping"),disabled:this.hasAllInputDisabled()}),n.createElement("div",{className:"help-message"},n.createElement(f.x6,null,"Directory group's users field to map to Passbolt group's field.")),t.fieldsMappingOpenLdapGroupUsersError&&a&&n.createElement("div",{id:"field-mapping-openldap-group-users-input-feedback",className:"error-message"},t.fieldsMappingOpenLdapGroupUsersError))),this.isActiveDirectoryChecked()&&n.createElement("div",{className:"input text ad openldap "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"User username field mapping")),n.createElement("input",{id:"field-mapping-ad-user-username-input",type:"text","aria-required":!0,name:"username",value:e.fieldsMapping.ad.user.username,onChange:this.handleAdUserFieldsMappingInputChange,className:"fluid form-element",placeholder:this.props.t("User username field mapping"),disabled:this.hasAllInputDisabled()}),n.createElement("div",{className:"help-message"},n.createElement(f.x6,null,"Directory user's username field to map to Passbolt user's username field.")),t.fieldsMappingAdUserUsernameError&&a&&n.createElement("div",{id:"field-mapping-ad-user-username-input-feedback",className:"error-message"},t.fieldsMappingAdUserUsernameError)))),n.createElement("div",{className:"accordion section-sync-options "+(e.openSynchronizationOptions?"":"closed")},n.createElement("h4",{className:"accordion-header"},n.createElement("button",{type:"button",className:"link no-border",onClick:this.handleSynchronizationOptionsTitleClicked},e.openSynchronizationOptions?n.createElement(Vt,{className:"caret-down"}):n.createElement(Wt,{className:"caret-right"}),n.createElement(f.x6,null,"Synchronization options"))),n.createElement("div",{className:"accordion-content"},n.createElement("div",{className:"select-wrapper input required ad openldap "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Default admin")),n.createElement(pn,{items:this.getUsersAllowedToBeDefaultAdmin(),id:"default-user-select",name:"defaultAdmin",value:e.defaultAdmin,onChange:this.handleInputChange,disabled:this.hasAllInputDisabled(),search:!0}),n.createElement("div",{className:"help-message"},n.createElement(f.x6,null,"The default admin user is the user that will perform the operations for the the directory."))),n.createElement("div",{className:"select-wrapper input required ad openldap "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Default group admin")),n.createElement(pn,{items:this.getUsersAllowedToBeDefaultGroupAdmin(),id:"default-group-admin-user-select",name:"defaultGroupAdmin",value:e.defaultGroupAdmin,onChange:this.handleInputChange,disabled:this.hasAllInputDisabled(),search:!0}),n.createElement("div",{className:"help-message"},n.createElement(f.x6,null,"The default group manager is the user that will be the group manager of newly created groups."))),n.createElement("div",{className:"input text ad openldap "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Groups parent group")),n.createElement("input",{id:"groups-parent-group-input",type:"text",name:"groupsParentGroup",value:e.groupsParentGroup,onChange:this.handleInputChange,className:"fluid form-element",placeholder:this.props.t("Groups parent group"),disabled:this.hasAllInputDisabled()}),n.createElement("div",{className:"help-message"},n.createElement(f.x6,null,"Synchronize only the groups which are members of this group."))),n.createElement("div",{className:"input text ad openldap "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Users parent group")),n.createElement("input",{id:"users-parent-group-input",type:"text",name:"usersParentGroup",value:e.usersParentGroup,onChange:this.handleInputChange,className:"fluid form-element",placeholder:this.props.t("Users parent group"),disabled:this.hasAllInputDisabled()}),n.createElement("div",{className:"help-message"},n.createElement(f.x6,null,"Synchronize only the users which are members of this group."))),this.isActiveDirectoryChecked&&n.createElement("div",{className:"input text ad openldap "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"User username fallback field")),n.createElement("input",{id:"fallback-fields-ad-username-fallback-input",type:"text","aria-required":!0,name:"username",value:e.fallbackFields.ad.username,onChange:this.handleAdFallbackFieldInputChange,className:"fluid form-element",placeholder:this.props.t("User username fallback field"),disabled:this.hasAllInputDisabled()}),n.createElement("div",{className:"help-message"},n.createElement(f.x6,null,"Directory user's username fallback field to use when user username field cannot be found.")),t.fallbackFieldsAdUsernameError&&a&&n.createElement("div",{id:"fallback-fields-ad-username-fallback-input-feedback",className:"error-message"},t.fallbackFieldsAdUsernameError)),this.isActiveDirectoryChecked()&&n.createElement("div",{className:"input text clearfix ad "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Enabled users only")),n.createElement("div",{className:"input toggle-switch ad form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"enabledUsersOnly",checked:e.enabledUsersOnly,onChange:this.handleInputChange,id:"enabled-users-only-toggle-button",disabled:this.hasAllInputDisabled()}),n.createElement("label",{className:"text",htmlFor:"enabled-users-only-toggle-button"},n.createElement(f.x6,null,"Only synchronize enabled users (AD)")))),n.createElement("div",{className:"input text clearfix ad openldap"},n.createElement("label",null,n.createElement(f.x6,null,"Sync operations")),n.createElement("div",{className:"col6"},n.createElement("div",{className:"input toggle-switch ad openldap form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"createUsers",checked:e.createUsers,onChange:this.handleInputChange,id:"sync-users-create-toggle-button",disabled:this.hasAllInputDisabled()}),n.createElement("label",{className:"text",htmlFor:"sync-users-create-toggle-button"},n.createElement(f.x6,null,"Create users"))),n.createElement("div",{className:"input toggle-switch ad openldap form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"deleteUsers",checked:e.deleteUsers,onChange:this.handleInputChange,id:"sync-users-delete-toggle-button",disabled:this.hasAllInputDisabled()}),n.createElement("label",{className:"text",htmlFor:"sync-users-delete-toggle-button"},n.createElement(f.x6,null,"Delete users"))),n.createElement("div",{className:"input toggle-switch ad openldap form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"updateUsers",checked:e.updateUsers,onChange:this.handleInputChange,id:"sync-users-update-toggle-button",disabled:this.hasAllInputDisabled()}),n.createElement("label",{className:"text",htmlFor:"sync-users-update-toggle-button"},n.createElement(f.x6,null,"Update users")))),n.createElement("div",{className:"col6 last"},n.createElement("div",{className:"input toggle-switch ad openldap form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"createGroups",checked:e.createGroups,onChange:this.handleInputChange,id:"sync-groups-create-toggle-button",disabled:this.hasAllInputDisabled()}),n.createElement("label",{className:"text",htmlFor:"sync-groups-create-toggle-button"},n.createElement(f.x6,null,"Create groups"))),n.createElement("div",{className:"input toggle-switch ad openldap form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"deleteGroups",checked:e.deleteGroups,onChange:this.handleInputChange,id:"sync-groups-delete-toggle-button",disabled:this.hasAllInputDisabled()}),n.createElement("label",{className:"text",htmlFor:"sync-groups-delete-toggle-button"},n.createElement(f.x6,null,"Delete groups"))),n.createElement("div",{className:"input toggle-switch ad openldap form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"updateGroups",checked:e.updateGroups,onChange:this.handleInputChange,id:"sync-groups-update-toggle-button",disabled:this.hasAllInputDisabled()}),n.createElement("label",{className:"text",htmlFor:"sync-groups-update-toggle-button"},n.createElement(f.x6,null,"Update groups"))))),n.createElement("div",{className:"input text clearfix ad openldap"},n.createElement("label",null,n.createElement(f.x6,null,"Delete or suspend users")),n.createElement("div",{className:"help-message"},n.createElement(f.x6,null,"Define the behaviour when existing synchronized users are removed from the users directory"),":"),n.createElement("div",{className:"radiolist-alt"},n.createElement("div",{className:"input radio "+("delete"===e.deleteUserBehavior?"checked":"")},n.createElement("input",{type:"radio",value:"delete",onChange:this.handleInputChange,name:"deleteUserBehavior",checked:"delete"===e.deleteUserBehavior,id:"deleteUserBehaviorDelete",disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"deleteUserBehaviorDelete"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Delete users")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"Delete the users and all the data associated with them.")," ",n.createElement(f.x6,null,"The data will be permanently deleted, this action cannot be undone.")))),n.createElement("div",{className:"input radio "+("disable"===e.deleteUserBehavior?"checked":"")},n.createElement("input",{type:"radio",value:"disable",onChange:this.handleInputChange,name:"deleteUserBehavior",checked:"disable"===e.deleteUserBehavior,id:"deleteUserBehaviorSuspended",disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"deleteUserBehaviorSuspended"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Suspend users")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"Suspend the users, preventing them from signing in to Passbolt and from receiving email notifications.")," ",n.createElement(f.x6,null,"Other users can still share resources with them and add them to groups.")))))))))),r&&n.createElement("div",{className:"warning message"},this.shouldShowSourceWarningMessage()&&n.createElement("div",null,n.createElement(f.x6,null,"These are the settings provided by a configuration file. If you save it, will ignore the settings on file and use the ones from the database.")),i&&n.createElement("div",null,n.createElement(f.x6,null,"Don't forget to save your settings to apply your modification.")),!this.isUserDirectoryChecked()&&n.createElement(n.Fragment,null,s&&n.createElement("div",null,n.createElement(f.x6,null,"The configuration has been disabled as it needs to be checked to make it correct before using it.")),!s&&n.createElement("div",null,n.createElement("p",{className:"description"},n.createElement(f.x6,null,"No Users Directory is configured. Enable it to synchronise your users and groups with passbolt.")))))),n.createElement(cs,null),Xa(n.createElement(n.Fragment,null,n.createElement("div",{className:"sidebar-help-section",id:"user-directory-settings-source"},n.createElement("h3",null,n.createElement(f.x6,null,"Configuration source")),n.createElement("p",null,n.createElement(f.x6,null,"This current configuration source is: "),this.configurationSource,".")),n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"Need help?")),n.createElement("p",null,n.createElement(f.x6,null,"Check out our ldap configuration guide.")),n.createElement("a",{className:"button",href:"https://passbolt.com/docs/admin/user-provisioning/users-directory/",target:"_blank",rel:"noopener noreferrer"},n.createElement(ps,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation"))))),document.getElementById("administration-help-panel")))}}hs.propTypes={adminUserDirectoryContext:i().object,administrationWorkspaceContext:i().object,t:i().func};const gs=Un(Ne((0,f.CI)("common")(hs)));var ys;function bs(){return bs=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},getSettings:()=>{},setSettings:()=>{},hasSettingsChanges:()=>{},findEmailNotificationSettings:()=>{},save:()=>{},setProcessing:()=>{},isProcessing:()=>{},clearContext:()=>{}});class Cs extends n.Component{constructor(e){super(e),this.state=this.defaultState;const t=e.context.getApiClientOptions();this.emailNotificationService=new ws(t)}get defaultState(){return{currentSettings:null,settings:new ks,processing:!0,getCurrentSettings:this.getCurrentSettings.bind(this),getSettings:this.getSettings.bind(this),setSettings:this.setSettings.bind(this),findEmailNotificationSettings:this.findEmailNotificationSettings.bind(this),hasSettingsChanges:this.hasSettingsChanges.bind(this),isProcessing:this.isProcessing.bind(this),setProcessing:this.setProcessing.bind(this),save:this.save.bind(this),clearContext:this.clearContext.bind(this)}}async findEmailNotificationSettings(){this.setProcessing(!0);const e=await this.emailNotificationService.find(),t=new ks(e);this.setState({currentSettings:t}),this.setState({settings:Object.assign({},t)}),this.setProcessing(!1)}getCurrentSettings(){return this.state.currentSettings}getSettings(){return this.state.settings}setSettings(e,t){const a=Object.assign({},this.state.settings,{[e]:t});this.setState({settings:a})}isProcessing(){return this.state.processing}setProcessing(e){this.setState({processing:e})}hasSettingsChanges(){return this.state.currentSettings&&JSON.stringify(this.state.currentSettings)!==JSON.stringify(this.state.settings)}clearContext(){const{currentSettings:e,settings:t,processing:a}=this.defaultState;this.setState({currentSettings:e,settings:t,processing:a})}async save(){this.setProcessing(!0);const e=new _s(this.state.settings);await this.emailNotificationService.save(e),await this.findEmailNotificationSettings()}render(){return n.createElement(Ss.Provider,{value:this.state},this.props.children)}}Cs.propTypes={context:i().any,children:i().any};const Ns=N(Cs);function Ts(e){return class extends n.Component{render(){return n.createElement(Ss.Consumer,null,t=>n.createElement(e,xs({adminEmailNotificationContext:t},this.props)))}}}class As extends n.Component{constructor(e){super(e),this.bindCallbacks()}async handleSaveClick(){try{await this.props.adminEmailNotificationContext.save(),this.handleSaveSuccess()}catch(e){this.handleSaveError(e)}finally{this.props.adminEmailNotificationContext.setProcessing(!1)}}isSaveEnabled(){return!this.props.adminEmailNotificationContext.isProcessing()&&this.props.adminEmailNotificationContext.hasSettingsChanges()}bindCallbacks(){this.handleSaveClick=this.handleSaveClick.bind(this)}async handleSaveSuccess(){await this.props.actionFeedbackContext.displaySuccess(this.props.t("The email notification settings were updated."))}async handleSaveError(e){"UserAbortsOperationError"!==e.name&&(console.error(e),await this.handleError(e))}async handleError(e){await this.props.actionFeedbackContext.displayError(e.message)}render(){return n.createElement("div",{className:"actions-wrapper"},n.createElement("button",{className:"button primary form",type:"button",disabled:!this.isSaveEnabled(),onClick:this.handleSaveClick,id:"save-settings"},n.createElement("span",null,n.createElement(f.x6,null,"Save"))))}}As.propTypes={adminEmailNotificationContext:i().object,actionFeedbackContext:i().object,t:i().func};const Is=Ts(m((0,f.CI)("common")(As)));class Rs extends n.Component{constructor(e){super(e),this.bindCallbacks()}async componentDidMount(){this.props.adminEmailNotificationContext.findEmailNotificationSettings()}componentWillUnmount(){this.props.administrationWorkspaceContext.resetDisplayAdministrationWorkspaceAction(),this.props.adminEmailNotificationContext.clearContext()}bindCallbacks(){this.handleInputChange=this.handleInputChange.bind(this)}handleInputChange(e){const t=e.target.checked,a=e.target.name;this.props.adminEmailNotificationContext.setSettings(a,t)}hasAllInputDisabled(){return this.props.adminEmailNotificationContext.isProcessing()}hasDatabaseSetting(){return this.props.adminEmailNotificationContext.getSettings().hasDatabaseSetting}hasFileConfigSetting(){return this.props.adminEmailNotificationContext.getSettings().hasFileConfigSetting}canUseFolders(){return this.props.context.siteSettings.canIUse("folders")}canUseAccountRecovery(){return this.props.context.siteSettings.canIUse("accountRecovery")}canUsePasswordExpiry(){return this.props.context.siteSettings.canIUse("passwordExpiry")||this.props.context.siteSettings.canIUse("passwordExpiryPolicies")}canUsePasswordExpiryAdvancedSettings(){return this.props.context.siteSettings.canIUse("passwordExpiryPolicies")}get settingsSource(){return this.hasDatabaseSetting()?"db":this.hasFileConfigSetting()?"file":"env"}get configurationSource(){return{env:this.props.t("environment variables"),file:this.props.t("file"),db:this.props.t("database")}[this.settingsSource]||this.props.t("unknown")}render(){const e=this.props.adminEmailNotificationContext.getSettings(),t=e&&this.props.adminEmailNotificationContext.hasSettingsChanges(),a=e&&this.hasFileConfigSetting(),s=e&&this.hasDatabaseSetting(),i=a||t;return n.createElement("div",{className:"row"},n.createElement("div",{className:"email-notification-settings main-column"},n.createElement("div",{className:"main-content"},n.createElement("h3",{className:"title"},n.createElement(f.x6,null,"Email delivery")),n.createElement("div",{className:"divider"}),n.createElement("p",null,n.createElement(f.x6,null,"In this section you can choose which email notifications will be sent.")),n.createElement("div",{className:"section"},n.createElement("div",{className:"password-section"},n.createElement("label",null,n.createElement(f.x6,null,"Passwords")),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"passwordCreate",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.passwordCreate,id:"send-password-create-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"send-password-create-toggle-button"},n.createElement(f.x6,null,"When a password is created, notify its creator."))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"passwordUpdateSelf",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.passwordUpdateSelf,id:"send-password-update-self-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"send-password-update-self-toggle-button"},n.createElement(f.x6,null,"When a password is updated, notify its creator."))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"passwordDeleteSelf",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.passwordDeleteSelf,id:"send-password-delete-self-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"send-password-delete-self-toggle-button"},n.createElement(f.x6,null,"When a password is deleted, notify its creator."))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"passwordUpdate",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.passwordUpdate,id:"send-password-update-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"send-password-update-toggle-button"},n.createElement(f.x6,null,"When a password is updated, notify the users who have access to it."))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"passwordDelete",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.passwordDelete,id:"send-password-delete-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"send-password-delete-toggle-button"},n.createElement(f.x6,null,"When a password is deleted, notify the users who had access to it."))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"passwordShare",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.passwordShare,id:"send-password-share-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"send-password-share-toggle-button"},n.createElement(f.x6,null,"When a password is shared, notify the users who gain access to it.")))),this.canUseFolders()&&n.createElement("div",{className:"folder-section"},n.createElement("label",null,n.createElement(f.x6,null,"Folders")),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"folderCreate",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.folderCreate,id:"send-folder-create-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"send-folder-create-toggle-button"},n.createElement(f.x6,null,"When a folder is created, notify its creator."))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"folderUpdateSelf",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.folderUpdateSelf,id:"send-folder-update-self-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"send-folder-update-self-toggle-button"},n.createElement(f.x6,null,"When a folder is updated, notify its creator."))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"folderDeleteSelf",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.folderDeleteSelf,id:"send-folder-delete-self-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"send-folder-delete-self-toggle-button"},n.createElement(f.x6,null,"When a folder is deleted, notify its creator."))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"folderUpdate",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.folderUpdate,id:"send-folder-update-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"send-folder-update-toggle-button"},n.createElement(f.x6,null,"When a folder is updated, notify the users who have access to it."))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"folderDelete",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.folderDelete,id:"send-folder-delete-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"send-folder-delete-toggle-button"},n.createElement(f.x6,null,"When a folder is deleted, notify the users who had access to it."))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"folderShare",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.folderShare,id:"send-folder-share-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"send-folder-share-toggle-button"},n.createElement(f.x6,null,"When a folder is shared, notify the users who gain access to it."))))),n.createElement("div",{className:"section"},n.createElement("div",{className:"comment-section"},n.createElement("label",null,n.createElement(f.x6,null,"Comments")),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"commentAdd",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.commentAdd,id:"send-comment-add-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"send-comment-add-toggle-button"},n.createElement(f.x6,null,"When a comment is posted on a password, notify the users who have access to this password."))))),n.createElement("div",{className:"section"},n.createElement("div",{className:"group-section"},n.createElement("label",null,n.createElement(f.x6,null,"Group membership")),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"groupDelete",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.groupDelete,id:"send-group-delete-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"send-group-delete-toggle-button"},n.createElement(f.x6,null,"When a group is deleted, notify the users who were members of it."))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"groupUserAdd",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.groupUserAdd,id:"send-group-user-add-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"send-group-user-add-toggle-button"},n.createElement(f.x6,null,"When users are added to a group, notify them."))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"groupUserDelete",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.groupUserDelete,id:"send-group-user-delete-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"send-group-user-delete-toggle-button"},n.createElement(f.x6,null,"When users are removed from a group, notify them."))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"groupUserUpdate",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.groupUserUpdate,id:"send-group-user-update-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"send-group-user-update-toggle-button"},n.createElement(f.x6,null,"When user roles change in a group, notify the corresponding users.")))),n.createElement("div",{className:"group-admin-section"},n.createElement("label",null,n.createElement(f.x6,null,"Group manager")),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"groupManagerUpdate",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.groupManagerUpdate,id:"send-group-manager-update-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"send-group-manager-update-toggle-button"},n.createElement(f.x6,null,"When members of a group change, notify the group manager(s)."))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"groupManagerRequestAddUser",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.groupManagerRequestAddUser,id:"send-group-manager-request-add-user-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"send-group-manager-request-add-user-toggle-button"},n.createElement(f.x6,null,"When group managers are requested to add users to a group, notify them."))))),n.createElement("h3",{className:"title"},n.createElement(f.x6,null,"Registration & Recovery")),n.createElement("div",{className:"divider"}),n.createElement("div",{className:"section"},n.createElement("div",{className:"admin-section"},n.createElement("label",null,n.createElement(f.x6,null,"Admin")),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"userSetupCompleteAdmin",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.userSetupCompleteAdmin,id:"user-setup-complete-admin-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"user-setup-complete-admin-toggle-button"},n.createElement(f.x6,null,"When a user completed a setup, notify all the administrators."))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"userRecoverCompleteAdmin",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.userRecoverCompleteAdmin,id:"user-recover-complete-admin-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"user-recover-complete-admin-toggle-button"},n.createElement(f.x6,null,"When a user completed a recover, notify all the administrators."))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"userRecoverAbortAdmin",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.userRecoverAbortAdmin,id:"user-recover-abort-admin-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"user-recover-abort-admin-toggle-button"},n.createElement(f.x6,null,"When a user aborted a recover, notify all the administrators.")))),n.createElement("div",{className:"user-section"},n.createElement("label",null,n.createElement(f.x6,null,"User")),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"userCreate",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.userCreate,id:"send-user-create-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"send-user-create-toggle-button"},n.createElement(f.x6,null,"When new users are invited to passbolt, notify them."))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"userRecover",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.userRecover,id:"send-user-recover-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"send-user-recover-toggle-button"},n.createElement(f.x6,null,"When users try to recover their account, notify them."))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"userRecoverComplete",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.userRecoverComplete,id:"user-recover-complete-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"user-recover-complete-toggle-button"},n.createElement(f.x6,null,"When users completed the recover of their account, notify them."))))),this.canUseAccountRecovery()&&n.createElement(n.Fragment,null,n.createElement("h3",{className:"title"},n.createElement(f.x6,null,"Account recovery")),n.createElement("div",{className:"divider"}),n.createElement("div",{className:"section"},n.createElement("div",{className:"admin-section"},n.createElement("label",null,n.createElement(f.x6,null,"Admin")),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"accountRecoveryRequestAdmin",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.accountRecoveryRequestAdmin,id:"account-recovery-request-admin-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"account-recovery-request-admin-toggle-button"},n.createElement(f.x6,null,"When an account recovery is requested, notify all the administrators."))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"accountRecoveryRequestPolicyUpdate",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.accountRecoveryRequestPolicyUpdate,id:"account-recovery-policy-update-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"account-recovery-policy-update-toggle-button"},n.createElement(f.x6,null,"When an account recovery policy is updated, notify all the administrators."))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"accountRecoveryRequestCreatedAmin",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.accountRecoveryRequestCreatedAmin,id:"account-recovery-response-created-admin-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"account-recovery-response-created-admin-toggle-button"},n.createElement(f.x6,null,"When an administrator answered to an account recovery request, notify the administrator at the origin of the action."))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"accountRecoveryRequestCreatedAllAdmins",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.accountRecoveryRequestCreatedAllAdmins,id:"account-recovery-response-created-all-admin-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"account-recovery-response-created-all-admin-toggle-button"},n.createElement(f.x6,null,"When an administrator answered to an account recovery request, notify all the administrators.")))),n.createElement("div",{className:"user-section"},n.createElement("label",null,n.createElement(f.x6,null,"User")),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"accountRecoveryRequestUser",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.accountRecoveryRequestUser,id:"account-recovery-request-user-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"account-recovery-request-user-toggle-button"},n.createElement(f.x6,null,"When an account recovery is requested, notify the user."))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"accountRecoveryRequestUserApproved",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.accountRecoveryRequestUserApproved,id:"account-recovery-response-user-approved-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"account-recovery-response-user-approved-toggle-button"},n.createElement(f.x6,null,"When an account recovery is approved, notify the user."))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"accountRecoveryRequestUserRejected",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.accountRecoveryRequestUserRejected,id:"account-recovery-response-user-rejected-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"account-recovery-response-user-rejected-toggle-button"},n.createElement(f.x6,null,"When an account recovery is rejected, notify the user.")))))),this.canUsePasswordExpiry()&&n.createElement(n.Fragment,null,n.createElement("h3",{className:"title"},n.createElement(f.x6,null,"Password expiry")),n.createElement("div",{className:"divider"}),n.createElement("div",{className:"section"},n.createElement("div",{className:"password-expiry-section"},n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"passwordExpiryExpiredUser",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.passwordExpiryExpiredUser,id:"password-expiry-expired-user-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"password-expiry-expired-user-toggle-button"},n.createElement(f.x6,null,"When a permission is revoked on a consumed password, notify the owner(s) to change it.")))))),n.createElement("h3",{className:"title"},n.createElement(f.x6,null,"Email content visibility")),n.createElement("div",{className:"divider"}),n.createElement("p",null,n.createElement(f.x6,null,"In this section you can adjust the composition of the emails, e.g. which information will be included in the notification.")),n.createElement("div",{className:"section"},n.createElement("div",{className:"password-section"},n.createElement("label",null,n.createElement(f.x6,null,"Passwords")),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"showUsername",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.showUsername,id:"show-username-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"show-username-toggle-button"},n.createElement(f.x6,null,"Username"))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"showUri",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.showUri,id:"show-uri-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"show-uri-toggle-button"},n.createElement(f.x6,null,"URI"))),n.createElement("span",{className:"input toggle-switch form-element ready"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"showSecret",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.showSecret,id:"show-secret-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"show-secret-toggle-button"},n.createElement(f.x6,null,"Encrypted secret"))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"showDescription",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.showDescription,id:"show-description-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"show-description-toggle-button"},n.createElement(f.x6,null,"Description")))),n.createElement("div",{className:"comment-section"},n.createElement("label",null,n.createElement(f.x6,null,"Comments")),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"showComment",disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,checked:e.showComment,id:"show-comment-toggle-button"}),n.createElement("label",{className:"text",htmlFor:"show-comment-toggle-button"},n.createElement(f.x6,null,"Comment content")))))),i&&n.createElement("div",{className:"warning message"},t&&n.createElement("div",{id:"email-notification-save-banner"},n.createElement("p",null,n.createElement(f.x6,null,"Don't forget to save your settings to apply your modification."))),a&&!s&&n.createElement("div",{id:"email-notification-fileconfig-exists-banner"},n.createElement("p",null,n.createElement(f.x6,null,"You seem to have Email Notification Settings defined in your passbolt.php (or via environment variables).")," ",n.createElement(f.x6,null,"Submitting the form will overwrite those settings with the ones you choose in the form below."))),a&&s&&n.createElement("div",{id:"email-notification-setting-overridden-banner"},n.createElement("p",null,n.createElement(f.x6,null,"Settings have been found in your database as well as in your passbolt.php (or environment variables).")," ",n.createElement(f.x6,null,"The settings displayed in the form below are the one stored in your database and have precedence over others."))))),n.createElement(Is,null),Xa(n.createElement(n.Fragment,null,n.createElement("div",{className:"sidebar-help-section",id:"email-notifications-source"},n.createElement("h3",null,n.createElement(f.x6,null,"Configuration source")),n.createElement("p",null,n.createElement(f.x6,null,"This current configuration source is: "),this.configurationSource,".")),n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"Need some help?")),n.createElement("p",null,n.createElement(f.x6,null,"For more information about email notification, checkout the dedicated page on the help website.")),n.createElement("a",{className:"button",href:"https://passbolt.com/docs/admin/emails/email-notifications/",target:"_blank",rel:"noopener noreferrer"},n.createElement(Sa,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation"))))),document.getElementById("administration-help-panel")))}}Rs.propTypes={context:i().any,administrationWorkspaceContext:i().object,adminEmailNotificationContext:i().object,t:i().func};const Ps=N(Ts(Ne((0,f.CI)("common")(Rs))));var Ds=a(8097);const Os=class{constructor(e){this.customerId=e?.customer_id||"",this.subscriptionId=e?"subscription_id"in e?e.subscription_id:"N/A":"",this.users=e?.users||null,this.email=e?"email"in e?e.email:"N/A":"",this.expiry=e?.expiry||null,this.created=e?.created||null,this.data=e?.data||null}};function Ms(){return Ms=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},findSubscriptionKey:()=>{},isProcessing:()=>{},setProcessing:()=>{},getActiveUsers:()=>{},clearContext:()=>{}});class Fs extends n.Component{constructor(e){super(e),this.state=this.defaultState}get defaultState(){return{subscription:new Os,processing:!0,getSubscription:this.getSubscription.bind(this),findSubscriptionKey:this.findSubscriptionKey.bind(this),isProcessing:this.isProcessing.bind(this),setProcessing:this.setProcessing.bind(this),getActiveUsers:this.getActiveUsers.bind(this),clearContext:this.clearContext.bind(this)}}async findSubscriptionKey(){this.setProcessing(!0);let e=new Os;try{const t=await this.props.context.onGetSubscriptionKeyRequested();e=new Os(t.toDto())}catch(t){"PassboltSubscriptionError"===t.name&&(e=new Os(t.subscription))}finally{this.setState({subscription:e}),this.setProcessing(!1)}}async getActiveUsers(){return(await this.props.context.port.request("passbolt.users.get-all")).filter(e=>e.active).length}getSubscription(){return this.state.subscription}isProcessing(){return this.state.processing}setProcessing(e){this.setState({processing:e})}clearContext(){const{subscription:e,processing:t}=this.defaultState;this.setState({subscription:e,processing:t})}render(){return n.createElement(Us.Provider,{value:this.state},this.props.children)}}function js(e){return class extends n.Component{render(){return n.createElement(Us.Consumer,null,t=>n.createElement(e,Ms({adminSubscriptionContext:t},this.props)))}}}Fs.propTypes={context:i().any,children:i().any},N(Fs);class Ls extends n.Component{constructor(e){super(e),this.bindCallbacks()}bindCallbacks(){this.getClassName=this.getClassName.bind(this)}getClassName(){let e="button primary form";return this.props.warning?e+=" warning":this.props.attention&&(e+=" attention"),this.props.disabled&&(e+=" disabled"),this.props.processing&&(e+=" processing"),this.props.big&&(e+=" big"),this.props.medium&&(e+=" medium"),this.props.fullWidth&&(e+=" full-width"),e}render(){return n.createElement("button",{type:"submit",className:this.getClassName(),disabled:this.props.disabled},this.props.value||n.createElement(f.x6,null,"Save"),this.props.processing&&n.createElement(En,null))}}Ls.defaultProps={warning:!1,attention:!1},Ls.propTypes={processing:i().bool,disabled:i().bool,value:i().oneOfType([i().arrayOf(i().node),i().node,i().string]),warning:i().bool,attention:i().bool,big:i().bool,medium:i().bool,fullWidth:i().bool};const qs=(0,f.CI)("common")(Ls),zs=class extends he{static getSchema(){return{type:"object",required:["subscription_id","users","expiry","created","data"],properties:{customer_id:{type:"string"},subscription_id:{type:"string"},users:{type:"integer"},email:{type:"string",format:"email"},created:{type:"string",format:"date-time"},expiry:{type:"string",format:"date-time"},data:{type:"string"}}}}get expiry(){return this._props.expiry}toDto(){return Object.assign({},this._props)}toJSON(){return this.toDto()}static get ENTITY_NAME(){return"Subscription"}},Ks=class{constructor(e){this.port=e}async createOrganizationSubscriptionKey(e){(0,ie.A)(e);const t=await this.port.request("passbolt.subscription.create",{data:e});return new zs(t)}async findOrganizationSubscriptionKey(){const e=await this.port.request("passbolt.subscription.get");return new zs(e)}async updateOrganizationSubscriptionKey(e){(0,ie.A)(e);const t=await this.port.request("passbolt.subscription.update",{data:e});return new zs(t)}async deleteOrganizationSubscriptionKey(){await this.port.request("passbolt.subscription.downgrade")}};class Vs extends n.Component{constructor(e){super(e),this.state=this.getDefaultState(),this.initEventHandlers(),this.createInputRef(),this.subscriptionKeyService=new Ks(e.context.port)}getDefaultState(){return{selectedFile:null,key:"",keyError:"",processing:!1,hasBeenValidated:!1}}initEventHandlers(){this.handleCloseClick=this.handleCloseClick.bind(this),this.handleFormSubmit=this.handleFormSubmit.bind(this),this.handleInputChange=this.handleInputChange.bind(this),this.handleKeyInputKeyUp=this.handleKeyInputKeyUp.bind(this),this.handleSelectSubscriptionKeyFile=this.handleSelectSubscriptionKeyFile.bind(this),this.handleSelectFile=this.handleSelectFile.bind(this)}createInputRef(){this.keyInputRef=n.createRef(),this.fileUploaderRef=n.createRef()}componentDidMount(){this.setState({key:this.props.context.editSubscriptionKey?.key||""})}async handleFormSubmit(e){e.preventDefault(),this.state.processing||await this.save()}handleInputChange(e){const t=e.target,a=t.value,n=t.name;this.setState({[n]:a})}handleKeyInputKeyUp(){if(this.state.hasAlreadyBeenValidated){const e=this.validateNameInput();this.setState(e)}}handleCloseClick(){this.props.context.setContext({editSubscriptionKey:null}),this.props.onClose()}handleSelectFile(){this.fileUploaderRef.current.click()}get selectedFilename(){return this.state.selectedFile?this.state.selectedFile.name:""}async handleSelectSubscriptionKeyFile(e){const[t]=e.target.files,a=await this.readSubscriptionKeyFile(t);this.setState({key:a,selectedFile:t}),this.state.hasBeenValidated&&await this.validate()}readSubscriptionKeyFile(e){const t=new FileReader;return new Promise((a,n)=>{t.onloadend=()=>{try{a(t.result)}catch(e){n(e)}},t.readAsText(e)})}async save(){if(!this.state.processing){if(this.setState({hasBeenValidated:!0,processing:!0}),!await this.validate())return this.handleValidateError(),void this.setState({processing:!1});try{this.props.onSave?await this.props.onSave(this.state.key):await this.subscriptionKeyService.updateOrganizationSubscriptionKey(this.state.key),await this.handleSaveSuccess(),await this.props.adminSubscriptionContext.findSubscriptionKey()}catch(e){this.setState({processing:!1}),this.handleSaveError(e),this.focusFieldError()}}}handleValidateError(){this.focusFieldError()}async handleSaveSuccess(){await this.props.actionFeedbackContext.displaySuccess(this.translate("The subscription key has been updated successfully.")),this.props.administrationWorkspaceContext.onMustRefreshSubscriptionKey(),this.props.context.setContext({editSubscriptionKey:null,refreshSubscriptionAnnouncement:!0}),this.props.onClose()}handleSaveError(e){if("PassboltSubscriptionError"===e.name)this.setState({keyError:e.message});else if("EntityValidationError"===e.name)this.setState({keyError:this.translate("The subscription key is invalid.")});else if("PassboltApiFetchError"===e.name&&e.data&&400===e.data.code)this.setState({keyError:e.message});else{console.error(e);const t={error:e};this.props.dialogContext.open($t,t)}}focusFieldError(){this.state.keyError&&this.keyInputRef.current.focus()}validateKeyInput(){const e=this.state.key.trim();let t="";return e.length||(t=this.translate("A subscription key is required.")),new Promise(e=>{this.setState({keyError:t},e)})}async validate(){return this.setState({keyError:""}),await this.validateKeyInput(),""===this.state.keyError}hasAllInputDisabled(){return this.state.processing}get translate(){return this.props.t}render(){return n.createElement(qt,{title:this.props.title??this.translate("Edit subscription key"),onClose:this.handleCloseClick,disabled:this.state.processing,className:"edit-subscription-dialog"},n.createElement("form",{onSubmit:this.handleFormSubmit,noValidate:!0},n.createElement("div",{className:"form-content"},n.createElement("div",{className:`input textarea required ${this.state.keyError?"error":""} ${this.hasAllInputDisabled()?"disabled":""}`},n.createElement("label",{htmlFor:"edit-tag-form-name"},n.createElement(f.x6,null,"Subscription key")),n.createElement("textarea",{id:"edit-subscription-form-key",name:"key",value:this.state.key,onKeyUp:this.handleKeyInputKeyUp,onChange:this.handleInputChange,disabled:this.hasAllInputDisabled(),ref:this.keyInputRef,className:"required full_report",required:"required",autoComplete:"off",autoFocus:!0})),n.createElement("div",{className:"input file "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("input",{type:"file",ref:this.fileUploaderRef,disabled:this.hasAllInputDisabled(),onChange:this.handleSelectSubscriptionKeyFile}),n.createElement("div",{className:"input-file-inline"},n.createElement("input",{type:"text",disabled:!0,placeholder:this.translate("No key file selected"),value:this.selectedFilename}),n.createElement("button",{type:"button",className:"button primary",onClick:this.handleSelectFile,disabled:this.hasAllInputDisabled()},n.createElement("span",null,n.createElement(f.x6,null,"Choose a file")))),this.state.keyError&&n.createElement("div",{className:"key error-message"},this.state.keyError),this.props.warning&&n.createElement("p",null,this.props.warning))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement(gn,{disabled:this.hasAllInputDisabled(),onClick:this.handleCloseClick}),n.createElement(qs,{disabled:this.hasAllInputDisabled(),processing:this.state.processing,value:this.translate("Save")}))))}}Vs.propTypes={context:i().any,onClose:i().func,actionFeedbackContext:i().any,adminSubscriptionContext:i().object,dialogContext:i().any,administrationWorkspaceContext:i().any,title:i().string,warning:i().string,onSave:i().func,t:i().func};const Gs=N(js(Ne(m(h((0,f.CI)("common")(Vs))))));class Bs{constructor(e){this.context=e.context,this.dialogContext=e.dialogContext,this.subscriptionContext=e.adminSubscriptionContext}static getInstance(e){return this.instance||(this.instance=new Bs(e)),this.instance}static killInstance(){this.instance=null}editSubscription(){const e={key:this.subscriptionContext.getSubscription().data};this.context.setContext({editSubscriptionKey:e}),this.dialogContext.open(Gs)}}const Ws=Bs,Hs=(e,t,a)=>{if(null===e)return"n/a";if("Infinity"===e)return t("Never");const n=Ds.c9.fromISO(e),s=n.diffNow().toMillis();return s>-1e3&&s<0?t("Just now"):n.toRelative({locale:a})};class $s extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.bindCallbacks()}get defaultState(){return{processing:!1,confirmed:!1}}bindCallbacks(){this.handleFormSubmit=this.handleFormSubmit.bind(this),this.handleConfirmChange=this.handleConfirmChange.bind(this)}handleConfirmChange(e){this.setState({confirmed:e.target.checked})}async handleFormSubmit(e){if(e.preventDefault(),!this.state.processing){this.setState({processing:!0});try{await this.props.onSubmit()}catch(e){console.error(e)}this.setState({processing:!1})}}get translate(){return this.props.t}render(){return n.createElement(qt,{title:this.translate("Are you sure you want to downgrade?"),onClose:this.props.onClose,disabled:this.state.processing,className:"confirm-downgrade-subscription-dialog"},n.createElement("form",{onSubmit:this.handleFormSubmit,noValidate:!0},n.createElement("div",{className:"form-content"},n.createElement("p",null,n.createElement(f.x6,null,"You are about to downgrade your subscription from Passbolt Pro to Community Edition.")),n.createElement("p",null,n.createElement(f.x6,null,"All settings and data specific to the Pro edition will be permanently lost, including Single Sign-On (SSO) configuration, directory synchronization (AD/SCIM), advanced role-based policies, audit logs and account recovery settings.")),n.createElement("p",null,n.createElement(f.x6,null,"All ongoing processes such as an import will be stopped and the data could be lost. Please make sure your users are not actively using the platform during the process. This process should take a few seconds.")),n.createElement("p",null,n.createElement(f.x6,null,"You and your team will be disconnected at the end of the process.")),n.createElement("p",null,n.createElement(f.x6,null,"Your team will also lose access to premium technical support. This action cannot be undone.")),n.createElement("div",{className:"input checkbox"},n.createElement("input",{id:"confirm-downgrade",type:"checkbox",name:"confirmed",checked:this.state.confirmed,disabled:this.state.processing,onChange:this.handleConfirmChange}),n.createElement("label",{htmlFor:"confirm-downgrade"},n.createElement(f.x6,null,"I confirm I want to downgrade and accept the data loss.")))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement(gn,{disabled:this.state.processing,onClick:this.props.onClose}),n.createElement(qs,{warning:!0,disabled:this.state.processing||!this.state.confirmed,processing:this.state.processing,value:this.translate("Downgrade and lose data")}))))}}$s.propTypes={context:i().any,dialogContext:i().any,actionFeedbackContext:i().any,onSubmit:i().func,onClose:i().func,t:i().func};const Ys=N(h(m((0,f.CI)("common")($s))));var Zs,Js;function Xs(){return Xs=Object.assign?Object.assign.bind():function(e){for(var t=1;tthis.props.dialogContext.close(e),onSubmit:()=>this.handleDowngrade(e)})}async handleDowngrade(e){try{await this.subscriptionKeyService.deleteOrganizationSubscriptionKey(),await this.props.actionFeedbackContext.displaySuccess(this.translate("Subscription has been removed successfully. The instance is now on Community Edition.")),this.props.dialogContext.close(e)}catch(e){if("UserAbortsOperationError"===e?.name)return;this.props.dialogContext.open($t,{error:e})}}handleRenewKey(){const e=this.props.adminSubscriptionContext.getSubscription();this.hasLimitUsersExceeded()?this.props.navigationContext.onGoToNewTab(`https://www.passbolt.com/subscription/ee/update/qty?subscription_id=${e.subscriptionId}&customer_id=${e.customerId}`):(this.hasSubscriptionKeyExpired()||this.hasSubscriptionKeyGoingToExpire())&&this.props.navigationContext.onGoToNewTab(`https://www.passbolt.com/subscription/ee/update/renew?subscription_id=${e.subscriptionId}&customer_id=${e.customerId}`)}handleUpdateKey(){this.subscriptionActionService.editSubscription()}hasSubscriptionKeyExpired(){return Ds.c9.fromISO(this.props.adminSubscriptionContext.getSubscription().expiry){},getLocale:()=>{},supportedLocales:()=>{},setLocale:()=>{},hasLocaleChanges:()=>{},findLocale:()=>{},save:()=>{},setProcessing:()=>{},isProcessing:()=>{},clearContext:()=>{}});class li extends n.Component{constructor(e){super(e),this.state=this.defaultState;const t=e.context.getApiClientOptions();this.internalisationService=new ii(t)}get defaultState(){return{currentLocale:null,locale:"en-UK",processing:!0,getCurrentLocale:this.getCurrentLocale.bind(this),getLocale:this.getLocale.bind(this),setLocale:this.setLocale.bind(this),findLocale:this.findLocale.bind(this),hasLocaleChanges:this.hasLocaleChanges.bind(this),isProcessing:this.isProcessing.bind(this),setProcessing:this.setProcessing.bind(this),save:this.save.bind(this),clearContext:this.clearContext.bind(this)}}findLocale(){this.setProcessing(!0);const e=this.props.context.siteSettings.locale;this.setState({currentLocale:e,locale:e,processing:!1})}getCurrentLocale(){return this.state.currentLocale}getLocale(){return this.state.locale}setLocale(e){this.setState({locale:e})}isProcessing(){return this.state.processing}setProcessing(e){this.setState({processing:e})}hasLocaleChanges(){return this.state.locale!==this.state.currentLocale}clearContext(){const{currentLocale:e,locale:t,processing:a}=this.defaultState;this.setState({currentLocale:e,locale:t,processing:a})}async save(){this.setProcessing(!0),await this.internalisationService.save({value:this.state.locale}),this.props.context.onRefreshLocaleRequested(this.state.locale),this.findLocale()}render(){return n.createElement(oi.Provider,{value:this.state},this.props.children)}}li.propTypes={context:i().any,children:i().any};const ci=N(li);function mi(e){return class extends n.Component{render(){return n.createElement(oi.Consumer,null,t=>n.createElement(e,ri({adminInternationalizationContext:t},this.props)))}}}class di extends n.Component{constructor(e){super(e),this.bindCallbacks()}async handleSaveClick(){try{await this.props.adminInternationalizationContext.save(),this.handleSaveSuccess()}catch(e){this.handleSaveError(e)}finally{this.props.adminInternationalizationContext.setProcessing(!1)}}isSaveEnabled(){return!this.props.adminInternationalizationContext.isProcessing()&&this.props.adminInternationalizationContext.hasLocaleChanges()}bindCallbacks(){this.handleSaveClick=this.handleSaveClick.bind(this)}async handleSaveSuccess(){await this.props.actionFeedbackContext.displaySuccess(this.props.t("The internationalization settings were updated."))}async handleSaveError(e){"UserAbortsOperationError"!==e.name&&(console.error(e),await this.handleError(e))}async handleError(e){await this.props.actionFeedbackContext.displayError(e.message)}render(){return n.createElement("div",{className:"actions-wrapper"},n.createElement("button",{className:"button primary form",id:"save-settings",type:"button",disabled:!this.isSaveEnabled(),onClick:this.handleSaveClick},n.createElement("span",null,n.createElement(f.x6,null,"Save"))))}}di.propTypes={context:i().object,adminInternationalizationContext:i().object,actionFeedbackContext:i().object,t:i().func};const ui=mi(m((0,f.CI)("common")(di)));class pi extends n.Component{constructor(e){super(e),this.bindCallbacks()}componentDidMount(){this.props.adminInternationalizationContext.findLocale()}componentWillUnmount(){this.props.administrationWorkspaceContext.resetDisplayAdministrationWorkspaceAction(),this.props.adminInternationalizationContext.clearContext()}bindCallbacks(){this.handleInputChange=this.handleInputChange.bind(this)}handleInputChange(e){this.props.adminInternationalizationContext.setLocale(e.target.value)}get supportedLocales(){return this.props.context.siteSettings.supportedLocales?this.props.context.siteSettings.supportedLocales.map(e=>({value:e.locale,label:e.label})):[]}render(){const e=this.props.adminInternationalizationContext.getLocale(),t=null!==this.props.adminInternationalizationContext.getCurrentLocale()&&this.props.adminInternationalizationContext.hasLocaleChanges();return n.createElement("div",{className:"row"},n.createElement("div",{className:"internationalisation-settings main-column"},n.createElement("div",{className:"main-content"},n.createElement("h3",{className:"title"},n.createElement(f.x6,null,"Internationalisation")),n.createElement("form",{className:"form"},n.createElement("div",{className:"select-wrapper input"},n.createElement("label",{htmlFor:"app-locale-input"},n.createElement(f.x6,null,"Language")),n.createElement(pn,{id:"locale-input",name:"locale",items:this.supportedLocales,value:e,onChange:this.handleInputChange}),n.createElement("p",null,n.createElement(f.x6,null,"The default language of the organisation."))))),t&&n.createElement("div",{className:"warning message"},n.createElement("div",null,n.createElement("p",null,n.createElement(f.x6,null,"Don't forget to save your settings to apply your modification."))))),n.createElement(ui,null),Xa(n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"Want to contribute?")),n.createElement("p",null,n.createElement(f.x6,null,"Your language is missing or you discovered an error in the translation, help us to improve passbolt.")),n.createElement("a",{className:"button",href:"https://www.passbolt.com/docs/contribute/translation/",target:"_blank",rel:"noopener noreferrer"},n.createElement(si,null),n.createElement("span",null,n.createElement(f.x6,null,"Contribute")))),document.getElementById("administration-help-panel")))}}pi.propTypes={context:i().object,administrationWorkspaceContext:i().object,adminInternationalizationContext:i().object,t:i().func};const hi=N(mi(Ne((0,f.CI)("common")(pi))));function gi(){return gi=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},getKeyInfo:()=>{},changePolicy:()=>{},changePublicKey:()=>{},hasPolicyChanges:()=>{},resetChanges:()=>{},downloadPrivateKey:()=>{},save:()=>{}});class bi extends n.Component{constructor(e){super(e),this.state=this.defaultState}get defaultState(){return{currentPolicy:null,policyChanges:{},findAccountRecoveryPolicy:this.findAccountRecoveryPolicy.bind(this),getKeyInfo:this.getKeyInfo.bind(this),changePolicy:this.changePolicy.bind(this),changePublicKey:this.changePublicKey.bind(this),hasPolicyChanges:this.hasPolicyChanges.bind(this),resetChanges:this.resetChanges.bind(this),downloadPrivateKey:this.downloadPrivateKey.bind(this),save:this.save.bind(this)}}async findAccountRecoveryPolicy(){if(!this.props.context.siteSettings.canIUse("accountRecovery"))return;const e=await this.props.context.port.request("passbolt.account-recovery.get-organization-policy");this.setState({currentPolicy:e})}changePolicy(e){const t=this.state.policyChanges;e===this.state.currentPolicy?.policy?delete t.policy:t.policy=e,"disabled"===e&&delete t.publicKey,this.setState({policyChanges:t})}changePublicKey(e){const t={...this.state.policyChanges,publicKey:e};this.setState({policyChanges:t})}hasPolicyChanges(){return Boolean(this.state.policyChanges?.publicKey)||Boolean(this.state.policyChanges?.policy)}async getKeyInfo(e){return e?this.props.context.port.request("passbolt.keyring.get-key-info",e):null}resetChanges(){this.setState({policyChanges:{}})}async downloadPrivateKey(e){await this.props.context.port.request("passbolt.account-recovery.download-organization-generated-key",e)}async save(e){const t=this.buildPolicySaveDto(),a=await this.props.context.port.request("passbolt.account-recovery.save-organization-policy",t,e);this.setState({currentPolicy:a,policyChanges:{}}),this.props.accountRecoveryContext.reloadAccountRecoveryPolicy()}buildPolicySaveDto(){const e={};return this.state.policyChanges.policy&&(e.policy=this.state.policyChanges.policy),this.state.policyChanges.publicKey&&(e.account_recovery_organization_public_key={armored_key:this.state.policyChanges.publicKey}),e}render(){return n.createElement(yi.Provider,{value:this.state},this.props.children)}}function fi(e){return class extends n.Component{render(){return n.createElement(yi.Consumer,null,t=>n.createElement(e,gi({adminAccountRecoveryContext:t},this.props)))}}}function Ei(){return Ei=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},stop:()=>{}});class wi extends n.Component{constructor(e){super(e),this.state=this.defaultState}get defaultState(){return{workflows:[],start:(e,t)=>{const a=(0,r.A)();return this.setState({workflows:[...this.state.workflows,{key:a,Workflow:e,workflowProps:t}]}),a},stop:async e=>this.setState({workflows:this.state.workflows.filter(t=>e!==t.key)})}}render(){return n.createElement(vi.Provider,{value:this.state},this.props.children)}}wi.displayName="WorkflowContextProvider",wi.propTypes={children:i().any};class ki extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.bindCallbacks(),this.createInputRef()}get defaultState(){return{processing:!1,key:"",keyError:"",password:"",passwordError:"",passwordWarning:"",hasAlreadyBeenValidated:!1,selectedFile:null}}bindCallbacks(){this.handleFormSubmit=this.handleFormSubmit.bind(this),this.handleCloseClick=this.handleCloseClick.bind(this),this.handleInputChange=this.handleInputChange.bind(this),this.handleKeyInputKeyUp=this.handleKeyInputKeyUp.bind(this),this.handlePasswordInputKeyUp=this.handlePasswordInputKeyUp.bind(this),this.handleSelectFile=this.handleSelectFile.bind(this),this.handleSelectOrganizationKeyFile=this.handleSelectOrganizationKeyFile.bind(this)}createInputRef(){this.keyInputRef=n.createRef(),this.fileUploaderRef=n.createRef(),this.passwordInputRef=n.createRef()}handleKeyInputKeyUp(){if(this.state.hasAlreadyBeenValidated){const e=this.validateKeyInput();this.setState(e)}}async handleSelectOrganizationKeyFile(e){const[t]=e.target.files,a=await this.readOrganizationKeyFile(t);this.fillOrganizationKey(a),this.setState({selectedFile:t}),this.state.hasAlreadyBeenValidated&&await this.validate()}readOrganizationKeyFile(e){const t=new FileReader;return new Promise((a,n)=>{t.onloadend=()=>{try{a(t.result)}catch(e){n(e)}},t.readAsText(e)})}fillOrganizationKey(e){this.setState({key:e})}validateKeyInput(){const e=this.state.key.trim();let t="";return e.length||(t=this.translate("An organization key is required.")),new Promise(e=>{this.setState({keyError:t},e)})}focusFirstFieldError(){this.state.keyError?this.keyInputRef.current.focus():this.state.passwordError&&this.passwordInputRef.current.focus()}handlePasswordInputKeyUp(){if(this.state.hasAlreadyBeenValidated)this.setState({passwordError:""});else{const e=this.state.password.length>=4096,t=this.translate("this is the maximum size for this field, make sure your data was not truncated"),a=e?t:"";this.setState({passwordWarning:a})}}handleInputChange(e){const t=e.target,a=t.value,n=t.name;this.setState({[n]:a})}handleSelectFile(){this.fileUploaderRef.current.click()}async handleFormSubmit(e){e.preventDefault(),this.state.processing||await this.save()}async save(){if(this.state.processing)return;if(this.setState({hasAlreadyBeenValidated:!0,processing:!0}),!await this.validate())return this.handleValidateError(),void this.setState({processing:!1});const e={armored_key:this.state.key,passphrase:this.state.password};try{await this.props.context.port.request("passbolt.account-recovery.validate-organization-private-key",e),await this.props.onSubmit(e),this.setState({processing:!1}),this.props.onClose()}catch(e){await this.handleSubmitError(e),this.setState({processing:!1})}}async handleSubmitError(e){"UserAbortsOperationError"!==e.name&&("WrongOrganizationRecoveryKeyError"===e.name?this.setState({expectedFingerprintError:e.expectedFingerprint}):"InvalidMasterPasswordError"===e.name?this.setState({passwordError:this.translate("This is not a valid passphrase.")}):"BadSignatureMessageGpgKeyError"===e.name||"GpgKeyError"===e.name?this.setState({keyError:e.message}):(console.error("Uncaught uncontrolled error"),this.onUnexpectedError(e)))}onUnexpectedError(e){const t={error:e};this.props.dialogContext.open($t,t)}handleValidateError(){this.focusFirstFieldError()}async validate(){return this.setState({keyError:"",passwordError:"",expectedFingerprintError:""}),await this.validateKeyInput(),""===this.state.keyError&&""===this.state.passwordError}hasAllInputDisabled(){return this.state.processing}handleCloseClick(){this.props.onClose()}formatFingerprint(e){if(!e)return n.createElement(n.Fragment,null);const t=e.toUpperCase().replace(/.{4}/g,"$& ");return n.createElement(n.Fragment,null,t.substr(0,24),n.createElement("br",null),t.substr(25))}get selectedFilename(){return this.state.selectedFile?this.state.selectedFile.name:""}get translate(){return this.props.t}render(){return n.createElement(qt,{title:this.translate("Organization Recovery Key"),onClose:this.handleCloseClick,disabled:this.state.processing,className:"provide-organization-recover-key-dialog"},n.createElement("form",{onSubmit:this.handleFormSubmit,noValidate:!0},n.createElement("div",{className:"form-content provide-organization-key"},n.createElement("div",{className:"input textarea required "+(this.state.keyError||this.state.expectedFingerprintError?"error":"")},n.createElement("label",{htmlFor:"organization-recover-form-key"},n.createElement(f.x6,null,"Enter the private key used by your organization for account recovery")),n.createElement("textarea",{id:"organization-recover-form-key",name:"key",value:this.state.key,onKeyUp:this.handleKeyInputKeyUp,onChange:this.handleInputChange,disabled:this.hasAllInputDisabled(),ref:this.keyInputRef,className:"required",placeholder:this.translate("Paste the OpenPGP Private key here"),required:"required",autoComplete:"off",autoFocus:!0})),n.createElement("div",{className:"input file"},n.createElement("input",{type:"file",id:"dialog-import-private-key",ref:this.fileUploaderRef,disabled:this.hasAllInputDisabled(),onChange:this.handleSelectOrganizationKeyFile}),n.createElement("label",{htmlFor:"dialog-import-private-key"},n.createElement(f.x6,null,"Select a file to import")),n.createElement("div",{className:"input-file-inline"},n.createElement("input",{type:"text",disabled:!0,placeholder:this.translate("No file selected"),defaultValue:this.selectedFilename}),n.createElement("button",{className:"button primary",type:"button",disabled:this.hasAllInputDisabled(),onClick:this.handleSelectFile},n.createElement("span",null,n.createElement(f.x6,null,"Choose a file")))),this.state.keyError&&n.createElement("div",{className:"key error-message"},this.state.keyError),this.state.expectedFingerprintError&&n.createElement("div",{className:"key error-message"},n.createElement(f.x6,null,"Error, this is not the current organization recovery key."),n.createElement("br",null),n.createElement(f.x6,null,"Expected fingerprint:"),n.createElement("br",null),n.createElement("br",null),n.createElement("span",{className:"fingerprint"},this.formatFingerprint(this.state.expectedFingerprintError)))),n.createElement("div",{className:"input-password-wrapper input "+(this.state.passwordError?"error":"")},n.createElement("label",{htmlFor:"generate-organization-key-form-password"},n.createElement(f.x6,null,"Organization key passphrase"),this.state.passwordWarning&&n.createElement(tt,null)),n.createElement(Za,{id:"generate-organization-key-form-password",name:"password",placeholder:this.translate("Passphrase"),autoComplete:"new-password",onKeyUp:this.handlePasswordInputKeyUp,value:this.state.password,securityToken:this.props.context.userSettings.getSecurityToken(),preview:!0,onChange:this.handleInputChange,disabled:this.hasAllInputDisabled(),inputRef:this.passwordInputRef}),this.state.passwordError&&n.createElement("div",{className:"password error-message"},this.state.passwordError),this.state.passwordWarning&&n.createElement("div",{className:"password warning-message"},n.createElement("strong",null,n.createElement(f.x6,null,"Warning:"))," ",this.state.passwordWarning))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement(gn,{disabled:this.hasAllInputDisabled(),onClick:this.handleCloseClick}),n.createElement(qs,{disabled:this.hasAllInputDisabled(),processing:this.state.processing,value:this.translate("Submit")}))))}}ki.propTypes={context:i().any.isRequired,onClose:i().func,onSubmit:i().func,actionFeedbackContext:i().any,dialogContext:i().object,t:i().func};const _i=N(h((0,f.CI)("common")(ki)));class xi extends n.Component{constructor(e){super(e),this.state=this.getDefaultState(),this.bindCallbacks()}getDefaultState(){return{processing:!1}}bindCallbacks(){this.handleSubmit=this.handleSubmit.bind(this),this.handleClose=this.handleClose.bind(this)}handleClose(){this.props.onClose()}get isProcessing(){return this.state.processing}async handleSubmit(e){if(e.preventDefault(),!this.isProcessing){this.setState({processing:!0});try{await this.props.onSubmit(),this.props.onClose()}catch(e){if(this.setState({processing:!1}),"UserAbortsOperationError"!==e.name)throw console.error("Uncaught uncontrolled error"),e}}}formatFingerprint(e){const t=(e=e||"").toUpperCase().replace(/.{4}/g,"$& ");return n.createElement(n.Fragment,null,t.substr(0,24),n.createElement("br",null),t.substr(25))}formatUserIds(e){return(e=e||[]).map((e,t)=>n.createElement(n.Fragment,{key:t},e.name,"<",e.email,">",n.createElement("br",null)))}formatDate(e){return Ds.c9.fromJSDate(new Date(e)).setLocale(this.props.context.locale).toLocaleString(Ds.c9.DATETIME_FULL)}get translate(){return this.props.t}render(){return n.createElement(qt,{title:this.translate("Save Settings Summary"),onClose:this.handleClose,disabled:this.state.processing,className:"save-recovery-account-settings-dialog"},n.createElement("form",{onSubmit:this.handleSubmit},n.createElement("div",{className:"form-content"},this.props.policy&&n.createElement(n.Fragment,null,n.createElement("label",null,n.createElement(f.x6,null,"New Account Recovery Policy")),n.createElement("div",{className:"account-recovery-setting-save"},n.createElement("p",{className:"name"},{mandatory:n.createElement(f.x6,null,"Prompt"),"opt-out":n.createElement(f.x6,null,"Optional, Opt-out"),"opt-in":n.createElement(f.x6,null,"Optional, Opt-in"),disabled:n.createElement(f.x6,null,"Disable")}[this.props.policy]),n.createElement("p",{className:"info"},{mandatory:n.createElement(n.Fragment,null,n.createElement(f.x6,null,"Every user is required to provide a copy of their private key and passphrase during setup."),n.createElement("br",null),n.createElement(f.x6,null,"Warning: You should inform your users not to store personal passwords.")),"opt-out":n.createElement(f.x6,null,"Every user will be prompted to provide a copy of their private key and passphrase by default during the setup, but they can opt out."),"opt-in":n.createElement(f.x6,null,"Every user can decide to provide a copy of their private key and passphrase by default during the setup, but they can opt in."),disabled:n.createElement(n.Fragment,null,n.createElement(f.x6,null,"Backup of the private key and passphrase will not be stored. This is the safest option."),n.createElement("br",null),n.createElement(f.x6,null,"Warning: If users lose their private key and passphrase they will not be able to recover their account."))}[this.props.policy]))),this.props.keyInfo&&n.createElement(n.Fragment,null,n.createElement("label",null,n.createElement(f.x6,null,"New Organization Recovery Key")),n.createElement("div",{className:"recovery-key-details"},n.createElement("table",{className:"table-info recovery-key"},n.createElement("tbody",null,n.createElement("tr",{className:"user-ids"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Uid")),n.createElement("td",{className:"value"},this.formatUserIds(this.props.keyInfo.user_ids))),n.createElement("tr",{className:"fingerprint"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Fingerprint")),n.createElement("td",{className:"value"},this.formatFingerprint(this.props.keyInfo.fingerprint))),n.createElement("tr",{className:"algorithm"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Algorithm")),n.createElement("td",{className:"value"},this.props.keyInfo.algorithm)),n.createElement("tr",{className:"key-length"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Key length")),n.createElement("td",{className:"value"},this.props.keyInfo.length)),n.createElement("tr",{className:"created"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Created")),n.createElement("td",{className:"value"},this.formatDate(this.props.keyInfo.created))),n.createElement("tr",{className:"expires"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Expires")),n.createElement("td",{className:"value",title:this.props.keyInfo.expires},Hs(this.props.keyInfo.expires,this.props.t,this.props.context.locale))))))),n.createElement("div",{className:"warning message no-margin"},n.createElement(f.x6,null,"Please review carefully this configuration as it will not be trivial to change this later."))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement("a",{target:"_blank",rel:"noopener noreferrer",href:"https://www.passbolt.com/docs/admin/authentication/account-recovery/",className:"button button-left "+(this.isProcessing?"disabled":"")},n.createElement(f.x6,null,"Learn more")),n.createElement(gn,{onClick:this.handleClose,disabled:this.isProcessing}),n.createElement(qs,{value:this.translate("Save"),disabled:this.isProcessing,processing:this.isProcessing,warning:!0}))))}}xi.propTypes={context:i().any,onClose:i().func,onSubmit:i().func,policy:i().string,keyInfo:i().object,t:i().func};const Si=N((0,f.CI)("common")(xi));class Ci extends n.Component{constructor(e){super(e),this.bindCallbacks()}componentDidMount(){this.displayConfirmSummaryDialog()}bindCallbacks(){this.handleCloseDialog=this.handleCloseDialog.bind(this),this.handleConfirmSave=this.handleConfirmSave.bind(this),this.handleSave=this.handleSave.bind(this),this.handleError=this.handleError.bind(this)}async displayConfirmSummaryDialog(){this.props.dialogContext.open(Si,{policy:this.props.adminAccountRecoveryContext.policyChanges?.policy,keyInfo:await this.getNewOrganizationKeyInfo(),onClose:this.handleCloseDialog,onSubmit:this.handleConfirmSave})}getNewOrganizationKeyInfo(){const e=this.props.adminAccountRecoveryContext.policyChanges?.publicKey;return e?this.props.adminAccountRecoveryContext.getKeyInfo(e):null}displayProvideAccountRecoveryOrganizationKeyDialog(){this.props.dialogContext.open(_i,{onClose:this.handleCloseDialog,onSubmit:this.handleSave})}handleCloseDialog(){this.props.onStop()}async handleConfirmSave(){Boolean(this.props.adminAccountRecoveryContext.currentPolicy?.account_recovery_organization_public_key)?this.displayProvideAccountRecoveryOrganizationKeyDialog():await this.handleSave()}async handleSave(e=null){try{await this.props.adminAccountRecoveryContext.save(e),await this.props.actionFeedbackContext.displaySuccess(this.translate("The organization recovery policy has been updated successfully")),this.props.onStop()}catch(e){this.handleError(e)}}handleError(e){if(["UserAbortsOperationError","WrongOrganizationRecoveryKeyError","InvalidMasterPasswordError","BadSignatureMessageGpgKeyError","GpgKeyError"].includes(e.name))throw e;"PassboltApiFetchError"===e.name&&e?.data?.body?.account_recovery_organization_public_key?.fingerprint?.isNotAccountRecoveryOrganizationPublicKeyFingerprintRule?this.props.dialogContext.open($t,{error:new Error(this.translate("The new organization recovery key should not be a formerly used organization recovery key."))}):this.props.dialogContext.open($t,{error:e}),this.props.onStop()}get translate(){return this.props.t}render(){return n.createElement(n.Fragment,null)}}Ci.propTypes={dialogContext:i().any,adminAccountRecoveryContext:i().any,actionFeedbackContext:i().object,context:i().object,onStop:i().func.isRequired,t:i().func};const Ni=N(h(m(fi((0,f.CI)("common")(Ci)))));class Ti extends n.Component{constructor(e){super(e),this.bindCallbacks()}bindCallbacks(){this.handleSaveClick=this.handleSaveClick.bind(this),this.handleEditSubscriptionClick=this.handleEditSubscriptionClick.bind(this)}handleSaveClick(){this.props.workflowContext.start(Ni,{})}handleEditSubscriptionClick(){this.props.adminAccountRecoveryContext.resetChanges()}isSaveEnabled(){if(!this.props.adminAccountRecoveryContext.hasPolicyChanges())return!1;const e=this.props.adminAccountRecoveryContext.policyChanges,t=this.props.adminAccountRecoveryContext.currentPolicy;if(e?.policy===Be.POLICY_DISABLED)return!0;const a=e.publicKey||t?.account_recovery_organization_public_key?.armored_key;return!(!Boolean(e.policy)||!Boolean(a))||t.policy!==Be.POLICY_DISABLED&&Boolean(e.publicKey)}isResetEnabled(){return this.props.adminAccountRecoveryContext.hasPolicyChanges()}render(){return n.createElement("div",{className:"actions-wrapper"},n.createElement("div",{className:"left-actions-wrapper"},n.createElement("button",{type:"button",className:"button secondary",disabled:!this.isResetEnabled(),onClick:this.handleEditSubscriptionClick},n.createElement("span",null,n.createElement(f.x6,null,"Reset settings")))),n.createElement("button",{type:"button",className:"button primary form",disabled:!this.isSaveEnabled(),onClick:this.handleSaveClick},n.createElement("span",null,n.createElement(f.x6,null,"Save"))))}}Ti.propTypes={adminAccountRecoveryContext:i().object,workflowContext:i().any};const Ai=function(e){return class extends n.Component{render(){return n.createElement(vi.Consumer,null,t=>n.createElement(e,Ei({workflowContext:t},this.props)))}}}(fi((0,f.CI)("common")(Ti)));class Ii extends n.Component{constructor(e){super(e),this.bindCallback()}bindCallback(){this.handleClick=this.handleClick.bind(this)}handleClick(){this.props.onClick(this.props.name)}render(){return n.createElement("li",{className:"tab "+(this.props.isActive?"active":"")},n.createElement("button",{type:"button",className:"tab-link",onClick:this.handleClick},this.props.name))}}Ii.propTypes={name:i().string,type:i().string.isRequired,isActive:i().bool,onClick:i().func,children:i().any};const Ri=Ii;class Pi extends n.Component{constructor(e){super(e),this.state=this.getDefaultState(e),this.bindCallback()}getDefaultState(e){return{activeTabName:e.activeTabName}}bindCallback(){this.handleTabClick=this.handleTabClick.bind(this)}handleTabClick(e){this.setState({activeTabName:e.type}),"function"==typeof e.onClick&&e.onClick()}render(){return n.createElement("div",{className:"tabs"},n.createElement("ul",{className:"tabs-nav"},this.props.children.map(({key:e,props:t})=>n.createElement(Ri,{key:e,name:t.name,type:t.type,onClick:()=>this.handleTabClick(t),isActive:t.type===this.state.activeTabName}))),n.createElement("div",{className:"tabs-active-content"},this.props.children.find(e=>e.props.type===this.state.activeTabName).props.children))}}Pi.propTypes={activeTabName:i().string,children:i().any};const Di=Pi;class Oi extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.bindCallbacks(),this.createInputRef()}get defaultState(){return{processing:!1,key:"",keyError:"",hasAlreadyBeenValidated:!1,selectedFile:null}}bindCallbacks(){this.handleSelectFile=this.handleSelectFile.bind(this),this.handleFormSubmit=this.handleFormSubmit.bind(this),this.handleInputChange=this.handleInputChange.bind(this),this.handleSelectOrganizationKeyFile=this.handleSelectOrganizationKeyFile.bind(this)}createInputRef(){this.keyInputRef=n.createRef(),this.fileUploaderRef=n.createRef()}async handleSelectOrganizationKeyFile(e){const[t]=e.target.files,a=await this.readOrganizationKeyFile(t);this.setState({key:a,selectedFile:t})}readOrganizationKeyFile(e){const t=new FileReader;return new Promise((a,n)=>{t.onloadend=()=>{try{a(t.result)}catch(e){n(e)}},t.readAsText(e)})}async validateKeyInput(){const e=this.state.key.trim();return""===e?Promise.reject(new Error(this.translate("The key can't be empty."))):await this.props.context.port.request("passbolt.account-recovery.validate-organization-key",e)}async validate(){return this.setState({keyError:""}),await this.validateKeyInput().then(()=>!0).catch(e=>(this.setState({keyError:e.message}),!1))}handleInputChange(e){const t=e.target;this.setState({[t.name]:t.value})}handleSelectFile(){this.fileUploaderRef.current.click()}async handleFormSubmit(e){e.preventDefault(),this.state.processing||await this.save()}async save(){if(!this.state.processing){if(this.setState({hasAlreadyBeenValidated:!0,processing:!0}),!await this.validate())return this.handleValidateError(),void this.setState({processing:!1});await this.props.onUpdateOrganizationKey(this.state.key.trim())}}handleValidateError(){this.focusFieldError()}focusFieldError(){this.state.keyError&&this.keyInputRef.current.focus()}hasAllInputDisabled(){return this.state.processing}get translate(){return this.props.t}get selectedFilename(){return this.state.selectedFile?this.state.selectedFile.name:""}render(){return n.createElement("form",{onSubmit:this.handleFormSubmit,noValidate:!0},n.createElement("div",{className:"form-content import-organization-key"},n.createElement("div",{className:"input textarea required "+(this.state.keyError?"error":"")},n.createElement("label",{htmlFor:"organization-recover-form-key"},n.createElement(f.x6,null,"Import an OpenPGP Public key")),n.createElement("textarea",{id:"organization-recover-form-key",name:"key",value:this.state.key,onKeyUp:this.handleKeyInputKeyUp,onChange:this.handleInputChange,disabled:this.hasAllInputDisabled(),ref:this.keyInputRef,className:"required",placeholder:this.translate("Add Open PGP Public key"),required:"required",autoComplete:"off",autoFocus:!0})),n.createElement("div",{className:"input file"},n.createElement("input",{type:"file",id:"dialog-import-private-key",ref:this.fileUploaderRef,disabled:this.hasAllInputDisabled(),onChange:this.handleSelectOrganizationKeyFile}),n.createElement("label",{htmlFor:"dialog-import-private-key"},n.createElement(f.x6,null,"Select a file to import")),n.createElement("div",{className:"input-file-inline"},n.createElement("input",{type:"text",disabled:!0,placeholder:this.translate("No file selected"),defaultValue:this.selectedFilename}),n.createElement("button",{className:"button primary",type:"button",disabled:this.hasAllInputDisabled(),onClick:this.handleSelectFile},n.createElement("span",null,n.createElement(f.x6,null,"Choose a file")))),this.state.keyError&&n.createElement("div",{className:"key error-message"},this.state.keyError)),!this.state.hasAlreadyBeenValidated&&n.createElement("div",{className:"message notice no-margin"},n.createElement(jt,{className:"svg-icon info baseline"}),n.createElement("strong",null,n.createElement(f.x6,null,"Pro tip"),":")," ",n.createElement(f.x6,null,"Learn how to"," ",n.createElement("a",{href:"https://www.passbolt.com/docs/admin/faq/generate-openpgp-key/",target:"_blank",rel:"noopener noreferrer"},"generate a key separately.")))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement(gn,{disabled:this.hasAllInputDisabled(),onClick:this.props.onClose}),n.createElement(qs,{disabled:this.hasAllInputDisabled(),processing:this.state.processing,value:this.translate("Apply")})))}}Oi.propTypes={context:i().object,onUpdateOrganizationKey:i().func,onClose:i().func,t:i().func};const Mi=N((0,f.CI)("common")(Oi)),Ui={"en-UK":["abdominal","acclimate","accompany","activator","acuteness","aerospace","affecting","affection","affidavit","affiliate","afflicted","afterglow","afterlife","aftermath","aftermost","afternoon","aggregate","agonizing","agreeable","agreeably","agreement","alabaster","albatross","algorithm","alienable","alongside","amazingly","ambiguity","ambiguous","ambitious","ambulance","amendable","amendment","amplifier","amusement","anaerobic","anatomist","angelfish","angriness","anguished","animating","animation","animosity","announcer","answering","antarctic","anthology","antiquely","antiquity","antitoxic","antitrust","antiviral","antivirus","appealing","appeasing","appendage","appetizer","appliance","applicant","appointee","appraisal","appraiser","apprehend","arbitrary","arbitrate","armadillo","arrogance","ascension","ascertain","asparagus","astrology","astronaut","astronomy","atrocious","attendant","attention","attentive","attractor","attribute","audacious","augmented","authentic","autograph","automaker","automated","automatic","autopilot","available","avalanche","backboard","backboned","backfield","backlands","backlight","backpedal","backshift","backspace","backstage","backtrack","backwater","bacterium","bagginess","balancing","bannister","barometer","barracuda","barricade","bartender","basically","battalion","battering","blanching","blandness","blaspheme","blasphemy","blatantly","blunderer","bodacious","boogeyman","boogieman","boondocks","borrowing","botanical","boundless","bountiful","breeching","brilliant","briskness","broadband","broadcast","broadness","broadside","broadways","bronchial","brownnose","brutishly","buccaneer","bucktooth","buckwheat","bulginess","bulldozer","bullfight","bunkhouse","cabdriver","calculate","calibrate","camcorder","canopener","capillary","capricorn","captivate","captivity","cardboard","cardstock","carefully","caregiver","caretaker","carnation","carnivore","carpenter","carpentry","carrousel","cartridge","cartwheel","catatonic","catchable","cathedral","cattishly","caucasian","causation","cauterize","celestial","certainly","certainty","certified","challenge","chamomile","chaperone","character","charbroil","chemicals","cherisher","chihuahua","childcare","childhood","childless","childlike","chokehold","circulate","clamshell","clergyman","clubhouse","clustered","coagulant","coastland","coastline","cofounder","cognition","cognitive","coherence","collected","collector","collision","commodity","commodore","commotion","commuting","compacted","compacter","compactly","compactor","companion","component","composite","composure","comprised","computing","concerned","concierge","condiment","condition","conducive","conductor","confidant","confident","confiding","configure","confining","confusing","confusion","congenial","congested","conjoined","connected","connector","consensus","consoling","consonant","constable","constrain","constrict","construct","consuming","container","contented","contently","contusion","copartner","cornbread","cornfield","cornflake","cornstalk","corporate","corroding","corrosive","cosmetics","cosponsor","countable","countdown","countless","crabgrass","craftsman","craftwork","cranberry","craziness","creamlike","creatable","crestless","crispness","crudeness","cruelness","crummiest","crunching","crushable","cubbyhole","culminate","cultivate","cupbearer","curliness","curvature","custodian","customary","customize","cytoplasm","cytoplast","dandelion","daredevil","darkening","darwinism","dastardly","deafening","dealmaker","debatable","decathlon","deceiving","deception","deceptive","decidable","decimeter","decompose","decorated","decorator","dedicator","defection","defective","defendant","defensive","deflation","deflected","deflector","degrading","dehydrate","delegator","delicious","delighted","delirious","deliverer","demanding","demeaning","democracy","demystify","denatured","deodorant","deodorize","departure","depletion","depravity","deprecate","desecrate","deserving","designate","designing","deskbound","destitute","detection","detective","detention","detergent","detonator","deviation","devotedly","devouring","dexterity","dexterous","diagnoses","diagnosis","diaphragm","dictation","difficult","diffusion","diffusive","diligence","dinginess","direction","directive","directory","dirtiness","disbelief","discharge","discourse","disengage","disfigure","disinfect","disliking","dislocate","dismantle","disparate","disparity","dispersal","dispersed","disperser","displease","disregard","dividable","divisible","divisibly","dizziness","dollhouse","doorframe","dormitory","dragonfly","dragonish","drainable","drainpipe","dramatize","dreadlock","dreamboat","dreamland","dreamless","dreamlike","drinkable","drop-down","dubiously","duplicate","duplicity","dwindling","earthlike","earthling","earthworm","eastbound","eastcoast","eccentric","ecologist","economist","ecosphere","ecosystem","education","effective","efficient","eggbeater","egomaniac","egotistic","elaborate","eldercare","electable","elevating","elevation","eliminate","elongated","eloquence","elsewhere","embattled","embellish","embroider","emergency","emphasize","empirical","emptiness","enactment","enchanted","enchilada","enclosure","encounter","encourage","endearing","endocrine","endorphin","endowment","endurable","endurance","energetic","engraving","enigmatic","enjoyable","enjoyably","enjoyment","enlarging","enlighten","entangled","entertain","entourage","enunciate","epidermal","epidermis","epileptic","equipment","equivocal","eradicate","ergonomic","escalator","escapable","esophagus","espionage","essential","establish","estimator","estranged","ethically","euphemism","evaluator","evaporate","everglade","evergreen","everybody","evolution","excavator","exceeding","exception","excitable","excluding","exclusion","exclusive","excretion","excretory","excursion","excusable","excusably","exemplary","exemplify","exemption","exerciser","exfoliate","exonerate","expansion","expansive","expectant","expedited","expediter","expensive","expletive","exploring","exposable","expulsion","exquisite","extending","extenuate","extortion","extradite","extrovert","extruding","exuberant","facecloth","faceplate","facsimile","factsheet","fanciness","fantasize","fantastic","favorable","favorably","ferocious","festivity","fidgeting","financial","finishing","flagstick","flagstone","flammable","flashback","flashbulb","flashcard","flattered","flatterer","flavorful","flavoring","footboard","footprint","fragility","fragrance","fraternal","freemason","freestyle","freezable","frequency","frightful","frigidity","frivolous","frostbite","frostlike","frugality","frustrate","gainfully","gallantly","gallstone","galvanize","gathering","gentleman","geography","geologist","geometric","geriatric","germicide","germinate","germproof","gestation","gibberish","giddiness","gigahertz","gladiator","glamorous","glandular","glorified","glorifier","glutinous","goldsmith","goofiness","graceless","gradation","gradually","grappling","gratified","gratitude","graveness","graveyard","gravitate","greedless","greyhound","grievance","grimacing","griminess","grumbling","guacamole","guileless","gumminess","habitable","hamburger","hamstring","handbrake","handclasp","handcraft","handiness","handiwork","handlebar","handprint","handsfree","handshake","handstand","handwoven","handwrite","hankering","haphazard","happening","happiness","hardcover","hardening","hardiness","hardwired","harmonica","harmonics","harmonize","hastiness","hatchback","hatchling","headboard","headcount","headdress","headfirst","headphone","headpiece","headscarf","headstand","headstone","heaviness","heftiness","hemstitch","herbicide","hesitancy","humiliate","humongous","humorless","hunchback","hundredth","hurricane","huskiness","hydration","hydroxide","hyperlink","hypertext","hypnotism","hypnotist","hypnotize","hypocrisy","hypocrite","ibuprofen","idealness","identical","illicitly","imaginary","imitation","immersion","immorally","immovable","immovably","impatient","impending","imperfect","implement","implicate","implosion","implosive","important","impotence","impotency","imprecise","impromptu","improving","improvise","imprudent","impulsive","irregular","irritable","irritably","isolating","isolation","italicize","itinerary","jackknife","jailbreak","jailhouse","jaywalker","jeeringly","jockstrap","jolliness","joylessly","jubilance","judgingly","judiciary","juiciness","justifier","kilometer","kinswoman","laborious","landowner","landscape","landslide","lankiness","legislate","legwarmer","lethargic","levitator","liability","librarian","limelight","litigator","livestock","lubricant","lubricate","luckiness","lucrative","ludicrous","luminance","lumpiness","lunchroom","lunchtime","luridness","lustfully","lustiness","luxurious","lyrically","machinist","magnesium","magnetism","magnetize","magnifier","magnitude","majorette","makeshift","malformed","mammogram","mandatory","manhandle","manicotti","manifesto","manliness","marauding","margarine","margarita","marmalade","marshland","marsupial","marvelous","masculine","matchbook","matchless","maternity","matriarch","matrimony","mayflower","modulator","moistness","molecular","monastery","moneybags","moneyless","moneywise","monologue","monstrous","moodiness","moonlight","moonscape","moonshine","moonstone","morbidity","mortality","mortician","mortified","mothproof","motivator","motocross","mountable","mousiness","moustache","multitask","multitude","mummified","municipal","murkiness","murmuring","mushiness","muskiness","mustiness","mutilated","mutilator","mystified","nanometer","nastiness","navigator","nebulizer","neglector","negligent","negotiate","neurology","ninetieth","numerator","nuttiness","obedience","oblivious","obnoxious","obscurity","observant","observing","obsession","obsessive","obstinate","obtrusive","occultist","occupancy","onslaught","operating","operation","operative","oppressed","oppressor","opulently","outnumber","outplayed","outskirts","outsource","outspoken","overblown","overboard","overbuilt","overcrowd","overdraft","overdrawn","overdress","overdrive","overeager","overeater","overexert","overgrown","overjoyed","overlabor","overlying","overnight","overplant","overpower","overprice","overreach","overreact","overshoot","oversight","oversized","oversleep","overspend","overstate","overstock","overstuff","oversweet","overthrow","overvalue","overwrite","oxidation","oxidizing","pacemaker","palatable","palpitate","panhandle","panoramic","pantomime","pantyhose","paparazzi","parachute","paragraph","paralegal","paralyses","paralysis","paramedic","parameter","paramount","parasitic","parchment","partition","partridge","passenger","passivism","patchwork","paternity","patriarch","patronage","patronize","pavestone","pediatric","pedometer","penholder","penniless","pentagram","percolate","perennial","perfected","perfectly","periscope","perkiness","perpetual","perplexed","persecute","persevere","persuaded","persuader","pessimism","pessimist","pesticide","petroleum","petticoat","pettiness","phonebook","phoniness","phosphate","plausible","plausibly","playgroup","playhouse","playmaker","plaything","plentiful","plexiglas","plutonium","pointless","polyester","polygraph","porcupine","portfolio","postnasal","powdering","prankster","preaching","precision","predefine","preflight","preformed","pregnancy","preheated","prelaunch","preoccupy","preschool","prescribe","preseason","president","presuming","pretended","pretender","prevalent","prewashed","primarily","privatize","proactive","probation","probiotic","procedure","procreate","profanity","professed","professor","profusely","prognosis","projector","prolonged","promenade","prominent","promotion","pronounce","proofread","propeller","proponent","protector","prototype","protozoan","providing","provoking","provolone","proximity","prudishly","publisher","pulmonary","pulverize","punctuate","punctured","pureblood","purgatory","purposely","pursuable","pushchair","pushiness","pyromania","qualified","qualifier","quartered","quarterly","quickness","quicksand","quickstep","quintuple","quizzical","quotation","radiantly","radiation","rancidity","ravishing","reacquire","reanalyze","reappoint","reapprove","rearrange","rebalance","recapture","recharger","recipient","reclining","reclusive","recognize","recollect","reconcile","reconfirm","reconvene","rectangle","rectified","recycling","reexamine","referable","reference","refinance","reflected","reflector","reformist","refueling","refurbish","refurnish","refutable","registrar","regretful","regulator","rehydrate","reimburse","reiterate","rejoicing","relapsing","relatable","relenting","relieving","reluctant","remindful","remission","remodeler","removable","rendering","rendition","renewable","renewably","renovator","repackage","repacking","repayment","repossess","repressed","reprimand","reprocess","reproduce","reprogram","reptilian","repugnant","repulsion","repulsive","repurpose","reputable","reputably","requisite","reshuffle","residence","residency","resilient","resistant","resisting","resurface","resurrect","retaining","retaliate","retention","retrieval","retriever","reverence","reversing","reversion","revisable","revivable","revocable","revolving","riverbank","riverboat","riverside","rockiness","rockslide","roundness","roundworm","runaround","sacrament","sacrifice","saddlebag","safeguard","safehouse","salvaging","salvation","sanctuary","sandblast","sandpaper","sandstone","sandstorm","sanitizer","sappiness","sarcastic","sasquatch","satirical","satisfied","sauciness","saxophone","scapegoat","scarecrow","scariness","scavenger","schematic","schilling","scientist","scorebook","scorecard","scoreless","scoundrel","scrambled","scrambler","scrimmage","scrounger","sculpture","secluding","seclusion","sectional","selection","selective","semicolon","semifinal","semisweet","sensation","sensitive","sensitize","sensually","september","sequester","serotonin","sevenfold","seventeen","shadiness","shakiness","sharpener","sharpness","shiftless","shininess","shivering","shortcake","shorthand","shortlist","shortness","shortwave","showpiece","showplace","shredding","shrubbery","shuffling","silliness","similarly","simmering","sincerity","situation","sixtyfold","skedaddle","skintight","skyrocket","slackness","slapstick","sliceable","slideshow","slighting","slingshot","slouching","smartness","smilingly","smokeless","smokiness","smuggling","snowboard","snowbound","snowdrift","snowfield","snowflake","snowiness","snowstorm","spearfish","spearhead","spearmint","spectacle","spectator","speculate","spellbind","spendable","spherical","spiritism","spiritual","splashing","spokesman","spotlight","sprinkled","sprinkler","squatting","squealing","squeamish","squeezing","squishier","stability","stabilize","stainable","stainless","stalemate","staleness","starboard","stargazer","starlight","startling","statistic","statutory","steadfast","steadying","steerable","steersman","stegosaur","sterility","sterilize","sternness","stiffness","stillness","stimulant","stimulate","stipulate","stonewall","stoneware","stonework","stoplight","stoppable","stopwatch","storeroom","storewide","straggler","straining","strangely","strategic","strenuous","strongbox","strongman","structure","stumbling","stylishly","subarctic","subatomic","subdivide","subheader","submarine","submersed","submitter","subscribe","subscript","subsector","subsiding","subsidize","substance","subsystem","subwoofer","succulent","suffering","suffocate","sulphuric","superbowl","superglue","superhero","supernova","supervise","supremacy","surcharge","surfacing","surfboard","surrender","surrogate","surviving","sustained","sustainer","swaddling","swampland","swiftness","swimmable","symphonic","synthesis","synthetic","tableware","tackiness","taekwondo","tarantula","tastiness","theatrics","thesaurus","thickness","thirstily","thirsting","threefold","throbbing","throwaway","throwback","thwarting","tightness","tightrope","tinderbox","tiptoeing","tradition","trailside","transform","translate","transpire","transport","transpose","trapezoid","treachery","treadmill","trembling","tribesman","tributary","trickster","trifocals","trimester","troubling","trustable","trustless","turbulent","twentieth","twiddling","twistable","ultimatum","umbilical","unabashed","unadorned","unadvised","unaligned","unaltered","unarmored","unashamed","unaudited","unbalance","unblended","unblessed","unbounded","unbraided","unbuckled","uncertain","unchanged","uncharted","unclaimed","unclamped","unclothed","uncolored","uncorrupt","uncounted","uncrushed","uncurious","undamaged","undaunted","undecided","undefined","undercoat","undercook","underdone","underfeed","underfoot","undergrad","underhand","underline","underling","undermine","undermost","underpaid","underpass","underrate","undertake","undertone","undertook","underwear","underwent","underwire","undesired","undiluted","undivided","undrafted","undrilled","uneatable","unelected","unengaged","unethical","unexpired","unexposed","unfailing","unfeeling","unfitting","unfixable","unfocused","unfounded","unfrosted","ungreased","unguarded","unhappily","unhealthy","unhearing","unhelpful","unhitched","uniformed","uniformly","unimpeded","uninjured","uninstall","uninsured","uninvited","unisexual","universal","unknotted","unknowing","unlearned","unleveled","unlighted","unlikable","unlimited","unlivable","unlocking","unlovable","unluckily","unmanaged","unmasking","unmatched","unmindful","unmixable","unmovable","unnamable","unnatural","unnerving","unnoticed","unopposed","unpainted","unpiloted","unplanned","unplanted","unpleased","unpledged","unpopular","unraveled","unreached","unreeling","unrefined","unrelated","unretired","unrevised","unrivaled","unroasted","unruffled","unscathed","unscented","unsecured","unselfish","unsettled","unshackle","unsheathe","unshipped","unsightly","unskilled","unspoiled","unstaffed","unstamped","unsterile","unstirred","unstopped","unstuffed","unstylish","untainted","untangled","untoasted","untouched","untracked","untrained","untreated","untrimmed","unvarying","unveiling","unvisited","unwarlike","unwatched","unwelcome","unwilling","unwitting","unwomanly","unworldly","unworried","unwrapped","unwritten","upcountry","uplifting","urologist","uselessly","vagrantly","vagueness","valuables","vaporizer","vehicular","veneering","ventricle","verbalize","vertebrae","viability","viewpoint","vindicate","violation","viscosity","vivacious","vividness","wackiness","washbasin","washboard","washcloth","washhouse","washstand","whimsical","wieldable","wikipedia","willfully","willpower","wolverine","womanhood","womankind","womanless","womanlike","worrisome","worsening","worshiper","wrongdoer","wrongness","yesterday","zestfully","zigzagged","zookeeper","zoologist","abnormal","abrasion","abrasive","abruptly","absentee","absently","absinthe","absolute","abstract","accuracy","accurate","accustom","achiness","acquaint","activate","activism","activist","activity","aeration","aerobics","affected","affluent","aflutter","agnostic","agreeing","alienate","alkaline","alkalize","almighty","alphabet","although","altitude","aluminum","amaretto","ambiance","ambition","amicably","ammonium","amniotic","amperage","amusable","anaconda","aneurism","animator","annotate","annoying","annually","anointer","anteater","antelope","antennae","antibody","antidote","antihero","antiques","antirust","anyplace","anything","anywhere","appendix","appetite","applause","approach","approval","aptitude","aqueduct","ardently","arguable","arguably","armchair","arrogant","aspirate","astonish","atlantic","atonable","attendee","attitude","atypical","audacity","audience","audition","autistic","avenging","aversion","aviation","babbling","backache","backdrop","backfire","backhand","backlash","backless","backpack","backrest","backroom","backside","backslid","backspin","backstab","backtalk","backward","backwash","backyard","bacteria","baffling","baguette","bakeshop","balsamic","banister","bankable","bankbook","banknote","bankroll","barbecue","bargraph","baritone","barrette","barstool","barterer","battered","blatancy","blighted","blinking","blissful","blizzard","bloating","bloomers","blooming","blustery","boastful","boasting","bondless","bonehead","boneless","bonelike","bootlace","borrower","botanist","bottling","bouncing","bounding","breeches","breeding","brethren","broiling","bronzing","browbeat","browsing","bruising","brunette","brussels","bubbling","buckshot","buckskin","buddhism","buddhist","bullfrog","bullhorn","bullring","bullseye","bullwhip","bunkmate","busybody","cadillac","calamari","calamity","calculus","camisole","campfire","campsite","canister","cannabis","capacity","cardigan","cardinal","careless","carmaker","carnival","cartload","cassette","casually","casualty","catacomb","catalyst","catalyze","catapult","cataract","catching","catering","catfight","cathouse","cautious","cavalier","celibacy","celibate","ceramics","ceremony","cesarean","cesspool","chaffing","champion","chaplain","charcoal","charging","charting","chastise","chastity","chatroom","chatting","cheating","chewable","childish","chirping","chitchat","chivalry","chloride","chlorine","choosing","chowtime","cilantro","cinnamon","circling","circular","citation","clambake","clanking","clapping","clarinet","clavicle","clerical","climatic","clinking","closable","clothing","clubbing","clumsily","coasting","coauthor","coeditor","cogwheel","coherent","cohesive","coleslaw","coliseum","collapse","colonial","colonist","colonize","colossal","commence","commerce","composed","composer","compound","compress","computer","conceded","conclude","concrete","condense","confetti","confider","confined","conflict","confound","confront","confused","congrats","congress","conjuror","constant","consumer","contempt","contents","contrite","cornball","cornhusk","cornmeal","coronary","corporal","corridor","cosigner","counting","covenant","coveting","coziness","crabbing","crablike","crabmeat","cradling","craftily","crawfish","crawlers","crawling","crayfish","creasing","creation","creative","creature","credible","credibly","crescent","cresting","crewless","crewmate","cringing","crisping","criteria","crumpled","cruncher","crusader","crushing","cucumber","cufflink","culinary","culpable","cultural","customer","cylinder","daffodil","daintily","dallying","dandruff","dangling","daringly","darkened","darkness","darkroom","datebook","daughter","daunting","daybreak","daydream","daylight","dazzling","deafness","debating","debtless","deceased","deceiver","december","decipher","declared","decrease","dedicate","deepness","defacing","defender","deferral","deferred","defiance","defiling","definite","deflator","deforest","degraded","degrease","dejected","delegate","deletion","delicacy","delicate","delirium","delivery","delusion","demeanor","democrat","demotion","deniable","departed","deplored","depraved","deputize","deranged","designed","designer","deskwork","desolate","destruct","detached","detector","detonate","detoxify","deviancy","deviator","devotion","devourer","devoutly","diabetes","diabetic","diabolic","diameter","dictator","diffused","diffuser","dilation","diligent","diminish","directed","directly","direness","disabled","disagree","disallow","disarray","disaster","disburse","disclose","discolor","discount","discover","disgrace","dislodge","disloyal","dismount","disorder","dispatch","dispense","displace","disposal","disprove","dissuade","distance","distaste","distinct","distract","distress","district","distrust","dividend","dividers","dividing","divinely","divinity","division","divisive","divorcee","doctrine","document","domelike","domestic","dominion","dominoes","donation","doorbell","doorknob","doornail","doorpost","doorstep","doorstop","doubling","dragging","dragster","drainage","dramatic","dreadful","dreamily","drearily","drilling","drinking","dripping","drivable","driveway","dropkick","drowsily","duckbill","duckling","ducktail","dullness","dumpling","dumpster","duration","dwelling","dynamite","dyslexia","dyslexic","earphone","earpiece","earplugs","easiness","eastward","economic","edginess","educated","educator","eggplant","eggshell","election","elective","elephant","elevator","eligible","eligibly","elliptic","eloquent","embezzle","embolism","emission","emoticon","empathic","emphases","emphasis","emphatic","employed","employee","employer","emporium","encircle","encroach","endanger","endeared","endpoint","enduring","energize","enforced","enforcer","engaging","engraved","engraver","enjoying","enlarged","enlisted","enquirer","entering","enticing","entrench","entryway","envelope","enviable","enviably","envision","epidemic","epidural","epilepsy","epilogue","epiphany","equation","erasable","escalate","escapade","escapist","escargot","espresso","esteemed","estimate","estrogen","eternity","evacuate","evaluate","everyday","everyone","evidence","excavate","exchange","exciting","existing","exorcism","exorcist","expenses","expiring","explicit","exponent","exporter","exposure","extended","exterior","external","fabulous","facebook","facedown","faceless","facelift","facility","familiar","famished","fastball","fastness","favoring","favorite","felt-tip","feminine","feminism","feminist","feminize","fernlike","ferocity","festival","fiddling","fidelity","fiftieth","figurine","filtrate","finalist","finalize","fineness","finished","finisher","fiscally","flagpole","flagship","flanking","flannels","flashily","flashing","flatfoot","flatness","flattery","flatware","flatworm","flavored","flaxseed","flogging","flounder","flypaper","follicle","fondling","fondness","football","footbath","footgear","foothill","foothold","footless","footnote","footpath","footrest","footsore","footwear","footwork","founding","fountain","fraction","fracture","fragment","fragrant","freckled","freckles","freebase","freefall","freehand","freeload","freeness","freeware","freewill","freezing","frenzied","frequent","friction","frighten","frigidly","frostily","frosting","fructose","frugally","galleria","gambling","gangrene","gatherer","gauntlet","generous","genetics","geologic","geometry","geranium","germless","gigabyte","gigantic","giggling","giveaway","glancing","glaucoma","gleaming","gloating","gloomily","glorious","glowworm","goatskin","goldfish","goldmine","goofball","gorgeous","graceful","gracious","gradient","graduate","graffiti","grafting","granddad","grandkid","grandson","granular","gratuity","greasily","greedily","greeting","grieving","grievous","grinning","groggily","grooving","grudging","grueling","grumpily","guidable","guidance","gullible","gurgling","gyration","habitant","habitual","handball","handbook","handcart","handclap","handcuff","handgrip","handheld","handling","handmade","handpick","handrail","handwash","handwork","handyman","hangnail","hangover","happiest","hardcopy","hardcore","harddisk","hardened","hardener","hardhead","hardness","hardship","hardware","hardwood","harmless","hatchery","hatching","hazelnut","haziness","headache","headband","headgear","headlamp","headless","headlock","headrest","headroom","headsman","headwear","helpless","helpline","henchman","heritage","hesitant","hesitate","hexagram","huddling","humbling","humility","humorist","humorous","humpback","hungrily","huntress","huntsman","hydrated","hydrogen","hypnoses","hypnosis","hypnotic","idealism","idealist","idealize","identify","identity","ideology","ignition","illusion","illusive","imagines","imbecile","immature","imminent","immobile","immodest","immortal","immunity","immunize","impaired","impeding","imperial","implicit","impolite","importer","imposing","impotent","imprison","improper","impurity","irrigate","irritant","irritate","islamist","isolated","jailbird","jalapeno","jaundice","jingling","jokester","jokingly","joyfully","joystick","jubilant","judicial","juggling","junction","juncture","junkyard","justness","juvenile","kangaroo","keenness","kerchief","kerosene","kilobyte","kilogram","kilowatt","kindling","kindness","kissable","knapsack","knickers","laboring","labrador","ladylike","landfall","landfill","landlady","landless","landline","landlord","landmark","landmass","landmine","landside","language","latitude","latticed","lavender","laxative","laziness","lecturer","leggings","lethargy","leverage","levitate","licorice","ligament","likeness","likewise","limpness","linguini","linguist","linoleum","litigate","luckless","lukewarm","luminous","lunchbox","luncheon","lushness","lustrous","lyricism","lyricist","macarena","macaroni","magazine","magician","magnetic","magnolia","mahogany","majestic","majority","makeover","managing","mandarin","mandolin","manicure","manpower","marathon","marbling","marigold","maritime","massager","matchbox","matching","material","maternal","maturely","maturing","maturity","maverick","maximize","mobility","mobilize","modified","moisture","molasses","molecule","molehill","monetary","monetize","mongoose","monkhood","monogamy","monogram","monopoly","monorail","monotone","monotype","monoxide","monsieur","monument","moonbeam","moonlike","moonrise","moonwalk","morality","morbidly","morphine","morphing","mortally","mortuary","mothball","motivate","mountain","mounting","mournful","mulberry","multiple","multiply","mumbling","munchkin","muscular","mushroom","mutation","national","nativity","naturist","nautical","navigate","nearness","neatness","negation","negative","negligee","neurosis","neurotic","nickname","nicotine","nineteen","nintendo","numbness","numerate","numerous","nuptials","nutrient","nutshell","obedient","obituary","obligate","oblivion","observer","obsessed","obsolete","obstacle","obstruct","occupant","occupier","ointment","olympics","omission","omnivore","oncoming","onlooker","onscreen","operable","operator","opponent","opposing","opposite","outboard","outbound","outbreak","outburst","outclass","outdated","outdoors","outfield","outflank","outgoing","outhouse","outlying","outmatch","outreach","outright","outscore","outshine","outshoot","outsider","outsmart","outtakes","outthink","outweigh","overarch","overbill","overbite","overbook","overcast","overcoat","overcome","overcook","overfeed","overfill","overflow","overfull","overhand","overhang","overhaul","overhead","overhear","overheat","overhung","overkill","overlaid","overload","overlook","overlord","overpass","overplay","overrate","override","overripe","overrule","overshot","oversold","overstay","overstep","overtake","overtime","overtone","overture","overturn","overview","oxymoron","pacifier","pacifism","pacifist","paddling","palpable","pampered","pamperer","pamphlet","pancreas","pandemic","panorama","parabola","parakeet","paralyze","parasail","parasite","parmesan","passable","passably","passcode","passerby","passover","passport","password","pastrami","paternal","patience","pavement","pavilion","paycheck","payphone","peculiar","peddling","pedicure","pedigree","pegboard","penalize","penknife","pentagon","perceive","perjurer","peroxide","petition","phrasing","placidly","platform","platinum","platonic","platypus","playable","playback","playlist","playmate","playroom","playtime","pleading","plethora","plunging","pointing","politely","popsicle","populace","populate","porridge","portable","porthole","portside","possible","possibly","postcard","pouncing","powdered","praising","prancing","prankish","preacher","preamble","precinct","predator","pregnant","premiere","premises","prenatal","preorder","pretense","previous","prideful","princess","pristine","probable","probably","proclaim","procurer","prodigal","profound","progress","prologue","promoter","prompter","promptly","proofing","properly","property","proposal","protegee","protract","protrude","provable","provided","provider","province","prowling","punctual","punisher","purchase","purebred","pureness","purifier","purplish","pursuant","purveyor","pushcart","pushover","puzzling","quadrant","quaintly","quarters","quotable","radiance","radiated","radiator","railroad","rambling","reabsorb","reaction","reactive","reaffirm","reappear","rearview","reassign","reassure","reattach","reburial","rebuttal","reckless","recliner","recovery","recreate","recycled","recycler","reemerge","refinery","refining","refinish","reforest","reformat","reformed","reformer","refreeze","refusing","register","registry","regulate","rekindle","relation","relative","reliable","reliably","reliance","relocate","remedial","remember","reminder","removing","renderer","renegade","renounce","renovate","rentable","reoccupy","repaying","repeated","repeater","rephrase","reporter","reproach","resample","research","reselect","reseller","resemble","resident","residual","resigned","resolute","resolved","resonant","resonate","resource","resubmit","resupply","retainer","retiring","retorted","reusable","reverend","reversal","revision","reviving","revolver","richness","riddance","ripeness","ripening","rippling","riverbed","riveting","robotics","rockband","rockfish","rocklike","rockstar","roulette","rounding","roundish","rumbling","sabotage","saddling","safeness","salaried","salutary","sampling","sanction","sanctity","sandbank","sandfish","sandworm","sanitary","satiable","saturate","saturday","scalding","scallion","scalping","scanning","scarcity","scarring","schedule","scheming","schnapps","scolding","scorpion","scouring","scouting","scowling","scrabble","scraggly","scribble","scribing","scrubbed","scrubber","scrutiny","sculptor","secluded","securely","security","sedation","sedative","sediment","seducing","selected","selector","semantic","semester","semisoft","senorita","sensuous","sequence","serrated","sessions","settling","severity","shakable","shamrock","shelving","shifting","shoplift","shopping","shoptalk","shortage","shortcut","showcase","showdown","showgirl","showroom","shrapnel","shredder","shrewdly","shrouded","shucking","siberian","silenced","silencer","simplify","singular","sinister","situated","sixtieth","sizzling","skeletal","skeleton","skillful","skimming","skimpily","skincare","skinhead","skinless","skinning","skipping","skirmish","skydiver","skylight","slacking","slapping","slashing","slighted","slightly","slimness","slinging","slobbery","sloppily","smashing","smelting","smuggler","smugness","sneezing","snipping","snowbird","snowdrop","snowfall","snowless","snowplow","snowshoe","snowsuit","snugness","spearman","specimen","speckled","spectrum","spelling","spending","spinning","spinster","spirited","splashed","splatter","splendid","splendor","splicing","splinter","splotchy","spoilage","spoiling","spookily","sporting","spotless","spotting","spyglass","squabble","squander","squatted","squatter","squealer","squeegee","squiggle","squiggly","stagnant","stagnate","staining","stalling","stallion","stapling","stardust","starfish","starless","starring","starship","starting","starving","steadier","steadily","steering","sterling","stifling","stimulus","stingily","stinging","stingray","stinking","stoppage","stopping","storable","stowaway","straddle","strained","strainer","stranger","strangle","strategy","strength","stricken","striking","striving","stroller","strongly","struggle","stubborn","stuffing","stunning","sturdily","stylized","subduing","subfloor","subgroup","sublease","sublevel","submerge","subpanel","subprime","subsonic","subtitle","subtotal","subtract","sufferer","suffrage","suitable","suitably","suitcase","sulphate","superior","superjet","superman","supermom","supplier","sureness","surgical","surprise","surround","survival","survivor","suspense","swapping","swimming","swimsuit","swimwear","swinging","sycamore","sympathy","symphony","syndrome","synopses","synopsis","tableful","tackling","tactical","tactless","talisman","tameness","tapeless","tapering","tapestry","tartness","tattered","tattling","theology","theorize","thespian","thieving","thievish","thinness","thinning","thirteen","thousand","threaten","thriving","throttle","throwing","thumping","thursday","tidiness","tightwad","tingling","tinkling","tinsmith","traction","trailing","tranquil","transfer","trapdoor","trapping","traverse","travesty","treading","trespass","triangle","tribunal","trickery","trickily","tricking","tricolor","tricycle","trillion","trimming","trimness","tripping","trolling","trombone","tropical","trousers","trustful","trusting","tubeless","tumbling","turbofan","turbojet","tweezers","twilight","twisting","ultimate","umbrella","unafraid","unbeaten","unbiased","unbitten","unbolted","unbridle","unbroken","unbundle","unburned","unbutton","uncapped","uncaring","uncoated","uncoiled","uncombed","uncommon","uncooked","uncouple","uncurled","underage","underarm","undercut","underdog","underfed","underpay","undertow","underuse","undocked","undusted","unearned","uneasily","unedited","unending","unenvied","unfasten","unfilled","unfitted","unflawed","unframed","unfreeze","unfrozen","unfunded","unglazed","ungloved","ungraded","unguided","unharmed","unheated","unhidden","unicycle","uniquely","unissued","universe","unjustly","unlawful","unleaded","unlinked","unlisted","unloaded","unloader","unlocked","unlovely","unloving","unmanned","unmapped","unmarked","unmasked","unmolded","unmoving","unneeded","unopened","unpadded","unpaired","unpeeled","unpicked","unpinned","unplowed","unproven","unranked","unrented","unrigged","unrushed","unsaddle","unsalted","unsavory","unsealed","unseated","unseeing","unseemly","unselect","unshaken","unshaved","unshaven","unsigned","unsliced","unsmooth","unsocial","unsoiled","unsolved","unsorted","unspoken","unstable","unsteady","unstitch","unsubtle","unsubtly","unsuited","untagged","untapped","unthawed","unthread","untimely","untitled","unturned","unusable","unvalued","unvaried","unveiled","unvented","unviable","unwanted","unwashed","unwieldy","unworthy","upcoming","upheaval","uplifted","uprising","upstairs","upstream","upstroke","upturned","urethane","vacation","vagabond","vagrancy","vanquish","variable","variably","vascular","vaseline","vastness","velocity","vendetta","vengeful","venomous","verbally","vertical","vexingly","vicinity","viewable","viewless","vigorous","vineyard","violator","virtuous","viselike","visiting","vitality","vitalize","vitamins","vocalist","vocalize","vocation","volatile","washable","washbowl","washroom","waviness","whacking","whenever","whisking","whomever","whooping","wildcard","wildfire","wildfowl","wildland","wildlife","wildness","winnings","wireless","wisplike","wobbling","wreckage","wrecking","wrongful","yearbook","yearling","yearning","zeppelin","abdomen","abiding","ability","abreast","abridge","absence","absolve","abstain","acclaim","account","acetone","acquire","acrobat","acronym","actress","acutely","aerosol","affront","ageless","agility","agonize","aground","alfalfa","algebra","almanac","alright","amenity","amiable","ammonia","amnesty","amplify","amusing","anagram","anatomy","anchovy","ancient","android","angelic","angling","angrily","angular","animate","annuity","another","antacid","anthill","antonym","anybody","anymore","anytime","apostle","appease","applaud","applied","approve","apricot","armband","armhole","armless","armoire","armored","armrest","arousal","arrange","arrival","ashamed","aspirin","astound","astride","atrophy","attempt","auction","audible","audibly","average","aviator","awkward","backing","backlit","backlog","badland","badness","baggage","bagging","bagpipe","balance","balcony","banking","banshee","barbell","barcode","barista","barmaid","barrack","barrier","battery","batting","bazooka","blabber","bladder","blaming","blazing","blemish","blinked","blinker","bloated","blooper","blubber","blurred","boaster","bobbing","bobsled","bobtail","bolster","bonanza","bonding","bonfire","booting","bootleg","borough","boxlike","breeder","brewery","brewing","bridged","brigade","brisket","briskly","bristle","brittle","broaden","broadly","broiler","brought","budding","buffalo","buffing","buffoon","bulldog","bullion","bullish","bullpen","bunkbed","busload","cabbage","caboose","cadmium","cahoots","calcium","caliber","caloric","calorie","calzone","camping","candied","canning","canteen","capable","capably","capital","capitol","capsize","capsule","caption","captive","capture","caramel","caravan","cardiac","carless","carload","carnage","carpool","carport","carried","cartoon","carving","carwash","cascade","catalog","catcall","catcher","caterer","catfish","catlike","cattail","catwalk","causing","caution","cavalry","certify","chalice","chamber","channel","chapped","chapter","charger","chariot","charity","charred","charter","chasing","chatter","cheddar","chemist","chevron","chewing","choking","chooser","chowder","citable","citadel","citizen","clapped","clapper","clarify","clarity","clatter","cleaver","clicker","climate","clobber","cloning","closure","clothes","clubbed","clutter","coastal","coaster","cobbler","coconut","coexist","collage","collide","comfort","commend","comment","commode","commute","company","compare","compile","compost","comrade","concave","conceal","concept","concert","concise","condone","conduit","confess","confirm","conform","conical","conjure","consent","console","consult","contact","contend","contest","context","contort","contour","control","convene","convent","copilot","copious","corncob","coroner","correct","corrode","corsage","cottage","country","courier","coveted","coyness","crafter","cranial","cranium","craving","crazily","creamed","creamer","crested","crevice","crewman","cricket","crimson","crinkle","crinkly","crisped","crisply","critter","crouton","crowbar","crucial","crudely","cruelly","cruelty","crumpet","crunchy","crushed","crusher","cryptic","crystal","cubical","cubicle","culprit","culture","cupcake","cupping","curable","curator","curling","cursive","curtain","custard","custody","customs","cycling","cyclist","dancing","darkish","darling","dawdler","daycare","daylong","dayroom","daytime","dazzler","dealing","debrief","decency","decibel","decimal","decline","default","defense","defiant","deflate","defraud","defrost","delouse","density","dentist","denture","deplete","depress","deprive","derived","deserve","desktop","despair","despise","despite","destiny","detract","devalue","deviant","deviate","devious","devotee","diagram","dictate","dimness","dingbat","diocese","dioxide","diploma","dipping","disband","discard","discern","discuss","disdain","disjoin","dislike","dismiss","disobey","display","dispose","dispute","disrupt","distant","distill","distort","divided","dolphin","donated","donator","doorman","doormat","doorway","drained","drainer","drapery","drastic","dreaded","dribble","driller","driving","drizzle","drizzly","dropbox","droplet","dropout","dropper","duchess","ducking","dumping","durable","durably","dutiful","dwelled","dweller","dwindle","dynamic","dynasty","earache","eardrum","earflap","earlobe","earmark","earmuff","earring","earshot","earthen","earthly","easeful","easiest","eatable","eclipse","ecology","economy","edition","effects","egotism","elastic","elderly","elevate","elitism","ellipse","elusive","embargo","embassy","emblaze","emerald","emotion","empathy","emperor","empower","emptier","enclose","encrust","encrypt","endless","endnote","endorse","engaged","engorge","engross","enhance","enjoyer","enslave","ensnare","entitle","entrust","entwine","envious","episode","equator","equinox","erasure","erratic","esquire","essence","etching","eternal","ethanol","evacuee","evasion","evasive","evident","exalted","example","exclaim","exclude","exhaust","expanse","explain","explode","exploit","explore","express","extinct","extrude","faceted","faction","factoid","factual","faculty","failing","falsify","fanatic","fancied","fanfare","fanning","fantasy","fascism","fasting","favored","federal","fencing","ferment","festive","fiction","fidgety","fifteen","figment","filling","finally","finance","finicky","finless","finlike","flaccid","flagman","flakily","flanked","flaring","flatbed","flatten","flattop","fleshed","florist","flyable","flyaway","flyover","footage","footing","footman","footpad","footsie","founder","fragile","framing","frantic","fraying","freebee","freebie","freedom","freeing","freeway","freight","fretful","fretted","frisbee","fritter","frosted","gaining","gallery","gallows","gangway","garbage","garland","garment","garnish","gauging","generic","gentile","geology","gestate","gesture","getaway","getting","giddily","gimmick","gizzard","glacial","glacier","glamour","glaring","glazing","gleeful","gliding","glimmer","glimpse","glisten","glitter","gloater","glorify","glowing","glucose","glutton","goggles","goliath","gondola","gosling","grading","grafted","grandly","grandma","grandpa","granite","granola","grapple","gratify","grating","gravity","grazing","greeter","grimace","gristle","grouped","growing","gruffly","grumble","grumbly","guiding","gumball","gumdrop","gumming","gutless","guzzler","habitat","hacking","hacksaw","haggler","halogen","hammock","hamster","handbag","handful","handgun","handled","handler","handoff","handsaw","handset","hangout","happier","happily","hardhat","harmful","harmony","harness","harpist","harvest","hastily","hatchet","hatless","heading","headset","headway","heavily","heaving","hedging","helpful","helping","hemlock","heroics","heroism","herring","herself","hexagon","humming","hunting","hurling","hurried","husband","hydrant","iciness","ideally","imaging","imitate","immerse","impeach","implant","implode","impound","imprint","improve","impulse","islamic","isotope","issuing","italics","jackpot","janitor","january","jarring","jasmine","jawless","jawline","jaybird","jellied","jitters","jittery","jogging","joining","joyride","jugular","jujitsu","jukebox","juniper","junkman","justice","justify","karaoke","kindred","kinetic","kinfolk","kinship","kinsman","kissing","kitchen","kleenex","krypton","labored","laborer","ladybug","lagging","landing","lantern","lapping","latrine","launder","laundry","legible","legibly","legroom","legwork","leotard","letdown","lettuce","liberty","library","licking","lifting","liftoff","limeade","limping","linseed","liquefy","liqueur","livable","lividly","luckily","lullaby","lumping","lumpish","lustily","machine","magenta","magical","magnify","majesty","mammary","manager","manatee","mandate","manhole","manhood","manhunt","mankind","manlike","manmade","mannish","marbled","marbles","marital","married","marxism","mashing","massive","mastiff","matador","matcher","maximum","moaning","mobster","modular","moisten","mollusk","mongrel","monitor","monsoon","monthly","moocher","moonlit","morally","mortify","mounted","mourner","movable","mullets","mummify","mundane","mushily","mustang","mustard","mutable","myspace","mystify","napping","nastily","natural","nearest","nemeses","nemesis","nervous","neutron","nuclear","nucleus","nullify","numbing","numeral","numeric","nursery","nursing","nurture","nutcase","nutlike","obliged","obscure","obvious","octagon","october","octopus","ominous","onboard","ongoing","onshore","onstage","opacity","operate","opossum","osmosis","outback","outcast","outcome","outgrow","outlast","outline","outlook","outmost","outpost","outpour","outrage","outrank","outsell","outward","overact","overall","overbid","overdue","overfed","overlap","overlay","overpay","overrun","overtly","overuse","oxidant","oxidize","pacific","padding","padlock","pajamas","pampers","pancake","panning","panther","paprika","papyrus","paradox","parched","parking","parkway","parsley","parsnip","partake","parting","partner","passage","passing","passion","passive","pastime","pasture","patient","patriot","payable","payback","payment","payroll","pelican","penalty","pendant","pending","pennant","pension","percent","perfume","perjury","petunia","phantom","phoenix","phonics","placard","placate","planner","plaster","plastic","plating","platter","playful","playing","playoff","playpen","playset","pliable","plunder","plywood","pointed","pointer","polygon","polymer","popcorn","popular","portion","postage","postbox","posting","posture","postwar","pouring","powdery","pranker","praying","preachy","precise","precook","predict","preface","pregame","prelude","premium","prepaid","preplan","preshow","presoak","presume","preteen","pretext","pretzel","prevail","prevent","preview","primary","primate","privacy","private","probing","problem","process","prodigy","produce","product","profane","profile","progeny","program","propose","prorate","proving","provoke","prowess","prowler","pruning","psychic","pulsate","pungent","purging","puritan","pursuit","pushing","pushpin","putdown","pyramid","quaking","qualify","quality","quantum","quarrel","quartet","quicken","quickly","quintet","ragweed","railcar","railing","railway","ranging","ranking","ransack","ranting","rasping","ravioli","reactor","reapply","reawake","rebirth","rebound","rebuild","rebuilt","recital","reclaim","recluse","recolor","recount","rectify","reenact","reenter","reentry","referee","refined","refocus","refract","refrain","refresh","refried","refusal","regalia","regally","regress","regroup","regular","reissue","rejoice","relapse","related","relearn","release","reliant","relieve","relight","remarry","rematch","remnant","remorse","removal","removed","remover","renewal","renewed","reoccur","reorder","repaint","replace","replica","reprint","reprise","reptile","request","require","reroute","rescuer","reshape","reshoot","residue","respect","rethink","retinal","retired","retiree","retouch","retrace","retract","retrain","retread","retreat","retrial","retying","reunion","reunite","reveler","revenge","revenue","revered","reverse","revisit","revival","reviver","rewrite","ribcage","rickety","ricotta","rifling","rigging","rimless","rinsing","ripcord","ripping","riptide","risotto","ritalin","riveter","roaming","robbing","rocking","rotting","rotunda","roundup","routine","routing","rubbing","rubdown","rummage","rundown","running","rupture","sabbath","saddled","sadness","saffron","sagging","salvage","sandbag","sandbar","sandbox","sanding","sandlot","sandpit","sapling","sarcasm","sardine","satchel","satisfy","savanna","savings","scabbed","scalded","scaling","scallop","scandal","scanner","scarily","scholar","science","scooter","scoring","scoured","scratch","scrawny","scrooge","scruffy","scrunch","scuttle","secrecy","secular","segment","seismic","seizing","seltzer","seminar","senator","serpent","service","serving","setback","setting","seventh","seventy","shadily","shading","shakily","shaking","shallot","shallow","shampoo","shaping","sharper","sharpie","sharply","shelter","shifter","shimmer","shindig","shingle","shining","shopper","shorten","shorter","shortly","showbiz","showing","showman","showoff","shrivel","shudder","shuffle","siamese","sibling","sighing","silicon","sincere","singing","sinless","sinuous","sitting","sixfold","sixteen","sixties","sizable","sizably","skating","skeptic","skilled","skillet","skimmed","skimmer","skipper","skittle","skyline","skyward","slacked","slacker","slander","slashed","slather","slicing","sliding","sloping","slouchy","smartly","smasher","smashup","smitten","smoking","smolder","smother","snagged","snaking","snippet","snooper","snoring","snorkel","snowcap","snowman","snuggle","species","specked","speller","spender","spinach","spindle","spinner","spinout","spirits","splashy","splurge","spoiled","spoiler","sponsor","spotted","spotter","spousal","sputter","squeeze","squishy","stadium","staging","stained","stamina","stammer","stardom","staring","starlet","starlit","starter","startle","startup","starved","stature","statute","staunch","stellar","stencil","sterile","sternum","stiffen","stiffly","stimuli","stinger","stipend","stoning","stopped","stopper","storage","stowing","stratus","stretch","strudel","stubbed","stubble","stubbly","student","studied","stuffed","stumble","stunned","stunner","styling","stylist","subdued","subject","sublime","subplot","subside","subsidy","subsoil","subtext","subtype","subzero","suction","suffice","suggest","sulfate","sulfide","sulfite","support","supreme","surface","surgery","surging","surname","surpass","surplus","surreal","survive","suspect","suspend","swagger","swifter","swiftly","swimmer","swinger","swizzle","swooned","symptom","synapse","synergy","t-shirt","tabasco","tabloid","tacking","tactful","tactics","tactile","tadpole","tainted","tannery","tanning","tantrum","tapered","tapioca","tapping","tarnish","tasting","theater","thermal","thermos","thicken","thicket","thimble","thinner","thirsty","thrower","thyself","tidings","tighten","tightly","tigress","timothy","tinfoil","tinwork","tipping","tracing","tractor","trading","traffic","tragedy","traitor","trapeze","trapped","trapper","treason","trekker","tremble","tribune","tribute","triceps","trickle","trident","trilogy","trimmer","trinity","triumph","trivial","trodden","tropics","trouble","truffle","trustee","tubular","tucking","tuesday","tuition","turbine","turmoil","twiddle","twisted","twister","twitter","unaired","unawake","unaware","unbaked","unblock","unboxed","uncanny","unchain","uncheck","uncivil","unclasp","uncloak","uncouth","uncover","uncross","uncrown","uncured","undated","undergo","undoing","undress","undying","unearth","uneaten","unequal","unfazed","unfiled","unfixed","ungodly","unhappy","unheard","unhinge","unicorn","unified","unifier","unkempt","unknown","unlaced","unlatch","unleash","unlined","unloved","unlucky","unmixed","unmoral","unmoved","unnamed","unnerve","unpaved","unquote","unrated","unrobed","unsaved","unscrew","unstuck","unsworn","untaken","untamed","untaxed","untimed","untried","untruth","untwist","untying","unusual","unvocal","unweave","unwired","unwound","unwoven","upchuck","upfront","upgrade","upright","upriver","upscale","upstage","upstart","upstate","upswing","uptight","uranium","urgency","urology","useable","utensil","utility","utilize","vacancy","vaguely","valiant","vanilla","vantage","variety","various","varmint","varnish","varsity","varying","vending","venture","verbose","verdict","version","vertigo","veteran","victory","viewing","village","villain","vintage","violate","virtual","viscous","visible","visibly","visitor","vitally","vividly","vocally","voicing","voltage","volumes","voucher","walmart","wannabe","wanting","washday","washing","washout","washtub","wasting","whoever","whoopee","wielder","wildcat","willing","wincing","winking","wistful","womanly","worried","worrier","wrangle","wrecker","wriggle","wriggly","wrinkle","wrinkly","writing","written","wronged","wrongly","wrought","yanking","yapping","yelling","yiddish","zealous","zipfile","zipping","zoology","abacus","ablaze","abroad","absurd","accent","aching","acting","action","active","affair","affirm","afford","aflame","afloat","afraid","agency","agenda","aghast","agreed","aliens","almost","alumni","always","ambush","amends","amount","amulet","amused","amuser","anchor","anemia","anemic","angled","angler","angles","animal","anthem","antics","antler","anyhow","anyone","anyway","apache","appear","armful","arming","armory","around","arrest","arrive","ascend","ascent","asleep","aspect","aspire","astute","atrium","attach","attain","attest","attire","august","author","autism","avatar","avenge","avenue","awaken","awhile","awning","babble","babied","baboon","backed","backer","backup","badass","baffle","bagful","bagged","baggie","bakery","baking","bamboo","banana","banish","banked","banker","banner","banter","barbed","barber","barley","barman","barrel","basics","basket","batboy","battle","bauble","blazer","bleach","blinks","blouse","bluish","blurry","bobbed","bobble","bobcat","bogged","boggle","bonded","bonnet","bonsai","booted","bootie","boring","botany","bottle","bottom","bounce","bouncy","bovine","boxcar","boxing","breach","breath","breeze","breezy","bright","broken","broker","bronco","bronze","browse","brunch","bubble","bubbly","bucked","bucket","buckle","budget","buffed","buffer","bulgur","bundle","bungee","bunion","busboy","busily","cabana","cabbie","cackle","cactus","caddie","camera","camper","campus","canary","cancel","candle","canine","canned","cannon","cannot","canola","canopy","canyon","capped","carbon","carded","caress","caring","carrot","cartel","carton","casing","casino","casket","catchy","catnap","catnip","catsup","cattle","caucus","causal","caviar","cavity","celery","celtic","cement","census","chance","change","chaste","chatty","cheese","cheesy","cherub","chewer","chirpy","choice","choosy","chosen","chrome","chubby","chummy","cinema","circle","circus","citric","citrus","clammy","clamor","clause","clench","clever","client","clinic","clique","clover","clumsy","clunky","clutch","cobalt","cobweb","coerce","coffee","collar","collie","colony","coming","common","compel","comply","concur","copied","copier","coping","copper","cornea","corned","corner","corral","corset","cortex","cosmic","cosmos","cotton","county","cozily","cradle","crafty","crayon","crazed","crease","create","credit","creole","cringe","crispy","crouch","crummy","crying","cuddle","cuddly","cupped","curdle","curfew","curing","curled","curler","cursor","curtly","curtsy","cussed","cyclic","cymbal","dagger","dainty","dander","danger","dangle","dating","daybed","deacon","dealer","debate","debtor","debunk","decade","deceit","decent","decode","decree","deduce","deduct","deepen","deeply","deface","defame","defeat","defile","define","deftly","defuse","degree","delete","deluge","deluxe","demise","demote","denial","denote","dental","depict","deploy","deport","depose","deputy","derail","detail","detest","device","diaper","dicing","dilute","dimmed","dimmer","dimple","dinghy","dining","dinner","dipped","dipper","disarm","dismay","disown","diving","doable","docile","dollar","dollop","domain","doodle","dorsal","dosage","dotted","douche","dreamt","dreamy","dreary","drench","drippy","driven","driver","drudge","dubbed","duffel","dugout","duller","duplex","duress","during","earful","earthy","earwig","easily","easing","easter","eatery","eating","eclair","edging","editor","effort","egging","eggnog","either","elated","eldest","eleven","elixir","embark","emblem","embody","emboss","enable","enamel","encode","encore","ending","energy","engine","engulf","enrage","enrich","enroll","ensure","entail","entire","entity","entomb","entrap","entree","enzyme","equate","equity","erased","eraser","errand","errant","eskimo","estate","ethics","evolve","excess","excuse","exhale","exhume","exodus","expand","expend","expert","expire","expose","extent","extras","fabric","facial","facing","factor","fading","falcon","family","famine","faster","faucet","fedora","feeble","feisty","feline","fender","ferret","ferris","fervor","fester","fiddle","figure","filing","filled","filler","filter","finale","finite","flashy","flatly","fleshy","flight","flinch","floral","flying","follow","fondly","fondue","footer","fossil","foster","frayed","freely","french","frenzy","friday","fridge","friend","fringe","frolic","frosty","frozen","frying","galley","gallon","galore","gaming","gander","gangly","garage","garden","gargle","garlic","garnet","garter","gating","gazing","geiger","gender","gently","gerbil","giblet","giggle","giggly","gigolo","gilled","girdle","giving","gladly","glance","glider","glitch","glitzy","gloomy","gluten","gnarly","google","gopher","gorged","gossip","gothic","gotten","graded","grader","granny","gravel","graves","greedy","grinch","groggy","groove","groovy","ground","grower","grudge","grunge","gurgle","gutter","hacked","hacker","halved","halves","hamlet","hamper","handed","hangup","hankie","harbor","hardly","hassle","hatbox","hatred","hazard","hazily","hazing","headed","header","helium","helmet","helper","herald","herbal","hermit","hubcap","huddle","humble","humbly","hummus","humped","humvee","hunger","hungry","hunter","hurdle","hurled","hurler","hurray","husked","hybrid","hyphen","idiocy","ignore","iguana","impale","impart","impish","impose","impure","iodine","iodize","iphone","itunes","jackal","jacket","jailer","jargon","jersey","jester","jigsaw","jingle","jockey","jogger","jovial","joyous","juggle","jumble","junior","junkie","jurist","justly","karate","keenly","kennel","kettle","kimono","kindle","kindly","kisser","kitten","kosher","ladder","ladies","lagged","lagoon","landed","lapdog","lapped","laptop","lather","latter","launch","laurel","lavish","lazily","legacy","legend","legged","legume","length","lesser","letter","levers","liable","lifter","likely","liking","lining","linked","liquid","litmus","litter","little","lively","living","lizard","lugged","lumber","lunacy","lushly","luster","luxury","lyrics","maggot","maimed","making","mammal","manger","mangle","manila","manned","mantis","mantra","manual","margin","marina","marine","marlin","maroon","marrow","marshy","mascot","mashed","masses","mating","matrix","matron","matted","matter","mayday","moaner","mobile","mocker","mockup","modify","module","monday","mooing","mooned","morale","mosaic","motion","motive","moving","mowing","mulled","mumble","muppet","museum","musket","muster","mutate","mutiny","mutual","muzzle","myself","naming","napkin","napped","narrow","native","nature","nearby","nearly","neatly","nebula","nectar","negate","nephew","neuron","neuter","nibble","nimble","nimbly","nuclei","nugget","number","numbly","nutmeg","nuzzle","object","oblong","obtain","obtuse","occupy","ocelot","octane","online","onward","oppose","outage","outbid","outfit","outing","outlet","output","outwit","oxford","oxygen","oyster","pacify","padded","paddle","paging","palace","paltry","panama","pantry","papaya","parade","parcel","pardon","parish","parlor","parole","parrot","parted","partly","pasted","pastel","pastor","patchy","patrol","pauper","paving","pawing","payday","paying","pebble","pebbly","pectin","pellet","pelvis","pencil","penpal","perish","pester","petite","petted","phobia","phoney","phrase","plasma","plated","player","pledge","plenty","plural","pointy","poison","poking","police","policy","polish","poncho","poplar","popper","porous","portal","portly","posing","possum","postal","posted","poster","pounce","powwow","prance","prayer","precut","prefix","prelaw","prepay","preppy","preset","pretty","prewar","primal","primer","prison","prissy","pronto","proofs","proton","proved","proven","prozac","public","pucker","pueblo","pumice","pummel","puppet","purely","purify","purist","purity","purple","pusher","pushup","puzzle","python","quarry","quench","quiver","racing","racism","racoon","radial","radish","raffle","ragged","raging","raider","raisin","raking","ramble","ramrod","random","ranged","ranger","ranked","rarity","rascal","ravage","ravine","raving","reason","rebate","reboot","reborn","rebuff","recall","recant","recast","recede","recent","recess","recite","recoil","recopy","record","recoup","rectal","refill","reflex","reflux","refold","refund","refuse","refute","regain","reggae","regime","region","reheat","rehire","rejoin","relish","relive","reload","relock","remake","remark","remedy","remold","remote","rename","rental","rented","renter","reopen","repair","repave","repeal","repent","replay","repose","repost","resale","reseal","resend","resent","resize","resort","result","resume","retail","retake","retold","retool","return","retype","reveal","reverb","revert","revise","revoke","revolt","reward","rewash","rewind","rewire","reword","rework","rewrap","ribbon","riches","richly","ridden","riding","rimmed","ripple","rising","roamer","robust","rocker","rocket","roping","roster","rotten","roving","rubbed","rubber","rubble","ruckus","rudder","ruined","rumble","runner","runway","sacred","sadden","safari","safely","salami","salary","saline","saloon","salute","sample","sandal","sanded","savage","savior","scabby","scarce","scared","scenic","scheme","scorch","scored","scorer","scotch","scouts","screen","scribe","script","scroll","scurvy","second","secret","sector","sedate","seduce","seldom","senate","senior","septic","septum","sequel","series","sermon","sesame","settle","shabby","shaded","shadow","shanty","sheath","shelve","sherry","shield","shifty","shimmy","shorts","shorty","shower","shrank","shriek","shrill","shrimp","shrine","shrink","shrubs","shrunk","siding","sierra","siesta","silent","silica","silver","simile","simple","simply","singer","single","sinner","sister","sitcom","sitter","sizing","sizzle","skater","sketch","skewed","skewer","skiing","skinny","slacks","sleeve","sliced","slicer","slider","slinky","sliver","slogan","sloped","sloppy","sludge","smoked","smooth","smudge","smudgy","smugly","snazzy","sneeze","snitch","snooze","snugly","specks","speech","sphere","sphinx","spider","spiffy","spinal","spiral","spleen","splice","spoils","spoken","sponge","spongy","spooky","sports","sporty","spotty","spouse","sprain","sprang","sprawl","spring","sprint","sprite","sprout","spruce","sprung","squall","squash","squeak","squint","squire","squirt","stable","staple","starch","starry","static","statue","status","stench","stereo","stifle","stingy","stinky","stitch","stooge","streak","stream","street","stress","strewn","strict","stride","strife","strike","strive","strobe","strode","struck","strung","stucco","studio","stuffy","stupor","sturdy","stylus","sublet","subpar","subtly","suburb","subway","sudden","sudoku","suffix","suitor","sulfur","sullen","sultry","supper","supply","surely","surfer","survey","swerve","switch","swivel","swoosh","system","tables","tablet","tackle","taking","talcum","tamale","tamper","tanned","target","tarmac","tartar","tartly","tassel","tattle","tattoo","tavern","thesis","thinly","thirty","thrash","thread","thrift","thrill","thrive","throat","throng","tidbit","tiling","timing","tingle","tingly","tinker","tinsel","tipoff","tipped","tipper","tiptop","tiring","tissue","trance","travel","treble","tremor","trench","triage","tricky","trifle","tripod","trophy","trough","trowel","trunks","tumble","turban","turkey","turret","turtle","twelve","twenty","twisty","twitch","tycoon","umpire","unable","unbend","unbent","unclad","unclip","unclog","uncork","undead","undone","unease","uneasy","uneven","unfair","unfold","unglue","unholy","unhook","unison","unkind","unless","unmade","unpack","unpaid","unplug","unread","unreal","unrest","unripe","unroll","unruly","unsafe","unsaid","unseen","unsent","unsnap","unsold","unsure","untidy","untold","untrue","unused","unwary","unwell","unwind","unworn","upbeat","update","upheld","uphill","uphold","upload","uproar","uproot","upside","uptake","uptown","upward","upwind","urchin","urgent","urging","usable","utmost","utopia","vacant","vacate","valium","valley","vanish","vanity","varied","vastly","veggie","velcro","velvet","vendor","verify","versus","vessel","viable","viewer","violet","violin","vision","volley","voting","voyage","waffle","waggle","waking","walnut","walrus","wanted","wasabi","washed","washer","waving","whacky","whinny","whoops","widely","widget","wilder","wildly","willed","willow","winner","winter","wiring","wisdom","wizard","wobble","wobbly","wooing","wreath","wrench","yearly","yippee","yogurt","yonder","zodiac","zombie","zoning","abide","acorn","affix","afoot","agent","agile","aging","agony","ahead","alarm","album","alias","alibi","alike","alive","aloft","aloha","alone","aloof","amaze","amber","amigo","amino","amiss","among","ample","amply","amuck","anger","anime","ankle","annex","antsy","anvil","aorta","apple","apply","april","apron","aptly","arena","argue","arise","armed","aroma","arose","array","arson","ashen","ashes","aside","askew","atlas","attic","audio","avert","avoid","await","award","aware","awoke","bacon","badge","badly","bagel","baggy","baked","balmy","banjo","barge","basil","basin","basis","batch","baton","blade","blame","blank","blast","bleak","bleep","blend","bless","blimp","bling","blitz","bluff","blunt","blurb","blurt","blush","bogus","boned","boney","bonus","booth","boots","boozy","borax","botch","boxer","briar","bribe","brick","bride","bring","brink","brook","broom","brunt","brush","brute","buddy","buggy","bulge","bully","bunch","bunny","cable","cache","cacti","caddy","cadet","cameo","canal","candy","canon","carat","cargo","carol","carry","carve","catty","cause","cedar","chafe","chain","chair","chant","chaos","chaps","charm","chase","cheek","cheer","chemo","chess","chest","chevy","chewy","chief","chili","chill","chimp","chive","chomp","chuck","chump","chunk","churn","chute","cider","cinch","civic","civil","claim","clamp","clang","clash","clasp","class","clean","clear","cleat","cleft","clerk","cling","cloak","clock","clone","cloud","clump","coach","cocoa","comfy","comic","comma","conch","coral","corny","couch","cough","could","cover","cramp","crane","crank","crate","crave","crazy","creed","creme","crepe","crept","cried","crier","crimp","croak","crock","crook","croon","cross","crowd","crown","crumb","crust","cupid","curly","curry","curse","curve","curvy","cushy","cycle","daily","dairy","daisy","dance","dandy","dares","dealt","debit","debug","decaf","decal","decay","decoy","defog","deity","delay","delta","denim","dense","depth","derby","deuce","diary","dimly","diner","dingo","dingy","ditch","ditto","ditzy","dizzy","dodge","dodgy","doily","doing","dolly","donor","donut","doozy","dowry","drank","dress","dried","drier","drift","drone","drool","droop","drove","drown","ducky","duvet","dwarf","dweeb","eagle","early","easel","eaten","ebony","ebook","ecard","eject","elbow","elite","elope","elude","elves","email","ember","emcee","emote","empty","ended","envoy","equal","error","erupt","essay","ether","evade","evict","evoke","exact","exert","exile","expel","fable","false","fancy","feast","femur","fence","ferry","fetal","fetch","fever","fiber","fifth","fifty","filth","finch","finer","flail","flaky","flame","flask","flick","flier","fling","flint","flirt","float","flock","floss","flyer","folic","foyer","frail","frame","frays","fresh","fried","frill","frisk","front","froth","frown","fruit","gaffe","gains","gamma","gauze","gecko","genre","gents","getup","giant","giddy","gills","given","giver","gizmo","glade","glare","glass","glory","gloss","glove","going","gonad","gooey","goofy","grain","grant","grape","graph","grasp","grass","gravy","green","grief","grill","grime","grimy","groin","groom","grope","grout","grove","growl","grunt","guide","guise","gully","gummy","gusto","gusty","haiku","hanky","happy","hardy","harsh","haste","hasty","haunt","haven","heave","hedge","hefty","hence","henna","herbs","hertz","human","humid","hurry","icing","idiom","igloo","image","imply","irate","issue","ivory","jaunt","jawed","jelly","jiffy","jimmy","jolly","judge","juice","juicy","jumbo","juror","kabob","karma","kebab","kitty","knelt","knoll","koala","kooky","kudos","ladle","lance","lanky","lapel","large","lasso","latch","legal","lemon","level","lilac","lilly","limes","limit","lingo","lived","liver","lucid","lunar","lurch","lusty","lying","macaw","magma","maker","mango","mangy","manly","manor","march","mardi","marry","mauve","maybe","mocha","molar","moody","morse","mossy","motor","motto","mouse","mousy","mouth","movie","mower","mulch","mumbo","mummy","mumps","mural","murky","mushy","music","musky","musty","nacho","nanny","nappy","nervy","never","niece","nifty","ninja","ninth","nutty","nylon","oasis","ocean","olive","omega","onion","onset","opium","other","otter","ought","ounce","outer","ovary","ozone","paced","pagan","pager","panda","panic","pants","paper","parka","party","pasta","pasty","patio","paver","payee","payer","pecan","penny","perch","perky","pesky","petal","petri","petty","phony","photo","plank","plant","plaza","pleat","pluck","poach","poise","poker","polar","polio","polka","poppy","poser","pouch","pound","power","press","pried","primp","print","prior","prism","prize","probe","prone","prong","props","proud","proxy","prude","prune","pulse","punch","pupil","puppy","purge","purse","pushy","quack","quail","quake","qualm","query","quiet","quill","quilt","quirk","quote","rabid","radar","radio","rally","ranch","rants","raven","reach","rebel","rehab","relax","relay","relic","remix","reply","rerun","reset","retry","reuse","rhyme","rigid","rigor","rinse","ritzy","rival","roast","robin","rocky","rogue","roman","rover","royal","rumor","runny","rural","sadly","saggy","saint","salad","salon","salsa","sandy","santa","sappy","sassy","satin","saucy","sauna","saved","savor","scale","scant","scarf","scary","scion","scoff","scone","scoop","scope","scorn","scrap","scuba","scuff","sedan","sepia","serve","setup","shack","shady","shaft","shaky","shale","shame","shank","shape","share","shawl","sheep","sheet","shelf","shell","shine","shiny","shirt","shock","shone","shore","shout","shove","shown","showy","shrug","shush","silly","siren","sixth","skied","skier","skies","skirt","skype","slain","slang","slate","sleek","sleep","sleet","slept","slick","slimy","slurp","slush","small","smell","smile","smirk","smite","smith","smock","smoky","snack","snare","snarl","sneak","sneer","snide","sniff","snore","snort","snout","snowy","snuff","speak","speed","spent","spied","spill","spilt","spiny","spoof","spool","spoon","spore","spout","spray","spree","sprig","squad","squid","stack","staff","stage","stamp","stand","stank","stark","stash","state","stays","steam","steed","steep","stick","stilt","stock","stoic","stoke","stole","stomp","stony","stood","stool","stoop","storm","stout","stove","straw","stray","strep","strum","strut","stuck","study","stump","stung","stunt","suave","sugar","suing","sushi","swarm","swear","sweat","sweep","swell","swept","swipe","swirl","swoop","swore","sworn","swung","syrup","tabby","tacky","talon","tamer","tarot","taste","tasty","taunt","thank","theft","theme","these","thigh","thing","think","thong","thorn","those","thumb","tiara","tibia","tidal","tiger","timid","trace","track","trade","train","traps","trash","treat","trend","trial","tried","trout","truce","truck","trump","truth","tubby","tulip","tummy","tutor","tweak","tweed","tweet","twerp","twice","twine","twins","twirl","tying","udder","ultra","uncle","uncut","unify","union","unlit","untie","until","unwed","unzip","upper","urban","usage","usher","usual","utter","valid","value","vegan","venue","venus","verse","vibes","video","viper","viral","virus","visor","vista","vixen","voice","voter","vowed","vowel","wafer","waged","wager","wages","wagon","waltz","watch","water","wharf","wheat","whiff","whiny","whole","widen","widow","width","wince","wired","wispy","woozy","worry","worst","wound","woven","wrath","wrist","xerox","yahoo","yeast","yield","yo-yo","yodel","yummy","zebra","zesty","zippy","able","acid","acre","acts","afar","aged","ahoy","aide","aids","ajar","aloe","alto","amid","anew","aqua","area","army","ashy","atom","atop","avid","awry","axis","barn","bash","bath","bats","blah","blip","blob","blog","blot","boat","body","boil","bolt","bony","book","boss","both","boxy","brim","bulb","bulk","bunt","bush","bust","buzz","cage","cake","calm","cane","cape","case","cash","chef","chip","chop","chug","city","clad","claw","clay","clip","coat","coil","coke","cola","cold","colt","coma","come","cone","cope","copy","cork","cost","cozy","crib","crop","crux","cube","cure","cusp","darn","dart","dash","data","dawn","dean","deck","deed","deem","defy","deny","dial","dice","dill","dime","dish","disk","dock","dole","dork","dose","dove","down","doze","drab","draw","drew","drum","duct","dude","duke","duly","dupe","dusk","dust","duty","each","eats","ebay","echo","edge","edgy","emit","envy","epic","even","evil","exes","exit","fade","fall","fame","fang","feed","feel","film","five","flap","fled","flip","flop","foam","foil","folk","font","food","fool","from","gala","game","gave","gawk","gear","geek","gift","glue","gnat","goal","goes","golf","gone","gong","good","goon","gore","gory","gout","gown","grab","gray","grew","grid","grip","grit","grub","gulf","gulp","guru","gush","guts","half","halt","hash","hate","hazy","heap","heat","huff","hula","hulk","hull","hunk","hurt","hush","icky","icon","idly","ipad","ipod","iron","item","java","jaws","jazz","jeep","jinx","john","jolt","judo","july","jump","june","jury","keep","kelp","kept","kick","kiln","kilt","king","kite","kiwi","knee","kung","lair","lake","lard","lark","lash","last","late","lazy","left","lego","lend","lens","lent","life","lily","limb","line","lint","lion","lisp","list","lung","lure","lurk","mace","malt","mama","many","math","mold","most","move","much","muck","mule","mute","mutt","myth","nail","name","nape","navy","neon","nerd","nest","next","oboe","ogle","oink","okay","omen","omit","only","onto","onyx","oops","ooze","oozy","opal","open","ouch","oval","oven","palm","pang","path","pelt","perm","peso","plod","plop","plot","plow","ploy","plug","plus","poem","poet","pogo","polo","pond","pony","pope","pork","posh","pout","pull","pulp","puma","punk","purr","putt","quit","race","rack","raft","rage","rake","ramp","rare","rash","ream","rely","reps","rice","ride","rift","rind","rink","riot","rise","risk","robe","romp","rope","rosy","ruby","rule","runt","ruse","rush","rust","saga","sage","said","sake","salt","same","sank","sash","scam","self","send","shed","ship","shun","shut","sift","silk","silo","silt","size","skid","slab","slam","slaw","sled","slip","slit","slot","slug","slum","smog","snap","snub","spew","spry","spud","spur","stem","step","stew","stir","such","suds","sulk","swab","swan","sway","taco","take","tall","tank","taps","task","that","thaw","thee","thud","thus","tidy","tile","till","tilt","tint","tiny","tray","tree","trio","turf","tusk","tutu","twig","tyke","unit","upon","used","user","veal","very","vest","veto","vice","visa","void","wake","walk","wand","wasp","wavy","wham","wick","wife","wifi","wilt","wimp","wind","wing","wipe","wiry","wise","wish","wolf","womb","woof","wool","word","work","xbox","yard","yarn","yeah","yelp","yoga","yoyo","zero","zips","zone","zoom","aim","art","bok","cod","cut","dab","dad","dig","dry","duh","duo","eel","elf","elk","elm","emu","fax","fit","foe","fog","fox","gab","gag","gap","gas","gem","guy","had","hug","hut","ice","icy","ion","irk","ivy","jab","jam","jet","job","jot","keg","lid","lip","map","mom","mop","mud","mug","nag","net","oaf","oak","oat","oil","old","opt","owl","pep","pod","pox","pry","pug","rug","rut","say","shy","sip","sly","tag","try","tug","tux","wad","why","wok","wow","yam","yen","yin","zap","zen","zit"]};var Fi=a(2052),ji=a.n(Fi);const Li=[{id:"not_available",label:"N/A",strength:0},{id:"very-weak",label:"Very weak",strength:1},{id:"weak",label:"Weak",strength:60},{id:"fair",label:"Fair",strength:80},{id:"strong",label:"Strong",strength:112},{id:"very-strong",label:"Very strong",strength:128}],qi={mask_upper:{label:"A-Z",characters:["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"]},mask_lower:{label:"a-z",characters:["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"]},mask_digit:{label:"0-9",characters:["0","1","2","3","4","5","6","7","8","9"]},mask_char1:{label:"# $ % & @ ^ ~",characters:["#","$","%","&","@","^","~"]},mask_parenthesis:{label:"{ [ ( | ) ] }",characters:["{","(","[","|","]",")","}"]},mask_char2:{label:". , : ;",characters:[".",",",":",";"]},mask_char3:{label:"' \" `",characters:["'",'"',"`"]},mask_char4:{label:"/ \\ _ -",characters:["/","\\","_","-"]},mask_char5:{label:"< * + ! ? =",characters:["<","*","+","!","?","="]},mask_emoji:{label:"😘",characters:["😀","😁","😂","😃","😄","😅","😆","😇","😈","😉","😊","😋","😌","😍","😎","😏","😐","😑","😒","😓","😔","😕","😖","😗","😘","😙","😚","😛","😜","😝","😞","😟","😠","😡","😢","😣","😤","😥","😦","😧","😨","😩","😪","😫","😬","😭","😮","😯","😰","😱","😲","😳","😴","😵","😶","😷","😸","😹","😺","😻","😼","😽","😾","😿","🙀","🙁","🙂","🙃","🙄","🙅","🙆","🙇","🙈","🙉","🙊","🙋","🙌","🙍","🙎","🙏"]}},zi=["O","l","|","I","0","1"],Ki=Object.values(qi).flatMap(e=>e.characters),Vi={evaluateMaxPasswordEntropy:e=>{const t=Object.entries(qi).filter(([t])=>e[t]).reduce((e,[t])=>[...e,...qi[t].characters],[]).filter(t=>!e.exclude_look_alike_chars||!zi.includes(t));return Gi(e.length,t.length)},entropyPassword:(e="")=>{const t=(new(ji())).splitGraphemes(e);let a=0;for(const[e]of Object.entries(qi)){const n=qi[e];t.some(e=>n.characters.includes(e))&&(a+=n.characters.length)}const n=new Set(t.filter(e=>!Ki.includes(e)));return Gi(t.length,a+n.size)},entropyPassphrase:(e=0,t="")=>Gi(e,3*Ui["en-UK"].length)+Vi.entropyPassword(t),strength:(e=0)=>Li.reduce((t,a)=>t?a.strength>t.strength&&e>=a.strength?a:t:a),calculEntropy:Gi};function Gi(e,t){return e&&t?e*(Math.log(t)/Math.log(2)):0}const Bi=function(e){const t={isPassphrase:!1};if(!e)return t;const a=Ui["en-UK"].reduce((e,t)=>{const a=e.remainingSecret.replace(new RegExp(t,"g"),""),n=(e.remainingSecret.length-a.length)/t.length;return{numberReplacement:e.numberReplacement+n,remainingSecret:a}},{numberReplacement:0,remainingSecret:e.toLowerCase()}),n=a.remainingSecret,s=a.numberReplacement-1;if(1===s)return-1===e.indexOf(n)||e.startsWith(n)||e.endsWith(n)?t:{numberWords:2,separator:n,isPassphrase:!0};if(0==n.length)return{numberWords:a.numberReplacement,separator:"",isPassphrase:!0};if(n.length%s!==0)return t;const i=n.length/s,r=n.substring(0,i),o=String(r).replace(/([-()[\]{}+?*.$^|,:#0}},Ji=(e,t)=>t.split(".").reduce((e,t)=>e?.[t],e),Xi=(e,t)=>{if(void 0===e||"string"!=typeof e||!e.length)return!1;if((t=t||{}).whitelistedProtocols&&!Array.isArray(t.whitelistedProtocols))throw new TypeError("The whitelistedProtocols should be an array of string.");if(t.defaultProtocol&&"string"!=typeof t.defaultProtocol)throw new TypeError("The defaultProtocol should be a string.");const a=t.whitelistedProtocols||[Qi.HTTP,Qi.HTTPS],n=[Qi.JAVASCRIPT],s=t.defaultProtocol||"";!/^(?:(?!:\/\/).)*:\/\//.test(e)&&s&&(e=`${s}//${e}`);try{const t=new URL(e);return!n.includes(t.protocol)&&!!a.includes(t.protocol)&&t.href}catch(e){return console.error("Failed to sanitize URL:",e),!1}},Qi={FTP:"http:",FTPS:"https:",HTTP:"http:",HTTPS:"https:",JAVASCRIPT:"javascript:",SSH:"ssh:"};class er{constructor(e){this.settings=this.sanitizeDto(e)}sanitizeDto(e){const t=JSON.parse(JSON.stringify(e));return this.sanitizeEmailValidateRegex(t),t}sanitizeEmailValidateRegex(e){const t=e?.passbolt?.email?.validate?.regex;t&&"string"==typeof t&&t.trim().length&&(e.passbolt.email.validate.regex=t.trim().replace(/^\/+/,"").replace(/\/+$/,""))}canIUse(e){let t=!1;const a=`passbolt.plugins.${e}`,n=Ji(this.settings,a)||null;if(n&&"object"==typeof n){const e=Ji(n,"enabled");void 0!==e&&!0!==e||(t=!0)}return t}isFeatureBeta(e){(0,ie.A)(e);const t=`passbolt.plugins.${e}.isInBeta`;return Ji(this.settings,t)||!1}getPluginSettings(e){const t=`passbolt.plugins.${e}`;return Ji(this.settings,t)}getRememberMeOptions(){return(this.getPluginSettings("rememberMe")||{}).options||{}}get hasRememberMeUntilILogoutOption(){return void 0!==(this.getRememberMeOptions()||{})[-1]}getServerTimezone(){return Ji(this.settings,"passbolt.app.server_timezone")}get termsLink(){const e=Ji(this.settings,"passbolt.legal.terms.url");return!!e&&Xi(e)}get privacyLink(){const e=Ji(this.settings,"passbolt.legal.privacy_policy.url");return!!e&&Xi(e)}get registrationPublic(){return!0===Ji(this.settings,"passbolt.registration.public")}get debug(){return!0===Ji(this.settings,"app.debug")}get url(){return Ji(this.settings,"app.url")||""}get version(){return Ji(this.settings,"app.version.number")}get isCommunityEdition(){return"ce"===Ji(this.settings,"passbolt.edition")}get locale(){return Ji(this.settings,"app.locale")||er.DEFAULT_LOCALE.locale}async setLocale(e){this.settings.app.locale=e}get supportedLocales(){return Ji(this.settings,"passbolt.plugins.locale.options")||er.DEFAULT_SUPPORTED_LOCALES}get generatorConfiguration(){return Ji(this.settings,"passbolt.plugins.generator.configuration")}get emailValidateRegex(){return this.settings?.passbolt?.email?.validate?.regex||null}static get DEFAULT_SUPPORTED_LOCALES(){return[er.DEFAULT_LOCALE]}static get DEFAULT_LOCALE(){return{locale:"en-UK",label:"English"}}}class tr{static validate(e){return"string"==typeof e&&Qt()("^[\\p{L}0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\p{L}0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[_\\p{L}0-9][-_\\p{L}0-9]*\\.)*(?:[\\p{L}0-9][-\\p{L}0-9]{0,62})\\.(?:(?:[a-z]{2}\\.)?[a-z]{2,})$","i").test(e)}}class ar{constructor(e){if("string"!=typeof e)throw Error("The regex should be a string.");this.regex=new(Qt())(e)}validate(e){return"string"==typeof e&&this.regex.test(e)}}class nr{static validate(e,t){return nr.getValidator(t).validate(e)}static getValidator(e){return e&&e instanceof er&&e.emailValidateRegex?new ar(e.emailValidateRegex):tr}}function sr(){return sr=Object.assign?Object.assign.bind():function(e){for(var t=1;t{}});class rr extends n.Component{constructor(e){super(e),this.state=this.defaultState}get defaultState(){return{policies:null,loadPolicies:this.loadPolicies.bind(this),setPolicies:this.setPolicies.bind(this)}}async loadPolicies(){const{policies:e}=this.state;if(null!==e)return e;const t=await this.props.context.port.request("passbolt.password-policies.get");return this.setPolicies(t),t}setPolicies(e){this.setState({policies:e})}render(){return n.createElement(ir.Provider,{value:this.state},this.props.children)}}function or(e){return class extends n.Component{render(){return n.createElement(ir.Consumer,null,t=>n.createElement(e,sr({passwordPoliciesContext:t},this.props)))}}}rr.propTypes={context:i().any,children:i().any},N(rr);class lr extends n.PureComponent{static getRelativeEntropyPosition(e){return 100-99/(1+Math.pow(e/90,3))}formatEntropy(e){return(e=e||0).toFixed(1)}get relativeTargetEntropyRatio(){return lr.getRelativeEntropyPosition(this.props.targetEntropy)}get targetEntropyPositionStyle(){return{left:`calc(${this.relativeTargetEntropyRatio}% - 0.6rem)`}}get colorClassName(){return this.hasEntropy()?this.props.entropy>=this.props.targetEntropy?"reached":this.props.isMinimumEntropyRequired?"required":"recommended":""}get targetTooltipMessage(){return this.props.isMinimumEntropyRequired?this.props.t("Minimal requirement"):this.props.t("Minimal recommendation")}get currentEntropyTooltipMessage(){const e=this.formatEntropy(this.props.entropy),t=this.formatEntropy(this.props.targetEntropy);return n.createElement(f.x6,null,"Entropy: ",{currentEntropy:e}," / ",{targettedEntropy:t}," bits")}get passwordStrengthLabel(){if(!this.hasEntropy()&&!this.hasError())return n.createElement(f.x6,null,"Quality");const e=Vi.strength(this.props.entropy);return n.createElement(n.Fragment,null,e.label)}getProgresseBarStyle(e){return{width:`${lr.getRelativeEntropyPosition(e)}%`}}hasEntropy(){return null!==this.props.entropy&&void 0!==this.props.entropy}hasError(){return this.props.error}render(){return n.createElement("div",{className:"password-complexity with-goal"},n.createElement("span",{className:"complexity-text"},n.createElement(Mt,{message:this.currentEntropyTooltipMessage},this.passwordStrengthLabel," ",n.createElement(jt,null))),n.createElement("span",{className:"progress"},n.createElement("span",{className:"progress-bar background"}),n.createElement("span",{className:`progress-bar target ${this.colorClassName}`,style:this.hasEntropy()?this.getProgresseBarStyle(this.props.targetEntropy):null}),n.createElement("span",{className:`progress-bar foreground ${this.colorClassName}`,style:this.hasEntropy()?this.getProgresseBarStyle(this.props.entropy):null}),n.createElement("span",{className:`target-entropy ${this.colorClassName}`,style:this.targetEntropyPositionStyle},n.createElement(Mt,{message:this.targetTooltipMessage},n.createElement("span",{className:"tooltip-anchor"})))))}}lr.defaultProps={isMinimumEntropyRequired:!0},lr.propTypes={targetEntropy:i().number.isRequired,isMinimumEntropyRequired:i().bool.isRequired,entropy:i().number,error:i().bool,t:i().func};const cr=(0,f.CI)("common")(lr);class mr extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.bindCallbacks(),this.createInputRef()}get defaultState(){return{name:"",nameError:"",email:"",emailError:"",algorithm:"RSA",keySize:4096,passphrase:"",passphraseConfirmation:"",passphraseWarning:"",passphraseEntropy:null,hasAlreadyBeenValidated:!1,isPwnedServiceAvailable:!0,passphraseInDictionnary:!1}}async componentDidMount(){const e=await this.props.passwordPoliciesContext.loadPolicies();this.initPwnedPasswordService(e)}bindCallbacks(){this.handleFormSubmit=this.handleFormSubmit.bind(this),this.handleInputChange=this.handleInputChange.bind(this),this.handleNameInputKeyUp=this.handleNameInputKeyUp.bind(this),this.handleEmailInputKeyUp=this.handleEmailInputKeyUp.bind(this),this.handlePassphraseChange=this.handlePassphraseChange.bind(this)}createInputRef(){this.nameInputRef=n.createRef(),this.emailInputRef=n.createRef(),this.passphraseInputRef=n.createRef(),this.passphraseConfirmationInputRef=n.createRef()}initPwnedPasswordService(e){const t=e?.external_dictionary_check;t&&(this.pownedService=new Zi(this.props.context.port)),this.setState({isPwnedServiceAvailable:t})}handleNameInputKeyUp(){this.state.hasAlreadyBeenValidated&&this.validateNameInput()}validateNameInput(){let e=null;return this.state.name.trim().length||(e=this.translate("A name is required.")),this.setState({nameError:e}),null===e}handleEmailInputKeyUp(){this.state.hasAlreadyBeenValidated&&this.validateEmailInput()}validateEmailInput(){let e=null;const t=this.state.email.trim();return t.length?nr.validate(t,this.props.context.siteSettings)||(e=this.translate("Please enter a valid email address.")):e=this.translate("An email is required."),this.setState({email:t,emailError:e}),null===e}async handlePassphraseChange(e){const t=e.target.value;this.setState({passphrase:t},()=>this.checkPassphraseValidity())}async checkPassphraseValidity(){let e=null;if(this.state.passphrase.length>0?e=(e=>{const{numberWords:t,separator:a,isPassphrase:n}=Bi(e);return n?Vi.entropyPassphrase(t,a):Vi.entropyPassword(e)})(this.state.passphrase):this.setState({passphraseInDictionnary:!1,passwordEntropy:null}),this.state.hasAlreadyBeenValidated)this.setState({passphraseInDictionnary:!1}),this.validatePassphraseInput();else{const e=this.state.passphrase.length>=4096,t=this.translate("this is the maximum size for this field, make sure your data was not truncated"),a=e?t:"";this.setState({passphraseWarning:a})}this.setState({passphraseEntropy:e})}validatePassphraseInput(){return!this.hasAnyErrors()}validatePassphraseConfirmationInput(){return!this.isEmptyPasswordConfirmation()&&!this.isPassphraseAndConfirmationDifferent()}hasWeakPassword(){return!this.isMinimumRequiredEntropyReached(this.state.passphraseEntropy)}isEmptyPasswordConfirmation(){return!this.state.passphraseConfirmation.length}isEmptyPassword(){return!this.state.passphrase.length}isPassphraseAndConfirmationDifferent(){return!this.isEmptyPasswordConfirmation()&&this.state.passphrase!==this.state.passphraseConfirmation}async evaluatePassphraseIsInDictionary(e){let t=this.state.isPwnedServiceAvailable;if(!t||!this.pownedService)return!1;let a=!1;try{const n=await this.pownedService.evaluateSecret(e);a=this.state.passphrase&&n.inDictionary&&this.isMinimumRequiredEntropyReached(this.state.passphraseEntropy),t=n.isPwnedServiceAvailable}catch(e){if(!(e instanceof Hi||e instanceof Yi))throw e;t=!1,a=!1}return this.setState({isPwnedServiceAvailable:t,passphraseInDictionnary:a}),a}handleInputChange(e){const t=e.target;this.setState({[t.name]:t.value})}handleValidateError(){this.focusFirstFieldError()}focusFirstFieldError(){this.state.nameError?this.nameInputRef.current.focus():this.state.emailError?this.emailInputRef.current.focus():this.hasAnyErrors()?this.passphraseInputRef.current.focus():this.validatePassphraseConfirmationInput()||this.passphraseConfirmationInputRef.current.focus()}async handleFormSubmit(e){e.preventDefault(),this.state.processing||(this.setState({hasAlreadyBeenValidated:!0}),await this.save())}hasAnyErrors(){const e=[this.isEmptyPassword(),this.state.passphraseInDictionnary];return e.push(this.hasWeakPassword()),e.push(!this.pownedService&&this.state.passphrase.length<8),e.includes(!0)}async save(){if(this.state.processing)return;if(this.setState({processing:!0}),!await this.validate())return this.handleValidateError(),void this.setState({processing:!1});if(await this.evaluatePassphraseIsInDictionary(this.state.passphrase))return void this.setState({processing:!1});const e=await this.generateKey();this.props.onUpdateOrganizationKey(e?.public_key?.armored_key,e?.private_key?.armored_key)}async validate(){const e=this.validateNameInput(),t=this.validateEmailInput(),a=this.validatePassphraseInput(),n=this.validatePassphraseConfirmationInput();return e&&t&&a&&n}async generateKey(){const e={name:this.state.name,email:this.state.email,algorithm:this.state.algorithm,keySize:this.state.keySize,passphrase:this.state.passphrase};return await this.props.context.port.request("passbolt.account-recovery.generate-organization-key",e)}hasAllInputDisabled(){return this.state.processing}isMinimumRequiredEntropyReached(e){return e>=80}get translate(){return this.props.t}get isPassphraseWarning(){return this.state.passphrase?.length>0&&!this.state.hasAlreadyBeenValidated&&(!this.state.isPwnedServiceAvailable||this.state.passphraseInDictionnary)}render(){const e=this.state.passphraseInDictionnary?0:this.state.passphraseEntropy;return n.createElement("form",{onSubmit:this.handleFormSubmit,noValidate:!0},n.createElement("div",{className:"form-content generate-organization-key"},n.createElement("div",{className:"input text required "+(this.state.nameError?"error":"")},n.createElement("label",{htmlFor:"generate-organization-key-form-name"},n.createElement(f.x6,null,"Name")),n.createElement("input",{id:"generate-organization-key-form-name",name:"name",type:"text",value:this.state.name,onKeyUp:this.handleNameInputKeyUp,onChange:this.handleInputChange,disabled:this.hasAllInputDisabled(),ref:this.nameInputRef,className:"required fluid",maxLength:"64",required:"required",autoComplete:"off",autoFocus:!0,placeholder:this.translate("Name")}),this.state.nameError&&n.createElement("div",{className:"name error-message"},this.state.nameError)),n.createElement("div",{className:"input text required "+(this.state.emailError?"error":"")},n.createElement("label",{htmlFor:"generate-organization-key-form-email"},n.createElement(f.x6,null,"Email")),n.createElement("input",{id:"generate-organization-key-form-email",name:"email",ref:this.emailInputRef,className:"required fluid",maxLength:"64",type:"email",autoComplete:"off",value:this.state.email,onChange:this.handleInputChange,placeholder:this.translate("Email Address"),onKeyUp:this.handleEmailInputKeyUp,disabled:this.hasAllInputDisabled(),required:"required"}),this.state.emailError&&n.createElement("div",{className:"email error-message"},this.state.emailError)),n.createElement("div",{className:"input select-wrapper"},n.createElement("label",{htmlFor:"generate-organization-key-form-algorithm"},n.createElement(f.x6,null,"Algorithm"),n.createElement(Mt,{message:this.translate("Algorithm and key size cannot be changed at the moment. These are secure default")},n.createElement(jt,null))),n.createElement("input",{id:"generate-organization-key-form-algorithm",name:"algorithm",value:this.state.algorithm,className:"fluid",type:"text",autoComplete:"off",disabled:!0})),n.createElement("div",{className:"input select-wrapper"},n.createElement("label",{htmlFor:"generate-organization-key-form-keySize"},n.createElement(f.x6,null,"Key Size"),n.createElement(Mt,{message:this.translate("Algorithm and key size cannot be changed at the moment. These are secure default")},n.createElement(jt,null))),n.createElement("input",{id:"generate-organization-key-form-key-size",name:"keySize",value:this.state.keySize,className:"fluid",type:"text",autoComplete:"off",disabled:!0})),n.createElement("div",{className:"input-password-wrapper input required "+(this.hasAnyErrors()&&this.state.hasAlreadyBeenValidated?"error":"")},n.createElement("label",{htmlFor:"generate-organization-key-form-password"},n.createElement(f.x6,null,"Organization key passphrase"),this.isPassphraseWarning&&n.createElement(tt,{className:"attention-required"})),n.createElement(Za,{id:"generate-organization-key-form-password",name:"password",placeholder:this.translate("Passphrase"),autoComplete:"new-password",preview:!0,securityToken:this.props.context.userSettings.getSecurityToken(),value:this.state.passphrase,onChange:this.handlePassphraseChange,disabled:this.hasAllInputDisabled(),inputRef:this.passphraseInputRef}),n.createElement(cr,{entropy:e,targetEntropy:80}),this.state.hasAlreadyBeenValidated&&n.createElement("div",{className:"password error-message"},this.isEmptyPassword()&&n.createElement("div",{className:"empty-passphrase error-message"},n.createElement(f.x6,null,"A passphrase is required.")),this.hasWeakPassword()&&e>0&&n.createElement("div",{className:"invalid-passphrase error-message"},n.createElement(f.x6,null,"A strong passphrase is required. The minimum complexity must be 'fair'.")),this.state.passphraseInDictionnary&&0===e&&!this.isEmptyPassword()&&n.createElement("div",{className:"invalid-passphrase error-message"},n.createElement(f.x6,null,"The passphrase should not be part of an exposed data breach.")))),n.createElement("div",{className:"input-password-wrapper input required "+(this.state.hasAlreadyBeenValidated&&!this.validatePassphraseConfirmationInput()?"error":"")},n.createElement("label",{htmlFor:"generate-organization-key-form-password"},n.createElement(f.x6,null,"Organization key passphrase confirmation")),n.createElement(Za,{id:"generate-organization-key-form-password-confirmation",name:"passphraseConfirmation",placeholder:this.translate("Passphrase confirmation"),autoComplete:"new-password",preview:!0,securityToken:this.props.context.userSettings.getSecurityToken(),value:this.state.passphraseConfirmation,onChange:this.handleInputChange,disabled:this.hasAllInputDisabled(),inputRef:this.passphraseConfirmationInputRef}),this.state.hasAlreadyBeenValidated&&n.createElement("div",{className:"password-confirmation error-message"},this.isEmptyPasswordConfirmation()&&n.createElement("div",{className:"empty-passphrase-confirmation error-message"},n.createElement(f.x6,null,"The passphrase confirmation is required.")),this.isPassphraseAndConfirmationDifferent()&&n.createElement("div",{className:"invalid-passphrase-confirmation error-message"},n.createElement(f.x6,null,"The passphrase confirmation should match the passphrase")))),n.createElement("div",{className:"warning message no-margin",id:"generate-organization-key-setting-overridden-banner"},n.createElement("p",null,n.createElement(f.x6,null,"Warning, we encourage you to generate your OpenPGP Organization Recovery Key separately. Make sure you keep a backup in a safe place.")))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement(gn,{disabled:this.hasAllInputDisabled(),onClick:this.props.onClose}),n.createElement(qs,{disabled:this.hasAllInputDisabled(),processing:this.state.processing,value:this.translate("Generate & Apply")})))}}mr.propTypes={context:i().any,onUpdateOrganizationKey:i().func,onClose:i().func,t:i().func,passwordPoliciesContext:i().object};const dr=N(h(or((0,f.CI)("common")(mr))));function ur(){return ur=Object.assign?Object.assign.bind():function(e){for(var t=1;t{await this.props.adminAccountRecoveryContext.downloadPrivateKey(e)}})}hasAllInputDisabled(){return this.state.processing||this.state.loading}hasOrganisationRecoveryKey(){const e=this.state.keyInfoDto;return Boolean(e)}isPolicyEnabled(){return Boolean("disabled"!==this.policy)}resetKeyInfo(){this.setState({keyInfoDto:null})}formatFingerprint(e){if(!e)return null;const t=e.toUpperCase().replace(/.{4}/g,"$& ");return n.createElement(n.Fragment,null,t.substr(0,24),n.createElement("br",null),t.substr(25))}formatUserIds(e){return e?e.map((e,t)=>n.createElement(n.Fragment,{key:t},e.name," <",e.email,">",n.createElement("br",null))):null}get translate(){return this.props.t}render(){const e=this.props.adminAccountRecoveryContext.hasPolicyChanges()||!this.hasOrganisationRecoveryKey()&&this.isPolicyEnabled();return n.createElement("div",{className:"row"},n.createElement("div",{className:"recover-account-settings main-column"},n.createElement("div",{className:"main-content"},n.createElement("h3",{className:"title"},n.createElement(f.x6,null,"Account Recovery")),n.createElement("form",{className:"form"},n.createElement("h4",{className:"no-border"},n.createElement(f.x6,null,"Account Recovery Policy")),n.createElement("p",null,n.createElement(f.x6,null,"In this section you can choose the default behavior of account recovery for all users.")),n.createElement("div",{className:"radiolist-alt"},n.createElement("div",{className:"input radio "+("mandatory"===this.policy?"checked":"")},n.createElement("input",{type:"radio",value:"mandatory",onChange:this.handlePolicyInputChange,name:"accountRecoveryPolicy",checked:"mandatory"===this.policy,id:"accountRecoveryPolicyMandatory",disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"accountRecoveryPolicyMandatory"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Prompt")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"Every user is required to provide a copy of their private key and passphrase during setup."),n.createElement("br",null),n.createElement(f.x6,null,"You should inform your users not to store personal passwords.")))),n.createElement("div",{className:"input radio "+("opt-out"===this.policy?"checked":"")},n.createElement("input",{type:"radio",value:"opt-out",onChange:this.handlePolicyInputChange,name:"accountRecoveryPolicy",checked:"opt-out"===this.policy,id:"accountRecoveryPolicyOptOut",disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"accountRecoveryPolicyOptOut"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Optional, Opt-out")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"Every user will be prompted to provide a copy of their private key and passphrase by default during the setup, but they can opt out.")))),n.createElement("div",{className:"input radio "+("opt-in"===this.policy?"checked":"")},n.createElement("input",{type:"radio",value:"opt-in",onChange:this.handlePolicyInputChange,name:"accountRecoveryPolicy",checked:"opt-in"===this.policy,id:"accountRecoveryPolicyOptIn",disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"accountRecoveryPolicyOptIn"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Optional, Opt-in")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"Every user can decide to provide a copy of their private key and passphrase by default during the setup, but they can opt in.")))),n.createElement("div",{className:"input radio "+("disabled"===this.policy?"checked":"")},n.createElement("input",{type:"radio",value:"disabled",onChange:this.handlePolicyInputChange,name:"accountRecoveryPolicy",checked:"disabled"===this.policy,id:"accountRecoveryPolicyDisable",disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"accountRecoveryPolicyDisable"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Disable (Default)")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"Backup of the private key and passphrase will not be stored. This is the safest option."),n.createElement(f.x6,null,"If users lose their private key and passphrase they will not be able to recover their account."))))),n.createElement("h4",null,n.createElement("span",{className:"input toggle-switch form-element "},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"organisationRecoveryKeyToggle",disabled:this.hasAllInputDisabled(),checked:this.isPolicyEnabled(),id:"recovery-key-toggle-button"}),n.createElement("label",{htmlFor:"recovery-key-toggle-button"},n.createElement(f.x6,null,"Organization Recovery Key")))),this.isPolicyEnabled()&&n.createElement(n.Fragment,null,n.createElement("p",null,n.createElement(f.x6,null,"Your organization recovery key will be used to decrypt and recover the private key and passphrase of the users that are participating in the account recovery program.")," ",n.createElement(f.x6,null,"The organization private recovery key should not be stored in passbolt.")," ",n.createElement(f.x6,null,"You should keep it offline in a safe place.")),n.createElement("div",{className:"recovery-key-details"},n.createElement("table",{className:"table-info recovery-key"},n.createElement("tbody",null,n.createElement("tr",{className:"user-ids"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"User ids")),this.organizationKeyInfo?.user_ids&&n.createElement("td",{className:"value"},this.formatUserIds(this.organizationKeyInfo.user_ids)),!this.organizationKeyInfo?.user_ids&&n.createElement("td",{className:"empty-value"},n.createElement(f.x6,null,"not available")),n.createElement("td",{className:"table-button"},n.createElement("button",{className:"button primary",type:"button",disabled:this.hasAllInputDisabled(),onClick:this.HandleUpdatePublicKeyClick},this.hasOrganisationRecoveryKey()&&n.createElement(f.x6,null,"Rotate Key"),!this.hasOrganisationRecoveryKey()&&n.createElement(f.x6,null,"Add an Organization Recovery Key")))),n.createElement("tr",{className:"fingerprint"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Fingerprint")),this.organizationKeyInfo?.fingerprint&&n.createElement("td",{className:"value"},this.formatFingerprint(this.organizationKeyInfo.fingerprint)),!this.organizationKeyInfo?.fingerprint&&n.createElement("td",{className:"empty-value"},n.createElement(f.x6,null,"not available"))),n.createElement("tr",{className:"algorithm"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Algorithm")),this.organizationKeyInfo?.algorithm&&n.createElement("td",{className:"value"},this.organizationKeyInfo.algorithm),!this.organizationKeyInfo?.algorithm&&n.createElement("td",{className:"empty-value"},n.createElement(f.x6,null,"not available"))),n.createElement("tr",{className:"key-length"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Key length")),this.organizationKeyInfo?.length&&n.createElement("td",{className:"value"},this.organizationKeyInfo.length),!this.organizationKeyInfo?.length&&n.createElement("td",{className:"empty-value"},n.createElement(f.x6,null,"not available"))),n.createElement("tr",{className:"created"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Created")),this.organizationKeyInfo?.created&&n.createElement("td",{className:"value",title:this.organizationKeyInfo.created},Hs(this.organizationKeyInfo.created,this.props.t,this.props.context.locale)),!this.organizationKeyInfo?.created&&n.createElement("td",{className:"empty-value"},n.createElement(f.x6,null,"not available"))),n.createElement("tr",{className:"expires"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Expires")),this.organizationKeyInfo?.expires&&n.createElement("td",{className:"value",title:this.organizationKeyInfo.expires},Hs(this.organizationKeyInfo.expires,this.props.t,this.props.context.locale)),!this.organizationKeyInfo?.expires&&n.createElement("td",{className:"empty-value"},n.createElement(f.x6,null,"not available"))))))))),e&&n.createElement("div",{className:"warning message",id:"email-notification-setting-overridden-banner"},this.props.adminAccountRecoveryContext.hasPolicyChanges()&&n.createElement("div",{id:"email-notification-setting-overridden-banner"},n.createElement("div",null,n.createElement("p",null,n.createElement(f.x6,null,"Don't forget to save your settings to apply your modification.")))),!this.hasOrganisationRecoveryKey()&&this.isPolicyEnabled()&&n.createElement("div",{id:"email-notification-setting-overridden-banner"},n.createElement("div",null,n.createElement("p",null,n.createElement(f.x6,null,"Warning, Don't forget to add an organization recovery key.")))))),n.createElement(Ai,null),Xa(n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"Need some help?")),n.createElement("p",null,n.createElement(f.x6,null,"For more information about account recovery, checkout the dedicated page on the help website.")),n.createElement("a",{className:"button",href:"https://passbolt.com/docs/admin/authentication/account-recovery/",target:"_blank",rel:"noopener noreferrer"},n.createElement(Er,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}vr.propTypes={context:i().object,dialogContext:i().any,administrationWorkspaceContext:i().object,adminAccountRecoveryContext:i().object,t:i().func};const wr=N(h(Ne(fi((0,f.CI)("common")(vr)))));class kr extends n.Component{render(){return n.createElement("div",{className:"row"},n.createElement("div",{className:"recover-account-settings-teasing main-column"},n.createElement("div",{className:"main-content"},n.createElement("h3",{className:"title",id:"recover-account-settings-title"},n.createElement(f.x6,null,"Account Recovery"),n.createElement(Ea,{className:"pro-teasing-icon"})),n.createElement("p",null,n.createElement(f.x6,null,"Recover lost user accounts.")),n.createElement("div",{className:"recover-account-info"},n.createElement("ul",{className:"recover-account-description"},n.createElement("li",null,n.createElement(fs,null),n.createElement(f.x6,null,"In case of passphrase loss.")),n.createElement("li",null,n.createElement(fs,null),n.createElement(f.x6,null,"In case of private key loss.")),n.createElement("li",null,n.createElement(fs,null),n.createElement(f.x6,null,"Configurable with an Organisation Recovery Key."))),n.createElement("div",null,n.createElement("a",{className:"button primary",href:"https://www.passbolt.com/ce-to-pro?utm_campaign=21060976-CE%20to%20Pro&utm_source=product",target:"_blank",rel:"noopener noreferrer"},n.createElement(f.x6,null,"Upgrade to Passbolt Pro")))))),Xa(n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"Need some help?")),n.createElement("p",null,n.createElement(f.x6,null,"For more information about account recovery, checkout the dedicated page on the help website.")),n.createElement("a",{className:"button",href:"https://passbolt.com/docs/admin/authentication/account-recovery/",target:"_blank",rel:"noopener noreferrer"},n.createElement(Er,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}kr.propTypes={context:i().object,t:i().func};const _r=N((0,f.CI)("common")(kr)),xr={25:{port:25,tls:!1},2525:{port:2525,tls:!1},587:{port:587,tls:!0},588:{port:588,tls:!0},465:{port:465,tls:!0}};function Sr(e,t){const a=[];for(let n=0;n(!a||e.host===a)&&e.port===t)}const Nr={id:"aws-ses",name:"AWS SES",icon:"aws-ses.svg",help_page:"https://docs.aws.amazon.com/ses/latest/dg/send-email-smtp.html",availableConfigurations:Sr(function(){const e=[];return["us-east-2","us-east-1","us-west-1","us-west-2","ap-south-1","ap-northeast-3","ap-northeast-2","ap-northeast-1","ap-southeast-1","ap-southeast-2","ca-central-1","eu-central-1","eu-west-1","eu-west-2","eu-west-3","sa-east-1","us-gov-west-1"].forEach(t=>{e.push(`email-smtp.${t}.amazonaws.com`)}),e}(),[25,2525,587])};Nr.defaultConfiguration=Cr(Nr,587,"email-smtp.eu-central-1.amazonaws.com");const Tr={id:"elastic-email",name:"ElasticEmail",icon:"elastic-email.svg",help_page:"https://help.elasticemail.com/en/articles/4803409-smtp-settings",availableConfigurations:Sr(["smtp.elasticemail.com","smtp25.elasticemail.com"],[25,2525,587])};Tr.defaultConfiguration=Cr(Tr,587,"smtp.elasticemail.com");const Ar={id:"google-workspace",name:"Google Workspace",icon:"gmail.svg",help_page:"https://support.google.com/a/answer/2956491",availableConfigurations:Sr(["smtp-relay.gmail.com"],[25,587])};Ar.defaultConfiguration=Cr(Ar,587);const Ir={id:"google-mail",name:"Google Mail",icon:"gmail.svg",help_page:"https://support.google.com/a/answer/2956491",availableConfigurations:Sr(["smtp.gmail.com"],[587])};Ir.defaultConfiguration=Cr(Ir,587);const Rr={id:"mailgun",name:"MailGun",icon:"mailgun.svg",help_page:"https://documentation.mailgun.com/en/latest/quickstart-sending.html",availableConfigurations:Sr(["smtp.mailgun.com"],[587])};Rr.defaultConfiguration=Rr.availableConfigurations[0];const Pr={id:"mailjet",name:"Mailjet",icon:"mailjet.svg",help_page:"https://dev.mailjet.com/smtp-relay/configuration/",availableConfigurations:Sr(["in-v3.mailjet.com"],[25,2525,587,588])};Pr.defaultConfiguration=Cr(Pr,587);const Dr={id:"mandrill",name:"Mandrill",icon:"mandrill.svg",help_page:"https://mailchimp.com/developer/transactional/docs/smtp-integration/",availableConfigurations:Sr(["smtp.mandrillapp.com"],[25,2525,587])};Dr.defaultConfiguration=Cr(Dr,587);const Or={id:"office-365",name:"Office 365",icon:"office365.svg",help_page:"https://learn.microsoft.com/exchange/mail-flow-best-practices/how-to-set-up-a-multifunction-device-or-application-to-send-email-using-microsoft-365-or-office-365",availableConfigurations:Sr(["smtp.office365.com"],[25,587])};Or.defaultConfiguration=Cr(Or,587);const Mr={id:"outlook",name:"Outlook",icon:"outlook.svg",help_page:"https://support.microsoft.com/office/pop-imap-and-smtp-settings-for-outlook-com-d088b986-291d-42b8-9564-9c414e2aa040",availableConfigurations:Sr(["smtp-mail.outlook.com"],[587])};Mr.defaultConfiguration=Cr(Mr,587);const Ur={id:"sendgrid",name:"Sendgrid",icon:"sendgrid.svg",help_page:"https://docs.sendgrid.com/for-developers/sending-email/integrating-with-the-smtp-api",availableConfigurations:Sr(["smtp.sendgrid.net"],[25,2525,587])};Ur.defaultConfiguration=Cr(Ur,587);const Fr={id:"sendinblue",name:"Sendinblue",icon:"sendinblue.svg",help_page:"https://help.sendinblue.com/hc/en-us/articles/209462765",availableConfigurations:Sr(["smtp-relay.sendinblue.com"],[25,587])};Fr.defaultConfiguration=Cr(Fr,587);const jr={id:"zoho",name:"Zoho",icon:"zoho.svg",help_page:"https://www.zoho.com/mail/help/zoho-smtp.html",availableConfigurations:Sr(["smtp.zoho.eu","smtppro.zoho.eu"],[587])};jr.defaultConfiguration=Cr(jr,587,"smtp.zoho.eu");const Lr=[Nr,Tr,Ir,Ar,Rr,Pr,Dr,Or,Mr,Ur,Fr,jr,{id:"other",name:"Other",icon:null,availableConfigurations:[],defaultConfiguration:{host:"",port:"",tls:!0}}];class qr extends sa{constructor(e){super(e,qr.RESOURCE_NAME)}static get RESOURCE_NAME(){return"smtp/settings"}async find(){const e=await this.apiClient.findAll();return e.body.tls=Boolean(e.body.tls),new oa(e)}async create(e){this.assertNonEmptyData(e);const t=await this.apiClient.create(e);return t.body.tls=Boolean(t.body.tls),new oa(t)}}const zr=qr,Kr=class extends he{static getSchema(){return{type:"object",required:[...$r.getSchema().required],properties:{...$r.getSchema().properties}}}marshall(){"string"==typeof this._props.port&&(this._props.port=parseInt(this._props.port,10)),super.marshall()}static getDefaultData(){return{}}toDto(){return{...super.toDto(),username:null,password:null}}static get ENTITY_NAME(){return"SmtpNoneAuthentication"}},Vr=class extends he{static getSchema(){return{type:"object",required:[...$r.getSchema().required,"username"],properties:{...$r.getSchema().properties,username:{type:"string",maxLength:256}}}}marshall(){"string"==typeof this._props.port&&(this._props.port=parseInt(this._props.port,10)),super.marshall()}static getDefaultData(){return{username:"",password:null,tenant_id:null,client_id:null,client_secret:null}}toDto(){return{...super.toDto(),password:null}}static get ENTITY_NAME(){return"SmtpUsernameAuthentication"}},Gr=class extends he{static getSchema(){return{type:"object",required:[...$r.getSchema().required,"username","password"],properties:{...$r.getSchema().properties,username:{type:"string",maxLength:256},password:{type:"string",maxLength:4096}}}}marshall(){"string"==typeof this._props.port&&(this._props.port=parseInt(this._props.port,10)),super.marshall()}static getDefaultData(){return{username:"",password:"",tenant_id:null,client_id:null,client_secret:null}}static get ENTITY_NAME(){return"SmtpUsernamePasswordAuthentication"}},Br=class extends he{static getSchema(){return{type:"object",required:[...$r.getSchema().required,"oauth_username","tenant_id","client_id","client_secret"],properties:{...$r.getSchema().properties,oauth_username:{type:"string",format:"email",maxLength:256},tenant_id:{type:"string",format:"uuid"},client_id:{type:"string",format:"uuid"},client_secret:{type:"string",minLength:1,maxLength:256},username:{type:"string",nullable:!0},password:{type:"string",nullable:!0}}}}marshall(){"string"==typeof this._props.port&&(this._props.port=parseInt(this._props.port,10)),super.marshall()}static getDefaultData(){return{oauth_username:"",password:null,tenant_id:"",client_id:"",client_secret:""}}static get ENTITY_NAME(){return"SmtpOAuthCredentialsGrantSettings"}},Wr="default",Hr="file",$r=class extends he{static getSchema(){return{type:"object",required:["host","port","sender_name","sender_email"],properties:{id:{type:"string",format:"uuid",nullable:!0},created:{type:"string",format:"date-time",nullable:!0},modified:{type:"string",format:"date-time",nullable:!0},source:{type:"string",enum:[Wr,"env","db",Hr]},host:{type:"string",minLength:1,maxLength:256},port:{type:"integer",minimum:1,maximum:65535},tls:{type:"boolean",nullable:!0},client:{type:"string",nullable:!0,maxLength:2048},sender_name:{type:"string",minLength:1,maxLength:256},sender_email:{type:"string",format:"email",maxLength:256}}}}marshall(){"string"==typeof this._props.port&&(this._props.port=parseInt(this._props.port,10)),super.marshall()}static createFromSettings(e,t={}){return"client_id"in e&&null!==e.client_id?new Br(e,t):"username"in e&&null!==e.username?"password"in e&&null!==e.password?new Gr(e,t):new Vr(e,t):new Kr(e,t)}static get ENTITY_NAME(){return"SmtpSettings"}static get SETTINGS_SOURCE_DEFAULT(){return Wr}static get SETTINGS_SOURCE_ENV(){return"env"}static get SETTINGS_SOURCE_DB(){return"db"}static get SETTINGS_SOURCE_FILE(){return Hr}},Yr=class{constructor(e){this.smtpSettingsApiService=new zr(e)}async find(){const e=await this.smtpSettingsApiService.find();return $r.createFromSettings(e.body)}},Zr=class{constructor(e){this.smtpSettingsApiService=new zr(e)}async save(e){const t=await this.smtpSettingsApiService.create(e.toDto());return $r.createFromSettings(t.body)}},Jr=["0-mail.com","007addict.com","020.co.uk","027168.com","0815.ru","0815.su","0clickemail.com","0sg.net","0wnd.net","0wnd.org","1033edge.com","10mail.org","10minutemail.co.za","10minutemail.com","11mail.com","123-m.com","123.com","123box.net","123india.com","123mail.cl","123mail.org","123qwe.co.uk","126.com","126.net","138mail.com","139.com","150mail.com","150ml.com","15meg4free.com","163.com","16mail.com","188.com","189.cn","1auto.com","1ce.us","1chuan.com","1colony.com","1coolplace.com","1email.eu","1freeemail.com","1fsdfdsfsdf.tk","1funplace.com","1internetdrive.com","1mail.ml","1mail.net","1me.net","1mum.com","1musicrow.com","1netdrive.com","1nsyncfan.com","1pad.de","1under.com","1webave.com","1webhighway.com","1zhuan.com","2-mail.com","20email.eu","20mail.in","20mail.it","20minutemail.com","212.com","21cn.com","247emails.com","24horas.com","2911.net","2980.com","2bmail.co.uk","2coolforyou.net","2d2i.com","2die4.com","2fdgdfgdfgdf.tk","2hotforyou.net","2mydns.com","2net.us","2prong.com","2trom.com","3000.it","30minutemail.com","30minutesmail.com","3126.com","321media.com","33mail.com","360.ru","37.com","3ammagazine.com","3dmail.com","3email.com","3g.ua","3mail.ga","3trtretgfrfe.tk","3xl.net","444.net","4email.com","4email.net","4gfdsgfdgfd.tk","4mg.com","4newyork.com","4warding.com","4warding.net","4warding.org","4x4fan.com","4x4man.com","50mail.com","5fm.za.com","5ghgfhfghfgh.tk","5iron.com","5star.com","60minutemail.com","6hjgjhgkilkj.tk","6ip.us","6mail.cf","6paq.com","702mail.co.za","74.ru","7mail.ga","7mail.ml","7tags.com","88.am","8848.net","888.nu","8mail.ga","8mail.ml","97rock.com","99experts.com","9ox.net","a-bc.net","a-player.org","a2z4u.net","a45.in","aaamail.zzn.com","aahlife.com","aamail.net","aapt.net.au","aaronkwok.net","abbeyroadlondon.co.uk","abcflash.net","abdulnour.com","aberystwyth.com","abolition-now.com","about.com","absolutevitality.com","abusemail.de","abv.bg","abwesend.de","abyssmail.com","ac20mail.in","academycougars.com","acceso.or.cr","access4less.net","accessgcc.com","accountant.com","acdcfan.com","acdczone.com","ace-of-base.com","acmecity.com","acmemail.net","acninc.net","acrobatmail.com","activatormail.com","activist.com","adam.com.au","add3000.pp.ua","addcom.de","address.com","adelphia.net","adexec.com","adfarrow.com","adinet.com.uy","adios.net","admin.in.th","administrativos.com","adoption.com","ados.fr","adrenalinefreak.com","adres.nl","advalvas.be","advantimo.com","aeiou.pt","aemail4u.com","aeneasmail.com","afreeinternet.com","africa-11.com","africamail.com","africamel.net","africanpartnersonline.com","afrobacon.com","ag.us.to","agedmail.com","agelessemail.com","agoodmail.com","ahaa.dk","ahk.jp","aichi.com","aim.com","aircraftmail.com","airforce.net","airforceemail.com","airpost.net","aiutamici.com","ajacied.com","ajaxapp.net","ak47.hu","aknet.kg","akphantom.com","albawaba.com","alecsmail.com","alex4all.com","alexandria.cc","algeria.com","algeriamail.com","alhilal.net","alibaba.com","alice.it","aliceadsl.fr","aliceinchainsmail.com","alivance.com","alive.cz","aliyun.com","allergist.com","allmail.net","alloymail.com","allracing.com","allsaintsfan.com","alltel.net","alpenjodel.de","alphafrau.de","alskens.dk","altavista.com","altavista.net","altavista.se","alternativagratis.com","alumni.com","alumnidirector.com","alvilag.hu","ama-trade.de","amail.com","amazonses.com","amele.com","america.hm","ameritech.net","amilegit.com","amiri.net","amiriindustries.com","amnetsal.com","amorki.pl","amrer.net","amuro.net","amuromail.com","ananzi.co.za","ancestry.com","andreabocellimail.com","andylau.net","anfmail.com","angelfan.com","angelfire.com","angelic.com","animail.net","animal.net","animalhouse.com","animalwoman.net","anjungcafe.com","anniefans.com","annsmail.com","ano-mail.net","anonmails.de","anonymbox.com","anonymous.to","anote.com","another.com","anotherdomaincyka.tk","anotherwin95.com","anti-ignorance.net","anti-social.com","antichef.com","antichef.net","antiqueemail.com","antireg.ru","antisocial.com","antispam.de","antispam24.de","antispammail.de","antongijsen.com","antwerpen.com","anymoment.com","anytimenow.com","aol.co.uk","aol.com","aol.de","aol.fr","aol.it","aol.jp","aon.at","apexmail.com","apmail.com","apollo.lv","aport.ru","aport2000.ru","apple.sib.ru","appraiser.net","approvers.net","aquaticmail.net","arabia.com","arabtop.net","arcademaster.com","archaeologist.com","archerymail.com","arcor.de","arcotronics.bg","arcticmail.com","argentina.com","arhaelogist.com","aristotle.org","army.net","armyspy.com","arnet.com.ar","art-en-ligne.pro","artistemail.com","artlover.com","artlover.com.au","artman-conception.com","as-if.com","asdasd.nl","asean-mail","asean-mail.com","asheville.com","asia-links.com","asia-mail.com","asia.com","asiafind.com","asianavenue.com","asiancityweb.com","asiansonly.net","asianwired.net","asiapoint.net","askaclub.ru","ass.pp.ua","assala.com","assamesemail.com","astroboymail.com","astrolover.com","astrosfan.com","astrosfan.net","asurfer.com","atheist.com","athenachu.net","atina.cl","atl.lv","atlas.cz","atlaswebmail.com","atlink.com","atmc.net","ato.check.com","atozasia.com","atrus.ru","att.net","attglobal.net","attymail.com","au.ru","auctioneer.net","aufeminin.com","aus-city.com","ausi.com","aussiemail.com.au","austin.rr.com","australia.edu","australiamail.com","austrosearch.net","autoescuelanerja.com","autograf.pl","automail.ru","automotiveauthority.com","autorambler.ru","aver.com","avh.hu","avia-tonic.fr","avtoritet.ru","awayonvacation.com","awholelotofamechi.com","awsom.net","axoskate.com","ayna.com","azazazatashkent.tk","azimiweb.com","azmeil.tk","bachelorboy.com","bachelorgal.com","backfliper.com","backpackers.com","backstreet-boys.com","backstreetboysclub.com","backtothefuturefans.com","backwards.com","badtzmail.com","bagherpour.com","bahrainmail.com","bakpaka.com","bakpaka.net","baldmama.de","baldpapa.de","ballerstatus.net","ballyfinance.com","balochistan.org","baluch.com","bangkok.com","bangkok2000.com","bannertown.net","baptistmail.com","baptized.com","barcelona.com","bareed.ws","barid.com","barlick.net","bartender.net","baseball-email.com","baseballmail.com","basketballmail.com","batuta.net","baudoinconsulting.com","baxomale.ht.cx","bboy.com","bboy.zzn.com","bcvibes.com","beddly.com","beeebank.com","beefmilk.com","beenhad.com","beep.ru","beer.com","beerandremotes.com","beethoven.com","beirut.com","belice.com","belizehome.com","belizemail.net","belizeweb.com","bell.net","bellair.net","bellsouth.net","berkscounty.com","berlin.com","berlin.de","berlinexpo.de","bestmail.us","betriebsdirektor.de","bettergolf.net","bharatmail.com","big1.us","big5mail.com","bigassweb.com","bigblue.net.au","bigboab.com","bigfoot.com","bigfoot.de","bigger.com","biggerbadder.com","bigmailbox.com","bigmir.net","bigpond.au","bigpond.com","bigpond.com.au","bigpond.net","bigpond.net.au","bigramp.com","bigstring.com","bikemechanics.com","bikeracer.com","bikeracers.net","bikerider.com","billsfan.com","billsfan.net","bimamail.com","bimla.net","bin-wieder-da.de","binkmail.com","bio-muesli.info","bio-muesli.net","biologyfan.com","birdfanatic.com","birdlover.com","birdowner.net","bisons.com","bitmail.com","bitpage.net","bizhosting.com","bk.ru","bkkmail.com","bla-bla.com","blackburnfans.com","blackburnmail.com","blackplanet.com","blader.com","bladesmail.net","blazemail.com","bleib-bei-mir.de","blink182.net","blockfilter.com","blogmyway.org","blondandeasy.com","bluebottle.com","bluehyppo.com","bluemail.ch","bluemail.dk","bluesfan.com","bluewin.ch","blueyonder.co.uk","blumail.org","blushmail.com","blutig.me","bmlsports.net","boardermail.com","boarderzone.com","boatracers.com","bobmail.info","bodhi.lawlita.com","bofthew.com","bol.com.br","bolando.com","bollywoodz.com","bolt.com","boltonfans.com","bombdiggity.com","bonbon.net","boom.com","bootmail.com","bootybay.de","bornagain.com","bornnaked.com","bossofthemoss.com","bostonoffice.com","boun.cr","bounce.net","bounces.amazon.com","bouncr.com","box.az","box.ua","boxbg.com","boxemail.com","boxformail.in","boxfrog.com","boximail.com","boyzoneclub.com","bradfordfans.com","brasilia.net","bratan.ru","brazilmail.com","brazilmail.com.br","breadtimes.press","breakthru.com","breathe.com","brefmail.com","brennendesreich.de","bresnan.net","brestonline.com","brew-master.com","brew-meister.com","brfree.com.br","briefemail.com","bright.net","britneyclub.com","brittonsign.com","broadcast.net","broadwaybuff.com","broadwaylove.com","brokeandhappy.com","brokenvalve.com","brujula.net","brunetka.ru","brusseler.com","bsdmail.com","bsnow.net","bspamfree.org","bt.com","btcc.org","btcmail.pw","btconnect.co.uk","btconnect.com","btinternet.com","btopenworld.co.uk","buerotiger.de","buffymail.com","bugmenot.com","bulgaria.com","bullsfan.com","bullsgame.com","bumerang.ro","bumpymail.com","bumrap.com","bund.us","bunita.net","bunko.com","burnthespam.info","burntmail.com","burstmail.info","buryfans.com","bushemail.com","business-man.com","businessman.net","businessweekmail.com","bust.com","busta-rhymes.com","busymail.com","busymail.com.com","busymail.comhomeart.com","butch-femme.net","butovo.net","buyersusa.com","buymoreplays.com","buzy.com","bvimailbox.com","byke.com","byom.de","byteme.com","c2.hu","c2i.net","c3.hu","c4.com","c51vsgq.com","cabacabana.com","cable.comcast.com","cableone.net","caere.it","cairomail.com","calcuttaads.com","calendar-server.bounces.google.com","calidifontain.be","californiamail.com","callnetuk.com","callsign.net","caltanet.it","camidge.com","canada-11.com","canada.com","canadianmail.com","canoemail.com","cantv.net","canwetalk.com","caramail.com","card.zp.ua","care2.com","careceo.com","careerbuildermail.com","carioca.net","cartelera.org","cartestraina.ro","casablancaresort.com","casema.nl","cash4u.com","cashette.com","casino.com","casualdx.com","cataloniamail.com","cataz.com","catcha.com","catchamail.com","catemail.com","catholic.org","catlover.com","catsrule.garfield.com","ccnmail.com","cd2.com","cek.pm","celineclub.com","celtic.com","center-mail.de","centermail.at","centermail.com","centermail.de","centermail.info","centermail.net","centoper.it","centralpets.com","centrum.cz","centrum.sk","centurylink.net","centurytel.net","certifiedmail.com","cfl.rr.com","cgac.es","cghost.s-a-d.de","chacuo.net","chaiyo.com","chaiyomail.com","chalkmail.net","chammy.info","chance2mail.com","chandrasekar.net","channelonetv.com","charityemail.com","charmedmail.com","charter.com","charter.net","chat.ru","chatlane.ru","chattown.com","chauhanweb.com","cheatmail.de","chechnya.conf.work","check.com","check.com12","check1check.com","cheeb.com","cheerful.com","chef.net","chefmail.com","chek.com","chello.nl","chemist.com","chequemail.com","cheshiremail.com","cheyenneweb.com","chez.com","chickmail.com","chil-e.com","childrens.md","childsavetrust.org","china.com","china.net.vg","chinalook.com","chinamail.com","chinesecool.com","chirk.com","chocaholic.com.au","chocofan.com","chogmail.com","choicemail1.com","chong-mail.com","chong-mail.net","christianmail.net","chronicspender.com","churchusa.com","cia-agent.com","cia.hu","ciaoweb.it","cicciociccio.com","cincinow.net","cirquefans.com","citeweb.net","citiz.net","citlink.net","city-of-bath.org","city-of-birmingham.com","city-of-brighton.org","city-of-cambridge.com","city-of-coventry.com","city-of-edinburgh.com","city-of-lichfield.com","city-of-lincoln.com","city-of-liverpool.com","city-of-manchester.com","city-of-nottingham.com","city-of-oxford.com","city-of-swansea.com","city-of-westminster.com","city-of-westminster.net","city-of-york.net","city2city.com","citynetusa.com","cityofcardiff.net","cityoflondon.org","ciudad.com.ar","ckaazaza.tk","claramail.com","classicalfan.com","classicmail.co.za","clear.net.nz","clearwire.net","clerk.com","clickforadate.com","cliffhanger.com","clixser.com","close2you.ne","close2you.net","clrmail.com","club-internet.fr","club4x4.net","clubalfa.com","clubbers.net","clubducati.com","clubhonda.net","clubmember.org","clubnetnoir.com","clubvdo.net","cluemail.com","cmail.net","cmail.org","cmail.ru","cmpmail.com","cmpnetmail.com","cnegal.com","cnnsimail.com","cntv.cn","codec.ro","codec.ro.ro","codec.roemail.ro","coder.hu","coid.biz","coldemail.info","coldmail.com","collectiblesuperstore.com","collector.org","collegebeat.com","collegeclub.com","collegemail.com","colleges.com","columbus.rr.com","columbusrr.com","columnist.com","comast.com","comast.net","comcast.com","comcast.net","comic.com","communityconnect.com","complxmind.com","comporium.net","comprendemail.com","compuserve.com","computer-expert.net","computer-freak.com","computer4u.com","computerconfused.com","computermail.net","computernaked.com","conexcol.com","cong.ru","conk.com","connect4free.net","connectbox.com","conok.com","consultant.com","consumerriot.com","contractor.net","contrasto.cu.cc","cookiemonster.com","cool.br","cool.fr.nf","coole-files.de","coolgoose.ca","coolgoose.com","coolkiwi.com","coollist.com","coolmail.com","coolmail.net","coolrio.com","coolsend.com","coolsite.net","cooooool.com","cooperation.net","cooperationtogo.net","copacabana.com","copper.net","copticmail.com","cornells.com","cornerpub.com","corporatedirtbag.com","correo.terra.com.gt","corrsfan.com","cortinet.com","cosmo.com","cotas.net","counsellor.com","countrylover.com","courriel.fr.nf","courrieltemporaire.com","cox.com","cox.net","coxinet.net","cpaonline.net","cracker.hu","craftemail.com","crapmail.org","crazedanddazed.com","crazy.ru","crazymailing.com","crazysexycool.com","crewstart.com","cristianemail.com","critterpost.com","croeso.com","crosshairs.com","crosswinds.net","crunkmail.com","crwmail.com","cry4helponline.com","cryingmail.com","cs.com","csinibaba.hu","cubiclink.com","cuemail.com","cumbriamail.com","curio-city.com","curryworld.de","curtsmail.com","cust.in","cute-girl.com","cuteandcuddly.com","cutekittens.com","cutey.com","cuvox.de","cww.de","cyber-africa.net","cyber-innovation.club","cyber-matrix.com","cyber-phone.eu","cyber-wizard.com","cyber4all.com","cyberbabies.com","cybercafemaui.com","cybercity-online.net","cyberdude.com","cyberforeplay.net","cybergal.com","cybergrrl.com","cyberinbox.com","cyberleports.com","cybermail.net","cybernet.it","cyberservices.com","cyberspace-asia.com","cybertrains.org","cyclefanz.com","cymail.net","cynetcity.com","d3p.dk","dabsol.net","dacoolest.com","dadacasa.com","daha.com","dailypioneer.com","dallas.theboys.com","dallasmail.com","dandikmail.com","dangerous-minds.com","dansegulvet.com","dasdasdascyka.tk","data54.com","date.by","daum.net","davegracey.com","dawnsonmail.com","dawsonmail.com","dayrep.com","dazedandconfused.com","dbzmail.com","dcemail.com","dcsi.net","ddns.org","deadaddress.com","deadlymob.org","deadspam.com","deafemail.net","deagot.com","deal-maker.com","dearriba.com","death-star.com","deepseafisherman.net","deforestationsucks.com","degoo.com","dejanews.com","delikkt.de","deliveryman.com","deneg.net","depechemode.com","deseretmail.com","desertmail.com","desertonline.com","desertsaintsmail.com","desilota.com","deskmail.com","deskpilot.com","despam.it","despammed.com","destin.com","detik.com","deutschland-net.com","devnullmail.com","devotedcouples.com","dezigner.ru","dfgh.net","dfwatson.com","dglnet.com.br","dgoh.org","di-ve.com","diamondemail.com","didamail.com","die-besten-bilder.de","die-genossen.de","die-optimisten.de","die-optimisten.net","die.life","diehardmail.com","diemailbox.de","digibel.be","digital-filestore.de","digitalforeplay.net","digitalsanctuary.com","digosnet.com","dingbone.com","diplomats.com","directbox.com","director-general.com","diri.com","dirtracer.com","dirtracers.com","discard.email","discard.ga","discard.gq","discardmail.com","discardmail.de","disciples.com","discofan.com","discovery.com","discoverymail.com","discoverymail.net","disign-concept.eu","disign-revelation.com","disinfo.net","dispomail.eu","disposable.com","disposableaddress.com","disposableemailaddresses.com","disposableinbox.com","dispose.it","dispostable.com","divismail.ru","divorcedandhappy.com","dm.w3internet.co.uk","dmailman.com","dmitrovka.net","dmitry.ru","dnainternet.net","dnsmadeeasy.com","doar.net","doclist.bounces.google.com","docmail.cz","docs.google.com","doctor.com","dodgeit.com","dodgit.com","dodgit.org","dodo.com.au","dodsi.com","dog.com","dogit.com","doglover.com","dogmail.co.uk","dogsnob.net","doityourself.com","domforfb1.tk","domforfb2.tk","domforfb3.tk","domforfb4.tk","domforfb5.tk","domforfb6.tk","domforfb7.tk","domforfb8.tk","domozmail.com","doneasy.com","donegal.net","donemail.ru","donjuan.com","dontgotmail.com","dontmesswithtexas.com","dontreg.com","dontsendmespam.de","doramail.com","dostmail.com","dotcom.fr","dotmsg.com","dotnow.com","dott.it","download-privat.de","dplanet.ch","dr.com","dragoncon.net","dragracer.com","drdrb.net","drivehq.com","dropmail.me","dropzone.com","drotposta.hu","dubaimail.com","dublin.com","dublin.ie","dump-email.info","dumpandjunk.com","dumpmail.com","dumpmail.de","dumpyemail.com","dunlopdriver.com","dunloprider.com","duno.com","duskmail.com","dustdevil.com","dutchmail.com","dvd-fan.net","dwp.net","dygo.com","dynamitemail.com","dyndns.org","e-apollo.lv","e-hkma.com","e-mail.com","e-mail.com.tr","e-mail.dk","e-mail.org","e-mail.ru","e-mail.ua","e-mailanywhere.com","e-mails.ru","e-tapaal.com","e-webtec.com","e4ward.com","earthalliance.com","earthcam.net","earthdome.com","earthling.net","earthlink.net","earthonline.net","eastcoast.co.za","eastlink.ca","eastmail.com","eastrolog.com","easy.com","easy.to","easypeasy.com","easypost.com","easytrashmail.com","eatmydirt.com","ebprofits.net","ec.rr.com","ecardmail.com","ecbsolutions.net","echina.com","ecolo-online.fr","ecompare.com","edmail.com","ednatx.com","edtnmail.com","educacao.te.pt","educastmail.com","eelmail.com","ehmail.com","einmalmail.de","einrot.com","einrot.de","eintagsmail.de","eircom.net","ekidz.com.au","elisanet.fi","elitemail.org","elsitio.com","eltimon.com","elvis.com","elvisfan.com","email-fake.gq","email-london.co.uk","email-value.com","email.biz","email.cbes.net","email.com","email.cz","email.ee","email.it","email.nu","email.org","email.ro","email.ru","email.si","email.su","email.ua","email.women.com","email2me.com","email2me.net","email4u.info","email60.com","emailacc.com","emailaccount.com","emailaddresses.com","emailage.ga","emailage.gq","emailasso.net","emailchoice.com","emailcorner.net","emailem.com","emailengine.net","emailengine.org","emailer.hubspot.com","emailforyou.net","emailgaul.com","emailgo.de","emailgroups.net","emailias.com","emailinfive.com","emailit.com","emaillime.com","emailmiser.com","emailoregon.com","emailpinoy.com","emailplanet.com","emailplus.org","emailproxsy.com","emails.ga","emails.incisivemedia.com","emails.ru","emailsensei.com","emailservice.com","emailsydney.com","emailtemporanea.com","emailtemporanea.net","emailtemporar.ro","emailtemporario.com.br","emailthe.net","emailtmp.com","emailto.de","emailuser.net","emailwarden.com","emailx.at.hm","emailx.net","emailxfer.com","emailz.ga","emailz.gq","emale.ru","ematic.com","embarqmail.com","emeil.in","emeil.ir","emil.com","eml.cc","eml.pp.ua","empereur.com","emptymail.com","emumail.com","emz.net","end-war.com","enel.net","enelpunto.net","engineer.com","england.com","england.edu","englandmail.com","epage.ru","epatra.com","ephemail.net","epiqmail.com","epix.net","epomail.com","epost.de","eposta.hu","eprompter.com","eqqu.com","eramail.co.za","eresmas.com","eriga.lv","ero-tube.org","eshche.net","esmailweb.net","estranet.it","ethos.st","etoast.com","etrademail.com","etranquil.com","etranquil.net","eudoramail.com","europamel.net","europe.com","europemail.com","euroseek.com","eurosport.com","evafan.com","evertonfans.com","every1.net","everyday.com.kh","everymail.net","everyone.net","everytg.ml","evopo.com","examnotes.net","excite.co.jp","excite.co.uk","excite.com","excite.it","execs.com","execs2k.com","executivemail.co.za","exemail.com.au","exg6.exghost.com","explodemail.com","express.net.ua","expressasia.com","extenda.net","extended.com","extremail.ru","eyepaste.com","eyou.com","ezagenda.com","ezcybersearch.com","ezmail.egine.com","ezmail.ru","ezrs.com","f-m.fm","f1fans.net","facebook-email.ga","facebook.com","facebookmail.com","facebookmail.gq","fadrasha.net","fadrasha.org","fahr-zur-hoelle.org","fake-email.pp.ua","fake-mail.cf","fake-mail.ga","fake-mail.ml","fakeinbox.com","fakeinformation.com","fakemailz.com","falseaddress.com","fan.com","fan.theboys.com","fannclub.com","fansonlymail.com","fansworldwide.de","fantasticmail.com","fantasymail.de","farang.net","farifluset.mailexpire.com","faroweb.com","fast-email.com","fast-mail.fr","fast-mail.org","fastacura.com","fastchevy.com","fastchrysler.com","fastem.com","fastemail.us","fastemailer.com","fastemailextractor.net","fastermail.com","fastest.cc","fastimap.com","fastkawasaki.com","fastmail.ca","fastmail.cn","fastmail.co.uk","fastmail.com","fastmail.com.au","fastmail.es","fastmail.fm","fastmail.gr","fastmail.im","fastmail.in","fastmail.jp","fastmail.mx","fastmail.net","fastmail.nl","fastmail.se","fastmail.to","fastmail.tw","fastmail.us","fastmailbox.net","fastmazda.com","fastmessaging.com","fastmitsubishi.com","fastnissan.com","fastservice.com","fastsubaru.com","fastsuzuki.com","fasttoyota.com","fastyamaha.com","fatcock.net","fatflap.com","fathersrightsne.org","fatyachts.com","fax.ru","fbi-agent.com","fbi.hu","fdfdsfds.com","fea.st","federalcontractors.com","feinripptraeger.de","felicity.com","felicitymail.com","female.ru","femenino.com","fepg.net","fetchmail.co.uk","fetchmail.com","fettabernett.de","feyenoorder.com","ffanet.com","fiberia.com","fibertel.com.ar","ficken.de","fificorp.com","fificorp.net","fightallspam.com","filipinolinks.com","filzmail.com","financefan.net","financemail.net","financier.com","findfo.com","findhere.com","findmail.com","findmemail.com","finebody.com","fineemail.com","finfin.com","finklfan.com","fire-brigade.com","fireman.net","fishburne.org","fishfuse.com","fivemail.de","fixmail.tk","fizmail.com","flashbox.5july.org","flashemail.com","flashmail.com","flashmail.net","fleckens.hu","flipcode.com","floridaemail.net","flytecrew.com","fmail.co.uk","fmailbox.com","fmgirl.com","fmguy.com","fnbmail.co.za","fnmail.com","folkfan.com","foodmail.com","footard.com","football.theboys.com","footballmail.com","foothills.net","for-president.com","force9.co.uk","forfree.at","forgetmail.com","fornow.eu","forpresident.com","fortuncity.com","fortunecity.com","forum.dk","fossefans.com","foxmail.com","fr33mail.info","francefans.com","francemel.fr","frapmail.com","free-email.ga","free-online.net","free-org.com","free.com.pe","free.fr","freeaccess.nl","freeaccount.com","freeandsingle.com","freebox.com","freedom.usa.com","freedomlover.com","freefanmail.com","freegates.be","freeghana.com","freelance-france.eu","freeler.nl","freemail.bozz.com","freemail.c3.hu","freemail.com.au","freemail.com.pk","freemail.de","freemail.et","freemail.gr","freemail.hu","freemail.it","freemail.lt","freemail.ms","freemail.nl","freemail.org.mk","freemail.ru","freemails.ga","freemeil.gq","freenet.de","freenet.kg","freeola.com","freeola.net","freeproblem.com","freesbee.fr","freeserve.co.uk","freeservers.com","freestamp.com","freestart.hu","freesurf.fr","freesurf.nl","freeuk.com","freeuk.net","freeukisp.co.uk","freeweb.org","freewebemail.com","freeyellow.com","freezone.co.uk","fresnomail.com","freudenkinder.de","freundin.ru","friction.net","friendlydevices.com","friendlymail.co.uk","friends-cafe.com","friendsfan.com","from-africa.com","from-america.com","from-argentina.com","from-asia.com","from-australia.com","from-belgium.com","from-brazil.com","from-canada.com","from-china.net","from-england.com","from-europe.com","from-france.net","from-germany.net","from-holland.com","from-israel.com","from-italy.net","from-japan.net","from-korea.com","from-mexico.com","from-outerspace.com","from-russia.com","from-spain.net","fromalabama.com","fromalaska.com","fromarizona.com","fromarkansas.com","fromcalifornia.com","fromcolorado.com","fromconnecticut.com","fromdelaware.com","fromflorida.net","fromgeorgia.com","fromhawaii.net","fromidaho.com","fromillinois.com","fromindiana.com","frominter.net","fromiowa.com","fromjupiter.com","fromkansas.com","fromkentucky.com","fromlouisiana.com","frommaine.net","frommaryland.com","frommassachusetts.com","frommiami.com","frommichigan.com","fromminnesota.com","frommississippi.com","frommissouri.com","frommontana.com","fromnebraska.com","fromnevada.com","fromnewhampshire.com","fromnewjersey.com","fromnewmexico.com","fromnewyork.net","fromnorthcarolina.com","fromnorthdakota.com","fromohio.com","fromoklahoma.com","fromoregon.net","frompennsylvania.com","fromrhodeisland.com","fromru.com","fromru.ru","fromsouthcarolina.com","fromsouthdakota.com","fromtennessee.com","fromtexas.com","fromthestates.com","fromutah.com","fromvermont.com","fromvirginia.com","fromwashington.com","fromwashingtondc.com","fromwestvirginia.com","fromwisconsin.com","fromwyoming.com","front.ru","frontier.com","frontiernet.net","frostbyte.uk.net","fsmail.net","ftc-i.net","ftml.net","fuckingduh.com","fudgerub.com","fullmail.com","funiran.com","funkfan.com","funky4.com","fuorissimo.com","furnitureprovider.com","fuse.net","fusemail.com","fut.es","fux0ringduh.com","fwnb.com","fxsmails.com","fyii.de","galamb.net","galaxy5.com","galaxyhit.com","gamebox.com","gamebox.net","gamegeek.com","games.com","gamespotmail.com","gamil.com","gamil.com.au","gamno.config.work","garbage.com","gardener.com","garliclife.com","gatwickemail.com","gawab.com","gay.com","gaybrighton.co.uk","gaza.net","gazeta.pl","gazibooks.com","gci.net","gdi.net","gee-wiz.com","geecities.com","geek.com","geek.hu","geeklife.com","gehensiemirnichtaufdensack.de","gelitik.in","gencmail.com","general-hospital.com","gentlemansclub.de","genxemail.com","geocities.com","geography.net","geologist.com","geopia.com","germanymail.com","get.pp.ua","get1mail.com","get2mail.fr","getairmail.cf","getairmail.com","getairmail.ga","getairmail.gq","getmails.eu","getonemail.com","getonemail.net","gfxartist.ru","gh2000.com","ghanamail.com","ghostmail.com","ghosttexter.de","giantmail.de","giantsfan.com","giga4u.de","gigileung.org","girl4god.com","girlsundertheinfluence.com","gishpuppy.com","givepeaceachance.com","glay.org","glendale.net","globalfree.it","globalpagan.com","globalsite.com.br","globetrotter.net","globo.com","globomail.com","gmail.co.za","gmail.com","gmail.com.au","gmail.com.br","gmail.ru","gmial.com","gmx.at","gmx.ch","gmx.co.uk","gmx.com","gmx.de","gmx.fr","gmx.li","gmx.net","gmx.us","gnwmail.com","go.com","go.ro","go.ru","go2.com.py","go2net.com","go4.it","gobrainstorm.net","gocollege.com","gocubs.com","godmail.dk","goemailgo.com","gofree.co.uk","gol.com","goldenmail.ru","goldmail.ru","goldtoolbox.com","golfemail.com","golfilla.info","golfmail.be","gonavy.net","gonuts4free.com","goodnewsmail.com","goodstick.com","google.com","googlegroups.com","googlemail.com","goosemoose.com","goplay.com","gorillaswithdirtyarmpits.com","gorontalo.net","gospelfan.com","gothere.uk.com","gotmail.com","gotmail.net","gotmail.org","gotomy.com","gotti.otherinbox.com","govolsfan.com","gportal.hu","grabmail.com","graduate.org","graffiti.net","gramszu.net","grandmamail.com","grandmasmail.com","graphic-designer.com","grapplers.com","gratisweb.com","great-host.in","greenmail.net","greensloth.com","groupmail.com","grr.la","grungecafe.com","gsrv.co.uk","gtemail.net","gtmc.net","gua.net","guerillamail.biz","guerillamail.com","guerrillamail.biz","guerrillamail.com","guerrillamail.de","guerrillamail.info","guerrillamail.net","guerrillamail.org","guerrillamailblock.com","guessmail.com","guju.net","gurlmail.com","gustr.com","guy.com","guy2.com","guyanafriends.com","gwhsgeckos.com","gyorsposta.com","gyorsposta.hu","h-mail.us","hab-verschlafen.de","hablas.com","habmalnefrage.de","hacccc.com","hackermail.com","hackermail.net","hailmail.net","hairdresser.com","hairdresser.net","haltospam.com","hamptonroads.com","handbag.com","handleit.com","hang-ten.com","hangglidemail.com","hanmail.net","happemail.com","happycounsel.com","happypuppy.com","harakirimail.com","haramamba.ru","hardcorefreak.com","hardyoungbabes.com","hartbot.de","hat-geld.de","hatespam.org","hawaii.rr.com","hawaiiantel.net","headbone.com","healthemail.net","heartthrob.com","heavynoize.net","heerschap.com","heesun.net","hehe.com","hello.hu","hello.net.au","hello.to","hellokitty.com","helter-skelter.com","hempseed.com","herediano.com","heremail.com","herono1.com","herp.in","herr-der-mails.de","hetnet.nl","hewgen.ru","hey.to","hhdevel.com","hideakifan.com","hidemail.de","hidzz.com","highmilton.com","highquality.com","highveldmail.co.za","hilarious.com","hinduhome.com","hingis.org","hiphopfan.com","hispavista.com","hitmail.com","hitmanrecords.com","hitthe.net","hkg.net","hkstarphoto.com","hmamail.com","hochsitze.com","hockeymail.com","hollywoodkids.com","home-email.com","home.de","home.nl","home.no.net","home.ro","home.se","homeart.com","homelocator.com","homemail.com","homenetmail.com","homeonthethrone.com","homestead.com","homeworkcentral.com","honduras.com","hongkong.com","hookup.net","hoopsmail.com","hopemail.biz","horrormail.com","host-it.com.sg","hot-mail.gq","hot-shop.com","hot-shot.com","hot.ee","hotbot.com","hotbox.ru","hotbrev.com","hotcoolmail.com","hotepmail.com","hotfire.net","hotletter.com","hotlinemail.com","hotmail.be","hotmail.ca","hotmail.ch","hotmail.co","hotmail.co.il","hotmail.co.jp","hotmail.co.nz","hotmail.co.uk","hotmail.co.za","hotmail.com","hotmail.com.ar","hotmail.com.au","hotmail.com.br","hotmail.com.mx","hotmail.com.tr","hotmail.de","hotmail.es","hotmail.fi","hotmail.fr","hotmail.it","hotmail.kg","hotmail.kz","hotmail.my","hotmail.nl","hotmail.ro","hotmail.roor","hotmail.ru","hotpop.com","hotpop3.com","hotvoice.com","housefan.com","housefancom","housemail.com","hsuchi.net","html.tou.com","hu2.ru","hughes.net","hulapla.de","humanoid.net","humanux.com","humn.ws.gy","humour.com","hunsa.com","hurting.com","hush.com","hushmail.com","hypernautica.com","i-connect.com","i-france.com","i-love-cats.com","i-mail.com.au","i-mailbox.net","i-p.com","i.am","i.am.to","i.amhey.to","i.ua","i12.com","i2828.com","i2pmail.org","iam4msu.com","iamawoman.com","iamfinallyonline.com","iamwaiting.com","iamwasted.com","iamyours.com","icestorm.com","ich-bin-verrueckt-nach-dir.de","ich-will-net.de","icloud.com","icmsconsultants.com","icq.com","icqmail.com","icrazy.com","icu.md","id-base.com","id.ru","ididitmyway.com","idigjesus.com","idirect.com","ieatspam.eu","ieatspam.info","ieh-mail.de","iespana.es","ifoward.com","ig.com.br","ignazio.it","ignmail.com","ihateclowns.com","ihateyoualot.info","iheartspam.org","iinet.net.au","ijustdontcare.com","ikbenspamvrij.nl","ilkposta.com","ilovechocolate.com","ilovegiraffes.net","ilovejesus.com","ilovelionking.com","ilovepokemonmail.com","ilovethemovies.com","ilovetocollect.net","ilse.nl","imaginemail.com","imail.org","imail.ru","imailbox.com","imails.info","imap-mail.com","imap.cc","imapmail.org","imel.org","imgof.com","imgv.de","immo-gerance.info","imneverwrong.com","imposter.co.uk","imstations.com","imstressed.com","imtoosexy.com","in-box.net","in2jesus.com","iname.com","inbax.tk","inbound.plus","inbox.com","inbox.lv","inbox.net","inbox.ru","inbox.si","inboxalias.com","inboxclean.com","inboxclean.org","incamail.com","includingarabia.com","incredimail.com","indeedemail.com","index.ua","indexa.fr","india.com","indiatimes.com","indo-mail.com","indocities.com","indomail.com","indosat.net.id","indus.ru","indyracers.com","inerted.com","inet.com","inet.net.au","info-media.de","info-radio.ml","info.com","info66.com","infoapex.com","infocom.zp.ua","infohq.com","infomail.es","infomart.or.jp","informaticos.com","infospacemail.com","infovia.com.ar","inicia.es","inmail.sk","inmail24.com","inmano.com","inmynetwork.tk","innocent.com","inonesearch.com","inorbit.com","inoutbox.com","insidebaltimore.net","insight.rr.com","inspectorjavert.com","instant-mail.de","instantemailaddress.com","instantmail.fr","instruction.com","instructor.net","insurer.com","interburp.com","interfree.it","interia.pl","interlap.com.ar","intermail.co.il","internet-club.com","internet-e-mail.com","internet-mail.org","internet-police.com","internetbiz.com","internetdrive.com","internetegypt.com","internetemails.net","internetmailing.net","internode.on.net","invalid.com","investormail.com","inwind.it","iobox.com","iobox.fi","iol.it","iol.pt","iowaemail.com","ip3.com","ip4.pp.ua","ip6.li","ip6.pp.ua","ipdeer.com","ipex.ru","ipoo.org","iportalexpress.com","iprimus.com.au","iqemail.com","irangate.net","iraqmail.com","ireland.com","irelandmail.com","irish2me.com","irj.hu","iroid.com","iscooler.com","isellcars.com","iservejesus.com","islamonline.net","islandemail.net","isleuthmail.com","ismart.net","isonfire.com","isp9.net","israelmail.com","ist-allein.info","ist-einmalig.de","ist-ganz-allein.de","ist-willig.de","italymail.com","itelefonica.com.br","itloox.com","itmom.com","ivebeenframed.com","ivillage.com","iwan-fals.com","iwi.net","iwmail.com","iwon.com","izadpanah.com","jabble.com","jahoopa.com","jakuza.hu","japan.com","jaydemail.com","jazzandjava.com","jazzfan.com","jazzgame.com","je-recycle.info","jeanvaljean.com","jerusalemmail.com","jesusanswers.com","jet-renovation.fr","jetable.com","jetable.de","jetable.fr.nf","jetable.net","jetable.org","jetable.pp.ua","jetemail.net","jewishmail.com","jfkislanders.com","jingjo.net","jippii.fi","jmail.co.za","jnxjn.com","job4u.com","jobbikszimpatizans.hu","joelonsoftware.com","joinme.com","jojomail.com","jokes.com","jordanmail.com","journalist.com","jourrapide.com","jovem.te.pt","joymail.com","jpopmail.com","jsrsolutions.com","jubiimail.dk","jump.com","jumpy.it","juniormail.com","junk1e.com","junkmail.com","junkmail.gq","juno.com","justemail.net","justicemail.com","justmail.de","justmailz.com","justmarriedmail.com","jwspamspy","k.ro","kaazoo.com","kabissa.org","kaduku.net","kaffeeschluerfer.com","kaffeeschluerfer.de","kaixo.com","kalpoint.com","kansascity.com","kapoorweb.com","karachian.com","karachioye.com","karbasi.com","kasmail.com","kaspop.com","katamail.com","kayafmmail.co.za","kbjrmail.com","kcks.com","kebi.com","keftamail.com","keg-party.com","keinpardon.de","keko.com.ar","kellychen.com","keptprivate.com","keromail.com","kewpee.com","keyemail.com","kgb.hu","khosropour.com","kichimail.com","kickassmail.com","killamail.com","killergreenmail.com","killermail.com","killmail.com","killmail.net","kimo.com","kimsdisk.com","kinglibrary.net","kinki-kids.com","kismail.ru","kissfans.com","kitemail.com","kittymail.com","kitznet.at","kiwibox.com","kiwitown.com","klassmaster.com","klassmaster.net","klzlk.com","km.ru","kmail.com.au","knol-power.nl","koko.com","kolumbus.fi","kommespaeter.de","konkovo.net","konsul.ru","konx.com","korea.com","koreamail.com","kosino.net","koszmail.pl","kozmail.com","kpnmail.nl","kreditor.ru","krim.ws","krongthip.com","krovatka.net","krunis.com","ksanmail.com","ksee24mail.com","kube93mail.com","kukamail.com","kulturbetrieb.info","kumarweb.com","kurzepost.de","kuwait-mail.com","kuzminki.net","kyokodate.com","kyokofukada.net","l33r.eu","la.com","labetteraverouge.at","lackmail.ru","ladyfire.com","ladymail.cz","lagerlouts.com","lags.us","lahoreoye.com","lakmail.com","lamer.hu","land.ru","langoo.com","lankamail.com","laoeq.com","laposte.net","lass-es-geschehen.de","last-chance.pro","lastmail.co","latemodels.com","latinmail.com","latino.com","lavabit.com","lavache.com","law.com","lawlita.com","lawyer.com","lazyinbox.com","learn2compute.net","lebanonatlas.com","leeching.net","leehom.net","lefortovo.net","legalactions.com","legalrc.loan","legislator.com","legistrator.com","lenta.ru","leonlai.net","letsgomets.net","letterbox.com","letterboxes.org","letthemeatspam.com","levele.com","levele.hu","lex.bg","lexis-nexis-mail.com","lhsdv.com","lianozovo.net","libero.it","liberomail.com","lick101.com","liebt-dich.info","lifebyfood.com","link2mail.net","linkmaster.com","linktrader.com","linuxfreemail.com","linuxmail.org","lionsfan.com.au","liontrucks.com","liquidinformation.net","lissamail.com","list.ru","listomail.com","litedrop.com","literaturelover.com","littleapple.com","littleblueroom.com","live.at","live.be","live.ca","live.cl","live.cn","live.co.uk","live.co.za","live.com","live.com.ar","live.com.au","live.com.mx","live.com.my","live.com.pt","live.com.sg","live.de","live.dk","live.fr","live.hk","live.ie","live.in","live.it","live.jp","live.nl","live.no","live.ru","live.se","liveradio.tk","liverpoolfans.com","ljiljan.com","llandudno.com","llangollen.com","lmxmail.sk","lobbyist.com","localbar.com","localgenius.com","locos.com","login-email.ga","loh.pp.ua","lol.ovpn.to","lolfreak.net","lolito.tk","lolnetwork.net","london.com","loobie.com","looksmart.co.uk","looksmart.com","looksmart.com.au","lookugly.com","lopezclub.com","lortemail.dk","louiskoo.com","lov.ru","love.com","love.cz","loveable.com","lovecat.com","lovefall.ml","lovefootball.com","loveforlostcats.com","lovelygirl.net","lovemail.com","lover-boy.com","lovergirl.com","lovesea.gq","lovethebroncos.com","lovethecowboys.com","lovetocook.net","lovetohike.com","loveyouforever.de","lovingjesus.com","lowandslow.com","lr7.us","lr78.com","lroid.com","lubovnik.ru","lukop.dk","luso.pt","luukku.com","luv2.us","luvrhino.com","lvie.com.sg","lvwebmail.com","lycos.co.uk","lycos.com","lycos.es","lycos.it","lycos.ne.jp","lycos.ru","lycosemail.com","lycosmail.com","m-a-i-l.com","m-hmail.com","m21.cc","m4.org","m4ilweb.info","mac.com","macbox.com","macbox.ru","macfreak.com","machinecandy.com","macmail.com","mad.scientist.com","madcrazy.com","madcreations.com","madonnafan.com","madrid.com","maennerversteherin.com","maennerversteherin.de","maffia.hu","magicmail.co.za","mahmoodweb.com","mail-awu.de","mail-box.cz","mail-center.com","mail-central.com","mail-easy.fr","mail-filter.com","mail-me.com","mail-page.com","mail-temporaire.fr","mail-tester.com","mail.austria.com","mail.az","mail.be","mail.bg","mail.bulgaria.com","mail.by","mail.byte.it","mail.co.za","mail.com","mail.com.tr","mail.ee","mail.entrepeneurmag.com","mail.freetown.com","mail.gr","mail.hitthebeach.com","mail.htl22.at","mail.kmsp.com","mail.md","mail.mezimages.net","mail.misterpinball.de","mail.nu","mail.org.uk","mail.pf","mail.pharmacy.com","mail.pt","mail.r-o-o-t.com","mail.ru","mail.salu.net","mail.sisna.com","mail.spaceports.com","mail.svenz.eu","mail.theboys.com","mail.usa.com","mail.vasarhely.hu","mail.vu","mail.wtf","mail.zp.ua","mail114.net","mail15.com","mail1a.de","mail1st.com","mail2007.com","mail21.cc","mail2aaron.com","mail2abby.com","mail2abc.com","mail2actor.com","mail2admiral.com","mail2adorable.com","mail2adoration.com","mail2adore.com","mail2adventure.com","mail2aeolus.com","mail2aether.com","mail2affection.com","mail2afghanistan.com","mail2africa.com","mail2agent.com","mail2aha.com","mail2ahoy.com","mail2aim.com","mail2air.com","mail2airbag.com","mail2airforce.com","mail2airport.com","mail2alabama.com","mail2alan.com","mail2alaska.com","mail2albania.com","mail2alcoholic.com","mail2alec.com","mail2alexa.com","mail2algeria.com","mail2alicia.com","mail2alien.com","mail2allan.com","mail2allen.com","mail2allison.com","mail2alpha.com","mail2alyssa.com","mail2amanda.com","mail2amazing.com","mail2amber.com","mail2america.com","mail2american.com","mail2andorra.com","mail2andrea.com","mail2andy.com","mail2anesthesiologist.com","mail2angela.com","mail2angola.com","mail2ann.com","mail2anna.com","mail2anne.com","mail2anthony.com","mail2anything.com","mail2aphrodite.com","mail2apollo.com","mail2april.com","mail2aquarius.com","mail2arabia.com","mail2arabic.com","mail2architect.com","mail2ares.com","mail2argentina.com","mail2aries.com","mail2arizona.com","mail2arkansas.com","mail2armenia.com","mail2army.com","mail2arnold.com","mail2art.com","mail2artemus.com","mail2arthur.com","mail2artist.com","mail2ashley.com","mail2ask.com","mail2astronomer.com","mail2athena.com","mail2athlete.com","mail2atlas.com","mail2atom.com","mail2attitude.com","mail2auction.com","mail2aunt.com","mail2australia.com","mail2austria.com","mail2azerbaijan.com","mail2baby.com","mail2bahamas.com","mail2bahrain.com","mail2ballerina.com","mail2ballplayer.com","mail2band.com","mail2bangladesh.com","mail2bank.com","mail2banker.com","mail2bankrupt.com","mail2baptist.com","mail2bar.com","mail2barbados.com","mail2barbara.com","mail2barter.com","mail2basketball.com","mail2batter.com","mail2beach.com","mail2beast.com","mail2beatles.com","mail2beauty.com","mail2becky.com","mail2beijing.com","mail2belgium.com","mail2belize.com","mail2ben.com","mail2bernard.com","mail2beth.com","mail2betty.com","mail2beverly.com","mail2beyond.com","mail2biker.com","mail2bill.com","mail2billionaire.com","mail2billy.com","mail2bio.com","mail2biologist.com","mail2black.com","mail2blackbelt.com","mail2blake.com","mail2blind.com","mail2blonde.com","mail2blues.com","mail2bob.com","mail2bobby.com","mail2bolivia.com","mail2bombay.com","mail2bonn.com","mail2bookmark.com","mail2boreas.com","mail2bosnia.com","mail2boston.com","mail2botswana.com","mail2bradley.com","mail2brazil.com","mail2breakfast.com","mail2brian.com","mail2bride.com","mail2brittany.com","mail2broker.com","mail2brook.com","mail2bruce.com","mail2brunei.com","mail2brunette.com","mail2brussels.com","mail2bryan.com","mail2bug.com","mail2bulgaria.com","mail2business.com","mail2buy.com","mail2ca.com","mail2california.com","mail2calvin.com","mail2cambodia.com","mail2cameroon.com","mail2canada.com","mail2cancer.com","mail2capeverde.com","mail2capricorn.com","mail2cardinal.com","mail2cardiologist.com","mail2care.com","mail2caroline.com","mail2carolyn.com","mail2casey.com","mail2cat.com","mail2caterer.com","mail2cathy.com","mail2catlover.com","mail2catwalk.com","mail2cell.com","mail2chad.com","mail2champaign.com","mail2charles.com","mail2chef.com","mail2chemist.com","mail2cherry.com","mail2chicago.com","mail2chile.com","mail2china.com","mail2chinese.com","mail2chocolate.com","mail2christian.com","mail2christie.com","mail2christmas.com","mail2christy.com","mail2chuck.com","mail2cindy.com","mail2clark.com","mail2classifieds.com","mail2claude.com","mail2cliff.com","mail2clinic.com","mail2clint.com","mail2close.com","mail2club.com","mail2coach.com","mail2coastguard.com","mail2colin.com","mail2college.com","mail2colombia.com","mail2color.com","mail2colorado.com","mail2columbia.com","mail2comedian.com","mail2composer.com","mail2computer.com","mail2computers.com","mail2concert.com","mail2congo.com","mail2connect.com","mail2connecticut.com","mail2consultant.com","mail2convict.com","mail2cook.com","mail2cool.com","mail2cory.com","mail2costarica.com","mail2country.com","mail2courtney.com","mail2cowboy.com","mail2cowgirl.com","mail2craig.com","mail2crave.com","mail2crazy.com","mail2create.com","mail2croatia.com","mail2cry.com","mail2crystal.com","mail2cuba.com","mail2culture.com","mail2curt.com","mail2customs.com","mail2cute.com","mail2cutey.com","mail2cynthia.com","mail2cyprus.com","mail2czechrepublic.com","mail2dad.com","mail2dale.com","mail2dallas.com","mail2dan.com","mail2dana.com","mail2dance.com","mail2dancer.com","mail2danielle.com","mail2danny.com","mail2darlene.com","mail2darling.com","mail2darren.com","mail2daughter.com","mail2dave.com","mail2dawn.com","mail2dc.com","mail2dealer.com","mail2deanna.com","mail2dearest.com","mail2debbie.com","mail2debby.com","mail2deer.com","mail2delaware.com","mail2delicious.com","mail2demeter.com","mail2democrat.com","mail2denise.com","mail2denmark.com","mail2dennis.com","mail2dentist.com","mail2derek.com","mail2desert.com","mail2devoted.com","mail2devotion.com","mail2diamond.com","mail2diana.com","mail2diane.com","mail2diehard.com","mail2dilemma.com","mail2dillon.com","mail2dinner.com","mail2dinosaur.com","mail2dionysos.com","mail2diplomat.com","mail2director.com","mail2dirk.com","mail2disco.com","mail2dive.com","mail2diver.com","mail2divorced.com","mail2djibouti.com","mail2doctor.com","mail2doglover.com","mail2dominic.com","mail2dominica.com","mail2dominicanrepublic.com","mail2don.com","mail2donald.com","mail2donna.com","mail2doris.com","mail2dorothy.com","mail2doug.com","mail2dough.com","mail2douglas.com","mail2dow.com","mail2downtown.com","mail2dream.com","mail2dreamer.com","mail2dude.com","mail2dustin.com","mail2dyke.com","mail2dylan.com","mail2earl.com","mail2earth.com","mail2eastend.com","mail2eat.com","mail2economist.com","mail2ecuador.com","mail2eddie.com","mail2edgar.com","mail2edwin.com","mail2egypt.com","mail2electron.com","mail2eli.com","mail2elizabeth.com","mail2ellen.com","mail2elliot.com","mail2elsalvador.com","mail2elvis.com","mail2emergency.com","mail2emily.com","mail2engineer.com","mail2english.com","mail2environmentalist.com","mail2eos.com","mail2eric.com","mail2erica.com","mail2erin.com","mail2erinyes.com","mail2eris.com","mail2eritrea.com","mail2ernie.com","mail2eros.com","mail2estonia.com","mail2ethan.com","mail2ethiopia.com","mail2eu.com","mail2europe.com","mail2eurus.com","mail2eva.com","mail2evan.com","mail2evelyn.com","mail2everything.com","mail2exciting.com","mail2expert.com","mail2fairy.com","mail2faith.com","mail2fanatic.com","mail2fancy.com","mail2fantasy.com","mail2farm.com","mail2farmer.com","mail2fashion.com","mail2fat.com","mail2feeling.com","mail2female.com","mail2fever.com","mail2fighter.com","mail2fiji.com","mail2filmfestival.com","mail2films.com","mail2finance.com","mail2finland.com","mail2fireman.com","mail2firm.com","mail2fisherman.com","mail2flexible.com","mail2florence.com","mail2florida.com","mail2floyd.com","mail2fly.com","mail2fond.com","mail2fondness.com","mail2football.com","mail2footballfan.com","mail2found.com","mail2france.com","mail2frank.com","mail2frankfurt.com","mail2franklin.com","mail2fred.com","mail2freddie.com","mail2free.com","mail2freedom.com","mail2french.com","mail2freudian.com","mail2friendship.com","mail2from.com","mail2fun.com","mail2gabon.com","mail2gabriel.com","mail2gail.com","mail2galaxy.com","mail2gambia.com","mail2games.com","mail2gary.com","mail2gavin.com","mail2gemini.com","mail2gene.com","mail2genes.com","mail2geneva.com","mail2george.com","mail2georgia.com","mail2gerald.com","mail2german.com","mail2germany.com","mail2ghana.com","mail2gilbert.com","mail2gina.com","mail2girl.com","mail2glen.com","mail2gloria.com","mail2goddess.com","mail2gold.com","mail2golfclub.com","mail2golfer.com","mail2gordon.com","mail2government.com","mail2grab.com","mail2grace.com","mail2graham.com","mail2grandma.com","mail2grandpa.com","mail2grant.com","mail2greece.com","mail2green.com","mail2greg.com","mail2grenada.com","mail2gsm.com","mail2guard.com","mail2guatemala.com","mail2guy.com","mail2hades.com","mail2haiti.com","mail2hal.com","mail2handhelds.com","mail2hank.com","mail2hannah.com","mail2harold.com","mail2harry.com","mail2hawaii.com","mail2headhunter.com","mail2heal.com","mail2heather.com","mail2heaven.com","mail2hebe.com","mail2hecate.com","mail2heidi.com","mail2helen.com","mail2hell.com","mail2help.com","mail2helpdesk.com","mail2henry.com","mail2hephaestus.com","mail2hera.com","mail2hercules.com","mail2herman.com","mail2hermes.com","mail2hespera.com","mail2hestia.com","mail2highschool.com","mail2hindu.com","mail2hip.com","mail2hiphop.com","mail2holland.com","mail2holly.com","mail2hollywood.com","mail2homer.com","mail2honduras.com","mail2honey.com","mail2hongkong.com","mail2hope.com","mail2horse.com","mail2hot.com","mail2hotel.com","mail2houston.com","mail2howard.com","mail2hugh.com","mail2human.com","mail2hungary.com","mail2hungry.com","mail2hygeia.com","mail2hyperspace.com","mail2hypnos.com","mail2ian.com","mail2ice-cream.com","mail2iceland.com","mail2idaho.com","mail2idontknow.com","mail2illinois.com","mail2imam.com","mail2in.com","mail2india.com","mail2indian.com","mail2indiana.com","mail2indonesia.com","mail2infinity.com","mail2intense.com","mail2iowa.com","mail2iran.com","mail2iraq.com","mail2ireland.com","mail2irene.com","mail2iris.com","mail2irresistible.com","mail2irving.com","mail2irwin.com","mail2isaac.com","mail2israel.com","mail2italian.com","mail2italy.com","mail2jackie.com","mail2jacob.com","mail2jail.com","mail2jaime.com","mail2jake.com","mail2jamaica.com","mail2james.com","mail2jamie.com","mail2jan.com","mail2jane.com","mail2janet.com","mail2janice.com","mail2japan.com","mail2japanese.com","mail2jasmine.com","mail2jason.com","mail2java.com","mail2jay.com","mail2jazz.com","mail2jed.com","mail2jeffrey.com","mail2jennifer.com","mail2jenny.com","mail2jeremy.com","mail2jerry.com","mail2jessica.com","mail2jessie.com","mail2jesus.com","mail2jew.com","mail2jeweler.com","mail2jim.com","mail2jimmy.com","mail2joan.com","mail2joann.com","mail2joanna.com","mail2jody.com","mail2joe.com","mail2joel.com","mail2joey.com","mail2john.com","mail2join.com","mail2jon.com","mail2jonathan.com","mail2jones.com","mail2jordan.com","mail2joseph.com","mail2josh.com","mail2joy.com","mail2juan.com","mail2judge.com","mail2judy.com","mail2juggler.com","mail2julian.com","mail2julie.com","mail2jumbo.com","mail2junk.com","mail2justin.com","mail2justme.com","mail2k.ru","mail2kansas.com","mail2karate.com","mail2karen.com","mail2karl.com","mail2karma.com","mail2kathleen.com","mail2kathy.com","mail2katie.com","mail2kay.com","mail2kazakhstan.com","mail2keen.com","mail2keith.com","mail2kelly.com","mail2kelsey.com","mail2ken.com","mail2kendall.com","mail2kennedy.com","mail2kenneth.com","mail2kenny.com","mail2kentucky.com","mail2kenya.com","mail2kerry.com","mail2kevin.com","mail2kim.com","mail2kimberly.com","mail2king.com","mail2kirk.com","mail2kiss.com","mail2kosher.com","mail2kristin.com","mail2kurt.com","mail2kuwait.com","mail2kyle.com","mail2kyrgyzstan.com","mail2la.com","mail2lacrosse.com","mail2lance.com","mail2lao.com","mail2larry.com","mail2latvia.com","mail2laugh.com","mail2laura.com","mail2lauren.com","mail2laurie.com","mail2lawrence.com","mail2lawyer.com","mail2lebanon.com","mail2lee.com","mail2leo.com","mail2leon.com","mail2leonard.com","mail2leone.com","mail2leslie.com","mail2letter.com","mail2liberia.com","mail2libertarian.com","mail2libra.com","mail2libya.com","mail2liechtenstein.com","mail2life.com","mail2linda.com","mail2linux.com","mail2lionel.com","mail2lipstick.com","mail2liquid.com","mail2lisa.com","mail2lithuania.com","mail2litigator.com","mail2liz.com","mail2lloyd.com","mail2lois.com","mail2lola.com","mail2london.com","mail2looking.com","mail2lori.com","mail2lost.com","mail2lou.com","mail2louis.com","mail2louisiana.com","mail2lovable.com","mail2love.com","mail2lucky.com","mail2lucy.com","mail2lunch.com","mail2lust.com","mail2luxembourg.com","mail2luxury.com","mail2lyle.com","mail2lynn.com","mail2madagascar.com","mail2madison.com","mail2madrid.com","mail2maggie.com","mail2mail4.com","mail2maine.com","mail2malawi.com","mail2malaysia.com","mail2maldives.com","mail2mali.com","mail2malta.com","mail2mambo.com","mail2man.com","mail2mandy.com","mail2manhunter.com","mail2mankind.com","mail2many.com","mail2marc.com","mail2marcia.com","mail2margaret.com","mail2margie.com","mail2marhaba.com","mail2maria.com","mail2marilyn.com","mail2marines.com","mail2mark.com","mail2marriage.com","mail2married.com","mail2marries.com","mail2mars.com","mail2marsha.com","mail2marshallislands.com","mail2martha.com","mail2martin.com","mail2marty.com","mail2marvin.com","mail2mary.com","mail2maryland.com","mail2mason.com","mail2massachusetts.com","mail2matt.com","mail2matthew.com","mail2maurice.com","mail2mauritania.com","mail2mauritius.com","mail2max.com","mail2maxwell.com","mail2maybe.com","mail2mba.com","mail2me4u.com","mail2mechanic.com","mail2medieval.com","mail2megan.com","mail2mel.com","mail2melanie.com","mail2melissa.com","mail2melody.com","mail2member.com","mail2memphis.com","mail2methodist.com","mail2mexican.com","mail2mexico.com","mail2mgz.com","mail2miami.com","mail2michael.com","mail2michelle.com","mail2michigan.com","mail2mike.com","mail2milan.com","mail2milano.com","mail2mildred.com","mail2milkyway.com","mail2millennium.com","mail2millionaire.com","mail2milton.com","mail2mime.com","mail2mindreader.com","mail2mini.com","mail2minister.com","mail2minneapolis.com","mail2minnesota.com","mail2miracle.com","mail2missionary.com","mail2mississippi.com","mail2missouri.com","mail2mitch.com","mail2model.com","mail2moldova.commail2molly.com","mail2mom.com","mail2monaco.com","mail2money.com","mail2mongolia.com","mail2monica.com","mail2montana.com","mail2monty.com","mail2moon.com","mail2morocco.com","mail2morpheus.com","mail2mors.com","mail2moscow.com","mail2moslem.com","mail2mouseketeer.com","mail2movies.com","mail2mozambique.com","mail2mp3.com","mail2mrright.com","mail2msright.com","mail2museum.com","mail2music.com","mail2musician.com","mail2muslim.com","mail2my.com","mail2myboat.com","mail2mycar.com","mail2mycell.com","mail2mygsm.com","mail2mylaptop.com","mail2mymac.com","mail2mypager.com","mail2mypalm.com","mail2mypc.com","mail2myphone.com","mail2myplane.com","mail2namibia.com","mail2nancy.com","mail2nasdaq.com","mail2nathan.com","mail2nauru.com","mail2navy.com","mail2neal.com","mail2nebraska.com","mail2ned.com","mail2neil.com","mail2nelson.com","mail2nemesis.com","mail2nepal.com","mail2netherlands.com","mail2network.com","mail2nevada.com","mail2newhampshire.com","mail2newjersey.com","mail2newmexico.com","mail2newyork.com","mail2newzealand.com","mail2nicaragua.com","mail2nick.com","mail2nicole.com","mail2niger.com","mail2nigeria.com","mail2nike.com","mail2no.com","mail2noah.com","mail2noel.com","mail2noelle.com","mail2normal.com","mail2norman.com","mail2northamerica.com","mail2northcarolina.com","mail2northdakota.com","mail2northpole.com","mail2norway.com","mail2notus.com","mail2noway.com","mail2nowhere.com","mail2nuclear.com","mail2nun.com","mail2ny.com","mail2oasis.com","mail2oceanographer.com","mail2ohio.com","mail2ok.com","mail2oklahoma.com","mail2oliver.com","mail2oman.com","mail2one.com","mail2onfire.com","mail2online.com","mail2oops.com","mail2open.com","mail2ophthalmologist.com","mail2optometrist.com","mail2oregon.com","mail2oscars.com","mail2oslo.com","mail2painter.com","mail2pakistan.com","mail2palau.com","mail2pan.com","mail2panama.com","mail2paraguay.com","mail2paralegal.com","mail2paris.com","mail2park.com","mail2parker.com","mail2party.com","mail2passion.com","mail2pat.com","mail2patricia.com","mail2patrick.com","mail2patty.com","mail2paul.com","mail2paula.com","mail2pay.com","mail2peace.com","mail2pediatrician.com","mail2peggy.com","mail2pennsylvania.com","mail2perry.com","mail2persephone.com","mail2persian.com","mail2peru.com","mail2pete.com","mail2peter.com","mail2pharmacist.com","mail2phil.com","mail2philippines.com","mail2phoenix.com","mail2phonecall.com","mail2phyllis.com","mail2pickup.com","mail2pilot.com","mail2pisces.com","mail2planet.com","mail2platinum.com","mail2plato.com","mail2pluto.com","mail2pm.com","mail2podiatrist.com","mail2poet.com","mail2poland.com","mail2policeman.com","mail2policewoman.com","mail2politician.com","mail2pop.com","mail2pope.com","mail2popular.com","mail2portugal.com","mail2poseidon.com","mail2potatohead.com","mail2power.com","mail2presbyterian.com","mail2president.com","mail2priest.com","mail2prince.com","mail2princess.com","mail2producer.com","mail2professor.com","mail2protect.com","mail2psychiatrist.com","mail2psycho.com","mail2psychologist.com","mail2qatar.com","mail2queen.com","mail2rabbi.com","mail2race.com","mail2racer.com","mail2rachel.com","mail2rage.com","mail2rainmaker.com","mail2ralph.com","mail2randy.com","mail2rap.com","mail2rare.com","mail2rave.com","mail2ray.com","mail2raymond.com","mail2realtor.com","mail2rebecca.com","mail2recruiter.com","mail2recycle.com","mail2redhead.com","mail2reed.com","mail2reggie.com","mail2register.com","mail2rent.com","mail2republican.com","mail2resort.com","mail2rex.com","mail2rhodeisland.com","mail2rich.com","mail2richard.com","mail2ricky.com","mail2ride.com","mail2riley.com","mail2rita.com","mail2rob.com","mail2robert.com","mail2roberta.com","mail2robin.com","mail2rock.com","mail2rocker.com","mail2rod.com","mail2rodney.com","mail2romania.com","mail2rome.com","mail2ron.com","mail2ronald.com","mail2ronnie.com","mail2rose.com","mail2rosie.com","mail2roy.com","mail2rss.org","mail2rudy.com","mail2rugby.com","mail2runner.com","mail2russell.com","mail2russia.com","mail2russian.com","mail2rusty.com","mail2ruth.com","mail2rwanda.com","mail2ryan.com","mail2sa.com","mail2sabrina.com","mail2safe.com","mail2sagittarius.com","mail2sail.com","mail2sailor.com","mail2sal.com","mail2salaam.com","mail2sam.com","mail2samantha.com","mail2samoa.com","mail2samurai.com","mail2sandra.com","mail2sandy.com","mail2sanfrancisco.com","mail2sanmarino.com","mail2santa.com","mail2sara.com","mail2sarah.com","mail2sat.com","mail2saturn.com","mail2saudi.com","mail2saudiarabia.com","mail2save.com","mail2savings.com","mail2school.com","mail2scientist.com","mail2scorpio.com","mail2scott.com","mail2sean.com","mail2search.com","mail2seattle.com","mail2secretagent.com","mail2senate.com","mail2senegal.com","mail2sensual.com","mail2seth.com","mail2sevenseas.com","mail2sexy.com","mail2seychelles.com","mail2shane.com","mail2sharon.com","mail2shawn.com","mail2ship.com","mail2shirley.com","mail2shoot.com","mail2shuttle.com","mail2sierraleone.com","mail2simon.com","mail2singapore.com","mail2single.com","mail2site.com","mail2skater.com","mail2skier.com","mail2sky.com","mail2sleek.com","mail2slim.com","mail2slovakia.com","mail2slovenia.com","mail2smile.com","mail2smith.com","mail2smooth.com","mail2soccer.com","mail2soccerfan.com","mail2socialist.com","mail2soldier.com","mail2somalia.com","mail2son.com","mail2song.com","mail2sos.com","mail2sound.com","mail2southafrica.com","mail2southamerica.com","mail2southcarolina.com","mail2southdakota.com","mail2southkorea.com","mail2southpole.com","mail2spain.com","mail2spanish.com","mail2spare.com","mail2spectrum.com","mail2splash.com","mail2sponsor.com","mail2sports.com","mail2srilanka.com","mail2stacy.com","mail2stan.com","mail2stanley.com","mail2star.com","mail2state.com","mail2stephanie.com","mail2steve.com","mail2steven.com","mail2stewart.com","mail2stlouis.com","mail2stock.com","mail2stockholm.com","mail2stockmarket.com","mail2storage.com","mail2store.com","mail2strong.com","mail2student.com","mail2studio.com","mail2studio54.com","mail2stuntman.com","mail2subscribe.com","mail2sudan.com","mail2superstar.com","mail2surfer.com","mail2suriname.com","mail2susan.com","mail2suzie.com","mail2swaziland.com","mail2sweden.com","mail2sweetheart.com","mail2swim.com","mail2swimmer.com","mail2swiss.com","mail2switzerland.com","mail2sydney.com","mail2sylvia.com","mail2syria.com","mail2taboo.com","mail2taiwan.com","mail2tajikistan.com","mail2tammy.com","mail2tango.com","mail2tanya.com","mail2tanzania.com","mail2tara.com","mail2taurus.com","mail2taxi.com","mail2taxidermist.com","mail2taylor.com","mail2taz.com","mail2teacher.com","mail2technician.com","mail2ted.com","mail2telephone.com","mail2teletubbie.com","mail2tenderness.com","mail2tennessee.com","mail2tennis.com","mail2tennisfan.com","mail2terri.com","mail2terry.com","mail2test.com","mail2texas.com","mail2thailand.com","mail2therapy.com","mail2think.com","mail2tickets.com","mail2tiffany.com","mail2tim.com","mail2time.com","mail2timothy.com","mail2tina.com","mail2titanic.com","mail2toby.com","mail2todd.com","mail2togo.com","mail2tom.com","mail2tommy.com","mail2tonga.com","mail2tony.com","mail2touch.com","mail2tourist.com","mail2tracey.com","mail2tracy.com","mail2tramp.com","mail2travel.com","mail2traveler.com","mail2travis.com","mail2trekkie.com","mail2trex.com","mail2triallawyer.com","mail2trick.com","mail2trillionaire.com","mail2troy.com","mail2truck.com","mail2trump.com","mail2try.com","mail2tunisia.com","mail2turbo.com","mail2turkey.com","mail2turkmenistan.com","mail2tv.com","mail2tycoon.com","mail2tyler.com","mail2u4me.com","mail2uae.com","mail2uganda.com","mail2uk.com","mail2ukraine.com","mail2uncle.com","mail2unsubscribe.com","mail2uptown.com","mail2uruguay.com","mail2usa.com","mail2utah.com","mail2uzbekistan.com","mail2v.com","mail2vacation.com","mail2valentines.com","mail2valerie.com","mail2valley.com","mail2vamoose.com","mail2vanessa.com","mail2vanuatu.com","mail2venezuela.com","mail2venous.com","mail2venus.com","mail2vermont.com","mail2vickie.com","mail2victor.com","mail2victoria.com","mail2vienna.com","mail2vietnam.com","mail2vince.com","mail2virginia.com","mail2virgo.com","mail2visionary.com","mail2vodka.com","mail2volleyball.com","mail2waiter.com","mail2wallstreet.com","mail2wally.com","mail2walter.com","mail2warren.com","mail2washington.com","mail2wave.com","mail2way.com","mail2waycool.com","mail2wayne.com","mail2webmaster.com","mail2webtop.com","mail2webtv.com","mail2weird.com","mail2wendell.com","mail2wendy.com","mail2westend.com","mail2westvirginia.com","mail2whether.com","mail2whip.com","mail2white.com","mail2whitehouse.com","mail2whitney.com","mail2why.com","mail2wilbur.com","mail2wild.com","mail2willard.com","mail2willie.com","mail2wine.com","mail2winner.com","mail2wired.com","mail2wisconsin.com","mail2woman.com","mail2wonder.com","mail2world.com","mail2worship.com","mail2wow.com","mail2www.com","mail2wyoming.com","mail2xfiles.com","mail2xox.com","mail2yachtclub.com","mail2yahalla.com","mail2yemen.com","mail2yes.com","mail2yugoslavia.com","mail2zack.com","mail2zambia.com","mail2zenith.com","mail2zephir.com","mail2zeus.com","mail2zipper.com","mail2zoo.com","mail2zoologist.com","mail2zurich.com","mail3000.com","mail333.com","mail4trash.com","mail4u.info","mail8.com","mailandftp.com","mailandnews.com","mailas.com","mailasia.com","mailbidon.com","mailbiz.biz","mailblocks.com","mailbolt.com","mailbomb.net","mailboom.com","mailbox.as","mailbox.co.za","mailbox.gr","mailbox.hu","mailbox72.biz","mailbox80.biz","mailbr.com.br","mailbucket.org","mailc.net","mailcan.com","mailcat.biz","mailcatch.com","mailcc.com","mailchoose.co","mailcity.com","mailclub.fr","mailclub.net","mailde.de","mailde.info","maildrop.cc","maildrop.gq","maildx.com","mailed.ro","maileimer.de","mailexcite.com","mailexpire.com","mailfa.tk","mailfly.com","mailforce.net","mailforspam.com","mailfree.gq","mailfreeonline.com","mailfreeway.com","mailfs.com","mailftp.com","mailgate.gr","mailgate.ru","mailgenie.net","mailguard.me","mailhaven.com","mailhood.com","mailimate.com","mailin8r.com","mailinatar.com","mailinater.com","mailinator.com","mailinator.net","mailinator.org","mailinator.us","mailinator2.com","mailinblack.com","mailincubator.com","mailingaddress.org","mailingweb.com","mailisent.com","mailismagic.com","mailite.com","mailmate.com","mailme.dk","mailme.gq","mailme.ir","mailme.lv","mailme24.com","mailmetrash.com","mailmight.com","mailmij.nl","mailmoat.com","mailms.com","mailnator.com","mailnesia.com","mailnew.com","mailnull.com","mailops.com","mailorg.org","mailoye.com","mailpanda.com","mailpick.biz","mailpokemon.com","mailpost.zzn.com","mailpride.com","mailproxsy.com","mailpuppy.com","mailquack.com","mailrock.biz","mailroom.com","mailru.com","mailsac.com","mailscrap.com","mailseal.de","mailsent.net","mailserver.ru","mailservice.ms","mailshell.com","mailshuttle.com","mailsiphon.com","mailslapping.com","mailsnare.net","mailstart.com","mailstartplus.com","mailsurf.com","mailtag.com","mailtemp.info","mailto.de","mailtome.de","mailtothis.com","mailtrash.net","mailtv.net","mailtv.tv","mailueberfall.de","mailup.net","mailwire.com","mailworks.org","mailzi.ru","mailzilla.com","mailzilla.org","makemetheking.com","maktoob.com","malayalamtelevision.net","malayalapathram.com","male.ru","maltesemail.com","mamber.net","manager.de","manager.in.th","mancity.net","manlymail.net","mantrafreenet.com","mantramail.com","mantraonline.com","manutdfans.com","manybrain.com","marchmail.com","marfino.net","margarita.ru","mariah-carey.ml.org","mariahc.com","marijuana.com","marijuana.nl","marketing.lu","marketingfanatic.com","marketweighton.com","married-not.com","marriedandlovingit.com","marry.ru","marsattack.com","martindalemail.com","martinguerre.net","mash4077.com","masrawy.com","matmail.com","mauimail.com","mauritius.com","maximumedge.com","maxleft.com","maxmail.co.uk","mayaple.ru","mbox.com.au","mbx.cc","mchsi.com","mcrmail.com","me-mail.hu","me.com","meanpeoplesuck.com","meatismurder.net","medical.net.au","medmail.com","medscape.com","meetingmall.com","mega.zik.dj","megago.com","megamail.pt","megapoint.com","mehrani.com","mehtaweb.com","meine-dateien.info","meine-diashow.de","meine-fotos.info","meine-urlaubsfotos.de","meinspamschutz.de","mekhong.com","melodymail.com","meloo.com","meltmail.com","members.student.com","menja.net","merda.flu.cc","merda.igg.biz","merda.nut.cc","merda.usa.cc","merseymail.com","mesra.net","message.hu","message.myspace.com","messagebeamer.de","messages.to","messagez.com","metacrawler.com","metalfan.com","metaping.com","metta.lk","mexicomail.com","mezimages.net","mfsa.ru","miatadriver.com","mierdamail.com","miesto.sk","mighty.co.za","migmail.net","migmail.pl","migumail.com","miho-nakayama.com","mikrotamanet.com","millionaireintraining.com","millionairemail.com","milmail.com","milmail.com15","mindless.com","mindspring.com","minermail.com","mini-mail.com","minister.com","ministry-of-silly-walks.de","mintemail.com","misery.net","misterpinball.de","mit.tc","mittalweb.com","mixmail.com","mjfrogmail.com","ml1.net","mlanime.com","mlb.bounce.ed10.net","mm.st","mmail.com","mns.ru","mo3gov.net","moakt.com","mobico.ru","mobilbatam.com","mobileninja.co.uk","mochamail.com","modemnet.net","modernenglish.com","modomail.com","mohammed.com","mohmal.com","moldova.cc","moldova.com","moldovacc.com","mom-mail.com","momslife.com","moncourrier.fr.nf","monemail.com","monemail.fr.nf","money.net","mongol.net","monmail.fr.nf","monsieurcinema.com","montevideo.com.uy","monumentmail.com","moomia.com","moonman.com","moose-mail.com","mor19.uu.gl","mortaza.com","mosaicfx.com","moscowmail.com","mosk.ru","most-wanted.com","mostlysunny.com","motorcyclefan.net","motormania.com","movemail.com","movieemail.net","movieluver.com","mox.pp.ua","mozartmail.com","mozhno.net","mp3haze.com","mp4.it","mr-potatohead.com","mrpost.com","mrspender.com","mscold.com","msgbox.com","msn.cn","msn.com","msn.nl","msx.ru","mt2009.com","mt2014.com","mt2015.com","mt2016.com","mttestdriver.com","muehlacker.tk","multiplechoices","mundomail.net","munich.com","music.com","music.com19","music.maigate.ru","musician.com","musician.org","musicscene.org","muskelshirt.de","muslim.com","muslimemail.com","muslimsonline.com","mutantweb.com","mvrht.com","my.com","my10minutemail.com","mybox.it","mycabin.com","mycampus.com","mycard.net.ua","mycity.com","mycleaninbox.net","mycool.com","mydomain.com","mydotcomaddress.com","myfairpoint.net","myfamily.com","myfastmail.com","myfunnymail.com","mygo.com","myiris.com","myjazzmail.com","mymac.ru","mymacmail.com","mymail-in.net","mymail.ro","mynamedot.com","mynet.com","mynetaddress.com","mynetstore.de","myotw.net","myownemail.com","myownfriends.com","mypacks.net","mypad.com","mypartyclip.de","mypersonalemail.com","myphantomemail.com","myplace.com","myrambler.ru","myrealbox.com","myremarq.com","mysamp.de","myself.com","myspaceinc.net","myspamless.com","mystupidjob.com","mytemp.email","mytempemail.com","mytempmail.com","mythirdage.com","mytrashmail.com","myway.com","myworldmail.com","n2.com","n2baseball.com","n2business.com","n2mail.com","n2soccer.com","n2software.com","nabc.biz","nabuma.com","nafe.com","nagarealm.com","nagpal.net","nakedgreens.com","name.com","nameplanet.com","nanaseaikawa.com","nandomail.com","naplesnews.net","naseej.com","nate.com","nativestar.net","nativeweb.net","naui.net","naver.com","navigator.lv","navy.org","naz.com","nc.rr.com","nc.ru","nchoicemail.com","neeva.net","nekto.com","nekto.net","nekto.ru","nemra1.com","nenter.com","neo.rr.com","neomailbox.com","nepwk.com","nervhq.org","nervmich.net","nervtmich.net","net-c.be","net-c.ca","net-c.cat","net-c.com","net-c.es","net-c.fr","net-c.it","net-c.lu","net-c.nl","net-c.pl","net-pager.net","net-shopping.com","net.tf","net4b.pt","net4you.at","netaddres.ru","netaddress.ru","netbounce.com","netbroadcaster.com","netby.dk","netc.eu","netc.fr","netc.it","netc.lu","netc.pl","netcenter-vn.net","netcity.ru","netcmail.com","netcourrier.com","netexecutive.com","netexpressway.com","netfirms.com","netgenie.com","netian.com","netizen.com.ar","netkushi.com","netlane.com","netlimit.com","netmail.kg","netmails.com","netmails.net","netman.ru","netmanor.com","netmongol.com","netnet.com.sg","netnoir.net","netpiper.com","netposta.net","netradiomail.com","netralink.com","netscape.net","netscapeonline.co.uk","netspace.net.au","netspeedway.com","netsquare.com","netster.com","nettaxi.com","nettemail.com","netterchef.de","netti.fi","netvigator.com","netzero.com","netzero.net","netzidiot.de","netzoola.com","neue-dateien.de","neuf.fr","neuro.md","neustreet.com","neverbox.com","newap.ru","newarbat.net","newmail.com","newmail.net","newmail.ru","newsboysmail.com","newyork.com","newyorkcity.com","nextmail.ru","nexxmail.com","nfmail.com","ngs.ru","nhmail.com","nice-4u.com","nicebush.com","nicegal.com","nicholastse.net","nicolastse.com","niepodam.pl","nightimeuk.com","nightmail.com","nightmail.ru","nikopage.com","nikulino.net","nimail.com","nincsmail.hu","ninfan.com","nirvanafan.com","nm.ru","nmail.cf","nnh.com","nnov.ru","no-spam.ws","no4ma.ru","noavar.com","noblepioneer.com","nogmailspam.info","nomail.pw","nomail.xl.cx","nomail2me.com","nomorespamemails.com","nonpartisan.com","nonspam.eu","nonspammer.de","nonstopcinema.com","norika-fujiwara.com","norikomail.com","northgates.net","nospam.ze.tc","nospam4.us","nospamfor.us","nospammail.net","nospamthanks.info","notmailinator.com","notsharingmy.info","notyouagain.com","novogireevo.net","novokosino.net","nowhere.org","nowmymail.com","ntelos.net","ntlhelp.net","ntlworld.com","ntscan.com","null.net","nullbox.info","numep.ru","nur-fuer-spam.de","nurfuerspam.de","nus.edu.sg","nuvse.com","nwldx.com","nxt.ru","ny.com","nybce.com","nybella.com","nyc.com","nycmail.com","nz11.com","nzoomail.com","o-tay.com","o2.co.uk","o2.pl","oaklandas-fan.com","oath.com","objectmail.com","obobbo.com","oceanfree.net","ochakovo.net","odaymail.com","oddpost.com","odmail.com","odnorazovoe.ru","office-dateien.de","office-email.com","officedomain.com","offroadwarrior.com","oi.com.br","oicexchange.com","oikrach.com","ok.kz","ok.net","ok.ru","okbank.com","okhuman.com","okmad.com","okmagic.com","okname.net","okuk.com","oldbuthealthy.com","oldies1041.com","oldies104mail.com","ole.com","olemail.com","oligarh.ru","olympist.net","olypmall.ru","omaninfo.com","omen.ru","ondikoi.com","onebox.com","onenet.com.ar","oneoffemail.com","oneoffmail.com","onet.com.pl","onet.eu","onet.pl","onewaymail.com","oninet.pt","onlatedotcom.info","online.de","online.ie","online.ms","online.nl","online.ru","onlinecasinogamblings.com","onlinewiz.com","onmicrosoft.com","onmilwaukee.com","onobox.com","onvillage.com","oopi.org","op.pl","opayq.com","opendiary.com","openmailbox.org","operafan.com","operamail.com","opoczta.pl","optician.com","optonline.net","optusnet.com.au","orange.fr","orange.net","orbitel.bg","ordinaryamerican.net","orgmail.net","orthodontist.net","osite.com.br","oso.com","otakumail.com","otherinbox.com","our-computer.com","our-office.com","our.st","ourbrisbane.com","ourklips.com","ournet.md","outel.com","outgun.com","outlawspam.com","outlook.at","outlook.be","outlook.cl","outlook.co.id","outlook.co.il","outlook.co.nz","outlook.co.th","outlook.com","outlook.com.au","outlook.com.br","outlook.com.gr","outlook.com.pe","outlook.com.tr","outlook.com.vn","outlook.cz","outlook.de","outlook.dk","outlook.es","outlook.fr","outlook.hu","outlook.ie","outlook.in","outlook.it","outlook.jp","outlook.kr","outlook.lv","outlook.my","outlook.nl","outlook.ph","outlook.pt","outlook.sa","outlook.sg","outlook.sk","outloook.com","over-the-rainbow.com","ovi.com","ovpn.to","owlpic.com","ownmail.net","ozbytes.net.au","ozemail.com.au","ozz.ru","pacbell.net","pacific-ocean.com","pacific-re.com","pacificwest.com","packersfan.com","pagina.de","pagons.org","paidforsurf.com","pakistanmail.com","pakistanoye.com","palestinemail.com","pancakemail.com","pandawa.com","pandora.be","paradiseemail.com","paris.com","parkjiyoon.com","parrot.com","parsmail.com","partlycloudy.com","partybombe.de","partyheld.de","partynight.at","parvazi.com","passwordmail.com","pathfindermail.com","patmail.com","patra.net","pconnections.net","pcpostal.com","pcsrock.com","pcusers.otherinbox.com","peachworld.com","pechkin.ru","pediatrician.com","pekklemail.com","pemail.net","penpen.com","peoplepc.com","peopleweb.com","pepbot.com","perfectmail.com","perovo.net","perso.be","personal.ro","personales.com","petlover.com","petml.com","petr.ru","pettypool.com","pezeshkpour.com","pfui.ru","phayze.com","phone.net","photo-impact.eu","photographer.net","phpbb.uu.gl","phreaker.net","phus8kajuspa.cu.cc","physicist.net","pianomail.com","pickupman.com","picusnet.com","piercedallover.com","pigeonportal.com","pigmail.net","pigpig.net","pilotemail.com","pimagop.com","pinoymail.com","piracha.net","pisem.net","pjjkp.com","planet-mail.com","planet.nl","planetaccess.com","planetall.com","planetarymotion.net","planetdirect.com","planetearthinter.net","planetmail.com","planetmail.net","planetout.com","plasa.com","playersodds.com","playful.com","playstation.sony.com","plexolan.de","pluno.com","plus.com","plus.google.com","plusmail.com.br","pmail.net","pobox.com","pobox.hu","pobox.ru","pobox.sk","pochta.by","pochta.ru","pochta.ws","pochtamt.ru","poczta.fm","poczta.onet.pl","poetic.com","pokemail.net","pokemonpost.com","pokepost.com","polandmail.com","polbox.com","policeoffice.com","politician.com","politikerclub.de","polizisten-duzer.de","polyfaust.com","poofy.org","poohfan.com","pookmail.com","pool-sharks.com","poond.com","pop3.ru","popaccount.com","popmail.com","popsmail.com","popstar.com","populus.net","portableoffice.com","portugalmail.com","portugalmail.pt","portugalnet.com","positive-thinking.com","post.com","post.cz","post.sk","posta.net","posta.ro","posta.rosativa.ro.org","postaccesslite.com","postafiok.hu","postafree.com","postaweb.com","poste.it","postfach.cc","postinbox.com","postino.ch","postino.it","postmark.net","postmaster.co.uk","postmaster.twitter.com","postpro.net","pousa.com","powerdivas.com","powerfan.com","pp.inet.fi","praize.com","pray247.com","predprinimatel.ru","premium-mail.fr","premiumproducts.com","premiumservice.com","prepodavatel.ru","presidency.com","presnya.net","press.co.jp","prettierthanher.com","priest.com","primposta.com","primposta.hu","printesamargareta.ro","privacy.net","privatdemail.net","privy-mail.com","privymail.de","pro.hu","probemail.com","prodigy.net","prodigy.net.mx","professor.ru","progetplus.it","programist.ru","programmer.net","programozo.hu","proinbox.com","project2k.com","prokuratura.ru","prolaunch.com","promessage.com","prontomail.com","prontomail.compopulus.net","protestant.com","protonmail.com","proxymail.eu","prtnx.com","prydirect.info","psv-supporter.com","ptd.net","public-files.de","public.usa.com","publicist.com","pulp-fiction.com","punkass.com","puppy.com.my","purinmail.com","purpleturtle.com","put2.net","putthisinyourspamdatabase.com","pwrby.com","q.com","qatar.io","qatarmail.com","qdice.com","qip.ru","qmail.com","qprfans.com","qq.com","qrio.com","quackquack.com","quake.ru","quakemail.com","qualityservice.com","quantentunnel.de","qudsmail.com","quepasa.com","quickhosts.com","quickinbox.com","quickmail.nl","quickmail.ru","quicknet.nl","quickwebmail.com","quiklinks.com","quikmail.com","qv7.info","qwest.net","qwestoffice.net","r-o-o-t.com","r7.com","raakim.com","racedriver.com","racefanz.com","racingfan.com.au","racingmail.com","radicalz.com","radiku.ye.vc","radiologist.net","ragingbull.com","ralib.com","rambler.ru","ranmamail.com","rastogi.net","ratt-n-roll.com","rattle-snake.com","raubtierbaendiger.de","ravearena.com","ravefan.com","ravemail.co.za","ravemail.com","razormail.com","rccgmail.org","rcn.com","rcpt.at","realemail.net","realestatemail.net","reality-concept.club","reallyfast.biz","reallyfast.info","reallymymail.com","realradiomail.com","realtyagent.com","realtyalerts.ca","reborn.com","recode.me","reconmail.com","recursor.net","recycledmail.com","recycler.com","recyclermail.com","rediff.com","rediffmail.com","rediffmailpro.com","rednecks.com","redseven.de","redsfans.com","redwhitearmy.com","regbypass.com","reggaefan.com","reggafan.com","regiononline.com","registerednurses.com","regspaces.tk","reincarnate.com","relia.com","reliable-mail.com","religious.com","remail.ga","renren.com","repairman.com","reply.hu","reply.ticketmaster.com","represantive.com","representative.com","rescueteam.com","resgedvgfed.tk","resource.calendar.google.com","resumemail.com","retailfan.com","rexian.com","rezai.com","rhyta.com","richmondhill.com","rickymail.com","rin.ru","ring.by","riopreto.com.br","rklips.com","rmqkr.net","rn.com","ro.ru","roadrunner.com","roanokemail.com","rock.com","rocketmail.com","rocketship.com","rockfan.com","rodrun.com","rogers.com","rojname.com","rol.ro","rome.com","romymichele.com","roosh.com","rootprompt.org","rotfl.com","roughnet.com","royal.net","rpharmacist.com","rr.com","rrohio.com","rsub.com","rt.nl","rtrtr.com","ru.ru","rubyridge.com","runbox.com","rushpost.com","ruttolibero.com","rvshop.com","rxdoc.biz","s-mail.com","s0ny.net","sabreshockey.com","sacbeemail.com","saeuferleber.de","safarimail.com","safe-mail.net","safersignup.de","safetymail.info","safetypost.de","safrica.com","sagra.lu","sagra.lu.lu","sagra.lumarketing.lu","sags-per-mail.de","sailormoon.com","saint-mike.org","saintly.com","saintmail.net","sale-sale-sale.com","salehi.net","salesperson.net","samerica.com","samilan.net","samiznaetekogo.net","sammimail.com","sanchezsharks.com","sandelf.de","sanfranmail.com","sanook.com","sanriotown.com","santanmail.com","sapo.pt","sativa.ro.org","saturnfans.com","saturnperformance.com","saudia.com","savecougars.com","savelife.ml","saveowls.com","sayhi.net","saynotospams.com","sbcglbal.net","sbcglobal.com","sbcglobal.net","scandalmail.com","scanova.in","scanova.io","scarlet.nl","scfn.net","schafmail.de","schizo.com","schmusemail.de","schoolemail.com","schoolmail.com","schoolsucks.com","schreib-doch-mal-wieder.de","schrott-email.de","schweiz.org","sci.fi","science.com.au","scientist.com","scifianime.com","scotland.com","scotlandmail.com","scottishmail.co.uk","scottishtories.com","scottsboro.org","scrapbookscrapbook.com","scubadiving.com","seanet.com","search.ua","search417.com","searchwales.com","sebil.com","seckinmail.com","secret-police.com","secretarias.com","secretary.net","secretemail.de","secretservices.net","secure-mail.biz","secure-mail.cc","seductive.com","seekstoyboy.com","seguros.com.br","sekomaonline.com","selfdestructingmail.com","sellingspree.com","send.hu","sendmail.ru","sendme.cz","sendspamhere.com","senseless-entertainment.com","sent.as","sent.at","sent.com","sentrismail.com","serga.com.ar","servemymail.com","servermaps.net","services391.com","sesmail.com","sexmagnet.com","seznam.cz","sfr.fr","shahweb.net","shaniastuff.com","shared-files.de","sharedmailbox.org","sharewaredevelopers.com","sharklasers.com","sharmaweb.com","shaw.ca","she.com","shellov.net","shieldedmail.com","shieldemail.com","shiftmail.com","shinedyoureyes.com","shitaway.cf","shitaway.cu.cc","shitaway.ga","shitaway.gq","shitaway.ml","shitaway.tk","shitaway.usa.cc","shitmail.de","shitmail.me","shitmail.org","shitware.nl","shmeriously.com","shockinmytown.cu.cc","shootmail.com","shortmail.com","shortmail.net","shotgun.hu","showfans.com","showslow.de","shqiptar.eu","shuf.com","sialkotcity.com","sialkotian.com","sialkotoye.com","sibmail.com","sify.com","sigaret.net","silkroad.net","simbamail.fm","sina.cn","sina.com","sinamail.com","singapore.com","singles4jesus.com","singmail.com","singnet.com.sg","singpost.com","sinnlos-mail.de","sirindia.com","siteposter.net","skafan.com","skeefmail.com","skim.com","skizo.hu","skrx.tk","skunkbox.com","sky.com","skynet.be","slamdunkfan.com","slapsfromlastnight.com","slaskpost.se","slave-auctions.net","slickriffs.co.uk","slingshot.com","slippery.email","slipry.net","slo.net","slotter.com","sm.westchestergov.com","smap.4nmv.ru","smapxsmap.net","smashmail.de","smellfear.com","smellrear.com","smileyface.comsmithemail.net","sminkymail.com","smoothmail.com","sms.at","smtp.ru","snail-mail.net","snail-mail.ney","snakebite.com","snakemail.com","sndt.net","sneakemail.com","sneakmail.de","snet.net","sniper.hu","snkmail.com","snoopymail.com","snowboarding.com","snowdonia.net","so-simple.org","socamail.com","socceraccess.com","socceramerica.net","soccermail.com","soccermomz.com","social-mailer.tk","socialworker.net","sociologist.com","sofimail.com","sofort-mail.de","sofortmail.de","softhome.net","sogetthis.com","sogou.com","sohu.com","sokolniki.net","sol.dk","solar-impact.pro","solcon.nl","soldier.hu","solution4u.com","solvemail.info","songwriter.net","sonnenkinder.org","soodomail.com","soodonims.com","soon.com","soulfoodcookbook.com","soundofmusicfans.com","southparkmail.com","sovsem.net","sp.nl","space-bank.com","space-man.com","space-ship.com","space-travel.com","space.com","spaceart.com","spacebank.com","spacemart.com","spacetowns.com","spacewar.com","spainmail.com","spam.2012-2016.ru","spam4.me","spamail.de","spamarrest.com","spamavert.com","spambob.com","spambob.net","spambob.org","spambog.com","spambog.de","spambog.net","spambog.ru","spambooger.com","spambox.info","spambox.us","spamcannon.com","spamcannon.net","spamcero.com","spamcon.org","spamcorptastic.com","spamcowboy.com","spamcowboy.net","spamcowboy.org","spamday.com","spamdecoy.net","spameater.com","spameater.org","spamex.com","spamfree.eu","spamfree24.com","spamfree24.de","spamfree24.info","spamfree24.net","spamfree24.org","spamgoes.in","spamgourmet.com","spamgourmet.net","spamgourmet.org","spamherelots.com","spamhereplease.com","spamhole.com","spamify.com","spaminator.de","spamkill.info","spaml.com","spaml.de","spammotel.com","spamobox.com","spamoff.de","spamslicer.com","spamspot.com","spamstack.net","spamthis.co.uk","spamtroll.net","spankthedonkey.com","spartapiet.com","spazmail.com","speed.1s.fr","speedemail.net","speedpost.net","speedrules.com","speedrulz.com","speedy.com.ar","speedymail.org","sperke.net","spils.com","spinfinder.com","spiritseekers.com","spl.at","spoko.pl","spoofmail.de","sportemail.com","sportmail.ru","sportsmail.com","sporttruckdriver.com","spray.no","spray.se","spybox.de","spymac.com","sraka.xyz","srilankan.net","ssl-mail.com","st-davids.net","stade.fr","stalag13.com","standalone.net","starbuzz.com","stargateradio.com","starmail.com","starmail.org","starmedia.com","starplace.com","starspath.com","start.com.au","starting-point.com","startkeys.com","startrekmail.com","starwars-fans.com","stealthmail.com","stillchronic.com","stinkefinger.net","stipte.nl","stockracer.com","stockstorm.com","stoned.com","stones.com","stop-my-spam.pp.ua","stopdropandroll.com","storksite.com","streber24.de","streetwisemail.com","stribmail.com","strompost.com","strongguy.com","student.su","studentcenter.org","stuffmail.de","subnetwork.com","subram.com","sudanmail.net","sudolife.me","sudolife.net","sudomail.biz","sudomail.com","sudomail.net","sudoverse.com","sudoverse.net","sudoweb.net","sudoworld.com","sudoworld.net","sueddeutsche.de","suhabi.com","suisse.org","sukhumvit.net","sul.com.br","sunmail1.com","sunpoint.net","sunrise-sunset.com","sunsgame.com","sunumail.sn","suomi24.fi","super-auswahl.de","superdada.com","supereva.it","supergreatmail.com","supermail.ru","supermailer.jp","superman.ru","superposta.com","superrito.com","superstachel.de","surat.com","suremail.info","surf3.net","surfree.com","surfsupnet.net","surfy.net","surgical.net","surimail.com","survivormail.com","susi.ml","sviblovo.net","svk.jp","swbell.net","sweb.cz","swedenmail.com","sweetville.net","sweetxxx.de","swift-mail.com","swiftdesk.com","swingeasyhithard.com","swingfan.com","swipermail.zzn.com","swirve.com","swissinfo.org","swissmail.com","swissmail.net","switchboardmail.com","switzerland.org","sx172.com","sympatico.ca","syom.com","syriamail.com","t-online.de","t.psh.me","t2mail.com","tafmail.com","takoe.com","takoe.net","takuyakimura.com","talk21.com","talkcity.com","talkinator.com","talktalk.co.uk","tamb.ru","tamil.com","tampabay.rr.com","tangmonkey.com","tankpolice.com","taotaotano.com","tatanova.com","tattooedallover.com","tattoofanatic.com","tbwt.com","tcc.on.ca","tds.net","teacher.com","teachermail.net","teachers.org","teamdiscovery.com","teamtulsa.net","tech-center.com","tech4peace.org","techemail.com","techie.com","technisamail.co.za","technologist.com","technologyandstocks.com","techpointer.com","techscout.com","techseek.com","techsniper.com","techspot.com","teenagedirtbag.com","teewars.org","tele2.nl","telebot.com","telebot.net","telefonica.net","teleline.es","telenet.be","telepac.pt","telerymd.com","teleserve.dynip.com","teletu.it","teleworm.com","teleworm.us","telfort.nl","telfortglasvezel.nl","telinco.net","telkom.net","telpage.net","telstra.com","telstra.com.au","temp-mail.com","temp-mail.de","temp-mail.org","temp-mail.ru","temp.headstrong.de","tempail.com","tempe-mail.com","tempemail.biz","tempemail.co.za","tempemail.com","tempemail.net","tempinbox.co.uk","tempinbox.com","tempmail.eu","tempmail.it","tempmail.us","tempmail2.com","tempmaildemo.com","tempmailer.com","tempmailer.de","tempomail.fr","temporarioemail.com.br","temporaryemail.net","temporaryemail.us","temporaryforwarding.com","temporaryinbox.com","temporarymailaddress.com","tempthe.net","tempymail.com","temtulsa.net","tenchiclub.com","tenderkiss.com","tennismail.com","terminverpennt.de","terra.cl","terra.com","terra.com.ar","terra.com.br","terra.com.pe","terra.es","test.com","test.de","tfanus.com.er","tfbnw.net","tfz.net","tgasa.ru","tgma.ru","tgngu.ru","tgu.ru","thai.com","thaimail.com","thaimail.net","thanksnospam.info","thankyou2010.com","thc.st","the-african.com","the-airforce.com","the-aliens.com","the-american.com","the-animal.com","the-army.com","the-astronaut.com","the-beauty.com","the-big-apple.com","the-biker.com","the-boss.com","the-brazilian.com","the-canadian.com","the-canuck.com","the-captain.com","the-chinese.com","the-country.com","the-cowboy.com","the-davis-home.com","the-dutchman.com","the-eagles.com","the-englishman.com","the-fastest.net","the-fool.com","the-frenchman.com","the-galaxy.net","the-genius.com","the-gentleman.com","the-german.com","the-gremlin.com","the-hooligan.com","the-italian.com","the-japanese.com","the-lair.com","the-madman.com","the-mailinglist.com","the-marine.com","the-master.com","the-mexican.com","the-ministry.com","the-monkey.com","the-newsletter.net","the-pentagon.com","the-police.com","the-prayer.com","the-professional.com","the-quickest.com","the-russian.com","the-seasiders.com","the-snake.com","the-spaceman.com","the-stock-market.com","the-student.net","the-whitehouse.net","the-wild-west.com","the18th.com","thecoolguy.com","thecriminals.com","thedoghousemail.com","thedorm.com","theend.hu","theglobe.com","thegolfcourse.com","thegooner.com","theheadoffice.com","theinternetemail.com","thelanddownunder.com","thelimestones.com","themail.com","themillionare.net","theoffice.net","theplate.com","thepokerface.com","thepostmaster.net","theraces.com","theracetrack.com","therapist.net","thereisnogod.com","thesimpsonsfans.com","thestreetfighter.com","theteebox.com","thewatercooler.com","thewebpros.co.uk","thewizzard.com","thewizzkid.com","thexyz.ca","thexyz.cn","thexyz.com","thexyz.es","thexyz.fr","thexyz.in","thexyz.mobi","thexyz.net","thexyz.org","thezhangs.net","thirdage.com","thisgirl.com","thisisnotmyrealemail.com","thismail.net","thoic.com","thraml.com","thrott.com","throwam.com","throwawayemailaddress.com","thundermail.com","tibetemail.com","tidni.com","tilien.com","timein.net","timormail.com","tin.it","tipsandadvice.com","tiran.ru","tiscali.at","tiscali.be","tiscali.co.uk","tiscali.it","tiscali.lu","tiscali.se","tittbit.in","tizi.com","tkcity.com","tlcfan.com","tmail.ws","tmailinator.com","tmicha.net","toast.com","toke.com","tokyo.com","tom.com","toolsource.com","toomail.biz","toothfairy.com","topchat.com","topgamers.co.uk","topletter.com","topmail-files.de","topmail.com.ar","topranklist.de","topsurf.com","topteam.bg","toquedequeda.com","torba.com","torchmail.com","torontomail.com","tortenboxer.de","totalmail.com","totalmail.de","totalmusic.net","totalsurf.com","toughguy.net","townisp.com","tpg.com.au","tradermail.info","trainspottingfan.com","trash-amil.com","trash-mail.at","trash-mail.com","trash-mail.de","trash-mail.ga","trash-mail.ml","trash2009.com","trash2010.com","trash2011.com","trashdevil.com","trashdevil.de","trashemail.de","trashmail.at","trashmail.com","trashmail.de","trashmail.me","trashmail.net","trashmail.org","trashmailer.com","trashymail.com","trashymail.net","travel.li","trayna.com","trbvm.com","trbvn.com","trevas.net","trialbytrivia.com","trialmail.de","trickmail.net","trillianpro.com","trimix.cn","tritium.net","trjam.net","trmailbox.com","tropicalstorm.com","truckeremail.net","truckers.com","truckerz.com","truckracer.com","truckracers.com","trust-me.com","truth247.com","truthmail.com","tsamail.co.za","ttml.co.in","tulipsmail.net","tunisiamail.com","turboprinz.de","turboprinzessin.de","turkey.com","turual.com","tushino.net","tut.by","tvcablenet.be","tverskie.net","tverskoe.net","tvnet.lv","tvstar.com","twc.com","twcny.com","twentylove.com","twinmail.de","twinstarsmail.com","tx.rr.com","tycoonmail.com","tyldd.com","typemail.com","tyt.by","u14269.ml","u2club.com","ua.fm","uae.ac","uaemail.com","ubbi.com","ubbi.com.br","uboot.com","uggsrock.com","uk2.net","uk2k.com","uk2net.com","uk7.net","uk8.net","ukbuilder.com","ukcool.com","ukdreamcast.com","ukmail.org","ukmax.com","ukr.net","ukrpost.net","ukrtop.com","uku.co.uk","ultapulta.com","ultimatelimos.com","ultrapostman.com","umail.net","ummah.org","umpire.com","unbounded.com","underwriters.com","unforgettable.com","uni.de","uni.de.de","uni.demailto.de","unican.es","unihome.com","universal.pt","uno.ee","uno.it","unofree.it","unomail.com","unterderbruecke.de","uogtritons.com","uol.com.ar","uol.com.br","uol.com.co","uol.com.mx","uol.com.ve","uole.com","uole.com.ve","uolmail.com","uomail.com","upc.nl","upcmail.nl","upf.org","upliftnow.com","uplipht.com","uraniomail.com","ureach.com","urgentmail.biz","uroid.com","us.af","usa.com","usa.net","usaaccess.net","usanetmail.com","used-product.fr","userbeam.com","usermail.com","username.e4ward.com","userzap.com","usma.net","usmc.net","uswestmail.net","uymail.com","uyuyuy.com","uzhe.net","v-sexi.com","v8email.com","vaasfc4.tk","vahoo.com","valemail.net","valudeal.net","vampirehunter.com","varbizmail.com","vcmail.com","velnet.co.uk","velnet.com","velocall.com","veloxmail.com.br","venompen.com","verizon.net","verizonmail.com","verlass-mich-nicht.de","versatel.nl","verticalheaven.com","veryfast.biz","veryrealemail.com","veryspeedy.net","vfemail.net","vickaentb.tk","videotron.ca","viditag.com","viewcastmedia.com","viewcastmedia.net","vinbazar.com","violinmakers.co.uk","vip.126.com","vip.21cn.com","vip.citiz.net","vip.gr","vip.onet.pl","vip.qq.com","vip.sina.com","vipmail.ru","viralplays.com","virgilio.it","virgin.net","virginbroadband.com.au","virginmedia.com","virtual-mail.com","virtualactive.com","virtualguam.com","virtualmail.com","visitmail.com","visitweb.com","visto.com","visualcities.com","vivavelocity.com","vivianhsu.net","viwanet.ru","vjmail.com","vjtimail.com","vkcode.ru","vlcity.ru","vlmail.com","vnet.citiz.net","vnn.vn","vnukovo.net","vodafone.nl","vodafonethuis.nl","voila.fr","volcanomail.com","vollbio.de","volloeko.de","vomoto.com","voo.be","vorsicht-bissig.de","vorsicht-scharf.de","vote-democrats.com","vote-hillary.com","vote-republicans.com","vote4gop.org","votenet.com","vovan.ru","vp.pl","vpn.st","vr9.com","vsimcard.com","vubby.com","vyhino.net","w3.to","wahoye.com","walala.org","wales2000.net","walkmail.net","walkmail.ru","walla.co.il","wam.co.za","wanaboo.com","wanadoo.co.uk","wanadoo.es","wanadoo.fr","wapda.com","war-im-urlaub.de","warmmail.com","warpmail.net","warrior.hu","wasteland.rfc822.org","watchmail.com","waumail.com","wazabi.club","wbdet.com","wearab.net","web-contact.info","web-emailbox.eu","web-ideal.fr","web-mail.com.ar","web-mail.pp.ua","web-police.com","web.de","webaddressbook.com","webadicta.org","webave.com","webbworks.com","webcammail.com","webcity.ca","webcontact-france.eu","webdream.com","webemail.me","webemaillist.com","webinbox.com","webindia123.com","webjump.com","webm4il.info","webmail.bellsouth.net","webmail.blue","webmail.co.yu","webmail.co.za","webmail.fish","webmail.hu","webmail.lawyer","webmail.ru","webmail.wiki","webmails.com","webmailv.com","webname.com","webprogramming.com","webskulker.com","webstation.com","websurfer.co.za","webtopmail.com","webtribe.net","webuser.in","wee.my","weedmail.com","weekmail.com","weekonline.com","wefjo.grn.cc","weg-werf-email.de","wegas.ru","wegwerf-emails.de","wegwerfadresse.de","wegwerfemail.com","wegwerfemail.de","wegwerfmail.de","wegwerfmail.info","wegwerfmail.net","wegwerfmail.org","wegwerpmailadres.nl","wehshee.com","weibsvolk.de","weibsvolk.org","weinenvorglueck.de","welsh-lady.com","wesleymail.com","westnet.com","westnet.com.au","wetrainbayarea.com","wfgdfhj.tk","wh4f.org","whale-mail.com","whartontx.com","whatiaas.com","whatpaas.com","wheelweb.com","whipmail.com","whoever.com","wholefitness.com","whoopymail.com","whtjddn.33mail.com","whyspam.me","wickedmail.com","wickmail.net","wideopenwest.com","wildmail.com","wilemail.com","will-hier-weg.de","willhackforfood.biz","willselfdestruct.com","windowslive.com","windrivers.net","windstream.com","windstream.net","winemaven.info","wingnutz.com","winmail.com.au","winning.com","winrz.com","wir-haben-nachwuchs.de","wir-sind-cool.org","wirsindcool.de","witty.com","wiz.cc","wkbwmail.com","wmail.cf","wo.com.cn","woh.rr.com","wolf-web.com","wolke7.net","wollan.info","wombles.com","women-at-work.org","women-only.net","wonder-net.com","wongfaye.com","wooow.it","work4teens.com","worker.com","workmail.co.za","workmail.com","worldbreak.com","worldemail.com","worldmailer.com","worldnet.att.net","wormseo.cn","wosaddict.com","wouldilie.com","wovz.cu.cc","wow.com","wowgirl.com","wowmail.com","wowway.com","wp.pl","wptamail.com","wrestlingpages.com","wrexham.net","writeme.com","writemeback.com","writeremail.com","wronghead.com","wrongmail.com","wtvhmail.com","wwdg.com","www.com","www.e4ward.com","www.mailinator.com","www2000.net","wwwnew.eu","wx88.net","wxs.net","wyrm.supernews.com","x-mail.net","x-networks.net","x.ip6.li","x5g.com","xagloo.com","xaker.ru","xd.ae","xemaps.com","xents.com","xing886.uu.gl","xmail.com","xmaily.com","xmastime.com","xmenfans.com","xms.nl","xmsg.com","xoom.com","xoommail.com","xoxox.cc","xoxy.net","xpectmore.com","xpressmail.zzn.com","xs4all.nl","xsecurity.org","xsmail.com","xtra.co.nz","xtram.com","xuno.com","xww.ro","xy9ce.tk","xyz.am","xyzfree.net","xzapmail.com","y7mail.com","ya.ru","yada-yada.com","yaho.com","yahoo.ae","yahoo.at","yahoo.be","yahoo.ca","yahoo.ch","yahoo.cn","yahoo.co","yahoo.co.id","yahoo.co.il","yahoo.co.in","yahoo.co.jp","yahoo.co.kr","yahoo.co.nz","yahoo.co.th","yahoo.co.uk","yahoo.co.za","yahoo.com","yahoo.com.ar","yahoo.com.au","yahoo.com.br","yahoo.com.cn","yahoo.com.co","yahoo.com.hk","yahoo.com.is","yahoo.com.mx","yahoo.com.my","yahoo.com.ph","yahoo.com.ru","yahoo.com.sg","yahoo.com.tr","yahoo.com.tw","yahoo.com.vn","yahoo.cz","yahoo.de","yahoo.dk","yahoo.es","yahoo.fi","yahoo.fr","yahoo.gr","yahoo.hu","yahoo.ie","yahoo.in","yahoo.it","yahoo.jp","yahoo.net","yahoo.nl","yahoo.no","yahoo.pl","yahoo.pt","yahoo.ro","yahoo.ru","yahoo.se","yahoofs.com","yahoomail.com","yalla.com","yalla.com.lb","yalook.com","yam.com","yandex.com","yandex.mail","yandex.pl","yandex.ru","yandex.ua","yapost.com","yapped.net","yawmail.com","yclub.com","yeah.net","yebox.com","yeehaa.com","yehaa.com","yehey.com","yemenmail.com","yep.it","yepmail.net","yert.ye.vc","yesbox.net","yesey.net","yeswebmaster.com","ygm.com","yifan.net","ymail.com","ynnmail.com","yogamaven.com","yogotemail.com","yomail.info","yopmail.com","yopmail.fr","yopmail.net","yopmail.org","yopmail.pp.ua","yopolis.com","yopweb.com","youareadork.com","youmailr.com","youpy.com","your-house.com","your-mail.com","yourdomain.com","yourinbox.com","yourlifesucks.cu.cc","yourlover.net","yournightmare.com","yours.com","yourssincerely.com","yourteacher.net","yourwap.com","youthfire.com","youthpost.com","youvegotmail.net","yuuhuu.net","yuurok.com","yyhmail.com","z1p.biz","z6.com","z9mail.com","za.com","zahadum.com","zaktouni.fr","zcities.com","zdnetmail.com","zdorovja.net","zeeks.com","zeepost.nl","zehnminuten.de","zehnminutenmail.de","zensearch.com","zensearch.net","zerocrime.org","zetmail.com","zhaowei.net","zhouemail.510520.org","ziggo.nl","zing.vn","zionweb.org","zip.net","zipido.com","ziplip.com","zipmail.com","zipmail.com.br","zipmax.com","zippymail.info","zmail.pt","zmail.ru","zoemail.com","zoemail.net","zoemail.org","zoho.com","zomg.info","zonai.com","zoneview.net","zonnet.nl","zooglemail.com","zoominternet.net","zubee.com","zuvio.com","zuzzurello.com","zvmail.com","zwallet.com","zweb.in","zxcv.com","zxcvbnm.com","zybermail.com","zydecofan.com","zzn.com","zzom.co.uk","zzz.com"];var Xr=a(3975);const Qr="(?:[_\\p{L}0-9][-_\\p{L}0-9]*\\.)*(?:[\\p{L}0-9][-\\p{L}0-9]{0,62})\\.(?:(?:[a-z]{2}\\.)?[a-z]{2,})",eo=class{static extractDomainFromEmail(e){const t=Qt()(`(?<=@)${Qr}`);return Qt().match(e,t)||""}static isProfessional(e){return!Jr.includes(e)}static checkDomainValidity(e){if(!Qt()(`^${Qr}$`).test(e))throw new Error("Cannot parse domain. The domain does not match the pattern.");try{if(!new URL(`https://${e}`).host)throw new Error("Cannot parse domain. The domain does not match the pattern.")}catch(e){throw new Error("Cannot parse domain. The domain is not valid.",{cause:e})}}static isValidHostname(e){return Qt()(`^${Qr}$`).test(e)||(0,Xr.A)({exact:!0}).test(e)}},to="none",ao="username",no="username_password",so="oauth",io=[Kr,Vr,Gr,Br],ro=[...new Set(io.flatMap(e=>Object.keys(e.getDefaultData())))];class oo extends he{static getSchema(){const e=$r.getSchema(),t={};for(const e of ro)for(const a of io){const n=a.getSchema().properties[e];if(n){t[e]={...n,nullable:!0};break}}return{type:"object",required:[...e.required],properties:{...e.properties,...t,provider:{type:"string",nullable:!0}}}}marshall(){if("string"==typeof this._props.port){const e=parseInt(this._props.port,10);this._props.port=isNaN(e)?this._props.port:e}}validate(e={}){this.marshall();let t=null;const a=e?.schema??this.cachedSchema;try{ae.validate(this.constructor.name,{...this._props},a)}catch(e){if(!(e instanceof X))throw e;t=e}let n=null;try{this.validateBuildRules(e?.validateBuildRules)}catch(e){if(!(e instanceof X))throw e;n=e}if(!t&&!n)return null;const s=t||new X;if(n)for(const e in n.details)if(!s.hasError(e)){const t=n.details[e];for(const a in t)s.addError(e,a,t[a])}return s}validateBuildRules(){const e=new X,t=this._props.client;if(t&&t.length>0&&(eo.isValidHostname(t)||e.addError("client","hostname","SMTP client should be a valid domain or IP address")),e.hasErrors())throw e}toFormDto(){const e={host:this._props.host??"",port:this._props.port??"",tls:this._props.tls??!0,client:this._props.client??"",sender_name:this._props.sender_name??"",sender_email:this._props.sender_email??"",provider:this._props.provider??null,source:this._props.source??null};for(const t of ro)e[t]=this._props[t]??null;return e}toApiDto(){const e=this.toDto();return delete e.provider,""===e.client&&(e.client=null),e}detectProvider(e){const t=this._props.host,a=parseInt(this._props.port,10),n=this._props.tls;for(let s=0;se.host===t&&e.port===a&&e.tls===n);if(r)return i.id}return"other"}changeAuthenticationMethod(e){const t=this._getAuthenticationEntityClass(e).getDefaultData(),a={};for(const e of ro)a[e]=this._props[e],this._props[e]=null;for(const[e,n]of Object.entries(t))null!==n&&(this._props[e]=a[e]??n)}_getAuthenticationEntityClass(e){switch(e){case to:return Kr;case ao:return Vr;case no:return Gr;case so:return Br;default:throw new Error(`Unknown authentication method: ${e}`)}}applyProviderDefaults(e){if(e.defaultConfiguration){const t=e.defaultConfiguration;void 0!==t.host&&(this._props.host=t.host),void 0!==t.port&&(this._props.port=t.port),void 0!==t.tls&&(this._props.tls=t.tls)}this._props.provider=e.id}getAuthenticationMethod(){return null!==this._props.client_id&&void 0!==this._props.client_id?so:null===this._props.username||void 0===this._props.username?to:null===this._props.password||void 0===this._props.password?ao:no}static createDefault(){return new oo({host:"",port:"",tls:!0,client:"",sender_email:"",sender_name:"Passbolt",...Gr.getDefaultData()},{validate:!1})}static get ENTITY_NAME(){return"SmtpSettingsForm"}static get AUTHENTICATION_METHOD_NONE(){return to}static get AUTHENTICATION_METHOD_USERNAME(){return ao}static get AUTHENTICATION_METHOD_USERNAME_PASSWORD(){return no}static get AUTHENTICATION_METHOD_OAUTH(){return so}static get AUTH_FIELDS(){return ro}}const lo=oo;class co extends sa{constructor(e){super(e,co.RESOURCE_NAME)}static get RESOURCE_NAME(){return"smtp/email"}async create(e){this.assertNonEmptyData(e);const t=await this.apiClient.create(e);return new oa(t)}}const mo=co,uo=class{constructor(e){this.smtpTestSettingsApiService=new mo(e)}async send(e,t){const a=e.toDto();return a.email_test_to=t,(await this.smtpTestSettingsApiService.create(a)).body}};var po=a(1811);function ho(){return ho=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},findSmtpSettings:()=>{},changeProvider:()=>{},changeAuthenticationMethod:()=>{},getAuthenticationMethod:()=>{},setData:()=>{},isSettingsModified:()=>{},isSettingsValid:()=>{},getErrors:()=>{},validateData:()=>{},getFieldToFocus:()=>{},saveSmtpSettings:()=>{},isProcessing:()=>{},hasProviderChanged:()=>{},sendTestMailTo:()=>{},isDataReady:()=>{},clearContext:()=>{}});class yo extends n.Component{constructor(e){super(e),this.state=this.defaultState;const t=e.context.getApiClientOptions();this.findSmtpSettingsService=new Yr(t),this.saveSmtpSettingsService=new Zr(t),this.sendTestSmtpSettingsService=new uo(t),this.fieldToFocus=null,this.providerHasChanged=!1,this.originalSettings=null,this.formSettings=null}get defaultState(){return{settings:{},isLoaded:!1,processing:!1,hasAlreadyBeenValidated:!1,getCurrentSmtpSettings:this.getCurrentSmtpSettings.bind(this),findSmtpSettings:this.findSmtpSettings.bind(this),changeProvider:this.changeProvider.bind(this),changeAuthenticationMethod:this.changeAuthenticationMethod.bind(this),getAuthenticationMethod:this.getAuthenticationMethod.bind(this),setData:this.setData.bind(this),isSettingsModified:this.isSettingsModified.bind(this),getErrors:this.getErrors.bind(this),validateData:this.validateData.bind(this),getFieldToFocus:this.getFieldToFocus.bind(this),saveSmtpSettings:this.saveSmtpSettings.bind(this),isProcessing:this.isProcessing.bind(this),hasProviderChanged:this.hasProviderChanged.bind(this),sendTestMailTo:this.sendTestMailTo.bind(this),isDataReady:this.isDataReady.bind(this),clearContext:this.clearContext.bind(this)}}validateForm=(0,po.A)(e=>this.formSettings?.validate({validateBuildRules:{siteSettings:this.props.context.siteSettings}}));hasSettingsChanges=(0,po.A)((e,t)=>this.originalSettings?.hasDiffProps(this.formSettings)||!1);async findSmtpSettings(){if(!this.props.context.siteSettings.canIUse("smtpSettings"))return null;let e;try{e=(await this.findSmtpSettingsService.find()).toDto(),e.client=e.client??"",e.username=e.username??null,e.password=e.password??null}catch(t){this.handleError(t),e=lo.createDefault().toFormDto()}e.sender_email=e.sender_email??this.props.context.loggedInUser.username,this.originalSettings=new lo(e,{validate:!1});const t=this.originalSettings.toFormDto();if(t.host&&t.port){const e=this.originalSettings.detectProvider(Lr);this.originalSettings.set("provider",e,{validate:!1})}this.formSettings=new lo(this.originalSettings.toDto(),{validate:!1}),this.setState({settings:this.formSettings.toFormDto(),isLoaded:!0})}clearContext(){this.originalSettings=null,this.formSettings=null;const{settings:e,isLoaded:t,processing:a,hasAlreadyBeenValidated:n}=this.defaultState;this.setState({settings:e,isLoaded:t,processing:a,hasAlreadyBeenValidated:n})}async saveSmtpSettings(){this.setState({processing:!0});try{const e=this.formSettings.toApiDto(),t=$r.createFromSettings(e);await this.saveSmtpSettingsService.save(t),this.props.actionFeedbackContext.displaySuccess(this.props.t("The SMTP settings have been saved successfully")),this.originalSettings=new lo(this.formSettings.toDto(),{validate:!1}),this.setState({settings:this.formSettings.toFormDto()})}catch(e){this.handleError(e)}finally{this.setState({processing:!1})}}async sendTestMailTo(e){const t=this.formSettings.toApiDto(),a=$r.createFromSettings(t);return await this.sendTestSmtpSettingsService.send(a,e)}hasProviderChanged(){const e=this.providerHasChanged;return this.providerHasChanged=!1,e}changeAuthenticationMethod(e){this.formSettings.changeAuthenticationMethod(e);const t=this.formSettings.detectProvider(Lr);this.formSettings.set("provider",t,{validate:!1}),this.setState({settings:this.formSettings.toFormDto()}),this.state.hasAlreadyBeenValidated&&this.validateData({setFocus:!1})}getAuthenticationMethod(){return this.formSettings?.getAuthenticationMethod()??null}changeProvider(e){const t=this.formSettings?.toFormDto()?.provider;e.id!==t&&(this.providerHasChanged=!0,this.formSettings.applyProviderDefaults(e),"office-365"!==e.id&&this.formSettings.getAuthenticationMethod()===lo.AUTHENTICATION_METHOD_OAUTH&&this.formSettings.changeAuthenticationMethod(lo.AUTHENTICATION_METHOD_USERNAME_PASSWORD),this.setState({settings:this.formSettings.toFormDto()}))}setData(e){for(const t in e)this.formSettings.set(t,e[t],{validate:!1});const t=this.formSettings.detectProvider(Lr);this.formSettings.set("provider",t,{validate:!1}),"office-365"!==t&&this.formSettings.getAuthenticationMethod()===lo.AUTHENTICATION_METHOD_OAUTH&&this.formSettings.changeAuthenticationMethod(lo.AUTHENTICATION_METHOD_USERNAME_PASSWORD),this.setState({settings:this.formSettings.toFormDto()}),this.state.hasAlreadyBeenValidated&&this.validateData({setFocus:!1})}isDataReady(){return this.state.isLoaded}isProcessing(){return this.state.processing}isSettingsModified(){return this.hasSettingsChanges(this.originalSettings?.toFormDto(),this.formSettings?.toFormDto())}getErrors(){return this.state.hasAlreadyBeenValidated?this.validateForm(this.state.settings):null}validateData({setFocus:e=!0}={}){const t=this.validateForm(this.state.settings),a=!t;if(!a&&e){const e=["username","password","oauth_username","tenant_id","client_id","client_secret","host","tls","port","client","sender_name","sender_email"];this.fieldToFocus=e.find(e=>t.hasError(e))}return this.setState({hasAlreadyBeenValidated:!0}),a}getCurrentSmtpSettings(){return this.state.settings}getFieldToFocus(){const e=this.fieldToFocus;return this.fieldToFocus=null,e}handleError(e){console.error(e),this.props.dialogContext.open($t,{error:e})}render(){return n.createElement(go.Provider,{value:this.state},this.props.children)}}yo.propTypes={context:i().any,dialogContext:i().object,actionFeedbackContext:i().object,children:i().any,t:i().func};const bo=N(h(m((0,f.CI)("common")(yo))));function fo(e){return class extends n.Component{render(){return n.createElement(go.Consumer,null,t=>n.createElement(e,ho({adminSmtpSettingsContext:t},this.props)))}}}const Eo="form",vo="error",wo="success";class ko extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.bindCallbacks()}get defaultState(){return{uiState:Eo,recipient:this.props.context.loggedInUser.username,processing:!1,displayLogs:!0}}bindCallbacks(){this.handleRetryClick=this.handleRetryClick.bind(this),this.handleError=this.handleError.bind(this),this.handleFormSubmit=this.handleFormSubmit.bind(this),this.handleInputChange=this.handleInputChange.bind(this),this.handleDisplayLogsClick=this.handleDisplayLogsClick.bind(this)}async handleFormSubmit(e){if(e.preventDefault(),this.validateForm()){try{this.setState({processing:!0});const e=await this.props.adminSmtpSettingsContext.sendTestMailTo(this.state.recipient);this.setState({uiState:wo,debugDetails:this.formatDebug(e.debug),displayLogs:!1})}catch(e){this.handleError(e)}this.setState({processing:!1})}}async handleInputChange(e){this.setState({recipient:e.target.value})}validateForm(){const e=nr.validate(this.state.recipient,this.props.context.siteSettings);return this.setState({recipientError:e?"":this.translate("Recipient must be a valid email")}),e}formatDebug(e){return JSON.stringify(e,null,4)}handleError(e){const t=e.data?.body?.debug,a=t?.length>0?t:e?.message;this.setState({uiState:vo,debugDetails:this.formatDebug(a),displayLogs:!0})}handleDisplayLogsClick(){this.setState({displayLogs:!this.state.displayLogs})}handleRetryClick(){this.setState({uiState:Eo})}hasAllInputDisabled(){return this.state.processing}get title(){return{form:this.translate("Send test email"),error:this.translate("Something went wrong!"),success:this.translate("Email sent")}[this.state.uiState]||""}get translate(){return this.props.t}render(){return n.createElement(qt,{className:"send-test-email-dialog",title:this.title,onClose:this.props.handleClose,disabled:this.hasAllInputDisabled()},this.state.uiState===Eo&&n.createElement("form",{onSubmit:this.handleFormSubmit,noValidate:!0},n.createElement("div",{className:"form-content"},n.createElement("div",{className:`input text required ${this.state.recipientError?"error":""} ${this.hasAllInputDisabled()?"disabled":""}`},n.createElement("label",null,n.createElement(f.x6,null,"Recipient")),n.createElement("input",{id:"recipient",type:"text",name:"recipient",required:"required",className:"required fluid form-element ready",placeholder:"name@email.com",onChange:this.handleInputChange,value:this.state.recipient,disabled:this.hasAllInputDisabled()}),this.state.recipientError&&n.createElement("div",{className:"recipient error-message"},this.state.recipientError)),n.createElement("div",{className:"message notice no-margin"},n.createElement("strong",null,n.createElement(f.x6,null,"Pro tip"),":")," ",n.createElement(f.x6,null,"after clicking on send, a test email will be sent to the recipient email in order to check that your configuration is correct."))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement(gn,{disabled:this.hasAllInputDisabled(),onClick:this.props.handleClose}),n.createElement(qs,{disabled:this.hasAllInputDisabled(),processing:this.state.processing,value:this.translate("Send")}))),this.state.uiState===vo&&n.createElement(n.Fragment,null,n.createElement("div",{className:"dialog-body"},n.createElement("p",null,n.createElement(f.x6,null,"The test email could not be sent. Kindly check the logs below for more information."),n.createElement("br",null),n.createElement("a",{className:"faq-link",href:"https://www.passbolt.com/docs/hosting/troubleshooting/email",rel:"noopener noreferrer",target:"_blank"},n.createElement(f.x6,null,"FAQ: Why are my emails not sent?"))),n.createElement("div",{className:"accordion-header"},n.createElement("button",{type:"button",className:"link no-border",onClick:this.handleDisplayLogsClick},n.createElement("span",null,n.createElement(f.x6,null,"Logs")),this.state.displayLogs?n.createElement(Vt,{className:"baseline svg-icon"}):n.createElement(Wt,{className:"baseline svg-icon"}))),this.state.displayLogs&&n.createElement("div",{className:"accordion-content"},n.createElement("textarea",{className:"full_report",readOnly:!0,value:this.state.debugDetails}))),n.createElement("div",{className:"dialog-footer clearfix"},n.createElement("button",{type:"button",className:"cancel",disabled:this.hasAllInputDisabled(),onClick:this.handleRetryClick},n.createElement(f.x6,null,"Retry")),n.createElement("button",{className:"button primary",type:"button",onClick:this.props.handleClose,disabled:this.isProcessing},n.createElement("span",null,n.createElement(f.x6,null,"Close"))))),this.state.uiState===wo&&n.createElement(n.Fragment,null,n.createElement("div",{className:"dialog-body"},n.createElement("p",null,n.createElement(f.x6,null,"The test email has been sent. Check your email box, you should receive it in a minute.")),n.createElement("div",{className:"accordion-header"},n.createElement("button",{type:"button",className:"link no-border",onClick:this.handleDisplayLogsClick},n.createElement("span",null,n.createElement(f.x6,null,"Logs")),this.state.displayLogs?n.createElement(Vt,{className:"baseline svg-icon"}):n.createElement(Wt,{className:"baseline svg-icon"}))),this.state.displayLogs&&n.createElement("div",{className:"accordion-content"},n.createElement("textarea",{className:"full_report",readOnly:!0,value:this.state.debugDetails})),n.createElement("div",{className:"message notice no-margin"},n.createElement("strong",null,n.createElement(f.x6,null,"Pro tip"),":")," ",n.createElement(f.x6,null,"Check your spam folder if you do not hear from us after a while."))),n.createElement("div",{className:"dialog-footer clearfix"},n.createElement("button",{type:"button",className:"cancel",disabled:this.hasAllInputDisabled(),onClick:this.handleRetryClick},n.createElement(f.x6,null,"Retry")),n.createElement("button",{className:"button primary",type:"button",onClick:this.props.handleClose,disabled:this.isProcessing},n.createElement("span",null,n.createElement(f.x6,null,"Close"))))))}}ko.propTypes={context:i().object,adminSmtpSettingsContext:i().object,handleClose:i().func,t:i().func};const _o=N(fo((0,f.CI)("common")(ko)));var xo,So;function Co(){return Co=Object.assign?Object.assign.bind():function(e){for(var t=1;te.id===t);this.props.adminSmtpSettingsContext.changeProvider(a)}handleAuthenticationMethodChange(e){this.props.adminSmtpSettingsContext.changeAuthenticationMethod(e.target.value)}handleInputChange(e){const t=e.target;this.props.adminSmtpSettingsContext.setData({[t.name]:t.value})}handleAdvancedSettingsToggle(){this.setState({showAdvancedSettings:!this.state.showAdvancedSettings})}isProcessing(){return this.props.adminSmtpSettingsContext.isProcessing()}get providerList(){return Lr.map(e=>({value:e.id,label:e.name}))}get authenticationMethodList(){const e=this.props.adminSmtpSettingsContext.getCurrentSmtpSettings(),t=[{value:Do,label:this.translate("None")},{value:Oo,label:this.translate("Username only")},{value:Mo,label:this.translate("Username & password")}];return"office-365"===e?.provider&&t.push({value:Uo,label:this.translate("OAuth (Client Credentials Grant)")}),t}get tlsSelectList(){return[{value:!0,label:this.translate("Yes")},{value:!1,label:this.translate("No")}]}get authenticationMethod(){return this.props.adminSmtpSettingsContext.getAuthenticationMethod()}shouldDisplayUsername(){return this.authenticationMethod===Oo||this.authenticationMethod===Mo}shouldDisplayPassword(){return this.authenticationMethod===Mo}shouldDisplayOAuth(){return this.authenticationMethod===Uo}shouldShowSourceWarningMessage(){const e=this.props.adminSmtpSettingsContext;return"db"!==e.getCurrentSmtpSettings().source&&e.isSettingsModified()}isReady(){return this.props.adminSmtpSettingsContext.isDataReady()}get settingsSource(){return this.props.adminSmtpSettingsContext?.getCurrentSmtpSettings()?.source}get configurationSource(){return{env:this.props.t("environment variables"),file:this.props.t("file"),db:this.props.t("database")}[this.settingsSource]||this.props.t("unknown")}get translate(){return this.props.t}render(){const e=this.props.adminSmtpSettingsContext.getCurrentSmtpSettings(),t=this.props.adminSmtpSettingsContext.getErrors(),a=Lr.find(t=>t.id===e?.provider),s=a?.name,i=this.props.adminSmtpSettingsContext.isSettingsModified(),r=i||this.shouldShowSourceWarningMessage();return n.createElement("div",{className:"row"},n.createElement(n.Fragment,null,n.createElement("div",{className:"third-party-provider-settings smtp-settings main-column"},n.createElement("div",{className:"main-content"},n.createElement("h3",{className:"title"},n.createElement(f.x6,null,"Email server")),this.isReady()&&!e?.provider&&n.createElement(n.Fragment,null,n.createElement("h4",{className:"no-border"},n.createElement(f.x6,null,"Select a provider")),n.createElement("div",{className:"provider-list"},Lr.map(e=>n.createElement("div",{key:e.id,className:"provider button",id:e.id,onClick:()=>this.props.adminSmtpSettingsContext.changeProvider(e)},n.createElement("div",{className:"provider-logo"},"other"===e.id&&n.createElement(Qs,null),"other"!==e.id&&n.createElement("img",{src:`${this.props.context.trustedDomain}/img/third_party/${e.icon}`})),n.createElement("p",{className:"provider-name"},e.name))))),this.isReady()&&e?.provider&&n.createElement(n.Fragment,null,n.createElement("form",{className:"form"},n.createElement("h4",{className:"no-border"},n.createElement(f.x6,null,"SMTP server configuration")),n.createElement("div",{className:"select-wrapper input required "+(this.isProcessing()?"disabled":"")},n.createElement("label",{htmlFor:"smtp-settings-form-provider"},n.createElement(f.x6,null,"Email provider")),n.createElement(pn,{id:"smtp-settings-form-provider",name:"provider",items:this.providerList,value:e.provider,onChange:this.handleProviderChange,disabled:this.isProcessing()})),n.createElement("div",{className:"select-wrapper input required "+(this.isProcessing()?"disabled":"")},n.createElement("label",{htmlFor:"smtp-settings-form-authentication-method"},n.createElement(f.x6,null,"Authentication method")),n.createElement(pn,{id:"smtp-settings-form-authentication-method",name:"authentication-method",items:this.authenticationMethodList,value:this.authenticationMethod,onChange:this.handleAuthenticationMethodChange,disabled:this.isProcessing()})),this.shouldDisplayUsername()&&n.createElement("div",{className:`input text ${t?.hasError("username")?"error":""} ${this.isProcessing()?"disabled":""}`},n.createElement("label",{htmlFor:"smtp-settings-form-username"},n.createElement(f.x6,null,"Username")),n.createElement("input",{id:"smtp-settings-form-username",ref:this.usernameFieldRef,name:"username",className:"fluid",maxLength:"256",type:"text",autoComplete:"off",value:e.username,onChange:this.handleInputChange,placeholder:this.translate("Username"),disabled:this.isProcessing()}),t?.hasError("username")&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"This is the maximum size for this field, make sure your data was not truncated."))),this.shouldDisplayPassword()&&n.createElement("div",{className:`input-password-wrapper input ${t?.hasError("password")?"error":""} ${this.isProcessing()?"disabled":""}`},n.createElement("label",{htmlFor:"smtp-settings-form-password"},n.createElement(f.x6,null,"Password")),n.createElement(Za,{id:"smtp-settings-form-password",name:"password",autoComplete:"new-password",placeholder:this.translate("Password"),preview:!0,value:e.password,onChange:this.handleInputChange,disabled:this.isProcessing(),inputRef:this.passwordFieldRef}),t?.hasError("password")&&n.createElement("div",{className:"password error-message"},n.createElement(f.x6,null,"This is the maximum size for this field, make sure your data was not truncated."))),this.shouldDisplayOAuth()&&n.createElement(n.Fragment,null,n.createElement("div",{className:`input text required ${t?.hasError("oauth_username")?"error":""} ${this.isProcessing()?"disabled":""}`},n.createElement("label",{htmlFor:"smtp-settings-form-oauth-username"},n.createElement(f.x6,null,"OAuth Username")),n.createElement("input",{id:"smtp-settings-form-oauth-username",ref:this.oauth_usernameFieldRef,name:"oauth_username","aria-required":!0,className:"fluid",maxLength:"256",type:"text",autoComplete:"off",value:e.oauth_username,onChange:this.handleInputChange,placeholder:this.translate("OAuth Username"),disabled:this.isProcessing()}),t?.hasError("oauth_username")&&n.createElement("div",{className:"error-message"},!e.oauth_username||t.hasError("oauth_username","required")?n.createElement(f.x6,null,"OAuth Username is required."):n.createElement(f.x6,null,"OAuth Username must be a valid email."))),n.createElement("div",{className:`input text required ${t?.hasError("tenant_id")?"error":""} ${this.isProcessing()?"disabled":""}`},n.createElement("label",{htmlFor:"smtp-settings-form-tenant-id"},n.createElement(f.x6,null,"Tenant ID")),n.createElement("input",{id:"smtp-settings-form-tenant-id",ref:this.tenant_idFieldRef,name:"tenant_id","aria-required":!0,className:"fluid",maxLength:"256",type:"text",autoComplete:"off",value:e.tenant_id,onChange:this.handleInputChange,placeholder:this.translate("Tenant ID"),disabled:this.isProcessing()}),t?.hasError("tenant_id")&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"Tenant ID is required."))),n.createElement("div",{className:`input text required ${t?.hasError("client_id")?"error":""} ${this.isProcessing()?"disabled":""}`},n.createElement("label",{htmlFor:"smtp-settings-form-client-id"},n.createElement(f.x6,null,"Client ID")),n.createElement("input",{id:"smtp-settings-form-client-id",ref:this.client_idFieldRef,name:"client_id","aria-required":!0,className:"fluid",maxLength:"256",type:"text",autoComplete:"off",value:e.client_id,onChange:this.handleInputChange,placeholder:this.translate("Client ID"),disabled:this.isProcessing()}),t?.hasError("client_id")&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"Client ID is required."))),n.createElement("div",{className:`input-password-wrapper input required ${t?.hasError("client_secret")?"error":""} ${this.isProcessing()?"disabled":""}`},n.createElement("label",{htmlFor:"smtp-settings-form-client-secret"},n.createElement(f.x6,null,"Client Secret")),n.createElement(Za,{id:"smtp-settings-form-client-secret",name:"client_secret",autoComplete:"new-password",placeholder:this.translate("Client Secret"),preview:!0,value:e.client_secret,onChange:this.handleInputChange,disabled:this.isProcessing(),inputRef:this.client_secretFieldRef}),t?.hasError("client_secret")&&n.createElement("div",{className:"password error-message"},n.createElement(f.x6,null,"Client Secret is required.")))),n.createElement("div",{className:"accordion-header"},n.createElement("button",{type:"button",className:"link no-border",onClick:this.handleAdvancedSettingsToggle},this.state.showAdvancedSettings?n.createElement(Vt,null):n.createElement(Wt,null),n.createElement(f.x6,null,"Advanced settings"))),this.state.showAdvancedSettings&&n.createElement("div",{className:"advanced-settings"},n.createElement("div",{className:`input text required ${t?.hasError("host")?"error":""} ${this.isProcessing()?"disabled":""}`},n.createElement("label",{htmlFor:"smtp-settings-form-host"},n.createElement(f.x6,null,"SMTP host")),n.createElement("input",{id:"smtp-settings-form-host",ref:this.hostFieldRef,name:"host","aria-required":!0,className:"fluid",maxLength:"256",type:"text",autoComplete:"off",value:e.host,onChange:this.handleInputChange,placeholder:this.translate("SMTP server address"),disabled:this.isProcessing()}),t?.hasError("host")&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"SMTP Host is required"))),n.createElement("div",{className:`input text required ${t?.hasError("tls")?"error":""} ${this.isProcessing()?"disabled":""}`},n.createElement("label",{htmlFor:"smtp-settings-form-tls"},n.createElement(f.x6,null,"Use TLS")),n.createElement(pn,{id:"smtp-settings-form-tls",name:"tls",items:this.tlsSelectList,value:e.tls,onChange:this.handleInputChange,disabled:this.isProcessing()}),t?.hasError("tls")&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"TLS must be set to 'Yes' or 'No'"))),n.createElement("div",{className:`input text required ${t?.hasError("port")?"error":""} ${this.isProcessing()?"disabled":""}`},n.createElement("label",{htmlFor:"smtp-settings-form-port"},n.createElement(f.x6,null,"Port")),n.createElement("input",{id:"smtp-settings-form-port","aria-required":!0,ref:this.portFieldRef,name:"port",className:"fluid",maxLength:"256",type:"text",autoComplete:"off",value:e.port,onChange:this.handleInputChange,placeholder:this.translate("Port number"),disabled:this.isProcessing()}),t?.hasError("port")&&n.createElement("div",{className:"error-message"},t.hasError("port","minimum")||t.hasError("port","maximum")?n.createElement(f.x6,null,"Port must be a number between 1 and 65535"):n.createElement(f.x6,null,"Port must be a valid number"))),n.createElement("div",{className:`input text ${t?.hasError("client")?"error":""} ${this.isProcessing()?"disabled":""}`},n.createElement("label",{htmlFor:"smtp-settings-form-client"},n.createElement(f.x6,null,"SMTP client")),n.createElement("input",{id:"smtp-settings-form-client",ref:this.clientFieldRef,name:"client",maxLength:"2048",type:"text",autoComplete:"off",value:e.client,onChange:this.handleInputChange,placeholder:this.translate("SMTP client address"),disabled:this.isProcessing()}),t?.hasError("client")&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"SMTP client should be a valid domain or IP address")))),n.createElement("h4",null,n.createElement(f.x6,null,"Sender configuration")),n.createElement("div",{className:`input text required ${t?.hasError("sender_name")?"error":""} ${this.isProcessing()?"disabled":""}`},n.createElement("label",{htmlFor:"smtp-settings-form-sender-name"},n.createElement(f.x6,null,"Sender name")),n.createElement("input",{id:"smtp-settings-form-sender-name",ref:this.senderNameFieldRef,name:"sender_name","aria-required":!0,className:"fluid",maxLength:"256",type:"text",autoComplete:"off",value:e.sender_name,onChange:this.handleInputChange,placeholder:this.translate("Sender name"),disabled:this.isProcessing()}),t?.hasError("sender_name")&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"Sender name is required")),n.createElement("p",null,n.createElement(f.x6,null,"This is the name users will see in their mailbox when passbolt sends a notification."))),n.createElement("div",{className:`input text required ${t?.hasError("sender_email")?"error":""} ${this.isProcessing()?"disabled":""}`},n.createElement("label",{htmlFor:"smtp-settings-form-sender-name"},n.createElement(f.x6,null,"Sender email")),n.createElement("input",{id:"smtp-settings-form-sender-email",ref:this.senderEmailFieldRef,name:"sender_email","aria-required":!0,className:"fluid",maxLength:"256",type:"text",autoComplete:"off",value:e.sender_email,onChange:this.handleInputChange,placeholder:this.translate("Sender email"),disabled:this.isProcessing()}),t?.hasError("sender_email")&&n.createElement("div",{className:"error-message"},!e.sender_email||t.hasError("sender_email","required")?n.createElement(f.x6,null,"Sender email is required"):n.createElement(f.x6,null,"Sender email must be a valid email")),n.createElement("p",null,n.createElement(f.x6,null,"This is the email address users will see in their mail box when passbolt sends a notification.",n.createElement("br",null),"It's a good practice to provide a working email address that users can reply to.")))))),r&&n.createElement("div",{className:"warning message"},this.shouldShowSourceWarningMessage()&&n.createElement("div",{id:"smtp-settings-source-warning"},n.createElement(f.x6,null,"These are the settings provided by a configuration file. If you save it, will ignore the settings on file and use the ones from the database.")),i&&n.createElement("div",null,n.createElement("p",null,n.createElement(f.x6,null,"Don't forget to save your settings to apply your modification."))))),n.createElement(Ao,null)),Xa(n.createElement(n.Fragment,null,n.createElement("div",{className:"sidebar-help-section",id:"smtp-settings-source"},n.createElement("h3",null,n.createElement(f.x6,null,"Configuration source")),n.createElement("p",null,n.createElement(f.x6,null,"This current configuration source is: "),this.configurationSource,".")),n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"Why do I need an SMTP server?")),n.createElement("p",null,n.createElement(f.x6,null,"Passbolt needs an smtp server in order to send invitation emails after an account creation and to send email notifications.")),n.createElement("a",{className:"button",href:"https://passbolt.com/docs/admin/emails/email-server/",target:"_blank",rel:"noopener noreferrer"},n.createElement(ps,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),a&&"other"!==a.id&&n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"How do I configure a ",{smtpProviderName:s}," SMTP server?")),n.createElement("a",{className:"button",href:a.help_page,target:"_blank",rel:"noopener noreferrer"},n.createElement(Po,null),n.createElement("span",null,n.createElement(f.x6,null,"See the ",{smtpProviderName:s}," documentation")))),e?.provider&&("google-mail"===e.provider||"google-workspace"===e.provider)&&n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"Why shouldn't I use my login password ?")),n.createElement("p",null,n.createElement(f.x6,null,'In order to use the "Username & Password" authentication method with Google, you will need to enable MFA on your Google Account. The password should not be your login password, you have to create an "App Password" generated by Google.. However, the email remain the same.')),n.createElement("a",{className:"button",href:"https://support.google.com/mail/answer/185833",target:"_blank",rel:"noopener noreferrer"},n.createElement(ps,null),n.createElement("span",null,n.createElement(f.x6,null,"More informations"))))),document.getElementById("administration-help-panel")))}}Fo.propTypes={context:i().object,dialogContext:i().any,administrationWorkspaceContext:i().object,adminSmtpSettingsContext:i().object,t:i().func};const jo=N(fo(h(Ne((0,f.CI)("common")(Fo))))),Lo=class{static clone(e){return new Map(JSON.parse(JSON.stringify(Array.from(e))))}static iterators(e){return[...e.keys()]}static listValues(e){return[...e.values()]}},qo=class{constructor(e){this.apiClientOptions=e}async find(){this.initClient();const e=await this.apiClient.findAll(),t=e?.body;return t}async save(e){this.initClient(),await this.apiClient.create(e)}async delete(e){this.initClient(),await this.apiClient.delete(e)}async checkDomainAllowed(e){this.initClient("dry-run"),await this.apiClient.create(e)}initClient(e="settings"){this.apiClientOptions.setResourceName(`self-registration/${e}`),this.apiClient=new pt(this.apiClientOptions)}},zo=class{constructor(e={}){this.allowedDomains=this.mapAllowedDomains(e.data?.allowed_domains||[])}mapAllowedDomains(e){return new Map(e.map(e=>[(0,r.A)(),e]))}getSettings(){return this.allowedDomains}setSettings(e){this.allowedDomains=this.mapAllowedDomains(e)}},Ko=class{constructor(e,t={}){this.id=t.id,this.provider=t.provider||"email_domains",this.data=this.mapData(e?.allowedDomains)}mapData(e=new Map){return{allowed_domains:Array.from(e.values())}}},Vo=class{constructor(e){this.translate=e,this.fields=new Map}validate(e){return this.fields=e,this.validateInputs()}validateInputs(){const e=new Map;return this.fields.forEach((t,a)=>{this.validateInput(a,t,e)}),e}validateInput(e,t,a){if(t.length)try{eo.checkDomainValidity(t)}catch{a.set(e,this.translate("This should be a valid domain"))}else a.set(e,this.translate("A domain is required."));this.checkDuplicateValue(a)}checkDuplicateValue(e){this.fields.forEach((t,a)=>{Lo.listValues(this.fields).filter(e=>e===t&&""!==e).length>1&&e.set(a,this.translate("This domain already exist"))})}};class Go extends n.Component{constructor(e){super(e),this.bindCallbacks()}bindCallbacks(){this.handleSubmit=this.handleSubmit.bind(this),this.handleClose=this.handleClose.bind(this)}handleClose(){this.props.onClose()}async handleSubmit(e){e.preventDefault(),await this.props.onSubmit(),this.props.onClose()}get allowedDomains(){return this.props.adminSelfRegistrationContext.getAllowedDomains()}render(){const e=this.props.adminSelfRegistrationContext.isProcessing();return n.createElement(qt,{title:this.props.t("Save self registration settings"),onClose:this.handleClose,disabled:e,className:"save-self-registration-settings-dialog"},n.createElement("form",{onSubmit:this.handleSubmit},n.createElement("div",{className:"form-content"},n.createElement("label",null,n.createElement(f.x6,null,"Allowed domains")),n.createElement("div",{className:"radiolist-alt"},n.createElement("div",{className:"input radio"},n.createElement("ul",{id:"domains-list"},this.allowedDomains&&Lo.iterators(this.allowedDomains).map(e=>n.createElement("li",{key:e},this.allowedDomains.get(e)))))),n.createElement("div",{className:"warning message no-margin"},n.createElement(f.x6,null,"Please review carefully this configuration."))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement(gn,{onClick:this.handleClose,disabled:e}),n.createElement(qs,{value:this.props.t("Save"),disabled:e,processing:e,warning:!0}))))}}Go.propTypes={context:i().any,onSubmit:i().func,adminSelfRegistrationContext:i().object,onClose:i().func,t:i().func};const Bo=N(Xo((0,f.CI)("common")(Go)));class Wo extends n.Component{constructor(e){super(e),this.bindCallbacks()}bindCallbacks(){this.handleSubmit=this.handleSubmit.bind(this),this.handleClose=this.handleClose.bind(this)}handleClose(){this.props.onClose()}async handleSubmit(e){e.preventDefault(),await this.props.onSubmit(),this.props.onClose()}render(){const e=this.props.adminSelfRegistrationContext.isProcessing();return n.createElement(qt,{title:this.props.t("Disable self registration"),onClose:this.handleClose,disabled:e,className:"delete-self-registration-settings-dialog"},n.createElement("form",{onSubmit:this.handleSubmit},n.createElement("div",{className:"form-content"},n.createElement("div",null,n.createElement("p",null,n.createElement(f.x6,null,"Are you sure to disable the self registration for the organization ?")),n.createElement("p",null,n.createElement(f.x6,null,"Users will not be able to self register anymore.")," ",n.createElement(f.x6,null,"Only administrators would be able to invite users to register. ")))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement(gn,{onClick:this.handleClose,disabled:e}),n.createElement(qs,{value:this.props.t("Save"),disabled:e,processing:e,warning:!0}))))}}Wo.propTypes={adminSelfRegistrationContext:i().object,onClose:i().func,onSubmit:i().func,t:i().func};const Ho=Xo((0,f.CI)("common")(Wo));function $o(){return $o=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},getAllowedDomains:()=>{},setAllowedDomains:()=>{},hasSettingsChanges:()=>{},setDomains:()=>{},findSettings:()=>{},setProcessing:()=>{},isProcessing:()=>{},clearContext:()=>{},isSubmitted:()=>{},setSubmitted:()=>{},setErrors:()=>{},getErrors:()=>{},setError:()=>{},save:()=>{},delete:()=>{},shouldFocus:()=>{},setFocus:()=>{},isSaved:()=>{},setSaved:()=>{},validateForm:()=>{}});class Zo extends n.Component{constructor(e){super(e),this.state=this.defaultState;const t=e.context.getApiClientOptions();this.selfRegistrationService=new qo(t),this.selfRegistrationFormService=new Vo(this.props.t)}get defaultState(){return{errors:new Map,submitted:!1,currentSettings:null,focus:!1,saved:!1,domains:new zo,processing:!0,getCurrentSettings:this.getCurrentSettings.bind(this),getAllowedDomains:this.getAllowedDomains.bind(this),setAllowedDomains:this.setAllowedDomains.bind(this),setDomains:this.setDomains.bind(this),findSettings:this.findSettings.bind(this),hasSettingsChanges:this.hasSettingsChanges.bind(this),isProcessing:this.isProcessing.bind(this),setProcessing:this.setProcessing.bind(this),clearContext:this.clearContext.bind(this),isSubmitted:this.isSubmitted.bind(this),setSubmitted:this.setSubmitted.bind(this),getErrors:this.getErrors.bind(this),setError:this.setError.bind(this),setErrors:this.setErrors.bind(this),save:this.save.bind(this),shouldFocus:this.shouldFocus.bind(this),setFocus:this.setFocus.bind(this),isSaved:this.isSaved.bind(this),setSaved:this.setSaved.bind(this),deleteSettings:this.deleteSettings.bind(this),validateForm:this.validateForm.bind(this)}}async findSettings(e=()=>{}){this.setProcessing(!0);const t=await this.selfRegistrationService.find();this.setState({currentSettings:t});const a=new zo(t);return this.setDomains(a,e),this.setProcessing(!1),a}getCurrentSettings(){return this.state.currentSettings}getAllowedDomains(){return this.state.domains.allowedDomains}setAllowedDomains(e,t,a=()=>{}){this.setState(a=>{const n=Lo.clone(a.domains.allowedDomains);return n.set(e,t),{domains:{allowedDomains:n}}},a)}setDomains(e,t=()=>{}){this.setState({domains:e},t)}isProcessing(){return this.state.processing}setProcessing(e){this.setState({processing:e})}isSubmitted(){return this.state.submitted}setSubmitted(e){this.setState({submitted:e}),this.setFocus(e)}getErrors(){return this.state.errors}shouldFocus(){return this.state.focus}setFocus(e){this.setState({focus:e})}setError(e,t){const a=Lo.clone(this.state.errors);a.set(e,t),this.setState({errors:a})}setErrors(e){this.setState({errors:e})}hasSettingsChanges(){const e=this.state.currentSettings?.data?.allowed_domains||[],t=Lo.listValues(this.state.domains.allowedDomains);return JSON.stringify(e)!==JSON.stringify(t)}clearContext(){const{currentSettings:e,domains:t,processing:a}=this.defaultState;this.setState({currentSettings:e,domains:t,processing:a})}save(){this.setSubmitted(!0),this.validateForm()&&(this.hasSettingsChanges()&&0===this.getAllowedDomains().size?this.displayConfirmDeletionDialog():this.displayConfirmSummaryDialog())}validateForm(){const e=this.selfRegistrationFormService.validate(this.state.getAllowedDomains());return this.state.setErrors(e),0===e.size}async handleSubmitError(e){"UserAbortsOperationError"!==e.name&&(console.error(e),await this.handleError(e))}async saveSettings(){try{this.setProcessing(!0);const e=new Ko(this.state.domains,this.state.currentSettings);await this.selfRegistrationService.save(e),await this.findSettings(()=>this.setSaved(!0)),await this.props.actionFeedbackContext.displaySuccess(this.props.t("The self registration settings for the organization were updated."))}catch(e){this.handleSubmitError(e)}finally{this.setProcessing(!1),this.setSubmitted(!1)}}async handleError(e){this.handleCloseDialog();const t={error:e};this.props.dialogContext.open($t,t)}handleCloseDialog(){this.props.dialogContext.close()}displayConfirmSummaryDialog(){this.props.dialogContext.open(Bo,{domains:this.getAllowedDomains(),onSubmit:()=>this.saveSettings(),onClose:()=>this.handleCloseDialog()})}displayConfirmDeletionDialog(){this.props.dialogContext.open(Ho,{onSubmit:()=>this.deleteSettings(),onClose:()=>this.handleCloseDialog()})}async deleteSettings(){try{this.setProcessing(!0),await this.selfRegistrationService.delete(this.state.currentSettings.id),await this.findSettings(),await this.props.actionFeedbackContext.displaySuccess(this.props.t("The self registration settings for the organization were updated."))}catch(e){this.handleSubmitError(e)}finally{this.setProcessing(!1),this.setSubmitted(!1)}}isSaved(){return this.state.saved}setSaved(e){return this.setState({saved:e})}render(){return n.createElement(Yo.Provider,{value:this.state},this.props.children)}}Zo.propTypes={context:i().any,children:i().any,t:i().any,dialogContext:i().any,actionFeedbackContext:i().object};const Jo=N(h(m((0,f.CI)("common")(Zo))));function Xo(e){return class extends n.Component{render(){return n.createElement(Yo.Consumer,null,t=>n.createElement(e,$o({adminSelfRegistrationContext:t},this.props)))}}}const Qo=new Map;function el(e){if("string"!=typeof e)return console.warn("useDynamicRefs: Cannot set ref without key");const t=n.createRef();return Qo.set(e,t),t}function tl(e){return e?Qo.get(e):console.warn("useDynamicRefs: Cannot get ref without key")}var al=a(6459),nl=a.n(al);class sl extends n.Component{constructor(e){super(e),this.bindCallbacks()}bindCallbacks(){this.handleSave=this.handleSave.bind(this)}get allowedDomains(){return this.props.adminSelfRegistrationContext.getAllowedDomains()}isSaveEnabled(){let e=!1;return this.props.adminSelfRegistrationContext.getCurrentSettings()?.provider||(e=!this.props.adminSelfRegistrationContext.hasSettingsChanges()),!this.props.adminSelfRegistrationContext.isProcessing()&&!e}async handleSave(){this.isSaveEnabled()&&this.props.adminSelfRegistrationContext.save()}render(){return n.createElement("div",{className:"actions-wrapper"},n.createElement("button",{className:"button primary form",type:"button",disabled:!this.isSaveEnabled(),id:"save-settings",onClick:this.handleSave},n.createElement("span",null,n.createElement(f.x6,null,"Save"))))}}sl.propTypes={adminSelfRegistrationContext:i().object,t:i().func};const il=(0,f.CI)("common")(Xo(sl));var rl;function ol(){return ol=Object.assign?Object.assign.bind():function(e){for(var t=1;tthis.assertNotProfessionalDomains(this.allowedDomains),300),this.bindCallbacks()}async componentDidMount(){await this.findSettings()}componentDidUpdate(){this.shouldFocusOnError(),this.shouldCheckWarnings()}componentWillUnmount(){this.props.administrationWorkspaceContext.resetDisplayAdministrationWorkspaceAction(),this.props.adminSelfRegistrationContext.clearContext()}get defaultState(){return{isEnabled:!1,warnings:new Map}}bindCallbacks(){this.handleToggleClicked=this.handleToggleClicked.bind(this),this.handleAddRowClick=this.handleAddRowClick.bind(this),this.handleInputChange=this.handleInputChange.bind(this),this.handleDeleteRow=this.handleDeleteRow.bind(this)}get currentUser(){return this.props.context.loggedInUser}get allowedDomains(){return this.props.adminSelfRegistrationContext.getAllowedDomains()}async findSettings(){const e=await this.props.adminSelfRegistrationContext.findSettings();this.setState({isEnabled:e.allowedDomains?.size>0}),this.assertNotProfessionalDomains(e.allowedDomains),this.validateForm()}assertNotProfessionalDomains(e){const t=new Map;e?.forEach((e,a)=>{eo.isProfessional(e)||t.set(a,"This is not a safe professional domain")}),this.setState({warnings:t})}setupSettings(){const e=new zo(this.props.adminSelfRegistrationContext.getCurrentSettings());if(this.props.adminSelfRegistrationContext.setDomains(e),this.assertNotProfessionalDomains(e.allowedDomains),0===e.allowedDomains.size){const e=eo.extractDomainFromEmail(this.currentUser?.username);eo.checkDomainValidity(e),this.populateUserDomain(e)}}shouldFocusOnError(){const e=this.props.adminSelfRegistrationContext.shouldFocus(),[t]=this.props.adminSelfRegistrationContext.getErrors().keys();t&&e&&(this.dynamicRefs.getRef(t).current.focus(),this.props.adminSelfRegistrationContext.setFocus(!1))}shouldCheckWarnings(){this.props.adminSelfRegistrationContext.isSaved()&&(this.props.adminSelfRegistrationContext.setSaved(!1),this.assertNotProfessionalDomains(this.allowedDomains))}populateUserDomain(e){const t=eo.isProfessional(e)?e:"";this.addRow(t)}addRow(e=""){const t=(0,r.A)();this.props.adminSelfRegistrationContext.setAllowedDomains(t,e,()=>{const e=this.dynamicRefs.getRef(t);e?.current.focus()})}handleDeleteRow(e){if(this.canDelete()){const t=this.allowedDomains;t.delete(e),this.props.adminSelfRegistrationContext.setDomains({allowedDomains:t}),this.validateForm(),this.assertNotProfessionalDomains(t)}}hasWarnings(){return this.state.warnings.size>0}hasAllInputDisabled(){return this.props.adminSelfRegistrationContext.isProcessing()}handleToggleClicked(){const e=!this.state.isEnabled;e?this.setupSettings():(this.props.adminSelfRegistrationContext.setDomains({allowedDomains:new Map}),this.props.adminSelfRegistrationContext.setErrors(new Map)),this.setState({isEnabled:e})}handleAddRowClick(){this.addRow()}handleInputChange(e){const t=e.target.value,a=e.target.name;this.props.adminSelfRegistrationContext.setAllowedDomains(a,t,()=>this.validateForm()),this.checkForPublicDomainDebounce()}validateForm(){this.props.adminSelfRegistrationContext.validateForm()}canDelete(){return this.allowedDomains.size>1}render(){const e=this.props.adminSelfRegistrationContext.isSubmitted(),t=this.props.adminSelfRegistrationContext.getErrors();return n.createElement("div",{className:"row"},n.createElement(n.Fragment,null,n.createElement("div",{className:"self-registration main-column"},n.createElement("div",{className:"main-content"},n.createElement("h3",null,n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"settings-toggle",onChange:this.handleToggleClicked,checked:this.state.isEnabled,disabled:this.hasAllInputDisabled(),id:"settings-toggle"}),n.createElement("label",{htmlFor:"settings-toggle"},n.createElement(f.x6,null,"Self Registration")))),!this.state.isEnabled&&n.createElement("p",{className:"description",id:"disabled-description"},n.createElement(f.x6,null,"User self registration is disabled.")," ",n.createElement(f.x6,null,"Only administrators can invite users to register.")),this.state.isEnabled&&n.createElement("div",{className:"self-registration-form"},n.createElement("div",{id:"self-registration-subtitle",className:`input ${this.hasWarnings()&&"warning"} ${e&&t.size>0&&"error"}`},n.createElement("label",{id:"enabled-label"},n.createElement(f.x6,null,"Email domain safe list"))),n.createElement("p",{className:"description",id:"enabled-description"},n.createElement(f.x6,null,"All the users with an email address ending with the domain in the safe list are allowed to register on passbolt.")),Lo.iterators(this.allowedDomains).map(a=>n.createElement("div",{key:a,className:"input"},n.createElement("div",{className:"domain-row"},n.createElement("input",{type:"text",className:"full-width",onChange:this.handleInputChange,id:`input-${a}`,name:a,value:this.allowedDomains.get(a),disabled:!this.hasAllInputDisabled,ref:this.dynamicRefs.setRef(a),placeholder:this.props.t("domain")}),n.createElement("button",{type:"button",disabled:!this.canDelete(),className:"button-icon",id:`delete-${a}`,onClick:()=>this.handleDeleteRow(a)},n.createElement(dl,null))),this.hasWarnings()&&this.state.warnings.get(a)&&n.createElement("div",{id:"domain-name-input-feedback",className:"warning-message"},n.createElement(f.x6,null,this.state.warnings.get(a))),t.get(a)&&e&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,t.get(a))))),n.createElement("div",{className:"domain-add"},n.createElement("button",{type:"button",onClick:this.handleAddRowClick},n.createElement(ll,null),n.createElement("span",null,n.createElement(f.x6,null,"Add")))))),this.props.adminSelfRegistrationContext.hasSettingsChanges()&&n.createElement("div",{className:"warning message",id:"self-registration-setting-overridden-banner"},n.createElement("div",null,n.createElement("p",null,n.createElement(f.x6,null,"Don't forget to save your settings to apply your modification."))))),n.createElement(il,null)),Xa(n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"What is user self registration?")),n.createElement("p",null,n.createElement(f.x6,null,"User self registration enables users with an email from a whitelisted domain to create their passbolt account without prior admin invitation.")),n.createElement("a",{className:"button",href:"https://passbolt.com/docs/admin/user-provisioning/self-registration/",target:"_blank",rel:"noopener noreferrer"},n.createElement(ps,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}ul.propTypes={dialogContext:i().any,context:i().any,adminSelfRegistrationContext:i().object,administrationWorkspaceContext:i().object,t:i().func};const pl=N(h(Xo(Ne((0,f.CI)("common")(ul))))),hl=[{id:"azure",name:"Microsoft",icon:n.createElement("svg",{width:"65",height:"64",viewBox:"0 0 65 64",fill:"none",xmlns:"http://www.w3.org/2000/svg"},n.createElement("path",{d:"M31.3512 3.04762H3.92261V30.4762H31.3512V3.04762Z",fill:"#F25022"}),n.createElement("path",{d:"M31.3512 33.5238H3.92261V60.9524H31.3512V33.5238Z",fill:"#00A4EF"}),n.createElement("path",{d:"M61.8274 3.04762H34.3988V30.4762H61.8274V3.04762Z",fill:"#7FBA00"}),n.createElement("path",{d:"M61.8274 33.5238H34.3988V60.9524H61.8274V33.5238Z",fill:"#FFB900"})),defaultConfig:{url:"https://login.microsoftonline.com",client_id:"",client_secret:"",tenant_id:"",client_secret_expiry:"",prompt:"login",email_claim:"email",login_hint:!0}},{id:"google",name:"Google",icon:n.createElement("svg",{width:"65",height:"64",viewBox:"0 0 65 64",fill:"none",xmlns:"http://www.w3.org/2000/svg"},n.createElement("path",{d:"M63.9451 32.72C63.9451 30.6133 63.7584 28.6133 63.4384 26.6667H33.3051V38.6933H50.5584C49.7851 42.64 47.5184 45.9733 44.1584 48.24V56.24H54.4517C60.4784 50.6667 63.9451 42.4533 63.9451 32.72Z",fill:"#4285F4"}),n.createElement("path",{d:"M33.305 64C41.945 64 49.1717 61.12 54.4517 56.24L44.1583 48.24C41.2783 50.16 37.625 51.3333 33.305 51.3333C24.9583 51.3333 17.8917 45.7067 15.3583 38.1067H4.745V46.3467C9.99833 56.8 20.7983 64 33.305 64Z",fill:"#34A853"}),n.createElement("path",{d:"M15.3584 38.1067C14.6917 36.1867 14.3451 34.1333 14.3451 32C14.3451 29.8667 14.7184 27.8133 15.3584 25.8933V17.6533H4.74505C2.55838 21.9733 1.30505 26.8267 1.30505 32C1.30505 37.1733 2.55838 42.0267 4.74505 46.3467L15.3584 38.1067Z",fill:"#FBBC05"}),n.createElement("path",{d:"M33.305 12.6667C38.025 12.6667 42.2383 14.2933 45.5717 17.4667L54.6917 8.34667C49.1717 3.17334 41.945 0 33.305 0C20.7983 0 9.99833 7.20001 4.745 17.6533L15.3583 25.8933C17.8917 18.2933 24.9583 12.6667 33.305 12.6667Z",fill:"#EA4335"})),defaultConfig:{client_id:"",client_secret:""}},{id:"oauth2",name:"OpenID",hiddenIfDisabled:!0,disabledForRecover:!0,icon:n.createElement("svg",{width:"65",height:"60",viewBox:"0 0 65 60",fill:"none",xmlns:"http://www.w3.org/2000/svg"},n.createElement("path",{d:"M64.2468 34.9929L62.9089 21.0968L57.9256 23.9083C53.2914 21.0968 47.3581 19.1061 40.7332 18.3046V24.4577C44.5336 25.117 47.9462 26.3321 50.7513 27.9544L45.5031 30.9146L64.2533 34.9929H64.2468Z",fill:"#B3B3B3"}),n.createElement("path",{d:"M9.94184 38.8774C9.94184 32.0069 17.4264 26.2222 27.632 24.4577V18.2981C12.023 20.1854 0.246826 28.6783 0.246826 38.8774C0.246826 49.0766 12.8891 58.1769 29.3319 59.6312V53.5557C18.2666 52.166 9.94184 46.1228 9.94184 38.8774Z",fill:"#B3B3B3"}),n.createElement("path",{d:"M29.332 5.09999V59.6377L39.027 55.0746V0.362366L29.332 5.09999Z",fill:"#F8931E"})),defaultConfig:{url:"",openid_configuration_path:"",scope:"openid email profile",client_id:"",client_secret:""}},{id:"adfs",name:"AD FS",hiddenIfDisabled:!0,disabledForRecover:!0,icon:n.createElement("svg",{width:"65",height:"64",viewBox:"0 0 65 64",fill:"none",xmlns:"http://www.w3.org/2000/svg"},n.createElement("path",{d:"M64.5443 48.7454V62.166C64.5443 63.7378 64.0607 64.0602 62.5695 63.8184C52.5746 62.3272 42.4587 60.957 32.3831 59.5464C30.5695 59.3046 29.9247 58.6597 29.9247 56.6849C30.0859 49.5514 30.0053 42.3776 29.9247 35.1635C29.9247 33.5917 30.4083 33.1081 31.9801 33.1081C42.2975 33.1887 52.4536 33.1887 62.5695 33.1887C64.2219 33.1887 64.6249 33.8335 64.6249 35.3247C64.4637 39.8386 64.5443 44.2718 64.5443 48.7454Z",fill:"#00AAF2"}),n.createElement("path",{d:"M47.416 30.6093C42.3379 30.6093 37.2598 30.5287 32.1817 30.6093C30.6099 30.6093 29.9651 30.2869 29.9651 28.4733C30.0457 21.1786 30.0457 14.0048 29.9651 6.79069C29.9651 5.38011 30.4487 4.89648 31.7787 4.65467C42.1767 3.16349 52.5747 1.7126 62.9726 0.140816C64.7862 -0.100997 64.4638 1.10807 64.4638 2.11563C64.4638 8.56399 64.5444 15.1333 64.4638 21.5816C64.4638 23.9595 64.3832 26.3373 64.4638 28.7151C64.5444 30.2063 63.9802 30.6093 62.5696 30.6093C57.5721 30.5287 52.4941 30.6093 47.416 30.6093Z",fill:"#00AAF2"}),n.createElement("path",{d:"M13.8038 33.3096H25.1691C26.3782 33.3096 26.9021 33.7126 26.9021 34.962V57.37C26.9021 58.6597 26.3378 58.7806 25.1691 58.6597C17.6326 57.5312 10.096 56.4431 2.59981 55.3952C1.10863 55.1534 0.625 54.6698 0.625 53.098C0.705605 47.1332 0.705605 41.1685 0.625 35.0829C0.625 33.5917 1.02802 33.1887 2.51921 33.1887C6.34792 33.3096 10.0154 33.3096 13.8038 33.3096Z",fill:"#00AAF2"}),n.createElement("path",{d:"M13.8038 30.6093H2.59977C1.18919 30.6093 0.705566 30.1257 0.705566 28.6345C0.786171 22.7504 0.786171 16.8663 0.705566 10.9418C0.705566 9.53126 1.10859 9.04763 2.59977 8.80582C10.1363 7.83856 17.6728 6.7504 25.169 5.54133C26.902 5.29952 27.0633 5.86375 27.0633 7.27433V28.7151C27.0633 30.2869 26.4184 30.5287 25.0078 30.5287C21.2597 30.5287 17.4713 30.6093 13.8038 30.6093Z",fill:"#00AAF2"})),defaultConfig:{url:"",openid_configuration_path:"",scope:"openid email profile",client_id:"",client_secret:""}},{id:"pingone",name:"PingOne",hiddenIfDisabled:!0,icon:n.createElement("svg",{width:"64",height:"64",viewBox:"0 0 64 64",fill:"none",xmlns:"http://www.w3.org/2000/svg"},n.createElement("path",{d:"M0 0H64V64H0V0Z",fill:"#BB2631"}),n.createElement("path",{d:"M30.719 51.2024L31.6177 51.0748V57.6038H30.7179L30.719 51.2024ZM34.43 51.9678V56.1936C34.43 56.9602 34.5576 57.2154 35.2011 57.2154C35.4563 57.2154 35.3287 57.2154 35.5838 57.0878L35.7114 57.6038C35.4562 57.7313 35.3287 57.8589 34.946 57.8589C34.6851 57.8589 34.43 57.7313 34.1748 57.7313C33.7921 57.4762 33.6646 57.0878 33.6646 56.4499V51.9678H32.7647V51.2024H33.537V48.7717H34.43V51.2024H35.839L35.5838 51.9678H34.43ZM36.4837 33.7946C35.7125 33.7946 34.6863 34.3049 33.7933 35.2035V46.5916H29.9547V34.814C29.9547 33.4118 29.8271 32.1304 29.4387 30.9755L32.8946 29.9549C33.283 30.5927 33.4105 31.3593 33.4105 32.0029C34.0484 31.6201 34.4311 31.2317 35.0747 30.849C35.9123 30.4431 36.8287 30.2253 37.7594 30.2112C39.4235 30.2112 40.8325 31.1042 41.3439 32.512C41.6036 33.1499 41.6036 33.7946 41.6036 34.8151V46.5927H37.7594V36.0965C37.7594 34.3049 37.5042 33.7946 36.4837 33.7946ZM47.4901 35.7138C47.4901 34.1761 48.3831 33.2786 49.791 33.2786C51.3287 33.2786 52.0998 34.1773 52.0998 35.7138C52.0998 37.2504 51.2 38.0158 49.6646 38.0158C48.5164 38.0158 47.4901 37.378 47.4901 35.7138ZM51.3275 42.4979H49.2818C48.8991 42.4979 48.644 42.3703 48.644 42.1152C48.644 41.7279 49.1543 41.3441 50.1805 40.8338H50.8184C54.0191 40.8338 56.3211 38.7869 56.3211 35.969C56.3211 34.9427 56.0659 34.0497 55.4281 33.2786C55.6832 33.2786 56.0659 33.4118 56.4486 33.4118C57.4749 33.4118 58.3679 33.0234 59.139 32.258L57.476 29.5676C56.5762 30.4663 55.4281 30.9766 54.4018 30.9766C53.8915 30.9766 53.3767 30.849 52.6101 30.5939C51.5838 30.3387 50.8184 30.2112 49.9197 30.2112C46.0812 30.2112 43.6516 32.3856 43.6516 35.7127C43.6516 38.1434 44.6722 39.5524 46.8523 40.1902C44.417 40.8338 44.1619 41.8544 44.1619 42.8806C44.1619 44.0345 44.5446 44.6723 45.3157 45.0562C45.9536 45.3102 47.1074 45.571 48.8991 45.571H50.5621C52.0998 45.571 53.248 46.0813 53.248 47.4903C53.248 48.1282 52.8652 48.7717 52.3549 49.1556C51.7114 49.5383 50.946 49.6659 49.9197 49.6659C48.128 49.6659 47.1063 49.028 47.1063 47.619C47.1063 47.2363 47.1063 46.9755 47.235 46.5927H43.5229C43.3953 46.8467 43.1345 47.3627 43.1345 48.2557C43.1345 49.4107 43.5217 50.3037 44.4159 51.0748C45.6973 52.4838 47.8717 52.8665 50.0518 52.8665C52.3538 52.8665 54.6558 52.3562 55.9372 50.8197C56.7026 49.9199 57.0911 48.7729 57.0911 47.4914C57.0911 46.0825 56.7038 44.9286 55.8096 44.0345C54.7845 42.8806 53.6341 42.4979 51.3275 42.4979ZM41.9852 57.4762C41.6025 57.4762 41.3416 57.2142 41.3416 56.7051C41.3416 56.3224 41.6036 55.9396 41.9852 55.9396C42.3668 55.9396 42.623 56.1948 42.623 56.7051C42.623 57.0878 42.2403 57.4762 41.9852 57.4762ZM41.9852 55.6845C41.4749 55.6845 41.0865 56.0672 41.0865 56.5775C41.0865 57.0878 41.4738 57.4762 41.9852 57.4762C42.4966 57.4762 42.8782 57.0878 42.8782 56.5764C42.7518 56.1948 42.369 55.6845 41.9852 55.6845ZM41.73 56.5775V56.3224H41.8576C41.9852 56.3224 42.1128 56.3224 42.1128 56.4499C42.1128 56.5775 41.9852 56.5775 41.8576 56.5775H41.73ZM42.3679 56.4499C42.3679 56.1948 42.2415 56.1948 41.9863 56.1948H41.6025V57.2154H41.7312V56.7051H41.8588L42.1139 57.2154H42.2415L41.9863 56.7051C42.2403 56.7051 42.3679 56.7051 42.3679 56.4499ZM41.6025 51.2024L39.5499 57.8589C39.1672 59.1403 38.6569 60.0333 37.6307 60.2885L37.3755 59.6506C37.8858 59.3955 38.2754 59.1403 38.5294 58.4968C38.4018 57.8589 38.4018 57.7313 38.4018 57.7313C38.2742 57.3486 38.0145 56.0672 37.7582 55.4237L36.4825 51.33L37.3755 50.9473L38.5294 55.1685C38.6569 55.8121 38.9121 56.8327 38.9121 56.8327C38.9121 56.8327 39.1672 56.0672 39.2948 55.4237L40.4486 51.2024H41.6025ZM13.4387 55.9385C13.4387 55.9385 13.3112 56.1936 13.056 56.4488C12.6733 56.7039 12.4125 56.8315 11.9022 56.8315C11.3919 56.8315 11.0092 56.5764 10.7483 56.0661C10.5701 55.5297 10.4838 54.9671 10.4932 54.402C10.4932 53.5021 10.6208 52.993 10.8816 52.4827C11.1368 52.0943 11.5195 51.8391 11.9022 51.8391C12.5457 51.8391 13.056 52.0943 13.3112 52.4827L13.4387 55.9385ZM14.3374 48.7706H13.4387V51.9667C13.2651 51.7225 13.0339 51.525 12.7657 51.3915C12.4975 51.258 12.2005 51.1926 11.901 51.2013C11.5198 51.2013 11.1356 51.3288 10.7483 51.584C9.98291 52.2218 9.6002 53.247 9.6002 54.5295C9.6002 56.5764 10.4932 57.8578 11.9022 57.8578C12.5446 57.8585 13.0572 57.6015 13.4399 57.0867C13.4399 57.4739 13.5663 57.7302 13.5663 57.7302H14.4661C14.3374 57.3475 14.3374 56.7039 14.3374 55.6834V48.7706ZM28.2895 51.2013H29.826L29.4376 51.9667H28.1619V56.1925C28.1619 56.9591 28.2895 57.2142 28.9273 57.2142C29.1825 57.2142 29.0549 57.2142 29.31 57.0867L29.4376 57.6026C29.1825 57.7302 29.0549 57.8578 28.6722 57.8578C28.417 57.8578 28.1619 57.7302 27.9067 57.7302C27.5183 57.4751 27.3908 57.0867 27.3908 56.4488V51.9667H26.6253V51.2013H27.3908V48.7706H28.2895V51.2013ZM22.7856 30.7203L26.6242 30.0825V46.5905H22.7856V30.7203ZM22.3984 25.9819C22.3984 24.5729 23.5511 23.4248 24.8325 23.4248C26.1082 23.4248 27.1356 24.5729 27.1356 25.9819C27.1356 27.3909 26.1093 28.6723 24.7049 28.6723C23.4246 28.6723 22.3984 27.5185 22.3984 25.9819ZM25.5979 51.9667C25.7266 52.2218 25.7266 52.4827 25.7266 52.7378V57.6015H24.8336V53.2504C24.8336 52.6125 24.8336 52.3574 24.5785 52.2241C24.4011 52.0653 24.1729 51.9749 23.9349 51.969C23.4246 51.969 22.7868 52.3563 22.2708 52.8677V57.6049H21.3767V52.6125C21.3767 51.7127 21.1215 51.2036 21.1215 51.2036L22.0157 50.9484C22.0157 50.9484 22.2708 51.4587 22.2708 51.969C22.9144 51.3311 23.4246 50.9484 24.0625 50.9484C24.8336 51.076 25.3439 51.4587 25.5991 51.969M16.6394 53.7607C16.6394 52.485 17.1497 51.7138 17.9208 51.7138C18.3035 51.7138 18.8138 51.969 18.9414 52.2241C19.1966 52.7401 19.1965 53.1228 19.3298 53.7607H16.6394ZM18.0484 50.9473C17.4049 50.9473 16.767 51.2035 16.2567 51.8414C15.7407 52.485 15.6132 53.2504 15.6132 54.2767C15.6132 56.4511 16.6394 57.7325 18.176 57.7325C18.9414 57.7325 19.585 57.4773 20.0952 56.9614L19.7125 56.3235C19.3298 56.7062 18.8138 56.9614 18.3036 56.9614C17.6657 56.9614 17.1497 56.7062 16.8946 56.1959C16.6394 55.8132 16.6394 55.4248 16.6394 54.7869V54.6594H20.2228V54.5318C20.2228 52.9941 20.0953 52.3562 19.585 51.8414C19.1977 51.2035 18.6863 50.9484 18.0484 50.9484M7.42578 57.6049H8.31878V48.6453H7.42578V57.6049ZM16.2567 33.7957C15.7407 34.6887 15.2316 34.9438 13.5663 34.9438H11.3919V28.2873H13.949C15.6132 28.2873 16.6394 29.5687 16.6394 31.6213C16.767 32.6419 16.6394 33.2797 16.2567 33.7957ZM18.3036 25.7291C17.1497 25.0912 16.1291 24.7039 12.6733 24.7039H7.42578V46.7215H11.5195V38.6594H13.6939C15.874 38.6594 16.767 38.3985 17.6657 37.8882C19.8412 36.7344 21.1215 34.4324 21.1215 31.4869C21.2491 28.9298 20.2228 26.8829 18.3036 25.7291Z",fill:"white"})),defaultConfig:{url:"https://auth.pingone.com",environment_id:"",client_id:"",client_secret:"",email_claim:"email"}}],gl="form",yl="success";class bl extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.bindCallbacks()}get defaultState(){return{uiState:gl,hasSuccessfullySignedInWithSso:!1,processing:!1,ssoToken:null}}bindCallbacks(){this.handleSignInTestClick=this.handleSignInTestClick.bind(this),this.handleActivateSsoSettings=this.handleActivateSsoSettings.bind(this),this.handleCloseDialog=this.handleCloseDialog.bind(this)}async handleSignInTestClick(e){e.preventDefault();try{this.setState({processing:!0});const e=await this.props.context.port.request("passbolt.sso.dry-run",this.props.configurationId);this.setState({uiState:yl,hasSuccessfullySignedInWithSso:!0,ssoToken:e})}catch(e){"UserAbortsOperationError"!==e?.name&&this.props.adminSsoContext.handleError(e)}this.setState({processing:!1})}async handleActivateSsoSettings(e){e.preventDefault();try{this.setState({processing:!0}),await this.props.context.port.request("passbolt.sso.activate-settings",this.props.configurationId,this.state.ssoToken),await this.props.context.port.request("passbolt.sso.generate-sso-kit",this.props.provider.id),this.props.onSuccessfulSettingsActivation(),await this.props.actionFeedbackContext.displaySuccess(this.props.t("The SSO settings have been saved successfully"))}catch(e){this.props.adminSsoContext.handleError(e)}this.setState({processing:!1}),this.handleCloseDialog()}handleCloseDialog(){this.props.onClose(),this.props.handleClose()}hasAllInputDisabled(){return this.state.processing}canSaveSettings(){return!this.hasAllInputDisabled()&&this.state.hasSuccessfullySignedInWithSso}get title(){return{form:this.translate("Test Single Sign-On configuration"),success:this.translate("Save Single Sign-On configuration")}[this.state.uiState]||""}get translate(){return this.props.t}render(){return n.createElement(qt,{className:"test-sso-settings-dialog sso-login-form",title:this.title,onClose:this.handleCloseDialog,disabled:this.hasAllInputDisabled()},n.createElement("form",{onSubmit:this.handleActivateSsoSettings},n.createElement("div",{className:"form-content"},this.state.uiState===gl&&n.createElement(n.Fragment,null,n.createElement("p",null,n.createElement(f.x6,null,"Before saving the settings, we need to test if the configuration is working.")),n.createElement("button",{type:"button",className:`sso-login-button ${this.props.provider.id}`,onClick:this.handleSignInTestClick,disabled:this.hasAllInputDisabled()},n.createElement("span",{className:"provider-logo"},this.props.provider.icon),this.translate("Sign in with {{providerName}}",{providerName:this.props.provider.name}))),this.state.uiState===yl&&n.createElement("p",null,this.translate("You successfully signed in with your {{providerName}} account. You can safely save your configuration.",{providerName:this.props.provider.name}))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement(gn,{disabled:this.hasAllInputDisabled(),onClick:this.handleCloseDialog}),n.createElement(qs,{disabled:!this.canSaveSettings(),processing:this.state.processing,value:this.translate("Save settings")}))))}}bl.propTypes={context:i().object,adminSsoContext:i().object,onClose:i().func,t:i().func,provider:i().object,configurationId:i().string,actionFeedbackContext:i().any,handleClose:i().func,onSuccessfulSettingsActivation:i().func};const fl=N($l(m((0,f.CI)("common")(bl))));class El extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.bindCallbacks()}get defaultState(){return{processing:!1}}bindCallbacks(){this.handleConfirmDelete=this.handleConfirmDelete.bind(this)}async handleConfirmDelete(e){e.preventDefault(),this.setState({processing:!0}),await this.props.adminSsoContext.deleteSettings(),this.setState({processing:!1}),this.props.onClose()}hasAllInputDisabled(){return this.state.processing}render(){const e=this.hasAllInputDisabled();return n.createElement(qt,{className:"delete-sso-settings-dialog",title:this.props.t("Disable Single Sign-On settings?"),onClose:this.props.onClose,disabled:e},n.createElement("form",{onSubmit:this.handleConfirmDelete,noValidate:!0},n.createElement("div",{className:"form-content"},n.createElement("p",null,n.createElement(f.x6,null,"Are you sure you want to disable the current Single Sign-On settings?")),n.createElement("p",null,n.createElement(f.x6,null,"This action cannot be undone. All the data associated with SSO will be permanently deleted."))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement(gn,{disabled:e,onClick:this.props.onClose}),n.createElement(qs,{warning:!0,disabled:e,processing:this.state.processing,value:this.props.t("Disable")}))))}}El.propTypes={adminSsoContext:i().object,onClose:i().func,t:i().func};const vl=$l((0,f.CI)("common")(El)),wl=["https://login.microsoftonline.com","https://login.microsoftonline.us","https://login.partner.microsoftonline.cn"];class kl extends se{constructor(e,t={}){const a=kl.sanitizeDto(e);super(ae.validate(kl.ENTITY_NAME,a,kl.getSchema()),t)}static getSchema(){return{type:"object",required:["url","client_id","tenant_id","client_secret","client_secret_expiry"],properties:{url:{type:"string",enum:wl},client_id:{type:"string",format:"uuid"},tenant_id:{type:"string",format:"uuid"},client_secret:{type:"string",minLength:1},client_secret_expiry:{type:"string",format:"date-time"},email_claim:{type:"string",enum:["email","preferred_username","upn"]},prompt:{type:"string",enum:["login","none"]},login_hint:{type:"boolean"}}}}static sanitizeDto(e){return e=Object.assign({},e),e?.email_claim||(e.email_claim="email"),e?.prompt||(e.prompt="login"),void 0===e.login_hint&&(e.login_hint=!0),e}static get ENTITY_NAME(){return"AzureSsoSettings"}static get PROVIDER_ID(){return"azure"}static get SUPPORTED_URLS(){return wl}}const _l=kl;class xl extends he{static getSchema(){return{type:"object",required:["url","client_id","tenant_id","client_secret","client_secret_expiry","email_claim","prompt","login_hint"],properties:{id:{type:"string",format:"uuid"},url:{type:"string"},client_id:{type:"string",format:"uuid"},tenant_id:{type:"string",format:"uuid"},client_secret:{type:"string",minLength:1},client_secret_expiry:{type:"string"},email_claim:{type:"string",enum:["email","preferred_username","upn"]},prompt:{type:"string",enum:["login","none"]},login_hint:{type:"boolean"}}}}marshall(){this._props.client_secret_expiry&&(this._props.client_secret_expiry=this._props.client_secret_expiry.toString().substring(0,10)),void 0===this._props.login_hint&&(this._props.login_hint=!0)}validate(e={}){this.marshall();let t=null;const a=e?.schema??this.cachedSchema;try{ae.validate(this.constructor.name,{...this._props},a)}catch(e){if(!(e instanceof X))throw e;t=e}return t||new X}get id(){return this._props.id}get url(){return this._props.url}get client_id(){return this._props.client_id}get tenant_id(){return this._props.tenant_id}get client_secret(){return this._props.client_secret}get client_secret_expiry(){return this._props.client_secret_expiry}get email_claim(){return this._props.email_claim}get prompt(){return this._props.prompt}get login_hint(){return this._props.login_hint}get provider(){return _l.PROVIDER_ID}toFormDto(){return{id:this._props.id,provider:this.provider,url:this._props.url??null,client_id:this._props.client_id??null,tenant_id:this._props.tenant_id??null,client_secret:this._props.client_secret??null,client_secret_expiry:this._props.client_secret_expiry??null,email_claim:this._props.email_claim??null,prompt:this._props.prompt??null,login_hint:this._props.login_hint??!0}}toEntityDto(){let e=this._props.client_secret_expiry;return e&&(e+=" 00:00:00"),{provider:this.provider,data:{url:this._props.url,client_id:this._props.client_id,tenant_id:this._props.tenant_id,client_secret:this._props.client_secret,client_secret_expiry:e,email_claim:this._props.email_claim,prompt:this._props.prompt,login_hint:this._props.login_hint}}}static fromEntityDto(e){const t=e.data,a={id:e?.id,url:t.url,client_id:t.client_id,tenant_id:t.tenant_id,client_secret:t.client_secret,client_secret_expiry:t.client_secret_expiry,email_claim:t.email_claim,prompt:t.prompt,login_hint:t.login_hint};return new xl(a,{validate:!1})}static createDefault(e={}){return new xl(e,{validate:!1})}static get ENTITY_NAME(){return"AzureSsoSettingsForm"}}const Sl=xl,Cl=/^https:\/\/.+[^/]$/;class Nl extends se{constructor(e,t={}){super(ae.validate(Nl.ENTITY_NAME,e,Nl.getSchema()),t)}static getSchema(){return{type:"object",required:["url","openid_configuration_path","scope","client_id","client_secret"],properties:{url:{type:"string",pattern:Cl},openid_configuration_path:{type:"string",minLength:1},scope:{type:"string",minLength:1},client_id:{type:"string",minLength:1},client_secret:{type:"string",minLength:1}}}}static get ENTITY_NAME(){return"OAuth2SsoSettings"}static get PROVIDER_ID(){return"oauth2"}}const Tl=Nl;class Al extends he{static getSchema(){const e=Tl.getSchema();return{...e,properties:{id:{type:"string"},...e.properties}}}get provider(){return Tl.PROVIDER_ID}get id(){return this._props.id||null}get url(){return this._props.url||null}get openid_configuration_path(){return this._props.openid_configuration_path||null}get scope(){return this._props.scope||null}get client_id(){return this._props.client_id||null}get client_secret(){return this._props.client_secret||null}validate(e={}){let t=null;const a=e?.schema??this.cachedSchema;try{ae.validate(this.constructor.name,{...this._props},a)}catch(e){if(!(e instanceof X))throw e;t=e}return t||new X}toFormDto(){return{id:this._props.id,url:this._props.url,openid_configuration_path:this._props.openid_configuration_path,scope:this._props.scope,client_id:this._props.client_id,client_secret:this._props.client_secret}}toEntityDto(){const e=this.toDto();return delete e.id,{provider:this.provider,data:{...e}}}static fromEntityDto({id:e,data:t}={}){const a={id:e,url:t.url,openid_configuration_path:t.openid_configuration_path,scope:t.scope,client_id:t.client_id,client_secret:t.client_secret};return new Al(a,{validate:!1})}static createDefault(e={}){return new Al(e,{validate:!1})}static get ENTITY_NAME(){return"OAuth2SsoSettingsForm"}}const Il=Al,Rl=["https://accounts.google.com"];class Pl extends se{constructor(e,t={}){super(ae.validate(Pl.ENTITY_NAME,e,Pl.getSchema()),t)}static getSchema(){return{type:"object",required:["client_id","client_secret"],properties:{client_id:{type:"string",minLength:1},client_secret:{type:"string",minLength:1}}}}static get ENTITY_NAME(){return"GoogleSsoSettings"}static get PROVIDER_ID(){return"google"}static get SUPPORTED_URLS(){return Rl}}const Dl=Pl;class Ol extends he{static getSchema(){const e=Dl.getSchema();return{...e,properties:{id:{type:"string",format:"uuid"},...e.properties}}}get provider(){return Dl.PROVIDER_ID}get id(){return this._props.id||null}get client_id(){return this._props.client_id||null}get client_secret(){return this._props.client_secret||null}validate(e={}){let t=null;const a=e?.schema??this.cachedSchema;try{ae.validate(this.constructor.name,{...this._props},a)}catch(e){if(!(e instanceof X))throw e;t=e}return t||new X}toFormDto(){return{id:this._props.id,client_id:this._props.client_id,client_secret:this._props.client_secret}}toEntityDto(){const e=this.toDto();return delete e.id,{provider:this.provider,data:{...e}}}static fromEntityDto({id:e,data:t}={}){const a={id:e,client_id:t.client_id,client_secret:t.client_secret};return new Ol(a,{validate:!1})}static createDefault(e={}){return new Ol(e,{validate:!1})}static get ENTITY_NAME(){return"GoogleSsoSettingsForm"}}const Ml=Ol,Ul=/^https:\/\/.+[^/]$/;class Fl extends se{constructor(e,t={}){super(ae.validate(Fl.ENTITY_NAME,e,Fl.getSchema()),t)}static getSchema(){return{type:"object",required:["url","openid_configuration_path","scope","client_id","client_secret"],properties:{url:{type:"string",pattern:Ul},openid_configuration_path:{type:"string",minLength:1},scope:{type:"string",minLength:1},client_id:{type:"string",minLength:1},client_secret:{type:"string",minLength:1}}}}static validateUrl(e){if("string"!=typeof e)throw new TypeError("The url should be a string.");let t;try{t=new URL(e)}catch(e){throw new Error("The url should be a valid url.",{cause:e})}if("https:"!==t.protocol)throw new Error("The url protocol should be HTTPS.")}static get ENTITY_NAME(){return"ADFSSsoSettings"}static get PROVIDER_ID(){return"adfs"}}const jl=Fl;class Ll extends he{static getSchema(){const e=jl.getSchema();return{type:"object",required:["url","openid_configuration_path","scope","client_id","client_secret"],properties:{id:{type:"string",format:"uuid"},url:e.properties.url,openid_configuration_path:e.properties.openid_configuration_path,scope:e.properties.scope,client_id:e.properties.client_id,client_secret:e.properties.client_secret}}}validate(e={}){const t=e?.schema??this.cachedSchema;let a=null;try{ae.validate(this.constructor.name,{...this._props},t)}catch(e){if(!(e instanceof X))throw e;a=e}return a||new X}get id(){return this._props.id}get url(){return this._props.url}get openid_configuration_path(){return this._props.openid_configuration_path}get scope(){return this._props.scope}get client_id(){return this._props.client_id}get client_secret(){return this._props.client_secret}get provider(){return jl.PROVIDER_ID}toFormDto(){return{id:this._props.id,provider:this.provider,url:this._props.url??null,openid_configuration_path:this._props.openid_configuration_path??null,scope:this._props.scope??null,client_id:this._props.client_id??null,client_secret:this._props.client_secret??null}}toEntityDto(){return{provider:this.provider,data:{url:this._props.url,openid_configuration_path:this._props.openid_configuration_path,scope:this._props.scope,client_id:this._props.client_id,client_secret:this._props.client_secret}}}static fromEntityDto(e){const t=e.data,a={id:e?.id,url:t.url,openid_configuration_path:t.openid_configuration_path,scope:t.scope,client_id:t.client_id,client_secret:t.client_secret};return new Ll(a,{validate:!1})}static createDefault(e={}){return new Ll(e,{validate:!1})}}const ql=Ll,zl=["https://auth.pingone.com","https://auth.pingone.eu","https://auth.pingone.ca","https://auth.pingone.asia","https://auth.pingone.com.au","https://auth.pingone.sg"],Kl=class extends he{static getSchema(){return{type:"object",required:["url","environment_id","client_id","client_secret","email_claim"],properties:{url:{type:"string",enum:zl},environment_id:{type:"string",minLength:1},client_id:{type:"string",minLength:1},client_secret:{type:"string",minLength:1},email_claim:{type:"string",minLength:1}}}}static get ENTITY_NAME(){return"PingOneSsoSettings"}static get PROVIDER_ID(){return"pingone"}static get SUPPORTED_URLS(){return zl}};class Vl extends he{static getSchema(){const e=Kl.getSchema();return{...e,properties:{id:{type:"string"},...e.properties}}}get provider(){return Kl.PROVIDER_ID}get id(){return this._props.id||null}get url(){return this._props.url||null}get environment_id(){return this._props.environment_id||null}get client_id(){return this._props.client_id||null}get client_secret(){return this._props.client_secret||null}get email_claim(){return this._props.email_claim||null}validate(e={}){let t=null;const a=e?.schema??this.cachedSchema;try{ae.validate(this.constructor.name,{...this._props},a)}catch(e){if(!(e instanceof X))throw e;t=e}return t||new X}toFormDto(){return{id:this._props.id,url:this._props.url,environment_id:this._props.environment_id,client_id:this._props.client_id,client_secret:this._props.client_secret,email_claim:this._props.email_claim}}toEntityDto(){const e=this.toDto();return delete e.id,{provider:this.provider,data:{...e}}}static fromEntityDto({id:e,data:t}={}){const a={id:e,url:t.url,environment_id:t.environment_id,client_id:t.client_id,client_secret:t.client_secret,email_claim:t.email_claim};return new Vl(a,{validate:!1})}static createDefault(e={}){return new Vl(e,{validate:!1})}static get SCOPE(){return"openid profile email"}static get ENTITY_NAME(){return"PingOneSsoSettingsForm"}}const Gl=Vl;function Bl(){return Bl=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},isProcessing:()=>{},loadSsoConfiguration:()=>{},getSsoConfiguration:()=>{},getProviderList:()=>{},isSsoConfigActivated:()=>{},isDataReady:()=>{},save:()=>{},disableSso:()=>{},hasFormChanged:()=>{},validateData:()=>{},saveAndTestConfiguration:()=>{},openTestDialog:()=>{},handleError:()=>{},getErrors:()=>{},deleteSettings:()=>{},showDeleteConfirmationDialog:()=>{}});class Hl extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.bindCallbacks(),this.isSsoConfigExisting=!1,this.shouldFocusOnError=!1,this.formSettings=null,this.originalSettings=null,this.cachedSsoConfig={}}get defaultState(){return{ssoConfig:null,providers:[],isLoaded:!1,processing:!1,hasBeenValidated:!1,hasFormChanged:this.hasFormChanged.bind(this),isProcessing:this.isProcessing.bind(this),isDataReady:this.isDataReady.bind(this),loadSsoConfiguration:this.loadSsoConfiguration.bind(this),getSsoConfiguration:this.getSsoConfiguration.bind(this),getProviderList:this.getProviderList.bind(this),isSsoConfigActivated:this.isSsoConfigActivated.bind(this),changeProvider:this.changeProvider.bind(this),disableSso:this.disableSso.bind(this),setValue:this.setValue.bind(this),validateData:this.validateData.bind(this),saveAndTestConfiguration:this.saveAndTestConfiguration.bind(this),handleError:this.handleError.bind(this),getErrors:this.getErrors.bind(this),deleteSettings:this.deleteSettings.bind(this),canDeleteSettings:this.canDeleteSettings.bind(this),showDeleteConfirmationDialog:this.showDeleteConfirmationDialog.bind(this),consumeFocusOnError:this.consumeFocusOnError.bind(this)}}bindCallbacks(){this.handleTestConfigCloseDialog=this.handleTestConfigCloseDialog.bind(this),this.handleSettingsActivation=this.handleSettingsActivation.bind(this)}validateForm=(0,po.A)(e=>this.formSettings?.validate());hasSettingsChanges=(0,po.A)((e,t)=>{try{return this.originalSettings?.hasDiffProps(this.formSettings)??!1}catch{return!0}});getSsoConfigDto(){return this.formSettings?{provider:this.formSettings.provider,...this.formSettings.toFormDto()}:null}async loadSsoConfiguration(){let e=null;try{e=await this.props.context.port.request("passbolt.sso.get-current")}catch(e){return this.props.dialogContext.open($t,{error:e}),{}}return this.isSsoConfigExisting=Boolean(e.provider),this.formSettings=this.getSsoProviderFormEntity(e),this.originalSettings=this.getSsoProviderFormEntity(e),this.setState({ssoConfig:this.getSsoConfigDto(),providers:e.providers,isLoaded:!0}),e}getSsoProviderFormEntity(e){if(!e?.provider)return null;switch(e.provider){case _l.PROVIDER_ID:return Sl.fromEntityDto(e);case Dl.PROVIDER_ID:return Ml.fromEntityDto(e);case Tl.PROVIDER_ID:return Il.fromEntityDto(e);case jl.PROVIDER_ID:return ql.fromEntityDto(e);case Kl.PROVIDER_ID:return Gl.fromEntityDto(e)}return null}getSsoConfiguration(){return this.state.ssoConfig}getProviderList(){return this.state.providers}getSsoConfigurationDto(){return this.formSettings.toEntityDto()}isSsoConfigActivated(){return Boolean(this.formSettings)}hasFormChanged(){return this.originalSettings&&this.formSettings?this.hasSettingsChanges(this.originalSettings.toFormDto(),this.formSettings.toFormDto()):null!==this.originalSettings&&null===this.formSettings||null===this.originalSettings&&null!==this.formSettings}setValue(e,t){this.formSettings.set(e,t,{validate:!1}),this.setState({ssoConfig:this.getSsoConfigDto()},()=>{this.state.hasBeenValidated&&this.validateData()})}disableSso(){this.formSettings&&(this.cachedSsoConfig[this.formSettings.provider]=this.formSettings),this.formSettings=null,this.setState({ssoConfig:null})}isDataReady(){return this.state.isLoaded}isProcessing(){return this.state.processing}changeProvider(e){e.disabled||(this.formSettings?.provider&&(this.cachedSsoConfig[this.formSettings.provider]=this.formSettings),this.formSettings=this.getCachedSsoConfigOrDefault(e.id),this.setState({ssoConfig:this.getSsoConfigDto()},()=>{this.state.hasBeenValidated&&this.validateData()}))}getCachedSsoConfigOrDefault(e){if(this.cachedSsoConfig[e])return this.cachedSsoConfig[e];const t=hl.find(t=>t.id===e),a={id:this.formSettings?.id,provider:e,data:t.defaultConfig};return this.getSsoProviderFormEntity(a)}validateData(e=!1){const t=this.validateForm(this.state.ssoConfig),a=Boolean(t?.hasErrors());return this.shouldFocusOnError=e&&a,this.setState({hasBeenValidated:!0}),!a}consumeFocusOnError(){const e=this.shouldFocusOnError;return this.shouldFocusOnError=!1,e}getErrors(){return this.state.hasBeenValidated?this.validateForm(this.state.ssoConfig):null}async saveAndTestConfiguration(){this.setState({processing:!0});const e=this.getSsoConfigurationDto();let t;try{t=await this.props.context.port.request("passbolt.sso.save-draft",e)}catch(e){return this.handleError(e),void this.setState({processing:!1})}await this.runTestConfig(t),this.formSettings=this.getSsoProviderFormEntity(t),this.setState({ssoConfig:this.getSsoConfigDto()})}canDeleteSettings(){return this.isSsoConfigExisting&&null===this.formSettings}showDeleteConfirmationDialog(){this.props.dialogContext.open(vl)}async deleteSettings(){this.setState({processing:!0});try{await this.props.context.port.request("passbolt.sso.delete-settings",this.originalSettings.id),this.props.actionFeedbackContext.displaySuccess(this.props.t("The SSO settings have been deleted successfully")),this.isSsoConfigExisting=!1,this.formSettings=null,this.originalSettings=null,this.setState({ssoConfig:null,processing:!1})}catch(e){this.handleError(e),this.setState({processing:!1})}}async runTestConfig(e){const t=hl.find(t=>t.id===e.provider);this.props.dialogContext.open(fl,{provider:t,configurationId:e.id,handleClose:this.handleTestConfigCloseDialog,onSuccessfulSettingsActivation:this.handleSettingsActivation})}handleTestConfigCloseDialog(){this.setState({processing:!1})}handleSettingsActivation(){this.isSsoConfigExisting=!0,this.originalSettings=this.getSsoProviderFormEntity({id:this.formSettings.id,provider:this.formSettings.provider,data:this.formSettings.toFormDto()})}handleError(e){console.error(e),this.props.dialogContext.open($t,{error:e})}render(){return n.createElement(Wl.Provider,{value:this.state},this.props.children)}}function $l(e){return class extends n.Component{render(){return n.createElement(Wl.Consumer,null,t=>n.createElement(e,Bl({adminSsoContext:t},this.props)))}}}Hl.propTypes={context:i().any,children:i().any,accountRecoveryContext:i().object,dialogContext:i().object,actionFeedbackContext:i().object,t:i().func},N(m(h((0,f.CI)("common")(Hl))));class Yl extends n.Component{constructor(e){super(e),this.bindCallbacks()}bindCallbacks(){this.handleSaveClick=this.handleSaveClick.bind(this)}async handleSaveClick(){const e=this.props.adminSsoContext;e.canDeleteSettings()?e.showDeleteConfirmationDialog():e.validateData(!0)&&await e.saveAndTestConfiguration()}isSaveEnabled(){return Boolean(this.props.adminSsoContext.ssoConfig?.provider)||this.props.adminSsoContext.canDeleteSettings()}render(){return n.createElement("div",{className:"actions-wrapper"},n.createElement("button",{type:"button",className:"button primary form",disabled:!this.isSaveEnabled(),onClick:this.handleSaveClick},n.createElement("span",null,n.createElement(f.x6,null,"Save"))))}}Yl.propTypes={adminSsoContext:i().object};const Zl=$l((0,f.CI)("common")(Yl));var Jl;function Xl(){return Xl=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},copy:()=>{}});class rc extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.clipboardServiceWorkerService=new nc(e.context.port)}get defaultState(){return{copyTemporarily:this.copyTemporarily.bind(this),copy:this.copy.bind(this)}}async copyTemporarily(e,t){(0,ie.A)(e),(0,ie.A)(t),await this.clipboardServiceWorkerService.copyTemporarily(e),this.props.actionFeedbackContext.displaySuccess(n.createElement(n.Fragment,null,t," ",n.createElement(f.x6,null,"It will clear in 30 seconds.")))}async copy(e,t){(0,ie.A)(e),(0,ie.A)(t),await this.clipboardServiceWorkerService.copy(e),this.props.actionFeedbackContext.displaySuccess(t)}render(){return n.createElement(ic.Provider,{value:this.state},this.props.children)}}function oc(e){return class extends n.Component{render(){return n.createElement(ic.Consumer,null,t=>n.createElement(e,sc({clipboardContext:t},this.props)))}}}rc.propTypes={context:i().any.isRequired,actionFeedbackContext:i().any.isRequired,children:i().any,t:i().func},N(m((0,f.CI)("common")(rc)));class lc extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.bindCallbacks(),this.createRefs()}get defaultState(){return{advancedSettingsOpened:!1}}bindCallbacks(){this.handleInputChange=this.handleInputChange.bind(this),this.handleCopyRedirectUrl=this.handleCopyRedirectUrl.bind(this),this.handleAdvancedSettingsCLick=this.handleAdvancedSettingsCLick.bind(this)}createRefs(){this.clientIdInputRef=n.createRef(),this.tenantIdInputRef=n.createRef(),this.clientSecretInputRef=n.createRef(),this.clientSecretExpiryInputRef=n.createRef()}componentDidUpdate(){if(!this.props.adminSsoContext.consumeFocusOnError())return;const e=this.props.adminSsoContext.getErrors();switch(this.getFirstFieldInError(e,["client_id","tenant_id","client_secret","client_secret_expiry"])){case"client_id":this.clientIdInputRef.current.focus();break;case"tenant_id":this.tenantIdInputRef.current.focus();break;case"client_secret":this.clientSecretInputRef.current.focus();break;case"client_secret_expiry":this.clientSecretExpiryInputRef.current.focus()}}getFirstFieldInError(e,t){for(let a=0;a({value:e,label:e}))}get emailClaimList(){return[{value:"email",label:this.translate("Email")},{value:"preferred_username",label:this.translate("Preferred username")},{value:"upn",label:this.translate("UPN")}]}get promptOptionList(){return[{value:"login",label:this.translate("Login")},{value:"none",label:this.translate("None")}]}get fullRedirectUrl(){return`${this.props.context.userSettings.getTrustedDomain()}/sso/azure/redirect`}get translate(){return this.props.t}render(){const e=this.props.adminSsoContext,t=e.getSsoConfiguration(),a=e.getErrors();return n.createElement(n.Fragment,null,n.createElement("div",{className:"select-wrapper input required "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",{htmlFor:"sso-azure-url-input"},n.createElement(f.x6,null,"Login URL")),n.createElement(pn,{id:"sso-azure-url-input",name:"url",items:this.availableUrlList,value:t.url,onChange:this.handleInputChange}),n.createElement("p",null,n.createElement(f.x6,null,"The Azure AD authentication endpoint. See"," ",n.createElement("a",{href:"https://learn.microsoft.com/en-us/azure/active-directory/develop/authentication-national-cloud#azure-ad-authentication-endpoints",rel:"noopener noreferrer",target:"_blank"},"alternatives"),"."))),n.createElement("div",{className:"input text input-wrapper "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Redirect URL")),n.createElement("div",{className:"button-inline"},n.createElement("input",{id:"sso-redirect-url-input",type:"text",className:"fluid form-element disabled",name:"redirect_url",value:this.fullRedirectUrl,placeholder:this.translate("Redirect URL"),readOnly:!0,disabled:!0}),n.createElement("button",{type:"button",onClick:this.handleCopyRedirectUrl,className:"copy-to-clipboard button button-icon"},n.createElement(Ql,null))),n.createElement("p",null,n.createElement(f.x6,null,"The URL to provide to Azure when registering the application."))),n.createElement("div",{className:"input text required "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Application (client) ID")),n.createElement("input",{id:"sso-azure-client-id-input",type:"text",className:"fluid form-element",name:"client_id",ref:this.clientIdInputRef,value:t.client_id,onChange:this.handleInputChange,placeholder:this.translate("Application (client) ID"),disabled:this.hasAllInputDisabled()}),a?.hasError("client_id")&&n.createElement("div",{className:"error-message"},this.displayErrors(a.getError("client_id"))),n.createElement("p",null,n.createElement(f.x6,null,"The public identifier for the app in Azure in UUID format.")," ",n.createElement("a",{href:"https://learn.microsoft.com/en-us/azure/healthcare-apis/register-application#application-id-client-id",rel:"noopener noreferrer",target:"_blank"},n.createElement(f.x6,null,"Where to find it?")))),n.createElement("div",{className:"input text required "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Directory (tenant) ID")),n.createElement("input",{id:"sso-azure-tenant-id-input",type:"text",className:"fluid form-element",name:"tenant_id",ref:this.tenantIdInputRef,value:t.tenant_id,onChange:this.handleInputChange,placeholder:this.translate("Directory ID"),disabled:this.hasAllInputDisabled()}),a?.hasError("tenant_id")&&n.createElement("div",{className:"error-message"},this.displayErrors(a.getError("tenant_id"))),n.createElement("p",null,n.createElement(f.x6,null,"The Azure Active Directory tenant ID, in UUID format.")," ",n.createElement("a",{href:"https://learn.microsoft.com/en-gb/azure/active-directory/fundamentals/active-directory-how-to-find-tenant",rel:"noopener noreferrer",target:"_blank"},n.createElement(f.x6,null,"Where to find it?")))),n.createElement("div",{className:"input text required "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Secret")),n.createElement(Za,{id:"sso-azure-secret-input",className:"fluid form-element",onChange:this.handleInputChange,autoComplete:"off",name:"client_secret",placeholder:this.translate("Secret"),disabled:this.hasAllInputDisabled(),value:t.client_secret,preview:!0,inputRef:this.clientSecretInputRef}),a?.hasError("client_secret")&&n.createElement("div",{className:"error-message"},this.displayErrors(a.getError("client_secret"))),n.createElement("p",null,n.createElement(f.x6,null,"Allows Azure and Passbolt API to securely share information.")," ",n.createElement("a",{href:"https://learn.microsoft.com/en-us/azure/marketplace/create-or-update-client-ids-and-secrets#add-a-client-id-and-client-secret",rel:"noopener noreferrer",target:"_blank"},n.createElement(f.x6,null,"Where to find it?")))),n.createElement("div",{className:"input text date-wrapper required "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Secret expiry")),n.createElement("div",{className:"button-inline"},n.createElement("input",{id:"sso-azure-secret-expiry-input",type:"date",className:"fluid form-element "+(t.client_secret_expiry?"":"empty"),name:"client_secret_expiry",ref:this.clientSecretExpiryInputRef,value:t.client_secret_expiry||"",onChange:this.handleInputChange,disabled:this.hasAllInputDisabled()}),n.createElement(ac,{className:"svg-icon"})),a?.hasError("client_secret_expiry")&&n.createElement("div",{className:"error-message"},this.displayErrors(a.getError("client_secret_expiry")))),n.createElement("div",{className:"warning message"},n.createElement("div",null,n.createElement(f.x6,null,n.createElement("b",null,"Warning"),": This secret will expire after some time (typically a few months). Make sure you save the expiry date and rotate it on time."))),n.createElement("div",null,n.createElement("div",{className:"accordion operation-details "+(this.state.advancedSettingsOpened?"":"closed")},n.createElement("div",{className:"accordion-header",onClick:this.handleAdvancedSettingsCLick},n.createElement("button",{type:"button",className:"link no-border",id:"advanced-settings-panel-button"},this.state.advancedSettingsOpened?n.createElement(Vt,{className:"caret-down"}):n.createElement(Wt,{className:"caret-right"}),n.createElement(f.x6,null,"Advanced settings"))))),this.state.advancedSettingsOpened&&n.createElement(n.Fragment,null,n.createElement("div",{className:"select-wrapper input required "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",{htmlFor:"email-claim-input"},n.createElement(f.x6,null,"Email claim")),n.createElement(pn,{id:"email-claim-input",name:"email_claim",items:this.emailClaimList,value:t.email_claim,onChange:this.handleInputChange}),n.createElement("p",null,n.createElement(f.x6,null,"Defines which Azure field needs to be used as Passbolt username."))),"upn"===t.email_claim&&n.createElement("div",{className:"warning message"},n.createElement("div",null,n.createElement(f.x6,null,n.createElement("b",null,"Warning"),": UPN is not active by default on Azure and requires a specific option set on Azure to be working."))),"email"===t.email_claim&&n.createElement("div",{className:"warning message"},n.createElement("div",null,n.createElement(f.x6,null,n.createElement("b",null,"Warning"),": using Azure email field to map with Passbolt username is generally unsafe (see. noauth vulnerability class)."))),n.createElement("div",{className:"select-wrapper input required "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",{htmlFor:"prompt-input"},n.createElement(f.x6,null,"Prompt")),n.createElement(pn,{id:"prompt-input",name:"prompt",items:this.promptOptionList,value:t.prompt,onChange:this.handleInputChange}),n.createElement("p",null,n.createElement(f.x6,null,"Defines the Azure login behaviour by prompting the user to fully login each time or not."))),n.createElement("div",{className:"input-wrapper form-element"},n.createElement("div",{className:"toggle-swith-title"},n.createElement(f.x6,null,"Login hint")),n.createElement("div",{className:"input toggle-switch"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"login_hint",onChange:this.handleInputChange,checked:t.login_hint,disabled:this.hasAllInputDisabled(),id:"login_hint-input"}),n.createElement("label",{htmlFor:"login_hint-input"},n.createElement(f.x6,null,"If checked, users signing in with Microsoft Azure must use their Passbolt email address."))))))}}lc.propTypes={adminSsoContext:i().object,actionFeedbackContext:i().any,context:i().any,clipboardContext:i().object,t:i().func};const cc=N(m($l(oc((0,f.CI)("common")(lc)))));class mc extends n.PureComponent{constructor(e){super(e),this.bindCallbacks(),this.createRefs()}bindCallbacks(){this.handleInputChange=this.handleInputChange.bind(this),this.handleCopyRedirectUrl=this.handleCopyRedirectUrl.bind(this)}createRefs(){this.clientIdInputRef=n.createRef(),this.clientSecretInputRef=n.createRef()}componentDidUpdate(){if(!this.props.adminSsoContext.consumeFocusOnError())return;const e=this.props.adminSsoContext.getErrors();switch(this.getFirstFieldInError(e,["client_id","client_secret"])){case"client_id":this.clientIdInputRef.current.focus();break;case"client_secret":this.clientSecretInputRef.current.focus()}}getFirstFieldInError(e,t){for(let a=0;ae.hasError(t))}handleInputChange(e){const t=e.target,a="checkbox"===t.type?t.checked:t.value,n=t.name;this.props.adminSsoContext.setValue(n,a)}async handleCopyRedirectUrl(){await this.props.clipboardContext.copy(this.fullRedirectUrl,this.translate("The redirection URL has been copied to the clipboard."))}hasAllInputDisabled(){return this.props.adminSsoContext.isProcessing()}displayErrors(e){return Object.values(e)}get urlSelectItems(){return Kl.SUPPORTED_URLS.map(e=>({value:e,label:e}))}get fullRedirectUrl(){return`${this.props.context.userSettings.getTrustedDomain()}/sso/pingone/redirect`}get translate(){return this.props.t}render(){const e=this.props.adminSsoContext,t=e.getSsoConfiguration(),a=e.getErrors();return n.createElement(n.Fragment,null,n.createElement("div",{className:"select-wrapper input required "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",{htmlFor:"sso-pingone-url-input"},n.createElement(f.x6,null,"URL")),n.createElement(pn,{id:"sso-pingone-url-input",name:"url",items:this.urlSelectItems,value:t.url,onChange:this.handleInputChange,disabled:this.hasAllInputDisabled()}),a?.hasError("url")&&n.createElement("div",{className:"error-message"},this.displayErrors(a.getError("url"))),n.createElement("p",null,n.createElement(f.x6,null,"The PingOne authentication URL for your region."))),n.createElement("div",{className:"input text input-wrapper "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",null,n.createElement(f.x6,null,"Redirect URL")),n.createElement("div",{className:"button-inline"},n.createElement("input",{id:"sso-pingone-redirect-url-input",type:"text",className:"fluid form-element disabled",name:"redirect_url",value:this.fullRedirectUrl,placeholder:this.translate("Redirect URL"),readOnly:!0,disabled:!0}),n.createElement("button",{type:"button",onClick:this.handleCopyRedirectUrl,className:"copy-to-clipboard button button-icon"},n.createElement(Ql,null))),n.createElement("p",null,n.createElement(f.x6,null,"The URL to provide to PingOne when registering the application."))),n.createElement("div",{className:"input text required "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",{htmlFor:"sso-pingone-environment-id-input"},n.createElement(f.x6,null,"Environment ID")),n.createElement("input",{id:"sso-pingone-environment-id-input",type:"text",className:"fluid form-element",name:"environment_id",ref:this.inputRefs.environment_id,value:t.environment_id,onChange:this.handleInputChange,placeholder:this.translate("Environment ID"),disabled:this.hasAllInputDisabled()}),a?.hasError("environment_id")&&n.createElement("div",{className:"error-message"},this.displayErrors(a.getError("environment_id"))),n.createElement("p",null,n.createElement(f.x6,null,"The public identifier for the PingOne application.")," ",n.createElement("a",{href:"https://docs.pingidentity.com/pingone/applications/p1_edit_application_oidc.html",rel:"noopener noreferrer",target:"_blank"},n.createElement(f.x6,null,"Where to find it?")))),n.createElement("div",{className:"input text required "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",{htmlFor:"sso-pingone-client-id-input"},n.createElement(f.x6,null,"Application (client) ID")),n.createElement("input",{id:"sso-pingone-client-id-input",type:"text",className:"fluid form-element",name:"client_id",ref:this.inputRefs.client_id,value:t.client_id,onChange:this.handleInputChange,placeholder:this.translate("Application (client) ID"),disabled:this.hasAllInputDisabled()}),a?.hasError("client_id")&&n.createElement("div",{className:"error-message"},this.displayErrors(a.getError("client_id"))),n.createElement("p",null,n.createElement(f.x6,null,"The public identifier for the app in PingOne in UUID format.")," ",n.createElement("a",{href:"https://docs.pingidentity.com/pingone/applications/p1_edit_application_oidc.html",rel:"noopener noreferrer",target:"_blank"},n.createElement(f.x6,null,"Where to find it?")))),n.createElement("div",{className:"input text required "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",{htmlFor:"sso-pingone-secret-input"},n.createElement(f.x6,null,"Secret")),n.createElement(Za,{id:"sso-pingone-secret-input",className:"fluid form-element",onChange:this.handleInputChange,autoComplete:"off",name:"client_secret",placeholder:this.translate("Secret"),disabled:this.hasAllInputDisabled(),value:t.client_secret,preview:!0,inputRef:this.inputRefs.client_secret}),a?.hasError("client_secret")&&n.createElement("div",{className:"error-message"},this.displayErrors(a.getError("client_secret"))),n.createElement("p",null,n.createElement(f.x6,null,"Allows PingOne and Passbolt API to securely share information.")," ",n.createElement("a",{href:"https://docs.pingidentity.com/pingone/applications/p1_edit_application_oidc.html",rel:"noopener noreferrer",target:"_blank"},n.createElement(f.x6,null,"Where to find it?")))),n.createElement("div",{className:"input text required disabled"},n.createElement("label",{htmlFor:"sso-pingone-scope-input"},n.createElement(f.x6,null,"Scope")),n.createElement("input",{id:"sso-pingone-scope-input",type:"text",className:"fluid form-element",name:"scope",value:Gl.SCOPE,disabled:!0}),n.createElement("p",null,n.createElement(f.x6,null,"Defines which PingOne field needs to be used as Passbolt username."))),n.createElement("div",{className:"input text required "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",{htmlFor:"sso-pingone-email-claim-input"},n.createElement(f.x6,null,"Email claim")),n.createElement("input",{id:"sso-pingone-email-claim-input",type:"text",className:"fluid form-element",name:"email_claim",ref:this.inputRefs.email_claim,value:t.email_claim,onChange:this.handleInputChange,placeholder:this.translate("Email claim"),disabled:this.hasAllInputDisabled()}),a?.hasError("email_claim")&&n.createElement("div",{className:"error-message"},this.displayErrors(a.getError("email_claim"))),n.createElement("p",null,n.createElement(f.x6,null,"Defines which PingOne field needs to be used as Passbolt username."))))}}Ec.propTypes={adminSsoContext:i().object,clipboardContext:i().object,context:i().any,t:i().func};const vc=N(oc($l((0,f.CI)("common")(Ec))));class wc extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.bindCallbacks()}get defaultState(){return{loading:!0,providers:[]}}async componentDidMount(){const e=await this.props.adminSsoContext.loadSsoConfiguration();this.setState({loading:!1,providers:e?.providers||[]})}bindCallbacks(){this.handleProviderInputChange=this.handleProviderInputChange.bind(this),this.handleSsoSettingToggle=this.handleSsoSettingToggle.bind(this)}handleProviderInputChange(e){this.props.adminSsoContext.changeProvider({id:e.target.value})}handleSsoSettingToggle(){this.props.adminSsoContext.isSsoConfigActivated()&&this.props.adminSsoContext.disableSso()}hasAllInputDisabled(){return this.props.adminSsoContext.isProcessing()||this.state.loading}get allSsoProviders(){const e=this.state.providers;return hl.map(t=>{const a={...t};return a.disabled=Boolean(a.disabled)||!e.includes(a.id),a}).filter(e=>!e.disabled||e.disabled&&!e?.hiddenIfDisabled)}get supportedSsoProviders(){const e=this.state.providers,t=[];return e.forEach(e=>{const a=hl.find(t=>t.id===e);a&&!a.disabled&&t.push({value:a.id,label:a.name})}),t}isReady(){return this.props.adminSsoContext.isDataReady()}render(){const e=this.props.adminSsoContext,t=e.getSsoConfiguration(),a=e.isSsoConfigActivated();return n.createElement("div",{className:"row"},n.createElement("div",{className:"third-party-provider-settings sso-settings main-column"},n.createElement("div",{className:"main-content"},n.createElement("h3",{className:"title"},n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"ssoToggle",onChange:this.handleSsoSettingToggle,checked:a,disabled:this.hasAllInputDisabled(),id:"ssoToggle"}),n.createElement("label",{htmlFor:"ssoToggle"},n.createElement(f.x6,null,"Single Sign-On")))),this.isReady()&&!a&&n.createElement(n.Fragment,null,n.createElement("h4",{className:"no-border"},n.createElement(f.x6,null,"Select a provider")),n.createElement("div",{className:"provider-list"},this.allSsoProviders.map(e=>n.createElement("div",{key:e.id,className:"provider button "+(e.disabled?"disabled":""),id:e.id,onClick:()=>this.props.adminSsoContext.changeProvider(e)},n.createElement("div",{className:"provider-logo"},e.icon),n.createElement("p",{className:"provider-name"},e.name,n.createElement("br",null),e.disabled&&n.createElement(f.x6,null,"(not yet available)")))))),this.isReady()&&a&&n.createElement("form",{className:"form"},n.createElement("div",{className:"select-wrapper input"},n.createElement("label",{htmlFor:"sso-provider-input"},n.createElement(f.x6,null,"Single Sign-On provider")),n.createElement(pn,{id:"sso-provider-input",name:"provider",items:this.supportedSsoProviders,value:t?.provider,onChange:this.handleProviderInputChange})),t?.provider===_l.PROVIDER_ID&&n.createElement(cc,null),t?.provider===Dl.PROVIDER_ID&&n.createElement(dc,null),t?.provider===Tl.PROVIDER_ID&&n.createElement(pc,null),t?.provider===jl.PROVIDER_ID&&n.createElement(gc,null),t?.provider===Kl.PROVIDER_ID&&n.createElement(vc,null))),this.props.adminSsoContext.hasFormChanged()&&n.createElement("div",{className:"warning message",id:"sso-setting-overridden-banner"},n.createElement("div",null,n.createElement("p",null,n.createElement(f.x6,null,"Don't forget to save your settings to apply your modification."))))),n.createElement(Zl,null),Xa(n.createElement(n.Fragment,null,n.createElement("div",{className:"sidebar-help-section warning message",id:"sso-setting-security-warning-banner"},n.createElement("h3",null,n.createElement(f.x6,null,"Important notice:")),n.createElement("p",null,n.createElement(f.x6,null,"Enabling SSO changes the security risks.")," ",n.createElement(f.x6,null,"For example an attacker with a local machine access maybe be able to access secrets, if the user is still logged in with the Identity provider.")," ",n.createElement(f.x6,null,"Make sure users follow screen lock best practices.")," ",n.createElement("a",{href:"https://passbolt.com/docs/admin/authentication/sso/",target:"_blank",rel:"noopener noreferrer"},n.createElement(f.x6,null,"Learn more")))),n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"Need some help?")),n.createElement("p",null,n.createElement(f.x6,null,"For more information about SSO, checkout the dedicated page on the help website.")),n.createElement("a",{className:"button",href:"https://passbolt.com/docs/admin/authentication/sso/",target:"_blank",rel:"noopener noreferrer"},n.createElement(ps,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),t?.provider===_l.PROVIDER_ID&&n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"How do I configure a AzureAD SSO?")),n.createElement("a",{className:"button",href:"https://docs.microsoft.com/en-us/azure/active-directory/manage-apps/add-application-portal-setup-sso",target:"_blank",rel:"noopener noreferrer"},n.createElement(fc,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),t?.provider===Dl.PROVIDER_ID&&n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"How do I configure a Google SSO?")),n.createElement("a",{className:"button",href:"https://developers.google.com/identity/openid-connect/openid-connect",target:"_blank",rel:"noopener noreferrer"},n.createElement(fc,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),t?.provider===jl.PROVIDER_ID&&n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"How do I configure an AD FS SSO?")),n.createElement("a",{className:"button",href:"https://learn.microsoft.com/en-gb/microsoft-365/troubleshoot/active-directory/set-up-adfs-for-single-sign-on",target:"_blank",rel:"noopener noreferrer"},n.createElement(fc,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),t?.provider===Kl.PROVIDER_ID&&n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"How do I configure PingOne SSO?")),n.createElement("a",{className:"button",href:"https://docs.pingidentity.com/pingone/applications/p1_applications_add_applications.html",target:"_blank",rel:"noopener noreferrer"},n.createElement(fc,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation"))))),document.getElementById("administration-help-panel")))}}wc.propTypes={administrationWorkspaceContext:i().object,adminSsoContext:i().object,actionFeedbackContext:i().any,context:i().any,t:i().func};const kc=N(m(Ne($l((0,f.CI)("common")(wc)))));class _c extends n.Component{render(){return n.createElement("div",{className:"row"},n.createElement("div",{className:"third-party-provider-settings-teasing sso-settings main-column"},n.createElement("div",{className:"main-content"},n.createElement("h3",{className:"title",id:"third-party-provider-settings-title"},n.createElement(f.x6,null,"Single Sign-On"),n.createElement(Ea,{className:"pro-teasing-icon"})),n.createElement("p",null,n.createElement(f.x6,null,"Simplify secure access through integration with identity providers.")),n.createElement("div",{className:"third-party-provider-settings-info"},n.createElement("ul",{className:"third-party-provider-settings-description"},n.createElement("li",null,n.createElement(fs,null),n.createElement(f.x6,null,"Reduce password fatigue and simplify login.")),n.createElement("li",null,n.createElement(fs,null),n.createElement(f.x6,null,"Centralise user authentication management.")),n.createElement("li",null,n.createElement(fs,null),n.createElement(f.x6,null,"Support major identity providers like Google and Microsoft."))),n.createElement("div",null,n.createElement("a",{className:"button primary",href:"https://www.passbolt.com/ce-to-pro?utm_campaign=21060976-CE%20to%20Pro&utm_source=product",target:"_blank",rel:"noopener noreferrer"},n.createElement(f.x6,null,"Upgrade to Passbolt Pro")))))),Xa(n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"Need some help?")),n.createElement("p",null,n.createElement(f.x6,null,"For more information about SSO, checkout the dedicated page on the help website.")),n.createElement("a",{className:"button",href:"https://passbolt.com/docs/admin/authentication/sso/",target:"_blank",rel:"noopener noreferrer"},n.createElement(ps,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}_c.propTypes={context:i().any,t:i().func};const xc=N((0,f.CI)("common")(_c)),Sc=class{constructor(e={remember_me_for_a_month:!1}){this.policy=e.policy,this.rememberMeForAMonth=e.remember_me_for_a_month}},Cc=class{constructor(e={rememberMeForAMonth:!1}){this.policy=e.policy||"opt-in",this.remember_me_for_a_month=e.rememberMeForAMonth}};function Nc(){return Nc=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},getSettings:()=>{},setSettings:()=>{},hasSettingsChanges:()=>{},findSettings:()=>{},setProcessing:()=>{},isProcessing:()=>{},clearContext:()=>{},save:()=>{}});class Ac extends n.Component{constructor(e){super(e),this.state=this.defaultState;const t=e.context.getApiClientOptions();this.mfaPolicyService=new ht(t)}get defaultState(){return{settings:new Sc,currentSettings:new Sc,processing:!0,getCurrentSettings:this.getCurrentSettings.bind(this),getSettings:this.getSettings.bind(this),setSettings:this.setSettings.bind(this),findSettings:this.findSettings.bind(this),hasSettingsChanges:this.hasSettingsChanges.bind(this),isProcessing:this.isProcessing.bind(this),setProcessing:this.setProcessing.bind(this),clearContext:this.clearContext.bind(this),save:this.save.bind(this)}}async findSettings(e=()=>{}){this.setProcessing(!0);const t=await this.mfaPolicyService.find(),a=new Sc(t);this.setState({currentSettings:a,settings:a},e),this.setProcessing(!1)}async save(){this.setProcessing(!0);const e=new Cc(this.state.settings);await this.mfaPolicyService.save(e),await this.findSettings()}getCurrentSettings(){return this.state.currentSettings}getSettings(){return this.state.settings}setSettings(e,t,a=()=>{}){const n=Object.assign({},this.state.settings,{[e]:t});this.setState({settings:n},a)}isProcessing(){return this.state.processing}setProcessing(e){this.setState({processing:e})}hasSettingsChanges(){return JSON.stringify(this.state.currentSettings)!==JSON.stringify(this.state.settings)}clearContext(){const{currentSettings:e,settings:t,processing:a}=this.defaultState;this.setState({currentSettings:e,settings:t,processing:a})}render(){return n.createElement(Tc.Provider,{value:this.state},this.props.children)}}Ac.propTypes={context:i().any,children:i().any,t:i().any,actionFeedbackContext:i().object};const Ic=N(Ac);function Rc(e){return class extends n.Component{render(){return n.createElement(Tc.Consumer,null,t=>n.createElement(e,Nc({adminMfaPolicyContext:t},this.props)))}}}class Pc extends n.Component{constructor(e){super(e),this.bindCallbacks()}bindCallbacks(){this.handleSave=this.handleSave.bind(this)}isSaveEnabled(){return!this.props.adminMfaPolicyContext.isProcessing()}async handleSave(){if(this.isSaveEnabled())try{await this.props.adminMfaPolicyContext.save(),this.handleSaveSuccess()}catch(e){this.handleSaveError(e)}finally{this.props.adminMfaPolicyContext.setProcessing(!1)}}async handleSaveSuccess(){await this.props.actionFeedbackContext.displaySuccess(this.props.t("The MFA policy settings were updated."))}async handleSaveError(e){"UserAbortsOperationError"!==e.name&&(console.error(e),await this.props.actionFeedbackContext.displayError(e.message))}render(){return n.createElement("div",{className:"actions-wrapper"},n.createElement("button",{className:"button primary form",type:"button",disabled:!this.isSaveEnabled(),id:"save-settings",onClick:this.handleSave},n.createElement("span",null,n.createElement(f.x6,null,"Save"))))}}Pc.propTypes={adminMfaPolicyContext:i().object,actionFeedbackContext:i().object,t:i().func};const Dc=Rc(m((0,f.CI)("common")(Pc)));class Oc extends n.Component{constructor(e){super(e),this.bindCallbacks()}async componentDidMount(){await this.findSettings()}componentWillUnmount(){this.props.adminMfaPolicyContext.clearContext()}bindCallbacks(){this.handleInputChange=this.handleInputChange.bind(this)}async findSettings(){await this.props.adminMfaPolicyContext.findSettings()}async handleInputChange(e){const t=e.target.name;let a=e.target.value;"rememberMeForAMonth"===t&&(a=e.target.checked),this.props.adminMfaPolicyContext.setSettings(t,a)}hasAllInputDisabled(){return this.props.adminMfaPolicyContext.isProcessing()}render(){const e=this.props.adminMfaPolicyContext.getSettings();return n.createElement("div",{className:"row"},n.createElement("div",{className:"mfa-policy-settings main-column"},n.createElement("div",{className:"main-content"},n.createElement("h3",{className:"title",id:"mfa-policy-settings-title"},n.createElement(f.x6,null,"MFA Policy")),n.createElement("form",{className:"form"},n.createElement("h4",{className:"no-border",id:"mfa-policy-subtitle"},n.createElement(f.x6,null,"Default users multi factor authentication policy")),n.createElement("p",{id:"mfa-policy-description"},n.createElement(f.x6,null,"You can choose the default behaviour of multi factor authentication for all users.")),n.createElement("div",{className:"radiolist-alt"},n.createElement("div",{className:"input radio "+("mandatory"===e?.policy?"checked":""),id:"mfa-policy-mandatory"},n.createElement("input",{type:"radio",value:"mandatory",onChange:this.handleInputChange,name:"policy",checked:"mandatory"===e?.policy,id:"mfa-policy-mandatory-radio",disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"mfa-policy-mandatory-radio"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Prompt")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"Users have to enable multi factor authentication. If they don't, they will be reminded every time they log in.")))),n.createElement("div",{className:"input radio "+("opt-in"===e?.policy?"checked":""),id:"mfa-policy-opt-in"},n.createElement("input",{type:"radio",value:"opt-in",onChange:this.handleInputChange,name:"policy",checked:"opt-in"===e?.policy,id:"mfa-policy-opt-in-radio",disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"mfa-policy-opt-in-radio"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Opt-in (default)")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"Users have the choice to enable multi factor authentication in their profile workspace."))))),n.createElement("h4",{id:"mfa-policy-remember-subtitle"},"Remember a device for a month"),n.createElement("span",{className:"input toggle-switch form-element "},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"rememberMeForAMonth",onChange:this.handleInputChange,disabled:this.hasAllInputDisabled(),checked:e?.rememberMeForAMonth,id:"remember-toggle-button"}),n.createElement("label",{htmlFor:"remember-toggle-button"},n.createElement(f.x6,null,"Allow “Remember this device for a month.” option during MFA."))))),this.props.adminMfaPolicyContext.hasSettingsChanges()&&n.createElement("div",{className:"warning message",id:"mfa-policy-setting-banner"},n.createElement("div",null,n.createElement("p",null,n.createElement(f.x6,null,"Don't forget to save your settings to apply your modification."))))),n.createElement(Dc,null),Xa(n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"Need some help?")),n.createElement("p",null,n.createElement(f.x6,null,"For more information about MFA policy settings, checkout the dedicated page on the help website.")),n.createElement("a",{className:"button",href:"https://passbolt.com/docs/admin/authentication/mfa-policy",target:"_blank",rel:"noopener noreferrer"},n.createElement(ps,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}Oc.propTypes={context:i().object,administrationWorkspaceContext:i().object,adminMfaPolicyContext:i().object,t:i().func};const Mc=N(Ne(Rc((0,f.CI)("common")(Oc))));class Uc extends n.Component{render(){return n.createElement("div",{className:"row"},n.createElement("div",{className:"mfa-settings-teasing main-column"},n.createElement("div",{className:"main-content"},n.createElement("h3",{className:"title",id:"mfa-settings-title"},n.createElement(f.x6,null,"MFA Policy"),n.createElement(Ea,{className:"pro-teasing-icon"})),n.createElement("p",null,n.createElement(f.x6,null,"Enhance security by enforcing multi-factor authentication.")),n.createElement("div",{className:"mfa-settings-info"},n.createElement("ul",{className:"mfa-settings-description"},n.createElement("li",null,n.createElement(fs,null),n.createElement(f.x6,null,"Strengthen user authentication.")),n.createElement("li",null,n.createElement(fs,null),n.createElement(f.x6,null,"Protect against unauthorised access.")),n.createElement("li",null,n.createElement(fs,null),n.createElement(f.x6,null,"Flexible configuration based on user roles or access levels."))),n.createElement("div",null,n.createElement("a",{className:"button primary",href:"https://www.passbolt.com/ce-to-pro?utm_campaign=21060976-CE%20to%20Pro&utm_source=product",target:"_blank",rel:"noopener noreferrer"},n.createElement(f.x6,null,"Upgrade to Passbolt Pro")))))),Xa(n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"Need some help?")),n.createElement("p",null,n.createElement(f.x6,null,"For more information about MFA policy settings, checkout the dedicated page on the help website.")),n.createElement("a",{className:"button",href:"https://passbolt.com/docs/admin/authentication/mfa-policy",target:"_blank",rel:"noopener noreferrer"},n.createElement(Sa,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}Uc.propTypes={context:i().object,t:i().func};const Fc=N((0,f.CI)("common")(Uc));class jc extends se{constructor(e,t={}){super(ae.validate(jc.ENTITY_NAME,e,jc.getSchema()),t)}static getSchema(){return{type:"object",required:["id","name"],properties:{id:{type:"string",format:"uuid"},name:{type:"string",maxLength:255}}}}get id(){return this._props.id}get name(){return this._props.name}static get ENTITY_NAME(){return"Action"}}const Lc=jc;class qc extends se{constructor(e,t={}){super(ae.validate(qc.ENTITY_NAME,e,qc.getSchema()),t)}static getSchema(){return{type:"object",required:["id","name"],properties:{id:{type:"string",format:"uuid"},name:{type:"string",maxLength:255}}}}get id(){return this._props.id}get name(){return this._props.name}static get ENTITY_NAME(){return"UiAction"}}const zc=qc;class Kc extends se{constructor(e,t={}){super(ae.validate(Kc.ENTITY_NAME,e,Kc.getSchema()),t),this._props.action&&(this._action=new Lc(this._props.action,{clone:!1})),delete this._props.action,this._props.ui_action&&(this._ui_action=new zc(this._props.ui_action,{clone:!1})),delete this._props.ui_action}static getSchema(){return{type:"object",required:["id","role_id","foreign_model","foreign_id","control_function"],properties:{id:{type:"string",format:"uuid"},role_id:{type:"string",format:"uuid"},foreign_model:{type:"string",enum:[Kc.FOREIGN_MODEL_ACTION,Kc.FOREIGN_MODEL_UI_ACTION]},foreign_id:{type:"string",format:"uuid"},control_function:{type:"string",enum:[K,V,G]},action:Lc.getSchema(),ui_action:zc.getSchema()}}}toDto(e){const t=Object.assign({},this._props);return e?(this._action&&e.action&&(t.action=this._action.toDto()),this._ui_action&&e.ui_action&&(t.ui_action=this._ui_action.toDto()),t):t}toUpdateDto(){return{id:this.id,control_function:this.controlFunction}}toJSON(){return this.toDto(Kc.ALL_CONTAIN_OPTIONS)}get id(){return this._props.id}get roleId(){return this._props.role_id}get foreignModel(){return this._props.foreign_model}get foreignId(){return this._props.foreign_id}get controlFunction(){return this._props.control_function}set controlFunction(e){ae.validateProp("control_function",e,Kc.getSchema().properties.control_function),this._props.control_function=e}get action(){return this._action||null}get uiAction(){return this._ui_action||null}static get ENTITY_NAME(){return"Rbac"}static get ALL_CONTAIN_OPTIONS(){return{action:!0,ui_action:!0}}static get FOREIGN_MODEL_ACTION(){return"Action"}static get FOREIGN_MODEL_UI_ACTION(){return"UiAction"}}const Vc=Kc;class Gc{static error(e){console.error(e);try{e instanceof Error&&"function"==typeof e.toJSON&&console.log(`Error: ${e.message}\nError structure: ${JSON.stringify(Gc.serializeError(e))}`)}catch(e){console.error("The logger was unable to extract additional error information",e)}}static serializeError(e){const{stack:t,cause:a,...n}=e.toJSON();return e.cause&&e.cause instanceof Error&&(n.cause=Gc.serializeError(e.cause)),e instanceof Z&&Array.isArray(e.errors)&&(n.errors=e.errors.map(e=>Gc.serializeError(e))),n}}const Bc=class extends de{static _cachedSchema={};get entityClass(){throw new Error("The collection class should declare the entity class that is handled.")}constructor(e=[],t={}){super(e,t),(t?.validate??!0)&&this.validateSchema(),this.pushMany(this._props,{...t,clone:!1}),this._props=null}validateSchema(){this._props=ae.validate(this.constructor.name,this._props,this.cachedSchema)}get cachedSchema(){return this.constructor._cachedSchema[this.constructor.name]||(this.constructor._cachedSchema[this.constructor.name]=this.constructor.getSchema()),this.constructor._cachedSchema[this.constructor.name]}static getSchema(){throw new Error("The collection class should declare its schema.")}buildOrCloneEntity(e,t={}){if(!e||"object"!=typeof e)throw new TypeError(`${this.entityClass.name}::buildOrCloneEntity expects "data" to be an object.`);return e instanceof this.entityClass&&(e=e.toDto(this.entityClass?.ALL_CONTAIN_OPTIONS)),new this.entityClass(e,t)}validateBuildRules(e,t={}){}validate(e={}){try{this.validateItems(e)}catch(e){if(!(e instanceof Z))throw e;return e}return null}validateItems(e={}){if(0===this.length)return null;const t=new Z;if(this.items.forEach((a,n)=>{const s=a.validate(e);s&&t.addItemValidationError(n,s)}),t.hasErrors())throw t}push(e,t={},a={}){const n=this.buildOrCloneEntity(e,t);this.validateBuildRules(n,a?.validateBuildRules),this._items.push(n),a?.onItemPushed?.(n)}pushOrReplace(e,t={},a={}){const n=a?.replacePropertyName||"id",s=this.items.findIndex(t=>t[n]===e[n]);if(-1!==s){this.items.splice(s,1);const n=this.buildOrCloneEntity(e,t);this.validateBuildRules(n,a?.validateBuildRules),this.items.splice(s,0,n)}else this.push(e,t,a)}pushMany(e,t={},a={}){if(!Array.isArray(e))throw new TypeError(`${this.constructor.name} pushMany expects "data" to be an array.`);e.forEach((e,n)=>{try{this.push(e,t,a)}catch(e){this.handlePushItemError(n,e,t)}})}handlePushItemError(e,t,a){if(!(t instanceof X||t instanceof Z||t instanceof ce))throw t;if(!a?.ignoreInvalidEntity){const a=new Z;throw a.addItemValidationError(e,t),a}{const a=`${this.entityClass.name}::pushMany ignored item (${e}) due to validation error.`;Gc.error(new Error(a,{cause:t}))}}},Wc=class extends Bc{get entityClass(){return Vc}constructor(e=[],t={}){super(e,t)}static getSchema(){return{type:"array",items:Vc.getSchema()}}validateBuildRules(e,t={}){this.assertNotExist("id",e._props.id,{haystackSet:t?.uniqueIdsSetCache})}toBulkUpdateDto(){return this.items.map(e=>e.toUpdateDto())}findRbacByUiActionName(e){if("string"!=typeof e&&!(e instanceof String))throw new Error("The name parameter should be a valid string.");return this.items.find(t=>t.uiAction?.name===e)}findRbacByRoleAndActionName(e,t){if(!(e instanceof ge))throw new Error("The role parameter should be a role entity.");if("string"!=typeof t&&!(t instanceof String))throw new Error("The name parameter should be a valid string.");return this.items.find(a=>a.roleId===e.id&&(a.uiAction?.name===t||a.action?.name===t))}findRbacByActionName(e){if("string"!=typeof e&&!(e instanceof String))throw new Error("The name parameter should be a valid string.");return this.items.find(t=>t.action?.name===e)}pushMany(e,t={},a={}){const n=new Set(this.extract("id"));a={onItemPushed:e=>{n.add(e._props.id)},validateBuildRules:{...a?.validateBuildRules,uniqueIdsSetCache:n},...a},super.pushMany(e,t,a)}remove(e){const t=this.items.length;let a=0;for(;a{},setRbacsUpdated:()=>{},save:()=>{},isProcessing:()=>{},hasSettingsChanges:()=>{},clearContext:()=>{}});class Zc extends n.Component{constructor(e){super(e),this.state=this.defaultState;const t=e.context.getApiClientOptions();this.rbacApiService=new Hc(t)}get defaultState(){return{processing:!1,rbacs:null,rbacsUpdated:new Wc([]),setRbacs:this.setRbacs.bind(this),setRbacsUpdated:this.setRbacsUpdated.bind(this),isProcessing:this.isProcessing.bind(this),hasSettingsChanges:this.hasSettingsChanges.bind(this),save:this.save.bind(this),clearContext:this.clearContext.bind(this)}}async setRbacs(e){this.setState({rbacs:e})}async setRbacsUpdated(e){this.setState({rbacsUpdated:e})}isProcessing(){return this.state.processing}setProcessing(e){this.setState({processing:e})}hasSettingsChanges(){return this.state.rbacsUpdated.items.length>0}clearContext(){const{rbacs:e,rbacsUpdated:t,processing:a}=this.defaultState;this.setState({rbacs:e,rbacsUpdated:t,processing:a})}async save(){this.setProcessing(!0);try{const e=this.state.rbacsUpdated.toBulkUpdateDto();if(0===this.state.rbacsUpdated.length)return;const t=(await this.rbacApiService.updateAll(e,{ui_action:!0,action:!0})).body,a=this.state.rbacs;t.forEach(e=>a.pushOrReplace(new Vc(e)));const n=new Wc([]);this.setState({rbacs:a,rbacsUpdated:n})}finally{this.setProcessing(!1)}}render(){return n.createElement(Yc.Provider,{value:this.state},this.props.children)}}Zc.propTypes={context:i().any,children:i().any};const Jc=N(Zc);function Xc(e){return class extends n.Component{render(){return n.createElement(Yc.Consumer,null,t=>n.createElement(e,$c({adminRbacContext:t},this.props)))}}}class Qc extends n.Component{constructor(e){super(e),this.bindCallbacks()}bindCallbacks(){this.handleSaveClick=this.handleSaveClick.bind(this)}async handleSaveClick(){try{await this.props.adminRbacContext.save(),this.handleSaveSuccess()}catch(e){this.handleSaveError(e)}}isSaveEnabled(){return!this.props.adminRbacContext.isProcessing()}async handleSaveSuccess(){await this.props.actionFeedbackContext.displaySuccess(this.props.t("The role-based access control settings were updated."))}async handleSaveError(e){console.error(e),await this.props.actionFeedbackContext.displayError(e.message)}render(){return n.createElement("div",{className:"actions-wrapper"},n.createElement("button",{className:"button primary form",type:"button",disabled:!this.isSaveEnabled(),onClick:this.handleSaveClick},n.createElement("span",null,n.createElement(f.x6,null,"Save"))))}}Qc.propTypes={context:i().object,adminRbacContext:i().object,actionFeedbackContext:i().object,t:i().func};const em=Xc(m((0,f.CI)("common")(Qc)));class tm extends n.Component{blankColumnSectionForRoles(){const e=[];for(let t=0;t{n.add(e._props.id),s.add(e._props.name)},validateBuildRules:{...a?.validateBuildRules,uniqueIdsSetCache:n,uniqueNamesSetCache:s},...a},super.pushMany(e,t,a)}filterByCustomRole(){this.filterByCallback(e=>!e.isAReservedRole())}filterOutGuestRole(){this.filterByCallback(e=>!e.isGuest())}getById(e){return this._items.find(t=>t.id===e)||null}static get ENTITY_NAME(){return"Roles"}};class sm extends n.Component{constructor(e){super(e),this.handleInputChange=this.handleInputChange.bind(this)}handleInputChange(e,t){this.props.onChange(t,this.props.actionName,e.target.value)}get allowedCtlFunctions(){const e=[{value:K,label:this.props.t("Allow")},{value:V,label:this.props.t("Deny")}];return this.props.actionName===U&&e.push({value:G,label:this.props.t("Allow group manager"),title:this.props.t("Allow group manager")}),e}get rowClassName(){return this.props.actionName.toLowerCase().replaceAll(/\W/g,"-")}getCtlFunctionForRole(e){const t=this.props.rbacsUpdated?.findRbacByRoleAndActionName(e,this.props.actionName)||this.props.rbacs?.findRbacByRoleAndActionName(e,this.props.actionName);return t?.controlFunction||null}hasChanged(){return!!this.props.rbacsUpdated.findRbacByUiActionName(this.props.actionName)}render(){let e=[];return this.props.roles&&(e=this.props.roles),n.createElement(n.Fragment,null,n.createElement("div",{className:`rbac-row ${this.rowClassName} flex-container inner level-${this.props.level} ${this.hasChanged()?"highlighted":""}`},n.createElement("div",{className:"flex-item first"},n.createElement("span",null,this.props.label)),n.createElement("div",{className:"flex-item"},n.createElement(pn,{className:"admin inline",items:this.allowedCtlFunctions,value:K,disabled:!0})),e.items.map(e=>n.createElement("div",{key:`${this.props.actionName}-${e.id}`,className:"flex-item input"},n.createElement(pn,{className:"inline",items:this.allowedCtlFunctions,value:this.getCtlFunctionForRole(e),disabled:!(this.props.rbacs?.length>0&&this.getCtlFunctionForRole(e)),onChange:t=>this.handleInputChange(t,e)}),!this.getCtlFunctionForRole(e)&&n.createElement("div",{className:"warning-message"},"There is no valid setting found for this action.")))))}}sm.propTypes={label:i().string.isRequired,level:i().number.isRequired,actionName:i().string.isRequired,rbacs:i().object,rbacsUpdated:i().object,roles:i().instanceOf(nm).isRequired,onChange:i().func.isRequired,t:i().func};const im=(0,f.CI)("common")(sm);class rm extends sa{constructor(e){super(e,rm.RESOURCE_NAME)}static get RESOURCE_NAME(){return"roles"}async findAll(){const e=await this.apiClient.findAll(),t=e.body&&e.body.length?e.body:[];return new oa({header:e.header,body:t})}async create(e){if(!e||!e.name)throw new TypeError("Role creation failed, invalid role data.");(0,ie.A)(e.name);const t=await this.apiClient.create(e);return new oa(t)}async update(e,t){if(!e)throw new TypeError("Role update failed, role id is required.");if(!ta(e))throw new TypeError("Role update failed, role id is not a valid uuid.");if(!t||!t.name)throw new TypeError("Role update failed, invalid role data.");(0,ie.A)(t.name);const a=await this.apiClient.update(e,t);return new oa(a)}async delete(e){if(!ta(e))throw new TypeError("Role deletion failed, roleId is not a valid uuid.");const t=await this.apiClient.delete(e);return new oa(t)}}var om;function lm(){return lm=Object.assign?Object.assign.bind():function(e){for(var t=1;tthis.roleEntity.validate(e));verifyDataHealth=(0,po.A)(e=>this.roleEntity.verifyHealth());handleClose(){this.props.onClose()}handleInputChange(e){const t=e.target,a=t.value,n=t.name;this.roleEntity.set(n,a,{validate:!1});const s={role:this.roleEntity.toDto()};this.setState(s)}async handleFormSubmit(e){if(e.preventDefault(),this.state.processing)return;this.setState({hasAlreadyBeenValidated:!0,processing:!0});const t=this.roleEntity.validate();if(t?.hasErrors()||this.roleEntity.isAReservedRole())return this.focusFirstFieldError(),void this.setState({processing:!1});await this.props.onSubmit(this.roleEntity),this.handleClose()}focusFirstFieldError(){this.nameRef.current.focus()}hasAllInputDisabled(){return this.state.processing}get translate(){return this.props.t}render(){const e=this.verifyDataHealth(this.state.role),t=this.state.hasAlreadyBeenValidated?this.validateForm(this.state.role):null,a=this.state.hasAlreadyBeenValidated&&this.roleEntity.isAReservedRole();return n.createElement(qt,{className:"role-create-dialog",title:this.translate("Create role"),onClose:this.handleClose,disabled:this.hasAllInputDisabled()},n.createElement("form",{className:"role-create-form",onSubmit:this.handleFormSubmit,noValidate:!0},n.createElement("div",{className:"form-content"},n.createElement("div",{className:`input text required ${t?.hasError("name")||a?"error":""} ${this.hasAllInputDisabled()?"disabled":""}`},n.createElement("label",{htmlFor:"role-name-input"},n.createElement(f.x6,null,"Role name"),e?.hasErrors()&&n.createElement(tt,{className:"attention-required"})),n.createElement("input",{id:"role-name-input",name:"name",ref:this.nameRef,type:"text",value:this.state.role.name,placeholder:this.props.t("New role"),maxLength:ge.ROLE_NAME_MAX_LENGTH,disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,autoComplete:"off",autoFocus:!0}),t?.hasErrors()&&n.createElement("div",{className:"error-message"},t?.hasError("name","maxLength")&&n.createElement(f.x6,null,"A name can not be more than 50 char in length."),t?.hasError("name","minLength")&&n.createElement(f.x6,null,"A name is required."),t?.hasError("name","trailing-spaces")&&n.createElement(f.x6,null,"The name contains forbidden trailing spaces.")),t?.hasError("name","maxLength")&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"A name can not be more than 255 char in length.")),a&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"This name is reserved by the system.")),e?.hasError("name","maxLength")&&n.createElement("div",{className:"name warning-message"},n.createElement("strong",null,n.createElement(f.x6,null,"Warning:"))," ",n.createElement(f.x6,null,"this is the maximum size for this field, make sure your data was not truncated.")))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement(gn,{disabled:this.hasAllInputDisabled(),onClick:this.handleClose}),n.createElement(qs,{disabled:this.hasAllInputDisabled(),processing:this.state.processing,value:this.translate("Save")}))))}}bm.propTypes={onClose:i().func,onSubmit:i().func.isRequired,t:i().func};const fm=(0,f.CI)("common")(bm);function Em(){return Em=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},onClose:()=>{}});class wm extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.bindCallbacks(),this.createRefs()}get defaultState(){return{dropdownOpen:!1,onClose:this.handleCloseDropdown.bind(this),onOpen:this.handleOpenDropdown.bind(this)}}createRefs(){this.dropdownRef=n.createRef()}bindCallbacks(){this.handleDocumentClickEvent=this.handleDocumentClickEvent.bind(this),this.handleDocumentContextualMenuEvent=this.handleDocumentContextualMenuEvent.bind(this),this.handleDocumentDragStartEvent=this.handleDocumentDragStartEvent.bind(this),this.handleCloseDropdown=this.handleCloseDropdown.bind(this)}componentDidMount(){document.addEventListener("click",this.handleDocumentClickEvent,{capture:!0}),document.addEventListener("contextmenu",this.handleDocumentContextualMenuEvent,{capture:!0}),document.addEventListener("dragstart",this.handleDocumentDragStartEvent,{capture:!0})}componentWillUnmount(){document.removeEventListener("click",this.handleDocumentClickEvent,{capture:!0}),document.removeEventListener("contextmenu",this.handleDocumentContextualMenuEvent,{capture:!0}),document.removeEventListener("dragstart",this.handleDocumentDragStartEvent,{capture:!0})}handleDocumentDragStartEvent(){this.handleCloseDropdown()}handleDocumentClickEvent(e){this.dropdownRef.current.contains(e.target)||this.handleCloseDropdown()}handleDocumentContextualMenuEvent(e){this.dropdownRef.current.contains(e.target)||this.handleCloseDropdown()}handleCloseDropdown(){this.setState({dropdownOpen:!1})}handleOpenDropdown(){const e=!this.state.dropdownOpen;this.setState({dropdownOpen:e})}render(){return n.createElement(vm.Provider,{value:this.state},n.createElement("div",{className:"dropdown",ref:this.dropdownRef},this.props.children))}}function km(e){return class extends n.Component{render(){return n.createElement(vm.Consumer,null,t=>n.createElement(e,Em({dropdownContext:t},this.props)))}}}wm.propTypes={children:i().any};class _m extends n.Component{render(){return n.createElement(wm,null,this.props.children)}}_m.propTypes={children:i().any.isRequired};const xm=_m;class Sm extends n.Component{constructor(e){super(e),this.bindCallbacks()}bindCallbacks(){this.handleDropdownMenuClickEvent=this.handleDropdownMenuClickEvent.bind(this)}handleDropdownMenuClickEvent(){this.props.dropdownContext.onOpen()}get dropdownOpen(){return this.props.dropdownContext.dropdownOpen}render(){return n.createElement("button",{type:"button",className:`${this.props.className} ${this.dropdownOpen?"open":""}`,disabled:this.props.disabled,onClick:this.handleDropdownMenuClickEvent},this.props.children)}}Sm.defaultProps={disabled:!1,direction:"right",className:"button-dropdown"},Sm.propTypes={className:i().string,disabled:i().bool,direction:i().string,dropdownContext:i().any,children:i().any};const Cm=km(Sm);class Nm extends n.Component{get dropdownMenuMustShow(){return this.props.dropdownContext.dropdownOpen}render(){return this.dropdownMenuMustShow&&n.createElement("ul",{className:`dropdown-content menu visible ${this.props.className} ${this.props.direction}`},this.props.children)}}Nm.defaultProps={direction:"right"},Nm.propTypes={direction:i().string,className:i().string,dropdownContext:i().any,children:i().any};const Tm=km(Nm);class Am extends n.Component{constructor(e){super(e),this.bindCallback()}bindCallback(){this.handleClick=this.handleClick.bind(this)}handleClick(){this.props.keepOpenOnClick||this.props.dropdownContext.onClose()}render(){return n.createElement("li",{onClick:this.handleClick,className:this.props.separator?"separator-after":""},n.createElement("div",{className:"row"},n.createElement("div",{className:"main-cell-wrapper"},n.createElement("div",{className:"main-cell"},this.props.children))))}}Am.defaultProps={keepOpenOnClick:!1},Am.propTypes={separator:i().bool,keepOpenOnClick:i().bool,dropdownContext:i().any,children:i().any};const Im=km(Am);class Rm extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.initEventHandlers()}get defaultState(){return{processing:!1}}initEventHandlers(){this.handleClose=this.handleClose.bind(this),this.handleFormSubmit=this.handleFormSubmit.bind(this)}async handleFormSubmit(e){e.preventDefault(),this.state.processing||(this.delete(),this.handleClose())}handleClose(){this.props.onClose()}delete(){this.setState({processing:!0}),this.props.onSubmit(this.props.role)}hasAllInputDisabled(){return this.state.processing}get translate(){return this.props.t}render(){return n.createElement(qt,{title:this.translate("Delete role?"),onClose:this.handleClose,disabled:this.state.processing,className:"delete-role-dialog"},n.createElement("form",{onSubmit:this.handleFormSubmit,noValidate:!0},n.createElement("div",{className:"form-content"},n.createElement("p",null,n.createElement(f.x6,null,"Are you sure you want to delete the role"," ",n.createElement("strong",{className:"dialog-variable"},{roleName:this.props.role.name}),"?")),n.createElement("p",null,n.createElement(f.x6,null,"Once the role is deleted, it will be removed permanently and will not be recoverable."))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement(gn,{disabled:this.hasAllInputDisabled(),onClick:this.handleClose}),n.createElement(qs,{disabled:this.hasAllInputDisabled(),processing:this.state.processing,value:this.translate("Delete"),warning:!0}))))}}Rm.propTypes={onClose:i().func,onSubmit:i().func,role:i().instanceOf(ge).isRequired,t:i().func};const Pm=(0,f.CI)("common")(Rm);class Dm extends n.Component{constructor(e){super(e),this.roleEntity=new ge(e.role),this.state=this.defaultState,this.createInputRefs(),this.bindEventHandlers()}get defaultState(){return{processing:!1,role:this.roleEntity.toDto(),hasAlreadyBeenValidated:!1}}createInputRefs(){this.nameRef=n.createRef()}bindEventHandlers(){this.handleClose=this.handleClose.bind(this),this.handleInputChange=this.handleInputChange.bind(this),this.handleFormSubmit=this.handleFormSubmit.bind(this)}validateForm=(0,po.A)(e=>this.roleEntity.validate(e));verifyDataHealth=(0,po.A)(e=>this.roleEntity.verifyHealth());handleClose(){this.props.onClose()}handleInputChange(e){const t=e.target,a=t.value,n=t.name;this.roleEntity.set(n,a,{validate:!1});const s={role:this.roleEntity.toDto()};this.setState(s)}async handleFormSubmit(e){if(e.preventDefault(),this.state.processing)return;this.setState({hasAlreadyBeenValidated:!0,processing:!0});const t=this.roleEntity.validate();if(t?.hasErrors()||this.roleEntity.isAReservedRole())return this.focusFirstFieldError(),void this.setState({processing:!1});await this.props.onSubmit(this.roleEntity),this.handleClose()}focusFirstFieldError(){this.nameRef.current.focus()}hasAllInputDisabled(){return this.state.processing}get translate(){return this.props.t}render(){const e=this.verifyDataHealth(this.state.role),t=this.state.hasAlreadyBeenValidated?this.validateForm(this.state.role):null,a=this.state.hasAlreadyBeenValidated&&this.roleEntity.isAReservedRole();return n.createElement(qt,{className:"role-edit-dialog",title:this.translate("Rename role"),onClose:this.handleClose,disabled:this.hasAllInputDisabled()},n.createElement("form",{className:"role-edit-form",onSubmit:this.handleFormSubmit,noValidate:!0},n.createElement("div",{className:"form-content"},n.createElement("div",{className:`input text required ${t?.hasError("name")||a?"error":""} ${this.hasAllInputDisabled()?"disabled":""}`},n.createElement("label",{htmlFor:"role-name-input"},n.createElement(f.x6,null,"Role name"),e?.hasErrors()&&n.createElement(tt,{className:"attention-required"})),n.createElement("input",{id:"role-name-input",name:"name",ref:this.nameRef,type:"text",value:this.state.role.name,maxLength:ge.ROLE_NAME_MAX_LENGTH,disabled:this.hasAllInputDisabled(),onChange:this.handleInputChange,autoComplete:"off",autoFocus:!0}),t?.hasErrors()&&n.createElement("div",{className:"error-message"},t?.hasError("name","maxLength")&&n.createElement(f.x6,null,"A name can not be more than 50 char in length."),t?.hasError("name","minLength")&&n.createElement(f.x6,null,"A name is required."),t?.hasError("name","trailing-spaces")&&n.createElement(f.x6,null,"The name contains forbidden trailing spaces.")),a&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"This name is reserved by the system.")),e?.hasError("name","maxLength")&&n.createElement("div",{className:"name warning-message"},n.createElement("strong",null,n.createElement(f.x6,null,"Warning:"))," ",n.createElement(f.x6,null,"this is the maximum size for this field, make sure your data was not truncated.")))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement(gn,{disabled:this.hasAllInputDisabled(),onClick:this.handleClose}),n.createElement(qs,{disabled:this.hasAllInputDisabled(),processing:this.state.processing,value:this.translate("Save")}))))}}Dm.propTypes={onClose:i().func,onSubmit:i().func.isRequired,role:i().instanceOf(ge).isRequired,t:i().func};const Om=(0,f.CI)("common")(Dm);class Mm extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.initEventHandlers()}get defaultState(){return{processing:!1}}initEventHandlers(){this.handleClose=this.handleClose.bind(this),this.handleFormSubmit=this.handleFormSubmit.bind(this)}async handleFormSubmit(e){e.preventDefault(),this.state.processing||(this.setState({processing:!0}),this.handleClose())}handleClose(){this.props.onClose()}hasAllInputDisabled(){return this.state.processing}get translate(){return this.props.t}render(){return n.createElement(qt,{title:this.translate("Delete role"),onClose:this.handleClose,disabled:this.state.processing,className:"delete-role-not-allowed-dialog"},n.createElement("form",{onSubmit:this.handleFormSubmit,noValidate:!0},n.createElement("div",{className:"form-content"},n.createElement("p",null,n.createElement(f.x6,null,"The role ",n.createElement("strong",{className:"dialog-variable"},{roleName:this.props.role.name})," can’t be deleted yet.")),n.createElement("p",null,n.createElement(f.x6,{count:this.props.usersCount},{count:this.props.usersCount}," user is still assigned to this role.")," ",n.createElement(f.x6,{count:this.props.usersCount},"Assign him a different role, then try deleting"," ",n.createElement("strong",{className:"dialog-variable"},{roleName:this.props.role.name})," again."))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement(gn,{disabled:this.hasAllInputDisabled(),onClick:this.handleClose}),n.createElement(qs,{disabled:this.hasAllInputDisabled(),processing:this.state.processing,value:this.translate("Ok")}))))}}Mm.propTypes={onClose:i().func,role:i().instanceOf(ge).isRequired,usersCount:i().number.isRequired,t:i().func};const Um=(0,f.CI)("common")(Mm);class Fm extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.bindCallbacks();const t=this.props.context.getApiClientOptions();this.roleApiService=new this.props.RoleApiService(t),this.rbacApiService=new this.props.RbacApiService(t),this.userApiService=new this.props.UserApiService(t)}get defaultState(){return{roles:null}}bindCallbacks(){this.updateRbacControlFunction=this.updateRbacControlFunction.bind(this),this.handleAddRoleClick=this.handleAddRoleClick.bind(this),this.createNewRole=this.createNewRole.bind(this),this.handleDeleteRoleClick=this.handleDeleteRoleClick.bind(this),this.deleteRole=this.deleteRole.bind(this),this.handleRenameRoleClick=this.handleRenameRoleClick.bind(this),this.renameRole=this.renameRole.bind(this)}async componentDidMount(){this.findAndLoadData()}componentWillUnmount(){this.props.adminRbacContext.clearContext()}findAndLoadData(){this.findAndLoadRoles(),this.findAndLoadRbacSettings()}async findAndLoadRoles(){const e=(await this.roleApiService.findAll()).body,t=new nm(e);t.filterOutGuestRole(),this.setState({roles:t})}async findAndLoadRbacSettings(){const e=(await this.rbacApiService.findAll({ui_action:!0,action:!0})).body,t=new Wc(e,!0);this.props.adminRbacContext.setRbacs(t)}updateRbacControlFunction(e,t,a){const n=this.props.adminRbacContext.rbacsUpdated,s=this.props.adminRbacContext.rbacs.findRbacByRoleAndActionName(e,t);if(s.controlFunction===a)n.remove(s);else{const e=new Vc(s.toDto({ui_action:!0,action:!0}));e.controlFunction=a,n.pushOrReplace(e)}this.props.adminRbacContext.setRbacsUpdated(n)}handleAddRoleClick(e){e.preventDefault(),this.props.dialogContext.open(fm,{onSubmit:this.createNewRole})}async createNewRole(e){try{await this.roleApiService.create(e.toDto()),this.findAndLoadData(),await this.props.actionFeedbackContext.displaySuccess(this.props.t("The role has been created successfully."))}catch(e){this.props.dialogContext.open($t,{error:e})}}async handleDeleteRoleClick(e,t){e.preventDefault();const a=(await this.userApiService.findAll()).body.filter(e=>e.role_id===t.id);a.length>0?this.props.dialogContext.open(Um,{role:t,usersCount:a.length}):this.props.dialogContext.open(Pm,{role:t,onSubmit:this.deleteRole})}async deleteRole(e){try{await this.roleApiService.delete(e.id),this.findAndLoadData(),await this.props.actionFeedbackContext.displaySuccess(this.props.t("The role has been deleted successfully."))}catch(e){this.props.dialogContext.open($t,{error:e})}}async handleRenameRoleClick(e,t){e.preventDefault(),this.props.dialogContext.open(Om,{role:t,onSubmit:this.renameRole})}async renameRole(e){try{await this.roleApiService.update(e.id,e.toUpdateDto()),this.findAndLoadData(),await this.props.actionFeedbackContext.displaySuccess(this.props.t("The role has been updated successfully."))}catch(e){this.props.dialogContext.open($t,{error:e})}}get canIUseTags(){return this.props.context.siteSettings.canIUse("tags")}get canIUseDesktop(){return this.props.context.siteSettings.canIUse("desktop")}get canIUseMobile(){return this.props.context.siteSettings.canIUse("mobile")}get canIUseFolders(){return this.props.context.siteSettings.canIUse("folders")}get canIUsePreviewPassword(){return this.props.context.siteSettings.canIUse("previewPassword")}get canIUseExport(){return this.props.context.siteSettings.canIUse("export")}get canIUseImport(){return this.props.context.siteSettings.canIUse("import")}get canIUseAccountRecovery(){return this.props.context.siteSettings.canIUse("accountRecovery")}get isReady(){return null!==this.state.roles}get canAddNewRole(){const e=nm.getSchema().maxItems-1;return null!==this.state.roles&&this.state.roles.lengthe.isUser()),a=this.state.roles.items.filter(e=>!e.isAdmin()&&!e.isUser());e.push(t,...a)}return new nm(e,{validate:!1})}blankColumnSectionForRoles(){const e=[];return this.state.roles?.items.forEach((t,a)=>{e.push(n.createElement("div",{className:"flex-item",key:a}," "))}),n.createElement(n.Fragment,null,e)}render(){const e=this.props.adminRbacContext.hasSettingsChanges(),t=this.customizableRoles,a=this.state.roles?.length;return n.createElement("div",{className:"row"},n.createElement("div",{className:"rbac-settings main-column"},n.createElement("div",{className:"main-content"},n.createElement("h3",{className:"title"},n.createElement(f.x6,null,"Role-Based Access Control")),n.createElement("div",{className:"section-header"},n.createElement("p",null,n.createElement(f.x6,null,"In this section you can define access controls for each user role.")),n.createElement("button",{type:"button",className:"button",onClick:this.handleAddRoleClick,disabled:!this.canAddNewRole,title:this.canAddNewRole?"":this.props.t("Maximum number of roles reached")},n.createElement(cm,null)," ",n.createElement(f.x6,null,"Add role"))),n.createElement("form",{className:"form"},n.createElement("div",{className:"flex-container outer"},n.createElement("div",{className:"flex-container inner header-flex"},n.createElement("div",{className:"flex-item first"}," "),n.createElement("div",{className:"flex-item centered"},n.createElement("span",{className:"ellipsis",title:this.props.t("Admin")},n.createElement(f.x6,null,"Admin"))),t.items.map(e=>n.createElement("div",{className:"flex-item centered",key:e.id},n.createElement("span",{className:"ellipsis",title:oe(this.getTranslatedRoleName(e))},oe(this.getTranslatedRoleName(e))),!e.isAReservedRole()&&n.createElement(xm,null,n.createElement(Cm,{className:"more button-action-icon link no-border"},n.createElement(um,null)),n.createElement(Tm,{className:"menu-action-contextual",direction:"left"},n.createElement(Im,null,n.createElement("button",{id:"rename_role_action",type:"button",className:"no-border",onClick:t=>this.handleRenameRoleClick(t,e)},n.createElement(ym,null),n.createElement("span",null,n.createElement(f.x6,null,"Rename")))),n.createElement(Im,null,n.createElement("button",{id:"delete_role_action",type:"button",className:"no-border",onClick:t=>this.handleDeleteRoleClick(t,e)},n.createElement(dl,null),n.createElement("span",null,n.createElement(f.x6,null,"Delete"))))))))),this.isReady&&n.createElement(n.Fragment,null,n.createElement("div",{className:"flex-container inner header-flex"},n.createElement("div",{className:"flex-item first"},n.createElement("label",null,n.createElement(f.x6,null,"API Permissions"))),this.blankColumnSectionForRoles()),n.createElement(am,{label:this.props.t("Group management"),level:1,rolesCount:a},n.createElement(im,{label:this.props.t("Create a group"),actionName:j,level:2,rbacs:this.props.adminRbacContext.rbacs,rbacsUpdated:this.props.adminRbacContext.rbacsUpdated,roles:t,onChange:this.updateRbacControlFunction})),this.canIUseAccountRecovery&&n.createElement(n.Fragment,null,n.createElement(am,{label:this.props.t("Account recovery request"),level:1,rolesCount:a},n.createElement(im,{label:this.props.t("Account recovery request view"),actionName:L,level:2,rbacs:this.props.adminRbacContext.rbacs,rbacsUpdated:this.props.adminRbacContext.rbacsUpdated,roles:t,onChange:this.updateRbacControlFunction}),n.createElement(im,{label:this.props.t("Account recovery request index"),actionName:q,level:2,rbacs:this.props.adminRbacContext.rbacs,rbacsUpdated:this.props.adminRbacContext.rbacsUpdated,roles:t,onChange:this.updateRbacControlFunction}),n.createElement(im,{label:this.props.t("Account recovery request review"),actionName:z,level:2,rbacs:this.props.adminRbacContext.rbacs,rbacsUpdated:this.props.adminRbacContext.rbacsUpdated,roles:t,onChange:this.updateRbacControlFunction}))),n.createElement("div",{className:"flex-container inner header-flex"},n.createElement("div",{className:"flex-item first"},n.createElement("label",null,n.createElement(f.x6,null,"UI Permissions"))),this.blankColumnSectionForRoles()),n.createElement(am,{label:this.props.t("Resources"),level:1,rolesCount:a},(this.canIUseImport||this.canIUseExport)&&n.createElement(am,{label:this.props.t("Import/Export"),level:2,rolesCount:a},this.canIUseImport&&n.createElement(im,{label:this.props.t("Can import"),actionName:"Resources.import",level:3,rbacs:this.props.adminRbacContext.rbacs,rbacsUpdated:this.props.adminRbacContext.rbacsUpdated,roles:t,onChange:this.updateRbacControlFunction}),this.canIUseExport&&n.createElement(im,{label:this.props.t("Can export"),actionName:"Resources.export",level:3,rbacs:this.props.adminRbacContext.rbacs,rbacsUpdated:this.props.adminRbacContext.rbacsUpdated,roles:t,onChange:this.updateRbacControlFunction})),n.createElement(am,{label:this.props.t("Password"),level:2,rolesCount:a},this.canIUsePreviewPassword&&n.createElement(im,{label:this.props.t("Can preview"),actionName:"Secrets.preview",level:3,rbacs:this.props.adminRbacContext.rbacs,rbacsUpdated:this.props.adminRbacContext.rbacsUpdated,roles:t,onChange:this.updateRbacControlFunction}),n.createElement(im,{label:this.props.t("Can copy"),actionName:"Secrets.copy",level:3,rbacs:this.props.adminRbacContext.rbacs,rbacsUpdated:this.props.adminRbacContext.rbacsUpdated,roles:t,onChange:this.updateRbacControlFunction})),n.createElement(am,{label:this.props.t("Metadata"),level:2,rolesCount:a},n.createElement(im,{label:this.props.t("Can see password activities"),actionName:"Resources.seeActivities",level:3,rbacs:this.props.adminRbacContext.rbacs,rbacsUpdated:this.props.adminRbacContext.rbacsUpdated,roles:t,onChange:this.updateRbacControlFunction}),n.createElement(im,{label:this.props.t("Can see password comments"),actionName:"Resources.seeComments",level:3,rbacs:this.props.adminRbacContext.rbacs,rbacsUpdated:this.props.adminRbacContext.rbacsUpdated,roles:t,onChange:this.updateRbacControlFunction})),(this.canIUseFolders||this.canIUseTags)&&n.createElement(am,{label:this.props.t("Organization"),level:2,rolesCount:a},this.canIUseFolders&&n.createElement(im,{label:this.props.t("Can use folders"),actionName:M,level:3,rbacs:this.props.adminRbacContext.rbacs,rbacsUpdated:this.props.adminRbacContext.rbacsUpdated,roles:t,onChange:this.updateRbacControlFunction}),this.canIUseTags&&n.createElement(im,{label:this.props.t("Can use tags"),actionName:"Tags.use",level:3,rbacs:this.props.adminRbacContext.rbacs,rbacsUpdated:this.props.adminRbacContext.rbacsUpdated,roles:t,onChange:this.updateRbacControlFunction})),n.createElement(am,{label:this.props.t("Sharing"),level:2,rolesCount:a},n.createElement(im,{label:this.props.t("Can see with whom passwords are shared with"),actionName:"Share.viewList",level:3,rbacs:this.props.adminRbacContext.rbacs,rbacsUpdated:this.props.adminRbacContext.rbacsUpdated,roles:t,onChange:this.updateRbacControlFunction}),n.createElement(im,{label:this.props.t("Can share folders"),actionName:"Folders.share",level:3,rbacs:this.props.adminRbacContext.rbacs,rbacsUpdated:this.props.adminRbacContext.rbacsUpdated,roles:t,onChange:this.updateRbacControlFunction}))),n.createElement(am,{label:this.props.t("Users"),level:1,rolesCount:a},n.createElement(im,{label:this.props.t("Can see users workspace"),actionName:U,level:2,rbacs:this.props.adminRbacContext.rbacs,rbacsUpdated:this.props.adminRbacContext.rbacsUpdated,roles:t,onChange:this.updateRbacControlFunction})),(this.canIUseMobile||this.canIUseDesktop)&&n.createElement(am,{label:this.props.t("User settings"),level:1,rolesCount:a},this.canIUseMobile&&n.createElement(im,{label:this.props.t("Can see mobile setup"),actionName:"Mobile.transfer",level:2,rbacs:this.props.adminRbacContext.rbacs,rbacsUpdated:this.props.adminRbacContext.rbacsUpdated,roles:t,onChange:this.updateRbacControlFunction}),this.canIUseDesktop&&n.createElement(im,{label:this.props.t("Can see desktop application setup"),actionName:"Desktop.transfer",level:2,rbacs:this.props.adminRbacContext.rbacs,rbacsUpdated:this.props.adminRbacContext.rbacsUpdated,roles:t,onChange:this.updateRbacControlFunction})))))),e&&n.createElement("div",{className:"warning message"},n.createElement("div",null,n.createElement("p",null,n.createElement(f.x6,null,"Don't forget to save your settings to apply your modification."))))),n.createElement(em,null),Xa(n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"Need help?")),n.createElement("p",null,n.createElement(f.x6,null,"Check out the Role Based Access Control documentation.")),n.createElement("a",{className:"button",href:"https://passbolt.com/docs/admin/role-based-access-control/",target:"_blank",rel:"noopener noreferrer"},n.createElement(ps,null),n.createElement("span",null,n.createElement(f.x6,null,"Read RBAC doc")))),document.getElementById("administration-help-panel")))}}Fm.defaultProps={RoleApiService:rm,RbacApiService:Hc,UserApiService:Sn},Fm.propTypes={context:i().object,administrationWorkspaceContext:i().object,adminRbacContext:i().object,dialogContext:i().object,RoleApiService:i().func,RbacApiService:i().func,UserApiService:i().func,t:i().func};const jm=N(Xc(Ne(h(m((0,f.CI)("common")(Fm)))))),Lm=class{constructor(e={}){this.default_generator=e.provider,this.external_dictionary_check=e.policyPassphraseExternalServices,this.password_generator_settings={min_length:e.minLength??8,max_length:e.minLength??128,length:e.passwordLength,mask_upper:e.mask_upper,mask_lower:e.mask_lower,mask_digit:e.mask_digit,mask_parenthesis:e.mask_parenthesis,mask_char1:e.mask_char1,mask_char2:e.mask_char2,mask_char3:e.mask_char3,mask_char4:e.mask_char4,mask_char5:e.mask_char5,mask_emoji:e.mask_emoji,exclude_look_alike_chars:e.excludeLookAlikeCharacters},this.passphrase_generator_settings={min_words:e.minWords??4,max_words:e.maxWords??40,words:e.wordsCount,word_separator:e.wordsSeparator,word_case:e.wordCase},this.source=e.source}},qm=class{constructor(e={}){this.provider="passphrase"===e?.default_generator?"passphrase":"password",this.policyPassphraseExternalServices=Boolean(e?.external_dictionary_check),this.source=e?.source??"default";const t=e?.password_generator_settings;this.passwordLength=t?.length??18,this.mask_upper=t?.mask_upper??!1,this.mask_lower=t?.mask_lower??!1,this.mask_digit=t?.mask_digit??!1,this.mask_parenthesis=t?.mask_parenthesis??!1,this.mask_char1=t?.mask_char1??!1,this.mask_char2=t?.mask_char2??!1,this.mask_char3=t?.mask_char3??!1,this.mask_char4=t?.mask_char4??!1,this.mask_char5=t?.mask_char5??!1,this.mask_emoji=t?.mask_emoji??!1,this.excludeLookAlikeCharacters=t?.exclude_look_alike_chars??!1;const a=e?.passphrase_generator_settings;this.wordsCount=a?.words??9,this.wordsSeparator=a?.word_separator??" ",this.wordCase=a?.word_case??"lowercase"}};function zm(){return zm=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},getSettingsErrors:()=>{},setSettings:()=>{},hasSettingsChanges:()=>{},findSettings:()=>{},setProcessing:()=>{},isProcessing:()=>{},isDataValid:()=>{},clearContext:()=>{},save:()=>{},validateData:()=>{},getPasswordGeneratorMasks:()=>{},getEntropyForPassphraseConfiguration:()=>{},getEntropyForPasswordConfiguration:()=>{},getMinimalRequiredEntropy:()=>{},getMinimalAdvisedEntropy:()=>{},isSourceChanging:()=>{}});class Vm extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.hasDataBeenValidated=!1}get defaultState(){return{settings:new qm,errors:{},currentSettings:new qm,processing:!0,getSettings:this.getSettings.bind(this),getSettingsErrors:this.getSettingsErrors.bind(this),setSettings:this.setSettings.bind(this),findSettings:this.findSettings.bind(this),hasSettingsChanges:this.hasSettingsChanges.bind(this),isProcessing:this.isProcessing.bind(this),setProcessing:this.setProcessing.bind(this),clearContext:this.clearContext.bind(this),save:this.save.bind(this),validateData:this.validateData.bind(this),getPasswordGeneratorMasks:this.getPasswordGeneratorMasks.bind(this),getEntropyForPassphraseConfiguration:this.getEntropyForPassphraseConfiguration.bind(this),getEntropyForPasswordConfiguration:this.getEntropyForPasswordConfiguration.bind(this),getMinimalRequiredEntropy:this.getMinimalRequiredEntropy.bind(this),getMinimalAdvisedEntropy:this.getMinimalAdvisedEntropy.bind(this),isSourceChanging:this.isSourceChanging.bind(this)}}async findSettings(e=()=>{}){this.setProcessing(!0);const t=await this.props.context.port.request("passbolt.password-policies.get-admin-settings"),a=new qm(t);this.setState({currentSettings:a,settings:a},e),this.setProcessing(!1)}validateData(){this.hasDataBeenValidated=!0;let e=!0;const t={},a=this.state.settings;a.mask_upper||a.mask_lower||a.mask_digit||a.mask_parenthesis||a.mask_char1||a.mask_char2||a.mask_char3||a.mask_char4||a.mask_char5||a.mask_emoji||(e=!1,t.masks=this.props.t("At least 1 set of characters must be selected")),a.passwordLength<8&&(e=!1,t.passwordLength=this.props.t("The password length must be set to 8 at least")),a.wordsCount<4&&(e=!1,t.wordsCount=this.props.t("The passphrase word count must be set to 4 at least")),a.wordsSeparator.length>10&&(e=!1,t.wordsSeparator=this.props.t("The words separator should be at a maximum of 10 characters long"));const n=this.getMinimalRequiredEntropy();return this.getEntropyForPassphraseConfiguration(){this.hasDataBeenValidated&&this.validateData()})}isProcessing(){return this.state.processing}setProcessing(e){this.setState({processing:e})}hasSettingsChanges(){return JSON.stringify(this.state.currentSettings)!==JSON.stringify(this.state.settings)}isSourceChanging(){return"db"!==this.state.currentSettings?.source&&"default"!==this.state.currentSettings?.source}clearContext(){const{currentSettings:e,settings:t,processing:a}=this.defaultState;this.setState({currentSettings:e,settings:t,processing:a})}render(){return n.createElement(Km.Provider,{value:this.state},this.props.children)}}function Gm(e){return class extends n.Component{render(){return n.createElement(Km.Consumer,null,t=>n.createElement(e,zm({adminPasswordPoliciesContext:t},this.props)))}}}Vm.propTypes={context:i().any,children:i().any,t:i().any,actionFeedbackContext:i().object},N((0,f.CI)("common")(Vm));class Bm extends n.Component{constructor(e){super(e),this.bindCallbacks()}bindCallbacks(){this.handleSave=this.handleSave.bind(this)}get isActionEnabled(){return!this.props.adminPasswordPoliciesContext.isProcessing()}async handleSave(){if(this.isActionEnabled&&this.props.adminPasswordPoliciesContext.validateData())try{await this.props.adminPasswordPoliciesContext.save();const e=this.props.adminPasswordPoliciesContext.getSettings();this.props.passwordPoliciesContext.setPolicies(new Lm(e)),await this.handleSaveSuccess()}catch(e){await this.handleSaveError(e)}}async handleSaveSuccess(){await this.props.actionFeedbackContext.displaySuccess(this.props.t("The password policy settings were updated."))}async handleSaveError(e){console.error(e),await this.props.actionFeedbackContext.displayError(e.message)}render(){const e=!this.isActionEnabled;return n.createElement("div",{className:"actions-wrapper"},n.createElement("button",{type:"button",className:"button primary form",disabled:e,id:"save-settings",onClick:this.handleSave},n.createElement("span",null,n.createElement(f.x6,null,"Save"))))}}Bm.propTypes={adminPasswordPoliciesContext:i().object,passwordPoliciesContext:i().object,actionFeedbackContext:i().object,t:i().func};const Wm=Gm(or(m((0,f.CI)("common")(Bm)))),Hm={COLOR_1:$m("#BA2809"),COLOR_2:$m("#FFA724"),COLOR_3:$m("#0EAA00")};function $m(e){const t=new RegExp("^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$","i").exec(e.trim());return t?{red:parseInt(t[1],16),green:parseInt(t[2],16),blue:parseInt(t[3],16)}:null}class Ym extends n.Component{get entropy(){return(this.props.entropy||0).toFixed(1)}get tooltipMessage(){return n.createElement(n.Fragment,null,n.createElement(f.x6,null,"Entropy:")," ",this.entropy," bits")}get passwordStrengthLabel(){if(!this.hasEntropy()&&!this.hasError())return n.createElement(f.x6,null,"Quality");const e=Vi.strength(this.props.entropy);return n.createElement(n.Fragment,null,e.label)}hasEntropy(){return null!==this.props.entropy&&void 0!==this.props.entropy}hasError(){return this.props.error}getProgresseBarStyle(){const e=this.getRelativeEntropyPosition();return{width:`${e}%`,backgroundColor:this.colorGradient(e)}}colorGradient(e){let t,a,n=e/100*2;return n>=1?(n-=1,t=Hm.COLOR_2,a=Hm.COLOR_3):(t=Hm.COLOR_1,a=Hm.COLOR_2),`rgb(${Math.floor(t.red+(a.red-t.red)*n)},${Math.floor(t.green+(a.green-t.green)*n)},${Math.floor(t.blue+(a.blue-t.blue)*n)})`}getRelativeEntropyPosition(){return 100-99/(1+Math.pow(this.props.entropy/90,10))}render(){return n.createElement("div",{className:"password-complexity"},n.createElement("span",{className:"complexity-text"},n.createElement(Mt,{message:this.tooltipMessage},this.passwordStrengthLabel," ",n.createElement(jt,null))),n.createElement("span",{className:"progress"},n.createElement("span",{className:"progress-bar background"}),n.createElement("span",{className:"progress-bar foreground "+(this.hasError()?"error":""),style:this.hasEntropy()?this.getProgresseBarStyle(this.props.entropy):null})))}}Ym.defaultProps={entropy:null},Ym.propTypes={entropy:i().number,error:i().bool};const Zm=(0,f.CI)("common")(Ym);class Jm extends n.Component{constructor(e){super(e),this.state={showPasswordSection:!1,showPassphraseSection:!1},this.bindCallbacks()}async componentDidMount(){await this.props.adminPasswordPoliciesContext.findSettings()}componentWillUnmount(){this.props.adminPasswordPoliciesContext.clearContext()}bindCallbacks(){this.handleCheckboxInputChange=this.handleCheckboxInputChange.bind(this),this.handleMaskToggled=this.handleMaskToggled.bind(this),this.handlePasswordSectionToggle=this.handlePasswordSectionToggle.bind(this),this.handlePassphraseSectionToggle=this.handlePassphraseSectionToggle.bind(this),this.handleInputChange=this.handleInputChange.bind(this),this.handleSliderInputChange=this.handleSliderInputChange.bind(this),this.handleLengthChange=this.handleLengthChange.bind(this)}handlePasswordSectionToggle(){this.setState({showPasswordSection:!this.state.showPasswordSection})}handlePassphraseSectionToggle(){this.setState({showPassphraseSection:!this.state.showPassphraseSection})}get wordCaseList(){return[{value:"lowercase",label:this.props.t("Lower case")},{value:"uppercase",label:this.props.t("Upper case")},{value:"camelcase",label:this.props.t("Camel case")}]}get providerList(){return[{value:"password",label:this.props.t("Password")},{value:"passphrase",label:this.props.t("Passphrase")}]}handleCheckboxInputChange(e){const t=e.target.name;this.props.adminPasswordPoliciesContext.setSettings(t,e.target.checked)}handleSliderInputChange(e){const t=parseInt(e.target.value,10),a=e.target.name;this.props.adminPasswordPoliciesContext.setSettings(a,t)}handleInputChange(e){const t=e.target,a=t.value,n=t.name;this.props.adminPasswordPoliciesContext.setSettings(n,a)}handleLengthChange(e){const t=e.target,a=parseInt(t.value,10),n=t.name;this.props.adminPasswordPoliciesContext.setSettings(n,a)}handleMaskToggled(e){const t=!this.props.adminPasswordPoliciesContext.getSettings()[e];this.props.adminPasswordPoliciesContext.setSettings(e,t)}hasAllInputDisabled(){return this.props.adminPasswordPoliciesContext.isProcessing()}get settingsSource(){return this.props.adminPasswordPoliciesContext?.getSettings()?.source}get configurationSource(){return{legacyEnv:this.props.t("environment variables (legacy)"),env:this.props.t("environment variables"),legacyFile:this.props.t("file (legacy)"),file:this.props.t("file"),db:this.props.t("database"),default:this.props.t("default configuration")}[this.settingsSource]||this.props.t("unknown")}render(){const e=this.props.adminPasswordPoliciesContext,t=e.getSettings(),a=e.getSettingsErrors(),s=e.getMinimalAdvisedEntropy(),i=e.getEntropyForPasswordConfiguration(),r=e.getEntropyForPassphraseConfiguration(),o=e.getPasswordGeneratorMasks(),l=in.createElement("button",{type:"button",key:e,className:"button button-toggle "+(t[e]?"selected":""),onClick:()=>this.handleMaskToggled(e),disabled:this.hasAllInputDisabled()},a.label))),a.masks&&n.createElement("div",{id:"password-mask-error",className:"error-message"},a.masks),n.createElement("div",{className:"input checkbox"},n.createElement("input",{id:"configure-password-generator-form-exclude-look-alike",type:"checkbox",name:"excludeLookAlikeCharacters",checked:t.excludeLookAlikeCharacters,onChange:this.handleCheckboxInputChange,disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"configure-password-generator-form-exclude-look-alike"},n.createElement(f.x6,null,"Exclude look-alike characters"))),n.createElement("p",null,n.createElement(f.x6,null,"You can select the set of characters used for the passwords that are generated randomly by passbolt in the password generator.")))),n.createElement("div",{className:"accordion-header"},n.createElement("button",{id:"accordion-toggle-passphrase",className:"link no-border",type:"button",onClick:this.handlePassphraseSectionToggle},this.state.showPassphraseSection?n.createElement(Vt,{className:"caret-down"}):n.createElement(Wt,{className:"caret-right"}),n.createElement(f.x6,null,"Passphrase settings"))),this.state.showPassphraseSection&&n.createElement("div",{className:"passphrase-settings"},n.createElement("div",{className:"estimated-entropy input"},n.createElement("label",null,n.createElement(f.x6,null,"Estimated entropy")),n.createElement(Zm,{entropy:r}),a.passphraseMinimalRequiredEntropy&&n.createElement("div",{className:"error-message"},a.passphraseMinimalRequiredEntropy)),n.createElement("div",{className:"input text "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",{htmlFor:"configure-passphrase-generator-form-word-count"},n.createElement(f.x6,null,"Number of words")),n.createElement("div",{className:"slider"},n.createElement("input",{name:"wordsCount",min:"4",max:"40",value:t.wordsCount,type:"range",onChange:this.handleSliderInputChange,disabled:this.hasAllInputDisabled()}),n.createElement("input",{type:"number",id:"configure-passphrase-generator-form-word-count",name:"wordsCount",min:"4",max:"40",value:t.wordsCount,onChange:this.handleLengthChange,disabled:this.hasAllInputDisabled()})),a.wordsCount&&n.createElement("div",{id:"wordsCount-error",className:"error-message"},a.wordsCount)),n.createElement("p",null,n.createElement(f.x6,null,"You can set the default length for the passphrases that are generated randomly by passbolt in the password generator.")),n.createElement("div",{className:"input text "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",{htmlFor:"configure-passphrase-generator-form-words-separator"},n.createElement(f.x6,null,"Words separator")),n.createElement("input",{type:"text",id:"configure-passphrase-generator-form-words-separator",name:"wordsSeparator",value:t.wordsSeparator,onChange:this.handleInputChange,placeholder:this.props.t("Type one or more characters"),disabled:this.hasAllInputDisabled()}),a.wordsSeparator&&n.createElement("div",{className:"error-message"},a.wordsSeparator)),n.createElement("div",{className:"select-wrapper input "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("label",{htmlFor:"configure-passphrase-generator-form-words-case"},n.createElement(f.x6,null,"Words case")),n.createElement(pn,{id:"configure-passphrase-generator-form-words-case",name:"wordCase",items:this.wordCaseList,value:t.wordCase,onChange:this.handleInputChange,disabled:this.hasAllInputDisabled()}))),n.createElement("h4",{id:"password-policies-external-services-subtitle"},n.createElement("span",{className:"input toggle-switch form-element ready"},n.createElement("input",{id:"passphrase-policy-external-services-toggle-button",type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"policyPassphraseExternalServices",onChange:this.handleCheckboxInputChange,checked:t?.policyPassphraseExternalServices,disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"passphrase-policy-external-services-toggle-button"},n.createElement(f.x6,null,"External services")))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement(f.x6,null,"Allow passbolt to access external services to check if a password has been compromised.")))),m&&n.createElement("div",{className:"warning message"},e.isSourceChanging()&&n.createElement("div",{id:"password-policies-setting-source-changing-banner"},n.createElement("p",null,n.createElement(f.x6,null,"The current configuration comes from a file or environment variables. If you save them, they will be overwritten and come from the database instead."))),e.hasSettingsChanges()&&n.createElement("div",{id:"password-policies-setting-banner"},n.createElement("p",null,n.createElement(f.x6,null,"Don't forget to save your settings to apply your modification."))),l&&n.createElement("div",{id:"minimal-password-entropy-advised-banner"},n.createElement("p",null,n.createElement(f.x6,null,"The current password configuration generates passwords that are not strong enough."),n.createElement("br",null),n.createElement(f.x6,null,"Passbolt recommends a minimum of ",{minimalAdvisedEntropy:s}," bits to be safe."))),c&&n.createElement("div",{id:"minimal-passphrase-entropy-advised-banner"},n.createElement("p",null,n.createElement(f.x6,null,"The current passphrase configuration generates passphrases that are not strong enough."),n.createElement("br",null),n.createElement(f.x6,null,"Passbolt recommends a minimum of ",{minimalAdvisedEntropy:s}," bits to be safe."))))),n.createElement(Wm,null),Xa(n.createElement(n.Fragment,null,n.createElement("div",{className:"sidebar-help-section",id:"password-policies-source"},n.createElement("h3",null,n.createElement(f.x6,null,"Configuration source")),n.createElement("p",null,n.createElement(f.x6,null,"This current configuration source is: "),this.configurationSource,".")),n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"What is password policy?")),n.createElement("p",null,n.createElement(f.x6,null,"For more information about the password policy settings, checkout the dedicated page on the help website.")),n.createElement("a",{className:"button",href:"https://passbolt.com/docs/admin/password-configuration/password-policy/",target:"_blank",rel:"noopener noreferrer"},n.createElement(Er,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation"))))),document.getElementById("administration-help-panel")))}}Jm.propTypes={context:i().object,administrationWorkspaceContext:i().object,adminPasswordPoliciesContext:i().object,t:i().func};const Xm=N(Ne(Gm((0,f.CI)("common")(Jm))));class Qm extends n.Component{render(){return n.createElement("div",{className:"row"},n.createElement("div",{className:"password-policies-settings-teasing main-column"},n.createElement("div",{className:"main-content"},n.createElement("h3",{className:"title",id:"password-policies-settings-title"},n.createElement(f.x6,null,"Password Policy"),n.createElement(Ea,{className:"pro-teasing-icon"})),n.createElement("p",null,n.createElement(f.x6,null,"Ensure strong and consistent passwords entropy across your organisation.")),n.createElement("div",{className:"password-policies-info"},n.createElement("ul",{className:"password-policies-description"},n.createElement("li",null,n.createElement(fs,null),n.createElement(f.x6,null,"Reduce the risk of weak passwords.")),n.createElement("li",null,n.createElement(fs,null),n.createElement(f.x6,null,"Enforce complexity requirements.")),n.createElement("li",null,n.createElement(fs,null),n.createElement(f.x6,null,"Ensure compliance with internal security standards."))),n.createElement("div",null,n.createElement("a",{className:"button primary",href:"https://www.passbolt.com/ce-to-pro?utm_campaign=21060976-CE%20to%20Pro&utm_source=product",target:"_blank",rel:"noopener noreferrer"},n.createElement(f.x6,null,"Upgrade to Passbolt Pro")))))),Xa(n.createElement(n.Fragment,null,n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"Need some help?")),n.createElement("p",null,n.createElement(f.x6,null,"For more information about the password policy settings, checkout the dedicated page on the help website.")),n.createElement("a",{className:"button",href:"https://passbolt.com/docs/admin/password-configuration/password-policy/",target:"_blank",rel:"noopener noreferrer"},n.createElement(Er,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation"))))),document.getElementById("administration-help-panel")))}}Qm.propTypes={context:i().object,t:i().func};const ed=N((0,f.CI)("common")(Qm));class td extends se{constructor(e,t={}){super(ae.validate(td.ENTITY_NAME,e,td.getSchema()),t)}static getSchema(){return{type:"object",required:["entropy_minimum","external_dictionary_check"],properties:{id:{type:"string",format:"uuid"},entropy_minimum:{type:"integer",minimum:50,maximum:224},external_dictionary_check:{type:"boolean"},created:{type:"string",format:"date-time"},created_by:{type:"string",format:"uuid"},modified:{type:"string",format:"date-time"},modified_by:{type:"string",format:"uuid"}}}}static get ENTITY_NAME(){return"UserPassphrasePolicies"}static createFromDefault(e={}){const t=Object.assign({entropy_minimum:50,external_dictionary_check:!0},e);return new td(t)}}const ad=td;class nd{constructor(e={}){this.external_dictionary_check=e?.external_dictionary_check,this.entropy_minimum=e?.entropy_minimum}static getSchema(){const e=ad.getSchema();return{type:"object",required:["entropy_minimum","external_dictionary_check"],properties:{entropy_minimum:e.properties.entropy_minimum,external_dictionary_check:e.properties.external_dictionary_check}}}static fromEntityDto(e){const t={entropy_minimum:parseInt(e?.entropy_minimum,10)||50,external_dictionary_check:Boolean(e?.external_dictionary_check)};return new nd(t)}static isDataDifferent(e,t){return["entropy_minimum","external_dictionary_check"].some(a=>e[a]!==t[a])}toEntityDto(){return{entropy_minimum:this.entropy_minimum,external_dictionary_check:this.external_dictionary_check}}cloneWithMutation(e,t){const a={...this,[e]:t};return new nd(a)}validate(){const e=nd.getSchema();try{ae.validate(this.constructor.name,this,e)}catch(e){return e}return new X}}const sd=nd;function id(){return id=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},setSettings:()=>{},findSettings:()=>{},isProcessing:()=>{},validateData:()=>{},save:()=>{},getErrors:()=>{},hasSettingsChanges:()=>{}});class od extends n.Component{constructor(e){super(e),this.state=this.defaultState}get defaultState(){return{processing:!1,errors:null,hasBeenValidated:!1,isDataModified:!1,settings:new sd,findSettings:this.findSettings.bind(this),getSettings:this.getSettings.bind(this),setSettings:this.setSettings.bind(this),isProcessing:this.isProcessing.bind(this),validateData:this.validateData.bind(this),save:this.save.bind(this),getErrors:this.getErrors.bind(this),hasSettingsChanges:this.hasSettingsChanges.bind(this)}}async findSettings(){this.setState({processing:!0});const e=await this.props.context.port.request("passbolt.user-passphrase-policies.find"),t=sd.fromEntityDto(e);this.setState({settings:t,currentSettings:t,processing:!1})}getSettings(){return this.state.settings}setSettings(e,t){const a=this.state.settings.cloneWithMutation(e,t),n=sd.isDataDifferent(a,this.state.currentSettings);if(!this.state.hasBeenValidated)return void this.setState({settings:a,isDataModified:n});const s=a.validate();this.setState({errors:s,settings:a,isDataModified:n})}isProcessing(){return this.state.processing}validateData(){const e=this.state.settings.validate(),t=e.hasErrors(),a=t?e:null;return this.setState({errors:a,hasBeenValidated:!0}),!t}async save(){this.setState({processing:!0});try{const e=this.state.settings.toEntityDto(),t=await this.props.context.port.request("passbolt.user-passphrase-policies.save",e),a=sd.fromEntityDto(t);this.setState({settings:a,currentSettings:a,processing:!1,isDataModified:!1})}finally{this.setState({processing:!1})}}getErrors(){return this.state.errors}hasSettingsChanges(){return this.state.isDataModified}render(){return n.createElement(rd.Provider,{value:this.state},this.props.children)}}function ld(e){return class extends n.Component{render(){return n.createElement(rd.Consumer,null,t=>n.createElement(e,id({adminUserPassphrasePoliciesContext:t},this.props)))}}}od.propTypes={context:i().any,children:i().any,t:i().any},N((0,f.CI)("common")(od));class cd extends n.Component{constructor(e){super(e),this.bindCallbacks()}bindCallbacks(){this.handleSave=this.handleSave.bind(this)}get isActionEnabled(){return!this.props.adminUserPassphrasePoliciesContext.isProcessing()}async handleSave(){if(this.isActionEnabled&&this.props.adminUserPassphrasePoliciesContext.validateData())try{await this.props.adminUserPassphrasePoliciesContext.save(),await this.handleSaveSuccess()}catch(e){await this.handleSaveError(e)}}async handleSaveSuccess(){await this.props.actionFeedbackContext.displaySuccess(this.props.t("The user passphrase policies were updated."))}async handleSaveError(e){console.error(e),await this.props.actionFeedbackContext.displayError(e.message),this.props.dialogContext.open($t,{error:e})}render(){const e=!this.isActionEnabled;return n.createElement("div",{className:"actions-wrapper"},n.createElement("button",{type:"button",className:"button primary form",disabled:e,id:"save-settings",onClick:this.handleSave},n.createElement("span",null,n.createElement(f.x6,null,"Save"))))}}cd.propTypes={adminUserPassphrasePoliciesContext:i().object,actionFeedbackContext:i().object,dialogContext:i().any,t:i().func};const md=ld(m(h((0,f.CI)("common")(cd))));class dd extends n.PureComponent{constructor(e){super(e),this.bindHandlers()}bindHandlers(){this.handleRangeOptionClick=this.handleRangeOptionClick.bind(this),this.handleRangeChange=this.handleRangeChange.bind(this)}handleRangeOptionClick(e){this.props.disabled||this.props.onChange(this.props.id,e)}handleRangeChange(e){const t=e.target;this.props.onChange(t.name,this.values[t.value].value)}getComputedStyleForEntropyStep(e,t){return{left:e*(100/(t-1))+"%"}}getValueIndex(e){return this.values.findIndex(t=>t.value===e)}get values(){return[{label:"50 bits",value:50},{label:"64 bits",value:64},{label:"80 bits",value:80},{label:"96 bits",value:96},{label:"128 bits",value:128},{label:"160 bits",value:160},{label:"192 bits",value:192},{label:"224 bits",value:224}]}render(){const e=this.values,t=e.length,{id:a,value:s}=this.props;return n.createElement("div",{className:"range-wrapper"},n.createElement("div",{className:"range-labels"},n.createElement("label",{key:"min"},n.createElement(f.x6,null,"Weak")),n.createElement("label",{key:"max"},n.createElement(f.x6,null,"Secure"))),n.createElement("div",{className:"range-input-wrapper"},n.createElement("input",{type:"range",className:"range-input",id:a,name:a,min:0,max:e.length-1,value:this.getValueIndex(s),list:`${this.props.id}-values`,onChange:this.handleRangeChange,required:!0,disabled:this.props.disabled}),n.createElement("ul",{className:"range-options"},e.map((e,a)=>n.createElement("li",{key:`li-${a}`,onClick:()=>this.handleRangeOptionClick(e.value),style:this.getComputedStyleForEntropyStep(a,t),className:"range-option "+(s===e.value?"range-option--active":""),disabled:this.props.disabled},e.label)))))}}dd.propTypes={value:i().number.isRequired,id:i().string.isRequired,onChange:i().func,disabled:i().bool};const ud=(0,f.CI)("common")(dd);class pd extends n.PureComponent{constructor(e){super(e),this.state=this.defaultState,this.bindCallbacks()}get defaultState(){return{isReady:!1}}async componentDidMount(){await this.props.adminUserPassphrasePoliciesContext.findSettings(),this.setState({isReady:!0})}bindCallbacks(){this.handleMinimumEntropyChange=this.handleMinimumEntropyChange.bind(this),this.handleCheckboxInputChange=this.handleCheckboxInputChange.bind(this)}hasAllInputDisabled(){return this.props.adminUserPassphrasePoliciesContext.isProcessing()}handleMinimumEntropyChange(e,t){const a=parseInt(t,10)||0;this.props.adminUserPassphrasePoliciesContext.setSettings(e,a)}handleCheckboxInputChange(e){const t=e.target,a=t.name,n=Boolean(t.checked);this.props.adminUserPassphrasePoliciesContext.setSettings(a,n)}isWeakSettings(e){return e.entropy_minimum<80}get hasWarnings(){const e=this.props.adminUserPassphrasePoliciesContext,t=e.getSettings();return e.hasSettingsChanges()||this.isWeakSettings(t)}render(){if(!this.state.isReady)return null;const e=this.hasAllInputDisabled(),t=this.props.adminUserPassphrasePoliciesContext,a=t.getSettings();return n.createElement("div",{className:"row"},n.createElement("div",{className:"password-policies-settings main-column"},n.createElement("div",{className:"main-content"},n.createElement("h3",{id:"user-passphrase-policies-title",className:"title"},n.createElement(f.x6,null,"User Passphrase Policies")),n.createElement("form",null,n.createElement("h4",{id:"user-passphrase-policies-entropy-minimum"},n.createElement(f.x6,null,"User passphrase minimal entropy")),n.createElement("div",{className:"input range"},n.createElement(ud,{id:"entropy_minimum",onChange:this.handleMinimumEntropyChange,value:a.entropy_minimum,disabled:e})),n.createElement("div",null,n.createElement(f.x6,null,"You can set the minimal entropy for the users' private key passphrase.")," ",n.createElement(f.x6,null,"This is the passphrase that is asked during sign in or recover.")),n.createElement("h4",{id:"user-passphrase-policies-external-services-subtitle"},n.createElement("span",{className:"input toggle-switch form-element ready"},n.createElement("input",{id:"user-passphrase-policies-external-services-toggle-button",type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"external_dictionary_check",onChange:this.handleCheckboxInputChange,checked:a?.external_dictionary_check,disabled:e}),n.createElement("label",{htmlFor:"user-passphrase-policies-external-services-toggle-button"},n.createElement(f.x6,null,"External password dictionary check")))),n.createElement("span",{className:"input toggle-switch form-element"},n.createElement(f.x6,null,"Allow passbolt to access external services to check if the user passphrase has been compromised when the user creates it.")))),this.hasWarnings&&n.createElement("div",{className:"warning message"},t.hasSettingsChanges()&&n.createElement("div",{id:"user-passphrase-policies-save-banner"},n.createElement("p",null,n.createElement(f.x6,null,"Don't forget to save your settings to apply your modification."))),this.isWeakSettings(a)&&n.createElement("div",{id:"user-passphrase-policies-weak-settings-banner"},n.createElement("p",null,n.createElement(f.x6,null,"Passbolt recommends passphrase strength to be at minimum of ",{MINIMAL_ADVISED_ENTROPY:80}," bits to be safe."))))),n.createElement(md,null),Xa(n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"What is user passphrase policies?")),n.createElement("p",null,n.createElement(f.x6,null,"For more information about the user passphrase policies, checkout the dedicated page on the help website.")),n.createElement("a",{className:"button",href:"https://passbolt.com/docs/admin/authentication/user-passphrase-policies/",target:"_blank",rel:"noopener noreferrer"},n.createElement(Er,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}pd.propTypes={context:i().object,administrationWorkspaceContext:i().object,adminUserPassphrasePoliciesContext:i().object,t:i().func};const hd=N(Ne(ld((0,f.CI)("common")(pd))));class gd extends n.Component{render(){return n.createElement("div",{className:"row"},n.createElement("div",{className:"user-passphrase-policies-settings-teasing main-column"},n.createElement("div",{className:"main-content"},n.createElement("h3",{id:"user-passphrase-policies-title",className:"title"},n.createElement(f.x6,null,"User Passphrase Policies"),n.createElement(Ea,{className:"pro-teasing-icon"})),n.createElement("p",null,n.createElement(f.x6,null,"Enforce secure user passphrases to protect account access.")),n.createElement("div",{className:"user-passphrase-policies-info"},n.createElement("ul",{className:"user-passphrase-policies-description"},n.createElement("li",null,n.createElement(fs,null),n.createElement(f.x6,null,"Mitigate risks associated with weak passphrases.")),n.createElement("li",null,n.createElement(fs,null),n.createElement(f.x6,null,"Customise minimum length and complexity.")),n.createElement("li",null,n.createElement(fs,null),n.createElement(f.x6,null,"Improve overall user account security."))),n.createElement("div",null,n.createElement("a",{className:"button primary",href:"https://www.passbolt.com/ce-to-pro?utm_campaign=21060976-CE%20to%20Pro&utm_source=product",target:"_blank",rel:"noopener noreferrer"},n.createElement(f.x6,null,"Upgrade to Passbolt Pro")))))),Xa(n.createElement(n.Fragment,null,n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"Need some help?")),n.createElement("p",null,n.createElement(f.x6,null,"For more information about the user passphrase policies, checkout the dedicated page on the help website.")),n.createElement("a",{className:"button",href:"https://www.passbolt.com/docs/admin/authentication/user-passphrase-policies/",target:"_blank",rel:"noopener noreferrer"},n.createElement(Er,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation"))))),document.getElementById("administration-help-panel")))}}gd.propTypes={context:i().object,t:i().func};const yd=N((0,f.CI)("common")(gd));class bd extends se{constructor(e,t={}){super(ae.validate(bd.ENTITY_NAME,e,bd.getSchema()),t)}static getSchema(){return{type:"object",required:["automatic_expiry","automatic_update"],properties:{id:{type:"string",format:"uuid"},default_expiry_period:{type:"null"},policy_override:{type:"boolean"},automatic_expiry:{type:"boolean"},automatic_update:{type:"boolean"},created:{type:"string",format:"date-time"},created_by:{type:"string",format:"uuid"},modified:{type:"string",format:"date-time"},modified_by:{type:"string",format:"uuid"}}}}calculateDefaultResourceExpiryDate(){return null}get isFeatureEnabled(){return Boolean(this._props.id)}static get ENTITY_NAME(){return"PasswordExpirySettings"}static createFromDefault(e={}){const t={default_expiry_period:null,policy_override:!1,automatic_expiry:!1,automatic_update:!1,...e};return new bd(t)}}const fd=bd;class Ed extends se{constructor(e,t={}){super(ae.validate(Ed.ENTITY_NAME,e,Ed.getSchema()),t)}static getSchema(){return{type:"object",required:["automatic_expiry","automatic_update","policy_override"],properties:{id:{type:"string",format:"uuid"},default_expiry_period:{type:"integer",minimum:1,maximum:999,nullable:!0},policy_override:{type:"boolean"},automatic_expiry:{type:"boolean"},automatic_update:{type:"boolean"},created:{type:"string",format:"date-time"},created_by:{type:"string",format:"uuid"},modified:{type:"string",format:"date-time"},modified_by:{type:"string",format:"uuid"}}}}calculateDefaultResourceExpiryDate(){return this.isFeatureEnabled&&this._props.default_expiry_period?Ds.c9.utc().plus({days:this._props.default_expiry_period}).toISO():null}get isFeatureEnabled(){return Boolean(this._props.id)}static get ENTITY_NAME(){return"passwordExpiryProSettingsEntity"}static createFromDefault(e={}){const t={default_expiry_period:null,policy_override:!1,automatic_expiry:!0,automatic_update:!0,...e};return new Ed(t)}}const vd=Ed;class wd{constructor(e={}){this.automatic_update=Boolean(e?.automatic_update),this.policy_override=Boolean(e?.policy_override),this.automatic_expiry=Boolean(e?.automatic_expiry);const t=parseInt(e?.default_expiry_period,10);this.default_expiry_period=isNaN(t)?null:t,this.default_expiry_period_toggle=void 0!==e?.default_expiry_period_toggle?Boolean(e.default_expiry_period_toggle):Boolean(this.default_expiry_period),e?.id&&(this.id=e?.id)}static getSchema(e=!1){const t=e?vd.getSchema():fd.getSchema();return this.getDefaultSchema(t,e)}static getDefaultSchema(e,t=!1){const a={type:"object",required:["automatic_expiry","automatic_update"],properties:{id:e.properties.id,automatic_expiry:e.properties.automatic_expiry,automatic_update:e.properties.automatic_update,policy_override:e.properties.policy_override,default_expiry_period:e.properties.default_expiry_period}};return t&&a.required.push("policy_override"),a}static fromEntityDto(e){const t={automatic_expiry:Boolean(e?.automatic_expiry),automatic_update:Boolean(e?.automatic_update),policy_override:Boolean(e?.policy_override),default_expiry_period:null!==e?.default_expiry_period?parseInt(e?.default_expiry_period,10):null};return e?.id&&(t.id=e.id),new wd(t)}static isDataDifferent(e,t){return["automatic_expiry","automatic_update","policy_override","default_expiry_period"].some(a=>e[a]!==t[a])}toEntityDto(){const e=this.default_expiry_period_toggle?this.default_expiry_period:null;return{automatic_expiry:this.automatic_expiry,automatic_update:this.automatic_update,policy_override:this.policy_override,default_expiry_period:e}}cloneWithMutation(e,t){const a={...this,[e]:t};return new wd(a)}validate(e=!1){const t=new X,a=wd.getSchema(e);try{ae.validate(this.constructor.name,this,a),this.validateFormInput(t,e)}catch(t){if(!(t instanceof X))throw t;return this.validateFormInput(t,e),t}return t}validateFormInput(e,t){t&&this.default_expiry_period_toggle&&null===this.default_expiry_period&&e.addError("default_expiry_period","required","The default_expiry_period is required.")}get isSettingsDisabled(){return!this.id}}const kd=wd;function _d(){return _d=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},get:()=>{},setSettingsBulk:()=>{},findSettings:()=>{},isProcessing:()=>{},validateData:()=>{},save:()=>{},getErrors:()=>{},isFeatureToggleEnabled:()=>{},setFeatureToggle:()=>{},hasSettingsChanges:()=>{},isSubmitted:()=>{},setSubmitted:()=>{},setDefaultExpiryToggle:()=>{}});class Sd extends n.Component{constructor(e){super(e),this.state=this.defaultState}get defaultState(){return{processing:!1,errors:null,hasBeenValidated:!1,isDataModified:!1,submitted:!1,currentSettings:new kd,featureToggleEnabled:!1,settings:new kd,findSettings:this.findSettings.bind(this),getSettings:this.getSettings.bind(this),setSettingsBulk:this.setSettingsBulk.bind(this),isProcessing:this.isProcessing.bind(this),validateData:this.validateData.bind(this),save:this.save.bind(this),getErrors:this.getErrors.bind(this),hasSettingsChanges:this.hasSettingsChanges.bind(this),isFeatureToggleEnabled:this.isFeatureToggleEnabled.bind(this),setFeatureToggle:this.setFeatureToggle.bind(this),setDefaultExpiryToggle:this.setDefaultExpiryToggle.bind(this),isSubmitted:this.isSubmitted.bind(this),setSubmitted:this.setSubmitted.bind(this)}}async findSettings(){this.setState({processing:!0}),this.setState({submitted:!1});const e=await this.props.context.port.request("passbolt.password-expiry.get-or-find",!0),t=kd.fromEntityDto(e);this.setState({toggleEnabled:t?.id,settings:t,currentSettings:t,processing:!1})}setDefaultExpiryToggle(e){let t=this.state.settings.default_expiry_period;e&&null===this.state.settings.default_expiry_period&&(t=90),this.setSettingsBulk({default_expiry_period_toggle:e,default_expiry_period:t})}getSettings(){return this.state.settings}setSubmitted(e){this.setState({submitted:e})}isSubmitted(){return this.state.submitted}setSettingsBulk(e){let t=this.state.settings;const a=Object.keys(e);for(let n=0;nn.createElement(e,_d({adminPasswordExpiryContext:t},this.props)))}}}Sd.propTypes={context:i().any,children:i().any,t:i().any},N((0,f.CI)("common")(Sd));class Nd extends n.Component{constructor(e){super(e),this.bindCallbacks()}bindCallbacks(){this.handleSave=this.handleSave.bind(this)}get isActionEnabled(){return!this.props.adminPasswordExpiryContext.isProcessing()}async handleSave(){if(this.props.adminPasswordExpiryContext.setSubmitted(!0),this.isActionEnabled&&this.props.adminPasswordExpiryContext.validateData())try{await this.props.adminPasswordExpiryContext.save(),await this.handleSaveSuccess()}catch(e){await this.handleSaveError(e)}}async handleSaveSuccess(){await this.props.actionFeedbackContext.displaySuccess(this.props.t("The password expiry settings were updated."))}async handleSaveError(e){console.error(e),await this.props.actionFeedbackContext.displayError(e.message),this.props.dialogContext.open($t,{error:e})}render(){const e=!this.isActionEnabled;return n.createElement("div",{className:"actions-wrapper"},n.createElement("button",{type:"button",className:"button primary form",disabled:e,id:"save-settings",onClick:this.handleSave},n.createElement("span",null,n.createElement(f.x6,null,"Save"))))}}Nd.propTypes={adminPasswordExpiryContext:i().object,actionFeedbackContext:i().object,dialogContext:i().any,t:i().func};const Td=m(Cd(h((0,f.CI)("common")(Nd))));class Ad extends n.PureComponent{constructor(e){super(e),this.bindCallbacks()}bindCallbacks(){this.handleFormSubmit=this.handleFormSubmit.bind(this),this.handleInputChange=this.handleInputChange.bind(this),this.handleExpiryPeriodToggleClick=this.handleExpiryPeriodToggleClick.bind(this)}handleInputChange(e){const{type:t,checked:a,value:n,name:s}=e.target,i="checkbox"===t?a:parseInt(n,10);this.props.adminPasswordExpiryContext.setSettingsBulk({[s]:i})}handleExpiryPeriodToggleClick(e){const t=e.target.checked;this.props.adminPasswordExpiryContext.setDefaultExpiryToggle(t)}async handleFormSubmit(e){if(e.preventDefault(),this.props.adminPasswordExpiryContext.setSubmitted(!0),!this.props.adminPasswordExpiryContext.isProcessing()&&this.props.adminPasswordExpiryContext.validateData())try{await this.props.adminPasswordExpiryContext.save(),await this.handleSaveSuccess()}catch(e){await this.handleSaveError(e)}}async handleSaveSuccess(){await this.props.actionFeedbackContext.displaySuccess(this.props.t("The password expiry settings were updated."))}async handleSaveError(e){await this.props.actionFeedbackContext.displayError(e.message),this.props.dialogContext.open($t,{error:e})}hasAllInputDisabled(){return this.props.adminPasswordExpiryContext.isProcessing()}get settings(){return this.props.adminPasswordExpiryContext.getSettings()}get errors(){const e=this.props.adminPasswordExpiryContext.getErrors();return e?.details}render(){const e=this.props.adminPasswordExpiryContext.isSubmitted(),t=this.settings.default_expiry_period||"",a=Boolean(this.settings?.default_expiry_period_toggle);return n.createElement("div",{id:"password-expiry-form-advanced"},n.createElement("form",{className:"form",onSubmit:this.handleFormSubmit},n.createElement("h4",{className:"no-border",id:"expiry-policies-subtitle"},n.createElement(f.x6,null,"Expiry Policies")),n.createElement("p",{id:"expiry-policies-description"},n.createElement(f.x6,null,"In this section you can choose the default behaviour of password expiry policy for all users.")),n.createElement("div",{className:"togglelist-alt"},n.createElement("span",{id:"default-expiry-period",className:"input toggle-switch form-element "+(this.errors?.default_expiry_period&&e?"has-error":"")},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"defaultExpiryPeriodToggle",onChange:this.handleExpiryPeriodToggleClick,checked:a,disabled:this.hasAllInputDisabled(),id:"default-expiry-period-toggle"}),n.createElement("label",{htmlFor:"default-expiry-period-toggle"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Default password expiry period")),n.createElement("span",{className:"info-input"},n.createElement(f.x6,null,n.createElement("span",null,"When a user creates a resource, a default expiry date is set to "),n.createElement("input",{type:"text",className:"toggle-input",id:"default-expiry-period-input",name:"default_expiry_period",onChange:this.handleInputChange,maxLength:3,value:t,disabled:this.hasAllInputDisabled()||!a,placeholder:"90"}),n.createElement("span",null,"days"))))),this.errors?.default_expiry_period&&e&&n.createElement("div",{className:"input"},!this.errors.default_expiry_period.required&&n.createElement("div",{className:"default-expiry-period-gte error-message"},n.createElement(f.x6,null,"The default password expiry period should be a number between 1 and 999 days.")),this.errors?.default_expiry_period.required&&n.createElement("div",{className:"default-expiry-period-required error-message"},n.createElement(f.x6,null,"The default password expiry period should be a valid number.")))),n.createElement("div",{className:"togglelist-alt"},n.createElement("span",{className:"input toggle-switch form-element",id:"policy-override"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"policy_override",onChange:this.handleInputChange,checked:this.settings.policy_override,disabled:this.hasAllInputDisabled(),id:"policy-override-toggle"}),n.createElement("label",{htmlFor:"policy-override-toggle"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Policy Override")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"Allow users to override the default policy."))))),n.createElement("h4",{className:"no-border",id:"automatic-workflow-subtitle"},n.createElement(f.x6,null,"Automatic workflows")),n.createElement("p",{id:"automatic-workflow-description"},n.createElement(f.x6,null,"In this section you can choose automatic behaviours.")),n.createElement("div",{className:"togglelist-alt"},n.createElement("span",{className:"input toggle-switch form-element",id:"automatic-expiry"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"automatic_expiry",onChange:this.handleInputChange,checked:this.settings.automatic_expiry,disabled:this.hasAllInputDisabled(),id:"automatic-expiry-toggle"}),n.createElement("label",{htmlFor:"automatic-expiry-toggle"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Automatic Expiry")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"Password automatically expires when a user or group with a user who has accessed the password is removed from the permission list."))))),n.createElement("div",{className:"togglelist-alt"},n.createElement("span",{className:"input toggle-switch form-element",id:"automatic-update"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"automatic_update",onChange:this.handleInputChange,checked:this.settings.automatic_update,disabled:this.hasAllInputDisabled(),id:"automatic-update-toggle"}),n.createElement("label",{htmlFor:"automatic-update-toggle"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Automatic Update")),n.createElement("span",{className:"info"},a?n.createElement(f.x6,null,"Password expiry date is renewed based on the default password expiry period whenever a password is updated."):n.createElement(f.x6,null,"Password is no longer marked as expired whenever the password is updated.")))))))}}Ad.propTypes={context:i().object,adminPasswordExpiryContext:i().object,actionFeedbackContext:i().object,dialogContext:i().object,t:i().func};const Id=N(Cd(m(h((0,f.CI)("common")(Ad)))));class Rd extends n.PureComponent{constructor(e){super(e),this.state=this.defaultState}get defaultState(){return{isReady:!1}}async componentDidMount(){await this.props.adminPasswordExpiryContext.findSettings(),this.setState({isReady:!0})}hasAllInputDisabled(){return this.props.adminPasswordExpiryContext.isProcessing()}get canUseAdvancedSettings(){return this.props.context.siteSettings.canIUse("passwordExpiryPolicies")}render(){if(!this.state.isReady)return null;const e=this.props.adminPasswordExpiryContext,t=e.isFeatureToggleEnabled();return n.createElement("div",{className:"row"},n.createElement("div",{className:"password-expiry-settings main-column"},n.createElement("div",{className:"main-content"},n.createElement("h3",{id:"password-expiry-settings-title",className:"title"},n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"passwordExpirySettingsToggle",onChange:()=>e.setFeatureToggle(!t),checked:t,disabled:this.hasAllInputDisabled(),id:"passwordExpirySettingsToggle"}),n.createElement("label",{htmlFor:"passwordExpirySettingsToggle"},n.createElement(f.x6,null,"Password Expiry")))),!t&&n.createElement("p",{className:"description"},n.createElement(f.x6,null,"No Password Expiry is configured. Enable it to activate automatic password expiration and automatic password expiration reset workflows.")),t&&n.createElement(n.Fragment,null,this.canUseAdvancedSettings?n.createElement(Id,null):n.createElement("div",{id:"password-expiry-settings-form"},n.createElement("h4",{id:"password-expiry-settings-automatic-workflows",className:"title title--required no-border"},n.createElement(f.x6,null,"Automatic workflows")),n.createElement("div",{className:"radiolist-alt"},n.createElement("div",{className:"input radio"},n.createElement("label",{htmlFor:"passwordExpiryAutomaticExpiry"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Automatic expiry")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"Password automatically expires when a user or group with a user who has accessed the password is removed from the permission list.")))),n.createElement("div",{className:"input radio"},n.createElement("label",{htmlFor:"passwordExpiryAutomatiUpdate"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Automatic update")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"Password is no longer marked as expired whenever the password is updated.")))))))),e.hasSettingsChanges()&&n.createElement("div",{className:"warning message",id:"password-expiry-settings-save-banner"},n.createElement("div",null,n.createElement("p",null,n.createElement(f.x6,null,"Don't forget to save your settings to apply your modification."))))),n.createElement(Td,null),Xa(n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"About password expiry")),n.createElement("p",null,n.createElement(f.x6,null,"For more information about the password expiry, checkout the dedicated page on the help website.")),n.createElement("a",{className:"button",href:"https://passbolt.com/docs/admin/password-configuration/password-expiry",target:"_blank",rel:"noopener noreferrer"},n.createElement(Er,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}Rd.propTypes={context:i().object,administrationWorkspaceContext:i().object,adminPasswordExpiryContext:i().object,t:i().func};const Pd=N(Ne(Cd((0,f.CI)("common")(Rd))));class Dd extends n.Component{get errorTitle(){return{403:this.props.t("Whoops... access is denied"),404:this.props.t("Whoops... looks like you are lost.")}[this.props.errorCode]||""}get errorDescription(){return{403:this.props.t("Access is restricted to authorized users only."),404:this.props.t("We could not find the page you are looking for.")}[this.props.errorCode]||""}render(){return n.createElement("div",{className:"row"},n.createElement("div",{className:"http-error main-column"},n.createElement("div",{className:"main-content"},n.createElement("h3",null,this.props.errorCode),n.createElement("h4",null,this.errorTitle),n.createElement("div",null,n.createElement("p",null,this.errorDescription)))))}}Dd.propTypes={errorCode:i().number.isRequired,t:i().func};const Od=(0,f.CI)("common")(Dd),Md=class{constructor(e){this.apiClientOptions=e,this.initClient()}async fetchHealthcheck(){this.initClient();const e=await this.apiClient.findAll();return e?.body}initClient(){this.apiClientOptions.setResourceName("healthcheck"),this.apiClient=new pt(this.apiClientOptions)}};class Ud extends se{constructor(e,t={}){super(ae.validate(Ud.ENTITY_NAME,e,Ud.getSchema()),t)}static getSchema(){return{type:"object",required:["peerValid","hostValid","notSelfSigned"],properties:{peerValid:{type:"boolean"},hostValid:{type:"boolean"},notSelfSigned:{type:"boolean"},info:{type:"string"}}}}get peerValid(){return this._props.peerValid}get hostValid(){return this._props.hostValid}get notSelfSigned(){return this._props.notSelfSigned}get info(){return this._props.info}static get ENTITY_NAME(){return"ssl"}}const Fd=Ud;class jd extends se{constructor(e,t={}){super(ae.validate(jd.ENTITY_NAME,e,jd.getSchema()),t)}static getSchema(){return{type:"object",required:["tablesCount","info","connect","supportedBackend","defaultContent"],properties:{tablesCount:{type:"boolean"},info:{type:"object",required:["tablesCount"],properties:{tablesCount:{type:"number"}}},connect:{type:"boolean"},supportedBackend:{type:"boolean"},defaultContent:{type:"boolean"}}}}get tablesCount(){return this._props.tablesCount}get info(){return this._props.info}get connect(){return this._props.connect}get supportedBackend(){return this._props.supportedBackend}get defaultContent(){return this._props.defaultContent}static get ENTITY_NAME(){return"database"}}const Ld=jd;class qd extends se{constructor(e,t={}){super(ae.validate(qd.ENTITY_NAME,e,qd.getSchema()),t)}static getSchema(){return{type:"object",required:["info","latestVersion","schema","robotsIndexDisabled","sslForce","sslFullBaseUrl","seleniumDisabled","registrationClosed","configPath","hostAvailabilityCheckEnabled","jsProd","emailNotificationEnabled"],properties:{info:{type:"object",required:["remoteVersion","currentVersion"],properties:{remoteVersion:{type:"string",nullable:!0},currentVersion:{type:"string"}}},latestVersion:{type:"boolean",nullable:!0},schema:{type:"boolean"},robotsIndexDisabled:{type:"boolean"},sslForce:{type:"boolean"},sslFullBaseUrl:{type:"boolean"},seleniumDisabled:{type:"boolean"},configPath:{type:"string"},registrationClosed:{type:"object",required:["isSelfRegistrationPluginEnabled","selfRegistrationProvider","isRegistrationPublicRemovedFromPassbolt"],properties:{isSelfRegistrationPluginEnabled:{type:"boolean"},selfRegistrationProvider:{type:"string",nullable:!0},isRegistrationPublicRemovedFromPassbolt:{type:"boolean"}}},hostAvailabilityCheckEnabled:{type:"boolean"},jsProd:{type:"boolean"},emailNotificationEnabled:{type:"boolean"}}}}get info(){return this._props.info}get latestVersion(){return this._props.latestVersion}getSchema(){return this._props.getSchema}get robotsIndexDisabled(){return this._props.robotsIndexDisabled}get sslForce(){return this._props.sslForce}get sslFullBaseUrl(){return this._props.sslFullBaseUrl}get schema(){return this._props.schema}get currentVersion(){return this._props.currentVersion}get configPath(){return this._props.configPath}get seleniumDisabled(){return this._props.seleniumDisabled}get registrationClosed(){return this._props.registrationClosed}get hostAvailabilityCheckEnabled(){return this._props.hostAvailabilityCheckEnabled}get jsProd(){return this._props.jsProd}get emailNotificationEnabled(){return this._props.emailNotificationEnabled}static get ENTITY_NAME(){return"application"}}const zd=qd;class Kd extends se{constructor(e,t={}){super(ae.validate(Kd.ENTITY_NAME,e,Kd.getSchema()),t)}static getSchema(){return{type:"object",required:["canDecryptVerify","canVerify","gpgKeyPublicInKeyring","canEncrypt","canDecrypt","canEncryptSign","canSign","gpgHome","gpgKeyPrivateFingerprint","gpgKeyPublicFingerprint","gpgKeyPublicEmail","gpgKeyPublicReadable","gpgKeyPrivateReadable","gpgKey","lib","gpgKeyNotDefault","info","gpgHomeWritable","gpgKeyPublic","gpgKeyPublicBlock","gpgKeyPrivate","gpgKeyPrivateBlock","isPublicServerKeyGopengpgCompatible","isPrivateServerKeyGopengpgCompatible"],properties:{canDecryptVerify:{type:"boolean"},canVerify:{type:"boolean"},gpgKeyPublicInKeyring:{type:"boolean"},canEncrypt:{type:"boolean"},canDecrypt:{type:"boolean"},canEncryptSign:{type:"boolean"},canSign:{type:"boolean"},gpgHome:{type:"boolean"},gpgKeyPrivateFingerprint:{type:"boolean"},gpgKeyPublicFingerprint:{type:"boolean"},gpgKeyPublicEmail:{type:"boolean"},gpgKeyPublicReadable:{type:"boolean"},gpgKeyPrivateReadable:{type:"boolean"},gpgKey:{type:"boolean"},lib:{type:"boolean"},gpgKeyNotDefault:{type:"boolean"},gpgHomeWritable:{type:"boolean"},gpgKeyPublic:{type:"boolean"},gpgKeyPublicBlock:{type:"boolean"},gpgKeyPrivate:{type:"boolean"},gpgKeyPrivateBlock:{type:"boolean"},isPublicServerKeyGopengpgCompatible:{type:"boolean"},isPrivateServerKeyGopengpgCompatible:{type:"boolean"},info:{type:"object",required:["gpgHome","gpgKeyPrivate"],properties:{gpgHome:{type:"string"},gpgKeyPrivate:{type:"string"}}}}}}get canDecryptVerify(){return this._props.canDecryptVerify}get canVerify(){return this._props.canVerify}get gpgKeyPublicInKeyring(){return this._props.gpgKeyPublicInKeyring}get canEncrypt(){return this._props.canEncrypt}get canDecrypt(){return this._props.canDecrypt}get canEncryptSign(){return this._props.canEncryptSign}get canSign(){return this._props.canSign}get gpgHome(){return this._props.gpgHome}get gpgKeyPrivateFingerprint(){return this._props.gpgKeyPrivateFingerprint}get gpgKeyPublicFingerprint(){return this._props.gpgKeyPublicFingerprint}get gpgKeyPublicEmail(){return this._props.gpgKeyPublicEmail}get gpgKeyPublicReadable(){return this._props.gpgKeyPublicReadable}get gpgKeyPrivateReadable(){return this._props.gpgKeyPrivateReadable}get gpgKey(){return this._props.gpgKey}get lib(){return this._props.lib}get gpgKeyNotDefault(){return this._props.gpgKeyNotDefault}get info(){return this._props.info}get gpgHomeWritable(){return this._props.gpgHomeWritable}get gpgKeyPublic(){return this._props.gpgKeyPublic}get gpgKeyPublicBlock(){return this._props.gpgKeyPublicBlock}get gpgKeyPrivate(){return this._props.gpgKeyPrivate}get gpgKeyPrivateBlock(){return this._props.gpgKeyPrivateBlock}get isPublicServerKeyGopengpgCompatible(){return this._props.isPublicServerKeyGopengpgCompatible}get isPrivateServerKeyGopengpgCompatible(){return this._props.isPrivateServerKeyGopengpgCompatible}static get ENTITY_NAME(){return"gpg"}}const Vd=Kd;class Gd extends se{constructor(e,t={}){super(ae.validate(Gd.ENTITY_NAME,e,Gd.getSchema()),t)}static getSchema(){return{type:"object",required:["phpVersion","nextMinPhpVersion","pcre","mbstring","gnupg","intl","image","tmpWritable","logWritable"],properties:{phpVersion:{type:"boolean"},nextMinPhpVersion:{type:"boolean"},pcre:{type:"boolean"},mbstring:{type:"boolean"},gnupg:{type:"boolean"},intl:{type:"boolean"},image:{type:"boolean"},tmpWritable:{type:"boolean"},logWritable:{type:"boolean"},info:{type:"object",required:["phpVersion"],properties:{serverPhpVersion:{"type:":"string"}}}}}}get phpVersion(){return this._props.phpVersion}get nextMinPhpVersion(){return this._props.nextMinPhpVersion}get pcre(){return this._props.pcre}get mbstring(){return this._props.mbstring}get gnupg(){return this._props.gnupg}get intl(){return this._props.intl}get image(){return this._props.image}get tmpWritable(){return this._props.tmpWritable}get logWritable(){return this._props.logWritable}get info(){return this._props.info}get serverPhpVersion(){return this._props.phpVersion}static get ENTITY_NAME(){return"environment"}}const Bd=Gd;class Wd extends se{constructor(e,t={}){super(ae.validate(Wd.ENTITY_NAME,e,Wd.getSchema()),t)}static getSchema(){return{type:"object",required:["app","passbolt"],properties:{app:{type:"boolean"},passbolt:{type:"boolean"}}}}get app(){return this._props.app}get passbolt(){return this._props.passbolt}static get ENTITY_NAME(){return"configFile"}}const Hd=Wd;class $d extends se{constructor(e,t={}){super(ae.validate($d.ENTITY_NAME,e,$d.getSchema()),t)}static getSchema(){return{type:"object",required:["cache","debugDisabled","salt","fullBaseUrl","validFullBaseUrl","info","fullBaseUrlReachable"],properties:{cache:{type:"boolean"},debugDisabled:{type:"boolean"},salt:{type:"boolean"},fullBaseUrl:{type:"boolean"},validFullBaseUrl:{type:"boolean"},info:{type:"object",required:["fullBaseUrl"],properties:{fullBaseUrl:{type:"string",format:"uri"}}},fullBaseUrlReachable:{type:"boolean"}}}}get cache(){return this._props.cache}get debugDisabled(){return this._props.debugDisabled}get salt(){return this._props.salt}get fullBaseUrl(){return this._props.fullBaseUrl}get validFullBaseUrl(){return this._props.validFullBaseUrl}get info(){return this._props.info}get fullBaseUrlReachable(){return this._props.fullBaseUrlReachable}static get ENTITY_NAME(){return"core"}}const Yd=$d;class Zd extends se{constructor(e,t={}){super(ae.validate(Zd.ENTITY_NAME,e,Zd.getSchema()),t)}static getSchema(){return{type:"object",required:["isEnabled","areEndpointsDisabled","errorMessage","source","isInDb"],properties:{isEnabled:{type:"boolean"},areEndpointsDisabled:{type:"boolean"},errorMessage:{anyOf:[{type:"boolean"},{type:"string"}]},source:{type:"string"},isInDb:{type:"boolean"}}}}get isEnabled(){return this._props.isEnabled}get areEndpointsDisabled(){return this._props.areEndpointsDisabled}get errorMessage(){return this._props.errorMessage}get source(){return this._props.source}get isInDb(){return this._props.isInDb}static get ENTITY_NAME(){return"smtpSettings"}}const Jd=Zd;class Xd extends se{constructor(e,t={}){super(ae.validate(Xd.ENTITY_NAME,e,Xd.getSchema()),t)}static getSchema(){return{type:"object",required:["endpointsDisabled"],properties:{endpointsDisabled:{type:"boolean"}}}}get endpointsDisabled(){return this._props.endpointsDisabled}static get ENTITY_NAME(){return"directorySync"}}const Qd=Xd;class eu extends se{constructor(e,t={}){super(ae.validate(eu.ENTITY_NAME,e,eu.getSchema()),t)}static getSchema(){return{type:"object",required:["sslHostVerification"],properties:{sslHostVerification:{type:"boolean"}}}}get sslHostVerification(){return this._props.sslHostVerification}static get ENTITY_NAME(){return"sso"}}const tu=eu;class au extends se{constructor(e,t={}){super(ae.validate(au.ENTITY_NAME,e,au.getSchema()),t)}static getSchema(){return{type:"object",required:["canDecryptMetadataPrivateKey"],properties:{canDecryptMetadataPrivateKey:{type:"boolean"},canValidatePrivateMetadataKey:{type:"boolean"},isServerHasAccessToMetadataKey:{type:"boolean"},isServerMetadataKeyAccessInZeroKnowledgeMode:{type:"boolean"},noActiveMetadataKey:{type:"boolean"}}}}get canDecryptMetadataPrivateKey(){return this._props.canDecryptMetadataPrivateKey}get canValidatePrivateMetadataKey(){return this._props.canValidatePrivateMetadataKey}get isServerHasAccessToMetadataKey(){return this._props.isServerHasAccessToMetadataKey}get isServerMetadataKeyAccessInZeroKnowledgeMode(){return this._props.isServerMetadataKeyAccessInZeroKnowledgeMode}get noActiveMetadataKey(){return this._props.noActiveMetadataKey}static get ENTITY_NAME(){return"metadata"}}const nu=au;class su extends se{constructor(e,t={}){super(ae.validate(su.ENTITY_NAME,e,su.getSchema()),t),this._props.ssl&&(this._ssl=new Fd(this._props.ssl,{clone:!1}),delete this._props.ssl),this._props.database&&(this._database=new Ld(this._props.database,{clone:!1}),delete this._props.database),this._props.application&&(this._application=new zd(this._props.application,{clone:!1}),delete this._props.application),this._props.gpg&&(this._gpg=new Vd(this._props.gpg,{clone:!1}),delete this._props.gpg),this._props.environment&&(this._environment=new Bd(this._props.environment,{clone:!1}),delete this._props.environment),this._props.configFile&&(this._configFile=new Hd(this._props.configFile,{clone:!1}),delete this._props.configFile),this._props.core&&(this._core=new Yd(this._props.core,{clone:!1}),delete this._props.core),this._props.smtpSettings&&(this._smtpSettings=new Jd(this._props.smtpSettings,{clone:!1}),delete this._props.smtpSettings),this._props.directorySync&&(this._directorySync=new Qd(this._props.directorySync,{clone:!1}),delete this._props.directorySync),this._props.sso&&(this._sso=new tu(this._props.sso,{clone:!1}),delete this._props.sso),this._props.metadata&&(this._metadata=new nu(this._props.metadata,{clone:!1}),delete this._props.metadata)}static getSchema(){return{type:"object",required:["database","ssl","application","gpg","configFile","core","smtpSettings"],properties:{database:Ld.getSchema(),ssl:Fd.getSchema(),application:zd.getSchema(),gpg:Vd.getSchema(),environment:Bd.getSchema(),configFile:Hd.getSchema(),core:Yd.getSchema(),smtpSettings:Jd.getSchema(),directorySync:Qd.getSchema(),sso:tu.getSchema(),metadata:nu.getSchema()}}}isSSLValid(){const e=this._props.ssl;return e.peerValid&&e.hostValid&&!e.notSelfSigned}static get ENTITY_NAME(){return"healthcheck"}get ssl(){return this._ssl||null}get database(){return this._database||null}get application(){return this._application||null}get gpg(){return this._gpg||null}get environment(){return this._environment||null}get configFile(){return this._configFile||null}get core(){return this._core||null}get smtpSettings(){return this._smtpSettings||null}get directorySync(){return this._directorySync||null}get sso(){return this._sso||null}get metadata(){return this._metadata}}const iu=su;function ru(){return ru=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},isProcessing:()=>{},loadHealthcheckData:()=>{},clearContext:()=>{},isHealthcheckEndpointEnabled:()=>{}});class lu extends n.Component{constructor(e){super(e),this.state=this.defaultState;const t=e.context.getApiClientOptions();this.healthcheckService=new Md(t)}get defaultState(){return{healthcheckData:null,endpointEnabled:!0,processing:!1,isProcessing:this.isProcessing.bind(this),loadHealthcheckData:this.fetchHealthcheckData.bind(this),clearContext:this.clearContext.bind(this),isHealthcheckEndpointEnabled:this.isHealthcheckEndpointEnabled.bind(this)}}isHealthcheckEndpointEnabled(){return this.state.endpointEnabled}async fetchHealthcheckData(){if(this.isHealthcheckEndpointEnabled()){this.setProcessing(!0);try{const e=await this.healthcheckService.fetchHealthcheck();if(e){const t=new iu(e);this.setState({healthcheckData:t})}else this.props.actionFeedbackContext.displayError("No data received from the server")}catch(e){console.error(e),this.setState({endpointEnabled:!1}),this.props.actionFeedbackContext.displayError(e.message)}finally{this.setProcessing(!1)}}}clearContext(){this.setState(this.defaultState)}isProcessing(){return this.state.processing}setProcessing(e){this.setState({processing:e})}render(){return n.createElement(ou.Provider,{value:this.state},this.props.children)}}lu.propTypes={context:i().any,actionFeedbackContext:i().any,children:i().any};const cu=N(m(lu));function mu(e){return class extends n.Component{render(){return n.createElement(ou.Consumer,null,t=>n.createElement(e,ru({adminHealthcheckContext:t},this.props)))}}}var du,uu,pu;function hu(){return hu=Object.assign?Object.assign.bind():function(e){for(var t=1;t!0===e.database.connect&&!0===e.database.defaultContent?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"Some default content is present")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"No default content found"),n.createElement(Mt,{message:this.props.t("Run the install script to set the dafault content such as roles and permission types")},n.createElement(jt,{className:"baseline svg-icon"}))),a=()=>!0===e.core.cache?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"Cache is working")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"Cache is not working"),n.createElement(Mt,{message:this.props.t("Check the settings in config/app.php")},n.createElement(jt,{className:"baseline svg-icon"}))),s=()=>!0===e.core.salt?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"Unique value set for security.salt")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"Default value found for security.salt"),n.createElement(Mt,{message:this.props.t("Edit the security.salt in config/app.php")},n.createElement(jt,{className:"baseline svg-icon"}))),i=()=>!0===e.configFile.app?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The application config file is present")):n.createElement("span",{className:"healthcheck-warning"},n.createElement(Au,null),n.createElement(f.x6,null,"The application config file is missing"),n.createElement(Mt,{message:this.props.t("Copy config/app.default.php to config/app.php")},n.createElement(jt,{className:"baseline svg-icon"}))),r=()=>!0===e.configFile.passbolt?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The passbolt config file is present")):n.createElement("span",{className:"healthcheck-warning"},n.createElement(Au,null),n.createElement(f.x6,null,"The passbolt config file is missing"),n.createElement(Mt,{message:this.props.t("Copy config/passbolt.default.php to config/passbolt.php")},n.createElement(jt,{className:"baseline svg-icon"}))),o=()=>!0===e.environment.pcre?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"PCRE compiled with unicode support")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"PCRE has not been compiled with Unicode support"),n.createElement(Mt,{message:this.props.t("Recompile PCRE with Unicode support by adding --enable-unicode-properties when configuring.")},n.createElement(jt,{className:"baseline svg-icon"}))),l=()=>!0===e.environment.tmpWritable?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The temporary directory and its content are writable and not executable")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"The temporary directory and its content are not writable, or are executable"),n.createElement(Mt,{message:this.props.t("Ensure the temporary directory and its content are writable by the webserver user.")},n.createElement(jt,{className:"baseline svg-icon"}))),c=()=>!0===e.environment.logWritable?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The logs directory and its content are writable")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"The logs directory and its content are not writable"),n.createElement(Mt,{message:this.props.t("Ensure the temporary directory and its content are writable by the webserver user.")},n.createElement(jt,{className:"baseline svg-icon"}))),m=()=>{const t=e.gpg.info.gpgHome.toString();return!0===e.gpg.gpgHome&&e.gpg.info.gpgHome?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The environment variable GNUPGHOME is set to ",{gpgHomeDirectory:t})):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"The environment variable GNUPGHOME is set to ",{gpgHomeDirectory:t}," but the directory does not exist"),n.createElement(Mt,{message:this.props.t("Ensure the keyring location exists and is accessible by the webserver user.")},n.createElement(jt,{className:"baseline svg-icon"})))},d=()=>{const t=e.gpg.info.gpgHome.toString();return!0===e.gpg.gpgHomeWritable&&e.gpg.info.gpgHome?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The directory ",{gpgHomeDirectory:t}," containing the keyring is writable by the webserver user")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"The directory ",{gpgHomeDirectory:t}," containing the keyring is not writable by the webserver user"),n.createElement(Mt,{message:this.props.t("Ensure the keyring location exists and is accessible by the webserver user.")},n.createElement(jt,{className:"baseline svg-icon"})))},u=()=>{const t=e.application.configPath.toString();return!0===e.gpg.gpgKeyPrivateFingerprint&&!0===e.gpg.gpgKeyPublicFingerprint?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The server key fingerprint matches the one defined in ",{configurationFilePath:t})):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"The server key fingerprint doesn't matches the one defined in ",{configurationFilePath:t}),n.createElement(Mt,{message:this.props.t("Double check the key fingerprint")},n.createElement(jt,{className:"baseline svg-icon"})))},p=()=>{const t=e.application.configPath.toString();return!0===e.gpg.gpgKeyPublicInKeyring?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The server public key defined in the ",{configurationFilePath:t}," (or environment variables) is in the keyring")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"The server public key defined in the ",{configurationFilePath:t}," (or environment variables) is not in the keyring"),n.createElement(Mt,{message:this.props.t("Import the private server key in the keyring of the webserver user.")},n.createElement(jt,{className:"baseline svg-icon"})))},h=()=>!0===e.gpg.gpgKeyPublicEmail?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"There is a valid email id defined for the server key")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"The server key does not have a valid email id"),n.createElement(Mt,{message:this.props.t("Edit or generate another key with a valid email id.")},n.createElement(jt,{className:"baseline svg-icon"}))),g=()=>!0===e.application.registrationClosed.isSelfRegistrationPluginEnabled?n.createElement("span",{className:"healthcheck-info"},n.createElement(Cu,null),n.createElement(f.x6,null,"The Self Registration plugin is enabled")):n.createElement("span",{className:"healthcheck-info"},n.createElement(Cu,null),n.createElement(f.x6,null,"The Self Registration plugin is disabled"),n.createElement(Mt,{message:this.props.t("Enable the plugin in order to define self registration settings.")},n.createElement(jt,{className:"baseline svg-icon"}))),y=()=>{const t=e.application.configPath.toString();return!0===e.application.registrationClosed.isRegistrationPublicRemovedFromPassbolt?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The deprecated self registration public settings was not found in ",{configurationFilePath:t})):n.createElement("span",{className:"healthcheck-warning"},n.createElement(Au,null),n.createElement(f.x6,null,"The deprecated self registration public settings was found in ",{configurationFilePath:t}),n.createElement(Mt,{message:this.props.t("You may remove the passbolt.registration.public setting")},n.createElement(jt,{className:"baseline svg-icon"})))},b=()=>!0===e.application.hostAvailabilityCheckEnabled?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"Host availability will be checked")):n.createElement("span",{className:"healthcheck-warning"},n.createElement(Au,null),n.createElement(f.x6,null,"Host availability checking is disabled"),n.createElement(Mt,{message:this.props.t("Make sure the instance is not publicly available on the internet.")},n.createElement(jt,{className:"baseline svg-icon"}))),E=()=>{if(e.smtpSettings.source){const t=e.smtpSettings.source.toString();return!0===e.smtpSettings.isInDb?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The SMTP Settings source is: ",{smtpSettingsSource:t})):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"The SMTP Settings source is: ",{smtpSettingsSource:t}),n.createElement(Mt,{message:this.props.t("It is recommended to set the SMTP Settings in the database through the administration section.")},n.createElement(jt,{className:"baseline svg-icon"})))}},v=()=>!0===e.smtpSettings.areEndpointsDisabled?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The SMTP Settings plugin endpoints are disabled")):n.createElement("span",{className:"healthcheck-warning"},n.createElement(Au,null),n.createElement(f.x6,null,"The SMTP Settings plugin endpoints are enabled"),n.createElement(Mt,{message:this.props.t("It is recommended to disable the plugin endpoints.")},n.createElement(jt,{className:"baseline svg-icon"}))),w=()=>!0===e.directorySync.endpointsDisabled?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The endpoints for updating the users directory configurations are disabled.")):n.createElement("span",{className:"healthcheck-warning"},n.createElement(Au,null),n.createElement(f.x6,null,"The endpoints for updating the users directory configurations are enabled."),n.createElement(Mt,{message:this.props.t("It is recommended to disable endpoints for updating the users directory configurations.")},n.createElement(jt,{className:"baseline svg-icon"}))),k=()=>!0===e.sso.sslHostVerification?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"SSL certification validation for SSO instance is enabled.")):n.createElement("span",{className:"healthcheck-warning"},n.createElement(Au,null),n.createElement(f.x6,null,"SSL certification validation for SSO instance is disabled."),n.createElement(Mt,{message:this.props.t("Disabling the ssl verify check can lead to security attacks.")},n.createElement(jt,{className:"baseline svg-icon"}))),_=()=>!0===e.metadata.canDecryptMetadataPrivateKey?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The server is able to decrypt the metadata private key.")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"Unable to decrypt the metadata private key."),n.createElement(Mt,{message:this.props.t("For more information, please run the health check from the command line on the server.")},n.createElement(jt,{className:"baseline svg-icon"}))),x=()=>!0===e.metadata.canValidatePrivateMetadataKey?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The server metadata private key is valid.")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"The server metadata private key is not valid."),n.createElement(Mt,{message:this.props.t("For more information, please run the health check from the command line on the server.")},n.createElement(jt,{className:"baseline svg-icon"}))),S=()=>!0===e.metadata.isServerHasAccessToMetadataKey?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The server has access to the metadata keys or does not require access to it.")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"The server does not have access to metadata key."),n.createElement(Mt,{message:this.props.t("When zero-knowledge mode is off, the server must have access to the metadata key. Without having access, the server won't be able to share the metadata private key with the users.")},n.createElement(jt,{className:"baseline svg-icon"}))),C=()=>!0===e.metadata.noActiveMetadataKey?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"Active metadata key found or not required.")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"No active metadata key found."),n.createElement(Mt,{message:this.props.t("For more information, please run the health check from the command line on the server.")},n.createElement(jt,{className:"baseline svg-icon"}))),N=this.props.adminHealthcheckContext.isHealthcheckEndpointEnabled();return n.createElement("div",{className:"row"},n.createElement("div",{className:"healthcheck-settings main-column"},n.createElement("div",{className:"main-content"},n.createElement("h3",null,n.createElement(f.x6,null,"Passbolt API Status")),N?(()=>!e||this.props.adminHealthcheckContext.isProcessing()?n.createElement(En,null):n.createElement(n.Fragment,null,n.createElement("h4",{className:"no-border"},n.createElement(f.x6,null,"Environment")),n.createElement("div",{className:"healthcheck-environment-section"},n.createElement("div",null,(()=>{if(e.environment.info.phpVersion&&!0===e.environment.phpVersion){const t=e.environment.info.phpVersion.toString();return n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"PHP version ",{phpVersion:t}))}return n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"PHP version is too low, passbolt need PHP 7.4 or higher"))})()),n.createElement("div",null,o()),n.createElement("div",null,l()),n.createElement("div",null,c()),n.createElement("div",null,!0===e.environment.image?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"GD or Imagick extension is installed")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"You must enable the gd or imagick extensions to use Passbolt"),n.createElement(Mt,{message:n.createElement("span",null,n.createElement(f.x6,null,"See"," ",n.createElement("a",{href:"https://secure.php.net/manual/en/book.image.php",target:"_blank",rel:"noopener noreferrer"},"this guide")))},n.createElement(jt,{className:"baseline svg-icon"})))),n.createElement("div",null,!0===e.environment.intl?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"Intl extension is installed")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"You must enable the intl extension to use Passbolt"),n.createElement(Mt,{message:n.createElement("span",null,n.createElement(f.x6,null,"See"," ",n.createElement("a",{href:"https://secure.php.net/manual/en/book.intl.php",target:"_blank",rel:"noopener noreferrer"},"this guide")))},n.createElement(jt,{className:"baseline svg-icon"})))),n.createElement("div",null,!0===e.environment.mbstring?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"Mbstring extension is installed")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"You must enable the mbstring extension to use Passbolt"),n.createElement(Mt,{message:n.createElement("span",null,n.createElement(f.x6,null,"See"," ",n.createElement("a",{href:"https://secure.php.net/manual/en/book.mbstring.php",target:"_blank",rel:"noopener noreferrer"},"this guide")))},n.createElement(jt,{className:"baseline svg-icon"}))))),n.createElement("h4",null,n.createElement(f.x6,null,"Config files")),n.createElement("div",{className:"healthcheck-configFiles-section"},n.createElement("div",null,i()),n.createElement("div",null,r())),n.createElement("h4",null,n.createElement(f.x6,null,"Core config")),n.createElement("div",{className:"healthcheck-core-section"},n.createElement("div",null,(()=>{if(!1===e.core.debugDisabled){const t=e.application.configPath.toString();return n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"Debug mode is on"),n.createElement(Mt,{message:n.createElement(f.x6,null,"Set debug = false; in ",{configurationFilePath:t})},n.createElement(jt,{className:"baseline svg-icon"})))}})()),n.createElement("div",null,a()),n.createElement("div",null,s()),n.createElement("div",null,(()=>{if(!0===e.core.fullBaseUrl){const t=e.core.info.fullBaseUrl.toString();return n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"Full base url is set to ",{fullBaseUrl:t}))}{const t=e.application.configPath.toString();return n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"Full base url is not set"),n.createElement(Mt,{message:n.createElement(f.x6,null,"Edit App.fullBaseUrl in ",{configurationFilePath:t})},n.createElement(jt,{className:"baseline svg-icon"})))}})()),n.createElement("div",null,(()=>{if(!0===e.core.validFullBaseUrl)return n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"App.fullBaseUrl validation OK"));{const t=e.application.configPath.toString();return n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"App.fullBaseUrl does not validate"),n.createElement(Mt,{message:n.createElement(f.x6,null,"Edit App.fullBaseUrl in ",{configurationFilePath:t})},n.createElement(jt,{className:"baseline svg-icon"})))}})()),n.createElement("div",null,(()=>{if(!0===e.core.fullBaseUrlReachable)return n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"/healthcheck/status is reachable"));{const t=e.application.configPath.toString();return n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"Could not reach the /healthcheck/status with the url specified in App.fullBaseUrl"),n.createElement(Mt,{message:n.createElement(f.x6,null,"Check that the domain name is correct in ",{configurationFilePath:t})},n.createElement(jt,{className:"baseline svg-icon"})))}})())),n.createElement("h4",null,n.createElement(f.x6,null,"SSL Certificate")),n.createElement("div",{className:"healthcheck-ssl-section"},n.createElement("div",null,!0===e.ssl.peerValid?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"SSL peer certificate validates")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"SSL peer certificate does not validate"),n.createElement(Mt,{message:n.createElement("span",null,n.createElement(f.x6,null,"Check"," ",n.createElement("a",{href:"https://www.passbolt.com/docs/hosting/configure/tls/",target:"_blank",rel:"noopener noreferrer"},"this guide")))},n.createElement(jt,{className:"baseline svg-icon"})))),n.createElement("div",null,!0===e.ssl.hostValid?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"Hostname is matching SSL certificate")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"Hostname does not match when validating certificates"),n.createElement(Mt,{message:n.createElement("span",null,n.createElement(f.x6,null,"Check"," ",n.createElement("a",{href:"https://www.passbolt.com/docs/hosting/configure/tls/",target:"_blank",rel:"noopener noreferrer"},"this guide")))},n.createElement(jt,{className:"baseline svg-icon"})))),n.createElement("div",null,!0===e.ssl.notSelfSigned?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"Not using a self-signed certificate")):n.createElement("span",{className:"healthcheck-warning"},n.createElement(Au,null),n.createElement(f.x6,null,"Using a self-signed certificate")))),n.createElement("h4",null,n.createElement(f.x6,null,"Database")),n.createElement("div",{className:"healthcheck-database-section"},n.createElement("div",null,(()=>{if(!0===e.database.connect)return n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The application is able to connect to the database"));{const t=e.application.configPath.toString();return n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"The application is not able to connect to the database"),n.createElement(Mt,{message:n.createElement(f.x6,null,"Double check the host, database name, username and password in ",{configurationFilePath:t})},n.createElement(jt,{className:"baseline svg-icon"})))}})()),n.createElement("div",null,(()=>{if(!0===e.database.connect&&e.database.tablesCount){const t=e.database.info.tablesCount.toString();return n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,{count:t}," tables found"))}})()),n.createElement("div",null,t())),n.createElement("h4",null,n.createElement(f.x6,null,"GPG Configuration")),n.createElement("div",{className:"healthcheck-gpg-section"},n.createElement("div",null,!0===e.gpg.lib?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"PHP GPG Module is installed and loaded")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"PHP GPG Module is not installed or loaded"),n.createElement(Mt,{message:n.createElement("span",null,n.createElement(f.x6,null,"Install php-gnupg, see"," ",n.createElement("a",{href:"http://php.net/manual/en/gnupg.installation.php",target:"_blank",rel:"noopener noreferrer"},"this guide")))},n.createElement(jt,{className:"baseline svg-icon"})))),n.createElement("div",null,m()),n.createElement("div",null,d()),n.createElement("div",null,(()=>{const t=e.application.configPath.toString();return!0===e.gpg.gpgKeyPublic&&!0===e.gpg.gpgKeyPublicReadable&&e.gpg.gpgKeyPublicBlock?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The public key file is defined in ",{configurationFilePath:t}," and readable.")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"The public key file is not defined in ",{configurationFilePath:t}," or not readable."),n.createElement(Mt,{message:n.createElement(f.x6,null,"Ensure the public key file is defined by the variable passbolt.gpg.serverKey.public in"," ",{configurationFilePath:t})},n.createElement(jt,{className:"baseline svg-icon"})))})()),n.createElement("div",null,(()=>{const t=e.application.configPath.toString();return!0===e.gpg.gpgKeyPrivate&&!0===e.gpg.gpgKeyPrivateReadable&&e.gpg.gpgKeyPrivateBlock?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The private key file is defined in ",{configurationFilePath:t}," and readable.")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"The private key file is not defined in ",{configurationFilePath:t}," or not readable."),n.createElement(Mt,{message:n.createElement(f.x6,null,"Ensure the private key file is defined by the variable passbolt.gpg.serverKey.private in"," ",{configurationFilePath:t})},n.createElement(jt,{className:"baseline svg-icon"})))})()),n.createElement("div",null,u()),n.createElement("div",null,p()),n.createElement("div",null,h()),n.createElement("div",null,!0===e.gpg.canEncrypt?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The public key can be used to encrypt a message")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"The public key cannot be used to encrypt a message"))),n.createElement("div",null,!0===e.gpg.canSign?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The public key can be used to sign a message")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"The public key cannot be used to sign a message"))),n.createElement("div",null,!0===e.gpg.canEncryptSign?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The public and private keys can be used to encrypt and sign a message")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"The public and private keys cannot be used to encrypt and sign a message"))),n.createElement("div",null,!0===e.gpg.canDecryptVerify?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The private key can be used to decrypt and verify a message")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"The private key cannot be used to decrypt and verify a message"))),n.createElement("div",null,!0===e.gpg.canVerify?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The public key can be used to verify a signature")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"The public key cannot be used to verify a signature"))),n.createElement("div",null,!0===e.gpg.isPublicServerKeyGopengpgCompatible?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The server public key format is Gopengpg compatible")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"The server public key format is not Gopengpg compatible"))),n.createElement("div",null,!0===e.gpg.isPrivateServerKeyGopengpgCompatible?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The server private key format is Gopengpg compatible")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"The server private key format is not Gopengpg compatible")))),n.createElement("h4",null,n.createElement(f.x6,null,"Application configuration")),n.createElement("div",{className:"healthcheck-app-section"},n.createElement("div",null,(()=>{if(!0===e.application.latestVersion&&e.application.info.remoteVersion){const t=e.application.info.remoteVersion.toString();return n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"Using latest passbolt version (",{version:t},")"))}if(!1===e.application.latestVersion&&e.application.info.remoteVersion){const t=e.application.info.currentVersion.toString(),a=e.application.info.remoteVersion.toString();return n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"The installation is not up to date. Currently using ",{currentVersion:t}," and it should be"," ",{latestAvailableVersion:a}),n.createElement(Mt,{message:n.createElement("span",null,n.createElement(f.x6,null,"See"," ",n.createElement("a",{href:"https://www.passbolt.com/docs/hosting/update",target:"_blank",rel:"noopener noreferrer"},"this guide")))},n.createElement(jt,{className:"baseline svg-icon"})))}if(null===e.application.latestVersion&&"undefined"===e.application.info.remoteVersion)return n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"It seems that the server is not able to reach internet."),n.createElement(Mt,{message:n.createElement("span",null,n.createElement(f.x6,null,"To confirm that you are running the latest version, check"," ",n.createElement("a",{href:"https://www.passbolt.com/changelog/api-bext",target:"_blank",rel:"noopener noreferrer"},"all the releases notes")))},n.createElement(jt,{className:"baseline svg-icon"})))})()),n.createElement("div",null,(()=>{if(!0===e.application.sslForce)return n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"Passbolt is configured to force SSL use"));{const t=e.application.configPath.toString();return n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"Passbolt is not configured to force SSL use"),n.createElement(Mt,{message:n.createElement(f.x6,null,"Set passbolt.ssl.force to true in ",{configurationFilePath:t})},n.createElement(jt,{className:"baseline svg-icon"})))}})()),n.createElement("div",null,(()=>{if(!0===e.application.sslFullBaseUrl)return n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"App.fullBaseUrl is set to HTTPS"));{const t=e.application.configPath.toString();return n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"App.fullBaseUrl is not set to HTTPS"),n.createElement(Mt,{message:n.createElement(f.x6,null,"Check App.fullBaseUrl url scheme in ",{configurationFilePath:t})},n.createElement(jt,{className:"baseline svg-icon"})))}})()),n.createElement("div",null,(()=>{if(!0===e.application.seleniumDisabled)return n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"Selenium API endpoints are disabled"));{const t=e.application.configPath.toString();return n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"Selenium API endpoints are active. This setting should be used for testing only"),n.createElement(Mt,{message:n.createElement(f.x6,null,"Set passbolt.selenium.active to false in ",{configurationFilePath:t})},n.createElement(jt,{className:"baseline svg-icon"})))}})()),n.createElement("div",null,(()=>{if(!0===e.application.robotsIndexDisabled)return n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"Search engine robots are told not to index content"));{const t=e.application.configPath.toString();return n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"Search engine robots are not told not to index content"),n.createElement(Mt,{message:n.createElement(f.x6,null,"Set passbolt.meta.robots to false in ",{configurationFilePath:t})},n.createElement(jt,{className:"baseline svg-icon"})))}})()),n.createElement("div",null,g()),n.createElement("div",null,(()=>{if(null===e.application.registrationClosed.selfRegistrationProvider)return n.createElement("span",{className:"healthcheck-info"},n.createElement(Cu,null),n.createElement(f.x6,null,"Registration is closed, only administrators can add users"));{const t=e.application.registrationClosed.selfRegistrationProvider.toString();return n.createElement("span",{className:"healthcheck-info"},n.createElement(Cu,null),n.createElement(f.x6,null,"The Self Registration provider is: ",{selfRegistrationProvider:t}))}})()),n.createElement("div",null,y()),n.createElement("div",null,b()),n.createElement("div",null,(()=>{if(!0===e.application.jsProd)return n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"Serving the compiled version of the javascript app"));{const t=e.application.configPath.toString();return n.createElement("span",{className:"healthcheck-warning"},n.createElement(Au,null),n.createElement(f.x6,null,"Using non-compiled Javascript. Passbolt will be slower"),n.createElement(Mt,{message:n.createElement(f.x6,null,"Set passbolt.js.build in ",{configurationFilePath:t})},n.createElement(jt,{className:"baseline svg-icon"})))}})()),n.createElement("div",null,!0===e.application.emailNotificationEnabled?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"All email notifications will be sent")):n.createElement("span",{className:"healthcheck-warning"},n.createElement(Au,null),n.createElement(f.x6,null,"Some email notifications are disabled by the administrators")))),n.createElement("h4",null,n.createElement(f.x6,null,"SMTP Settings")),n.createElement("div",{className:"healthcheck-smtp-section"},n.createElement("div",null,!0===e.smtpSettings.isEnabled?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The SMTP Settings plugin is enabled")):n.createElement("span",{className:"healthcheck-warning"},n.createElement(Au,null),n.createElement(f.x6,null,"The SMTP Settings plugin is disabled"))),n.createElement("div",null,(()=>{if(!1===e.smtpSettings.errorMessage)return n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"SMTP Settings coherent. You may send a test email to validate them"));{const t=e.smtpSettings.errorMessage.toString();return n.createElement("span",{className:"healthcheck-fail"},n.createElement(_u,null),n.createElement(f.x6,null,"SMTP Settings errors: ",{errorMessage:t}))}})()),n.createElement("div",null,E()),n.createElement("div",null,v())),this.shouldDisplayUserDirectory&&n.createElement(n.Fragment,null,n.createElement("h4",null,n.createElement(f.x6,null,"Directory Sync")),n.createElement("div",{className:"healthcheck-directorySync-section"},n.createElement("div",null,w()))),this.shouldDisplaySSO&&n.createElement(n.Fragment,null,n.createElement("h4",null,n.createElement(f.x6,null,"SSO")),n.createElement("div",{className:"healthcheck-sso-section"},n.createElement("div",null,k()))),this.shouldDisplayMetadata&&n.createElement(n.Fragment,null,n.createElement("h4",null,n.createElement(f.x6,null,"Metadata")),n.createElement("div",{className:"healthcheck-metadata-section"},!0===e.metadata.isServerMetadataKeyAccessInZeroKnowledgeMode?n.createElement("span",{className:"healthcheck-success"},n.createElement(vu,null),n.createElement(f.x6,null,"The server does not have access to the server metadata private key in Zero-knowledge mode.")):n.createElement(n.Fragment,null,n.createElement("div",null,_()),n.createElement("div",null,x()),n.createElement("div",null,S()),n.createElement("div",null,C()))))))():n.createElement("div",null,n.createElement(f.x6,null,"The health check API endpoint has been disabled in the server configuration."))),Xa(n.createElement(n.Fragment,null,n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"What is this page?")),n.createElement("p",null,n.createElement(f.x6,null,"This page is available to help administrators diagnose if something is wrong with a passbolt installation and help keeping it secure.")),n.createElement("p",null,n.createElement(f.x6,null,"The color is really important here so it's easier for you to spot what's not running as expected")),n.createElement("div",{className:"healthcheck-color-legends"},n.createElement("div",{className:"healthcheck-success"},n.createElement(vu,null)," ",n.createElement(f.x6,null,"Everything is running as expected.")),n.createElement("div",{className:"healthcheck-warning"},n.createElement(Au,null)," ",n.createElement(f.x6,null,"Something inside your configuration is not what we recommend, but you can skip it if it has been done on purpose.")),n.createElement("div",{className:"healthcheck-fail"},n.createElement(_u,null)," ",n.createElement(f.x6,null,"There is an error with the current configuration, you might want to resolve it.")),n.createElement("div",{className:"healthcheck-info"},n.createElement(Cu,null)," ",n.createElement(f.x6,null,"This is just an information shared, no action is required.")))),n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"Something wrong?")),n.createElement("p",null,n.createElement(f.x6,null,"Hang in there! Depending your installation, you might need to check the documentation in order to run the healthcheck from the CLI")),n.createElement("a",{className:"button",href:"https://www.passbolt.com/docs/admin/server-maintenance/passbolt-api-status/",target:"_blank",rel:"noopener noreferrer"},n.createElement(ps,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation"))))),document.getElementById("administration-help-panel"))))}}Iu.propTypes={context:i().object,adminHealthcheckContext:i().any,children:i().any,administrationWorkspaceContext:i().object,t:i().func};const Ru=N(Ne(mu((0,f.CI)("common")(Iu)))),Pu="v4",Du="v5";class Ou extends he{static getSchema(){return{type:"object",required:["default_resource_types","default_folder_type","default_tag_type","default_comment_type","allow_creation_of_v5_resources","allow_creation_of_v5_folders","allow_creation_of_v5_tags","allow_creation_of_v5_comments","allow_creation_of_v4_resources","allow_creation_of_v4_folders","allow_creation_of_v4_tags","allow_creation_of_v4_comments","allow_v4_v5_upgrade","allow_v5_v4_downgrade"],properties:{default_resource_types:{type:"string",enum:[Pu,Du]},default_folder_type:{type:"string",enum:[Pu,Du]},default_tag_type:{type:"string",enum:[Pu,Du]},default_comment_type:{type:"string",enum:[Pu,Du]},allow_creation_of_v5_resources:{type:"boolean"},allow_creation_of_v5_folders:{type:"boolean"},allow_creation_of_v5_tags:{type:"boolean"},allow_creation_of_v5_comments:{type:"boolean"},allow_creation_of_v4_resources:{type:"boolean"},allow_creation_of_v4_folders:{type:"boolean"},allow_creation_of_v4_tags:{type:"boolean"},allow_creation_of_v4_comments:{type:"boolean"},allow_v4_v5_upgrade:{type:"boolean"},allow_v5_v4_downgrade:{type:"boolean"}}}}static createFromV4Default(){return new Ou({default_resource_types:Pu,default_folder_type:Pu,default_tag_type:Pu,default_comment_type:Pu,allow_creation_of_v5_resources:!1,allow_creation_of_v5_folders:!1,allow_creation_of_v5_tags:!1,allow_creation_of_v5_comments:!1,allow_creation_of_v4_resources:!0,allow_creation_of_v4_folders:!0,allow_creation_of_v4_tags:!0,allow_creation_of_v4_comments:!0,allow_v4_v5_upgrade:!1,allow_v5_v4_downgrade:!1})}static createFromDefault(e={}){return new Ou({default_resource_types:Pu,default_folder_type:Pu,default_tag_type:Pu,default_comment_type:Pu,allow_creation_of_v5_resources:!1,allow_creation_of_v5_folders:!1,allow_creation_of_v5_tags:!1,allow_creation_of_v5_comments:!1,allow_creation_of_v4_resources:!0,allow_creation_of_v4_folders:!0,allow_creation_of_v4_tags:!0,allow_creation_of_v4_comments:!0,allow_v4_v5_upgrade:!1,allow_v5_v4_downgrade:!1,...e})}static createFromV5Default(e={}){return new Ou({default_resource_types:Du,default_folder_type:Pu,default_tag_type:Pu,default_comment_type:Pu,allow_creation_of_v5_resources:!0,allow_creation_of_v5_folders:!1,allow_creation_of_v5_tags:!1,allow_creation_of_v5_comments:!1,allow_creation_of_v4_resources:!1,allow_creation_of_v4_folders:!0,allow_creation_of_v4_tags:!0,allow_creation_of_v4_comments:!0,allow_v4_v5_upgrade:!1,allow_v5_v4_downgrade:!1,...e})}validateBuildRules(){let e;if(this.isDefaultResourceTypeV4&&!this.allowCreationOfV4Resources){e=e||new X;const t="Allow creation of v4 resources should be true when default resources is v4";e.addError("allow_creation_of_v4_resources","is_default",t),e.addError("default_resource_types","allow_create_v4",t)}else if(this.isDefaultResourceTypeV5&&!this.allowCreationOfV5Resources){e=e||new X;const t="Allow creation of v5 resources should be true when default resources is v5";e.addError("allow_creation_of_v5_resources","is_default",t),e.addError("default_resource_types","allow_create_v5",t)}if(e)throw e}get defaultResourceTypes(){return this._props.default_resource_types}get allowCreationOfV5Resources(){return this._props.allow_creation_of_v5_resources}get allowCreationOfV4Resources(){return this._props.allow_creation_of_v4_resources}get allowCreationOfV5Folders(){return this._props.allow_creation_of_v5_folders}get allowCreationOfV4Folders(){return this._props.allow_creation_of_v4_folders}get allowCreationOfV5Tags(){return this._props.allow_creation_of_v5_tags}get allowCreationOfV4Tags(){return this._props.allow_creation_of_v4_tags}get allowCreationOfV5Comments(){return this._props.allow_creation_of_v5_comments}get allowCreationOfV4Comments(){return this._props.allow_creation_of_v4_comments}get isDefaultResourceTypeV5(){return this._props.default_resource_types===Du}get isDefaultResourceTypeV4(){return this._props.default_resource_types===Pu}get allowV5V4Downgrade(){return this._props.allow_v5_v4_downgrade}get allowV4V5Upgrade(){return this._props.allow_v4_v5_upgrade}}const Mu=Ou,Uu="keepass-icon-set",Fu="passbolt-icon-set",ju="password-string",Lu="password-and-description",qu="password-description-totp",zu="totp",Ku="v5-default",Vu="v5-password-string",Gu="v5-default-with-totp",Bu="v5-totp-standalone",Wu="v5-custom-fields",Hu="v5-note",$u="v5-pin-code",Yu={resource:{type:"object",required:["name"],properties:{name:{type:"string",maxLength:255},username:{type:"string",maxLength:255,nullable:!0},description:{maxLength:1e4,nullable:!0,type:"string"},uri:{type:"string",maxLength:1024,nullable:!0}}},secret:{type:"string",maxLength:4096}},Zu={resource:{type:"object",required:["name"],properties:{name:{type:"string",maxLength:255},username:{type:"string",maxLength:255,nullable:!0},uri:{type:"string",maxLength:1024,nullable:!0}}},secret:{type:"object",required:["password"],properties:{password:{type:"string",maxLength:4096},description:{type:"string",maxLength:1e4,nullable:!0}}}},Ju={resource:{type:"object",required:["name"],properties:{name:{type:"string",maxLength:255},uri:{type:"string",maxLength:1024,nullable:!0}}},secret:{type:"object",required:["totp"],properties:{totp:{type:"object",required:["secret_key","digits","algorithm"],properties:{algorithm:{type:"string",minLength:4,maxLength:6},secret_key:{type:"string",maxLength:1024},digits:{type:"number",minimum:6,maximum:8},period:{type:"number"}}}}}},Xu={resource:{type:"object",required:["name"],properties:{name:{type:"string",maxLength:255},username:{type:"string",maxLength:255,nullable:!0},uri:{type:"string",maxLength:1024,nullable:!0}}},secret:{type:"object",required:["password","totp"],properties:{password:{type:"string",maxLength:4096},description:{type:"string",maxLength:1e4,nullable:!0},totp:Ju.secret.properties.totp}}},Qu={resource:{type:"object",required:["name"],properties:{name:{type:"string",maxLength:255},username:{type:"string",maxLength:255,nullable:!0},uris:{type:"array",items:{type:"string",maxLength:1024,nullable:!0},maxItems:32},description:{type:"string",maxLength:1e4,nullable:!0},icon:{type:"object",required:[],properties:{type:{type:"string",enum:[Uu,Fu]},value:{type:"number",minimum:0,nullable:!0},background_color:{type:"string",nullable:!0}}},custom_fields:{type:"array",maxItems:128,items:{type:"object",required:["id","type"],properties:{id:{type:"string",format:"uuid"},type:{type:"string",enum:["text","password","boolean","number","uri"]},metadata_key:{type:"string",maxLength:255,nullable:!0},metadata_value:{anyOf:[{type:"string",maxLength:2e4},{type:"number"},{type:"boolean"}],nullable:!0}}}}}},secret:{type:"object",required:["custom_fields","object_type"],properties:{object_type:{type:"string",enum:["PASSBOLT_SECRET_DATA"]},custom_fields:{type:"array",maxItems:128,items:{type:"object",required:["id","type"],properties:{id:{type:"string",format:"uuid"},type:{type:"string",enum:["text","password","boolean","number","uri"]},secret_key:{type:"string",maxLength:255,nullable:!0},secret_value:{anyOf:[{type:"string",maxLength:2e4},{type:"number"},{type:"boolean"}],nullable:!0}}}}}}},ep={resource:{type:"object",required:["name"],properties:{name:{type:"string",maxLength:255},username:{type:"string",maxLength:255,nullable:!0},uris:{type:"array",items:{type:"string",maxLength:1024,nullable:!0},maxItems:32},description:{type:"string",maxLength:1e4,nullable:!0},icon:{type:"object",required:[],properties:{type:{type:"string",enum:[Uu,Fu]},value:{type:"number",minimum:0,nullable:!0},background_color:{type:"string",nullable:!0}}},custom_fields:Qu.resource.properties.custom_fields}},secret:{type:"object",required:["password"],properties:{object_type:{type:"string",enum:["PASSBOLT_SECRET_DATA"]},password:{type:"string",maxLength:4096,nullable:!0},description:{type:"string",maxLength:5e4,nullable:!0},custom_fields:Qu.secret.properties.custom_fields}}},tp={resource:{type:"object",required:["name"],properties:{name:{type:"string",maxLength:255},username:{type:"string",maxLength:255,nullable:!0},uris:{type:"array",items:{type:"string",maxLength:1024,nullable:!0},maxItems:32},description:{type:"string",maxLength:1e4,nullable:!0},icon:{type:"object",required:[],properties:{type:{type:"string",enum:[Uu,Fu]},value:{type:"number",minimum:0,nullable:!0},background_color:{type:"string",nullable:!0}}}}},secret:{type:"string",maxLength:4096}},ap={resource:{type:"object",required:["name"],properties:{name:{type:"string",maxLength:255},username:{type:"string",maxLength:255,nullable:!0},uris:{type:"array",items:{type:"string",maxLength:1024,nullable:!0},maxItems:32},description:{type:"string",maxLength:1e4,nullable:!0},icon:{type:"object",required:[],properties:{type:{type:"string",enum:[Uu,Fu]},value:{type:"number",minimum:0,nullable:!0},background_color:{type:"string",nullable:!0}}},custom_fields:Qu.resource.properties.custom_fields}},secret:{type:"object",required:["password","totp"],properties:{object_type:{type:"string",enum:["PASSBOLT_SECRET_DATA"]},password:{type:"string",maxLength:4096,nullable:!0},description:{type:"string",maxLength:5e4,nullable:!0},totp:Ju.secret.properties.totp,custom_fields:Qu.secret.properties.custom_fields}}},np={resource:{type:"object",required:["name"],properties:{name:{type:"string",maxLength:255},uris:{type:"array",items:{type:"string",maxLength:1024,nullable:!0},maxItems:32},description:{type:"string",maxLength:1e4,nullable:!0},icon:{type:"object",required:[],properties:{type:{type:"string",enum:[Uu,Fu]},value:{type:"number",minimum:0,nullable:!0},background_color:{type:"string",nullable:!0}}}}},secret:{type:"object",required:["totp"],properties:{object_type:{type:"string",enum:["PASSBOLT_SECRET_DATA"]},totp:{type:"object",required:["secret_key","digits","algorithm"],properties:{algorithm:{type:"string",minLength:4,maxLength:6},secret_key:{type:"string",maxLength:1024},digits:{type:"number",minimum:6,maximum:8},period:{type:"number"}}}}}},sp={resource:{type:"object",required:["name"],properties:{name:{type:"string",maxLength:255},uris:{type:"array",items:{type:"string",maxLength:1024,nullable:!0},maxItems:32},description:{type:"string",maxLength:1e4,nullable:!0},icon:{type:"object",required:[],properties:{type:{type:"string",enum:[Uu,Fu]},value:{type:"number",minimum:0,nullable:!0},background_color:{type:"string",nullable:!0}}}}},secret:{type:"object",required:["description","object_type"],properties:{object_type:{type:"string",enum:["PASSBOLT_SECRET_DATA"]},description:{type:"string",maxLength:5e4}}}},ip={resource:{type:"object",required:["name"],properties:{name:{type:"string",maxLength:255},description:{type:"string",maxLength:1e4,nullable:!0},icon:{type:"object",required:[],properties:{type:{type:"string",enum:[Uu,Fu]},value:{type:"number",minimum:0,nullable:!0},background_color:{type:"string",nullable:!0}}}}},secret:{type:"object",required:["pin_code","object_type"],properties:{object_type:{type:"string",enum:["PASSBOLT_SECRET_DATA"]},pin_code:{type:"string",minLength:4,maxLength:12,pattern:"^\\d+$"},description:{type:"string",maxLength:5e4,nullable:!0}}}},rp={[ju]:Vu,[Lu]:Ku,[qu]:Gu,[zu]:Bu},op=new class{get SCHEMAS(){return{[ju]:Yu,[Lu]:Zu,[qu]:Xu,[zu]:Ju,[Ku]:ep,[Vu]:tp,[Gu]:ap,[Bu]:np,[Wu]:Qu,[Hu]:sp,[$u]:ip}}},lp=[ju,Lu,qu,Ku,Gu,Vu],cp=[qu,zu,Gu,Bu],mp=[zu,Bu],dp=[ju,Vu],up=[Lu,qu,Ku,Gu,Hu,$u],pp=[ju,Ku,Gu,Vu,Bu,Wu,Hu,$u],hp=[Ku,Vu,Gu,Bu,Wu,Hu],gp=[Ku,Gu,Wu];class yp extends he{marshall(){if("string"!=typeof this._props.slug||!(this._props.slug in op.SCHEMAS))return void delete this._props.definition;const e=op.SCHEMAS[this._props.slug],t=Object.assign({},e);this._props.definition=t}static getSchema(){return{type:"object",required:["id","name","slug","definition"],properties:{id:{type:"string",format:"uuid"},name:{type:"string",minLength:1,maxLength:255},slug:{type:"string",minLength:1,maxLength:64},definition:{type:"object"},description:{type:"string",maxLength:255,nullable:!0},icon:{type:"object",required:[],properties:{type:{type:"string",enum:[Uu,Fu]},value:{type:"number",minimum:0,nullable:!0},background_color:{type:"string",pattern:/^#(?:[0-9A-F]{6}|[0-9A-F]{8})$/i,nullable:!0}}},resources_count:{type:"integer"},created:{type:"string",format:"date-time"},modified:{type:"string",format:"date-time"},deleted:{type:"string",format:"date-time",nullable:!0}}}}get id(){return this._props.id}get slug(){return this._props.slug}get definition(){return this._props.definition}get resourcesCount(){return this._props.resources_count||null}set deleted(e){const t=yp.getSchema().properties.deleted;t?.nullable&&null===e||ae.validateProp("deleted",e,t),this._props.deleted=e}hasTotp(){return cp.includes(this.slug)}hasPassword(){return lp.includes(this.slug)}hasCustomFields(){return gp.includes(this.slug)}hasPinCode(){return $u===this.slug}isStandalonePinCode(){return this.hasPinCode()}isStandaloneTotp(){return mp.includes(this.slug)}isPasswordString(){return dp.includes(this.slug)}hasSecretDescription(){return up.includes(this.slug)}hasMetadataDescription(){return pp.includes(this.slug)}hasMetadataUris(){return hp.includes(this.slug)}get version(){return this.slug.startsWith("v5")?Du:Pu}isV5(){return this.version===Du}isV4(){return this.version===Pu}isDeleted(){return void 0!==this._props.deleted&&null!==this._props.deleted}}const bp=yp,fp=[ju,Lu,qu,zu,Ku,Gu,Vu,Bu,Wu,Hu,$u],Ep=class extends Bc{get entityClass(){return bp}constructor(e=[],t={}){super(e,t)}static getSchema(){return{type:"array",items:bp.getSchema()}}validateBuildRules(e,t={}){this.assertNotExist("id",e._props.id,{haystackSet:t?.uniqueIdsSetCache}),this.assertNotExist("slug",e._props.slug,{haystackSet:t?.uniqueSlugsSetCache})}isResourceTypeIdPresent(e){return this._items.some(t=>t.id===e)}filterByPasswordResourceTypes(){this.filterByPropertyValueIn("slug",lp)}filterByTOTPResourceTypes(){this.filterByPropertyValueIn("slug",cp)}filterByResourceTypeVersion(e){this.filterByCallback(t=>t.version===e)}getFirstById(e){return this.getFirst("id",e)}getFirstBySlug(e){return this.getFirst("slug",e)}hasOneWithSlug(e){return Boolean(this.getFirstBySlug(e))}hasSomePasswordResourceTypes(e=Pu){return this.items.some(t=>t.hasPassword()&&t.version===e)}hasSomeTotpResourceTypes(e=Pu){return this.items.some(t=>t.hasTotp()&&t.version===e)}hasSomeCustomFieldsResourceTypes(e=Pu){return this.items.some(t=>t.hasCustomFields()&&t.version===e)}hasSomeNoteResourceTypes(e=Pu){return this.items.some(t=>t.hasSecretDescription()&&t.version===e)}hasSomePinCodeResourceTypes(e=Pu){return this.items.some(t=>t.hasPinCode()&&t.version===e)}hasSomeMetadataDescriptionResourceTypes(e=Pu){return this.items.some(t=>t.hasMetadataDescription()&&t.version===e)}hasSomeOfVersion(e=Pu){return this.items.some(t=>t.version===e)}getResourceTypeMatchingResource(e,t=Pu){if((0,ie.A)(t),null==e?.secret||"object"!=typeof e.secret)throw new TypeError("The resource DTO is not an expected object");let a=null,n=null;const s=Object.keys(e.secret);for(const e of this.items){if(e.version!==t||e.isPasswordString())continue;const i=Object.keys(e.definition.secret.properties);if(s.every(e=>i.includes(e))){const t=i.filter(e=>!s.includes(e)).length;if(0===t)return e;(!n||n>t)&&(n=t,a=e)}}return a}pushMany(e,t={},a={}){const n=new Set(this.extract("id")),s=new Set(this.extract("slug"));a={onItemPushed:e=>{n.add(e.id),s.add(e.slug)},validateBuildRules:{...a?.validateBuildRules,uniqueIdsSetCache:n,uniqueSlugsSetCache:s},...a},super.pushMany(e,t,a)}push(e,t={},a={}){fp.includes(e?.slug)&&super.push(e,t,a)}},vp=class extends he{static getSchema(){return{type:"object",required:["user_id","armored_key"],properties:{id:{type:"string",format:"uuid"},user_id:{type:"string",format:"uuid"},fingerprint:{type:"string",minLength:40,maxLength:40},armored_key:{type:"string"},deleted:{type:"boolean"},type:{type:"string",nullable:!0},uid:{type:"string"},bits:{type:"integer",nullable:!0},key_id:{type:"string",minLength:8,maxLength:16},key_created:{type:"string",format:"date-time"},expires:{type:"string",format:"date-time",nullable:!0},created:{type:"string",format:"date-time"},modified:{type:"string",format:"date-time"}}}}get id(){return this._props.id||null}get userId(){return this._props.user_id}get armoredKey(){return this._props.armored_key}get fingerprint(){return this._props.fingerprint}get created(){return this._props.created||null}get modified(){return this._props.modified||null}get isDeleted(){return void 0===this._props.deleted?null:this._props.deleted}static get ENTITY_NAME(){return"gpgkey"}};class wp extends he{static getSchema(){return{type:"object",required:[wp.AVATAR_URL_SIZE_MEDIUM,wp.AVATAR_URL_SIZE_SMALL],properties:{medium:{type:"string"},small:{type:"string"}}}}get medium(){return this._props.medium}get small(){return this._props.small}static get ENTITY_NAME(){return"AvatarUrl"}static get AVATAR_URL_SIZE_MEDIUM(){return"medium"}static get AVATAR_URL_SIZE_SMALL(){return"small"}}const kp=wp,_p=class extends he{constructor(e={},t={}){super(e,t),this._props.url&&(this._url=new kp(this._props.url,{...t,clone:!1}),delete this._props.url)}static getSchema(){return{type:"object",required:["url"],properties:{id:{type:"string",format:"uuid"},created:{type:"string",format:"date-time"},modified:{type:"string",format:"date-time"},url:kp.getSchema()}}}get id(){return this._props.id||null}get urlMedium(){return this._url.medium}get urlSmall(){return this._url.small}get created(){return this._props.created||null}get modified(){return this._props.modified||null}toDto(e){const t=super.toDto(e);return t.url=this._url.toDto(),t}static get ENTITY_NAME(){return"Avatar"}static get AVATAR_URL_SIZE_MEDIUM(){return"medium"}static get AVATAR_URL_SIZE_SMALL(){return"small"}};class xp extends he{constructor(e={},t={}){super(e,t),this._props.avatar&&(this._avatar=new _p(this._props.avatar,{...t,clone:!1}),delete this._props.avatar)}static getSchema(){return{type:"object",required:["first_name","last_name"],properties:{id:{type:"string",format:"uuid"},user_id:{type:"string",format:"uuid"},first_name:{type:"string",minLength:1,maxLength:255},last_name:{type:"string",minLength:1,maxLength:255},created:{type:"string",format:"date-time"},modified:{type:"string",format:"date-time"},avatar:_p.getSchema()}}}toDto(e){const t=Object.assign({},this._props);return this.avatar&&e&&e.avatar&&(t.avatar=this.avatar.toDto()),t}toJSON(){return this.toDto(xp.ALL_CONTAIN_OPTIONS)}static get ENTITY_NAME(){return"Profile"}static get ALL_CONTAIN_OPTIONS(){return{avatar:!0}}get id(){return this._props.id||null}get name(){return`${this._props.first_name} ${this._props.last_name}`}get firstName(){return this._props.first_name}get lastName(){return this._props.last_name}get userId(){return this._props.user_id||null}get created(){return this._props.created||null}get modified(){return this._props.modified||null}get avatar(){return this._avatar||null}}const Sp=xp,Cp=class extends he{static getSchema(){return{type:"object",required:["user_id","is_admin"],properties:{id:{type:"string",format:"uuid"},user_id:{type:"string",format:"uuid"},group_id:{type:"string",format:"uuid"},is_admin:{type:"boolean"},created:{type:"string",format:"date-time"}}}}toDto(){return Object.assign({},this._props)}get id(){return this._props.id||null}get userId(){return this._props.user_id}get groupId(){return this._props.group_id||null}get isAdmin(){return this._props.is_admin}get created(){return this._props.created||null}set id(e){if(!ee().isUUID(e))throw new TypeError("The group user id should be a valid UUID.");this._props.id=e}static get ENTITY_NAME(){return"GroupUser"}static get ALL_CONTAIN_OPTIONS(){return{}}},Np=class extends Bc{get entityClass(){return Cp}static getSchema(){return{type:"array",items:Cp.getSchema()}}get groupsUsers(){return this._items}static get ENTITY_NAME(){return"GroupsUsers"}getGroupUserByUserId(e){return this.groupsUsers.find(t=>t.userId===e)}getById(e){return this.items.find(t=>t.id===e)}};class Tp extends se{constructor(e,t={}){super(ae.validate(Tp.ENTITY_NAME,e,Tp.getSchema()),t)}static getSchema(){return{type:"object",required:["recipient_foreign_model","recipient_fingerprint","data"],properties:{id:{type:"string",format:"uuid"},private_key_id:{type:"string",format:"uuid"},recipient_foreign_model:{type:"string",enum:[Tp.FOREIGN_MODEL_ORGANIZATION_KEY]},recipient_foreign_key:{type:"string",format:"uuid"},recipient_fingerprint:{type:"string",length:40},data:{type:"string"}}}}toDto(){return Object.assign({},this._props)}toJSON(){return this.toDto()}get id(){return this._props.id||null}get privateKeyId(){return this._props.private_key_id||null}get recipientForeignKey(){return this._props.recipient_foreign_key||null}get data(){return this._props.data}get recipientForeignModel(){return this._props.recipient_foreign_model}get recipientFingerprint(){return this._props.recipient_fingerprint}static get ENTITY_NAME(){return"AccountRecoveryPrivateKeyPassword"}static get FOREIGN_MODEL_ORGANIZATION_KEY(){return"AccountRecoveryOrganizationKey"}}const Ap=Tp;class Ip extends de{constructor(e,t={}){super(ae.validate(Ip.ENTITY_NAME,e,Ip.getSchema()),t),this._props.map(e=>e.id).sort().sort((e,t)=>{if(e===t)throw new ce(0,Ip.RULE_UNIQUE_ID,`AccountRecoveryPrivateKeyPassword id ${e} already exists.`)}),this._props.forEach(e=>{this._items.push(new Ap(e,{...t,clone:!1}))}),this._props=null}static getSchema(){return{type:"array",items:Ap.getSchema()}}get accountRecoveryPrivateKeyPasswords(){return this._items}get ids(){return this._items.map(e=>e.id)}static sanitizeDto(e){return Array.isArray(e)?((e,t)=>{if(!Array.isArray(e))throw new TypeError("deduplicateObjects first parameter should be an array.");if("string"!=typeof t)throw new TypeError("deduplicateObjects second parameter should be a string.");const a=e.filter(e=>Object.prototype.hasOwnProperty.call(e,t)).map(e=>e[t]).reduce((e,t,a)=>(e[t]=Object.prototype.hasOwnProperty.call(e,t)?e[t]:a,e),{});return e.filter((e,n)=>!Object.prototype.hasOwnProperty.call(e,t)||a[e[t]]===n)})(e,"id"):[]}assertUniqueId(e){if(!e.id)return;const t=this.accountRecoveryPrivateKeyPasswords.length;let a=0;for(;at.id===e);this.items.splice(t,1)}removeMany(e){for(const t in e)this.remove(e[t])}filterByForeignModel(e){return this.items.find(t=>t.recipientForeignModel===e)}static get ENTITY_NAME(){return"AccountRecoveryPrivateKeyPassword"}static get RULE_UNIQUE_ID(){return"unique_id"}}const Rp=Ip;class Pp extends se{constructor(e,t={}){if(super(ae.validate(Pp.ENTITY_NAME,e,Pp.getSchema()),t),this._props.account_recovery_private_key_passwords){const e=Rp.sanitizeDto(this._props.account_recovery_private_key_passwords);this._account_recovery_private_key_passwords=new Rp(e,{...t,clone:!1}),delete this._props.account_recovery_private_key_passwords}}static getSchema(){return{type:"object",required:[],properties:{id:{type:"string",format:"uuid"},user_id:{type:"string",format:"uuid"},data:{type:"string"},created:{type:"string",format:"date-time"},modified:{type:"string",format:"date-time"},created_by:{type:"string",format:"uuid"},modified_by:{type:"string",format:"uuid"},account_recovery_private_key_passwords:Rp.getSchema()}}}toDto(e){const t=Object.assign({},this._props);return e?(this._account_recovery_private_key_passwords&&e.account_recovery_private_key_passwords&&(t.account_recovery_private_key_passwords=this._account_recovery_private_key_passwords.toDto()),t):t}toJSON(){return this.toDto(Pp.ALL_CONTAIN_OPTIONS)}get id(){return this._props.id||null}get userId(){return this._props.user_id||null}get data(){return this._props.data||null}get accountRecoveryPrivateKeyPasswords(){return this._account_recovery_private_key_passwords||null}static get ENTITY_NAME(){return"AccountRecoveryPrivateKey"}static get ALL_CONTAIN_OPTIONS(){return{account_recovery_private_key_passwords:!0}}}const Dp=Pp;class Op extends se{constructor(e,t={}){super(ae.validate(Op.ENTITY_NAME,e,Op.getSchema()),t),this._props.account_recovery_private_key&&(this._account_recovery_private_key=new Dp(this._props.account_recovery_private_key,{...t,clone:!1}),delete this._props.account_recovery_private_key)}static getSchema(){return{type:"object",required:["status"],properties:{id:{type:"string",format:"uuid"},user_id:{type:"string",format:"uuid"},status:{type:"string",enum:[Op.STATUS_APPROVED,Op.STATUS_REJECTED]},created:{type:"string",format:"date-time"},modified:{type:"string",format:"date-time"},created_by:{type:"string",format:"uuid"},modified_by:{type:"string",format:"uuid"},account_recovery_private_key:Dp.getSchema()}}}toDto(e){const t=Object.assign({},this._props);return this._account_recovery_private_key&&e?.account_recovery_private_key&&(t.account_recovery_private_key=this._account_recovery_private_key.toDto(Dp.ALL_CONTAIN_OPTIONS)),t}toJSON(){return this.toDto()}get status(){return this._props.status}get isApproved(){return this.status===Op.STATUS_APPROVED}get isRejected(){return this.status===Op.STATUS_REJECTED}get accountRecoveryPrivateKey(){return this._account_recovery_private_key||null}static get ENTITY_NAME(){return"AccountRecoveryUserSetting"}static get ALL_CONTAIN_OPTIONS(){return{account_recovery_private_key:!0}}static get STATUS_APPROVED(){return"approved"}static get STATUS_REJECTED(){return"rejected"}}const Mp=Op;class Up extends se{constructor(e={},t={}){super(ae.validate(Up.ENTITY_NAME,e,Up.getSchema()),t)}static getSchema(){return{type:"object",required:["id","status"],properties:{id:{type:"string",format:"uuid"},status:{type:"string",enum:["pending"]},created:{type:"string",format:"date-time"},modified:{type:"string",format:"date-time"},created_by:{type:"string",format:"uuid"},modified_by:{type:"string",format:"uuid"}}}}get id(){return this._props.id}get status(){return this._props.status}static get ENTITY_NAME(){return"PendingAccountRecoveryRequest"}}const Fp=Up;class jp extends he{constructor(e,t={}){super(e,t),this._props.profile&&(this._profile=new Sp(this._props.profile,{...t,clone:!1}),delete this._props.profile),this._props.role&&(this._role=new ge(this._props.role,{...t,clone:!1}),delete this._props.role),this._props.gpgkey&&(this._gpgkey=new vp(this._props.gpgkey,{...t,clone:!1}),delete this._props.gpgkey),this._props.groups_users&&(this._groups_users=new Np(this._props.groups_users,{...t,clone:!1}),delete this._props.groups_users),this._props.account_recovery_user_setting&&(this._account_recovery_user_setting=new Mp(this._props.account_recovery_user_setting,{...t,clone:!1}),delete this._props.account_recovery_user_setting),this._props.pending_account_recovery_request&&(this._pending_account_recovery_request=new Fp(this._props.pending_account_recovery_request,{...t,clone:!1}),delete this._props.pending_account_recovery_request)}marshall(){""===this._props.last_logged_in&&(this._props.last_logged_in=null),super.marshall()}static getSchema(){return{type:"object",required:["username"],properties:{id:{type:"string",format:"uuid"},role_id:{type:"string",format:"uuid"},username:{type:"string"},active:{type:"boolean"},deleted:{type:"boolean"},disabled:{type:"string",format:"date-time",nullable:!0},missing_metadata_key_ids:{type:"array",items:{type:"string",format:"uuid"}},created:{type:"string",format:"date-time"},modified:{type:"string",format:"date-time"},last_logged_in:{type:"string",format:"date-time",nullable:!0},is_mfa_enabled:{type:"boolean",nullable:!0},locale:{type:"string",pattern:/^[a-z]{2}-[A-Z]{2}$/,nullable:!0},role:ge.getSchema(),profile:Sp.getSchema(),gpgkey:vp.getSchema(),groups_users:Np.getSchema(),account_recovery_user_setting:Mp.getSchema(),pending_account_recovery_request:Fp.getSchema()}}}toDto(e){const t=Object.assign({},this._props);return e?(this.role&&e.role&&(t.role=this.role.toDto()),this.profile&&e.profile&&(!0===e.profile?t.profile=this.profile.toDto():t.profile=this.profile.toDto(e.profile)),this.gpgkey&&e.gpgkey&&(t.gpgkey=this.gpgkey.toDto()),this.groupsUsers&&e.groups_users&&(t.groups_users=this.groupsUsers.toDto()),this.accountRecoveryUserSetting&&e.account_recovery_user_setting&&(t.account_recovery_user_setting=this.accountRecoveryUserSetting.toDto()),this.pendingAccountRecoveryUserRequest&&e.pending_account_recovery_request&&(t.pending_account_recovery_request=this.pendingAccountRecoveryUserRequest.toDto()),t):t}toJSON(){return this.toDto(jp.ALL_CONTAIN_OPTIONS)}get id(){return this._props.id||null}get roleId(){return this._props.role_id||null}get username(){return this._props.username}get isActive(){return void 0===this._props.active?null:this._props.active}get isDeleted(){return void 0===this._props.deleted?null:this._props.deleted}get missingMetadataKeysIds(){return this._props.missing_metadata_key_ids||[]}get created(){return this._props.created||null}get modified(){return this._props.modified||null}get lastLoggedIn(){return this._props.last_logged_in||null}get isMfaEnabled(){return void 0===this._props.is_mfa_enabled?null:this._props.is_mfa_enabled}get locale(){return this._props.locale||null}set locale(e){this._props.locale=e}getUserFormattedName(e=e=>e,t={withUsername:!1}){const a=this.profile;return a&&(Boolean(a.firstName)||Boolean(a.lastName))?t.withUsername?`${a.firstName} ${a.lastName} (${this.username})`:`${a.firstName} ${a.lastName}`:e("Unknown user")}get status(){return this.isDeleted?"deleted":Boolean(this._props.disabled&&new Date(this._props.disabled)<=new Date)?"suspended":"active"}set missingMetadataKeysIds(e){this._props.missing_metadata_key_ids=e}static get ALL_CONTAIN_OPTIONS(){return{profile:Sp.ALL_CONTAIN_OPTIONS,role:!0,gpgkey:!0,groups_users:!0,account_recovery_user_setting:!0,pending_account_recovery_request:!0}}static get ENTITY_NAME(){return"User"}get profile(){return this._profile||null}get role(){return this._role||null}get gpgkey(){return this._gpgkey||null}get groupsUsers(){return this._groups_users||null}get accountRecoveryUserSetting(){return this._account_recovery_user_setting||null}get pendingAccountRecoveryUserRequest(){return this._pending_account_recovery_request||null}}const Lp=jp,qp=class extends he{static getSchema(){return{type:"object",required:["object_type","domain","fingerprint","armored_key","passphrase"],properties:{object_type:{type:"string",enum:["PASSBOLT_METADATA_PRIVATE_KEY"]},domain:{type:"string",maxLength:1024},fingerprint:{type:"string",pattern:/^[a-f0-9]{40}$/im},armored_key:{type:"string",maxLength:1e4,pattern:/^-----BEGIN PGP PRIVATE KEY BLOCK-----\r?\n((?:[!-9;-~]+: [^\r\n]*\r?\n)*\r?\n)((?:[A-Za-z/-9+]{1,76}\r?\n)*)([A-Za-z/-9+]{1,76}={0,2}\r?\n)(=[A-Za-z/-9+]{4}\r?\n)-----END PGP PRIVATE KEY BLOCK-----\s*$/},passphrase:{type:"string",maxLength:1024}}}}get armoredKey(){return this._props.armored_key}get fingerprint(){return this._props.fingerprint}};class zp extends he{constructor(e,t={}){super(e,t),this._props.data&&"string"!=typeof this._props.data&&(this._data=new qp(this._props.data,{...t,clone:!1}),delete this._props.data)}static getSchema(){return{type:"object",required:["user_id","data"],properties:{id:{type:"string",format:"uuid",nullable:!0},metadata_key_id:{type:"string",format:"uuid",nullable:!0},user_id:{type:"string",format:"uuid",nullable:!0},data_signed_by_current_user:{type:"string",format:"date-time",nullable:!0},data:{anyOf:[{type:"string",maxLength:1e4,pattern:/^-----BEGIN PGP MESSAGE-----\r?\n((?:[!-9;-~]+: [^\r\n]*\r?\n)*\r?\n)((?:[A-Za-z/-9+]{1,76}\r?\n)*)([A-Za-z/-9+]{1,76}={0,2}\r?\n)(=[A-Za-z/-9+]{4}\r?\n)-----END PGP MESSAGE-----\s*$/},{type:"object"}]},created:{type:"string",format:"date-time"},created_by:{type:"string",format:"uuid",nullable:!0},modified:{type:"string",format:"date-time"},modified_by:{type:"string",format:"uuid",nullable:!0}}}}validateBuildRules(){if(Boolean(this._props.data)&&Boolean(this._data)){const e=new X,t="The property data and _data cannot be set at the same time";throw e.addError("data","only-one-defined",t),e}}toDto(e){const t=Object.assign({},this._props),a=this.data;return t.data=a instanceof qp?a.toDto():a,e?(this._creator&&e.creator&&(t.creator=this._creator.toDto(Lp.ALL_CONTAIN_OPTIONS)),t):t}toDataDto(){return{data:this.toDto().data}}toContentCodeConfirmTrustRequestDto(){const e=this.toDto();return delete e.data,e}toJSON(){return this.toDto(Lp.ALL_CONTAIN_OPTIONS)}cloneForSharing(e){const t={user_id:e,metadata_key_id:this.metadataKeyId,data:this.data};return new zp(t)}marshall(){}get data(){return this.isDecrypted?this._data:this._props.data}get id(){return this._props.id||null}get metadataKeyId(){return this._props.metadata_key_id||null}get isDecrypted(){return Boolean(this._data)}get userId(){return this._props.user_id}get dataSignedByCurrentUser(){return this._props.data_signed_by_current_user||null}get modifiedBy(){return this._props.modified_by}get modified(){return this._props.modified}set modified(e){this._props.modified=e}set modifiedBy(e){this._props.modifiedBy=e}set data(e){ae.validateProp("data",e,this.cachedSchema.properties.data),"string"==typeof e?(this._props.data=e,delete this._data):(this._data=new qp(e.toDto(),{clone:!0,validate:!1}),delete this._props.data)}set dataSignedByCurrentUser(e){ae.validateProp("data_signed_by_current_user",e,this.cachedSchema.properties.data_signed_by_current_user),this._props.data_signed_by_current_user=e}static get ALL_CONTAIN_OPTIONS(){return{creator:!0}}}const Kp=zp,Vp=class extends Bc{get entityClass(){return Kp}constructor(e=[],t={}){super(e,t)}static getSchema(){return{type:"array",items:Kp.getSchema()}}validateBuildRules(e,t={}){this.assertNotExist("id",e._props.id,{haystackSet:t?.uniqueIdsSetCache}),this.assertNotExist("user_id",e._props.user_id,{haystackSet:t?.uniqueUserIdsSetCache}),this.assertSameMetadataKeyId(e)}assertSameMetadataKeyId(e){if(!e.metadataKeyId)return;const t=this._items.find(e=>Boolean(e.metadataKeyId))?.metadataKeyId;if(!t)return;if(e.metadataKeyId===t)return;const a=new X;throw a.addError("metadata_key_id","same_metadata_key","The collection should not contain different metadata key ID."),a}hasDecryptedPrivateKeys(){return this._items.some(e=>e.isDecrypted)}hasEncryptedPrivateKeys(){return this._items.some(e=>!e.isDecrypted)}pushMany(e,t={},a={}){const n=new Set(this.extract("id")),s=new Set(this.extract("user_id"));a={onItemPushed:e=>{n.add(e._props.id),s.add(e._props.user_id)},validateBuildRules:{...a?.validateBuildRules,uniqueIdsSetCache:n,uniqueUserIdsSetCache:s},...a},super.pushMany(e,t,a)}},Gp=class extends he{constructor(e,t={}){super(e,t),this._props.metadata_private_keys&&(this._metadata_private_keys=new Vp(this._props.metadata_private_keys,{...t,clone:!1}),delete this._props.metadata_private_keys,this.assertSameMetadataKeyId()),this._props.creator&&(this._creator=new Lp(this._props.creator,{...t,clone:!1}),delete this._props.creator)}static getSchema(){return{type:"object",required:["fingerprint","armored_key"],properties:{id:{type:"string",format:"uuid",nullable:!0},fingerprint:{type:"string",pattern:/^[a-f0-9]{40}$/im},armored_key:{type:"string",maxLength:1e4,pattern:/^-----BEGIN PGP PUBLIC KEY BLOCK-----\r?\n((?:[!-9;-~]+: [^\r\n]*\r?\n)*\r?\n)((?:[A-Za-z/-9+]{1,76}\r?\n)*)([A-Za-z/-9+]{1,76}={0,2}\r?\n)(=[A-Za-z/-9+]{4}\r?\n)-----END PGP PUBLIC KEY BLOCK-----\s*$/},created:{type:"string",format:"date-time",nullable:!0},created_by:{type:"string",format:"uuid",nullable:!0},modified:{type:"string",format:"date-time",nullable:!0},modified_by:{type:"string",format:"uuid",nullable:!0},deleted:{type:"string",format:"date-time",nullable:!0},expired:{type:"string",format:"date-time",nullable:!0},metadata_private_keys:Vp.getSchema(),creator:Lp.getSchema()}}}validateBuildRules(){}assertSameMetadataKeyId(){if(0!==(this._metadata_private_keys?.length||0)&&this.id!==this._metadata_private_keys.items[0].metadataKeyId){const e=new X;throw e.addError("id:metadata_private_keys","same_id","`id` and the `metadata_private_keys.id` should be the same"),e}}assertFingerprintPublicAndPrivateKeysMatch(){0!==(this._metadata_private_keys?.length||0)&&this._metadata_private_keys.items.forEach((e,t)=>{if(e.isDecrypted&&e.data.fingerprint!==this.fingerprint){const e=new X;throw e.addError(`metadata_private_keys.${t}.fingerprint`,"fingerprint_match","The fingerprint of the metadata private key does not match the fingerprint of the metadata public key"),e}})}toDto(e){const t=Object.assign({},this._props);return e?(this._metadata_private_keys&&e.metadata_private_keys&&(t.metadata_private_keys=this._metadata_private_keys.toDto()),this._creator&&e.creator&&(t.creator=this._creator.toDto(Lp.ALL_CONTAIN_OPTIONS)),t):t}toContentCodeConfirmTrustRequestDto(){const e=this.toDto();return this._metadata_private_keys&&(e.metadata_private_keys=this._metadata_private_keys.items.map(e=>e.toContentCodeConfirmTrustRequestDto())),this._creator&&(e.creator=this._creator.toDto(Lp.ALL_CONTAIN_OPTIONS)),e}get armoredKey(){return this._props.armored_key}get id(){return this._props.id||null}get metadataPrivateKeys(){return this._metadata_private_keys||null}get created(){return this._props.created||null}get fingerprint(){return this._props.fingerprint}get expired(){return this._props.expired||null}get creator(){return this._creator||null}static get ALL_CONTAIN_OPTIONS(){return{metadata_private_keys:!0}}},Bp=class extends Bc{get entityClass(){return Gp}constructor(e=[],t={}){super(e,t)}static getSchema(){return{type:"array",items:Gp.getSchema()}}validateBuildRules(e,t={}){this.assertNotExist("id",e._props.id,{haystackSet:t?.uniqueIdsSetCache}),this.assertNotExist("fingerprint",e._props.fingerprint,{haystackSet:t?.uniqueFingerprintsSetCache})}assertFingerprintsPublicAndPrivateKeysMatch(){this._items.forEach((e,t)=>{try{e.assertFingerprintPublicAndPrivateKeysMatch(t)}catch(e){const a=new Z;throw a.addItemValidationError(t,e),a}})}getFirstByLatestCreated(){return this.length?this._items.reduce((e,t)=>e.created?t.created&&t.created>e.created?t:e:t):null}toDto(e={}){return this._items.map(t=>t.toDto(e))}hasDecryptedKeys(){return this._items.some(e=>e.metadataPrivateKeys?.hasDecryptedPrivateKeys())}hasEncryptedKeys(){return this._items.some(e=>e.metadataPrivateKeys?.hasEncryptedPrivateKeys())}filterOutMissingMetadataPrivateKeys(){this.filterByCallback(e=>e.metadataPrivateKeys?.length)}pushMany(e,t={},a={}){const n=new Set(this.extract("id")),s=new Set(this.extract("fingerprint"));a={onItemPushed:e=>{n.add(e._props.id),s.add(e._props.fingerprint)},validateBuildRules:{...a?.validateBuildRules,uniqueIdsSetCache:n,uniqueFingerprintsSetCache:s},...a},super.pushMany(e,t,a)}},Wp=["default_resource_types","allow_creation_of_v5_resources","allow_creation_of_v4_resources","allow_v4_v5_upgrade","allow_v5_v4_downgrade"],Hp=class extends Mu{toFormDto(){return Wp.reduce((e,t)=>(void 0!==this._props[t]&&(e[t]=this._props[t]),e),{})}verifyHealth(e,t){let a=null;if(void 0===e)return a;if(void 0===t)return a;if(!(e instanceof Ep))throw new TypeError("The parameter 'resourceTypes' is not a valid 'ResourceTypesCollection' type.");if(!(t instanceof Bp))throw new TypeError("The parameter 'metadataKeysCollection' is not a valid 'MetadataKeysCollection' type.");const n=e.hasSomeOfVersion(Pu),s=e.hasSomeOfVersion(Du);return this.allowCreationOfV4Resources&&!n&&(a=a||new X,a.addError("allow_creation_of_v4_resources","resource_types_deleted","Resource types v4 are deleted.")),this.isDefaultResourceTypeV4&&!n&&(a=a||new X,a.addError("default_resource_types","resource_types_v4_deleted","Resource types v4 are deleted.")),this.allowCreationOfV5Resources&&!s&&(a=a||new X,a.addError("allow_creation_of_v5_resources","resource_types_deleted","Resource types v5 are deleted.")),this.isDefaultResourceTypeV5&&!s&&(a=a||new X,a.addError("default_resource_types","resource_types_v5_deleted","Resource types v5 are deleted.")),this.allowV5V4Downgrade&&!n&&(a=a||new X,a.addError("allow_v5_v4_downgrade","resource_types_deleted","Resource types v4 are deleted.")),this.allowV5V4Downgrade&&!this.allowCreationOfV4Resources&&(a=a||new X,a.addError("allow_v5_v4_downgrade","allow_creation","Resource types v4 creation is not allowed.")),this.allowV4V5Upgrade&&!s&&(a=a||new X,a.addError("allow_v4_v5_upgrade","resource_types_deleted","Resource types v5 are deleted.")),this.allowV4V5Upgrade&&!this.allowCreationOfV5Resources&&(a=a||new X,a.addError("allow_v4_v5_upgrade","allow_creation","Resource types v5 creation is not allowed.")),0===t.items.filter(e=>!e.expired).length&&this.allowCreationOfV5Resources&&(a=a||new X,a.addError("allow_creation_of_v5_resources","active_metadata_key","No active metadata key defined.")),a}},$p=class extends Bc{get entityClass(){return Kp}constructor(e=[],t={}){super(e,t)}static getSchema(){return{type:"array",items:Kp.getSchema()}}validateBuildRules(e,t){this.assertUniqueMetadataKeyIdUserId(e,{haystackSet:t?.uniqueMetadataKeyIdUserIdSetCache})}assertUniqueMetadataKeyIdUserId(e,t){if(!e.userId||!e.metadataKeyId)return;let a=t?.haystackSet;a||(a=new Set(this.items.map(e=>`${e.metadataKeyId}:${e.userId}`)));const n=`${e.metadataKeyId}:${e.userId}`;if(a.has(n)){const e=new X,t=`The collection already includes an element that has a couple metadata_key_id:user_id (${n}) with an identical value.`;throw e.addError("metadata_key_id:user_id","unique",t),e}}pushMany(e,t={},a={}){const n=new Set(this.items.map(e=>`${e.metadataKeyId}:${e.userId}`));a={onItemPushed:e=>{n.add(`${e.metadataKeyId}:${e.userId}`)},validateBuildRules:{...a?.validateBuildRules,uniqueMetadataKeyIdUserIdSetCache:n},...a},super.pushMany(e,t,a)}hasDecryptedPrivateKeys(){return this._items.some(e=>e.isDecrypted)}hasEncryptedPrivateKeys(){return this._items.some(e=>!e.isDecrypted)}};class Yp extends he{static getSchema(){return{type:"object",required:["allow_usage_of_personal_keys","zero_knowledge_key_share"],properties:{allow_usage_of_personal_keys:{type:"boolean"},zero_knowledge_key_share:{type:"boolean"},metadata_private_keys:$p.getSchema()}}}static get associations(){return{metadata_private_keys:$p}}validateBuildRules(){if(this._props.zero_knowledge_key_share&&this.metadataPrivateKeys?.length>0){const e=new X,t="If the property zero_knowledge_key_share is true, metadata_private_keys cannot be set";throw e.addError("metadata_private_keys","not_defined_for_zero_knowledge",t),e}}static createFromDefault(e={}){return new Yp({allow_usage_of_personal_keys:!0,zero_knowledge_key_share:!1,...e})}toDto(e){const t=Object.assign({},this._props);return e?(this._metadataPrivateKeys&&e.metadata_private_keys&&(t.metadata_private_keys=this._metadataPrivateKeys.toDto()),t):t}get allowUsageOfPersonalKeys(){return this._props.allow_usage_of_personal_keys}get zeroKnowledgeKeyShare(){return this._props.zero_knowledge_key_share}get metadataPrivateKeys(){return this._metadataPrivateKeys||null}set metadataPrivateKeys(e){if(!(e instanceof $p))throw new TypeError("The metadataPrivateKeysCollection is not of MetadataPrivateKeysCollection type");this._metadataPrivateKeys=e}static get ALL_CONTAIN_OPTIONS(){return{metadata_private_keys:!0}}}const Zp=Yp,Jp=class{constructor(e){this.port=e}async findKeysSettings(){const e=await this.port.request("passbolt.metadata.find-metadata-keys-settings");return new Zp(e)}async findTypesSettings(){const e=await this.port.request("passbolt.metadata.find-metadata-types-settings");return new Mu(e)}async saveTypesSettings(e){if(!(e instanceof Mu))throw new TypeError("The 'settings' property should be of type 'MetadataTypesSettingsEntity'.");const t=await this.port.request("passbolt.metadata.save-metadata-types-settings",e.toDto());return new Mu(t)}async saveKeysSettings(e){if(!(e instanceof Zp))throw new TypeError("The 'settings' property should be of type 'MetadataKeysSettingsEntity'.");const t=await this.port.request("passbolt.metadata.save-metadata-keys-settings",e.toDto());return new Zp(t)}};class Xp extends n.Component{render(){return n.createElement("div",{className:"actions-wrapper"},n.createElement("button",{type:"button",className:"button primary form",disabled:this.props.isProcessing,onClick:this.props.onSaveRequested},n.createElement("span",null,n.createElement(f.x6,null,"Save"))))}}Xp.propTypes={isProcessing:i().bool,onSaveRequested:i().func,t:i().func};const Qp=(0,f.CI)("common")(Xp);function eh(){return eh=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},resourceTypes:null,updateLocalStorage:()=>{}});class ah extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.runningLocalStorageUpdatePromise=null,this.initEventHandlers()}get defaultState(){return{get:this.get.bind(this),resourceTypes:null,updateLocalStorage:this.updateLocalStorage.bind(this)}}initEventHandlers(){this.handleStorageChange=this.handleStorageChange.bind(this)}componentDidMount(){this.props.context.storage.onChanged.addListener(this.handleStorageChange)}componentWillUnmount(){this.props.context.storage.onChanged.removeListener(this.handleStorageChange)}handleStorageChange(e){e.resourceTypes&&this.set(e.resourceTypes.newValue)}set(e){const t=new Ep(e);this.setState({resourceTypes:t})}get(){return null===this.state.resourceTypes?(this.loadLocalStorage(),null):this.state.resourceTypes}async loadLocalStorage(){const e=await this.props.context.storage.local.get(["resourceTypes"]);e.resourceTypes?this.set(e.resourceTypes):this.updateLocalStorage()}async updateLocalStorage(){null===this.runningLocalStorageUpdatePromise?(this.runningLocalStorageUpdatePromise=this.props.context.port.request("passbolt.resource-type.get-or-find-all"),await this.runningLocalStorageUpdatePromise,this.runningLocalStorageUpdatePromise=null):await this.runningLocalStorageUpdatePromise}render(){return n.createElement(th.Provider,{value:this.state},this.props.children)}}function nh(e){return class extends n.Component{render(){return n.createElement(th.Consumer,null,t=>n.createElement(e,eh({resourceTypesLocalStorageContext:t,resourceTypes:t.get()},this.props)))}}}ah.propTypes={context:i().any,children:i().any},N(ah);class sh extends se{constructor(e,t={}){const a=sh.sanitizeDto(e);super(ae.validate(sh.ENTITY_NAME,a,sh.getSchema()),t)}static getSchema(){return{type:"object",required:["armored_key"],properties:{armored_key:{type:"string",minLength:1},key_id:{type:"string",minLength:8,maxLength:16},user_ids:{type:"array"},fingerprint:{type:"string",minLength:40,maxLength:40},expires:{anyOf:[{type:"string",format:"date-time"},{type:"string",pattern:"^Infinity$"},{}],nullable:!0},created:{type:"string",format:"date-time"},algorithm:{type:"string"},length:{type:"integer",minimum:1},curve:{type:"string",nullable:!0},private:{type:"boolean"},revoked:{type:"boolean"}}}}static sanitizeDto(e){const t=JSON.parse(JSON.stringify(e));if(e.key&&(t.armored_key=e.key,delete t.key),e.keyId&&(t.key_id=e.keyId,delete t.keyId),e.userIds&&(t.user_ids=e.userIds,delete t.userIds),e.created)try{const e=new Date(t.created);t.created=e.toISOString()}catch{delete t.created}if("Never"===e.expires)t.expires="Infinity";else if(e.expires&&"Infinity"!==e.expires)try{const e=new Date(t.expires);t.expires=e.toISOString()}catch{delete t.expires,console.error(`ExternalGpgKeyEntity::sanitizeDto Unable to sanitize the key for the user ${e.user_id}`)}return t}get armoredKey(){return this._props.armored_key}get keyId(){return this._props.key_id}get userIds(){return this._props.user_ids}get fingerprint(){return this._props.fingerprint}get expires(){return this._props.expires}get isValid(){return null!==this.expires}get created(){return this._props.created}get algorithm(){return this._props.algorithm}get length(){return this._props.length}get curve(){return this._props.curve}get revoked(){return this._props.revoked}get private(){return this._props.private}get isExpired(){const e=this.expires;if(null===e)return null;if("Infinity"===e)return!1;const t=Date.now();return new Date(e)this.formSettings?.validate());verifyDataHealth=(0,po.A)((e,t,a)=>this.formSettings?.verifyHealth(t,a));hasSettingsChanges=(0,po.A)((e,t,a)=>this.originalSettings?.hasDiffProps(this.formSettings));handleInputChange(e){if(this.hasAllInputDisabled())return;const{type:t,checked:a,value:n,name:s}=e.target,i="checkbox"===t?a:n;this.setFormPropertyValue(s,i)}setFormPropertyValue(e,t){this.formSettings.set(e,t,{validate:!1}),this.setState({settings:this.formSettings.toFormDto()})}hasAllInputDisabled(){return this.state.isProcessing}handleFormSubmit(e){e.preventDefault(),this.save()}async save(){if(this.state.isProcessing)return;const e=this.validateForm(this.state.settings);if(e?.hasErrors()){const e=!0;return void this.setState({hasAlreadyBeenValidated:e})}this.setState({isProcessing:!0});try{this.originalSettings=await this.metadataSettingsServiceWorkerService.saveTypesSettings(this.formSettings),this.formSettings=new Hp(this.originalSettings.toDto()),await this.props.actionFeedbackContext.displaySuccess(this.props.t("The encrypted metadata settings were updated."))}catch(e){this.props.dialogContext.open($t,{error:e})}this.setState({hasAlreadyBeenValidated:!0,isProcessing:!1,settings:this.formSettings.toDto()})}render(){const e=this.state.hasAlreadyBeenValidated?this.validateForm(this.state.settings):null,t=this.verifyDataHealth(this.state.settings,this.props.resourceTypes,this.metadataKeys),a=this.hasSettingsChanges(this.originalSettings,this.formSettings,this.state.settings),s=this.props.context.siteSettings.isFeatureBeta("metadata"),i=s||a;return n.createElement("div",{className:"row"},n.createElement("div",{id:"content-types-encrypted-metadata-settings",className:"main-column"},n.createElement("div",{className:"main-content"},n.createElement("form",{onSubmit:this.handleFormSubmit,"data-testid":"submit-form"},n.createElement("h3",{className:"title"},n.createElement("label",null,n.createElement(f.x6,null,"Encrypted metadata"))),n.createElement("p",{className:"description"},n.createElement(f.x6,null,"Encrypted metadata for resources is available.")," ",n.createElement(f.x6,null,"Define the strategy to manage and migrate the legacy items.")),n.createElement("h4",null,n.createElement(f.x6,null,"Supported metadata types")),n.createElement("p",{className:"description"},n.createElement(f.x6,null,"Define which metadata types are enabled for this instance.")),n.createElement("div",{className:`input toggle-switch form-element\n ${e?.hasError("allow_creation_of_v5_resources")?"error":""}\n ${t?.hasError("allow_creation_of_v5_resources")?"warning":""}`},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"allow_creation_of_v5_resources",id:"allowCreationOfV5ResourcesInput",onChange:this.handleInputChange,checked:this.state.settings.allow_creation_of_v5_resources,disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"allowCreationOfV5ResourcesInput"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Enable encrypted metadata (recommended)")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"Enable encrypted metadata for resources.")),e?.hasError("allow_creation_of_v5_resources","is_default")&&n.createElement("div",{className:"name error-message"},n.createElement(f.x6,null,"Encrypted metadata must be enabled to set it as the default type.")),!e?.hasError("allow_creation_of_v5_resources")&&n.createElement(n.Fragment,null,t?.hasError("allow_creation_of_v5_resources","resource_types_deleted")&&n.createElement("div",{className:"name warning-message"},n.createElement(f.x6,null,"All encrypted metadata resource types were previously disabled. Re-enable them if you want users to create resources of this type.")),t?.hasError("allow_creation_of_v5_resources","active_metadata_key")&&n.createElement("div",{className:"name warning-message"},n.createElement(f.x6,null,"A metadata key should be enabled to allow users to create resources of this type."))))),n.createElement("div",{className:`input toggle-switch form-element\n ${e?.hasError("allow_creation_of_v4_resources")?"error":""}\n ${t?.hasError("allow_creation_of_v4_resources")?"warning":""}`},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"allow_creation_of_v4_resources",id:"allowCreationOfV4ResourcesInput",onChange:this.handleInputChange,checked:this.state.settings.allow_creation_of_v4_resources,disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"allowCreationOfV4ResourcesInput"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Enable legacy cleartext metadata")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"Enable legacy cleartext metadata for resources.")),e?.hasError("allow_creation_of_v4_resources","is_default")&&n.createElement("div",{className:"name error-message"},n.createElement(f.x6,null,"Legacy cleartext metadata must be enabled to set it as the default type.")),!e?.hasError("allow_creation_of_v4_resources")&&t?.hasError("allow_creation_of_v4_resources","resource_types_deleted")&&n.createElement("div",{className:"name warning-message"},n.createElement(f.x6,null,"All legacy cleartext resource types were previously disabled. Re-enable them if you want users to create resources of this type.")))),n.createElement("h4",null,n.createElement(f.x6,null,"Default metadata type")),n.createElement("p",{className:"description"},n.createElement(f.x6,null,"Define which metadata type is used by default.")),n.createElement("div",{className:"radiolist-alt"},n.createElement("div",{className:`input radio\n ${"v5"===this.state.settings.default_resource_types?"checked":""}\n ${e?.hasError("default_resource_types","allow_create_v5")?"error":""}\n ${!e?.hasError("default_resource_types","allow_create_v5")&&t?.hasError("default_resource_types","resource_types_v5_deleted")?"warning":""}`},n.createElement("input",{type:"radio",value:"v5",onChange:this.handleInputChange,name:"default_resource_types",checked:"v5"===this.state.settings.default_resource_types,id:"defaultResourceTypesV5Input",disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"defaultResourceTypesV5Input"},n.createElement("span",{className:"name bold"},n.createElement(f.x6,null,"Encrypted metadata (recommended)")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"Users can create resources with encrypted metadata by default."),n.createElement("br",null)),e?.hasError("default_resource_types","allow_create_v5")&&n.createElement("div",{className:"name error-message"},n.createElement(f.x6,null,"Encrypted metadata must be enabled to set it as the default type.")),!e?.hasError("default_resource_types","allow_create_v5")&&t?.hasError("default_resource_types","resource_types_v5_deleted")&&n.createElement("div",{className:"name warning-message"},n.createElement(f.x6,null,"All encrypted metadata resource types were previously disabled. Re-enable them if you want users to create resources of this type.")))),n.createElement("div",{className:`input radio ${"v4"===this.state.settings.default_resource_types?"checked":""}\n ${e?.hasError("default_resource_types","allow_create_v4")?"error":""}\n ${!e?.hasError("default_resource_types","allow_create_v4")&&t?.hasError("default_resource_types","resource_types_v4_deleted")?"warning":""}`},n.createElement("input",{type:"radio",value:"v4",onChange:this.handleInputChange,name:"default_resource_types",checked:"v4"===this.state.settings.default_resource_types,id:"defaultResourceTypesV4Input",disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"defaultResourceTypesV4Input"},n.createElement("span",{className:"name bold"},n.createElement(f.x6,null,"Legacy cleartext metadata")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"Users can create legacy resources with cleartext metadata by default.")),e?.hasError("default_resource_types","allow_create_v4")&&n.createElement("div",{className:"name error-message"},n.createElement(f.x6,null,"Legacy cleartext metadata must be enabled to set it as the default type.")),!e?.hasError("default_resource_types","allow_create_v4")&&t?.hasError("default_resource_types","resource_types_v4_deleted")&&n.createElement("div",{className:"name warning-message"},n.createElement(f.x6,null,"All legacy cleartext resource types were previously disabled. Re-enable them if you want users to create resources of this type."))))),n.createElement("h4",{className:"no-border"},n.createElement(f.x6,null,"Self served migration")),n.createElement("div",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"allow_v4_v5_upgrade",id:"allowV4V5UpgradeInput",onChange:this.handleInputChange,checked:this.state.settings.allow_v4_v5_upgrade,disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"allowV4V5UpgradeInput",className:"text"},n.createElement(f.x6,null,"Allow users to upgrade their content from cleartext to encrypted metadata type."),t?.hasError("allow_v4_v5_upgrade","resource_types_deleted")&&n.createElement("div",{className:"name warning-message"},n.createElement(f.x6,null,"All encrypted metadata resource types were previously disabled. Re-enable them if you want users to upgrade their resources.")),t?.hasError("allow_v4_v5_upgrade","allow_creation")&&n.createElement("div",{className:"name warning-message"},n.createElement(f.x6,null,"Encrypted metadata should be enabled to allow users to upgrade their resources.")))))),i&&n.createElement("div",{className:"warning message"},s&&n.createElement("div",null,n.createElement("b",null,n.createElement(f.x6,null,"Warning:"))," ",n.createElement(f.x6,null,"Your current API version includes beta support for encrypted metadata and new resource types.")," ",n.createElement(f.x6,null,"To ensure stability and avoid potential issues, upgrade to the latest version before enabling these features.")),a&&n.createElement("div",{className:"form-banner"},n.createElement("p",null,n.createElement("b",null,n.createElement(f.x6,null,"Warning:"))," ",n.createElement(f.x6,null,"Don't forget to save your settings to apply your modification."))))),n.createElement(Qp,{onSaveRequested:this.save,isProcessing:this.state.isProcessing}),Xa(n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"Need help?")),n.createElement("p",null,n.createElement(f.x6,null,"For more information about the content type support and migration, checkout the dedicated page on the official website.")),n.createElement("a",{className:"button",target:"_blank",rel:"noopener noreferrer",href:"https://passbolt.com/docs/admin/metadata-encryption/encrypted-metadata/"},n.createElement(ps,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}ch.propTypes={context:i().object,actionFeedbackContext:i().object,dialogContext:i().object,createPortal:i().func,metadataSettingsServiceWorkerService:i().object,metadataKeysServiceWorkerService:i().object,resourceTypes:i().instanceOf(Ep),t:i().func};const mh=N(m(h(nh((0,f.CI)("common")(ch)))));var dh;function uh(){return uh=Object.assign?Object.assign.bind():function(e){for(var t=1;te.id).sort().sort((e,t)=>{if(e===t)throw new ce(0,fh.RULE_UNIQUE_ID,`Gpgkey fingerprint ${e} already exists.`)}),this._props.forEach(e=>{this._items.push(new ih(e,{clone:!1}))}),this._props=null}static getSchema(){return{type:"array",items:ih.getSchema()}}static get ENTITY_NAME(){return"externalGpgKey"}static get RULE_UNIQUE_ID(){return"fingerprint"}}const Eh=fh,vh=class{constructor(e){this.port=e}async keyInfo(e){const t=await this.port.request("passbolt.keyring.get-key-info",e);return new ih(t)}async keysInfo(e=[]){const t=[];for(const a of e){const e=await this.keyInfo(a);t.push(e)}return new Eh(t)}},wh=class extends Zp{constructor(e,t={}){super(e,t),this._props.generated_metadata_key&&(this._generated_metadata_key=new oh(this._props.generated_metadata_key,{...t,clone:!1}),delete this._props.generated_metadata_key)}static getSchema(){return{type:"object",required:["allow_usage_of_personal_keys","zero_knowledge_key_share"],properties:{...Zp.getSchema().properties,generated_metadata_key:oh.getSchema()}}}toDto(){return{...this._props,generated_metadata_key:this.generatedMetadataKey?.toDto({public_key:!0,private_key:!0})||null}}get generatedMetadataKey(){return this._generated_metadata_key||null}set generatedMetadataKey(e){if(null!==e&&!(e instanceof oh))throw new TypeError("The parameter `generatedMetadataKey` should be of type ExternalGpgKeyPairEntity.");this._generated_metadata_key=e}};class kh extends n.Component{render(){return n.createElement("div",{className:"actions-wrapper"},n.createElement("button",{type:"button",className:"button primary form "+(this.props.isProcessing?"processing":""),disabled:this.props.isDisabled,onClick:this.props.onSaveRequested},n.createElement("span",null,n.createElement(f.x6,null,"Save")),this.props.isProcessing&&n.createElement(En,null)))}}kh.propTypes={isProcessing:i().bool,isDisabled:i().bool,onSaveRequested:i().func,t:i().func};const _h=(0,f.CI)("common")(kh);class xh extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.bindCallbacks()}get defaultState(){return{processing:!1}}bindCallbacks(){this.handleConfirm=this.handleConfirm.bind(this),this.handleCancel=this.handleCancel.bind(this)}async handleConfirm(e){e.preventDefault(),this.props.onConfirm(),this.props.onClose()}async handleCancel(){this.props.onClose()}hasAllInputDisabled(){return this.state.processing}render(){const e=this.hasAllInputDisabled();return n.createElement(qt,{className:"confirm-metadata-key-rotation-dialog",title:this.props.t("Please confirm"),onClose:this.handleCancel,disabled:e},n.createElement("div",{className:"form-content"},n.createElement("label",null,n.createElement(f.x6,null,"New shared Metadata key")),n.createElement("div",{className:"metadata-key-info"},n.createElement("table",{className:"table-info"},n.createElement("tbody",null,n.createElement("tr",{className:"fingerprint"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Fingerprint")),n.createElement("td",{className:"value"},n.createElement(bh,{fingerprint:this.props.metadataKeyInfo.fingerprint}))),n.createElement("tr",{className:"algorithm"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Algorithm")),n.createElement("td",{className:"value"},this.props.metadataKeyInfo.algorithm)),n.createElement("tr",{className:"created"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Created")),this.props.metadataKeyInfo.created&&n.createElement("td",{className:"value",title:this.props.metadataKeyInfo.created},Hs(this.props.metadataKeyInfo.created,this.props.t,this.props.context.locale)),!this.props.metadataKeyInfo.created&&n.createElement("td",{className:"empty-value"},n.createElement(f.x6,null,"Pending")))))),n.createElement("p",null,n.createElement(f.x6,null,"This operation may take a few minutes."))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement("button",{type:"button",className:"link cancel",onClick:this.handleCancel,disabled:e},n.createElement(f.x6,null,"Cancel")),n.createElement("button",{type:"button",className:"button primary form",onClick:this.handleConfirm,disabled:e},n.createElement(f.x6,null,"Rotate key"))))}}xh.propTypes={context:i().object,metadataKeyInfo:i().object,onConfirm:i().func,onClose:i().func,t:i().func};const Sh=N((0,f.CI)("common")(xh));class Ch extends n.Component{originalSettings=null;formSettings=null;constructor(e){super(e),this.metadataSettingsServiceWorkerService=e.metadataSettingsServiceWorkerService??new Jp(e.context.port),this.metadataKeysServiceWorkerService=e.metadataKeysServiceWorkerService??new lh(e.context.port),this.gpgServiceWorkerService=e.gpgServiceWorkerService??new vh(e.context.port),this.state=this.defaultState,this.bindCallbacks()}get defaultState(){return{isProcessing:!0,hasAlreadyBeenValidated:!1,settings:{allow_usage_of_personal_keys:!0,zero_knowledge_key_share:!1,generated_metadata_key:null},activeMetadataKeys:null,expiredMetadataKeys:null}}bindCallbacks(){this.handleFormSubmit=this.handleFormSubmit.bind(this),this.handleInputChange=this.handleInputChange.bind(this),this.generateMetadataKey=this.generateMetadataKey.bind(this),this.save=this.save.bind(this)}async componentDidMount(){await this.loadKeysSettings(),await this.loadKeys(),this.setState({isProcessing:!1})}async loadKeysSettings(){try{const e=await this.metadataSettingsServiceWorkerService.findKeysSettings();this.originalSettings=new wh(e.toDto(),{validate:!1}),this.formSettings=new wh(e.toDto(),{validate:!1}),this.setState({settings:this.formSettings.toDto()})}catch(e){await this.handleUnexpectedError(e)}}handleUnexpectedError(e){if(console.error(e),"UserAbortsOperationError"!==e.name)return this.props.dialogContext.open($t,{error:e})}async loadKeys(){try{const e=await this.metadataKeysServiceWorkerService.findAll();e.items.sort((e,t)=>Ds.c9.fromISO(t.created)!e.expired);const a=new Bp(e);a.filterByCallback(e=>e.expired);const n=e.items.map(e=>e.armoredKey),s=await this.gpgServiceWorkerService.keysInfo(n);this.setState({activeMetadataKeys:t,expiredMetadataKeys:a,metadataKeysInfo:s})}catch(e){await this.handleUnexpectedError(e)}}hasSettingsChanges=(0,po.A)((e,t,a)=>e?.hasDiffProps(t)||e?.generatedMetadataKey!==t?.generatedMetadataKey);handleInputChange(e){if(this.hasAllInputDisabled())return;const{type:t,checked:a,value:n,name:s}=e.target;let i=n;"checkbox"===t&&(i=a),"allow_usage_of_personal_keys"!==s&&"zero_knowledge_key_share"!==s||(i="true"===n),this.setFormPropertyValue(s,i)}setFormPropertyValue(e,t){this.formSettings.set(e,t,{validate:!1}),this.setState({settings:this.formSettings.toDto()})}hasAllInputDisabled(){return this.state.isProcessing||this.hasMissingMetadataKeys}async generateMetadataKey(){const e=this.state.metadataKeysInfo,t=this.state.activeMetadataKeys;this.setState({isProcessing:!0});try{const a=await this.metadataKeysServiceWorkerService.generateKeyPair(),n=await this.gpgServiceWorkerService.keyInfo(a.publicKey.armoredKey);e.push(n);const s=new Gp({armored_key:a.publicKey.armoredKey,fingerprint:n.fingerprint});t.push(s),this.formSettings.generatedMetadataKey=a,this.setState({activeMetadataKeys:t,metadataKeysInfo:e,settings:this.formSettings.toDto()})}catch(e){await this.handleUnexpectedError(e)}this.setState({isProcessing:!1})}async rotateMetadataKey(e){this.setState({isProcessing:!0});try{const t=await this.metadataKeysServiceWorkerService.generateKeyPair(),a=await this.gpgServiceWorkerService.keyInfo(t.publicKey.armoredKey);this.props.dialogContext.open(Sh,{metadataKeyInfo:a,onConfirm:()=>this.handleRotateKeyConfirmation(t,e)})}catch(e){await this.handleUnexpectedError(e)}finally{this.setState({isProcessing:!1})}}async handleRotateKeyConfirmation(e,t){try{await this.metadataKeysServiceWorkerService.rotate(e,t.id),await this.loadKeys(),await this.props.actionFeedbackContext.displaySuccess(this.props.t("The metadata key has been rotated."))}catch(e){await this.handleUnexpectedError(e),await this.loadKeys()}}async resumeRotationMetadataKey(e){this.setState({isProcessing:!0});try{await this.metadataKeysServiceWorkerService.resumeRotation(e),await this.loadKeys(),await this.props.actionFeedbackContext.displaySuccess(this.props.t("The metadata key has been rotated."))}catch(e){await this.handleUnexpectedError(e),await this.loadKeys()}finally{this.setState({isProcessing:!1})}}handleFormSubmit(e){e.preventDefault(),this.save()}async save(){if(this.state.isProcessing)return;this.setState({isProcessing:!0});const e=this.validateForm(this.state.settings);if(e?.hasErrors())this.setState({isProcessing:!1,hasAlreadyBeenValidated:!0});else{try{await this.saveMetadataKeysSettings(),await this.createMetadataKey(),await this.props.actionFeedbackContext.displaySuccess(this.props.t("The metadata key settings were updated."))}catch(e){await this.handleUnexpectedError(e)}this.setState({isProcessing:!1,settings:this.formSettings.toDto()})}}validateForm=(0,po.A)(e=>{if(!this.formSettings)return null;let t=this.formSettings.validate();return this.state.activeMetadataKeys.length||(t=t||new X,t.addError("generated_metadata_key","required",this.props.t("A shared metadata key is required."))),t});async saveMetadataKeysSettings(){const e=new Zp(this.formSettings.toDto()),t=await this.metadataSettingsServiceWorkerService.saveKeysSettings(e);this.originalSettings=new wh({...this.originalSettings.toDto(),...t.toDto()}),this.formSettings=new wh({...this.formSettings.toDto(),...t.toDto()})}async createMetadataKey(){if(!this.formSettings.generatedMetadataKey)return;const e=await this.metadataKeysServiceWorkerService.createKey(this.formSettings.generatedMetadataKey);this.state.activeMetadataKeys.pushOrReplace(e,{},{replacePropertyName:"fingerprint"}),this.formSettings.generatedMetadataKey=null}get hasMissingMetadataKeys(){return this.props.context.loggedInUser.missing_metadata_key_ids?.length>0}render(){const e=this.state.hasAlreadyBeenValidated?this.validateForm(this.state.settings):null,t=this.hasSettingsChanges(this.originalSettings,this.formSettings,this.state.settings),a=this.props.context.siteSettings.isFeatureBeta("metadata"),s=a||t||e?.hasError("generated_metadata_key","required")||this.hasMissingMetadataKeys;return n.createElement("div",{className:"row"},n.createElement("div",{id:"content-types-metadata-key-settings",className:"main-column"},n.createElement("div",{className:"main-content"},n.createElement("form",{onSubmit:this.handleFormSubmit,"data-testid":"submit-form"},n.createElement("h3",{className:"title"},n.createElement("label",null,n.createElement(f.x6,null,"Metadata key"))),n.createElement("p",{className:"description"},n.createElement(f.x6,null,"This section controls the layer of encryption that is used to protect metadata such as the name of a resource, URIs, etc.")),n.createElement("h4",{className:"no-border"},n.createElement(f.x6,null,"Metadata key policy")),n.createElement("p",{className:"description"},n.createElement(f.x6,null,"It is possible for users to use their personal keys to encrypt resources metadata for more security. However you can elect to enforce the use of the shared metadata keys for all resources metadata for auditing purposes. Secrets such as passwords will always be encrypted using the user personal keys.")),n.createElement("div",{className:"radiolist-alt"},n.createElement("div",{className:`input radio ${!0===this.state.settings.allow_usage_of_personal_keys?"checked":""} ${this.hasAllInputDisabled()&&"disabled"}`},n.createElement("input",{type:"radio",value:"true",onChange:this.handleInputChange,name:"allow_usage_of_personal_keys",checked:!0===this.state.settings.allow_usage_of_personal_keys,id:"allowUsageOfPersonalKeysInput",disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"allowUsageOfPersonalKeysInput"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Allow the use of personal keys. (Recommended)")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"Users can use shared and personal keys. By default personal resources that are not shared will be encrypted with the users personal keys."),n.createElement("br",null)))),n.createElement("div",{className:`input radio ${!1===this.state.settings.allow_usage_of_personal_keys?"checked":""} ${this.hasAllInputDisabled()&&"disabled"}`},n.createElement("input",{type:"radio",value:"false",onChange:this.handleInputChange,name:"allow_usage_of_personal_keys",checked:!1===this.state.settings.allow_usage_of_personal_keys,id:"disallowUsageOfPersonalKeysInput",disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"disallowUsageOfPersonalKeysInput"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Enforce the use of shared metadata keys.")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"By default, metadata wil be encrypted with the shared keys. It is not possible to use personal keys to encrypt metadata."),n.createElement("br",null))))),n.createElement("h4",null,n.createElement(f.x6,null,"Zero knowledge")),n.createElement("p",{className:"description"},n.createElement(f.x6,null,"This section defines how the shared metadata key is shared with users.")),n.createElement("div",{className:"radiolist-alt"},n.createElement("div",{className:`input radio ${!1===this.state.settings.zero_knowledge_key_share?"checked":""} ${this.hasAllInputDisabled()&&"disabled"}`},n.createElement("input",{type:"radio",value:"false",onChange:this.handleInputChange,name:"zero_knowledge_key_share",checked:!1===this.state.settings.zero_knowledge_key_share,id:"disableZeroKnowledgeKeyShareInput",disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"disableZeroKnowledgeKeyShareInput"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"User-friendly mode (Better on-boarding)")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"The shared metadata key is accessible to the server and can be shared by the server when a user completes the setup. In practice, an attacker with full server access can see the shared metadata."),n.createElement("br",null)))),n.createElement("div",{className:`input radio ${!0===this.state.settings.zero_knowledge_key_share?"checked":""} ${this.hasAllInputDisabled()&&"disabled"}`},n.createElement("input",{type:"radio",value:"true",onChange:this.handleInputChange,name:"zero_knowledge_key_share",checked:!0===this.state.settings.zero_knowledge_key_share,id:"enableZeroKnowledgeKeyShareInput",disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"enableZeroKnowledgeKeyShareInput"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Zero-knowledge mode (More secure)")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"The shared metadata key is not available to the server and must be shared with users by the admins. New users are not allowed to create or access shared content until they are provided the metadata key. It is recommended to rotate the key if you switch to that mode."),n.createElement("br",null))))),n.createElement("h4",null,n.createElement(f.x6,null,"Shared metadata keys")),n.createElement("div",{className:`metadata-key-info ${e?.hasError("generated_metadata_key","required")&&"error"}`},this.state.activeMetadataKeys?.length>0&&n.createElement("div",{id:"metadata-active-keys"},this.state.activeMetadataKeys?.items.map((e,t)=>{const a=this.state.metadataKeysInfo?.getFirst("fingerprint",e.fingerprint);return n.createElement("table",{key:e.fingerprint,className:"table-info"},n.createElement("tbody",null,n.createElement("tr",{className:"fingerprint"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Fingerprint")),n.createElement("td",{className:"value"},n.createElement(bh,{fingerprint:e.fingerprint})),n.createElement("td",{className:"table-button"},1===this.state.activeMetadataKeys.length&&0===this.state.expiredMetadataKeys?.length&&n.createElement("button",{className:"button primary medium form",type:"button",disabled:this.hasAllInputDisabled(),onClick:()=>this.rotateMetadataKey(e)},n.createElement(f.x6,null,"Rotate key")),t>=1&&n.createElement("button",{className:"button primary medium form",type:"button",disabled:this.hasAllInputDisabled(),onClick:()=>this.resumeRotationMetadataKey(e)},n.createElement(f.x6,null,"Resume rotation")))),n.createElement("tr",{className:"algorithm"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Algorithm")),n.createElement("td",{className:"value"},a?.algorithm," ",a?.curve)),n.createElement("tr",{className:"key-length"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Key length")),n.createElement("td",{className:"value"},a?.length)),n.createElement("tr",{className:"created"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Created")),e.created&&n.createElement("td",{className:"value"},n.createElement("span",{title:e.created},Hs(e.created,this.props.t,this.props.context.locale))),!e.created&&n.createElement("td",{className:"empty-value"},n.createElement(f.x6,null,"Pending"))),n.createElement("tr",{className:"status"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Status")),n.createElement("td",{className:"value"},n.createElement("span",{title:"Active"},n.createElement(f.x6,null,"Active"))))))})),!this.state.activeMetadataKeys?.length&&n.createElement("div",{id:"no-metadata-active-keys"},n.createElement("table",{className:"table-info"},n.createElement("tbody",null,n.createElement("tr",null,n.createElement("td",{className:"empty-value"},n.createElement(f.x6,null,"You need to generate a new shared key to enable encrypted metadata.")),n.createElement("td",{className:"table-button"},n.createElement("button",{className:"button primary medium form",type:"button",disabled:this.hasAllInputDisabled(),onClick:this.generateMetadataKey,"data-testid":"generate-key-buton"},n.createElement(f.x6,null,"Generate key")))),e?.hasError("generated_metadata_key","required")&&n.createElement("tr",{className:"error-message"},n.createElement(f.x6,null,"A shared metadata key is required."))))),this.state.expiredMetadataKeys?.length>0&&n.createElement(n.Fragment,null,n.createElement("h4",null,n.createElement(f.x6,null,"Previous keys")),n.createElement("div",{id:"metadata-expired-keys"},this.state.expiredMetadataKeys?.items.map(e=>{const t=this.state.metadataKeysInfo.getFirst("fingerprint",e.fingerprint);return n.createElement("table",{key:e.fingerprint,className:"table-info"},n.createElement("tbody",null,n.createElement("tr",{className:"fingerprint"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Fingerprint")),n.createElement("td",{className:"value"},n.createElement(bh,{fingerprint:e.fingerprint})),n.createElement("td",{className:"table-button"},this.state.activeMetadataKeys.length>0&&null===this.formSettings.generatedMetadataKey&&n.createElement("button",{className:"button primary medium form",type:"button",disabled:this.hasAllInputDisabled(),onClick:()=>this.resumeRotationMetadataKey(e)},n.createElement(f.x6,null,"Resume rotation")))),n.createElement("tr",{className:"algorithm"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Algorithm")),n.createElement("td",{className:"value"},t?.algorithm," ",t?.curve)),n.createElement("tr",{className:"key-length"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Key length")),n.createElement("td",{className:"value"},t?.length)),n.createElement("tr",{className:"created"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Created")),n.createElement("td",{className:"value"},n.createElement("span",{title:e.created},Hs(e.created,this.props.t,this.props.context.locale)))),n.createElement("tr",{className:"status"},n.createElement("td",{className:"label"},n.createElement(f.x6,null,"Status")),n.createElement("td",{className:"value"},n.createElement("span",{title:e.expired},this.props.t("Expired {{expiredDate}}",{expiredDate:Hs(e.expired,this.props.t,this.props.context.locale)}))))))})))))),s&&n.createElement("div",{className:"warning message"},a&&n.createElement("div",{className:"form-banner"},n.createElement("b",null,n.createElement(f.x6,null,"Warning:"))," ",n.createElement(f.x6,null,"Your current API version includes beta support for encrypted metadata and new resource types.")," ",n.createElement(f.x6,null,"To ensure stability and avoid potential issues, upgrade to the latest version before enabling these features.")),t&&n.createElement("div",{className:"form-banner"},n.createElement("p",null,n.createElement("b",null,n.createElement(f.x6,null,"Warning:"))," ",n.createElement(f.x6,null,"Don't forget to save your settings to apply your modification."))),e?.hasError("generated_metadata_key","required")&&n.createElement("div",{className:"form-banner"},n.createElement("p",null,n.createElement("b",null,n.createElement(f.x6,null,"Warning:"))," ",n.createElement(f.x6,null,"A shared metadata key is required to save the metadata keys settings."))),this.hasMissingMetadataKeys&&n.createElement("div",{className:"form-banner"},n.createElement("p",null,n.createElement("b",null,n.createElement(f.x6,null,"Warning:"))," ",n.createElement(f.x6,null,"You are missing shared metadata keys.")," ",n.createElement(f.x6,null,"Ask another administrator to share them with you to update the metadata keys settings."))))),n.createElement(_h,{onSaveRequested:this.save,isProcessing:this.state.isProcessing,isDisabled:this.hasAllInputDisabled()}),Xa(n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"Need help?")),n.createElement("p",null,n.createElement(f.x6,null,"For more information about the content type support and migration, checkout the dedicated page on the official website.")),n.createElement("a",{className:"button",target:"_blank",rel:"noopener noreferrer",href:"https://passbolt.com/docs/admin/metadata-encryption/manage-metadata-key/"},n.createElement(ps,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}Ch.propTypes={context:i().object,actionFeedbackContext:i().object,dialogContext:i().object,createPortal:i().func,metadataSettingsServiceWorkerService:i().object,metadataKeysServiceWorkerService:i().object,gpgServiceWorkerService:i().object,t:i().func};const Nh=N(h(m((0,f.CI)("common")(Ch))));var Th,Ah;function Ih(){return Ih=Object.assign?Object.assign.bind():function(e){for(var t=1;t!e.expired).length>0)return null;const t=new X;return t.addError("global_form","active_metadata_key","No active metadata key defined."),t}_verifyMigrateResourcesToV5Health(e,t,a){this._props.migrate_resources_to_v5&&!a.allowCreationOfV5Resources&&(e=e||new X).addError("migrate_resources_to_v5","allow_creation_of_v5_resources","Resource types v5 creation is not allowed.");const n=t.hasSomeOfVersion(Du);if(this._props.migrate_resources_to_v5&&!n)return(e=e||new X).addError("migrate_resources_to_v5","resource_types_v5_deleted","Resource types v5 are deleted."),e;const s=t.items.filter(e=>e.version===Pu).every(e=>t.hasOneWithSlug(rp[e.slug]));return this._props.migrate_resources_to_v5&&!s&&(e=e||new X).addError("migrate_resources_to_v5","resource_types_v5_partially_deleted","Some resource types v5 are missing."),e}_verifyMigrateFoldersToV5Health(e,t){return this._props.migrate_folders_to_v5&&!t.allowV4V5Upgrade&&(e=e||new X).addError("migrate_folders_to_v5","allow_v4_v5_upgrade","Folders v5 creation is not allowed."),this._props.migrate_folders_to_v5&&!t.allowCreationOfV5Folders&&(e=e||new X).addError("migrate_folders_to_v5","allow_creation_of_v5_folders","Folders v5 creation is not allowed."),e}_verifyMigrateTagsToV5Health(e,t){return this._props.migrate_tags_to_v5&&!t.allowV4V5Upgrade&&(e=e||new X).addError("migrate_tags_to_v5","allow_v4_v5_upgrade","Tags v5 creation is not allowed."),this._props.migrate_tags_to_v5&&!t.allowCreationOfV5Folders&&(e=e||new X).addError("migrate_tags_to_v5","allow_creation_of_v5_tags","Tags v5 creation is not allowed."),e}_verifyMigrateCommentsToV5Health(e,t){return this._props.migrate_comments_to_v5&&!t.allowV4V5Upgrade&&(e=e||new X).addError("migrate_comments_to_v5","allow_v4_v5_upgrade","Comments v5 creation is not allowed."),this._props.migrate_comments_to_v5&&!t.allowCreationOfV5Folders&&(e=e||new X).addError("migrate_comments_to_v5","allow_creation_of_v5_comments","Comments v5 creation is not allowed."),e}},ag=class{constructor(e){this.port=e}async findCountMetadataMigrateResources(e=!1){const t=await this.port.request("passbolt.metadata.find-metadata-migrate-resources-details",e);return new ia(t)}async migrate(e,t){await this.port.request("passbolt.metadata.migrate-resources-metadata",e,t)}};class ng extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.bindCallbacks()}get defaultState(){return{processing:!1}}bindCallbacks(){this.handleConfirm=this.handleConfirm.bind(this),this.handleCancel=this.handleCancel.bind(this)}async handleConfirm(e){e.preventDefault(),this.props.confirm(),this.props.onClose()}async handleCancel(){this.props.cancel(),this.props.onClose()}hasAllInputDisabled(){return this.state.processing}render(){const e=this.hasAllInputDisabled();return n.createElement(qt,{className:"confirm-migrate-metadata-dialog",title:this.props.t("Please confirm"),onClose:this.handleCancel,disabled:e},n.createElement("div",{className:"form-content"},n.createElement("p",null,n.createElement("strong",null,n.createElement(f.x6,null,"Are you sure you want to migrate the selected items to use encrypted metadata?"))),n.createElement("p",null,n.createElement(f.x6,null,"If you have integrations, you will have to make sure they are updated before triggering the migration.")),n.createElement("p",null,n.createElement(f.x6,null,"The operation may take a few minutes."))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement("button",{type:"button",className:"link cancel",onClick:this.handleCancel,disabled:e},n.createElement(f.x6,null,"Cancel")),n.createElement("button",{type:"button",className:"button primary form",onClick:this.handleConfirm,disabled:e},n.createElement(f.x6,null,"Migrate"))))}}ng.propTypes={cancel:i().func,confirm:i().func,onClose:i().func,t:i().func};const sg=(0,f.CI)("common")(ng);class ig extends n.Component{formSettings=void 0;metadataTypesSettings=void 0;metadataKeys=void 0;migrationCountDetails=void 0;migrationCountDetailsShared=void 0;constructor(e){super(e),this.formSettings=new tg({}),this.metadataSettingsServiceWorkerService=e.metadataSettingsServiceWorkerService??new Jp(e.context.port),this.metadataKeysServiceWorkerService=e.metadataKeysServiceWorkerService??new lh(e.context.port),this.metadataMigrateContentServiceWorkerService=e.metadataMigrateContentServiceWorkerService??new ag(e.context.port),this.state=this.defaultState,this.bindCallbacks()}get defaultState(){return{isReady:!1,isProcessing:!1,hasAlreadyBeenValidated:!1,hasMigrationRunOnce:!1,settings:this.formSettings.toDto()}}bindCallbacks(){this.handleFormSubmit=this.handleFormSubmit.bind(this),this.handleInputChange=this.handleInputChange.bind(this),this.handleMigrateScopeInputChange=this.handleMigrateScopeInputChange.bind(this),this.runMigration=this.runMigration.bind(this),this.askForMigrationConfirmation=this.askForMigrationConfirmation.bind(this)}async componentDidMount(){await this.initData()}async initData(){this.metadataTypesSettings=await this.metadataSettingsServiceWorkerService.findTypesSettings(),this.metadataKeys=await this.metadataKeysServiceWorkerService.findAll(),this.migrationCountDetailsShared=await this.metadataMigrateContentServiceWorkerService.findCountMetadataMigrateResources(!0),this.migrationCountDetails=await this.metadataMigrateContentServiceWorkerService.findCountMetadataMigrateResources(),this.setState({settings:this.formSettings.toDto(),isProcessing:!1,isReady:!0})}validateForm=(0,po.A)(e=>this.formSettings?.validate());verifyDataHealth=(0,po.A)((e,t,a,n)=>this.formSettings?.verifyHealth(t,a,n));handleInputChange(e){if(this.hasAllInputDisabled())return;const{type:t,checked:a,value:n,name:s}=e.target,i="checkbox"===t?a:n;this.setFormPropertyValue(s,i)}handleMigrateScopeInputChange(e){const{value:t,name:a}=e.target;this.setFormPropertyValue(a,"all-content"===t)}setFormPropertyValue(e,t){this.formSettings.set(e,t,{validate:!1}),this.setState({settings:this.formSettings.toDto()})}get hasMissingMetadataKeys(){return this.props.context.loggedInUser.missing_metadata_key_ids?.length>0}hasAllInputDisabled(){return this.state.isProcessing}handleFormSubmit(e){e.preventDefault(),this.askForMigrationConfirmation()}get hasPendingMigration(){return this.hasPendingResourcesMigration||this.hasPendingFoldersMigration||this.hasPendingCommentsMigration||this.hasPendingTagsMigration}get totalResources(){return this.totalSharedResources+this.totalPersonalResources}get totalSharedResources(){return this.migrationCountDetailsShared?.count}get totalPersonalResources(){return this.migrationCountDetailsPersonal?.count}get migrationCountDetailsPersonal(){return{...this.migrationCountDetails,count:this.migrationCountDetails?.count-this.migrationCountDetailsShared?.count}}get hasPendingResourcesMigration(){return this.totalResources>0}get hasPendingFoldersMigration(){return this.totalFolders>0}get hasPendingTagsMigration(){return this.totalTags>0}get hasPendingCommentsMigration(){return this.totalComments>0}get migrationStatus(){return this.hasPendingMigration?this.state.hasMigrationRunOnce?this.props.t("Pending"):this.props.t("Required"):this.props.t("Done")}hasElementsToMigrate(){return this.totalResources>0}hasGlobalError(e){return e?.hasError("global_form")||!1}askForMigrationConfirmation(){this.props.dialogContext.open(sg,{confirm:this.runMigration,cancel:()=>{}})}async runMigration(){if(this.state.isProcessing)return;const e=this.validateForm(this.state.settings),t=this.verifyDataHealth(this.state.settings,this.props.resourceTypes,this.metadataTypesSettings,this.metadataKeys);if(e?.hasErrors()||this.hasGlobalError(t))this.setState({hasAlreadyBeenValidated:!0});else{this.setState({isProcessing:!0});try{const e=this.formSettings.sharedContentOnly?this.migrationCountDetailsShared:this.migrationCountDetails;await this.metadataMigrateContentServiceWorkerService.migrate(this.formSettings.toDto(),e),await this.initData(),this.hasElementsToMigrate()?this.props.actionFeedbackContext.displayWarning(this.props.t("Encrypted metadata were partially migrated.")):this.props.actionFeedbackContext.displaySuccess(this.props.t("The encrypted metadata were migrated."))}catch(e){this.props.dialogContext.open($t,{error:e})}this.setState({hasAlreadyBeenValidated:!0,hasMigrationRunOnce:!0})}}render(){const e=this.verifyDataHealth(this.state.settings,this.props.resourceTypes,this.metadataTypesSettings,this.metadataKeys),t=this.hasGlobalError(e),a=this.props.context.siteSettings.isFeatureBeta("metadata"),s=!t&&(a||!this.hasMissingMetadataKeys&&this.hasPendingMigration);return n.createElement("div",{className:"row"},n.createElement("div",{id:"migrate-metadata-settings",className:"main-column"},n.createElement("div",{className:"main-content"},n.createElement("form",{onSubmit:this.handleFormSubmit,"data-testid":"submit-form"},n.createElement("h3",{className:"title"},n.createElement("label",null,n.createElement(f.x6,null,"Migrate metadata"))),n.createElement("p",{className:"description"},n.createElement(f.x6,null,"Initiate a migration to convert cleartext metadata to encrypted metadata.")),n.createElement("h4",null,n.createElement(f.x6,null,"Summary")),n.createElement("div",{className:"feedback-card"},this.state.isReady&&this.hasPendingMigration&&n.createElement(Qh,{name:"warning"}),this.state.isReady&&!this.hasPendingMigration&&n.createElement(Qh,{name:"success"}),n.createElement("div",{className:"migration-status-information"},n.createElement("ul",null,n.createElement("li",{className:"migration-status"},n.createElement("span",{className:"label"},n.createElement(f.x6,null,"Migration status")),n.createElement("span",{className:"value"},this.migrationStatus)),n.createElement("li",{className:"migration-resources-count"},n.createElement("span",{className:"label"},n.createElement(f.x6,null,"Resources")),n.createElement("span",{className:"value"},this.hasPendingResourcesMigration?n.createElement(n.Fragment,null,this.props.t("{{count}} to be migrated",{count:this.totalResources})," (",this.props.t("{{count}} shared resources",{count:this.totalSharedResources}),","," ",this.props.t("{{count}} personal resources",{count:this.totalPersonalResources}),")"):n.createElement(f.x6,null,"All migrated")))))),n.createElement("h4",null,n.createElement(f.x6,null,"Items to migrate")),n.createElement("div",{className:"togglelist"},n.createElement("span",{className:`input toggle-switch form-element ${!t&&e?.hasError("migrate_resources_to_v5")&&"warning"}`},n.createElement("input",{id:"migrateResourcesInput",type:"checkbox",name:"migrate_resources_to_v5",className:"toggle-switch-checkbox checkbox",onChange:this.handleInputChange,checked:this.state.settings.migrate_resources_to_v5,disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"migrateResourcesInput"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Resources:")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"Name, Username, URI, Cleartext description.")),!t&&e?.hasError("migrate_resources_to_v5")&&n.createElement("div",{className:"warning"},e?.hasError("migrate_resources_to_v5","allow_creation_of_v5_resources")&&n.createElement("div",{className:"warning-message"},n.createElement(f.x6,null,"Resource types v5 creation is not allowed.")),e?.hasError("migrate_resources_to_v5","resource_types_v5_deleted")&&n.createElement("div",{className:"warning-message"},n.createElement(f.x6,null,"Resources will not be migrated as no content types with encrypted metadata is allowed.")),e?.hasError("migrate_resources_to_v5","resource_types_v5_partially_deleted")&&n.createElement("div",{className:"warning-message"},n.createElement(f.x6,null,"Not all resources will be migrated, some corresponding content types are not active.")))))),n.createElement("h4",null,n.createElement(f.x6,null,"Migration scope")),n.createElement("div",{className:"radiolist-alt"},n.createElement("div",{className:`input radio ${this.state.settings.migrate_personal_content&&"checked"} ${this.hasAllInputDisabled()&&"disabled"}`},n.createElement("input",{type:"radio",value:"all-content",onChange:this.handleMigrateScopeInputChange,name:"migrate_personal_content",checked:this.state.settings.migrate_personal_content,id:"migrateScopeAllContentInput",disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"migrateScopeAllContentInput"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"All content")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"All resources including the private ones.")))),n.createElement("div",{className:`input radio ${!this.state.settings.migrate_personal_content&&"checked"} ${this.hasAllInputDisabled()&&"disabled"}`},n.createElement("input",{type:"radio",value:"shared-only",onChange:this.handleMigrateScopeInputChange,name:"migrate_personal_content",checked:!this.state.settings.migrate_personal_content,id:"migrateScopeSharedContentInput",disabled:this.hasAllInputDisabled()}),n.createElement("label",{htmlFor:"migrateScopeSharedContentInput"},n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Shared content only")),n.createElement("span",{className:"info"},n.createElement(f.x6,null,"Only shared resources are migrated."))))))),t&&this.hasPendingMigration&&n.createElement("div",{className:"error message"},n.createElement("div",null,n.createElement(f.x6,null,"No active metadata keys available."))),!t&&this.hasMissingMetadataKeys&&n.createElement("div",{className:"error message"},n.createElement("div",null,n.createElement(f.x6,null,"You lack access to the shared metadata key.")," ",n.createElement(f.x6,null,"Please ask another administrator to share it with you."))),s&&n.createElement("div",{className:"warning message"},a&&n.createElement("div",{className:"form-banner"},n.createElement("b",null,n.createElement(f.x6,null,"Warning:"))," ",n.createElement(f.x6,null,"Your current API version includes beta support for encrypted metadata and new resource types.")," ",n.createElement(f.x6,null,"To ensure stability and avoid potential issues, upgrade to the latest version before enabling these features.")),!this.hasMissingMetadataKeys&&this.hasPendingMigration&&n.createElement("div",null,n.createElement("p",null,n.createElement("b",null,n.createElement(f.x6,null,"Warning:"))," ",n.createElement(f.x6,null,"If you have integrations, you will have to make sure they are updated before triggering the migration."))))),n.createElement("div",{className:"actions-wrapper"},n.createElement("button",{type:"button",className:"button primary",disabled:this.state.isProcessing||t||this.hasMissingMetadataKeys,onClick:this.handleFormSubmit},n.createElement("span",null,n.createElement(f.x6,null,"Migrate")))),Xa(n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"Need help?")),n.createElement("p",null,n.createElement(f.x6,null,"For more information about the content type support and migration, checkout the dedicated page on the official website.")),n.createElement("a",{className:"button",target:"_blank",rel:"noopener noreferrer",href:"https://passbolt.com/docs/admin/metadata-encryption/migrate-metadata/"},n.createElement(jt,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}ig.propTypes={context:i().object,actionFeedbackContext:i().object,dialogContext:i().object,createPortal:i().func,metadataSettingsServiceWorkerService:i().object,metadataKeysServiceWorkerService:i().object,metadataMigrateContentServiceWorkerService:i().object,resourceTypes:i().instanceOf(Ep),t:i().func};const rg=N(m(h(nh(h((0,f.CI)("common")(ig)))))),og={passwordV4:[ju,Lu],totpV4:[zu],passwordV5:[Ku,Vu],totpV5:[Bu],customFieldsV5:[Wu],noteV5:[Hu],pinCodeV5:[$u]},lg={passwordV4:[ju,Lu,qu],totpV4:[zu,qu],passwordV5:[Ku,Vu,Gu],totpV5:[Bu,Gu],customFieldsV5:[Wu],noteV5:[Hu],pinCodeV5:[$u]};class cg extends he{constructor(e,t){super(e,t),this._props.resource_types&&(this._resource_types=new Ep(this._props.resource_types))}static getSchema(){return{type:"object",required:["password_v4","password_v5","totp_v4","totp_v5","custom_fields_v5","note_v5","pin_code_v5","password_v4_count","password_v5_count","totp_v4_count","totp_v5_count","custom_fields_v5_count","note_v5_count","pin_code_v5_count","resource_types","has_v4_resource_types","has_v5_resource_types"],properties:{password_v4:{type:"boolean"},password_v5:{type:"boolean"},totp_v4:{type:"boolean"},totp_v5:{type:"boolean"},custom_fields_v5:{type:"boolean"},note_v5:{type:"boolean"},pin_code_v5:{type:"boolean"},password_v4_count:{type:"integer"},password_v5_count:{type:"integer"},totp_v4_count:{type:"integer"},totp_v5_count:{type:"integer"},custom_fields_v5_count:{type:"integer"},note_v5_count:{type:"integer"},pin_code_v5_count:{type:"integer"},has_v4_resource_types:{type:"boolean"},has_v5_resource_types:{type:"boolean"},resource_types:Ep.getSchema()}}}static createFormResourcesTypesCollection(e){if(!(e instanceof Ep))throw new TypeError("The parameter 'resource_types' is not a valid 'ResourceTypesCollection' type.");const t=e.items.filter(e=>!e.isDeleted()),a=new Ep(t),n=this._areAllResourceTypesAvailable(og.passwordV4,a),s=this._areAllResourceTypesAvailable(og.passwordV5,a),i=this._areAllResourceTypesAvailable(og.totpV4,a),r=this._areAllResourceTypesAvailable(og.totpV5,a),o=this._areAllResourceTypesAvailable(og.customFieldsV5,a),l=this._areAllResourceTypesAvailable(og.noteV5,a),c=this._areAllResourceTypesAvailable(og.pinCodeV5,a),m=this._getResourcesCountForResourceTypeFamily(lg.passwordV4,e),d=this._getResourcesCountForResourceTypeFamily(lg.passwordV5,e),u=this._getResourcesCountForResourceTypeFamily(lg.totpV4,e),p=this._getResourcesCountForResourceTypeFamily(lg.totpV5,e),h=this._getResourcesCountForResourceTypeFamily(lg.customFieldsV5,a),g=this._getResourcesCountForResourceTypeFamily(lg.noteV5,e),y=this._getResourcesCountForResourceTypeFamily(lg.pinCodeV5,e),b=e.hasSomeOfVersion("v4"),f=e.hasSomeOfVersion("v5");return new cg({password_v4:n,password_v5:s,totp_v4:i,totp_v5:r,custom_fields_v5:o,note_v5:l,pin_code_v5:c,password_v4_count:m,password_v5_count:d,totp_v4_count:u,totp_v5_count:p,note_v5_count:g,pin_code_v5_count:y,custom_fields_v5_count:h,has_v4_resource_types:b,has_v5_resource_types:f,resource_types:e})}static _getResourcesCountForResourceTypeFamily(e,t){let a=0;for(let n=0;nt.hasOneWithSlug(e))}validateBuildRules(){let e=null;if(!this._props.password_v4&&this._props.password_v4_count>0&&(e=e||new X,e.addError("password_v4","has_content","Password content type is disabled but there are existing password resources.")),!this._props.totp_v4&&this._props.totp_v4_count>0&&(e=e||new X,e.addError("totp_v4","has_content","TOTP content type is disabled but there are existing TOTP resources.")),!this._props.password_v5&&this._props.password_v5_count>0&&(e=e||new X,e.addError("password_v5","has_content","Password content type is disabled but there are existing password resources.")),!this._props.totp_v5&&this._props.totp_v5_count>0&&(e=e||new X,e.addError("totp_v5","has_content","TOTP content type is disabled but there are existing TOTP resources.")),!this._props.custom_fields_v5&&this._props.custom_fields_v5_count>0&&(e=e||new X,e.addError("custom_fields_v5","has_content","Custom fields content type is disabled but there are existing custom fields resources.")),!this._props.note_v5&&this._props.note_v5_count>0&&(e=e||new X,e.addError("note_v5","has_content","Note content type is disabled but there are existing note resources.")),!this._props.pin_code_v5&&this._props.pin_code_v5_count>0&&(e=e||new X,e.addError("pin_code_v5","has_content","Pin code content type is disabled but there are existing pin code resources.")),!(this._props.password_v4||this._props.totp_v4||this._props.password_v5||this._props.totp_v5||this._props.note_v5||this._props.pin_code_v5)){const t="At least one content type should be allowed",a="minimum_requirement";e=e||new X,e.addError("password_v4",a,t),e.addError("totp_v4",a,t),e.addError("password_v5",a,t),e.addError("totp_v5",a,t),e.addError("custom_fields_v5",a,t),e.addError("note_v5",a,t),e.addError("pin_code_v5",a,t)}if(e)throw e}verifyHealth(e,t){if(void 0===e)return null;if(void 0===t)return null;if(!(e instanceof Mu))throw new TypeError("The parameter 'metadataTypesSettings' is not a valid 'MetadataTypesSettingsEntity' type.");if(!(t instanceof Bp))throw new TypeError("The parameter 'metadataKeysCollection' is not a valid 'MetadataKeysCollection' type.");let a=null;!e.allowCreationOfV4Resources||this._props.password_v4||this._props.totp_v4||(a=new X,a.addError("password_v4","is_creation_alowed","V4 resource creation is enabled but password content type is disabled."),a.addError("totp_v4","is_creation_alowed","V4 resource creation is enabled but TOTP content type is disabled.")),!e.allowCreationOfV4Resources&&this._props.password_v4&&(a=a||new X,a.addError("password_v4","is_creation_not_alowed","Creation of resource type v4 is not allowed.")),!e.allowCreationOfV4Resources&&this._props.totp_v4&&(a=a||new X,a.addError("totp_v4","is_creation_not_alowed","Creation of resource type v4 is not allowed.")),!e.allowCreationOfV5Resources||this._props.password_v5||this._props.totp_v5||this._props.custom_fields_v5||this._props.note_v5||this._props.pin_code_v5||(a=a||new X,a.addError("password_v5","is_creation_alowed","V5 resource creation is enabled but password content type is disabled."),a.addError("totp_v5","is_creation_alowed","V5 resource creation is enabled but TOTP content type is disabled."),a.addError("custom_fields_v5","is_creation_alowed","V5 resource creation is enabled but custom fields content type is disabled."),a.addError("note_v5","is_creation_alowed","V5 resource creation is enabled but note content type is disabled."),a.addError("pin_code_v5","is_creation_alowed","V5 resource creation is enabled but pin code content type is disabled.")),!e.allowCreationOfV5Resources&&this._props.password_v5&&(a=a||new X,a.addError("password_v5","is_creation_not_alowed","Creation of resource type v5 is not allowed.")),!e.allowCreationOfV5Resources&&this._props.totp_v5&&(a=a||new X,a.addError("totp_v5","is_creation_not_alowed","Creation of resource type v5 is not allowed.")),!e.allowCreationOfV5Resources&&this._props.note_v5&&(a=a||new X,a.addError("note_v5","is_creation_not_alowed","Creation of resource type v5 is not allowed.")),!e.allowCreationOfV5Resources&&this._props.custom_fields_v5&&(a=a||new X,a.addError("custom_fields_v5","is_creation_not_alowed","Creation of resource type v5 is not allowed.")),!e.allowCreationOfV5Resources&&this._props.pin_code_v5&&(a=a||new X,a.addError("pin_code_v5","is_creation_not_alowed","Creation of resource type v5 is not allowed."));const n=t.items.filter(e=>!e.expired);return 0===n.length&&this._props.password_v5&&(a=a||new X,a.addError("password_v5","active_metadata_key","No active metadata key defined.")),0===n.length&&this._props.totp_v5&&(a=a||new X,a.addError("totp_v5","active_metadata_key","No active metadata key defined.")),0===n.length&&this._props.custom_fields_v5&&(a=a||new X,a.addError("custom_fields_v5","active_metadata_key","No active metadata key defined.")),0===n.length&&this._props.note_v5&&(a=a||new X,a.addError("note_v5","active_metadata_key","No active metadata key defined.")),0===n.length&&this._props.pin_code_v5&&(a=a||new X,a.addError("pin_code_v5","active_metadata_key","No active metadata key defined.")),a}toFormDto(){return{password_v4:this._props.password_v4,password_v5:this._props.password_v5,totp_v4:this._props.totp_v4,totp_v5:this._props.totp_v5,custom_fields_v5:this._props.custom_fields_v5,note_v5:this._props.note_v5,pin_code_v5:this._props.pin_code_v5,password_v4_count:this._props.password_v4_count,password_v5_count:this._props.password_v5_count,totp_v4_count:this._props.totp_v4_count,totp_v5_count:this._props.totp_v5_count,custom_fields_v5_count:this._props.custom_fields_v5_count,note_v5_count:this._props.note_v5_count,pin_code_v5_count:this._props.pin_code_v5_count,has_v4_resource_types:this._props.has_v4_resource_types,has_v5_resource_types:this._props.has_v5_resource_types,resource_types:this._resource_types}}toResourceTypesCollection(){const e=this._resource_types.items.filter(e=>this._props.password_v4&&e.isV4()&&e.hasPassword()&&!e.hasTotp()||this._props.totp_v4&&e.isV4()&&!e.hasPassword()&&e.hasTotp()||this._props.totp_v4&&this._props.password_v4&&e.isV4()&&e.hasPassword()&&e.hasTotp()||this._props.password_v5&&e.isV5()&&e.hasPassword()&&!e.hasTotp()||this._props.totp_v5&&e.isV5()&&!e.hasPassword()&&e.hasTotp()||this._props.totp_v5&&this._props.password_v5&&e.isV5()&&e.hasPassword()&&e.hasTotp()||this._props.custom_fields_v5&&e.slug===Wu||this._props.note_v5&&e.slug===Hu||this._props.pin_code_v5&&e.slug===$u),t=this._resource_types.items.filter(t=>!e.some(e=>t.id===e.id)),a=e.filter(e=>e.isDeleted()),n=t.filter(e=>!e.isDeleted()),s=Ds.c9.now().toISO();for(let e=0;ethis.formSettings?.validate());verifyDataHealth=(0,po.A)((e,t,a)=>this.formSettings?.verifyHealth(t,a));hasSettingsChanges=(0,po.A)((e,t,a)=>this.originalSettings?.hasDiffProps(this.formSettings));handleInputChange(e){if(this.hasAllInputDisabled())return;const{type:t,checked:a,value:n,name:s}=e.target,i="checkbox"===t?a:n;this.setFormPropertyValue(s,i)}setFormPropertyValue(e,t){this.formSettings.set(e,t,{validate:!1}),this.setState({settings:this.formSettings.toFormDto()})}hasAllInputDisabled(){return this.state.isProcessing}handleFormSubmit(e){e.preventDefault(),this.save()}isInputDisabled(e,t){return this.hasAllInputDisabled()||e>0&&t}async save(){if(this.state.isProcessing)return;const e=this.validateForm(this.state.settings);if(e?.hasErrors())this.setState({hasAlreadyBeenValidated:!0});else{this.setState({isProcessing:!0});try{const e=this.formSettings.toResourceTypesCollection();await this.resourceTypesServiceWorkerService.updateAllDeletedStatus(e);const t=await this.resourceTypesServiceWorkerService.findAllByDeletedAndNonDeleted();this.originalSettings=mg.createFormResourcesTypesCollection(t),this.formSettings=new mg(this.originalSettings.toFormDto()),await this.props.actionFeedbackContext.displaySuccess(this.props.t("The allowed content types were updated."))}catch(e){console.error(e),this.props.dialogContext.open($t,{error:e})}this.setState({hasAlreadyBeenValidated:!0,isProcessing:!1,settings:this.formSettings.toFormDto()})}}addTooltipOnDisabledElement(e,t){return t?n.createElement(Mt,{message:"You cannot disable a content type that is in use.",direction:"right"},e):n.createElement(n.Fragment,null,e)}render(){const e=this.state.hasAlreadyBeenValidated?this.validateForm(this.state.settings):null,t=this.verifyDataHealth(this.state.settings,this.metadataTypesSettings,this.metadataKeys),a=this.hasSettingsChanges(this.originalSettings,this.formSettings,this.state.settings),s=this.props.context.siteSettings.isFeatureBeta("metadata"),i=s||a;return n.createElement("div",{className:"row"},n.createElement("div",{id:"allow-content-types",className:"main-column"},n.createElement("div",{className:"main-content"},n.createElement("form",{onSubmit:this.handleFormSubmit,"data-testid":"submit-form"},n.createElement("h3",{className:"title"},n.createElement("label",null,n.createElement(f.x6,null,"Allow content types"))),this.state.settings.has_v5_resource_types&&n.createElement(n.Fragment,null,n.createElement("h4",{className:"no-border"},n.createElement(f.x6,null,"Encrypted metadata")),n.createElement("p",{className:"description"},n.createElement(f.x6,null,"Select which content type with encrypted metadata is available for your whole organisation.")),n.createElement("div",{className:"checkboxlist"},n.createElement("span",{className:`input checkbox form-element ${e?.hasError("password_v5")&&"error"} ${!e?.hasError("password_v5")&&t?.hasError("password_v5")&&"warning"}`},n.createElement("input",{type:"checkbox",id:"passwordV5Input",className:"checkbox",name:"password_v5",onChange:this.handleInputChange,checked:this.state.settings.password_v5,disabled:this.isInputDisabled(this.state.settings.password_v5_count,this.state.settings.password_v5)}),n.createElement("label",{htmlFor:"passwordV5Input"},this.addTooltipOnDisabledElement(n.createElement("div",{className:"allow-content-type-item"},n.createElement(hg,null),n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Password")),n.createElement("span",{className:"info"},this.props.t("({{count}} resources)",{count:this.state.settings.password_v5_count}))),this.isInputDisabled(this.state.settings.password_v5_count,this.state.settings.password_v5)),e?.hasError("password_v5","has_content")&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"Password content type is disabled but there are existing password resources.")),e?.hasError("password_v5","minimum_requirement")&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"At least one content type should be allowed")),!e?.hasError("password_v5")&&n.createElement(n.Fragment,null,t?.hasError("password_v5","is_creation_alowed")&&n.createElement("div",{className:"warning-message"},n.createElement(f.x6,null,"V5 resource creation is enabled but password content type is disabled.")),t?.hasError("password_v5","active_metadata_key")&&n.createElement("div",{className:"warning-message"},n.createElement(f.x6,null,"No active metadata key defined.")),t?.hasError("password_v5","is_creation_not_alowed")&&n.createElement("div",{className:"warning-message"},n.createElement(f.x6,null,"Creation of content type v5 is not allowed."))))),n.createElement("span",{className:`input checkbox form-element ${e?.hasError("totp_v5")&&"error"} ${!e?.hasError("totp_v5")&&t?.hasError("totp_v5")&&"warning"}`},n.createElement("input",{type:"checkbox",id:"totpV5Input",className:"checkbox",name:"totp_v5",onChange:this.handleInputChange,checked:this.state.settings.totp_v5,disabled:this.isInputDisabled(this.state.settings.totp_v5_count,this.state.settings.totp_v5)}),n.createElement("label",{htmlFor:"totpV5Input"},this.addTooltipOnDisabledElement(n.createElement("div",{className:"allow-content-type-item"},n.createElement(fg,null),n.createElement("span",{className:"name"},n.createElement(f.x6,null,"TOTP")),n.createElement("span",{className:"info"},this.props.t("({{count}} resources)",{count:this.state.settings.totp_v5_count}))),this.isInputDisabled(this.state.settings.totp_v5_count,this.state.settings.totp_v5)),e?.hasError("totp_v5","has_content")&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"TOTP content type is disabled but there are existing TOTP resources.")),e?.hasError("totp_v5","minimum_requirement")&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"At least one content type should be allowed")),!e?.hasError("totp_v5")&&n.createElement(n.Fragment,null,t?.hasError("totp_v5","is_creation_alowed")&&n.createElement("div",{className:"warning-message"},n.createElement(f.x6,null,"V5 resource creation is enabled but TOTP content type is disabled.")),t?.hasError("totp_v5","active_metadata_key")&&n.createElement("div",{className:"warning-message"},n.createElement(f.x6,null,"No active metadata key defined.")),t?.hasError("totp_v5","is_creation_not_alowed")&&n.createElement("div",{className:"warning-message"},n.createElement(f.x6,null,"Creation of content type v5 is not allowed."))))),n.createElement("span",{className:`input checkbox form-element ${e?.hasError("custom_fields_v5")&&"error"} ${!e?.hasError("custom_fields_v5")&&t?.hasError("custom_fields_v5")&&"warning"}`},n.createElement("input",{type:"checkbox",id:"customFieldsV5Input",className:"checkbox",name:"custom_fields_v5",onChange:this.handleInputChange,checked:this.state.settings.custom_fields_v5,disabled:this.isInputDisabled(this.state.settings.custom_fields_v5_count,this.state.settings.custom_fields_v5)}),n.createElement("label",{htmlFor:"customFieldsV5Input"},this.addTooltipOnDisabledElement(n.createElement("div",{className:"allow-content-type-item"},n.createElement(wg,null),n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Custom fields")),n.createElement("span",{className:"info"},this.props.t("({{count}} resources)",{count:this.state.settings.custom_fields_v5_count}))),this.isInputDisabled(this.state.settings.custom_fields_v5_count,this.state.settings.custom_fields_v5)),e?.hasError("custom_fields_v5","has_content")&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"Custom fields content type is disabled but there are existing custom fields resources.")),e?.hasError("custom_fields_v5","minimum_requirement")&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"At least one content type should be allowed")),!e?.hasError("custom_fields_v5")&&n.createElement(n.Fragment,null,t?.hasError("custom_fields_v5","is_creation_alowed")&&n.createElement("div",{className:"warning-message"},n.createElement(f.x6,null,"V5 resource creation is enabled but custom fields content type is disabled.")),t?.hasError("custom_fields_v5","active_metadata_key")&&n.createElement("div",{className:"warning-message"},n.createElement(f.x6,null,"No active metadata key defined.")),t?.hasError("custom_fields_v5","is_creation_not_alowed")&&n.createElement("div",{className:"warning-message"},n.createElement(f.x6,null,"Creation of content type v5 is not allowed."))))),n.createElement("span",{className:`input checkbox form-element ${e?.hasError("note_v5")&&"error"} ${!e?.hasError("note_v5")&&t?.hasError("note_v5")&&"warning"}`},n.createElement("input",{type:"checkbox",id:"noteV5Input",className:"checkbox",name:"note_v5",onChange:this.handleInputChange,checked:this.state.settings.note_v5,disabled:this.isInputDisabled(this.state.settings.note_v5_count,this.state.settings.note_v5)}),n.createElement("label",{htmlFor:"noteV5Input"},this.addTooltipOnDisabledElement(n.createElement("div",{className:"allow-content-type-item"},n.createElement(xg,null),n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Note")),n.createElement("span",{className:"info"},this.props.t("({{count}} resources)",{count:this.state.settings.note_v5_count}))),this.isInputDisabled(this.state.settings.note_v5_count,this.state.settings.note_v5)),e?.hasError("note_v5","has_content")&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"Note content type is disabled but there are existing note resources.")),e?.hasError("note_v5","minimum_requirement")&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"At least one content type should be allowed")),!e?.hasError("note_v5")&&n.createElement(n.Fragment,null,t?.hasError("note_v5","is_creation_alowed")&&n.createElement("div",{className:"warning-message"},n.createElement(f.x6,null,"V5 resource creation is enabled but note content type is disabled.")),t?.hasError("note_v5","active_metadata_key")&&n.createElement("div",{className:"warning-message"},n.createElement(f.x6,null,"No active metadata key defined.")),t?.hasError("note_v5","is_creation_not_alowed")&&n.createElement("div",{className:"warning-message"},n.createElement(f.x6,null,"Creation of content type v5 is not allowed."))))),n.createElement("span",{className:`input checkbox form-element ${e?.hasError("pin_code_v5")&&"error"} ${!e?.hasError("pin_code_v5")&&t?.hasError("pin_code_v5")&&"warning"}`},n.createElement("input",{type:"checkbox",id:"pinCodeV5Input",className:"checkbox",name:"pin_code_v5",onChange:this.handleInputChange,checked:this.state.settings.pin_code_v5,disabled:this.isInputDisabled(this.state.settings.pin_code_v5_count,this.state.settings.pin_code_v5)}),n.createElement("label",{htmlFor:"pinCodeV5Input"},this.addTooltipOnDisabledElement(n.createElement("div",{className:"allow-content-type-item"},n.createElement(Ng,null),n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Pin code")),n.createElement("span",{className:"info"},this.props.t("({{count}} resources)",{count:this.state.settings.pin_code_v5_count}))),this.isInputDisabled(this.state.settings.pin_code_v5_count,this.state.settings.pin_code_v5)),e?.hasError("pin_code_v5","has_content")&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"PIN code content type is disabled but there are existing PIN code resources.")),e?.hasError("pin_code_v5","minimum_requirement")&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"At least one content type should be allowed")),!e?.hasError("pin_code_v5")&&n.createElement(n.Fragment,null,t?.hasError("pin_code_v5","is_creation_alowed")&&n.createElement("div",{className:"warning-message"},n.createElement(f.x6,null,"V5 resource creation is enabled but PIN code content type is disabled.")),t?.hasError("pin_code_v5","active_metadata_key")&&n.createElement("div",{className:"warning-message"},n.createElement(f.x6,null,"No active metadata key defined.")),t?.hasError("pin_code_v5","is_creation_not_alowed")&&n.createElement("div",{className:"warning-message"},n.createElement(f.x6,null,"Creation of content type v5 is not allowed."))))))),this.state.settings.has_v4_resource_types&&n.createElement(n.Fragment,null,n.createElement("h4",{className:`${!this.state.settings.has_password_v5&&"no-border"}`},n.createElement(f.x6,null,"Legacy cleartext metadata")),n.createElement("p",{className:"description"},n.createElement(f.x6,null,"Select which content type with cleartext metadata is available for your whole organisation.")),n.createElement("div",{className:"checkboxlist"},n.createElement("span",{className:`input checkbox form-element ${e?.hasError("password_v4")&&"error"} ${!e?.hasError("password_v4")&&t?.hasError("password_v4")&&"warning"}`},n.createElement("input",{type:"checkbox",id:"passwordV4Input",className:"checkbox",name:"password_v4",onChange:this.handleInputChange,checked:this.state.settings.password_v4,disabled:this.isInputDisabled(this.state.settings.password_v4_count,this.state.settings.password_v4)}),n.createElement("label",{htmlFor:"passwordV4Input"},this.addTooltipOnDisabledElement(n.createElement("div",{className:"allow-content-type-item"},n.createElement(hg,null),n.createElement("span",{className:"name"},n.createElement(f.x6,null,"Password")),n.createElement("span",{className:"info"},this.props.t("({{count}} resources)",{count:this.state.settings.password_v4_count}))),this.isInputDisabled(this.state.settings.password_v4_count,this.state.settings.password_v4)),e?.hasError("password_v4","has_content")&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"Password content type is disabled but there are existing password resources.")),e?.hasError("password_v4","minimum_requirement")&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"At least one content type should be allowed")),!e?.hasError("password_v4")&&n.createElement(n.Fragment,null,t?.hasError("password_v4","is_creation_alowed")&&n.createElement("div",{className:"warning-message"},n.createElement(f.x6,null,"V4 resource creation is enabled but password content type is disabled.")),t?.hasError("password_v4","is_creation_not_alowed")&&n.createElement("div",{className:"warning-message"},n.createElement(f.x6,null,"Creation of content type v4 is not allowed."))))),n.createElement("span",{className:`input checkbox form-element ${e?.hasError("totp_v4")&&"error"} ${!e?.hasError("totp_v4")&&t?.hasError("totp_v4")&&"warning"}`},n.createElement("input",{type:"checkbox",id:"totpV4Input",className:"checkbox",name:"totp_v4",onChange:this.handleInputChange,checked:this.state.settings.totp_v4,disabled:this.isInputDisabled(this.state.settings.totp_v4_count,this.state.settings.totp_v4)}),n.createElement("label",{htmlFor:"totpV4Input"},this.addTooltipOnDisabledElement(n.createElement("div",{className:"allow-content-type-item"},n.createElement(fg,null),n.createElement("span",{className:"name"},n.createElement(f.x6,null,"TOTP")),n.createElement("span",{className:"info"},this.props.t("({{count}} resources)",{count:this.state.settings.totp_v4_count}))),this.isInputDisabled(this.state.settings.totp_v4_count,this.state.settings.totp_v4)),e?.hasError("totp_v4","has_content")&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"TOTP content type is disabled but there are existing TOTP resources.")),e?.hasError("totp_v4","minimum_requirement")&&n.createElement("div",{className:"error-message"},n.createElement(f.x6,null,"At least one content type should be allowed")),!e?.hasError("totp_v4")&&n.createElement(n.Fragment,null,t?.hasError("totp_v4","is_creation_alowed")&&n.createElement("div",{className:"warning-message"},n.createElement(f.x6,null,"V4 resource creation is enabled but TOTP content type is disabled.")),t?.hasError("totp_v4","is_creation_not_alowed")&&n.createElement("div",{className:"warning-message"},n.createElement(f.x6,null,"Creation of content type v4 is not allowed."))))))))),i&&n.createElement("div",{className:"warning message"},s&&n.createElement("div",{className:"form-banner"},n.createElement("b",null,n.createElement(f.x6,null,"Warning:"))," ",n.createElement(f.x6,null,"Your current API version includes beta support for encrypted metadata and new resource types.")," ",n.createElement(f.x6,null,"To ensure stability and avoid potential issues, upgrade to the latest version before enabling these features.")),a&&n.createElement("div",null,n.createElement("p",null,n.createElement("b",null,n.createElement(f.x6,null,"Warning:"))," ",n.createElement(f.x6,null,"Don't forget to save your settings to apply your modification."))))),n.createElement("div",{className:"actions-wrapper"},n.createElement("button",{type:"button",className:"button primary",disabled:this.state.isProcessing,onClick:this.handleFormSubmit},n.createElement("span",null,n.createElement(f.x6,null,"Save")))),Xa(n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"Need help?")),n.createElement("p",null,n.createElement(f.x6,null,"For more information about the content type support and migration, checkout the dedicated page on the official website.")),n.createElement("a",{className:"button",target:"_blank",rel:"noopener noreferrer",href:"https://passbolt.com/docs/admin/metadata-encryption/allowed-content-types/"},n.createElement(jt,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}Tg.propTypes={context:i().object,dialogContext:i().object,actionFeedbackContext:i().object,createPortal:i().func,resourceTypesServiceWorkerService:i().object,metadataKeysServiceWorkerService:i().object,metadataSettingsServiceWorkerService:i().object,t:i().func};const Ag=N(m(h((0,f.CI)("common")(Tg))));class Ig extends n.PureComponent{get pill(){return this.props.isBeta?n.createElement("span",{className:"chips beta"},"beta"):this.props.isNew?n.createElement("span",{className:"chips new"},"new"):n.createElement(n.Fragment,null)}get hasAPill(){return Boolean(this.props.isBeta||this.props.isNew)}render(){return n.createElement("button",{type:"button",className:"button-transparent card",onClick:this.props.onClick},this.props.icon,n.createElement("div",{className:"card-information"},n.createElement("span",{className:`title-wrapper ${this.hasAPill&&"with-pill"}`},n.createElement("span",{className:"title",title:this.props.title},this.props.title,this.pill),this.props.proTeasing&&n.createElement(Ea,null)),this.props.description&&n.createElement("span",{className:"info",title:this.props.description},this.props.description)))}}Ig.defaultProps={isBeta:!1,proTeasing:!1},Ig.propTypes={icon:i().object.isRequired,title:i().string.isRequired,description:i().string,isBeta:i().bool.isRequired,isNew:i().bool,onClick:i().func,proTeasing:i().bool.isRequired};const Rg=Ig;var Pg;function Dg(){return Dg=Object.assign?Object.assign.bind():function(e){for(var t=1;tn.createElement(Rg,{key:e.title,icon:e.icon,title:e.title,description:e.description,onClick:()=>this.handleClickOn(e),isBeta:this.isDisplayedAsBeta(e),isNew:Boolean(e.isNew),proTeasing:e.displayProTeasingIcon}))))))}}mb.propTypes={context:i().object,navigationContext:i().object,administrationEncryptedMetadataGettingStartedContext:i().object,metadataGettingStartedSettings:i().object,t:i().func};const db=N(ga(Ke((0,f.CI)("common")(mb))));var ub;function pb(){return pb=Object.assign?Object.assign.bind():function(e){for(var t=1;t{const n=e?.profile;return n&&(Boolean(n.first_name)||Boolean(n.last_name))?a.withUsername?`${n.first_name} ${n.last_name} (${e.username})`:`${n.first_name} ${n.last_name}`:t("Unknown user")};class Fb extends n.Component{render(){return n.createElement(n.Fragment,null,this.props.shouldDisplayWarning&&n.createElement("div",{className:"sidebar-help-section warning message"},n.createElement("div",{className:"form-banner"},n.createElement("p",null,n.createElement("b",null,n.createElement(f.x6,null,"Warning:"))," ",n.createElement(f.x6,null,"if you think the secret has been compromised please regenerate and update it in your provider settings.")))),n.createElement("div",{className:"sidebar-help-section"},n.createElement("h3",null,n.createElement(f.x6,null,"Need help?")),n.createElement("p",null,n.createElement(f.x6,null,"For more information about SCIM, checkout the dedicated page on the official website.")),n.createElement("a",{className:"button",target:"_blank",rel:"noopener noreferrer",href:"https://www.passbolt.com/docs/admin/user-provisioning/scim"},n.createElement(jt,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))))}}Fb.propTypes={shouldDisplayWarning:i().bool.isRequired};const jb=Fb;class Lb{constructor(e){this.port=e}async findAll(){const e=await this.port.request("passbolt.role.get-all");return new nm(e)}async updateResourceLocalStorage(){await this.port.request("passbolt.role.update-local-storage")}}function qb(){return qb=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},getAllRoles:()=>{},refreshRoles:()=>{}});class Kb extends n.Component{constructor(e){super(e),this.state=this.defaultState(),this.runningLocalStorageUpdatePromise=null,this.roleServiceWorkerService=new Lb(e.context.port),this.initEventHandlers()}defaultState(){return{rolesCollection:null,getRole:this.getRole.bind(this),getAllRoles:this.getAllRoles.bind(this),refreshRoles:this.refreshRoles.bind(this)}}componentDidMount(){this.props.context.storage.onChanged.addListener(this.handleStorageChange)}componentWillUnmount(){this.props.context.storage.onChanged.removeListener(this.handleStorageChange)}initEventHandlers(){this.handleStorageChange=this.handleStorageChange.bind(this)}handleStorageChange(e){e[this.storageKey]&&this.set(e[this.storageKey].newValue)}set(e){const t=new nm(e);this.setState({rolesCollection:t})}get storageKey(){return"roles"}getRole(e){const t=this.state.rolesCollection?.getById(e);return t||(this.refreshRoles(),null)}async loadLocalStorage(){const e=await this.props.context.storage.local.get([this.storageKey]);e[this.storageKey]?this.set(e[this.storageKey]):this.refreshRoles()}getAllRoles(){return this.state.rolesCollection?this.state.rolesCollection:(this.loadLocalStorage(),null)}async refreshRoles(){null===this.runningLocalStorageUpdatePromise?(this.runningLocalStorageUpdatePromise=this.roleServiceWorkerService.updateResourceLocalStorage(),await this.runningLocalStorageUpdatePromise,this.runningLocalStorageUpdatePromise=null):await this.runningLocalStorageUpdatePromise}render(){return n.createElement(zb.Provider,{value:this.state},this.props.children)}}Kb.propTypes={context:i().any,children:i().any},Kb.displayName="RoleContextProvider",N(Kb);class Vb extends n.Component{originalSettings=null;formSettings=null;scimSettingsService=null;constructor(e){super(e),this.state=this.defaultState,this.bindCallbacks(),this.scimSettingsService=e.scimSettingsServiceWorkerService??new Mb(this.props.context.port)}get defaultState(){return{isProcessing:!0,hasAlreadyBeenValidated:!1,enabled:!1,settings:null}}bindCallbacks(){this.handleFormSubmit=this.handleFormSubmit.bind(this),this.handleInputChange=this.handleInputChange.bind(this),this.save=this.save.bind(this),this.handleToggleEnabled=this.handleToggleEnabled.bind(this),this.handleCopyScimUrl=this.handleCopyScimUrl.bind(this),this.handleCopySecretToken=this.handleCopySecretToken.bind(this),this.handleRegenerateSecretToken=this.handleRegenerateSecretToken.bind(this)}async componentDidMount(){this.props.context.users||await this.props.context.port.request("passbolt.users.update-local-storage"),await this.findScimSettings(),this.setState({isProcessing:!1})}componentWillUnmount(){this.clearContext()}get adminUsers(){const e=this.props.roles.items.filter(e=>e.isAdmin())?.[0]||null,t=this.props.context.users;return null!==t&&e?t.filter(t=>!0===t.active&&t.role_id===e.id):[]}get adminUsersForSelect(){return this.adminUsers&&this.adminUsers.map(e=>({value:e.id,label:Ub(e,this.props.t,{withUsername:!0})}))}async findScimSettings(){this.setState({isProcessing:!0});try{const e=await this.scimSettingsService.findSettings();e&&(this.originalSettings=new Ob(e,{validate:!1}),this.formSettings=new Ob(e,{validate:!1}),this.setState({settings:this.formSettings.toDto(),enabled:!0}))}catch(e){await this.handleUnexpectedError(e),this.setDefaultSettings()}this.setState({isProcessing:!1})}setDefaultSettings(){this.formSettings=Ob.createFromDefault(this.adminUsers[0].id),this.setState({settings:this.formSettings.toDto()})}handleToggleEnabled(){this.state.enabled||(this.formSettings=Ob.createFromDefault(this.adminUsers[0].id),this.setState({settings:this.formSettings.toDto()})),this.setState({enabled:!this.state.enabled})}hasSettingsChanges=(0,po.A)((e,t,a)=>e?.hasDiffProps(t)||!1);handleInputChange(e){if(this.hasAllInputDisabled())return;const{type:t,checked:a,name:n}=e.target,s="checkbox"===t?a:e.target.value;this.setFormPropertyValue(n,s)}setFormPropertyValue(e,t){this.formSettings.set(e,t,{validate:!1}),this.setState({settings:this.formSettings.toDto()})}hasAllInputDisabled(){return this.state.isProcessing}async handleCopyScimUrl(){await this.props.clipboardContext.copy(this.scimUrl,this.props.t("The SCIM URL has been copied to the clipboard."))}async handleCopySecretToken(){await this.props.clipboardContext.copy(this.state.settings.secret_token,this.props.t("The SCIM secret token has been copied to the clipboard."))}handleRegenerateSecretToken(){const e=Pb.generateScimSecretToken();this.setFormPropertyValue("secret_token",e)}handleFormSubmit(e){e.preventDefault(),this.save()}async save(){if(this.state.isProcessing)return;this.setState({isProcessing:!0});const e=this.validateForm();if(e?.hasErrors())this.setState({isProcessing:!1,hasAlreadyBeenValidated:!0});else{try{const e=await this.saveScimSettings();this.formSettings=e?new Ob(e,{validate:!1}):null,this.originalSettings=e?new Ob(this.formSettings.toDto(),{validate:!1}):null,this.setState({settings:e?this.formSettings.toDto():null,enabled:null!==e}),await this.props.actionFeedbackContext.displaySuccess(this.props.t("The SCIM settings were updated."))}catch(e){await this.handleUnexpectedError(e)}this.setState({isProcessing:!1})}}validateForm(){return this.formSettings?this.formSettings.validate():null}async saveScimSettings(){if(this.state.enabled){let e;return e=this.originalSettings?await this.scimSettingsService.updateSettings(this.formSettings,this.originalSettings.id):await this.scimSettingsService.createSettings(this.formSettings),e}return this.originalSettings&&await this.scimSettingsService.disableSettings(this.originalSettings.id),null}handleUnexpectedError(e){if(console.error(e),"UserAbortsOperationError"!==e.name)return this.props.dialogContext.open($t,{error:e})}clearContext(){this.setState(this.defaultState)}isSecretTokenExpired(){const e=this.state.settings?.expired;return!!e&&Ds.c9.fromISO(e)n.createElement(e,qb({roleContext:t,roles:t.getAllRoles()},this.props)))}}}((0,f.CI)("common")(Vb)))))));class Bb extends n.Component{render(){return n.createElement("div",{className:"row"},n.createElement("div",{className:"scim-teasing main-column"},n.createElement("div",{className:"main-content"},n.createElement("h3",{className:"title",id:"scim-title"},n.createElement(f.x6,null,"SCIM"),n.createElement(Ea,{className:"pro-teasing-icon"})),n.createElement("p",null,n.createElement(f.x6,null,"Automate user identity management and provisioning via standardised SCIM integration.")),n.createElement("div",{className:"scim-info"},n.createElement("ul",{className:"scim-description"},n.createElement("li",null,n.createElement(fs,null),n.createElement(f.x6,null,"Efficiently manage user identities in the cloud.")),n.createElement("li",null,n.createElement(fs,null),n.createElement(f.x6,null,"Simplify onboarding and offboarding processes.")),n.createElement("li",null,n.createElement(fs,null),n.createElement(f.x6,null,"Reduce manual administrative overhead and errors."))),n.createElement("div",null,n.createElement("a",{className:"button primary",href:"https://www.passbolt.com/ce-to-pro?utm_campaign=21060976-CE%20to%20Pro&utm_source=product",target:"_blank",rel:"noopener noreferrer"},n.createElement(f.x6,null,"Upgrade to Passbolt Pro")))))))}}Bb.propTypes={context:i().object,t:i().func};const Wb=N((0,f.CI)("common")(Bb));class Hb extends he{static getSchema(){return{type:"object",required:["max_revisions","allow_sharing_revisions"],properties:{id:{type:"string",format:"uuid"},max_revisions:{type:"integer",minimum:1},allow_sharing_revisions:{type:"boolean"}}}}static createFromDefault(e={}){return new Hb({max_revisions:1,allow_sharing_revisions:!1,...e})}get id(){return this._props.id}get maxRevisions(){return this._props.max_revisions}get allowSharingRevisions(){return this._props.allow_sharing_revisions}get isFeatureEnabled(){return this.maxRevisions>1}}const $b=Hb;class Yb{constructor(e){this.port=e}async findSettings(){const e=await this.port.request("passbolt.secret-revisions.find-settings");return new $b(e)}async saveSettings(e){if(!(e instanceof $b))throw new TypeError("The parameter `secretRevisionSettingsEntity` should be of type SecretRevisionsSettingsEntity.");const t=await this.port.request("passbolt.secret-revisions.save-settings",e);return new $b(t)}async deleteSettings(){await this.port.request("passbolt.secret-revisions.delete-settings")}}class Zb extends n.Component{originalSettings=null;formSettings=null;constructor(e){super(e),this.secretRevisionsSettingsServiceWorkerService=new Yb(e.context.port),this.state=this.defaultState,this.bindCallbacks()}get defaultState(){return{isProcessing:!0,hasAlreadyBeenValidated:!1,isFeatureEnabled:!1,settings:{}}}bindCallbacks(){this.handleFormSubmit=this.handleFormSubmit.bind(this),this.handleInputChange=this.handleInputChange.bind(this),this.handleEnableFeature=this.handleEnableFeature.bind(this),this.save=this.save.bind(this)}async componentDidMount(){this.originalSettings=await this.secretRevisionsSettingsServiceWorkerService.findSettings(),this.formSettings=new $b(this.originalSettings.toDto(),{validate:!1});const e=this.formSettings.toDto();this.setState({settings:e,isFeatureEnabled:this.originalSettings.isFeatureEnabled,isProcessing:!1})}validateForm=(0,po.A)(e=>this.formSettings?.validate());hasSettingsChanges=(0,po.A)((e,t)=>this.originalSettings?.hasDiffProps(this.formSettings)||this.originalSettings?.isFeatureEnabled!==t);handleInputChange(e){const{value:t,name:a}=e.target,n=parseInt(t,10)+1;this.setFormPropertyValue(a,n)}setFormPropertyValue(e,t){this.formSettings.set(e,t,{validate:!1}),this.setState({settings:this.formSettings.toDto()})}get maxRevisionsLimit(){return this.props.context.siteSettings.getPluginSettings("secretRevisions")?.maxRevisionsLimit||11}get maxRevisionsLimitToDisplay(){return(this.maxRevisionsLimit-1).toString()}handleEnableFeature(e){const{checked:t}=e.target;t&&1===this.state.settings.max_revisions&&this.setFormPropertyValue("max_revisions",2),this.setState({isFeatureEnabled:t})}hasAllInputDisabled(){return this.state.isProcessing}async handleFormSubmit(e){e.preventDefault(),await this.save()}get hasMaxRevisionsError(){return this.state.settings.max_revisions<2||this.state.settings.max_revisions>this.maxRevisionsLimit}async save(){if(this.state.isProcessing)return;const e=this.validateForm(this.state.settings);if(e?.hasErrors()||this.hasMaxRevisionsError)this.setState({hasAlreadyBeenValidated:!0});else{this.setState({isProcessing:!0});try{this.state.isFeatureEnabled?this.state.isFeatureEnabled&&await this.saveSettings():await this.deleteSettings(),await this.props.actionFeedbackContext.displaySuccess(this.props.t("The secret history settings were updated."))}catch(e){console.error(e),this.props.dialogContext.open($t,{error:e})}this.setState({hasAlreadyBeenValidated:!0,isProcessing:!1,settings:this.formSettings.toDto()})}}async deleteSettings(){await this.secretRevisionsSettingsServiceWorkerService.deleteSettings(),this.originalSettings=$b.createFromDefault(),this.formSettings=new $b(this.originalSettings.toDto(),{validate:!1})}async saveSettings(){const e=this.formSettings.toDto();this.originalSettings=new $b(e,{validate:!1}),this.originalSettings=await this.secretRevisionsSettingsServiceWorkerService.saveSettings(new $b(e)),this.formSettings=new $b(this.originalSettings.toDto(),{validate:!1})}render(){const e=this.maxRevisionsLimitToDisplay,t=this.state.hasAlreadyBeenValidated?this.validateForm(this.state.settings):null,a=this.hasSettingsChanges(this.state.settings,this.state.isFeatureEnabled),s=t?.hasError("max_revisions")||this.state.hasAlreadyBeenValidated&&this.hasMaxRevisionsError;return n.createElement("div",{className:"row"},n.createElement("div",{id:"secret-history",className:"main-column"},n.createElement("div",{className:"main-content"},n.createElement("form",{onSubmit:this.handleFormSubmit},n.createElement("h3",{id:"secret-history-settings-title",className:"title"},n.createElement("span",{className:"input toggle-switch form-element"},n.createElement("input",{type:"checkbox",className:"toggle-switch-checkbox checkbox",name:"secretHistorySettingsToggle",onChange:this.handleEnableFeature,checked:this.state.isFeatureEnabled,disabled:this.hasAllInputDisabled(),id:"passwordExpirySettingsToggle"}),n.createElement("label",{htmlFor:"passwordExpirySettingsToggle"},n.createElement(f.x6,null,"Secret history")))),!this.state.isFeatureEnabled&&n.createElement("p",{className:"description"},n.createElement(f.x6,null,"No secret history is configured. Enable it to activate and set the number of passwords revisions.")),this.state.isFeatureEnabled&&n.createElement(n.Fragment,null,n.createElement("p",{className:"description"},n.createElement(f.x6,null,"Control how many revisions are retained, enabling users to view and restore historical data.")),n.createElement("div",{className:"input text "+(this.hasAllInputDisabled()?"disabled":"")},n.createElement("h4",null,n.createElement("label",{htmlFor:"configure-secret-history-form-length"},n.createElement(f.x6,null,"History length"))),n.createElement("div",{className:"slider"},n.createElement("input",{name:"max_revisions",min:"1",max:this.maxRevisionsLimit-1,value:this.state.settings.max_revisions-1,step:"1",type:"range",onChange:this.handleInputChange,disabled:this.hasAllInputDisabled()}),n.createElement("input",{id:"configure-secret-history-form-length",type:"number",name:"max_revisions",min:"1",max:this.maxRevisionsLimit-1,value:this.state.settings.max_revisions-1,onChange:this.handleInputChange,disabled:this.hasAllInputDisabled()})),n.createElement("p",{className:"description"},n.createElement(f.x6,null,"This is the number of revisions kept once users have access.")),s&&n.createElement("div",{id:"maxRevisions-error",className:"error-message"},n.createElement(f.x6,null,"The history length must be between 1 and ",{maxRevisionsLimitToDisplay:e},".")))))),a&&n.createElement("div",{className:"warning message"},n.createElement("div",null,n.createElement("p",null,n.createElement("b",null,n.createElement(f.x6,null,"Warning:"))," ",n.createElement(f.x6,null,"Don't forget to save your settings to apply your modification."))))),n.createElement("div",{className:"actions-wrapper"},n.createElement("button",{type:"button",className:"button primary",disabled:this.state.isProcessing,onClick:this.handleFormSubmit},n.createElement("span",null,n.createElement(f.x6,null,"Save")))))}}Zb.propTypes={context:i().object,dialogContext:i().object,actionFeedbackContext:i().object,t:i().func};const Jb=N(m(h((0,f.CI)("common")(Zb))));function Xb(){return Xb=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},close:()=>{}});class ef extends n.Component{constructor(e){super(e),this.state=this.defaultState}get defaultState(){return{announcements:[],show:(e,t)=>{const a=(0,r.A)();return this.setState({announcements:[...this.state.announcements,{key:a,Announcement:e,AnnouncementProps:t}]}),a},close:async e=>await this.setState({announcements:this.state.announcements.filter(t=>e!==t.key)})}}render(){return n.createElement(Qb.Provider,{value:this.state},this.props.children)}}function tf(e){return class extends n.Component{render(){return n.createElement(Qb.Consumer,null,t=>n.createElement(e,Xb({announcementContext:t},this.props)))}}}function af(){return af=Object.assign?Object.assign.bind():function(e){for(var t=1;tn.createElement(t,af({key:e,onClose:()=>this.close(e)},a))),this.props.children)}}nf.propTypes={announcementContext:i().any,children:i().any};const sf=tf(nf);class rf extends n.Component{constructor(e){super(e),this.bindCallbacks()}bindCallbacks(){this.handleGoBack=this.handleGoBack.bind(this)}isCommunityEdition(){return this.props.context.siteSettings.isCommunityEdition}isHomePageSelected(){return Te.HOME===this.props.administrationWorkspaceContext.selectedAdministration||Te.NONE===this.props.administrationWorkspaceContext.selectedAdministration}isMfaSelected(){return Te.MFA===this.props.administrationWorkspaceContext.selectedAdministration}isMfaPolicySelected(){return Te.MFA_POLICY===this.props.administrationWorkspaceContext.selectedAdministration}isPasswordPoliciesSelected(){return Te.PASSWORD_POLICIES===this.props.administrationWorkspaceContext.selectedAdministration}isUserDirectorySelected(){return Te.USER_DIRECTORY===this.props.administrationWorkspaceContext.selectedAdministration}isEmailNotificationsSelected(){return Te.EMAIL_NOTIFICATION===this.props.administrationWorkspaceContext.selectedAdministration}isSubscriptionSelected(){return Te.SUBSCRIPTION===this.props.administrationWorkspaceContext.selectedAdministration}isInternationalizationSelected(){return Te.INTERNATIONALIZATION===this.props.administrationWorkspaceContext.selectedAdministration}isAccountRecoverySelected(){return Te.ACCOUNT_RECOVERY===this.props.administrationWorkspaceContext.selectedAdministration}isSmtpSettingsSelected(){return Te.SMTP_SETTINGS===this.props.administrationWorkspaceContext.selectedAdministration}isSelfRegistrationSelected(){return Te.SELF_REGISTRATION===this.props.administrationWorkspaceContext.selectedAdministration}isSsoSelected(){return Te.SSO===this.props.administrationWorkspaceContext.selectedAdministration}isRbacSelected(){return Te.RBAC===this.props.administrationWorkspaceContext.selectedAdministration}isUserPassphrasePoliciesSelected(){return Te.USER_PASSPHRASE_POLICIES===this.props.administrationWorkspaceContext.selectedAdministration}isPasswordExpirySelected(){return Te.PASSWORD_EXPIRY===this.props.administrationWorkspaceContext.selectedAdministration}isContentTypesEncryptedMetadataSelected(){return Te.CONTENT_TYPES_ENCRYPTED_METADATA===this.props.administrationWorkspaceContext.selectedAdministration}isContentTypesMetadataKeySelected(){return Te.CONTENT_TYPES_METADATA_KEY===this.props.administrationWorkspaceContext.selectedAdministration}isMigrateMetadataSelected(){return Te.MIGRATE_METADATA===this.props.administrationWorkspaceContext.selectedAdministration}isAllowContentTypesSelected(){return Te.ALLOW_CONTENT_TYPES===this.props.administrationWorkspaceContext.selectedAdministration}isGetStartedMetadataSelected(){return Te.METADATA_GETTING_STARTED===this.props.administrationWorkspaceContext.selectedAdministration}isScimSelected(){return Te.SCIM===this.props.administrationWorkspaceContext.selectedAdministration}isSecretHistorySelected(){return Te.SECRET_HISTORY===this.props.administrationWorkspaceContext.selectedAdministration}handleGoBack(){this.props.navigationContext.onGoToPasswordsRequested()}get isHttpError403(){return Te.HTTP_403_ACCESS_DENIED===this.props.administrationWorkspaceContext.selectedAdministration}get isHttpError404(){return Te.HTTP_404_NOT_FOUND===this.props.administrationWorkspaceContext.selectedAdministration}isHealthcheckSelected(){return Te.HEALTHCHECK===this.props.administrationWorkspaceContext.selectedAdministration}render(){return n.createElement("div",{id:"container",className:"page administration"},n.createElement("div",{id:"app",className:"app"},n.createElement(sf,null),n.createElement("div",{className:"panel main"},n.createElement("div",{className:"panel left"},!this.isHttpError403&&n.createElement("div",{className:"sidebar-content"},n.createElement("div",{className:"top-bar-left-navigation"},n.createElement("div",{className:"navigation"},n.createElement("button",{type:"button",className:"button-transparent back",onClick:this.handleGoBack},n.createElement(ph,null)),n.createElement("span",{className:"title administration"},n.createElement(f.x6,null,"Organisation settings")))),n.createElement("div",{className:"sidebar-content-left"},n.createElement(wa,null)))),n.createElement("div",{className:"panel middle"},n.createElement("div",{className:"header"},!this.isHttpError403&&n.createElement(n.Fragment,null,n.createElement("div",{className:"header-left"}),n.createElement("div",{className:"header-right"},n.createElement(Cb,{isUserAdmin:!0,isUserWorkspaceVisible:!0,currentWorkspace:xb}),n.createElement(Zt,{baseUrl:this.props.context.trustedDomain||this.props.context.userSettings.getTrustedDomain(),user:this.props.context.loggedInUser})))),n.createElement("div",{className:"middle-right"},n.createElement("div",{className:"breadcrumbs-and-grid"},n.createElement("div",{className:"top-bar"},n.createElement(on,null)),n.createElement("div",{className:"main-page"},this.isHttpError403&&n.createElement(Od,{errorCode:403}),this.isHttpError404&&n.createElement(Od,{errorCode:404}),this.isHomePageSelected()&&n.createElement(db,null),this.isMfaSelected()&&n.createElement(en,null),this.isMfaPolicySelected()&&(this.isCommunityEdition()?n.createElement(Fc,null):n.createElement(Mc,null)),this.isPasswordPoliciesSelected()&&(this.isCommunityEdition()?n.createElement(ed,null):n.createElement(Xm,null)),this.isUserDirectorySelected()&&(this.isCommunityEdition()?n.createElement(vs,null):n.createElement(gs,null)),this.isEmailNotificationsSelected()&&n.createElement(Ps,null),this.isSubscriptionSelected()&&n.createElement(ti,null),this.isInternationalizationSelected()&&n.createElement(hi,null),this.isAccountRecoverySelected()&&(this.isCommunityEdition()?n.createElement(_r,null):n.createElement(wr,null)),this.isSmtpSettingsSelected()&&n.createElement(jo,null),this.isSelfRegistrationSelected()&&n.createElement(pl,null),this.isSsoSelected()&&(this.isCommunityEdition()?n.createElement(xc,null):n.createElement(kc,null)),this.isRbacSelected()&&n.createElement(jm,null),this.isUserPassphrasePoliciesSelected()&&(this.isCommunityEdition()?n.createElement(yd,null):n.createElement(hd,null)),this.isPasswordExpirySelected()&&n.createElement(Pd,null),this.isHealthcheckSelected()&&n.createElement(Ru,null),this.isContentTypesEncryptedMetadataSelected()&&n.createElement(mh,null),this.isContentTypesMetadataKeySelected()&&n.createElement(Nh,null),this.isMigrateMetadataSelected()&&n.createElement(rg,null),this.isAllowContentTypesSelected()&&n.createElement(Ag,null),this.isGetStartedMetadataSelected()&&n.createElement(Ab,null),this.isScimSelected()&&(this.isCommunityEdition()?n.createElement(Wb,null):n.createElement(Gb,null)),this.isSecretHistorySelected()&&n.createElement(Jb,null))),n.createElement(x.Switch,null,n.createElement(x.Route,{exact:!0,path:["/app/administration","/app/administration/scim-teasing","/app/administration/secret-history"]}),n.createElement(x.Route,null,n.createElement("div",{className:"help-panel"},n.createElement("div",{className:"sidebar-help",id:"administration-help-panel"}),n.createElement(gh,null)))))))))}}rf.propTypes={context:i().any,administrationWorkspaceContext:i().object,navigationContext:i().any};const of=N(Ke(Ne(rf)));class lf extends n.Component{constructor(e){super(e),this.initEventHandlers(),this.createReferences()}initEventHandlers(){this.handleCloseClick=this.handleCloseClick.bind(this),this.handleSignInClick=this.handleSignInClick.bind(this)}createReferences(){this.loginLinkRef=n.createRef()}handleCloseClick(){this.goToLogin()}handleSignInClick(){this.goToLogin()}goToLogin(){this.props.context.port.request("passbolt.tab.reload")}render(){return n.createElement(qt,{title:this.props.t("Session Expired"),onClose:this.handleCloseClick,className:"session-expired-dialog"},n.createElement("div",{className:"form-content"},n.createElement("p",null,n.createElement(f.x6,null,"Your session has expired, you need to sign in."))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement("a",{ref:this.loginLinkRef,onClick:this.handleSignInClick,className:"primary button form",target:"_parent",role:"button",rel:"noopener noreferrer"},n.createElement(f.x6,null,"Sign in"))))}}lf.propTypes={context:i().any,t:i().func};const cf=N((0,x.withRouter)((0,f.CI)("common")(lf)));class mf extends n.Component{constructor(e){super(e),this.bindCallbacks()}bindCallbacks(){this.handleSessionExpiredEvent=this.handleSessionExpiredEvent.bind(this)}componentDidMount(){this.props.context.onExpiredSession(this.handleSessionExpiredEvent)}handleSessionExpiredEvent(){this.props.dialogContext.closeAll(),this.props.dialogContext.open(cf)}render(){return n.createElement(n.Fragment,null)}}mf.propTypes={context:i().any,dialogContext:i().any};const df=N(h(mf));class uf extends n.Component{constructor(e){super(e),this.bindCallbacks()}bindCallbacks(){this.handleClose=this.handleClose.bind(this)}handleClose(){this.props.onClose()}render(){return n.createElement("div",{className:`${this.props.className} announcement`},n.createElement("div",{className:"announcement-content"},this.props.canClose&&n.createElement("button",{type:"button",className:"announcement-close dialog-close button-transparent",onClick:this.handleClose},n.createElement(Rt,{className:"svg-icon"}),n.createElement("span",{className:"visually-hidden"},n.createElement(f.x6,null,"Close"))),this.props.children))}}uf.propTypes={children:i().node,className:i().string,canClose:i().bool,onClose:i().func};const pf=(0,f.CI)("common")(uf);class hf extends n.Component{render(){return n.createElement(pf,{className:"subscription",onClose:this.props.onClose,canClose:!0},n.createElement("p",null,n.createElement(f.x6,null,"Warning:")," ",n.createElement(f.x6,null,"your subscription key will expire")," ",n.createElement("span",{title:this.props.expiry},Hs(this.props.expiry,this.props.t,this.props.context.locale)),".",n.createElement("button",{className:"link",type:"button",onClick:this.props.navigationContext.onGoToAdministrationSubscriptionRequested},n.createElement(f.x6,null,"Manage Subscription"))))}}hf.propTypes={context:i().any,expiry:i().string,navigationContext:i().any,onClose:i().func,t:i().func};const gf=N(Ke(tf((0,f.CI)("common")(hf))));class yf extends n.Component{render(){return n.createElement(pf,{className:"subscription",onClose:this.props.onClose,canClose:!1},n.createElement("p",null,n.createElement(f.x6,null,"Warning:")," ",n.createElement(f.x6,null,"your subscription requires your attention. The stability of the application is at risk."),n.createElement("button",{className:"link",type:"button",onClick:this.props.navigationContext.onGoToAdministrationSubscriptionRequested},n.createElement(f.x6,null,"Manage Subscription"))))}}yf.propTypes={navigationContext:i().any,onClose:i().func,i18n:i().any};const bf=Ke(tf((0,f.CI)("common")(yf)));class ff extends n.Component{render(){return n.createElement(pf,{className:"subscription",onClose:this.props.onClose,canClose:!1},n.createElement("p",null,n.createElement(f.x6,null,"Warning:")," ",n.createElement(f.x6,null,"your subscription key is not valid. The stability of the application is at risk."),n.createElement("button",{className:"link",type:"button",onClick:this.props.navigationContext.onGoToAdministrationSubscriptionRequested},n.createElement(f.x6,null,"Manage Subscription"))))}}ff.propTypes={navigationContext:i().any,onClose:i().func,i18n:i().any};const Ef=Ke(tf((0,f.CI)("common")(ff)));class vf extends n.Component{constructor(e){super(e),this.bindCallbacks()}bindCallbacks(){this.handleAnnouncementSubscriptionEvent=this.handleAnnouncementSubscriptionEvent.bind(this)}componentDidMount(){this.handleAnnouncementSubscriptionEvent()}componentDidUpdate(e){this.handleRefreshSubscriptionAnnouncement(e.context.refreshSubscriptionAnnouncement)}async handleRefreshSubscriptionAnnouncement(e){this.props.context.refreshSubscriptionAnnouncement!==e&&this.props.context.refreshSubscriptionAnnouncement&&(await this.handleAnnouncementSubscriptionEvent(),this.props.context.setContext({refreshSubscriptionAnnouncement:null}))}async handleAnnouncementSubscriptionEvent(){this.hideSubscriptionAnnouncement();try{const e=await this.props.context.onGetSubscriptionKeyRequested();this.isSubscriptionGoingToExpire(e.expiry)&&this.props.announcementContext.show(gf,{expiry:e.expiry})}catch(e){"PassboltSubscriptionError"===e.name?this.props.announcementContext.show(bf):this.props.announcementContext.show(Ef)}}hideSubscriptionAnnouncement(){const e=[gf,bf,Ef];this.props.announcementContext.announcements.forEach(t=>{e.some(e=>e===t.Announcement)&&this.props.announcementContext.close(t.key)})}isSubscriptionGoingToExpire(e){return Ds.c9.fromISO(e)e.startsWith("csrfToken"))?.split("=");return e&&2===e.length?e[1]:null}const e=this.baseUrl.toString(),t="/"===e.slice(-1)?e:`${e}/`,a=await browser.cookies.get({name:"csrfToken",url:t});return a?.value||null}}class _f extends Error{constructor(e,t={}){super(e),this.name="PassboltSubscriptionError",this.subscription=t}}const xf=_f,Sf=class{constructor(e){e.setResourceName("auth"),this.apiClient=new pt(e)}async logout(){const e=this.apiClient.buildUrl(`${this.apiClient.baseUrl}/logout`,{}),t=await this.apiClient.sendRequest("POST",e,null,{redirect:"manual"});if(!t.ok&&0!==t.status)return this._logoutLegacy()}async _logoutLegacy(){const e=this.apiClient.buildUrl(`${this.apiClient.baseUrl}/logout`,{}),t=await this.apiClient.sendRequest("GET",e,null,{redirect:"manual"});if(!t.ok&&0!==t.status)throw new ot("An unexpected error happened during the legacy logout process",{code:t.status})}};class Cf extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.authLogoutService=new Sf(this.getApiClientOptions())}async componentDidMount(){await this.getLoggedInUser();const e=await this.getSiteSettings();await this.getRbacs(e),this.initLocale(),this.removeSplashScreen();const t=document.querySelector(".temporary.skeleton");t&&t.remove()}componentWillUnmount(){clearTimeout(this.scheduledCheckIsAuthenticatedTimeout)}get defaultState(){return{name:"api",loggedInUser:null,rbacs:null,siteSettings:null,trustedDomain:this.baseUrl,basename:new URL(this.baseUrl).pathname,getApiClientOptions:this.getApiClientOptions.bind(this),locale:null,displayTestUserDirectoryDialogProps:{userDirectoryTestResult:null},setContext:e=>{this.setState(e)},onLogoutRequested:()=>this.onLogoutRequested(),onCheckIsAuthenticatedRequested:()=>this.onCheckIsAuthenticatedRequested(),onExpiredSession:this.onExpiredSession.bind(this),onGetSubscriptionKeyRequested:()=>this.onGetSubscriptionKeyRequested(),onRefreshLocaleRequested:this.onRefreshLocaleRequested.bind(this)}}get isReady(){return null!==this.state.loggedInUser&&null!==this.state.rbacs&&null!==this.state.siteSettings&&null!==this.state.locale}get baseUrl(){const e=document.getElementsByTagName("base")&&document.getElementsByTagName("base")[0];return e?e.attributes.href.value.replace(/\/*$/g,""):(console.error("Unable to retrieve the page base tag"),"")}getApiClientOptions(){return(new kf).setBaseUrl(this.state.trustedDomain)}async getLoggedInUser(){const e=this.getApiClientOptions().setResourceName("users"),t=new pt(e),a=(await t.get("me",{"contain[account_recovery_user_setting]":"1"})).body;this.setState({loggedInUser:a})}async getRbacs(e){if(!e.canIUse("rbacs"))return void this.setState({rbacs:new Wc});const t=this.getApiClientOptions(),a=new Hc(t),n=(await a.findMe({ui_action:!0,action:!0})).body,s=new Wc(n,!0);this.setState({rbacs:s})}async getSiteSettings(){const e=this.getApiClientOptions().setResourceName("settings"),t=new pt(e),a=await t.findAll(),n=new er(a.body);return this.setState({siteSettings:n}),n}async initLocale(){const e=await this.getUserLocale();if(e)return this.setState({locale:e.locale});const t=this.state.siteSettings.locale;return this.setState({locale:t})}async getUserLocale(){const e=(await this.getUserSettings()).find(e=>"locale"===e.property);if(e)return this.state.siteSettings.supportedLocales.find(t=>t.locale===e.value)}async getUserSettings(){const e=this.getApiClientOptions().setResourceName("account/settings"),t=new pt(e);return(await t.findAll()).body}removeSplashScreen(){document.getElementsByTagName("html")[0].classList.remove("launching")}async onLogoutRequested(){await this.authLogoutService.logout(),window.location.href=this.state.trustedDomain}async onCheckIsAuthenticatedRequested(){try{const e=this.getApiClientOptions().setResourceName("auth"),t=new pt(e);return await t.get("is-authenticated"),!0}catch(e){if(e instanceof ot&&401===e.data.code)return!1;throw e}}onExpiredSession(e){this.scheduledCheckIsAuthenticatedTimeout=setTimeout(async()=>{await this.onCheckIsAuthenticatedRequested()?this.onExpiredSession(e):e()},6e4)}async onGetSubscriptionKeyRequested(){try{const e=this.getApiClientOptions().setResourceName("ee/subscription"),t=new pt(e);return(await t.get("key")).body}catch(e){if(e instanceof ot&&e.data&&402===e.data.code){const t=e.data.body;throw new xf(e.message,t)}throw e}}onRefreshLocaleRequested(e){this.state.siteSettings.setLocale(e),this.initLocale()}render(){return n.createElement(T.Provider,{value:this.state},this.isReady&&this.props.children)}}Cf.propTypes={children:i().any};const Nf=Cf;var Tf=a(2635),Af=a(1347);class If extends n.Component{constructor(e){super(e),this.state=this.defaultState}get defaultState(){return{ready:!1}}async componentDidMount(){await(0,Tf.Yx)(f.r9).use(Af.A).init({lng:this.locale,load:"currentOnly",interpolation:{escapeValue:!1},react:{useSuspense:!1},backend:{loadPath:(e,t)=>this.getTranslationPath(e,t)},supportedLngs:this.supportedLocales,fallbackLng:!1,ns:["common"],defaultNS:"common",keySeparator:!1,nsSeparator:!1,debug:!1}),this.setState({ready:!0})}getTranslationPath(e,t){const a=e[0],n=t[0],s="en-GB"===a?"en-UK":a;return(this.props.loadingPath||"/locales/{{lng}}/{{ns}}.json").replace("{{lng}}",s).replace("{{ns}}",n)}get supportedLocales(){let e=[];return this.props.context.siteSettings?.supportedLocales?e=this.props.context.siteSettings?.supportedLocales.map(e=>e.locale):e.push(this.locale),e.includes("en-UK")&&e.push("en-GB"),e}get locale(){return this.props.context.locale}async componentDidUpdate(e){await this.handleLocaleChange(e.context.locale)}async handleLocaleChange(e){this.locale!==e&&await(0,Tf.v2)(this.locale)}get isReady(){return this.state.ready}render(){return n.createElement(n.Fragment,null,this.isReady&&this.props.children)}}If.propTypes={context:i().any,loadingPath:i().any,children:i().any};const Rf=N(If);class Pf{constructor(){this.baseUrl=this.getBaseUrl()}async getOrganizationAccountRecoverySettings(){const e=this.getApiClientOptions().setResourceName("account-recovery/organization-policies"),t=new pt(e);return(await t.findAll()).body}getBaseUrl(){const e=document.getElementsByTagName("base")&&document.getElementsByTagName("base")[0];return e?e.attributes.href.value.replace(/\/*$/g,""):(console.error("Unable to retrieve the page base tag"),"")}getApiClientOptions(){return(new kf).setBaseUrl(this.baseUrl)}getCsrfToken(){const e=document.cookie;if(!e)return;const t=e.split("; ");if(!t)return;const a=t.find(e=>e.startsWith("csrfToken"));if(!a)return;const n=a.split("=");return n&&2===n.length?n[1]:void 0}}class Df extends n.Component{render(){const e=new Pf;return n.createElement(Nf,null,n.createElement(T.Consumer,null,t=>n.createElement(Rf,{loadingPath:`${t.trustedDomain}/locales/{{lng}}/{{ns}}.json`},n.createElement(ve,null,n.createElement(We,{accountRecoveryUserService:e},n.createElement(vt,null,n.createElement(c,null,n.createElement(p,null,n.createElement(ef,null,n.createElement(b,null,n.createElement(k,null),n.createElement(df,null),t.loggedInUser&&"admin"===t.loggedInUser.role.name&&t.siteSettings.canIUse("ee")&&n.createElement(wf,null),n.createElement(_.Kd,{basename:t.basename},n.createElement(ze,null,n.createElement(x.Switch,null,n.createElement(x.Route,{exact:!0,path:["/app/administration/subscription","/app/administration/account-recovery","/app/administration/password-policies","/app/administration/user-passphrase-policies","/app/administration/password-expiry","/app/administration/content-types/metadata","/app/administration/content-types/metadata-key","/app/administration/content-types/metadata-getting-started","/app/administration/subscription-teasing","/app/administration/account-recovery-teasing","/app/administration/password-policies-teasing","/app/administration/user-passphrase-policies-teasing","/app/administration/scim-teasing","/app/administration/secret-history"]}),n.createElement(x.Route,{path:"/app/administration"},n.createElement(Se,null,n.createElement(bo,null,n.createElement(Fe,null),n.createElement(Mn,null,n.createElement(Jo,null,n.createElement(Oe,null),n.createElement(Ua,null,n.createElement(Ic,null,n.createElement(Ns,null,n.createElement(ci,null,n.createElement(Jc,null,n.createElement(cu,null,n.createElement(ha,{service:new ca(t.getApiClientOptions())},n.createElement(of,null))))))))))))))))))))))))))}}const Of=Df;var Mf=a(5338);const Uf=document.createElement("div");document.body.appendChild(Uf),(0,Mf.H)(Uf).render(n.createElement(Of,null))}},s={};function i(e){var t=s[e];if(void 0!==t)return t.exports;var a=s[e]={exports:{}};return n[e].call(a.exports,a,a.exports,i),a.exports}i.m=n,e=[],i.O=(t,a,n,s)=>{if(!a){var r=1/0;for(m=0;m=s)&&Object.keys(i.O).every(e=>i.O[e](a[l]))?a.splice(l--,1):(o=!1,s0&&e[m-1][2]>s;m--)e[m]=e[m-1];e[m]=[a,n,s]},i.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return i.d(t,{a:t}),t},a=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,i.t=function(e,n){if(1&n&&(e=this(e)),8&n)return e;if("object"==typeof e&&e){if(4&n&&e.__esModule)return e;if(16&n&&"function"==typeof e.then)return e}var s=Object.create(null);i.r(s);var r={};t=t||[null,a({}),a([]),a(a)];for(var o=2&n&&e;("object"==typeof o||"function"==typeof o)&&!~t.indexOf(o);o=a(o))Object.getOwnPropertyNames(o).forEach(t=>r[t]=()=>e[t]);return r.default=()=>e,i.d(s,r),s},i.d=(e,t)=>{for(var a in t)i.o(t,a)&&!i.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:t[a]})},i.e=()=>Promise.resolve(),i.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),i.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),i.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.j=815,(()=>{var e={815:0};i.O.j=t=>0===e[t];var t=(t,a)=>{var n,s,[r,o,l]=a,c=0;if(r.some(t=>0!==e[t])){for(n in o)i.o(o,n)&&(i.m[n]=o[n]);if(l)var m=l(i)}for(t&&t(a);ci(3652));r=i.O(r)})(); \ No newline at end of file diff --git a/webroot/locales/cs-CZ/common.json b/webroot/locales/cs-CZ/common.json index 60be8df0bd..d21e11f522 100644 --- a/webroot/locales/cs-CZ/common.json +++ b/webroot/locales/cs-CZ/common.json @@ -1794,6 +1794,8 @@ "What is user self registration?": "Co je to samo-registrace uživatele?", "When a comment is posted on a password, notify the users who have access to this password.": "Když je k heslu přidán komentář, upozorněte uživatele, kteří k tomuto heslu mají přístup.", "When a folder is created, notify its creator.": "Když je vytvořena složka, upozorněte jeho tvůrce.", + "When a folder is updated, notify its creator.": "Když je složka aktualizována, upozorněte jejího tvůrce.", + "When a folder is deleted, notify its creator.": "Když je složka odstraněna, upozorněte jejího tvůrce.", "When a folder is deleted, notify the users who had access to it.": "Když je složka odstraněna, upozorněte uživatele, kteří k ní měli přístup.", "When a folder is shared, notify the users who gain access to it.": "Když je složka nasdílena, upozorněte uživatele, kteří k ní získali přístup.", "When a folder is updated, notify the users who have access to it.": "Když je složka aktualizována, upozorněte uživatele, kteří k ní mají přístup.", @@ -1802,6 +1804,8 @@ "When a password is deleted, notify the users who had access to it.": "Když je heslo odstraněno, upozorněte uživatele, kteří k němu měli přístup.", "When a password is shared, notify the users who gain access to it.": "Když je heslo nasdíleno, upozorněte uživatele, kteří k němu získali přístup.", "When a password is updated, notify the users who have access to it.": "Když je heslo aktualizováno, upozorněte uživatele, kteří k němu mají přístup.", + "When a password is updated, notify its creator.": "Když je heslo aktualizováno, upozorněte jeho tvůrce.", + "When a password is deleted, notify its creator.": "Když je heslo odstraněno, upozorněte jeho tvůrce.", "When a permission is revoked on a consumed password, notify the owner(s) to change it.": "Když je na spotřebovaném heslu zrušeno oprávnění, upozorněte vlastníka/vlastníky, aby jej změnili.", "When a user aborted a recover, notify all the administrators.": "Když uživatel přeruší proces obnovy, upozorněte všechny administrátory.", "When a user completed a recover, notify all the administrators.": "Když uživatel dokončí obnovu, upozorněte všechny administrátory.", @@ -2056,4 +2060,4 @@ "Unable to mark the resource as expired._few": "Nepodařilo se označit zdroje jako expirované.", "Unable to mark the resource as expired._many": "Nepodařilo se označit zdroje jako expirované.", "Unable to mark the resource as expired._other": "Nepodařilo se označit zdroje jako expirované." -} \ No newline at end of file +} diff --git a/webroot/locales/de-DE/common.json b/webroot/locales/de-DE/common.json index 9e44b13af5..da6a9904cc 100644 --- a/webroot/locales/de-DE/common.json +++ b/webroot/locales/de-DE/common.json @@ -1794,6 +1794,8 @@ "What is user self registration?": "Was ist eine Benutzerregistrierung?", "When a comment is posted on a password, notify the users who have access to this password.": "Wenn ein Kommentar zu einem Passwort veröffentlicht wird, benachrichtige die Benutzer, die Zugang zu diesem Passwort haben.", "When a folder is created, notify its creator.": "Wenn ein Ordner erstellt wurde, benachrichtige dessen Ersteller.", + "When a folder is updated, notify its creator.": "Wenn ein Ordner aktualisiert wurde, benachrichtige dessen Ersteller.", + "When a folder is deleted, notify its creator.": "Wenn ein Ordner gelöscht wurde, benachrichtige dessen Ersteller.", "When a folder is deleted, notify the users who had access to it.": "Wenn ein Ordner gelöscht wurde, benachrichtige die Benutzer, die Zugriff darauf hatten.", "When a folder is shared, notify the users who gain access to it.": "Wenn ein Ordner freigegeben wurde, benachrichtige die Benutzer, die Zugriff darauf haben.", "When a folder is updated, notify the users who have access to it.": "Wenn ein Ordner aktualisiert wurde, benachrichtige die Benutzer, die Zugriff darauf haben.", @@ -1802,6 +1804,8 @@ "When a password is deleted, notify the users who had access to it.": "Wenn ein Passwort gelöscht wurde, benachrichtige die Benutzer, die Zugriff darauf hatten.", "When a password is shared, notify the users who gain access to it.": "Wenn ein Passwort freigegeben wird, benachrichtige die Benutzer, die Zugriff darauf erhalten.", "When a password is updated, notify the users who have access to it.": "Wenn ein Passwort aktualisiert wurde, benachrichtige die Benutzer, die Zugriff darauf haben.", + "When a password is updated, notify its creator.": "Wenn ein Passwort aktualisiert wurde, benachrichtige dessen Ersteller.", + "When a password is deleted, notify its creator.": "Wenn ein Passwort gelöscht wurde, benachrichtige dessen Ersteller.", "When a permission is revoked on a consumed password, notify the owner(s) to change it.": "Wenn eine Berechtigung für ein genutztes Passwort widerrufen wird, benachrichtigen Sie die Eigentümer(innen), es zu ändern.", "When a user aborted a recover, notify all the administrators.": "Wenn ein Benutzer eine Wiederherstellung abgebrochen hat, benachrichtige alle Administratoren.", "When a user completed a recover, notify all the administrators.": "Wenn ein Benutzer eine Wiederherstellung abgeschlossen hat, benachrichtige alle Administratoren.", @@ -1986,4 +1990,4 @@ "This resource does not need an expiry date._other": "Für diese Ressourcen ist kein Ablaufdatum erforderlich.", "Unable to mark the resource as expired._one": "Die Ressource kann nicht als abgelaufen markiert werden.", "Unable to mark the resource as expired._other": "Die Ressourcen können nicht als abgelaufen markiert werden." -} \ No newline at end of file +} diff --git a/webroot/locales/en-UK/common.json b/webroot/locales/en-UK/common.json index 39165f1ce8..bfd442c802 100644 --- a/webroot/locales/en-UK/common.json +++ b/webroot/locales/en-UK/common.json @@ -1865,6 +1865,8 @@ "What is user self registration?": "What is user self registration?", "When a comment is posted on a password, notify the users who have access to this password.": "When a comment is posted on a password, notify the users who have access to this password.", "When a folder is created, notify its creator.": "When a folder is created, notify its creator.", + "When a folder is updated, notify its creator.": "When a folder is updated, notify its creator.", + "When a folder is deleted, notify its creator.": "When a folder is deleted, notify its creator.", "When a folder is deleted, notify the users who had access to it.": "When a folder is deleted, notify the users who had access to it.", "When a folder is shared, notify the users who gain access to it.": "When a folder is shared, notify the users who gain access to it.", "When a folder is updated, notify the users who have access to it.": "When a folder is updated, notify the users who have access to it.", @@ -1873,6 +1875,8 @@ "When a password is deleted, notify the users who had access to it.": "When a password is deleted, notify the users who had access to it.", "When a password is shared, notify the users who gain access to it.": "When a password is shared, notify the users who gain access to it.", "When a password is updated, notify the users who have access to it.": "When a password is updated, notify the users who have access to it.", + "When a password is updated, notify its creator.": "When a password is updated, notify its creator.", + "When a password is deleted, notify its creator.": "When a password is deleted, notify its creator.", "When a permission is revoked on a consumed password, notify the owner(s) to change it.": "When a permission is revoked on a consumed password, notify the owner(s) to change it.", "When a user aborted a recover, notify all the administrators.": "When a user aborted a recover, notify all the administrators.", "When a user completed a recover, notify all the administrators.": "When a user completed a recover, notify all the administrators.", diff --git a/webroot/locales/es-ES/common.json b/webroot/locales/es-ES/common.json index be0da1a41c..0a6b0db12b 100644 --- a/webroot/locales/es-ES/common.json +++ b/webroot/locales/es-ES/common.json @@ -1794,6 +1794,8 @@ "What is user self registration?": "¿Qué es el auto-registro de usuarios?", "When a comment is posted on a password, notify the users who have access to this password.": "Cuando se publique un comentario en una contraseña, notificar a los usuarios que tengan acceso a esta contraseña.", "When a folder is created, notify its creator.": "Cuando se cree una carpeta, notifíquelo a su autor.", + "When a folder is updated, notify its creator.": "Cuando se actualice una carpeta, notifíquelo a su autor.", + "When a folder is deleted, notify its creator.": "Cuando se elimine una carpeta, notifíquelo a su autor.", "When a folder is deleted, notify the users who had access to it.": "Cuando una carpeta es eliminada, notificar a los usuarios que tengan acceso a ella.", "When a folder is shared, notify the users who gain access to it.": "Cuando se comparta una carpeta, notificar a los usuarios que tengan acceso a ella.", "When a folder is updated, notify the users who have access to it.": "Cuando se actualice una carpeta, notificar a los usuarios que tengan acceso a ella.", @@ -1802,6 +1804,8 @@ "When a password is deleted, notify the users who had access to it.": "Cuando se elimina una contraseña, notificar a los usuarios que tengan acceso a ella.", "When a password is shared, notify the users who gain access to it.": "Cuando se comparte una contraseña, notificar a los usuarios que tengan acceso a ella.", "When a password is updated, notify the users who have access to it.": "Cuando se actualice una contraseña, notificar a los usuarios que tienen acceso a ella.", + "When a password is updated, notify its creator.": "Cuando se actualice una contraseña, notifíquelo a su autor.", + "When a password is deleted, notify its creator.": "Cuando se elimine una contraseña, notificar a su creador.", "When a permission is revoked on a consumed password, notify the owner(s) to change it.": "Cuando se revoca un permiso en una contraseña consumida, notifique al propietario que la cambie.", "When a user aborted a recover, notify all the administrators.": "Cuando un usuario abortó una recuperación, notificar a todos los administradores.", "When a user completed a recover, notify all the administrators.": "Cuando un usuario haya completado una recuperación, notificar a todos los administradores.", @@ -1986,4 +1990,4 @@ "This resource does not need an expiry date._other": "Estos recursos no necesitan una fecha de caducidad.", "Unable to mark the resource as expired._one": "No se puede marcar el recurso como caducado.", "Unable to mark the resource as expired._other": "No se pueden marcar los recursos como caducados." -} \ No newline at end of file +} diff --git a/webroot/locales/fr-FR/common.json b/webroot/locales/fr-FR/common.json index f165c0fd9a..6b91d60aa6 100644 --- a/webroot/locales/fr-FR/common.json +++ b/webroot/locales/fr-FR/common.json @@ -1794,6 +1794,8 @@ "What is user self registration?": "Qu'est-ce que l'auto-inscription de l'utilisateur ?", "When a comment is posted on a password, notify the users who have access to this password.": "Lorsqu'un commentaire est publié sur un mot de passe, informer les utilisateurs qui ont accès à ce mot de passe.", "When a folder is created, notify its creator.": "Lorsqu'un dossier est créé, informer son créateur.", + "When a folder is updated, notify its creator.": "Lorsqu'un dossier est mis à jour, informer son créateur.", + "When a folder is deleted, notify its creator.": "Lorsqu'un dossier est supprimé, informer son créateur.", "When a folder is deleted, notify the users who had access to it.": "Lorsqu'un dossier est supprimé, avisez les utilisateurs qui y avaient accès.", "When a folder is shared, notify the users who gain access to it.": "Lorsqu'un dossier est partagé, informer les utilisateurs qui y ont gagné accès.", "When a folder is updated, notify the users who have access to it.": "Lorsqu'un dossier est mis à jour, informer les utilisateurs qui y ont accès.", @@ -1802,6 +1804,8 @@ "When a password is deleted, notify the users who had access to it.": "Lorsqu'un mot de passe est supprimé, informer les utilisateurs qui y avaient accès.", "When a password is shared, notify the users who gain access to it.": "Lorsqu'un mot de passe est partagé, informer les utilisateurs qui y ont gagné accès.", "When a password is updated, notify the users who have access to it.": "Lorsqu'un mot de passe est mis à jour, informer les utilisateurs qui y ont accès.", + "When a password is updated, notify its creator.": "Lorsqu'un mot de passe est mis à jour, informer son créateur.", + "When a password is deleted, notify its creator.": "Lorsqu'un mot de passe est supprimé, informer son créateur.", "When a permission is revoked on a consumed password, notify the owner(s) to change it.": "Lorsqu'une permission est révoquée sur un mot de passe consommé, avertissez le(s) propriétaire(s) de le modifier.", "When a user aborted a recover, notify all the administrators.": "Lorsqu'un utilisateur a abandonné une récupération, avertissez tous les administrateurs.", "When a user completed a recover, notify all the administrators.": "Lorsqu'un utilisateur a terminé une récupération, avertissez tous les administrateurs.", @@ -1986,4 +1990,4 @@ "This resource does not need an expiry date._other": "Ces ressources ne nécessitent pas de date d'expiration.", "Unable to mark the resource as expired._one": "Impossible de marquer la ressource comme expirée.", "Unable to mark the resource as expired._other": "Impossible de marquer les ressources comme expirées." -} \ No newline at end of file +} diff --git a/webroot/locales/it-IT/common.json b/webroot/locales/it-IT/common.json index 8ba42549ef..62c3ef3f06 100644 --- a/webroot/locales/it-IT/common.json +++ b/webroot/locales/it-IT/common.json @@ -1794,6 +1794,8 @@ "What is user self registration?": "Cos'è l'auto-registrazione dell'utente?", "When a comment is posted on a password, notify the users who have access to this password.": "Quando si pubblica un commento su una password, informare gli utenti che hanno accesso alla password.", "When a folder is created, notify its creator.": "Quando si crea una cartella, avvisare il creatore.", + "When a folder is updated, notify its creator.": "Quando si aggiorna una cartella, avvisare il creatore.", + "When a folder is deleted, notify its creator.": "Quando si elimina una cartella, avvisare il creatore.", "When a folder is deleted, notify the users who had access to it.": "Quando si elimina una cartella, avvisare gli utenti che vi hanno avuto accesso.", "When a folder is shared, notify the users who gain access to it.": "Quando si condivide una cartella, avvisare gli utenti che ne ottengono l'accesso.", "When a folder is updated, notify the users who have access to it.": "Quando si aggiorna una cartella, avvisare gli utenti che vi hanno accesso.", @@ -1802,6 +1804,8 @@ "When a password is deleted, notify the users who had access to it.": "Quando una password viene eliminata, avvisare gli utenti che hanno avuto accesso ad essa.", "When a password is shared, notify the users who gain access to it.": "Quando una password è condivisa, avvisa gli utenti che ottengono l'accesso ad essa.", "When a password is updated, notify the users who have access to it.": "Quando una password viene aggiornata, avvisare gli utenti che hanno accesso ad essa.", + "When a password is updated, notify its creator.": "Quando si aggiorna una password, avvisare il creatore.", + "When a password is deleted, notify its creator.": "Quando si elimina una password, avvisare il suo creatore.", "When a permission is revoked on a consumed password, notify the owner(s) to change it.": "Quando viene revocato un permesso su una password utilizzata, avvisa il proprietario (o i proprietari) di cambiarla.", "When a user aborted a recover, notify all the administrators.": "Quando un utente interrompe una procedura di recupero, avvisa tutti gli amministratori.", "When a user completed a recover, notify all the administrators.": "Quando un utente completa una procedura di recupero, avvisa tutti gli amministratori.", @@ -1986,4 +1990,4 @@ "This resource does not need an expiry date._other": "Queste risorse non necessitano di una data di scadenza.", "Unable to mark the resource as expired._one": "Impossibile contrassegnare la risorsa come scaduta.", "Unable to mark the resource as expired._other": "Impossibile contrassegnare le risorse come scadute." -} \ No newline at end of file +} diff --git a/webroot/locales/ja-JP/common.json b/webroot/locales/ja-JP/common.json index 5c49319b84..b7d2782db9 100644 --- a/webroot/locales/ja-JP/common.json +++ b/webroot/locales/ja-JP/common.json @@ -1794,6 +1794,8 @@ "What is user self registration?": "ユーザーセルフ登録とは何ですか?", "When a comment is posted on a password, notify the users who have access to this password.": "コメントがパスワードに投稿された場合、このパスワードにアクセスできるユーザーに通知します。", "When a folder is created, notify its creator.": "フォルダが作成されたら、作成者に通知します。", + "When a folder is updated, notify its creator.": "フォルダが更新されたら、作成者に通知します。", + "When a folder is deleted, notify its creator.": "フォルダが削除されたら、作成者に通知します。", "When a folder is deleted, notify the users who had access to it.": "フォルダが削除されたら、アクセス権を持っていたユーザーに通知します。", "When a folder is shared, notify the users who gain access to it.": "フォルダが共有されたら、アクセス権を得るユーザーに通知します。", "When a folder is updated, notify the users who have access to it.": "フォルダが更新されたら、アクセス権を持つユーザーに通知します。", @@ -1802,6 +1804,8 @@ "When a password is deleted, notify the users who had access to it.": "パスワードが削除されたら、アクセス権を持っていたユーザーに通知します。", "When a password is shared, notify the users who gain access to it.": "パスワードが共有されたら、アクセス権を得るユーザーに通知します。", "When a password is updated, notify the users who have access to it.": "パスワードが更新されたら、アクセス権を持つユーザーに通知します。", + "When a password is updated, notify its creator.": "パスワードが更新されたら、作成者に通知します。", + "When a password is deleted, notify its creator.": "パスワードが削除されたら、作成者に通知します。", "When a permission is revoked on a consumed password, notify the owner(s) to change it.": "パーミッションを取り消されたパスワードが消費されていた場合、所有者(s)に変更するよう通知します。", "When a user aborted a recover, notify all the administrators.": "ユーザーが復旧を中止した場合、すべての管理者に通知します。", "When a user completed a recover, notify all the administrators.": "ユーザーが復旧を完了した場合、すべての管理者に通知します。", @@ -1951,4 +1955,4 @@ "The resource has been marked as expired._other": "リソースは期限切れとしてマークされました。", "This resource does not need an expiry date._other": "これらのリソースには有効期限は必要ありません。", "Unable to mark the resource as expired._other": "リソースを期限切れにマークできませんでした。" -} \ No newline at end of file +} diff --git a/webroot/locales/ko-KR/common.json b/webroot/locales/ko-KR/common.json index 5de66740b8..ea7e4d2a55 100644 --- a/webroot/locales/ko-KR/common.json +++ b/webroot/locales/ko-KR/common.json @@ -1794,6 +1794,8 @@ "What is user self registration?": "사용자 자체 등록이란 무엇인가요?", "When a comment is posted on a password, notify the users who have access to this password.": "비밀번호에 의견이 작성되면 이 비밀번호에 대한 접근 권한이 있는 사용자에게 알립니다.", "When a folder is created, notify its creator.": "폴더가 생성되면 해당 폴더를 만든 사람에게 알립니다.", + "When a folder is updated, notify its creator.": "폴더가 업데이트되면 해당 폴더를 만든 사람에게 알립니다.", + "When a folder is deleted, notify its creator.": "폴더가 삭제되면 해당 폴더를 만든 사람에게 알립니다.", "When a folder is deleted, notify the users who had access to it.": "폴더가 삭제되면 폴더에 대한 접근 권한을 가진 사용자에게 알립니다.", "When a folder is shared, notify the users who gain access to it.": "폴더가 공유되면 폴더에 대한 접근 권한을 얻은 사용자에게 알립니다.", "When a folder is updated, notify the users who have access to it.": "폴더가 업데이트되면 폴더에 대한 접근 권한을 가진 사용자에게 알립니다.", @@ -1802,6 +1804,8 @@ "When a password is deleted, notify the users who had access to it.": "비밀번호가 삭제되면 비밀번호에 대한 접근 권한을 가진 사용자에게 알립니다.", "When a password is shared, notify the users who gain access to it.": "비밀번호가 공유되면 비밀번호에 대한 접근 권한을 얻은 사용자에게 알립니다.", "When a password is updated, notify the users who have access to it.": "비밀번호가 업데이트되면 비밀번호에 대한 접근 권한을 가진 사용자에게 알립니다.", + "When a password is updated, notify its creator.": "암호가 업데이트되면 해당 암호를 만든 사람에게 알립니다.", + "When a password is deleted, notify its creator.": "비밀번호가 삭제되면 해당 비밀번호를 만든 사람에게 알립니다.", "When a permission is revoked on a consumed password, notify the owner(s) to change it.": "사용한 비밀번호에 대한 권한이 취소되면 소유자에게 변경할 것을 알립니다.", "When a user aborted a recover, notify all the administrators.": "사용자가 복구를 중단하면 모든 관리자에게 알립니다.", "When a user completed a recover, notify all the administrators.": "사용자가 복구를 완료하면 모든 관리자에게 알립니다.", @@ -1951,4 +1955,4 @@ "The resource has been marked as expired._other": "리소스가 만료된 것으로 표시되었습니다.", "This resource does not need an expiry date._other": "이 리소스는 만료일이 필요하지 않습니다.", "Unable to mark the resource as expired._other": "리소스를 만료된 것으로 표시할 수 없습니다." -} \ No newline at end of file +} diff --git a/webroot/locales/lt-LT/common.json b/webroot/locales/lt-LT/common.json index 4a2ba7b2fb..b33a29fc7d 100644 --- a/webroot/locales/lt-LT/common.json +++ b/webroot/locales/lt-LT/common.json @@ -1794,6 +1794,8 @@ "What is user self registration?": "Kas yra vartotojo savarankiška registracija?", "When a comment is posted on a password, notify the users who have access to this password.": "Kai komentaras paskelbiamas apie slaptažodį, praneškite vartotojams, kurie turi prieigą prie šio slaptažodžio.", "When a folder is created, notify its creator.": "Kai aplankas sukurtas, praneškite jo kūrėjui.", + "When a folder is updated, notify its creator.": "Kai aplankas atnaujinamas, praneškite jo kūrėjui.", + "When a folder is deleted, notify its creator.": "Kai aplankas ištrinamas, praneškite jo kūrėjui.", "When a folder is deleted, notify the users who had access to it.": "Kai aplankas ištrinamas, praneškite vartotojams, kurie turėjo prieigą prie jo.", "When a folder is shared, notify the users who gain access to it.": "Kai aplanku dalinamasi, praneškite naudotojams, kurie gauna prieigą prie jo.\n", "When a folder is updated, notify the users who have access to it.": "Kai aplankas atnaujinamas, informuokite vartotojus, kurie turi prieigą prie jo.\n", @@ -1802,6 +1804,8 @@ "When a password is deleted, notify the users who had access to it.": "Kai slaptažodis ištrintas, informuokite vartotojus, kurie turėjo prieigą prie jo.\n", "When a password is shared, notify the users who gain access to it.": "Kai slaptažodžiu dalinamasi, praneškite naudotojams, kurie turi prieigą prie jo.", "When a password is updated, notify the users who have access to it.": "Kai slaptažodis atnaujinamas, informuokite vartotojus, kurie turi prieigą prie jo.", + "When a password is updated, notify its creator.": "Kai slaptažodis atnaujinamas, praneškite jo kūrėjui.", + "When a password is deleted, notify its creator.": "Kai slaptažodis ištrinamas, praneškite jo kūrėjui.", "When a permission is revoked on a consumed password, notify the owner(s) to change it.": "Kai atšaukiama teisė prie naudojamo slaptažodžio, praneškite savininkui (-ams) jį pakeisti.", "When a user aborted a recover, notify all the administrators.": "Kai vartotojas atšaukia atkūrimą, praneškite visiems administratoriams.", "When a user completed a recover, notify all the administrators.": "Kai vartotojas baigia atkūrimą, praneškite visiems administratoriams.", @@ -2056,4 +2060,4 @@ "Unable to mark the resource as expired._few": "Nepavyko pažymėti išteklių kaip pasibaigusių.", "Unable to mark the resource as expired._many": "Nepavyko pažymėti išteklių kaip pasibaigusių.", "Unable to mark the resource as expired._other": "Nepavyko pažymėti išteklių kaip pasibaigusių." -} \ No newline at end of file +} diff --git a/webroot/locales/nl-NL/common.json b/webroot/locales/nl-NL/common.json index 43eceb4acf..4724b46cac 100644 --- a/webroot/locales/nl-NL/common.json +++ b/webroot/locales/nl-NL/common.json @@ -1794,6 +1794,8 @@ "What is user self registration?": "Wat is self-registratie van gebruikers?", "When a comment is posted on a password, notify the users who have access to this password.": "Als er een opmerking is geplaatst met betrekking tot een wachtwoord, informeer dan de gebruikers die toegang hebben tot dit wachtwoord.", "When a folder is created, notify its creator.": "Als een map is aangemaakt, breng de maker hiervan op de hoogte.", + "When a folder is updated, notify its creator.": "Als een map is bijgewerkt, breng de maker hiervan op de hoogte.", + "When a folder is deleted, notify its creator.": "Als een map is verwijderd, breng de maker hiervan op de hoogte.", "When a folder is deleted, notify the users who had access to it.": "Wanneer een map wordt verwijderd, informeer dan de gebruikers die er toegang toe hadden.", "When a folder is shared, notify the users who gain access to it.": "Als een map wordt gedeeld, informeer dan de gebruikers die er toegang toe krijgen.", "When a folder is updated, notify the users who have access to it.": "Wanneer een map is bijgewerkt, informeer dan de gebruikers die er toegang toe hebben.", @@ -1802,6 +1804,8 @@ "When a password is deleted, notify the users who had access to it.": "Wanneer een wachtwoord wordt verwijderd, informeer dan de gebruikers die er toegang toe hadden.", "When a password is shared, notify the users who gain access to it.": "Als een wachtwoord wordt gedeeld, informeer dan de gebruikers die er toegang toe krijgen.", "When a password is updated, notify the users who have access to it.": "Als een wachtwoord is bijgewerkt, informeer dan de gebruikers die er toegang toe hebben.", + "When a password is updated, notify its creator.": "Als een wachtwoord is bijgewerkt, breng de maker hiervan op de hoogte.", + "When a password is deleted, notify its creator.": "Als een wachtwoord is verwijderd, breng de maker hiervan op de hoogte.", "When a permission is revoked on a consumed password, notify the owner(s) to change it.": "Wanneer een machtiging op een gebruikt wachtwoord wordt ingetrokken, waarschuw dan de eigenaar(s) om het te wijzigen.", "When a user aborted a recover, notify all the administrators.": "Als een gebruiker een herstel heeft afgebroken, breng dan alle beheerders op de hoogte.", "When a user completed a recover, notify all the administrators.": "Als een gebruiker een herstel heeft voltooid, breng dan alle beheerders op de hoogte.", @@ -1986,4 +1990,4 @@ "This resource does not need an expiry date._other": "Deze middelen hebben geen vervaldatum nodig.", "Unable to mark the resource as expired._one": "Kan het middel niet markeren als verlopen.", "Unable to mark the resource as expired._other": "Kan de middelen niet markeren als verlopen." -} \ No newline at end of file +} diff --git a/webroot/locales/pl-PL/common.json b/webroot/locales/pl-PL/common.json index 8f20b5e4af..df4fd7be24 100644 --- a/webroot/locales/pl-PL/common.json +++ b/webroot/locales/pl-PL/common.json @@ -1794,6 +1794,8 @@ "What is user self registration?": "Co to jest samodzielna rejestracja użytkowników?", "When a comment is posted on a password, notify the users who have access to this password.": "Gdy do hasła zostanie dopisany komentarz, powiadom użytkowników z dostępem do tego hasła.", "When a folder is created, notify its creator.": "Gdy folder zostanie utworzony, powiadom jego twórcę.", + "When a folder is updated, notify its creator.": "Gdy folder zostanie zaktualizowany, powiadom jego twórcę.", + "When a folder is deleted, notify its creator.": "Gdy folder zostanie usunięty, powiadom jego twórcę.", "When a folder is deleted, notify the users who had access to it.": "Gdy folder zostanie usunięty, powiadom użytkowników, którzy mieli do niego dostęp.", "When a folder is shared, notify the users who gain access to it.": "Gdy folder zostanie udostępniony, powiadom użytkowników, którzy otrzymują do niego dostęp.", "When a folder is updated, notify the users who have access to it.": "Gdy folder zostanie zaktualizowany, powiadom użytkowników, którzy mają do niego dostęp.", @@ -1802,6 +1804,8 @@ "When a password is deleted, notify the users who had access to it.": "Gdy hasło zostanie usunięte, powiadom użytkowników, którzy mieli do niego dostęp.", "When a password is shared, notify the users who gain access to it.": "Gdy hasło zostanie udostępnione, powiadom użytkowników, którzy otrzymują do niego dostęp.", "When a password is updated, notify the users who have access to it.": "Gdy hasło zostanie zaktualizowane, powiadom użytkowników, którzy mają do niego dostęp.", + "When a password is updated, notify its creator.": "Gdy hasło zostanie zaktualizowane, powiadom jego twórcę.", + "When a password is deleted, notify its creator.": "Gdy hasło zostanie usunięte, powiadom jego twórcę.", "When a permission is revoked on a consumed password, notify the owner(s) to change it.": "Gdy uprawnienie do używanego hasła zostanie cofnięte, powiadom właściciela(-li) o konieczności jego zmiany.", "When a user aborted a recover, notify all the administrators.": "Gdy użytkownik przerwie odzyskiwanie, powiadom wszystkich administratorów.", "When a user completed a recover, notify all the administrators.": "Gdy użytkownik uklończy odzyskiwanie, powiadom wszystkich administratorów.", @@ -2056,4 +2060,4 @@ "Unable to mark the resource as expired._few": "Nie można oznaczyć zasobów jako wygasłych.", "Unable to mark the resource as expired._many": "Nie można oznaczyć zasobów jako wygasłych.", "Unable to mark the resource as expired._other": "Nie można oznaczyć zasobów jako wygasłych." -} \ No newline at end of file +} diff --git a/webroot/locales/pt-BR/common.json b/webroot/locales/pt-BR/common.json index 3b1ee158b9..4c8924d692 100644 --- a/webroot/locales/pt-BR/common.json +++ b/webroot/locales/pt-BR/common.json @@ -1794,6 +1794,8 @@ "What is user self registration?": "O que é registro próprio de usuário?", "When a comment is posted on a password, notify the users who have access to this password.": "Quando um comentário é postado em uma senha, notificar os usuários que têm acesso a esta senha.", "When a folder is created, notify its creator.": "Quando uma pasta for criada, notifique seu criador.", + "When a folder is updated, notify its creator.": "Quando uma pasta for atualizada, notifique seu criador.", + "When a folder is deleted, notify its creator.": "Quando uma pasta for excluída, notifique seu criador.", "When a folder is deleted, notify the users who had access to it.": "Quando uma pasta é excluída, notifique os usuários que tiveram acesso a ela.", "When a folder is shared, notify the users who gain access to it.": "Quando uma pasta é compartilhada, notifique os usuários que têm acesso a ela.", "When a folder is updated, notify the users who have access to it.": "Quando uma pasta é atualizada, notifique os usuários que têm acesso a ela.", @@ -1802,6 +1804,8 @@ "When a password is deleted, notify the users who had access to it.": "Quando uma senha é excluída, notifique os usuários que tiveram acesso a ela.", "When a password is shared, notify the users who gain access to it.": "Quando uma senha é compartilhada, notifique os usuários que obtêm acesso a ela.", "When a password is updated, notify the users who have access to it.": "Quando uma senha é atualizada, notifique os usuários que têm acesso a ela.", + "When a password is updated, notify its creator.": "Quando uma senha for atualizada, notifique seu criador.", + "When a password is deleted, notify its creator.": "Quando uma senha for excluída, notifique seu criador.", "When a permission is revoked on a consumed password, notify the owner(s) to change it.": "Quando uma permissão é revogada em uma senha consumida, notificar os proprietários para alterá-la.", "When a user aborted a recover, notify all the administrators.": "Quando um usuário abortar uma recuperação, notificar todos os administradores.", "When a user completed a recover, notify all the administrators.": "Quando um usuário completar uma recuperação, notificar todos os administradores.", @@ -1986,4 +1990,4 @@ "This resource does not need an expiry date._other": "Esses recursos não precisam de uma data de validade.", "Unable to mark the resource as expired._one": "Não é possível marcar o recurso como expirado.", "Unable to mark the resource as expired._other": "Não é possível marcar os recursos como expirados." -} \ No newline at end of file +} diff --git a/webroot/locales/ro-RO/common.json b/webroot/locales/ro-RO/common.json index dcc63a404a..0114db1ca7 100644 --- a/webroot/locales/ro-RO/common.json +++ b/webroot/locales/ro-RO/common.json @@ -1794,6 +1794,8 @@ "What is user self registration?": "Ce este auto-înregistrarea utilizatorilor?", "When a comment is posted on a password, notify the users who have access to this password.": "Când un comentariu este postat pentru o parolă, notifică utilizatorii care au acces la această parolă.", "When a folder is created, notify its creator.": "Când un folder este creat, anunțați creatorul.", + "When a folder is updated, notify its creator.": "Când un folder este actualizat, anunțați creatorul.", + "When a folder is deleted, notify its creator.": "Când un folder este șters, anunțați creatorul.", "When a folder is deleted, notify the users who had access to it.": "Când un folder este șters, notificați utilizatorii care au avut acces la el.", "When a folder is shared, notify the users who gain access to it.": "Atunci când un folder este partajat, notifică utilizatorii care au acces la el.", "When a folder is updated, notify the users who have access to it.": "Când un folder este actualizat, notifică utilizatorii care au acces la el.", @@ -1802,6 +1804,8 @@ "When a password is deleted, notify the users who had access to it.": "Când o parolă este ștearsă, notificați utilizatorii care au avut acces la ea.", "When a password is shared, notify the users who gain access to it.": "Când o parolă este partajată, notificați utilizatorii care au acces la ea.", "When a password is updated, notify the users who have access to it.": "Când o parolă este actualizată, notificați utilizatorii care au acces la ea.", + "When a password is updated, notify its creator.": "Când o parolă este actualizată, anunțați creatorul.", + "When a password is deleted, notify its creator.": "Când o parolă este ștearsă, anunțați creatorul.", "When a permission is revoked on a consumed password, notify the owner(s) to change it.": "Când o permisiune este revocată pentru o parolă consumată, anunțați proprietarul(ii) să o schimbe.", "When a user aborted a recover, notify all the administrators.": "Când un utilizator a renunțat la recuperare, notificați toți administratorii.", "When a user completed a recover, notify all the administrators.": "Când un utilizator a finalizat o recuperare, notifică toți administratorii.", @@ -2021,4 +2025,4 @@ "Unable to mark the resource as expired._one": "Nu se poate marca resursa ca expirată.", "Unable to mark the resource as expired._few": "Nu se pot marca resursele ca expirate.", "Unable to mark the resource as expired._other": "Nu se pot marca resursele ca expirate." -} \ No newline at end of file +} diff --git a/webroot/locales/ru-RU/common.json b/webroot/locales/ru-RU/common.json index b82f5c0b20..7fa885c517 100644 --- a/webroot/locales/ru-RU/common.json +++ b/webroot/locales/ru-RU/common.json @@ -1794,6 +1794,8 @@ "What is user self registration?": "Что такое саморегистрация?", "When a comment is posted on a password, notify the users who have access to this password.": "При появлении комментария к паролю уведомлять пользователей, имеющих к этому паролю доступ.", "When a folder is created, notify its creator.": "При создании папки уведомлять его создателя.", + "When a folder is updated, notify its creator.": "При обновлении папки уведомлять ее создателя.", + "When a folder is deleted, notify its creator.": "При удалении папки уведомлять ее создателя.", "When a folder is deleted, notify the users who had access to it.": "При удалении папки уведомлять пользователей, имевших к ней доступ.", "When a folder is shared, notify the users who gain access to it.": "При введении общего доступа к папке уведомлять пользователей, получающих доступ.", "When a folder is updated, notify the users who have access to it.": "При обновлении папки уведомлять пользователей, имеющих к ней доступ.", @@ -1802,6 +1804,8 @@ "When a password is deleted, notify the users who had access to it.": "При удалении пароля уведомлять пользователей, имевших к нему доступ.", "When a password is shared, notify the users who gain access to it.": "При введении общего доступа к паролю уведомлять пользователей, получающих доступ.", "When a password is updated, notify the users who have access to it.": "При обновлении пароля уведомлять пользователей, имеющих к нему доступ.", + "When a password is updated, notify its creator.": "При обновлении пароля уведомлять его создателя.", + "When a password is deleted, notify its creator.": "При удалении пароля уведомлять его создателя.", "When a permission is revoked on a consumed password, notify the owner(s) to change it.": "Когда разрешение на используемый пароль отзывается, уведомляйте владельца(владельцев) о необходимости его изменить.", "When a user aborted a recover, notify all the administrators.": "При прерывании восстановления пользователем уведомлять всех администраторов.", "When a user completed a recover, notify all the administrators.": "При завершении восстановления пользователем уведомлять всех администраторов.", @@ -2056,4 +2060,4 @@ "Unable to mark the resource as expired._few": "Не удалось отметить ресурсы как истекшие.", "Unable to mark the resource as expired._many": "Не удалось отметить ресурсы как истекшие.", "Unable to mark the resource as expired._other": "Не удалось отметить ресурсы как истекшие." -} \ No newline at end of file +} diff --git a/webroot/locales/sl-SI/common.json b/webroot/locales/sl-SI/common.json index a7fb0a4a30..3d08a345c9 100644 --- a/webroot/locales/sl-SI/common.json +++ b/webroot/locales/sl-SI/common.json @@ -1794,6 +1794,8 @@ "What is user self registration?": "Kaj je samoregistracija uporabnikov?", "When a comment is posted on a password, notify the users who have access to this password.": "Ko je objavljen komentar na geslo, obvestite uporabnike, ki imajo dostop do tega gesla.", "When a folder is created, notify its creator.": "Ko je ustvarjena mapa, obvestite njenega ustvarjalca.", + "When a folder is updated, notify its creator.": "Ko je mapa posodobljena, obvestite njenega ustvarjalca.", + "When a folder is deleted, notify its creator.": "Ko je mapa izbrisana, obvestite njenega ustvarjalca.", "When a folder is deleted, notify the users who had access to it.": "Ko je mapa izbrisana, obvestite uporabnike, ki imajo dostop do nje.", "When a folder is shared, notify the users who gain access to it.": "Ko je mapa deljena, obvestite uporabnike, ki pridobijo dostop do nje.", "When a folder is updated, notify the users who have access to it.": "Ko je mapa posodobljena, obvestite uporabnike, ki imajo dostop do nje.", @@ -1802,6 +1804,8 @@ "When a password is deleted, notify the users who had access to it.": "Ko je geslo izbrisano, obvestite uporabnike, ki so imeli dostop do njega.", "When a password is shared, notify the users who gain access to it.": "Ko je geslo deljeno, obvestite uporabnike, ki pridobijo dostop do njega.", "When a password is updated, notify the users who have access to it.": "Ko je geslo posodobljeno, obvestite uporabnike, ki imajo dostop do njega.", + "When a password is updated, notify its creator.": "Ko je geslo posodobljeno, obvestite njegovega ustvarjalca.", + "When a password is deleted, notify its creator.": "Ko je geslo izbrisano, obvestite njegovega ustvarjalca.", "When a permission is revoked on a consumed password, notify the owner(s) to change it.": "Ko je dovoljenje za dostop do uporabljanega gesla preklicano, obvesti lastnika/lastnike, naj ga spremenijo.", "When a user aborted a recover, notify all the administrators.": "Ko uporabnik prekine obnovo, obvestite vse administratorje.", "When a user completed a recover, notify all the administrators.": "Ko uporabnik dokonča obnovo, obvestite vse administratorje.", @@ -2056,4 +2060,4 @@ "Unable to mark the resource as expired._two": "Virov ni mogoče označiti kot poteklih.", "Unable to mark the resource as expired._few": "Virov ni mogoče označiti kot poteklih.", "Unable to mark the resource as expired._other": "Virov ni mogoče označiti kot poteklih." -} \ No newline at end of file +} diff --git a/webroot/locales/sv-SE/common.json b/webroot/locales/sv-SE/common.json index a2cd506b36..18cd57cff2 100644 --- a/webroot/locales/sv-SE/common.json +++ b/webroot/locales/sv-SE/common.json @@ -1794,6 +1794,8 @@ "What is user self registration?": "Vad är användarsjälvregistrering?", "When a comment is posted on a password, notify the users who have access to this password.": "När en kommentar läggs upp på ett lösenord, meddela de användare som har tillgång till detta lösenord.", "When a folder is created, notify its creator.": "När en mapp skapas, meddela dess skapare.", + "When a folder is updated, notify its creator.": "När en mapp uppdateras, meddela dess skapare.", + "When a folder is deleted, notify its creator.": "När en mapp tas bort, meddela dess skapare.", "When a folder is deleted, notify the users who had access to it.": "När en mapp tas bort, meddela användarna som hade tillgång till den.", "When a folder is shared, notify the users who gain access to it.": "När en mapp delas, meddela användarna som får tillgång till den.", "When a folder is updated, notify the users who have access to it.": "När en mapp är uppdaterad, meddela användarna som har tillgång till den.", @@ -1802,6 +1804,8 @@ "When a password is deleted, notify the users who had access to it.": "När ett lösenord tas bort, meddela användarna som hade tillgång till det.", "When a password is shared, notify the users who gain access to it.": "När ett lösenord delas, meddela användarna som får tillgång till det.", "When a password is updated, notify the users who have access to it.": "När ett lösenord uppdateras, meddela de användare som har tillgång till det.", + "When a password is updated, notify its creator.": "När ett lösenord uppdateras, meddela dess skapare.", + "When a password is deleted, notify its creator.": "När ett lösenord tas bort, meddela dess skapare.", "When a permission is revoked on a consumed password, notify the owner(s) to change it.": "När en behörighet återkallas för ett använt lösenord, meddela ägaren(ägarna) att byta det.", "When a user aborted a recover, notify all the administrators.": "När en användare har avbrutit en återställning, meddela alla administratörer.", "When a user completed a recover, notify all the administrators.": "När en användare har slutfört en återställning, meddela alla administratörer.", @@ -1986,4 +1990,4 @@ "This resource does not need an expiry date._other": "Dessa resurser behöver inget utgångsdatum.", "Unable to mark the resource as expired._one": "Det gick inte att markera resursen som utgången.", "Unable to mark the resource as expired._other": "Det gick inte att markera resurserna som utgångna." -} \ No newline at end of file +} diff --git a/webroot/locales/uk-UA/common.json b/webroot/locales/uk-UA/common.json index 9ae627f307..1b06052865 100644 --- a/webroot/locales/uk-UA/common.json +++ b/webroot/locales/uk-UA/common.json @@ -1794,6 +1794,8 @@ "What is user self registration?": "Що таке самостійна реєстрація користувачів?", "When a comment is posted on a password, notify the users who have access to this password.": "Коли коментар додано до пароля, повідомити користувачів, у яких є доступ до цього пароля.", "When a folder is created, notify its creator.": "Коли теку створено, повідомити її творця.", + "When a folder is updated, notify its creator.": "Коли теку оновлено, повідомити її творця.", + "When a folder is deleted, notify its creator.": "Коли теку видалено, повідомити її творця.", "When a folder is deleted, notify the users who had access to it.": "Коли теку видалено, повідомити користувачів які мали доступ до неї.", "When a folder is shared, notify the users who gain access to it.": "Коли текою поділились, повідомити користувачів, які отримали доступ до неї.", "When a folder is updated, notify the users who have access to it.": "Коли теку оновлено, повідомити користувачів які мають доступ до неї.", @@ -1802,6 +1804,8 @@ "When a password is deleted, notify the users who had access to it.": "Коли пароль видалено, повідомити користувачів які мали доступ до нього.", "When a password is shared, notify the users who gain access to it.": "Коли паролем поділились, повідомити користувачів, які отримали доступ до нього.", "When a password is updated, notify the users who have access to it.": "Коли пароль оновлено, повідомити користувачів які мають доступ до нього.", + "When a password is updated, notify its creator.": "Коли пароль оновлено, повідомити його творця.", + "When a password is deleted, notify its creator.": "Коли пароль видалено, повідомити його творця.", "When a permission is revoked on a consumed password, notify the owner(s) to change it.": "Коли дозвіл на використаний пароль відкликається, повідомляйте власника(ів) про необхідність його змінити.", "When a user aborted a recover, notify all the administrators.": "Коли користувач перервав відновлення, повідомити усіх адміністраторів.", "When a user completed a recover, notify all the administrators.": "Коли користувач завершив відновлення, повідомити усіх адміністраторів.", @@ -2056,4 +2060,4 @@ "Unable to mark the resource as expired._few": "Неможливо позначити ресурси як прострочені.", "Unable to mark the resource as expired._many": "Неможливо позначити ресурси як прострочені.", "Unable to mark the resource as expired._other": "Неможливо позначити ресурси як прострочені." -} \ No newline at end of file +}