diff --git a/config/default.php b/config/default.php index 0bc0f0979c..424f476389 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 779ff891f4..528a3488d9 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 20b09e6855..e321b67843 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 dd9a3043b3..06a3e1ddbe 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 38d96dc2d8..8c8a0ad024 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 321e12aca0..af3011c6e1 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 b2e9539a42..fb8f242d24 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 f5dcb60e1a..2a304c4e29 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 d378446892..b36906552c 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 9b34a34bcb..f4af93b12c 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 72916188a5..cbdf34cd83 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 58bf042659..296f2506af 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 29942a0035..7b4294fdec 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 a62e42c86c..d2398020f4 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 9bc7fbb6f2..e85d934c84 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 bfbbb685f6..d2d2098a33 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 e5e43bbb7e..cec6683ebf 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 101dc2b169..b5a8c6b638 100644 --- a/src/Controller/Resources/ResourcesDeleteController.php +++ b/src/Controller/Resources/ResourcesDeleteController.php @@ -94,12 +94,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 @@ -144,7 +143,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 fcf20f5cdf..9049116dfa 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={1939(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 y 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(b.Provider,{value:this.state},this.props.children)}}y.displayName="ContextualMenuContextProvider",y.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 x=a(4625),S=a(6347);function C(){return C=Object.assign?Object.assign.bind():function(e){for(var t=1;tn.createElement(e,C({context:t},this.props)))}}}const T=_;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 be{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 ye(){return ye=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 be.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,ye({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 Se 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),b=Ie.passwordExpirySettings.test(t),y=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),x=Ie.scim.test(t),S=Ie.secretHistory.test(t),C=Ie.mfaPolicyTeasing.test(t),_=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||C?D=Te.MFA_POLICY:i||_?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:b?D=Te.PASSWORD_EXPIRY:y?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:x||P?D=Te.SCIM:S&&(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(xe.Provider,{value:this.state},this.props.children)}}Se.displayName="AdministrationWorkspaceContextProvider",Se.propTypes={context:i().object,children:i().any,location:i().object,match:i().object,history:i().object,loadingContext:i().object,rbacContext:i().object};const Ce=(0,S.withRouter)(N(we((_e=Se,class extends n.Component{render(){return n.createElement(I.Consumer,null,e=>n.createElement(_e,A({loadingContext:e},this.props)))}}))));var _e;function Ne(e){return class extends n.Component{render(){return n.createElement(xe.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(b.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,S.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 bt(){return bt=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:yt,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:yt,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,xt;function St(){return St=Object.assign?Object.assign.bind():function(e){for(var t=1;tn.createElement(e,bt({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}}const Xt=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}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.")}},Qt=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)}},ea=class extends he{constructor(e,t={}){super(e,t),this._props.pagination&&(this._pagination=new Qt(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}},ta=class extends he{constructor(e,t={}){super(e,t),this._props.header&&(this._header=new ea(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 aa extends Xt{constructor(e){super(e,"metadata/settings/")}async get(){const e=await this.apiClient.get("getting-started");return new ta(e)}}class na{constructor(e){this.metadataGettingStartedSettingsApiService=new aa(e)}async findGettingStartedSettings(){try{const e=await this.metadataGettingStartedSettingsApiService.get();return new Jt(e.body)}catch(e){return console.error(e),Jt.createFromDefault()}}}class sa{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 ia(){return ia=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},metadataGettingStartedSettings:null,update:()=>{}});class oa 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(ra.Provider,{value:this.state},this.props.children)}}oa.propTypes={service:i().oneOfType([i().instanceOf(na),i().instanceOf(sa)]),children:i().any};const la=oa;function ca(e){return class extends n.Component{render(){return n.createElement(ra.Consumer,null,t=>n.createElement(e,ia({administrationEncryptedMetadataGettingStartedContext:t,metadataGettingStartedSettings:t.get()},this.props)))}}}var ma,da;function ua(){return ua=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(pa,{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(pa,{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(pa,{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(pa,{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(pa,{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(pa,{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(pa,{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"))))))))))}}ha.propTypes={context:i().object,administrationWorkspaceContext:i().object,history:i().object,navigationContext:i().any,metadataGettingStartedSettings:i().instanceOf(Jt)};const ga=(0,S.withRouter)(N(Ke(Ne(ca((0,f.CI)("common")(ha))))));var ba,ya;function fa(){return fa=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 Aa 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 xa,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 xa(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 _a(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(Ta.Provider,{value:this.state},this.props.children)}}Aa.propTypes={context:i().any,children:i().any};const Ia=N(Aa);function Ra(e){return class extends n.Component{render(){return n.createElement(Ta.Consumer,null,t=>n.createElement(e,Na({adminMfaContext:t},this.props)))}}}var Pa=a(3050),Da=a.n(Pa);class Oa{constructor(e,t){this.context=e,this.translation=t}static getInstance(e,t){return this.instance||(this.instance=new Oa(e,t)),this.instance}static killInstance(){this.instance=null}validateInput(e,t,a){const n=e.trim();return n.length?Da()(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 Ma=Oa;class Ua extends n.Component{constructor(e){super(e),this.bindCallbacks(),this.mfaFormService=Ma.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"))))}}Ua.propTypes={adminMfaContext:i().object,actionFeedbackContext:i().object,t:i().func};const Fa=Ra(m((0,f.CI)("common")(Ua)));var ja,La;function qa(){return qa=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:"4096",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(za,{className:"svg-icon eye-open"}),this.state.viewPassword&&n.createElement(Ga,{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)))}}Ba.defaultProps={id:"",name:"",autoComplete:"off"},Ba.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})};const Wa=(0,f.CI)("common")(Ba);var Ha=a(961);function $a(e,t,a){return n.createElement(n.Fragment,null,t&&(0,Ha.createPortal)(e,t,a))}class Ya extends n.Component{constructor(e){super(e),this.mfaFormService=Ma.getInstance(this.props.adminMfaContext,this.props.t),this.bindCallbacks()}async componentDidMount(){this.props.administrationWorkspaceContext.setDisplayAdministrationWorkspaceAction(Fa),this.isRunningUnderHttps&&this.props.adminMfaContext.findMfaSettings()}componentWillUnmount(){this.props.administrationWorkspaceContext.resetDisplayAdministrationWorkspaceAction(),this.props.adminMfaContext.clearContext(),Ma.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(Wa,{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(Wa,{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(Fa,null),$a(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(Ea,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}Ya.propTypes={context:i().object,adminMfaContext:i().object,createPortal:i().func,administrationWorkspaceContext:i().object,t:i().func};const Za=N(Ra(Ne((0,f.CI)("common")(Ya))));class Ja 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)}}Ja.propTypes={items:i().array,children:i().any};const Xa=Ja;class Qa extends n.Component{render(){return n.createElement("button",{type:"button",className:"link no-border inline ellipsis",onClick:this.props.onClick},this.props.name)}}Qa.propTypes={name:i().string,onClick:i().func};const en=Qa;class tn extends n.Component{get items(){switch(this.props.administrationWorkspaceContext.selectedAdministration){case Te.NONE:return[];case Te.HOME:return[n.createElement(en,{key:"bread-2",name:this.translate("Home"),onClick:this.onLastBreadcrumbClick.bind(this)})];default:return[n.createElement(en,{key:"bread-3",name:this.translate("Home"),onClick:this.props.navigationContext.onGoToAdministrationRequested}),n.createElement(en,{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(Xa,{items:this.items})}}tn.propTypes={administrationWorkspaceContext:i().object,location:i().object,history:i().object,navigationContext:i().any,t:i().func};const an=(0,S.withRouter)(Ke(Ne((0,f.CI)("common")(tn)))),nn=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 sn;function rn(){return rn=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(on,{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))))))}}ln.defaultProps={id:"",name:"select",className:"",direction:"bottom"},ln.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:nn.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 cn=(0,f.CI)("common")(ln);class mn 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)}}mn.defaultProps={value:n.createElement(f.x6,null,"Cancel")},mn.propTypes={disabled:i().bool,onClick:i().func,value:i().oneOfType([i().arrayOf(i().node),i().node,i().string])};const dn=(0,f.CI)("common")(mn);var un,pn;function hn(){return hn=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(gn,null))))}}bn.propTypes={onClose:i().func,title:i().string};const yn=(0,f.CI)("common")(bn),fn="directorysync",En=class{constructor(e){this.apiClientOptions=e,e.setResourceName(`${fn}`)}async findAll(){this.apiClientOptions.setResourceName(`${fn}/settings`);const e=new pt(this.apiClientOptions);return(await e.findAll()).body}async update(e){this.apiClientOptions.setResourceName(`${fn}`);const t=new pt(this.apiClientOptions);return(await t.update("settings",e)).body}async delete(){return this.apiClientOptions.setResourceName(`${fn}`),new pt(this.apiClientOptions).delete("settings")}async test(e){return this.apiClientOptions.setResourceName(`${fn}/settings/test`),new pt(this.apiClientOptions).create(e)}async simulate(){this.apiClientOptions.setResourceName(`${fn}`);const e=new pt(this.apiClientOptions);return(await e.get("synchronize/dry-run")).body}async synchronize(){this.apiClientOptions.setResourceName(`${fn}/synchronize`);const e=new pt(this.apiClientOptions);return(await e.create({})).body}},vn=/^[a-f0-9]{8}-[a-f0-9]{4}-[0-5][a-f0-9]{3}-[089ab][a-f0-9]{3}-[a-f0-9]{12}$/i,wn=e=>new(Da())(vn).test(e);class kn extends Xt{constructor(e){super(e,kn.RESOURCE_NAME)}static getSupportedContainOptions(){return["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"]}async findAll(e={},t={}){e=e?this.formatContainOptions(e,kn.getSupportedContainOptions()):null,t=t?this.formatFilterOptions(t,kn.getSupportedFiltersOptions()):null;const a={...e,...t},n=await this.apiClient.findAll(a);return new ta(n)}async findByRoleId(e){return wn(e),this.findAll({},{"has-role-id":e})}static get RESOURCE_NAME(){return"users"}}const xn=kn,Sn="mail",Cn="uniqueMember";class _n{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=_n.defaultFieldsMapping(e.fields_mapping),this.fallbackFields=_n.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=_n.defaultFieldsMapping(),this.fallbackFields=_n.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:Sn,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:Cn},e?.openldap?.group)}}}static defaultFallbackFields(e={}){return{ad:Object.assign({username:""},e?.ad)}}static get DEFAULT_AD_FIELDS_MAPPING_USER_USERNAME_VALUE(){return Sn}static get DEFAULT_OPENLDAP_FIELDS_MAPPING_GROUP_USERS_VALUE(){return Cn}}const Nn=_n,Tn=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 An(){return An=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 Pn extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.userDirectoryService=new En(e.context.getApiClientOptions()),this.userService=new xn(e.context.getApiClientOptions())}get defaultState(){return{users:[],errors:this.initErrors(),mustSynchronize:!1,currentSettings:null,settings:new Nn,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.userService.findAll()).body,a=t.find(e=>this.props.context.loggedInUser.id===e.id),n=new Nn(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=Nn.DEFAULT_AD_FIELDS_MAPPING_USER_USERNAME_VALUE,this.setError("fieldsMappingAdUserUsernameError",null),this.setError("fieldsMappingAdUserUsernameFallbackeError",null)),this.isOpenLdapFieldsMappingGroupUsersResetNeeded(e,t)&&(a.fieldsMapping.openldap.group.users=Nn.DEFAULT_OPENLDAP_FIELDS_MAPPING_GROUP_USERS_VALUE,this.setError("fieldsMappingOpenLdapGroupUsersError",null)),this.setState({settings:a})}isAdFieldsMappingUserUsernameResetNeeded(e,t){return e===In&&"openldap"===t}isOpenLdapFieldsMappingGroupUsersResetNeeded(e,t){return e===In&&"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 Tn(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 Tn(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(Rn.Provider,{value:this.state},this.props.children)}}Pn.propTypes={context:i().any,children:i().any,dialogContext:i().object};const Dn=N(h(Pn));function On(e){return class extends n.Component{render(){return n.createElement(Rn.Consumer,null,t=>n.createElement(e,An({adminUserDirectoryContext:t},this.props)))}}}var Mn=a(8140),Un=a.n(Mn);class Fn 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`;Un()(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(yn,{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(dn,{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")))))}}Fn.propTypes={onClose:i().func,dialogContext:i().object,actionFeedbackContext:i().any,adminUserDirectoryContext:i().object,t:i().func};const jn=m(On((0,f.CI)("common")(Fn)));class Ln 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`;Un()(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(yn,{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")))))}}Ln.propTypes={onClose:i().func,actionFeedbackContext:i().any,adminUserDirectoryContext:i().object,t:i().func};const qn=m(On((0,f.CI)("common")(Ln)));class zn{constructor(e,t){this.context=e,this.translate=t}static getInstance(e,t){return this.instance||(this.instance=new zn(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?Da()("^[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 Kn=zn;class Vn 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(Vn,{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,")"))))}}Vn.propTypes={node:i().object};const Gn=Vn;class Bn 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(Gn,{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"))))}}Bn.propTypes={context:i().any,onClose:i().func,t:i().func};const Wn=N((0,f.CI)("common")(Bn));var Hn;function $n(){return $n=Object.assign?Object.assign.bind():function(e){for(var t=1;tthis.handleFormSubmit("test")},n.createElement(Yn,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(ts,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(is,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"))))}}rs.propTypes={context:i().object,dialogContext:i().object,adminUserDirectoryContext:i().object,actionFeedbackContext:i().object,t:i().func};const os=N(m(h(On((0,f.CI)("common")(rs)))));var ls,cs;function ms(){return ms=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(cn,{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(cn,{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(cn,{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(cn,{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(os,null),$a(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(ds,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation"))))),document.getElementById("administration-help-panel")))}}us.propTypes={adminUserDirectoryContext:i().object,administrationWorkspaceContext:i().object,t:i().func};const ps=On(Ne((0,f.CI)("common")(us)));var hs;function gs(){return gs=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},getSettings:()=>{},setSettings:()=>{},hasSettingsChanges:()=>{},findEmailNotificationSettings:()=>{},save:()=>{},setProcessing:()=>{},isProcessing:()=>{},clearContext:()=>{}});class Ss extends n.Component{constructor(e){super(e),this.state=this.defaultState;const t=e.context.getApiClientOptions();this.emailNotificationService=new Es(t)}get defaultState(){return{currentSettings:null,settings:new vs,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 vs(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 ws(this.state.settings);await this.emailNotificationService.save(e),await this.findEmailNotificationSettings()}render(){return n.createElement(xs.Provider,{value:this.state},this.props.children)}}Ss.propTypes={context:i().any,children:i().any};const Cs=N(Ss);function _s(e){return class extends n.Component{render(){return n.createElement(xs.Consumer,null,t=>n.createElement(e,ks({adminEmailNotificationContext:t},this.props)))}}}class Ns 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"))))}}Ns.propTypes={adminEmailNotificationContext:i().object,actionFeedbackContext:i().object,t:i().func};const Ts=_s(m((0,f.CI)("common")(Ns)));class As 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(Ts,null),$a(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(Ea,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation"))))),document.getElementById("administration-help-panel")))}}As.propTypes={context:i().any,administrationWorkspaceContext:i().object,adminEmailNotificationContext:i().object,t:i().func};const Is=N(_s(Ne((0,f.CI)("common")(As))));var Rs,Ps,Ds=a(8097);function Os(){return Os=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},findSubscriptionKey:()=>{},isProcessing:()=>{},setProcessing:()=>{},getActiveUsers:()=>{},clearContext:()=>{}});class ci extends n.Component{constructor(e){super(e),this.state=this.defaultState}get defaultState(){return{subscription:new ri,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 ri;try{const t=await this.props.context.onGetSubscriptionKeyRequested();e=new ri(t.toDto())}catch(t){"PassboltSubscriptionError"===t.name&&(e=new ri(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(li.Provider,{value:this.state},this.props.children)}}function mi(e){return class extends n.Component{render(){return n.createElement(li.Consumer,null,t=>n.createElement(e,oi({adminSubscriptionContext:t},this.props)))}}}ci.propTypes={context:i().any,children:i().any},N(ci);const di=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"}},ui=class{constructor(e){this.port=e}async findOrganizationSubscriptionKey(){const e=await this.port.request("passbolt.subscription.get");return new di(e)}async updateOrganizationSubscriptionKey(e){(0,ie.A)(e);const t=await this.port.request("passbolt.subscription.update",{data:e});return new di(t)}};class pi extends n.Component{constructor(e){super(e),this.state=this.getDefaultState(),this.initEventHandlers(),this.createInputRef(),this.subscriptionKeyService=new ui(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{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.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))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement(dn,{disabled:this.hasAllInputDisabled(),onClick:this.handleCloseClick}),n.createElement(ii,{disabled:this.hasAllInputDisabled(),processing:this.state.processing,value:this.translate("Save")}))))}}pi.propTypes={context:i().any,onClose:i().func,actionFeedbackContext:i().any,adminSubscriptionContext:i().object,dialogContext:i().any,administrationWorkspaceContext:i().any,t:i().func};const hi=N(mi(Ne(m(h((0,f.CI)("common")(pi))))));class gi{constructor(e){this.context=e.context,this.dialogContext=e.dialogContext,this.subscriptionContext=e.adminSubscriptionContext}static getInstance(e){return this.instance||(this.instance=new gi(e)),this.instance}static killInstance(){this.instance=null}editSubscription(){const e={key:this.subscriptionContext.getSubscription().data};this.context.setContext({editSubscriptionKey:e}),this.dialogContext.open(hi)}}const bi=gi,yi=(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})};var fi,Ei;function vi(){return vi=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},getLocale:()=>{},supportedLocales:()=>{},setLocale:()=>{},hasLocaleChanges:()=>{},findLocale:()=>{},save:()=>{},setProcessing:()=>{},isProcessing:()=>{},clearContext:()=>{}});class Pi extends n.Component{constructor(e){super(e),this.state=this.defaultState;const t=e.context.getApiClientOptions();this.internalisationService=new Ai(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(Ri.Provider,{value:this.state},this.props.children)}}Pi.propTypes={context:i().any,children:i().any};const Di=N(Pi);function Oi(e){return class extends n.Component{render(){return n.createElement(Ri.Consumer,null,t=>n.createElement(e,Ii({adminInternationalizationContext:t},this.props)))}}}class Mi 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"))))}}Mi.propTypes={context:i().object,adminInternationalizationContext:i().object,actionFeedbackContext:i().object,t:i().func};const Ui=Oi(m((0,f.CI)("common")(Mi)));class Fi 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(cn,{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),$a(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(Ti,null),n.createElement("span",null,n.createElement(f.x6,null,"Contribute")))),document.getElementById("administration-help-panel")))}}Fi.propTypes={context:i().object,administrationWorkspaceContext:i().object,adminInternationalizationContext:i().object,t:i().func};const ji=N(Oi(Ne((0,f.CI)("common")(Fi))));function Li(){return Li=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},getKeyInfo:()=>{},changePolicy:()=>{},changePublicKey:()=>{},hasPolicyChanges:()=>{},resetChanges:()=>{},downloadPrivateKey:()=>{},save:()=>{}});class zi 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(qi.Provider,{value:this.state},this.props.children)}}function Ki(e){return class extends n.Component{render(){return n.createElement(qi.Consumer,null,t=>n.createElement(e,Li({adminAccountRecoveryContext:t},this.props)))}}}function Vi(){return Vi=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},stop:()=>{}});class Bi 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(Gi.Provider,{value:this.state},this.props.children)}}Bi.displayName="WorkflowContextProvider",Bi.propTypes={children:i().any};class Wi 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(Wa,{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(dn,{disabled:this.hasAllInputDisabled(),onClick:this.handleCloseClick}),n.createElement(ii,{disabled:this.hasAllInputDisabled(),processing:this.state.processing,value:this.translate("Submit")}))))}}Wi.propTypes={context:i().any.isRequired,onClose:i().func,onSubmit:i().func,actionFeedbackContext:i().any,dialogContext:i().object,t:i().func};const Hi=N(h((0,f.CI)("common")(Wi)));class $i 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},yi(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(dn,{onClick:this.handleClose,disabled:this.isProcessing}),n.createElement(ii,{value:this.translate("Save"),disabled:this.isProcessing,processing:this.isProcessing,warning:!0}))))}}$i.propTypes={context:i().any,onClose:i().func,onSubmit:i().func,policy:i().string,keyInfo:i().object,t:i().func};const Yi=N((0,f.CI)("common")($i));class Zi 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(Yi,{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(Hi,{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)}}Zi.propTypes={dialogContext:i().any,adminAccountRecoveryContext:i().any,actionFeedbackContext:i().object,context:i().object,onStop:i().func.isRequired,t:i().func};const Ji=N(h(m(Ki((0,f.CI)("common")(Zi)))));class Xi 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(Ji,{})}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"))))}}Xi.propTypes={adminAccountRecoveryContext:i().object,workflowContext:i().any};const Qi=function(e){return class extends n.Component{render(){return n.createElement(Gi.Consumer,null,t=>n.createElement(e,Vi({workflowContext:t},this.props)))}}}(Ki((0,f.CI)("common")(Xi)));class er 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))}}er.propTypes={name:i().string,type:i().string.isRequired,isActive:i().bool,onClick:i().func,children:i().any};const tr=er;class ar 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(tr,{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))}}ar.propTypes={activeTabName:i().string,children:i().any};const nr=ar;class sr 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(dn,{disabled:this.hasAllInputDisabled(),onClick:this.props.onClose}),n.createElement(ii,{disabled:this.hasAllInputDisabled(),processing:this.state.processing,value:this.translate("Apply")})))}}sr.propTypes={context:i().object,onUpdateOrganizationKey:i().func,onClose:i().func,t:i().func};const ir=N((0,f.CI)("common")(sr)),rr={"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 or=a(2052),lr=a.n(or);const cr=[{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}],mr={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:["😀","😁","😂","😃","😄","😅","😆","😇","😈","😉","😊","😋","😌","😍","😎","😏","😐","😑","😒","😓","😔","😕","😖","😗","😘","😙","😚","😛","😜","😝","😞","😟","😠","😡","😢","😣","😤","😥","😦","😧","😨","😩","😪","😫","😬","😭","😮","😯","😰","😱","😲","😳","😴","😵","😶","😷","😸","😹","😺","😻","😼","😽","😾","😿","🙀","🙁","🙂","🙃","🙄","🙅","🙆","🙇","🙈","🙉","🙊","🙋","🙌","🙍","🙎","🙏"]}},dr=["O","l","|","I","0","1"],ur=Object.values(mr).flatMap(e=>e.characters),pr={evaluateMaxPasswordEntropy:e=>{const t=Object.entries(mr).filter(([t])=>e[t]).reduce((e,[t])=>[...e,...mr[t].characters],[]).filter(t=>!e.exclude_look_alike_chars||!dr.includes(t));return hr(e.length,t.length)},entropyPassword:(e="")=>{const t=(new(lr())).splitGraphemes(e);let a=0;for(const[e]of Object.entries(mr)){const n=mr[e];t.some(e=>n.characters.includes(e))&&(a+=n.characters.length)}const n=new Set(t.filter(e=>!ur.includes(e)));return hr(t.length,a+n.size)},entropyPassphrase:(e=0,t="")=>hr(e,3*rr["en-UK"].length)+pr.entropyPassword(t),strength:(e=0)=>cr.reduce((t,a)=>t?a.strength>t.strength&&e>=a.strength?a:t:a),calculEntropy:hr};function hr(e,t){return e&&t?e*(Math.log(t)/Math.log(2)):0}const gr=function(e){const t={isPassphrase:!1};if(!e)return t;const a=rr["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}},wr=(e,t)=>t.split(".").reduce((e,t)=>e?.[t],e),kr=(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||[xr.HTTP,xr.HTTPS],n=[xr.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}},xr={FTP:"http:",FTPS:"https:",HTTP:"http:",HTTPS:"https:",JAVASCRIPT:"javascript:",SSH:"ssh:"};class Sr{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=wr(this.settings,a)||null;if(n&&"object"==typeof n){const e=wr(n,"enabled");void 0!==e&&!0!==e||(t=!0)}return t}isFeatureBeta(e){(0,ie.A)(e);const t=`passbolt.plugins.${e}.isInBeta`;return wr(this.settings,t)||!1}getPluginSettings(e){const t=`passbolt.plugins.${e}`;return wr(this.settings,t)}getRememberMeOptions(){return(this.getPluginSettings("rememberMe")||{}).options||{}}get hasRememberMeUntilILogoutOption(){return void 0!==(this.getRememberMeOptions()||{})[-1]}getServerTimezone(){return wr(this.settings,"passbolt.app.server_timezone")}get termsLink(){const e=wr(this.settings,"passbolt.legal.terms.url");return!!e&&kr(e)}get privacyLink(){const e=wr(this.settings,"passbolt.legal.privacy_policy.url");return!!e&&kr(e)}get registrationPublic(){return!0===wr(this.settings,"passbolt.registration.public")}get debug(){return!0===wr(this.settings,"app.debug")}get url(){return wr(this.settings,"app.url")||""}get version(){return wr(this.settings,"app.version.number")}get isCommunityEdition(){return"ce"===wr(this.settings,"passbolt.edition")}get locale(){return wr(this.settings,"app.locale")||Sr.DEFAULT_LOCALE.locale}async setLocale(e){this.settings.app.locale=e}get supportedLocales(){return wr(this.settings,"passbolt.plugins.locale.options")||Sr.DEFAULT_SUPPORTED_LOCALES}get generatorConfiguration(){return wr(this.settings,"passbolt.plugins.generator.configuration")}get emailValidateRegex(){return this.settings?.passbolt?.email?.validate?.regex||null}static get DEFAULT_SUPPORTED_LOCALES(){return[Sr.DEFAULT_LOCALE]}static get DEFAULT_LOCALE(){return{locale:"en-UK",label:"English"}}}class Cr{static validate(e){return"string"==typeof e&&Da()("^[\\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 _r{constructor(e){if("string"!=typeof e)throw Error("The regex should be a string.");this.regex=new(Da())(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 Sr&&e.emailValidateRegex?new _r(e.emailValidateRegex):Cr}}function Tr(){return Tr=Object.assign?Object.assign.bind():function(e){for(var t=1;t{}});class Ir 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(Ar.Provider,{value:this.state},this.props.children)}}function Rr(e){return class extends n.Component{render(){return n.createElement(Ar.Consumer,null,t=>n.createElement(e,Tr({passwordPoliciesContext:t},this.props)))}}}Ir.propTypes={context:i().any,children:i().any},N(Ir);class Pr 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 Pr.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=pr.strength(this.props.entropy);return n.createElement(n.Fragment,null,e.label)}getProgresseBarStyle(e){return{width:`${Pr.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"})))))}}Pr.defaultProps={isMinimumEntropyRequired:!0},Pr.propTypes={targetEntropy:i().number.isRequired,isMinimumEntropyRequired:i().bool.isRequired,entropy:i().number,error:i().bool,t:i().func};const Dr=(0,f.CI)("common")(Pr);class Or 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 vr(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}=gr(e);return n?pr.entropyPassphrase(t,a):pr.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 yr||e instanceof Er))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(Wa,{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(Dr,{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(Wa,{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(dn,{disabled:this.hasAllInputDisabled(),onClick:this.props.onClose}),n.createElement(ii,{disabled:this.hasAllInputDisabled(),processing:this.state.processing,value:this.translate("Generate & Apply")})))}}Or.propTypes={context:i().any,onUpdateOrganizationKey:i().func,onClose:i().func,t:i().func,passwordPoliciesContext:i().object};const Mr=N(h(Rr((0,f.CI)("common")(Or))));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},yi(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},yi(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(Qi,null),$a(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(Vr,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}Gr.propTypes={context:i().object,dialogContext:i().any,administrationWorkspaceContext:i().object,adminAccountRecoveryContext:i().object,t:i().func};const Br=N(h(Ne(Ki((0,f.CI)("common")(Gr)))));class Wr 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(pa,{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(bs,null),n.createElement(f.x6,null,"In case of passphrase loss.")),n.createElement("li",null,n.createElement(bs,null),n.createElement(f.x6,null,"In case of private key loss.")),n.createElement("li",null,n.createElement(bs,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")))))),$a(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(Vr,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}Wr.propTypes={context:i().object,t:i().func};const Hr=N((0,f.CI)("common")(Wr)),$r={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 Yr(e,t){const a=[];for(let n=0;n(!a||e.host===a)&&e.port===t)}const Jr={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:Yr(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])};Jr.defaultConfiguration=Zr(Jr,587,"email-smtp.eu-central-1.amazonaws.com");const Xr={id:"elastic-email",name:"ElasticEmail",icon:"elastic-email.svg",help_page:"https://help.elasticemail.com/en/articles/4803409-smtp-settings",availableConfigurations:Yr(["smtp.elasticemail.com","smtp25.elasticemail.com"],[25,2525,587])};Xr.defaultConfiguration=Zr(Xr,587,"smtp.elasticemail.com");const Qr={id:"google-workspace",name:"Google Workspace",icon:"gmail.svg",help_page:"https://support.google.com/a/answer/2956491",availableConfigurations:Yr(["smtp-relay.gmail.com"],[25,587])};Qr.defaultConfiguration=Zr(Qr,587);const eo={id:"google-mail",name:"Google Mail",icon:"gmail.svg",help_page:"https://support.google.com/a/answer/2956491",availableConfigurations:Yr(["smtp.gmail.com"],[587])};eo.defaultConfiguration=Zr(eo,587);const to={id:"mailgun",name:"MailGun",icon:"mailgun.svg",help_page:"https://documentation.mailgun.com/en/latest/quickstart-sending.html",availableConfigurations:Yr(["smtp.mailgun.com"],[587])};to.defaultConfiguration=to.availableConfigurations[0];const ao={id:"mailjet",name:"Mailjet",icon:"mailjet.svg",help_page:"https://dev.mailjet.com/smtp-relay/configuration/",availableConfigurations:Yr(["in-v3.mailjet.com"],[25,2525,587,588])};ao.defaultConfiguration=Zr(ao,587);const no={id:"mandrill",name:"Mandrill",icon:"mandrill.svg",help_page:"https://mailchimp.com/developer/transactional/docs/smtp-integration/",availableConfigurations:Yr(["smtp.mandrillapp.com"],[25,2525,587])};no.defaultConfiguration=Zr(no,587);const so={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:Yr(["smtp.office365.com"],[25,587])};so.defaultConfiguration=Zr(so,587);const io={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:Yr(["smtp-mail.outlook.com"],[587])};io.defaultConfiguration=Zr(io,587);const ro={id:"sendgrid",name:"Sendgrid",icon:"sendgrid.svg",help_page:"https://docs.sendgrid.com/for-developers/sending-email/integrating-with-the-smtp-api",availableConfigurations:Yr(["smtp.sendgrid.net"],[25,2525,587])};ro.defaultConfiguration=Zr(ro,587);const oo={id:"sendinblue",name:"Sendinblue",icon:"sendinblue.svg",help_page:"https://help.sendinblue.com/hc/en-us/articles/209462765",availableConfigurations:Yr(["smtp-relay.sendinblue.com"],[25,587])};oo.defaultConfiguration=Zr(oo,587);const lo={id:"zoho",name:"Zoho",icon:"zoho.svg",help_page:"https://www.zoho.com/mail/help/zoho-smtp.html",availableConfigurations:Yr(["smtp.zoho.eu","smtppro.zoho.eu"],[587])};lo.defaultConfiguration=Zr(lo,587,"smtp.zoho.eu");const co=[Jr,Xr,eo,Qr,to,ao,no,so,io,ro,oo,lo,{id:"other",name:"Other",icon:null,availableConfigurations:[],defaultConfiguration:{host:"",port:"",tls:!0}}];class mo extends Xt{constructor(e){super(e,mo.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 ta(e)}async create(e){this.assertNonEmptyData(e);const t=await this.apiClient.create(e);return t.body.tls=Boolean(t.body.tls),new ta(t)}}const uo=mo,po=class extends he{static getSchema(){return{type:"object",required:[...Eo.getSchema().required],properties:{...Eo.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"}},ho=class extends he{static getSchema(){return{type:"object",required:[...Eo.getSchema().required,"username"],properties:{...Eo.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"}},go=class extends he{static getSchema(){return{type:"object",required:[...Eo.getSchema().required,"username","password"],properties:{...Eo.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"}},bo=class extends he{static getSchema(){return{type:"object",required:[...Eo.getSchema().required,"oauth_username","tenant_id","client_id","client_secret"],properties:{...Eo.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"}},yo="default",fo="file",Eo=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:[yo,"env","db",fo]},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 bo(e,t):"username"in e&&null!==e.username?"password"in e&&null!==e.password?new go(e,t):new ho(e,t):new po(e,t)}static get ENTITY_NAME(){return"SmtpSettings"}static get SETTINGS_SOURCE_DEFAULT(){return yo}static get SETTINGS_SOURCE_ENV(){return"env"}static get SETTINGS_SOURCE_DB(){return"db"}static get SETTINGS_SOURCE_FILE(){return fo}},vo=class{constructor(e){this.smtpSettingsApiService=new uo(e)}async find(){const e=await this.smtpSettingsApiService.find();return Eo.createFromSettings(e.body)}},wo=class{constructor(e){this.smtpSettingsApiService=new uo(e)}async save(e){const t=await this.smtpSettingsApiService.create(e.toDto());return Eo.createFromSettings(t.body)}},ko=["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 xo=a(3975);const So="(?:[_\\p{L}0-9][-_\\p{L}0-9]*\\.)*(?:[\\p{L}0-9][-\\p{L}0-9]{0,62})\\.(?:(?:[a-z]{2}\\.)?[a-z]{2,})",Co=class{static extractDomainFromEmail(e){const t=Da()(`(?<=@)${So}`);return Da().match(e,t)||""}static isProfessional(e){return!ko.includes(e)}static checkDomainValidity(e){if(!Da()(`^${So}$`).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 Da()(`^${So}$`).test(e)||(0,xo.A)({exact:!0}).test(e)}},_o="none",No="username",To="username_password",Ao="oauth",Io=[po,ho,go,bo],Ro=[...new Set(Io.flatMap(e=>Object.keys(e.getDefaultData())))];class Po extends he{static getSchema(){const e=Eo.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&&(Co.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 _o:return po;case No:return ho;case To:return go;case Ao:return bo;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?Ao:null===this._props.username||void 0===this._props.username?_o:null===this._props.password||void 0===this._props.password?No:To}static createDefault(){return new Po({host:"",port:"",tls:!0,client:"",sender_email:"",sender_name:"Passbolt",...go.getDefaultData()},{validate:!1})}static get ENTITY_NAME(){return"SmtpSettingsForm"}static get AUTHENTICATION_METHOD_NONE(){return _o}static get AUTHENTICATION_METHOD_USERNAME(){return No}static get AUTHENTICATION_METHOD_USERNAME_PASSWORD(){return To}static get AUTHENTICATION_METHOD_OAUTH(){return Ao}static get AUTH_FIELDS(){return Ro}}const Do=Po;class Oo extends Xt{constructor(e){super(e,Oo.RESOURCE_NAME)}static get RESOURCE_NAME(){return"smtp/email"}async create(e){this.assertNonEmptyData(e);const t=await this.apiClient.create(e);return new ta(t)}}const Mo=Oo,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 Fo=a(1811);function jo(){return jo=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 qo extends n.Component{constructor(e){super(e),this.state=this.defaultState;const t=e.context.getApiClientOptions();this.findSmtpSettingsService=new vo(t),this.saveSmtpSettingsService=new wo(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,Fo.A)(e=>this.formSettings?.validate({validateBuildRules:{siteSettings:this.props.context.siteSettings}}));hasSettingsChanges=(0,Fo.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=Do.createDefault().toFormDto()}e.sender_email=e.sender_email??this.props.context.loggedInUser.username,this.originalSettings=new Do(e,{validate:!1});const t=this.originalSettings.toFormDto();if(t.host&&t.port){const e=this.originalSettings.detectProvider(co);this.originalSettings.set("provider",e,{validate:!1})}this.formSettings=new Do(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=Eo.createFromSettings(e);await this.saveSmtpSettingsService.save(t),this.props.actionFeedbackContext.displaySuccess(this.props.t("The SMTP settings have been saved successfully")),this.originalSettings=new Do(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=Eo.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(co);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()===Do.AUTHENTICATION_METHOD_OAUTH&&this.formSettings.changeAuthenticationMethod(Do.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(co);this.formSettings.set("provider",t,{validate:!1}),"office-365"!==t&&this.formSettings.getAuthenticationMethod()===Do.AUTHENTICATION_METHOD_OAUTH&&this.formSettings.changeAuthenticationMethod(Do.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(Lo.Provider,{value:this.state},this.props.children)}}qo.propTypes={context:i().any,dialogContext:i().object,actionFeedbackContext:i().object,children:i().any,t:i().func};const zo=N(h(m((0,f.CI)("common")(qo))));function Ko(e){return class extends n.Component{render(){return n.createElement(Lo.Consumer,null,t=>n.createElement(e,jo({adminSmtpSettingsContext:t},this.props)))}}}const Vo="form",Go="error",Bo="success";class Wo extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.bindCallbacks()}get defaultState(){return{uiState:Vo,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:Bo,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:Go,debugDetails:this.formatDebug(a),displayLogs:!0})}handleDisplayLogsClick(){this.setState({displayLogs:!this.state.displayLogs})}handleRetryClick(){this.setState({uiState:Vo})}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===Vo&&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(dn,{disabled:this.hasAllInputDisabled(),onClick:this.props.handleClose}),n.createElement(ii,{disabled:this.hasAllInputDisabled(),processing:this.state.processing,value:this.translate("Send")}))),this.state.uiState===Go&&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===Bo&&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"))))))}}Wo.propTypes={context:i().object,adminSmtpSettingsContext:i().object,handleClose:i().func,t:i().func};const Ho=N(Ko((0,f.CI)("common")(Wo)));var $o,Yo;function Zo(){return Zo=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 co.map(e=>({value:e.id,label:e.name}))}get authenticationMethodList(){const e=this.props.adminSmtpSettingsContext.getCurrentSmtpSettings(),t=[{value:nl,label:this.translate("None")},{value:sl,label:this.translate("Username only")},{value:il,label:this.translate("Username & password")}];return"office-365"===e?.provider&&t.push({value:rl,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===sl||this.authenticationMethod===il}shouldDisplayPassword(){return this.authenticationMethod===il}shouldDisplayOAuth(){return this.authenticationMethod===rl}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=co.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"},co.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(wi,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(cn,{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(cn,{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(Wa,{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(Wa,{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(cn,{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(Qo,null)),$a(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(ds,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(al,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(ds,null),n.createElement("span",null,n.createElement(f.x6,null,"More informations"))))),document.getElementById("administration-help-panel")))}}ol.propTypes={context:i().object,dialogContext:i().any,administrationWorkspaceContext:i().object,adminSmtpSettingsContext:i().object,t:i().func};const ll=N(Ko(h(Ne((0,f.CI)("common")(ol))))),cl=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()]}},ml=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)}},dl=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)}},ul=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())}}},pl=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{Co.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)=>{cl.listValues(this.fields).filter(e=>e===t&&""!==e).length>1&&e.set(a,this.translate("This domain already exist"))})}};class hl 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&&cl.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(dn,{onClick:this.handleClose,disabled:e}),n.createElement(ii,{value:this.props.t("Save"),disabled:e,processing:e,warning:!0}))))}}hl.propTypes={context:i().any,onSubmit:i().func,adminSelfRegistrationContext:i().object,onClose:i().func,t:i().func};const gl=N(kl((0,f.CI)("common")(hl)));class bl 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(dn,{onClick:this.handleClose,disabled:e}),n.createElement(ii,{value:this.props.t("Save"),disabled:e,processing:e,warning:!0}))))}}bl.propTypes={adminSelfRegistrationContext:i().object,onClose:i().func,onSubmit:i().func,t:i().func};const yl=kl((0,f.CI)("common")(bl));function fl(){return fl=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 vl extends n.Component{constructor(e){super(e),this.state=this.defaultState;const t=e.context.getApiClientOptions();this.selfRegistrationService=new ml(t),this.selfRegistrationFormService=new pl(this.props.t)}get defaultState(){return{errors:new Map,submitted:!1,currentSettings:null,focus:!1,saved:!1,domains:new dl,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 dl(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=cl.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=cl.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=cl.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 ul(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(gl,{domains:this.getAllowedDomains(),onSubmit:()=>this.saveSettings(),onClose:()=>this.handleCloseDialog()})}displayConfirmDeletionDialog(){this.props.dialogContext.open(yl,{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(El.Provider,{value:this.state},this.props.children)}}vl.propTypes={context:i().any,children:i().any,t:i().any,dialogContext:i().any,actionFeedbackContext:i().object};const wl=N(h(m((0,f.CI)("common")(vl))));function kl(e){return class extends n.Component{render(){return n.createElement(El.Consumer,null,t=>n.createElement(e,fl({adminSelfRegistrationContext:t},this.props)))}}}const xl=new Map;function Sl(e){if("string"!=typeof e)return console.warn("useDynamicRefs: Cannot set ref without key");const t=n.createRef();return xl.set(e,t),t}function Cl(e){return e?xl.get(e):console.warn("useDynamicRefs: Cannot get ref without key")}var _l=a(6459),Nl=a.n(_l);class Tl 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"))))}}Tl.propTypes={adminSelfRegistrationContext:i().object,t:i().func};const Al=(0,f.CI)("common")(kl(Tl));var Il;function Rl(){return Rl=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)=>{Co.isProfessional(e)||t.set(a,"This is not a safe professional domain")}),this.setState({warnings:t})}setupSettings(){const e=new dl(this.props.adminSelfRegistrationContext.getCurrentSettings());if(this.props.adminSelfRegistrationContext.setDomains(e),this.assertNotProfessionalDomains(e.allowedDomains),0===e.allowedDomains.size){const e=Co.extractDomainFromEmail(this.currentUser?.username);Co.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=Co.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.")),cl.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(Ml,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(Pl,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(Al,null)),$a(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(ds,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 Fl=N(h(kl(Ne((0,f.CI)("common")(Ul))))),jl=[{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"}}],Ll="form",ql="success";class zl extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.bindCallbacks()}get defaultState(){return{uiState:Ll,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:ql,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===Ll&&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===ql&&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(dn,{disabled:this.hasAllInputDisabled(),onClick:this.handleCloseDialog}),n.createElement(ii,{disabled:!this.canSaveSettings(),processing:this.state.processing,value:this.translate("Save settings")}))))}}zl.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 Kl=N(fc(m((0,f.CI)("common")(zl))));class Vl 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(dn,{disabled:e,onClick:this.props.onClose}),n.createElement(ii,{warning:!0,disabled:e,processing:this.state.processing,value:this.props.t("Disable")}))))}}Vl.propTypes={adminSsoContext:i().object,onClose:i().func,t:i().func};const Gl=fc((0,f.CI)("common")(Vl)),Bl=["https://login.microsoftonline.com","https://login.microsoftonline.us","https://login.partner.microsoftonline.cn"];class Wl extends se{constructor(e,t={}){const a=Wl.sanitizeDto(e);super(ae.validate(Wl.ENTITY_NAME,a,Wl.getSchema()),t)}static getSchema(){return{type:"object",required:["url","client_id","tenant_id","client_secret","client_secret_expiry"],properties:{url:{type:"string",enum:Bl},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 Bl}}const Hl=Wl;class $l 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 Hl.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 $l(a,{validate:!1})}static createDefault(e={}){return new $l(e,{validate:!1})}static get ENTITY_NAME(){return"AzureSsoSettingsForm"}}const Yl=$l,Zl=/^https:\/\/.+[^/]$/;class Jl extends se{constructor(e,t={}){super(ae.validate(Jl.ENTITY_NAME,e,Jl.getSchema()),t)}static getSchema(){return{type:"object",required:["url","openid_configuration_path","scope","client_id","client_secret"],properties:{url:{type:"string",pattern:Zl},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 Xl=Jl;class Ql extends he{static getSchema(){const e=Xl.getSchema();return{...e,properties:{id:{type:"string"},...e.properties}}}get provider(){return Xl.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 Ql(a,{validate:!1})}static createDefault(e={}){return new Ql(e,{validate:!1})}static get ENTITY_NAME(){return"OAuth2SsoSettingsForm"}}const ec=Ql,tc=["https://accounts.google.com"];class ac extends se{constructor(e,t={}){super(ae.validate(ac.ENTITY_NAME,e,ac.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 tc}}const nc=ac;class sc extends he{static getSchema(){const e=nc.getSchema();return{...e,properties:{id:{type:"string",format:"uuid"},...e.properties}}}get provider(){return nc.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 sc(a,{validate:!1})}static createDefault(e={}){return new sc(e,{validate:!1})}static get ENTITY_NAME(){return"GoogleSsoSettingsForm"}}const ic=sc,rc=/^https:\/\/.+[^/]$/;class oc extends se{constructor(e,t={}){super(ae.validate(oc.ENTITY_NAME,e,oc.getSchema()),t)}static getSchema(){return{type:"object",required:["url","openid_configuration_path","scope","client_id","client_secret"],properties:{url:{type:"string",pattern:rc},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 lc=oc;class cc extends he{static getSchema(){const e=lc.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 lc.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 cc(a,{validate:!1})}static createDefault(e={}){return new cc(e,{validate:!1})}}const mc=cc,dc=["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"],uc=class extends he{static getSchema(){return{type:"object",required:["url","environment_id","client_id","client_secret","email_claim"],properties:{url:{type:"string",enum:dc},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 dc}};class pc extends he{static getSchema(){const e=uc.getSchema();return{...e,properties:{id:{type:"string"},...e.properties}}}get provider(){return uc.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 pc(a,{validate:!1})}static createDefault(e={}){return new pc(e,{validate:!1})}static get SCOPE(){return"openid profile email"}static get ENTITY_NAME(){return"PingOneSsoSettingsForm"}}const hc=pc;function gc(){return gc=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 yc 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,Fo.A)(e=>this.formSettings?.validate());hasSettingsChanges=(0,Fo.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 Hl.PROVIDER_ID:return Yl.fromEntityDto(e);case nc.PROVIDER_ID:return ic.fromEntityDto(e);case Xl.PROVIDER_ID:return ec.fromEntityDto(e);case lc.PROVIDER_ID:return mc.fromEntityDto(e);case uc.PROVIDER_ID:return hc.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=jl.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(Gl)}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=jl.find(t=>t.id===e.provider);this.props.dialogContext.open(Kl,{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(bc.Provider,{value:this.state},this.props.children)}}function fc(e){return class extends n.Component{render(){return n.createElement(bc.Consumer,null,t=>n.createElement(e,gc({adminSsoContext:t},this.props)))}}}yc.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")(yc))));class Ec 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"))))}}Ec.propTypes={adminSsoContext:i().object};const vc=fc((0,f.CI)("common")(Ec));var wc;function kc(){return kc=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},copy:()=>{}});class Ic 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(Ac.Provider,{value:this.state},this.props.children)}}function Rc(e){return class extends n.Component{render(){return n.createElement(Ac.Consumer,null,t=>n.createElement(e,Tc({clipboardContext:t},this.props)))}}}Ic.propTypes={context:i().any.isRequired,actionFeedbackContext:i().any.isRequired,children:i().any,t:i().func},N(m((0,f.CI)("common")(Ic)));class Pc 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(cn,{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(xc,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(Wa,{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(_c,{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(cn,{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(cn,{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."))))))}}Pc.propTypes={adminSsoContext:i().object,actionFeedbackContext:i().any,context:i().any,clipboardContext:i().object,t:i().func};const Dc=N(m(fc(Rc((0,f.CI)("common")(Pc)))));class Oc 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 uc.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(cn,{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(xc,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(Wa,{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:hc.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."))))}}Vc.propTypes={adminSsoContext:i().object,clipboardContext:i().object,context:i().any,t:i().func};const Gc=N(Rc(fc((0,f.CI)("common")(Vc))));class Bc 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 jl.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=jl.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(cn,{id:"sso-provider-input",name:"provider",items:this.supportedSsoProviders,value:t?.provider,onChange:this.handleProviderInputChange})),t?.provider===Hl.PROVIDER_ID&&n.createElement(Dc,null),t?.provider===nc.PROVIDER_ID&&n.createElement(Mc,null),t?.provider===Xl.PROVIDER_ID&&n.createElement(Fc,null),t?.provider===lc.PROVIDER_ID&&n.createElement(Lc,null),t?.provider===uc.PROVIDER_ID&&n.createElement(Gc,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(vc,null),$a(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(ds,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),t?.provider===Hl.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(Kc,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),t?.provider===nc.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(Kc,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),t?.provider===lc.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(Kc,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),t?.provider===uc.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(Kc,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation"))))),document.getElementById("administration-help-panel")))}}Bc.propTypes={administrationWorkspaceContext:i().object,adminSsoContext:i().object,actionFeedbackContext:i().any,context:i().any,t:i().func};const Wc=N(m(Ne(fc((0,f.CI)("common")(Bc)))));class Hc 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(pa,{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(bs,null),n.createElement(f.x6,null,"Reduce password fatigue and simplify login.")),n.createElement("li",null,n.createElement(bs,null),n.createElement(f.x6,null,"Centralise user authentication management.")),n.createElement("li",null,n.createElement(bs,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")))))),$a(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(ds,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}Hc.propTypes={context:i().any,t:i().func};const $c=N((0,f.CI)("common")(Hc)),Yc=class{constructor(e={remember_me_for_a_month:!1}){this.policy=e.policy,this.rememberMeForAMonth=e.remember_me_for_a_month}},Zc=class{constructor(e={rememberMeForAMonth:!1}){this.policy=e.policy||"opt-in",this.remember_me_for_a_month=e.rememberMeForAMonth}};function Jc(){return Jc=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},getSettings:()=>{},setSettings:()=>{},hasSettingsChanges:()=>{},findSettings:()=>{},setProcessing:()=>{},isProcessing:()=>{},clearContext:()=>{},save:()=>{}});class Qc 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 Yc,currentSettings:new Yc,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 Yc(t);this.setState({currentSettings:a,settings:a},e),this.setProcessing(!1)}async save(){this.setProcessing(!0);const e=new Zc(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(Xc.Provider,{value:this.state},this.props.children)}}Qc.propTypes={context:i().any,children:i().any,t:i().any,actionFeedbackContext:i().object};const em=N(Qc);function tm(e){return class extends n.Component{render(){return n.createElement(Xc.Consumer,null,t=>n.createElement(e,Jc({adminMfaPolicyContext:t},this.props)))}}}class am 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"))))}}am.propTypes={adminMfaPolicyContext:i().object,actionFeedbackContext:i().object,t:i().func};const nm=tm(m((0,f.CI)("common")(am)));class sm 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(nm,null),$a(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(ds,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}sm.propTypes={context:i().object,administrationWorkspaceContext:i().object,adminMfaPolicyContext:i().object,t:i().func};const im=N(Ne(tm((0,f.CI)("common")(sm))));class rm 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(pa,{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(bs,null),n.createElement(f.x6,null,"Strengthen user authentication.")),n.createElement("li",null,n.createElement(bs,null),n.createElement(f.x6,null,"Protect against unauthorised access.")),n.createElement("li",null,n.createElement(bs,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")))))),$a(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(Ea,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}rm.propTypes={context:i().object,t:i().func};const om=N((0,f.CI)("common")(rm));class lm extends se{constructor(e,t={}){super(ae.validate(lm.ENTITY_NAME,e,lm.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 cm=lm;class mm extends se{constructor(e,t={}){super(ae.validate(mm.ENTITY_NAME,e,mm.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 dm=mm;class um extends se{constructor(e,t={}){super(ae.validate(um.ENTITY_NAME,e,um.getSchema()),t),this._props.action&&(this._action=new cm(this._props.action,{clone:!1})),delete this._props.action,this._props.ui_action&&(this._ui_action=new dm(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:[um.FOREIGN_MODEL_ACTION,um.FOREIGN_MODEL_UI_ACTION]},foreign_id:{type:"string",format:"uuid"},control_function:{type:"string",enum:[K,V,G]},action:cm.getSchema(),ui_action:dm.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(um.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,um.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 pm=um;class hm{static error(e){console.error(e);try{e instanceof Error&&"function"==typeof e.toJSON&&console.log(`Error: ${e.message}\nError structure: ${JSON.stringify(hm.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=hm.serializeError(e.cause)),e instanceof Z&&Array.isArray(e.errors)&&(n.errors=e.errors.map(e=>hm.serializeError(e))),n}}const gm=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.`;hm.error(new Error(a,{cause:t}))}}},bm=class extends gm{get entityClass(){return pm}constructor(e=[],t={}){super(e,t)}static getSchema(){return{type:"array",items:pm.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 vm extends n.Component{constructor(e){super(e),this.state=this.defaultState;const t=e.context.getApiClientOptions();this.rbacApiService=new ym(t)}get defaultState(){return{processing:!1,rbacs:null,rbacsUpdated:new bm([]),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 pm(e)));const n=new bm([]);this.setState({rbacs:a,rbacsUpdated:n})}finally{this.setProcessing(!1)}}render(){return n.createElement(Em.Provider,{value:this.state},this.props.children)}}vm.propTypes={context:i().any,children:i().any};const wm=N(vm);function km(e){return class extends n.Component{render(){return n.createElement(Em.Consumer,null,t=>n.createElement(e,fm({adminRbacContext:t},this.props)))}}}class xm 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"))))}}xm.propTypes={context:i().object,adminRbacContext:i().object,actionFeedbackContext:i().object,t:i().func};const Sm=km(m((0,f.CI)("common")(xm)));class Cm 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 Tm 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(cn,{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(cn,{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.")))))}}Tm.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 Am=(0,f.CI)("common")(Tm);class Im extends Xt{constructor(e){super(e,Im.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 ta({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 ta(t)}async update(e,t){if(!e)throw new TypeError("Role update failed, role id is required.");if(!wn(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 ta(a)}async delete(e){if(!wn(e))throw new TypeError("Role deletion failed, roleId is not a valid uuid.");const t=await this.apiClient.delete(e);return new ta(t)}}var Rm;function Pm(){return Pm=Object.assign?Object.assign.bind():function(e){for(var t=1;tthis.roleEntity.validate(e));verifyDataHealth=(0,Fo.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(dn,{disabled:this.hasAllInputDisabled(),onClick:this.handleClose}),n.createElement(ii,{disabled:this.hasAllInputDisabled(),processing:this.state.processing,value:this.translate("Save")}))))}}zm.propTypes={onClose:i().func,onSubmit:i().func.isRequired,t:i().func};const Km=(0,f.CI)("common")(zm);function Vm(){return Vm=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},onClose:()=>{}});class Bm 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(Gm.Provider,{value:this.state},n.createElement("div",{className:"dropdown",ref:this.dropdownRef},this.props.children))}}function Wm(e){return class extends n.Component{render(){return n.createElement(Gm.Consumer,null,t=>n.createElement(e,Vm({dropdownContext:t},this.props)))}}}Bm.propTypes={children:i().any};class Hm extends n.Component{render(){return n.createElement(Bm,null,this.props.children)}}Hm.propTypes={children:i().any.isRequired};const $m=Hm;class Ym 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)}}Ym.defaultProps={disabled:!1,direction:"right",className:"button-dropdown"},Ym.propTypes={className:i().string,disabled:i().bool,direction:i().string,dropdownContext:i().any,children:i().any};const Zm=Wm(Ym);class Jm 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)}}Jm.defaultProps={direction:"right"},Jm.propTypes={direction:i().string,className:i().string,dropdownContext:i().any,children:i().any};const Xm=Wm(Jm);class Qm 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))))}}Qm.defaultProps={keepOpenOnClick:!1},Qm.propTypes={separator:i().bool,keepOpenOnClick:i().bool,dropdownContext:i().any,children:i().any};const ed=Wm(Qm);class td 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(dn,{disabled:this.hasAllInputDisabled(),onClick:this.handleClose}),n.createElement(ii,{disabled:this.hasAllInputDisabled(),processing:this.state.processing,value:this.translate("Delete"),warning:!0}))))}}td.propTypes={onClose:i().func,onSubmit:i().func,role:i().instanceOf(ge).isRequired,t:i().func};const ad=(0,f.CI)("common")(td);class nd 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,Fo.A)(e=>this.roleEntity.validate(e));verifyDataHealth=(0,Fo.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(dn,{disabled:this.hasAllInputDisabled(),onClick:this.handleClose}),n.createElement(ii,{disabled:this.hasAllInputDisabled(),processing:this.state.processing,value:this.translate("Save")}))))}}nd.propTypes={onClose:i().func,onSubmit:i().func.isRequired,role:i().instanceOf(ge).isRequired,t:i().func};const sd=(0,f.CI)("common")(nd);class id 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(dn,{disabled:this.hasAllInputDisabled(),onClick:this.handleClose}),n.createElement(ii,{disabled:this.hasAllInputDisabled(),processing:this.state.processing,value:this.translate("Ok")}))))}}id.propTypes={onClose:i().func,role:i().instanceOf(ge).isRequired,usersCount:i().number.isRequired,t:i().func};const rd=(0,f.CI)("common")(id);class od 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 bm(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 pm(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(Km,{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(rd,{role:t,usersCount:a.length}):this.props.dialogContext.open(ad,{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(sd,{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(Dm,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($m,null,n.createElement(Zm,{className:"more button-action-icon link no-border"},n.createElement(Um,null)),n.createElement(Xm,{className:"menu-action-contextual",direction:"left"},n.createElement(ed,null,n.createElement("button",{id:"rename_role_action",type:"button",className:"no-border",onClick:t=>this.handleRenameRoleClick(t,e)},n.createElement(qm,null),n.createElement("span",null,n.createElement(f.x6,null,"Rename")))),n.createElement(ed,null,n.createElement("button",{id:"delete_role_action",type:"button",className:"no-border",onClick:t=>this.handleDeleteRoleClick(t,e)},n.createElement(Ml,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(_m,{label:this.props.t("Group management"),level:1,rolesCount:a},n.createElement(Am,{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(_m,{label:this.props.t("Account recovery request"),level:1,rolesCount:a},n.createElement(Am,{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(Am,{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(Am,{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(_m,{label:this.props.t("Resources"),level:1,rolesCount:a},(this.canIUseImport||this.canIUseExport)&&n.createElement(_m,{label:this.props.t("Import/Export"),level:2,rolesCount:a},this.canIUseImport&&n.createElement(Am,{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(Am,{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(_m,{label:this.props.t("Password"),level:2,rolesCount:a},this.canIUsePreviewPassword&&n.createElement(Am,{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(Am,{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(_m,{label:this.props.t("Metadata"),level:2,rolesCount:a},n.createElement(Am,{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(Am,{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(_m,{label:this.props.t("Organization"),level:2,rolesCount:a},this.canIUseFolders&&n.createElement(Am,{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(Am,{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(_m,{label:this.props.t("Sharing"),level:2,rolesCount:a},n.createElement(Am,{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(Am,{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(_m,{label:this.props.t("Users"),level:1,rolesCount:a},n.createElement(Am,{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(_m,{label:this.props.t("User settings"),level:1,rolesCount:a},this.canIUseMobile&&n.createElement(Am,{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(Am,{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(Sm,null),$a(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(ds,null),n.createElement("span",null,n.createElement(f.x6,null,"Read RBAC doc")))),document.getElementById("administration-help-panel")))}}od.defaultProps={RoleApiService:Im,RbacApiService:ym,UserApiService:xn},od.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 ld=N(km(Ne(h(m((0,f.CI)("common")(od)))))),cd=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}},md=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 dd(){return dd=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 pd extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.hasDataBeenValidated=!1}get defaultState(){return{settings:new md,errors:{},currentSettings:new md,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 md(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(ud.Provider,{value:this.state},this.props.children)}}function hd(e){return class extends n.Component{render(){return n.createElement(ud.Consumer,null,t=>n.createElement(e,dd({adminPasswordPoliciesContext:t},this.props)))}}}pd.propTypes={context:i().any,children:i().any,t:i().any,actionFeedbackContext:i().object},N((0,f.CI)("common")(pd));class gd 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 cd(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"))))}}gd.propTypes={adminPasswordPoliciesContext:i().object,passwordPoliciesContext:i().object,actionFeedbackContext:i().object,t:i().func};const bd=hd(Rr(m((0,f.CI)("common")(gd)))),yd={COLOR_1:fd("#BA2809"),COLOR_2:fd("#FFA724"),COLOR_3:fd("#0EAA00")};function fd(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 Ed 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=pr.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=yd.COLOR_2,a=yd.COLOR_3):(t=yd.COLOR_1,a=yd.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})))}}Ed.defaultProps={entropy:null},Ed.propTypes={entropy:i().number,error:i().bool};const vd=(0,f.CI)("common")(Ed);class wd 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(vd,{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(cn,{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(bd,null),$a(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(Vr,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation"))))),document.getElementById("administration-help-panel")))}}wd.propTypes={context:i().object,administrationWorkspaceContext:i().object,adminPasswordPoliciesContext:i().object,t:i().func};const kd=N(Ne(hd((0,f.CI)("common")(wd))));class xd 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(pa,{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(bs,null),n.createElement(f.x6,null,"Reduce the risk of weak passwords.")),n.createElement("li",null,n.createElement(bs,null),n.createElement(f.x6,null,"Enforce complexity requirements.")),n.createElement("li",null,n.createElement(bs,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")))))),$a(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(Vr,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation"))))),document.getElementById("administration-help-panel")))}}xd.propTypes={context:i().object,t:i().func};const Sd=N((0,f.CI)("common")(xd));class Cd extends se{constructor(e,t={}){super(ae.validate(Cd.ENTITY_NAME,e,Cd.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 Cd(t)}}const _d=Cd;class Nd{constructor(e={}){this.external_dictionary_check=e?.external_dictionary_check,this.entropy_minimum=e?.entropy_minimum}static getSchema(){const e=_d.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 Td=Nd;function Ad(){return Ad=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},setSettings:()=>{},findSettings:()=>{},isProcessing:()=>{},validateData:()=>{},save:()=>{},getErrors:()=>{},hasSettingsChanges:()=>{}});class Rd extends n.Component{constructor(e){super(e),this.state=this.defaultState}get defaultState(){return{processing:!1,errors:null,hasBeenValidated:!1,isDataModified:!1,settings:new Td,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=Td.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=Td.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=Td.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(Id.Provider,{value:this.state},this.props.children)}}function Pd(e){return class extends n.Component{render(){return n.createElement(Id.Consumer,null,t=>n.createElement(e,Ad({adminUserPassphrasePoliciesContext:t},this.props)))}}}Rd.propTypes={context:i().any,children:i().any,t:i().any},N((0,f.CI)("common")(Rd));class Dd 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"))))}}Dd.propTypes={adminUserPassphrasePoliciesContext:i().object,actionFeedbackContext:i().object,dialogContext:i().any,t:i().func};const Od=Pd(m(h((0,f.CI)("common")(Dd))));class Md 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)))))}}Md.propTypes={value:i().number.isRequired,id:i().string.isRequired,onChange:i().func,disabled:i().bool};const Ud=(0,f.CI)("common")(Md);class Fd 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(Od,null),$a(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(Vr,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}Fd.propTypes={context:i().object,administrationWorkspaceContext:i().object,adminUserPassphrasePoliciesContext:i().object,t:i().func};const jd=N(Ne(Pd((0,f.CI)("common")(Fd))));class Ld 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(pa,{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(bs,null),n.createElement(f.x6,null,"Mitigate risks associated with weak passphrases.")),n.createElement("li",null,n.createElement(bs,null),n.createElement(f.x6,null,"Customise minimum length and complexity.")),n.createElement("li",null,n.createElement(bs,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")))))),$a(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(Vr,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation"))))),document.getElementById("administration-help-panel")))}}Ld.propTypes={context:i().object,t:i().func};const qd=N((0,f.CI)("common")(Ld));class zd extends se{constructor(e,t={}){super(ae.validate(zd.ENTITY_NAME,e,zd.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 zd(t)}}const Kd=zd;class Vd extends se{constructor(e,t={}){super(ae.validate(Vd.ENTITY_NAME,e,Vd.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 Vd(t)}}const Gd=Vd;class Bd{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?Gd.getSchema():Kd.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 Bd(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 Bd(a)}validate(e=!1){const t=new X,a=Bd.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 Wd=Bd;function Hd(){return Hd=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 Yd 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 Wd,featureToggleEnabled:!1,settings:new Wd,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=Wd.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,Hd({adminPasswordExpiryContext:t},this.props)))}}}Yd.propTypes={context:i().any,children:i().any,t:i().any},N((0,f.CI)("common")(Yd));class Jd 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"))))}}Jd.propTypes={adminPasswordExpiryContext:i().object,actionFeedbackContext:i().object,dialogContext:i().any,t:i().func};const Xd=m(Zd(h((0,f.CI)("common")(Jd))));class Qd 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.")))))))}}Qd.propTypes={context:i().object,adminPasswordExpiryContext:i().object,actionFeedbackContext:i().object,dialogContext:i().object,t:i().func};const eu=N(Zd(m(h((0,f.CI)("common")(Qd)))));class tu 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(eu,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(Xd,null),$a(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(Vr,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}tu.propTypes={context:i().object,administrationWorkspaceContext:i().object,adminPasswordExpiryContext:i().object,t:i().func};const au=N(Ne(Zd((0,f.CI)("common")(tu))));class nu 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)))))}}nu.propTypes={errorCode:i().number.isRequired,t:i().func};const su=(0,f.CI)("common")(nu),iu=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 ru extends se{constructor(e,t={}){super(ae.validate(ru.ENTITY_NAME,e,ru.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 ou=ru;class lu extends se{constructor(e,t={}){super(ae.validate(lu.ENTITY_NAME,e,lu.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 cu=lu;class mu extends se{constructor(e,t={}){super(ae.validate(mu.ENTITY_NAME,e,mu.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 du=mu;class uu extends se{constructor(e,t={}){super(ae.validate(uu.ENTITY_NAME,e,uu.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 pu=uu;class hu extends se{constructor(e,t={}){super(ae.validate(hu.ENTITY_NAME,e,hu.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 gu=hu;class bu extends se{constructor(e,t={}){super(ae.validate(bu.ENTITY_NAME,e,bu.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 yu=bu;class fu extends se{constructor(e,t={}){super(ae.validate(fu.ENTITY_NAME,e,fu.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 Eu=fu;class vu extends se{constructor(e,t={}){super(ae.validate(vu.ENTITY_NAME,e,vu.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 wu=vu;class ku extends se{constructor(e,t={}){super(ae.validate(ku.ENTITY_NAME,e,ku.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 xu=ku;class Su extends se{constructor(e,t={}){super(ae.validate(Su.ENTITY_NAME,e,Su.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 Cu=Su;class _u extends se{constructor(e,t={}){super(ae.validate(_u.ENTITY_NAME,e,_u.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=_u;class Tu extends se{constructor(e,t={}){super(ae.validate(Tu.ENTITY_NAME,e,Tu.getSchema()),t),this._props.ssl&&(this._ssl=new ou(this._props.ssl,{clone:!1}),delete this._props.ssl),this._props.database&&(this._database=new cu(this._props.database,{clone:!1}),delete this._props.database),this._props.application&&(this._application=new du(this._props.application,{clone:!1}),delete this._props.application),this._props.gpg&&(this._gpg=new pu(this._props.gpg,{clone:!1}),delete this._props.gpg),this._props.environment&&(this._environment=new gu(this._props.environment,{clone:!1}),delete this._props.environment),this._props.configFile&&(this._configFile=new yu(this._props.configFile,{clone:!1}),delete this._props.configFile),this._props.core&&(this._core=new Eu(this._props.core,{clone:!1}),delete this._props.core),this._props.smtpSettings&&(this._smtpSettings=new wu(this._props.smtpSettings,{clone:!1}),delete this._props.smtpSettings),this._props.directorySync&&(this._directorySync=new xu(this._props.directorySync,{clone:!1}),delete this._props.directorySync),this._props.sso&&(this._sso=new Cu(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:cu.getSchema(),ssl:ou.getSchema(),application:du.getSchema(),gpg:pu.getSchema(),environment:gu.getSchema(),configFile:yu.getSchema(),core:Eu.getSchema(),smtpSettings:wu.getSchema(),directorySync:xu.getSchema(),sso:Cu.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 Au=Tu;function Iu(){return Iu=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},isProcessing:()=>{},loadHealthcheckData:()=>{},clearContext:()=>{},isHealthcheckEndpointEnabled:()=>{}});class Pu extends n.Component{constructor(e){super(e),this.state=this.defaultState;const t=e.context.getApiClientOptions();this.healthcheckService=new iu(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 Au(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(Ru.Provider,{value:this.state},this.props.children)}}Pu.propTypes={context:i().any,actionFeedbackContext:i().any,children:i().any};const Du=N(m(Pu));function Ou(e){return class extends n.Component{render(){return n.createElement(Ru.Consumer,null,t=>n.createElement(e,Iu({adminHealthcheckContext:t},this.props)))}}}var Mu,Uu,Fu;function ju(){return ju=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(Gu,null),n.createElement(f.x6,null,"Some default content is present")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,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(Gu,null),n.createElement(f.x6,null,"Cache is working")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,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(Gu,null),n.createElement(f.x6,null,"Unique value set for security.salt")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,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(Gu,null),n.createElement(f.x6,null,"The application config file is present")):n.createElement("span",{className:"healthcheck-warning"},n.createElement(Qu,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(Gu,null),n.createElement(f.x6,null,"The passbolt config file is present")):n.createElement("span",{className:"healthcheck-warning"},n.createElement(Qu,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(Gu,null),n.createElement(f.x6,null,"PCRE compiled with unicode support")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,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(Gu,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(Hu,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(Gu,null),n.createElement(f.x6,null,"The logs directory and its content are writable")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,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(Gu,null),n.createElement(f.x6,null,"The environment variable GNUPGHOME is set to ",t)):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,null),n.createElement(f.x6,null,"The environment variable GNUPGHOME is set to ",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(Gu,null),n.createElement(f.x6,null,"The directory ",t," containing the keyring is writable by the webserver user")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,null),n.createElement(f.x6,null,"The directory ",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(Gu,null),n.createElement(f.x6,null,"The server key fingerprint matches the one defined in ",t)):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,null),n.createElement(f.x6,null,"The server key fingerprint doesn't matches the one defined in ",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(Gu,null),n.createElement(f.x6,null,"The server public key defined in the ",t," (or environment variables) is in the keyring")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,null),n.createElement(f.x6,null,"The server public key defined in the ",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(Gu,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(Hu,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(Zu,null),n.createElement(f.x6,null,"The Self Registration plugin is enabled")):n.createElement("span",{className:"healthcheck-info"},n.createElement(Zu,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"}))),b=()=>{const t=e.application.configPath.toString();return!0===e.application.registrationClosed.isRegistrationPublicRemovedFromPassbolt?n.createElement("span",{className:"healthcheck-success"},n.createElement(Gu,null),n.createElement(f.x6,null,"The deprecated self registration public settings was not found in ",t)):n.createElement("span",{className:"healthcheck-warning"},n.createElement(Qu,null),n.createElement(f.x6,null,"The deprecated self registration public settings was found in ",t),n.createElement(Mt,{message:this.props.t("You may remove the passbolt.registration.public setting")},n.createElement(jt,{className:"baseline svg-icon"})))},y=()=>!0===e.application.hostAvailabilityCheckEnabled?n.createElement("span",{className:"healthcheck-success"},n.createElement(Gu,null),n.createElement(f.x6,null,"Host availability will be checked")):n.createElement("span",{className:"healthcheck-warning"},n.createElement(Qu,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(Gu,null),n.createElement(f.x6,null,"The SMTP Settings source is: ",{smtpSettingsSource:t})):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,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(Gu,null),n.createElement(f.x6,null,"The SMTP Settings plugin endpoints are disabled")):n.createElement("span",{className:"healthcheck-warning"},n.createElement(Qu,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(Gu,null),n.createElement(f.x6,null,"The endpoints for updating the users directory configurations are disabled.")):n.createElement("span",{className:"healthcheck-warning"},n.createElement(Qu,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(Gu,null),n.createElement(f.x6,null,"SSL certification validation for SSO instance is enabled.")):n.createElement("span",{className:"healthcheck-warning"},n.createElement(Qu,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"}))),x=()=>!0===e.metadata.canDecryptMetadataPrivateKey?n.createElement("span",{className:"healthcheck-success"},n.createElement(Gu,null),n.createElement(f.x6,null,"The server is able to decrypt the metadata private key.")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,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"}))),S=()=>!0===e.metadata.canValidatePrivateMetadataKey?n.createElement("span",{className:"healthcheck-success"},n.createElement(Gu,null),n.createElement(f.x6,null,"The server metadata private key is valid.")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,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"}))),C=()=>!0===e.metadata.isServerHasAccessToMetadataKey?n.createElement("span",{className:"healthcheck-success"},n.createElement(Gu,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(Hu,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"}))),_=()=>!0===e.metadata.noActiveMetadataKey?n.createElement("span",{className:"healthcheck-success"},n.createElement(Gu,null),n.createElement(f.x6,null,"Active metadata key found or not required.")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,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(gn,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(Gu,null),n.createElement(f.x6,null,"PHP version ",{phpVersion:t}))}return n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,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(Gu,null),n.createElement(f.x6,null,"GD or Imagick extension is installed")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,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(Gu,null),n.createElement(f.x6,null,"Intl extension is installed")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,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(Gu,null),n.createElement(f.x6,null,"Mbstring extension is installed")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,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(Hu,null),n.createElement(f.x6,null,"Debug mode is on"),n.createElement(Mt,{message:n.createElement(f.x6,null,"Set debug = false; in ",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(Gu,null),n.createElement(f.x6,null,"Full base url is set to ",t))}{const t=e.application.configPath.toString();return n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,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 ",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(Gu,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(Hu,null),n.createElement(f.x6,null,"App.fullBaseUrl does not validate"),n.createElement(Mt,{message:n.createElement(f.x6,null,"Edit App.fullBaseUrl in ",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(Gu,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(Hu,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 ",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(Gu,null),n.createElement(f.x6,null,"SSL peer certificate validates")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,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(Gu,null),n.createElement(f.x6,null,"Hostname is matching SSL certificate")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,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(Gu,null),n.createElement(f.x6,null,"Not using a self-signed certificate")):n.createElement("span",{className:"healthcheck-warning"},n.createElement(Qu,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(Gu,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(Hu,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 ",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(Gu,null),n.createElement(f.x6,{count:t},{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(Gu,null),n.createElement(f.x6,null,"PHP GPG Module is installed and loaded")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,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(Gu,null),n.createElement(f.x6,null,"The public key file is defined in ",t," and readable.")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,null),n.createElement(f.x6,null,"The public key file is not defined in ",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"," ",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(Gu,null),n.createElement(f.x6,null,"The private key file is defined in ",t," and readable.")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,null),n.createElement(f.x6,null,"The private key file is not defined in ",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"," ",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(Gu,null),n.createElement(f.x6,null,"The public key can be used to encrypt a message")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,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(Gu,null),n.createElement(f.x6,null,"The public key can be used to sign a message")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,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(Gu,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(Hu,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(Gu,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(Hu,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(Gu,null),n.createElement(f.x6,null,"The public key can be used to verify a signature")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,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(Gu,null),n.createElement(f.x6,null,"The server public key format is Gopengpg compatible")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,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(Gu,null),n.createElement(f.x6,null,"The server private key format is Gopengpg compatible")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,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(Gu,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(Hu,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(Hu,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(Gu,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(Hu,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 ",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(Gu,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(Hu,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 ",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(Gu,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(Hu,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 ",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(Gu,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(Hu,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 ",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(Zu,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(Zu,null),n.createElement(f.x6,null,"The Self Registration provider is: ",{selfRegistrationProvider:t}))}})()),n.createElement("div",null,b()),n.createElement("div",null,y()),n.createElement("div",null,(()=>{if(!0===e.application.jsProd)return n.createElement("span",{className:"healthcheck-success"},n.createElement(Gu,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(Qu,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 ",t)},n.createElement(jt,{className:"baseline svg-icon"})))}})()),n.createElement("div",null,!0===e.application.emailNotificationEnabled?n.createElement("span",{className:"healthcheck-success"},n.createElement(Gu,null),n.createElement(f.x6,null,"All email notifications will be sent")):n.createElement("span",{className:"healthcheck-warning"},n.createElement(Qu,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(Gu,null),n.createElement(f.x6,null,"The SMTP Settings plugin is enabled")):n.createElement("span",{className:"healthcheck-warning"},n.createElement(Qu,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(Gu,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(Hu,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(Gu,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,x()),n.createElement("div",null,S()),n.createElement("div",null,C()),n.createElement("div",null,_()))))))():n.createElement("div",null,n.createElement(f.x6,null,"The health check API endpoint has been disabled in the server configuration."))),$a(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(Gu,null)," ",n.createElement(f.x6,null,"Everything is running as expected.")),n.createElement("div",{className:"healthcheck-warning"},n.createElement(Qu,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(Hu,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(Zu,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(ds,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation"))))),document.getElementById("administration-help-panel"))))}}ep.propTypes={context:i().object,adminHealthcheckContext:i().any,children:i().any,administrationWorkspaceContext:i().object,t:i().func};const tp=N(Ne(Ou((0,f.CI)("common")(ep)))),ap="v4",np="v5";class sp 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:[ap,np]},default_folder_type:{type:"string",enum:[ap,np]},default_tag_type:{type:"string",enum:[ap,np]},default_comment_type:{type:"string",enum:[ap,np]},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 sp({default_resource_types:ap,default_folder_type:ap,default_tag_type:ap,default_comment_type:ap,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 sp({default_resource_types:ap,default_folder_type:ap,default_tag_type:ap,default_comment_type:ap,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 sp({default_resource_types:np,default_folder_type:ap,default_tag_type:ap,default_comment_type:ap,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===np}get isDefaultResourceTypeV4(){return this._props.default_resource_types===ap}get allowV5V4Downgrade(){return this._props.allow_v5_v4_downgrade}get allowV4V5Upgrade(){return this._props.allow_v4_v5_upgrade}}const ip=sp,rp="keepass-icon-set",op="passbolt-icon-set",lp="password-string",cp="password-and-description",mp="password-description-totp",dp="totp",up="v5-default",pp="v5-password-string",hp="v5-default-with-totp",gp="v5-totp-standalone",bp="v5-custom-fields",yp="v5-note",fp="v5-pin-code",Ep={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}},vp={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}}}},wp={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"}}}}}},kp={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:wp.secret.properties.totp}}},xp={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:[rp,op]},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}}}}}}},Sp={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:[rp,op]},value:{type:"number",minimum:0,nullable:!0},background_color:{type:"string",nullable:!0}}},custom_fields:xp.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:xp.secret.properties.custom_fields}}},Cp={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:[rp,op]},value:{type:"number",minimum:0,nullable:!0},background_color:{type:"string",nullable:!0}}}}},secret:{type:"string",maxLength:4096}},_p={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:[rp,op]},value:{type:"number",minimum:0,nullable:!0},background_color:{type:"string",nullable:!0}}},custom_fields:xp.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:wp.secret.properties.totp,custom_fields:xp.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:[rp,op]},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"}}}}}},Tp={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:[rp,op]},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}}}},Ap={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:[rp,op]},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}}}},Ip={[lp]:pp,[cp]:up,[mp]:hp,[dp]:gp},Rp=new class{get SCHEMAS(){return{[lp]:Ep,[cp]:vp,[mp]:kp,[dp]:wp,[up]:Sp,[pp]:Cp,[hp]:_p,[gp]:Np,[bp]:xp,[yp]:Tp,[fp]:Ap}}},Pp=[lp,cp,mp,up,hp,pp],Dp=[mp,dp,hp,gp],Op=[dp,gp],Mp=[lp,pp],Up=[cp,mp,up,hp,yp,fp],Fp=[lp,up,hp,pp,gp,bp,yp,fp],jp=[up,pp,hp,gp,bp,yp],Lp=[up,hp,bp];class qp extends he{marshall(){if("string"!=typeof this._props.slug||!(this._props.slug in Rp.SCHEMAS))return void delete this._props.definition;const e=Rp.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:[rp,op]},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=qp.getSchema().properties.deleted;t?.nullable&&null===e||ae.validateProp("deleted",e,t),this._props.deleted=e}hasTotp(){return Dp.includes(this.slug)}hasPassword(){return Pp.includes(this.slug)}hasCustomFields(){return Lp.includes(this.slug)}hasPinCode(){return fp===this.slug}isStandalonePinCode(){return this.hasPinCode()}isStandaloneTotp(){return Op.includes(this.slug)}isPasswordString(){return Mp.includes(this.slug)}hasSecretDescription(){return Up.includes(this.slug)}hasMetadataDescription(){return Fp.includes(this.slug)}hasMetadataUris(){return jp.includes(this.slug)}get version(){return this.slug.startsWith("v5")?np:ap}isV5(){return this.version===np}isV4(){return this.version===ap}isDeleted(){return void 0!==this._props.deleted&&null!==this._props.deleted}}const zp=qp,Kp=[lp,cp,mp,dp,up,hp,pp,gp,bp,yp,fp],Vp=class extends gm{get entityClass(){return zp}constructor(e=[],t={}){super(e,t)}static getSchema(){return{type:"array",items:zp.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",Pp)}filterByTOTPResourceTypes(){this.filterByPropertyValueIn("slug",Dp)}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=ap){return this.items.some(t=>t.hasPassword()&&t.version===e)}hasSomeTotpResourceTypes(e=ap){return this.items.some(t=>t.hasTotp()&&t.version===e)}hasSomeCustomFieldsResourceTypes(e=ap){return this.items.some(t=>t.hasCustomFields()&&t.version===e)}hasSomeNoteResourceTypes(e=ap){return this.items.some(t=>t.hasSecretDescription()&&t.version===e)}hasSomePinCodeResourceTypes(e=ap){return this.items.some(t=>t.hasPinCode()&&t.version===e)}hasSomeMetadataDescriptionResourceTypes(e=ap){return this.items.some(t=>t.hasMetadataDescription()&&t.version===e)}hasSomeOfVersion(e=ap){return this.items.some(t=>t.version===e)}getResourceTypeMatchingResource(e,t=ap){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={}){Kp.includes(e?.slug)&&super.push(e,t,a)}},Gp=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 Bp extends he{static getSchema(){return{type:"object",required:[Bp.AVATAR_URL_SIZE_MEDIUM,Bp.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 Wp=Bp,Hp=class extends he{constructor(e={},t={}){super(e,t),this._props.url&&(this._url=new Wp(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:Wp.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 $p extends he{constructor(e={},t={}){super(e,t),this._props.avatar&&(this._avatar=new Hp(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:Hp.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($p.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 Yp=$p;class Zp extends he{constructor(e,t={}){super(e,t),this._props.profile&&(this._profile=new Yp(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 Gp(this._props.gpgkey,{...t,clone:!1}),delete this._props.gpgkey)}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"},role:ge.getSchema(),profile:Yp.getSchema(),gpgkey:Gp.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()),t):t}toJSON(){return this.toDto(Zp.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}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:Yp.ALL_CONTAIN_OPTIONS,role:!0,gpgkey:!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}}const Jp=Zp,Xp=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 Qp extends he{constructor(e,t={}){super(e,t),this._props.data&&"string"!=typeof this._props.data&&(this._data=new Xp(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 Xp?a.toDto():a,e?(this._creator&&e.creator&&(t.creator=this._creator.toDto(Jp.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(Jp.ALL_CONTAIN_OPTIONS)}cloneForSharing(e){const t={user_id:e,metadata_key_id:this.metadataKeyId,data:this.data};return new Qp(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 Xp(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 eh=Qp,th=class extends gm{get entityClass(){return eh}constructor(e=[],t={}){super(e,t)}static getSchema(){return{type:"array",items:eh.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)}},ah=class extends he{constructor(e,t={}){super(e,t),this._props.metadata_private_keys&&(this._metadata_private_keys=new th(this._props.metadata_private_keys,{...t,clone:!1}),delete this._props.metadata_private_keys,this.assertSameMetadataKeyId()),this._props.creator&&(this._creator=new Jp(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:th.getSchema(),creator:Jp.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(Jp.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(Jp.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}}},nh=class extends gm{get entityClass(){return ah}constructor(e=[],t={}){super(e,t)}static getSchema(){return{type:"array",items:ah.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)}},sh=["default_resource_types","allow_creation_of_v5_resources","allow_creation_of_v4_resources","allow_v4_v5_upgrade","allow_v5_v4_downgrade"],ih=class extends ip{toFormDto(){return sh.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 Vp))throw new TypeError("The parameter 'resourceTypes' is not a valid 'ResourceTypesCollection' type.");if(!(t instanceof nh))throw new TypeError("The parameter 'metadataKeysCollection' is not a valid 'MetadataKeysCollection' type.");const n=e.hasSomeOfVersion(ap),s=e.hasSomeOfVersion(np);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}},rh=class extends gm{get entityClass(){return eh}constructor(e=[],t={}){super(e,t)}static getSchema(){return{type:"array",items:eh.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 oh 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:rh.getSchema()}}}static get associations(){return{metadata_private_keys:rh}}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 oh({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 rh))throw new TypeError("The metadataPrivateKeysCollection is not of MetadataPrivateKeysCollection type");this._metadataPrivateKeys=e}static get ALL_CONTAIN_OPTIONS(){return{metadata_private_keys:!0}}}const lh=oh,ch=class{constructor(e){this.port=e}async findKeysSettings(){const e=await this.port.request("passbolt.metadata.find-metadata-keys-settings");return new lh(e)}async findTypesSettings(){const e=await this.port.request("passbolt.metadata.find-metadata-types-settings");return new ip(e)}async saveTypesSettings(e){if(!(e instanceof ip))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 ip(t)}async saveKeysSettings(e){if(!(e instanceof lh))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 lh(t)}};class mh 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"))))}}mh.propTypes={isProcessing:i().bool,onSaveRequested:i().func,t:i().func};const dh=(0,f.CI)("common")(mh);function uh(){return uh=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},resourceTypes:null,updateLocalStorage:()=>{}});class hh 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 Vp(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(ph.Provider,{value:this.state},this.props.children)}}function gh(e){return class extends n.Component{render(){return n.createElement(ph.Consumer,null,t=>n.createElement(e,uh({resourceTypesLocalStorageContext:t,resourceTypes:t.get()},this.props)))}}}hh.propTypes={context:i().any,children:i().any},N(hh);class bh extends se{constructor(e,t={}){const a=bh.sanitizeDto(e);super(ae.validate(bh.ENTITY_NAME,a,bh.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,Fo.A)((e,t,a)=>this.formSettings?.verifyHealth(t,a));hasSettingsChanges=(0,Fo.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 ih(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(dh,{onSaveRequested:this.save,isProcessing:this.state.isProcessing}),$a(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(ds,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}wh.propTypes={context:i().object,actionFeedbackContext:i().object,dialogContext:i().object,createPortal:i().func,metadataSettingsServiceWorkerService:i().object,metadataKeysServiceWorkerService:i().object,resourceTypes:i().instanceOf(Vp),t:i().func};const kh=N(m(h(gh((0,f.CI)("common")(wh)))));var xh;function Sh(){return Sh=Object.assign?Object.assign.bind():function(e){for(var t=1;te.id).sort().sort((e,t)=>{if(e===t)throw new ce(0,Ih.RULE_UNIQUE_ID,`Gpgkey fingerprint ${e} already exists.`)}),this._props.forEach(e=>{this._items.push(new yh(e,{clone:!1}))}),this._props=null}static getSchema(){return{type:"array",items:yh.getSchema()}}static get ENTITY_NAME(){return"externalGpgKey"}static get RULE_UNIQUE_ID(){return"fingerprint"}}const Rh=Ih,Ph=class{constructor(e){this.port=e}async keyInfo(e){const t=await this.port.request("passbolt.keyring.get-key-info",e);return new yh(t)}async keysInfo(e=[]){const t=[];for(const a of e){const e=await this.keyInfo(a);t.push(e)}return new Rh(t)}},Dh=class extends lh{constructor(e,t={}){super(e,t),this._props.generated_metadata_key&&(this._generated_metadata_key=new Eh(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:{...lh.getSchema().properties,generated_metadata_key:Eh.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 Eh))throw new TypeError("The parameter `generatedMetadataKey` should be of type ExternalGpgKeyPairEntity.");this._generated_metadata_key=e}};class Oh 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(gn,null)))}}Oh.propTypes={isProcessing:i().bool,isDisabled:i().bool,onSaveRequested:i().func,t:i().func};const Mh=(0,f.CI)("common")(Oh);class Uh 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(Ah,{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},yi(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"))))}}Uh.propTypes={context:i().object,metadataKeyInfo:i().object,onConfirm:i().func,onClose:i().func,t:i().func};const Fh=N((0,f.CI)("common")(Uh));class jh extends n.Component{originalSettings=null;formSettings=null;constructor(e){super(e),this.metadataSettingsServiceWorkerService=e.metadataSettingsServiceWorkerService??new ch(e.context.port),this.metadataKeysServiceWorkerService=e.metadataKeysServiceWorkerService??new vh(e.context.port),this.gpgServiceWorkerService=e.gpgServiceWorkerService??new Ph(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 Dh(e.toDto(),{validate:!1}),this.formSettings=new Dh(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 nh(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,Fo.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 ah({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(Fh,{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,Fo.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 lh(this.formSettings.toDto()),t=await this.metadataSettingsServiceWorkerService.saveKeysSettings(e);this.originalSettings=new Dh({...this.originalSettings.toDto(),...t.toDto()}),this.formSettings=new Dh({...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(Ah,{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},yi(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(Ah,{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},yi(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:yi(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(Mh,{onSaveRequested:this.save,isProcessing:this.state.isProcessing,isDisabled:this.hasAllInputDisabled()}),$a(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(ds,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}jh.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 Lh=N(h(m((0,f.CI)("common")(jh)))),qh=class extends he{static getSchema(){return{type:"object",required:["migrate_resources_to_v5","migrate_folders_to_v5","migrate_tags_to_v5","migrate_comments_to_v5","migrate_personal_content"],properties:{migrate_resources_to_v5:{type:"boolean"},migrate_folders_to_v5:{type:"boolean"},migrate_tags_to_v5:{type:"boolean"},migrate_comments_to_v5:{type:"boolean"},migrate_personal_content:{type:"boolean"}}}}marshall(){this._props.migrate_resources_to_v5=this._props.migrate_resources_to_v5??!0,this._props.migrate_folders_to_v5=this._props.migrate_folders_to_v5??!1,this._props.migrate_tags_to_v5=this._props.migrate_tags_to_v5??!1,this._props.migrate_comments_to_v5=this._props.migrate_comments_to_v5??!1,this._props.migrate_personal_content=this._props.migrate_personal_content??!1}get migrateResources(){return!this._props.migrate_resources_to_v5}get migrateFolders(){return!this._props.migrate_folders_to_v5}get migrateTags(){return!this._props.migrate_tags_to_v5}get migrateComments(){return!this._props.migrate_comments_to_v5}get sharedContentOnly(){return!this._props.migrate_personal_content}},zh=class extends qh{verifyHealth(e,t,a){if(void 0===e)return null;if(void 0===t)return null;if(void 0===a)return null;if(!(e instanceof Vp))throw new TypeError("The parameter 'resourceTypesCollection' is not a valid 'ResourceTypesCollection' type.");if(!(t instanceof ip))throw new TypeError("The parameter 'metadataTypesSettings' is not a valid 'MetadataTypesSettingsEntity' type.");if(!(a instanceof nh))throw new TypeError("The parameter 'metadataKeysCollection' is not a valid 'MetadataKeysCollection' type.");let n=this._verifyGlobalHealth(a);return n=this._verifyMigrateResourcesToV5Health(n,e,t,a),n=this._verifyMigrateFoldersToV5Health(n,t,a),n=this._verifyMigrateTagsToV5Health(n,t,a),n=this._verifyMigrateCommentsToV5Health(n,t,a),n}_verifyGlobalHealth(e){if(e.items.filter(e=>!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(np);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===ap).every(e=>t.hasOneWithSlug(Ip[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}},Kh=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 Qt(t)}async migrate(e,t){await this.port.request("passbolt.metadata.migrate-resources-metadata",e,t)}};class Vh 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"))))}}Vh.propTypes={cancel:i().func,confirm:i().func,onClose:i().func,t:i().func};const Gh=(0,f.CI)("common")(Vh);class Bh 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 zh({}),this.metadataSettingsServiceWorkerService=e.metadataSettingsServiceWorkerService??new ch(e.context.port),this.metadataKeysServiceWorkerService=e.metadataKeysServiceWorkerService??new vh(e.context.port),this.metadataMigrateContentServiceWorkerService=e.metadataMigrateContentServiceWorkerService??new Kh(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,Fo.A)(e=>this.formSettings?.validate());verifyDataHealth=(0,Fo.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(Gh,{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(ni,{name:"warning"}),this.state.isReady&&!this.hasPendingMigration&&n.createElement(ni,{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")))),$a(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")))}}Bh.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(Vp),t:i().func};const Wh=N(m(h(gh(h((0,f.CI)("common")(Bh)))))),Hh={passwordV4:[lp,cp],totpV4:[dp],passwordV5:[up,pp],totpV5:[gp],customFieldsV5:[bp],noteV5:[yp],pinCodeV5:[fp]},$h={passwordV4:[lp,cp,mp],totpV4:[dp,mp],passwordV5:[up,pp,hp],totpV5:[gp,hp],customFieldsV5:[bp],noteV5:[yp],pinCodeV5:[fp]};class Yh extends he{constructor(e,t){super(e,t),this._props.resource_types&&(this._resource_types=new Vp(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:Vp.getSchema()}}}static createFormResourcesTypesCollection(e){if(!(e instanceof Vp))throw new TypeError("The parameter 'resource_types' is not a valid 'ResourceTypesCollection' type.");const t=e.items.filter(e=>!e.isDeleted()),a=new Vp(t),n=this._areAllResourceTypesAvailable(Hh.passwordV4,a),s=this._areAllResourceTypesAvailable(Hh.passwordV5,a),i=this._areAllResourceTypesAvailable(Hh.totpV4,a),r=this._areAllResourceTypesAvailable(Hh.totpV5,a),o=this._areAllResourceTypesAvailable(Hh.customFieldsV5,a),l=this._areAllResourceTypesAvailable(Hh.noteV5,a),c=this._areAllResourceTypesAvailable(Hh.pinCodeV5,a),m=this._getResourcesCountForResourceTypeFamily($h.passwordV4,e),d=this._getResourcesCountForResourceTypeFamily($h.passwordV5,e),u=this._getResourcesCountForResourceTypeFamily($h.totpV4,e),p=this._getResourcesCountForResourceTypeFamily($h.totpV5,e),h=this._getResourcesCountForResourceTypeFamily($h.customFieldsV5,a),g=this._getResourcesCountForResourceTypeFamily($h.noteV5,e),b=this._getResourcesCountForResourceTypeFamily($h.pinCodeV5,e),y=e.hasSomeOfVersion("v4"),f=e.hasSomeOfVersion("v5");return new Yh({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:b,custom_fields_v5_count:h,has_v4_resource_types:y,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 ip))throw new TypeError("The parameter 'metadataTypesSettings' is not a valid 'MetadataTypesSettingsEntity' type.");if(!(t instanceof nh))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===bp||this._props.note_v5&&e.slug===yp||this._props.pin_code_v5&&e.slug===fp),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,Fo.A)((e,t,a)=>this.formSettings?.verifyHealth(t,a));hasSettingsChanges=(0,Fo.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=Zh.createFormResourcesTypesCollection(t),this.formSettings=new Zh(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(eg,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(sg,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(og,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(mg,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(pg,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(eg,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(sg,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")))),$a(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")))}}hg.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 gg=N(m(h((0,f.CI)("common")(hg))));class bg 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(pa,null)),this.props.description&&n.createElement("span",{className:"info",title:this.props.description},this.props.description)))}}bg.defaultProps={isBeta:!1,proTeasing:!1},bg.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 yg=bg;var fg;function Eg(){return Eg=Object.assign?Object.assign.bind():function(e){for(var t=1;tn.createElement(yg,{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}))))))}}Zb.propTypes={context:i().object,navigationContext:i().object,administrationEncryptedMetadataGettingStartedContext:i().object,metadataGettingStartedSettings:i().object,t:i().func};const Jb=N(ca(Ke((0,f.CI)("common")(Zb))));var Xb;function Qb(){return Qb=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 xy 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")))))}}xy.propTypes={shouldDisplayWarning:i().bool.isRequired};const Sy=xy;class Cy{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 _y(){return _y=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},getAllRoles:()=>{},refreshRoles:()=>{}});class Ty extends n.Component{constructor(e){super(e),this.state=this.defaultState(),this.runningLocalStorageUpdatePromise=null,this.roleServiceWorkerService=new Cy(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(Ny.Provider,{value:this.state},this.props.children)}}Ty.propTypes={context:i().any,children:i().any},Ty.displayName="RoleContextProvider",N(Ty);class Ay extends n.Component{originalSettings=null;formSettings=null;scimSettingsService=null;constructor(e){super(e),this.state=this.defaultState,this.bindCallbacks(),this.scimSettingsService=e.scimSettingsServiceWorkerService??new wy(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:ky(e,this.props.t,{withUsername:!0})}))}async findScimSettings(){this.setState({isProcessing:!0});try{const e=await this.scimSettingsService.findSettings();e&&(this.originalSettings=new vy(e,{validate:!1}),this.formSettings=new vy(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=vy.createFromDefault(this.adminUsers[0].id),this.setState({settings:this.formSettings.toDto()})}handleToggleEnabled(){this.state.enabled||(this.formSettings=vy.createFromDefault(this.adminUsers[0].id),this.setState({settings:this.formSettings.toDto()})),this.setState({enabled:!this.state.enabled})}hasSettingsChanges=(0,Fo.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=fy.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 vy(e,{validate:!1}):null,this.originalSettings=e?new vy(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,_y({roleContext:t,roles:t.getAllRoles()},this.props)))}}}((0,f.CI)("common")(Ay)))))));class Ry 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(pa,{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(bs,null),n.createElement(f.x6,null,"Efficiently manage user identities in the cloud.")),n.createElement("li",null,n.createElement(bs,null),n.createElement(f.x6,null,"Simplify onboarding and offboarding processes.")),n.createElement("li",null,n.createElement(bs,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")))))))}}Ry.propTypes={context:i().object,t:i().func};const Py=N((0,f.CI)("common")(Ry));class Dy 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 Dy({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 Oy=Dy;class My{constructor(e){this.port=e}async findSettings(){const e=await this.port.request("passbolt.secret-revisions.find-settings");return new Oy(e)}async saveSettings(e){if(!(e instanceof Oy))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 Oy(t)}async deleteSettings(){await this.port.request("passbolt.secret-revisions.delete-settings")}}class Uy extends n.Component{originalSettings=null;formSettings=null;constructor(e){super(e),this.secretRevisionsSettingsServiceWorkerService=new My(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 Oy(this.originalSettings.toDto(),{validate:!1});const e=this.formSettings.toDto();this.setState({settings:e,isFeatureEnabled:this.originalSettings.isFeatureEnabled,isProcessing:!1})}validateForm=(0,Fo.A)(e=>this.formSettings?.validate());hasSettingsChanges=(0,Fo.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=Oy.createFromDefault(),this.formSettings=new Oy(this.originalSettings.toDto(),{validate:!1})}async saveSettings(){const e=this.formSettings.toDto();this.originalSettings=new Oy(e,{validate:!1}),this.originalSettings=await this.secretRevisionsSettingsServiceWorkerService.saveSettings(new Oy(e)),this.formSettings=new Oy(this.originalSettings.toDto(),{validate:!1})}render(){const e=this.state.hasAlreadyBeenValidated?this.validateForm(this.state.settings):null,t=this.hasSettingsChanges(this.state.settings,this.state.isFeatureEnabled),a=e?.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.")),a&&n.createElement("div",{id:"maxRevisions-error",className:"error-message"},n.createElement(f.x6,null,"The history length must be between 1 and ",this.maxRevisionsLimitToDisplay,".")))))),t&&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")))))}}Uy.propTypes={context:i().object,dialogContext:i().object,actionFeedbackContext:i().object,t:i().func};const Fy=N(m(h((0,f.CI)("common")(Uy))));function jy(){return jy=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},close:()=>{}});class qy 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(Ly.Provider,{value:this.state},this.props.children)}}function zy(e){return class extends n.Component{render(){return n.createElement(Ly.Consumer,null,t=>n.createElement(e,jy({announcementContext:t},this.props)))}}}function Ky(){return Ky=Object.assign?Object.assign.bind():function(e){for(var t=1;tn.createElement(t,Ky({key:e,onClose:()=>this.close(e)},a))),this.props.children)}}Vy.propTypes={announcementContext:i().any,children:i().any};const Gy=zy(Vy);class By 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(Gy,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(Ch,null)),n.createElement("span",{className:"title administration"},n.createElement(f.x6,null,"Organisation settings")))),n.createElement("div",{className:"sidebar-content-left"},n.createElement(ga,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(uy,{isUserAdmin:!0,isUserWorkspaceVisible:!0,currentWorkspace:my}),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(an,null)),n.createElement("div",{className:"main-page"},this.isHttpError403&&n.createElement(su,{errorCode:403}),this.isHttpError404&&n.createElement(su,{errorCode:404}),this.isHomePageSelected()&&n.createElement(Jb,null),this.isMfaSelected()&&n.createElement(Za,null),this.isMfaPolicySelected()&&(this.isCommunityEdition()?n.createElement(om,null):n.createElement(im,null)),this.isPasswordPoliciesSelected()&&(this.isCommunityEdition()?n.createElement(Sd,null):n.createElement(kd,null)),this.isUserDirectorySelected()&&(this.isCommunityEdition()?n.createElement(fs,null):n.createElement(ps,null)),this.isEmailNotificationsSelected()&&n.createElement(Is,null),this.isSubscriptionSelected()&&(this.isCommunityEdition()?n.createElement(Ci,null):n.createElement(xi,null)),this.isInternationalizationSelected()&&n.createElement(ji,null),this.isAccountRecoverySelected()&&(this.isCommunityEdition()?n.createElement(Hr,null):n.createElement(Br,null)),this.isSmtpSettingsSelected()&&n.createElement(ll,null),this.isSelfRegistrationSelected()&&n.createElement(Fl,null),this.isSsoSelected()&&(this.isCommunityEdition()?n.createElement($c,null):n.createElement(Wc,null)),this.isRbacSelected()&&n.createElement(ld,null),this.isUserPassphrasePoliciesSelected()&&(this.isCommunityEdition()?n.createElement(qd,null):n.createElement(jd,null)),this.isPasswordExpirySelected()&&n.createElement(au,null),this.isHealthcheckSelected()&&n.createElement(tp,null),this.isContentTypesEncryptedMetadataSelected()&&n.createElement(kh,null),this.isContentTypesMetadataKeySelected()&&n.createElement(Lh,null),this.isMigrateMetadataSelected()&&n.createElement(Wh,null),this.isAllowContentTypesSelected()&&n.createElement(gg,null),this.isGetStartedMetadataSelected()&&n.createElement(gy,null),this.isScimSelected()&&(this.isCommunityEdition()?n.createElement(Py,null):n.createElement(Iy,null)),this.isSecretHistorySelected()&&n.createElement(Fy,null))),n.createElement(S.Switch,null,n.createElement(S.Route,{exact:!0,path:["/app/administration","/app/administration/scim-teasing","/app/administration/secret-history"]}),n.createElement(S.Route,null,n.createElement("div",{className:"help-panel"},n.createElement("div",{className:"sidebar-help",id:"administration-help-panel"}),n.createElement(Nh,null)))))))))}}By.propTypes={context:i().any,administrationWorkspaceContext:i().object,navigationContext:i().any};const Wy=N(Ke(Ne(By)));class Hy 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"))))}}Hy.propTypes={context:i().any,t:i().func};const $y=N((0,S.withRouter)((0,f.CI)("common")(Hy)));class Yy 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($y)}render(){return n.createElement(n.Fragment,null)}}Yy.propTypes={context:i().any,dialogContext:i().any};const Zy=N(h(Yy));class Jy 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))}}Jy.propTypes={children:i().node,className:i().string,canClose:i().bool,onClose:i().func};const Xy=(0,f.CI)("common")(Jy);class Qy extends n.Component{render(){return n.createElement(Xy,{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},yi(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"))))}}Qy.propTypes={context:i().any,expiry:i().string,navigationContext:i().any,onClose:i().func,t:i().func};const ef=N(Ke(zy((0,f.CI)("common")(Qy))));class tf extends n.Component{render(){return n.createElement(Xy,{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"))))}}tf.propTypes={navigationContext:i().any,onClose:i().func,i18n:i().any};const af=Ke(zy((0,f.CI)("common")(tf)));class nf extends n.Component{render(){return n.createElement(Xy,{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"))))}}nf.propTypes={navigationContext:i().any,onClose:i().func,i18n:i().any};const sf=Ke(zy((0,f.CI)("common")(nf)));class rf 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(ef,{expiry:e.expiry})}catch(e){"PassboltSubscriptionError"===e.name?this.props.announcementContext.show(af):this.props.announcementContext.show(sf)}}hideSubscriptionAnnouncement(){const e=[ef,af,sf];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 cf extends Error{constructor(e,t={}){super(e),this.name="PassboltSubscriptionError",this.subscription=t}}const mf=cf,df=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 uf extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.authLogoutService=new df(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 lf).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 bm});const t=this.getApiClientOptions(),a=new ym(t),n=(await a.findMe({ui_action:!0,action:!0})).body,s=new bm(n,!0);this.setState({rbacs:s})}async getSiteSettings(){const e=this.getApiClientOptions().setResourceName("settings"),t=new pt(e),a=await t.findAll(),n=new Sr(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 mf(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)}}uf.propTypes={children:i().any};const pf=uf;var hf=a(2635),gf=a(1347);class bf extends n.Component{constructor(e){super(e),this.state=this.defaultState}get defaultState(){return{ready:!1}}async componentDidMount(){await(0,hf.Yx)(f.r9).use(gf.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,hf.v2)(this.locale)}get isReady(){return this.state.ready}render(){return n.createElement(n.Fragment,null,this.isReady&&this.props.children)}}bf.propTypes={context:i().any,loadingPath:i().any,children:i().any};const yf=N(bf);class ff{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 lf).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 Ef extends n.Component{render(){const e=new ff;return n.createElement(pf,null,n.createElement(T.Consumer,null,t=>n.createElement(yf,{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(qy,null,n.createElement(y,null,n.createElement(k,null),n.createElement(Zy,null),t.loggedInUser&&"admin"===t.loggedInUser.role.name&&t.siteSettings.canIUse("ee")&&n.createElement(of,null),n.createElement(x.Kd,{basename:t.basename},n.createElement(ze,null,n.createElement(S.Switch,null,n.createElement(S.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(S.Route,{path:"/app/administration"},n.createElement(Ce,null,n.createElement(zo,null,n.createElement(Fe,null),n.createElement(Dn,null,n.createElement(wl,null,n.createElement(Oe,null),n.createElement(Ia,null,n.createElement(em,null,n.createElement(Cs,null,n.createElement(Di,null,n.createElement(wm,null,n.createElement(Du,null,n.createElement(la,{service:new na(t.getApiClientOptions())},n.createElement(Wy,null))))))))))))))))))))))))))}}const vf=Ef;var wf=a(5338);const kf=document.createElement("div");document.body.appendChild(kf),(0,wf.H)(kf).render(n.createElement(vf,null))}},s={};function i(e){var t=s[e];if(void 0!==t)return t.exports;if(void 0===n[e]){var a=new Error("Cannot find module '"+e+"'");throw a.code="MODULE_NOT_FOUND",a}var r=s[e]={exports:{}};return n[e].call(r.exports,r,r.exports,i),r.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(1939));r=i.O(r)})(); \ No newline at end of file +(()=>{"use strict";var e,t,a,n={1939(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 y 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(b.Provider,{value:this.state},this.props.children)}}y.displayName="ContextualMenuContextProvider",y.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 x=a(4625),S=a(6347);function C(){return C=Object.assign?Object.assign.bind():function(e){for(var t=1;tn.createElement(e,C({context:t},this.props)))}}}const T=_;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 be{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 ye(){return ye=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 be.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,ye({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 Se 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),b=Ie.passwordExpirySettings.test(t),y=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),x=Ie.scim.test(t),S=Ie.secretHistory.test(t),C=Ie.mfaPolicyTeasing.test(t),_=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||C?D=Te.MFA_POLICY:i||_?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:b?D=Te.PASSWORD_EXPIRY:y?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:x||P?D=Te.SCIM:S&&(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(xe.Provider,{value:this.state},this.props.children)}}Se.displayName="AdministrationWorkspaceContextProvider",Se.propTypes={context:i().object,children:i().any,location:i().object,match:i().object,history:i().object,loadingContext:i().object,rbacContext:i().object};const Ce=(0,S.withRouter)(N(we((_e=Se,class extends n.Component{render(){return n.createElement(I.Consumer,null,e=>n.createElement(_e,A({loadingContext:e},this.props)))}}))));var _e;function Ne(e){return class extends n.Component{render(){return n.createElement(xe.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(b.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,S.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 bt(){return bt=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:yt,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:yt,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,xt;function St(){return St=Object.assign?Object.assign.bind():function(e){for(var t=1;tn.createElement(e,bt({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}}const Xt=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}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.")}},Qt=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)}},ea=class extends he{constructor(e,t={}){super(e,t),this._props.pagination&&(this._pagination=new Qt(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}},ta=class extends he{constructor(e,t={}){super(e,t),this._props.header&&(this._header=new ea(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 aa extends Xt{constructor(e){super(e,"metadata/settings/")}async get(){const e=await this.apiClient.get("getting-started");return new ta(e)}}class na{constructor(e){this.metadataGettingStartedSettingsApiService=new aa(e)}async findGettingStartedSettings(){try{const e=await this.metadataGettingStartedSettingsApiService.get();return new Jt(e.body)}catch(e){return console.error(e),Jt.createFromDefault()}}}class sa{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 ia(){return ia=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},metadataGettingStartedSettings:null,update:()=>{}});class oa 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(ra.Provider,{value:this.state},this.props.children)}}oa.propTypes={service:i().oneOfType([i().instanceOf(na),i().instanceOf(sa)]),children:i().any};const la=oa;function ca(e){return class extends n.Component{render(){return n.createElement(ra.Consumer,null,t=>n.createElement(e,ia({administrationEncryptedMetadataGettingStartedContext:t,metadataGettingStartedSettings:t.get()},this.props)))}}}var ma,da;function ua(){return ua=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(pa,{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(pa,{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(pa,{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(pa,{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(pa,{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(pa,{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(pa,{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"))))))))))}}ha.propTypes={context:i().object,administrationWorkspaceContext:i().object,history:i().object,navigationContext:i().any,metadataGettingStartedSettings:i().instanceOf(Jt)};const ga=(0,S.withRouter)(N(Ke(Ne(ca((0,f.CI)("common")(ha))))));var ba,ya;function fa(){return fa=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 Aa 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 xa,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 xa(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 _a(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(Ta.Provider,{value:this.state},this.props.children)}}Aa.propTypes={context:i().any,children:i().any};const Ia=N(Aa);function Ra(e){return class extends n.Component{render(){return n.createElement(Ta.Consumer,null,t=>n.createElement(e,Na({adminMfaContext:t},this.props)))}}}var Pa=a(3050),Da=a.n(Pa);class Oa{constructor(e,t){this.context=e,this.translation=t}static getInstance(e,t){return this.instance||(this.instance=new Oa(e,t)),this.instance}static killInstance(){this.instance=null}validateInput(e,t,a){const n=e.trim();return n.length?Da()(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 Ma=Oa;class Ua extends n.Component{constructor(e){super(e),this.bindCallbacks(),this.mfaFormService=Ma.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"))))}}Ua.propTypes={adminMfaContext:i().object,actionFeedbackContext:i().object,t:i().func};const Fa=Ra(m((0,f.CI)("common")(Ua)));var ja,La;function qa(){return qa=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:"4096",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(za,{className:"svg-icon eye-open"}),this.state.viewPassword&&n.createElement(Ga,{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)))}}Ba.defaultProps={id:"",name:"",autoComplete:"off"},Ba.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})};const Wa=(0,f.CI)("common")(Ba);var Ha=a(961);function $a(e,t,a){return n.createElement(n.Fragment,null,t&&(0,Ha.createPortal)(e,t,a))}class Ya extends n.Component{constructor(e){super(e),this.mfaFormService=Ma.getInstance(this.props.adminMfaContext,this.props.t),this.bindCallbacks()}async componentDidMount(){this.props.administrationWorkspaceContext.setDisplayAdministrationWorkspaceAction(Fa),this.isRunningUnderHttps&&this.props.adminMfaContext.findMfaSettings()}componentWillUnmount(){this.props.administrationWorkspaceContext.resetDisplayAdministrationWorkspaceAction(),this.props.adminMfaContext.clearContext(),Ma.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(Wa,{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(Wa,{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(Fa,null),$a(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(Ea,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}Ya.propTypes={context:i().object,adminMfaContext:i().object,createPortal:i().func,administrationWorkspaceContext:i().object,t:i().func};const Za=N(Ra(Ne((0,f.CI)("common")(Ya))));class Ja 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)}}Ja.propTypes={items:i().array,children:i().any};const Xa=Ja;class Qa extends n.Component{render(){return n.createElement("button",{type:"button",className:"link no-border inline ellipsis",onClick:this.props.onClick},this.props.name)}}Qa.propTypes={name:i().string,onClick:i().func};const en=Qa;class tn extends n.Component{get items(){switch(this.props.administrationWorkspaceContext.selectedAdministration){case Te.NONE:return[];case Te.HOME:return[n.createElement(en,{key:"bread-2",name:this.translate("Home"),onClick:this.onLastBreadcrumbClick.bind(this)})];default:return[n.createElement(en,{key:"bread-3",name:this.translate("Home"),onClick:this.props.navigationContext.onGoToAdministrationRequested}),n.createElement(en,{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(Xa,{items:this.items})}}tn.propTypes={administrationWorkspaceContext:i().object,location:i().object,history:i().object,navigationContext:i().any,t:i().func};const an=(0,S.withRouter)(Ke(Ne((0,f.CI)("common")(tn)))),nn=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 sn;function rn(){return rn=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(on,{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))))))}}ln.defaultProps={id:"",name:"select",className:"",direction:"bottom"},ln.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:nn.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 cn=(0,f.CI)("common")(ln);class mn 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)}}mn.defaultProps={value:n.createElement(f.x6,null,"Cancel")},mn.propTypes={disabled:i().bool,onClick:i().func,value:i().oneOfType([i().arrayOf(i().node),i().node,i().string])};const dn=(0,f.CI)("common")(mn);var un,pn;function hn(){return hn=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(gn,null))))}}bn.propTypes={onClose:i().func,title:i().string};const yn=(0,f.CI)("common")(bn),fn="directorysync",En=class{constructor(e){this.apiClientOptions=e,e.setResourceName(`${fn}`)}async findAll(){this.apiClientOptions.setResourceName(`${fn}/settings`);const e=new pt(this.apiClientOptions);return(await e.findAll()).body}async update(e){this.apiClientOptions.setResourceName(`${fn}`);const t=new pt(this.apiClientOptions);return(await t.update("settings",e)).body}async delete(){return this.apiClientOptions.setResourceName(`${fn}`),new pt(this.apiClientOptions).delete("settings")}async test(e){return this.apiClientOptions.setResourceName(`${fn}/settings/test`),new pt(this.apiClientOptions).create(e)}async simulate(){this.apiClientOptions.setResourceName(`${fn}`);const e=new pt(this.apiClientOptions);return(await e.get("synchronize/dry-run")).body}async synchronize(){this.apiClientOptions.setResourceName(`${fn}/synchronize`);const e=new pt(this.apiClientOptions);return(await e.create({})).body}},vn=/^[a-f0-9]{8}-[a-f0-9]{4}-[0-5][a-f0-9]{3}-[089ab][a-f0-9]{3}-[a-f0-9]{12}$/i,wn=e=>new(Da())(vn).test(e);class kn extends Xt{constructor(e){super(e,kn.RESOURCE_NAME)}static getSupportedContainOptions(){return["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"]}async findAll(e={},t={}){e=e?this.formatContainOptions(e,kn.getSupportedContainOptions()):null,t=t?this.formatFilterOptions(t,kn.getSupportedFiltersOptions()):null;const a={...e,...t},n=await this.apiClient.findAll(a);return new ta(n)}async findByRoleId(e){return wn(e),this.findAll({},{"has-role-id":e})}static get RESOURCE_NAME(){return"users"}}const xn=kn,Sn="mail",Cn="uniqueMember";class _n{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=_n.defaultFieldsMapping(e.fields_mapping),this.fallbackFields=_n.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=_n.defaultFieldsMapping(),this.fallbackFields=_n.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:Sn,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:Cn},e?.openldap?.group)}}}static defaultFallbackFields(e={}){return{ad:Object.assign({username:""},e?.ad)}}static get DEFAULT_AD_FIELDS_MAPPING_USER_USERNAME_VALUE(){return Sn}static get DEFAULT_OPENLDAP_FIELDS_MAPPING_GROUP_USERS_VALUE(){return Cn}}const Nn=_n,Tn=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 An(){return An=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 Pn extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.userDirectoryService=new En(e.context.getApiClientOptions()),this.userService=new xn(e.context.getApiClientOptions())}get defaultState(){return{users:[],errors:this.initErrors(),mustSynchronize:!1,currentSettings:null,settings:new Nn,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.userService.findAll()).body,a=t.find(e=>this.props.context.loggedInUser.id===e.id),n=new Nn(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=Nn.DEFAULT_AD_FIELDS_MAPPING_USER_USERNAME_VALUE,this.setError("fieldsMappingAdUserUsernameError",null),this.setError("fieldsMappingAdUserUsernameFallbackeError",null)),this.isOpenLdapFieldsMappingGroupUsersResetNeeded(e,t)&&(a.fieldsMapping.openldap.group.users=Nn.DEFAULT_OPENLDAP_FIELDS_MAPPING_GROUP_USERS_VALUE,this.setError("fieldsMappingOpenLdapGroupUsersError",null)),this.setState({settings:a})}isAdFieldsMappingUserUsernameResetNeeded(e,t){return e===In&&"openldap"===t}isOpenLdapFieldsMappingGroupUsersResetNeeded(e,t){return e===In&&"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 Tn(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 Tn(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(Rn.Provider,{value:this.state},this.props.children)}}Pn.propTypes={context:i().any,children:i().any,dialogContext:i().object};const Dn=N(h(Pn));function On(e){return class extends n.Component{render(){return n.createElement(Rn.Consumer,null,t=>n.createElement(e,An({adminUserDirectoryContext:t},this.props)))}}}var Mn=a(8140),Un=a.n(Mn);class Fn 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`;Un()(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(yn,{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(dn,{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")))))}}Fn.propTypes={onClose:i().func,dialogContext:i().object,actionFeedbackContext:i().any,adminUserDirectoryContext:i().object,t:i().func};const jn=m(On((0,f.CI)("common")(Fn)));class Ln 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`;Un()(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(yn,{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")))))}}Ln.propTypes={onClose:i().func,actionFeedbackContext:i().any,adminUserDirectoryContext:i().object,t:i().func};const qn=m(On((0,f.CI)("common")(Ln)));class zn{constructor(e,t){this.context=e,this.translate=t}static getInstance(e,t){return this.instance||(this.instance=new zn(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?Da()("^[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 Kn=zn;class Vn 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(Vn,{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,")"))))}}Vn.propTypes={node:i().object};const Gn=Vn;class Bn 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(Gn,{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"))))}}Bn.propTypes={context:i().any,onClose:i().func,t:i().func};const Wn=N((0,f.CI)("common")(Bn));var Hn;function $n(){return $n=Object.assign?Object.assign.bind():function(e){for(var t=1;tthis.handleFormSubmit("test")},n.createElement(Yn,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(ts,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(is,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"))))}}rs.propTypes={context:i().object,dialogContext:i().object,adminUserDirectoryContext:i().object,actionFeedbackContext:i().object,t:i().func};const os=N(m(h(On((0,f.CI)("common")(rs)))));var ls,cs;function ms(){return ms=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(cn,{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(cn,{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(cn,{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(cn,{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(os,null),$a(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(ds,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation"))))),document.getElementById("administration-help-panel")))}}us.propTypes={adminUserDirectoryContext:i().object,administrationWorkspaceContext:i().object,t:i().func};const ps=On(Ne((0,f.CI)("common")(us)));var hs;function gs(){return gs=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},getSettings:()=>{},setSettings:()=>{},hasSettingsChanges:()=>{},findEmailNotificationSettings:()=>{},save:()=>{},setProcessing:()=>{},isProcessing:()=>{},clearContext:()=>{}});class Ss extends n.Component{constructor(e){super(e),this.state=this.defaultState;const t=e.context.getApiClientOptions();this.emailNotificationService=new Es(t)}get defaultState(){return{currentSettings:null,settings:new vs,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 vs(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 ws(this.state.settings);await this.emailNotificationService.save(e),await this.findEmailNotificationSettings()}render(){return n.createElement(xs.Provider,{value:this.state},this.props.children)}}Ss.propTypes={context:i().any,children:i().any};const Cs=N(Ss);function _s(e){return class extends n.Component{render(){return n.createElement(xs.Consumer,null,t=>n.createElement(e,ks({adminEmailNotificationContext:t},this.props)))}}}class Ns 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"))))}}Ns.propTypes={adminEmailNotificationContext:i().object,actionFeedbackContext:i().object,t:i().func};const Ts=_s(m((0,f.CI)("common")(Ns)));class As 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(Ts,null),$a(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(Ea,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation"))))),document.getElementById("administration-help-panel")))}}As.propTypes={context:i().any,administrationWorkspaceContext:i().object,adminEmailNotificationContext:i().object,t:i().func};const Is=N(_s(Ne((0,f.CI)("common")(As))));var Rs,Ps,Ds=a(8097);function Os(){return Os=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},findSubscriptionKey:()=>{},isProcessing:()=>{},setProcessing:()=>{},getActiveUsers:()=>{},clearContext:()=>{}});class ci extends n.Component{constructor(e){super(e),this.state=this.defaultState}get defaultState(){return{subscription:new ri,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 ri;try{const t=await this.props.context.onGetSubscriptionKeyRequested();e=new ri(t.toDto())}catch(t){"PassboltSubscriptionError"===t.name&&(e=new ri(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(li.Provider,{value:this.state},this.props.children)}}function mi(e){return class extends n.Component{render(){return n.createElement(li.Consumer,null,t=>n.createElement(e,oi({adminSubscriptionContext:t},this.props)))}}}ci.propTypes={context:i().any,children:i().any},N(ci);const di=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"}},ui=class{constructor(e){this.port=e}async findOrganizationSubscriptionKey(){const e=await this.port.request("passbolt.subscription.get");return new di(e)}async updateOrganizationSubscriptionKey(e){(0,ie.A)(e);const t=await this.port.request("passbolt.subscription.update",{data:e});return new di(t)}};class pi extends n.Component{constructor(e){super(e),this.state=this.getDefaultState(),this.initEventHandlers(),this.createInputRef(),this.subscriptionKeyService=new ui(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{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.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))),n.createElement("div",{className:"submit-wrapper clearfix"},n.createElement(dn,{disabled:this.hasAllInputDisabled(),onClick:this.handleCloseClick}),n.createElement(ii,{disabled:this.hasAllInputDisabled(),processing:this.state.processing,value:this.translate("Save")}))))}}pi.propTypes={context:i().any,onClose:i().func,actionFeedbackContext:i().any,adminSubscriptionContext:i().object,dialogContext:i().any,administrationWorkspaceContext:i().any,t:i().func};const hi=N(mi(Ne(m(h((0,f.CI)("common")(pi))))));class gi{constructor(e){this.context=e.context,this.dialogContext=e.dialogContext,this.subscriptionContext=e.adminSubscriptionContext}static getInstance(e){return this.instance||(this.instance=new gi(e)),this.instance}static killInstance(){this.instance=null}editSubscription(){const e={key:this.subscriptionContext.getSubscription().data};this.context.setContext({editSubscriptionKey:e}),this.dialogContext.open(hi)}}const bi=gi,yi=(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})};var fi,Ei;function vi(){return vi=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},getLocale:()=>{},supportedLocales:()=>{},setLocale:()=>{},hasLocaleChanges:()=>{},findLocale:()=>{},save:()=>{},setProcessing:()=>{},isProcessing:()=>{},clearContext:()=>{}});class Pi extends n.Component{constructor(e){super(e),this.state=this.defaultState;const t=e.context.getApiClientOptions();this.internalisationService=new Ai(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(Ri.Provider,{value:this.state},this.props.children)}}Pi.propTypes={context:i().any,children:i().any};const Di=N(Pi);function Oi(e){return class extends n.Component{render(){return n.createElement(Ri.Consumer,null,t=>n.createElement(e,Ii({adminInternationalizationContext:t},this.props)))}}}class Mi 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"))))}}Mi.propTypes={context:i().object,adminInternationalizationContext:i().object,actionFeedbackContext:i().object,t:i().func};const Ui=Oi(m((0,f.CI)("common")(Mi)));class Fi 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(cn,{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),$a(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(Ti,null),n.createElement("span",null,n.createElement(f.x6,null,"Contribute")))),document.getElementById("administration-help-panel")))}}Fi.propTypes={context:i().object,administrationWorkspaceContext:i().object,adminInternationalizationContext:i().object,t:i().func};const ji=N(Oi(Ne((0,f.CI)("common")(Fi))));function Li(){return Li=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},getKeyInfo:()=>{},changePolicy:()=>{},changePublicKey:()=>{},hasPolicyChanges:()=>{},resetChanges:()=>{},downloadPrivateKey:()=>{},save:()=>{}});class zi 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(qi.Provider,{value:this.state},this.props.children)}}function Ki(e){return class extends n.Component{render(){return n.createElement(qi.Consumer,null,t=>n.createElement(e,Li({adminAccountRecoveryContext:t},this.props)))}}}function Vi(){return Vi=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},stop:()=>{}});class Bi 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(Gi.Provider,{value:this.state},this.props.children)}}Bi.displayName="WorkflowContextProvider",Bi.propTypes={children:i().any};class Wi 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(Wa,{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(dn,{disabled:this.hasAllInputDisabled(),onClick:this.handleCloseClick}),n.createElement(ii,{disabled:this.hasAllInputDisabled(),processing:this.state.processing,value:this.translate("Submit")}))))}}Wi.propTypes={context:i().any.isRequired,onClose:i().func,onSubmit:i().func,actionFeedbackContext:i().any,dialogContext:i().object,t:i().func};const Hi=N(h((0,f.CI)("common")(Wi)));class $i 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},yi(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(dn,{onClick:this.handleClose,disabled:this.isProcessing}),n.createElement(ii,{value:this.translate("Save"),disabled:this.isProcessing,processing:this.isProcessing,warning:!0}))))}}$i.propTypes={context:i().any,onClose:i().func,onSubmit:i().func,policy:i().string,keyInfo:i().object,t:i().func};const Yi=N((0,f.CI)("common")($i));class Zi 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(Yi,{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(Hi,{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)}}Zi.propTypes={dialogContext:i().any,adminAccountRecoveryContext:i().any,actionFeedbackContext:i().object,context:i().object,onStop:i().func.isRequired,t:i().func};const Ji=N(h(m(Ki((0,f.CI)("common")(Zi)))));class Xi 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(Ji,{})}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"))))}}Xi.propTypes={adminAccountRecoveryContext:i().object,workflowContext:i().any};const Qi=function(e){return class extends n.Component{render(){return n.createElement(Gi.Consumer,null,t=>n.createElement(e,Vi({workflowContext:t},this.props)))}}}(Ki((0,f.CI)("common")(Xi)));class er 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))}}er.propTypes={name:i().string,type:i().string.isRequired,isActive:i().bool,onClick:i().func,children:i().any};const tr=er;class ar 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(tr,{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))}}ar.propTypes={activeTabName:i().string,children:i().any};const nr=ar;class sr 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(dn,{disabled:this.hasAllInputDisabled(),onClick:this.props.onClose}),n.createElement(ii,{disabled:this.hasAllInputDisabled(),processing:this.state.processing,value:this.translate("Apply")})))}}sr.propTypes={context:i().object,onUpdateOrganizationKey:i().func,onClose:i().func,t:i().func};const ir=N((0,f.CI)("common")(sr)),rr={"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 or=a(2052),lr=a.n(or);const cr=[{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}],mr={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:["😀","😁","😂","😃","😄","😅","😆","😇","😈","😉","😊","😋","😌","😍","😎","😏","😐","😑","😒","😓","😔","😕","😖","😗","😘","😙","😚","😛","😜","😝","😞","😟","😠","😡","😢","😣","😤","😥","😦","😧","😨","😩","😪","😫","😬","😭","😮","😯","😰","😱","😲","😳","😴","😵","😶","😷","😸","😹","😺","😻","😼","😽","😾","😿","🙀","🙁","🙂","🙃","🙄","🙅","🙆","🙇","🙈","🙉","🙊","🙋","🙌","🙍","🙎","🙏"]}},dr=["O","l","|","I","0","1"],ur=Object.values(mr).flatMap(e=>e.characters),pr={evaluateMaxPasswordEntropy:e=>{const t=Object.entries(mr).filter(([t])=>e[t]).reduce((e,[t])=>[...e,...mr[t].characters],[]).filter(t=>!e.exclude_look_alike_chars||!dr.includes(t));return hr(e.length,t.length)},entropyPassword:(e="")=>{const t=(new(lr())).splitGraphemes(e);let a=0;for(const[e]of Object.entries(mr)){const n=mr[e];t.some(e=>n.characters.includes(e))&&(a+=n.characters.length)}const n=new Set(t.filter(e=>!ur.includes(e)));return hr(t.length,a+n.size)},entropyPassphrase:(e=0,t="")=>hr(e,3*rr["en-UK"].length)+pr.entropyPassword(t),strength:(e=0)=>cr.reduce((t,a)=>t?a.strength>t.strength&&e>=a.strength?a:t:a),calculEntropy:hr};function hr(e,t){return e&&t?e*(Math.log(t)/Math.log(2)):0}const gr=function(e){const t={isPassphrase:!1};if(!e)return t;const a=rr["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}},wr=(e,t)=>t.split(".").reduce((e,t)=>e?.[t],e),kr=(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||[xr.HTTP,xr.HTTPS],n=[xr.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}},xr={FTP:"http:",FTPS:"https:",HTTP:"http:",HTTPS:"https:",JAVASCRIPT:"javascript:",SSH:"ssh:"};class Sr{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=wr(this.settings,a)||null;if(n&&"object"==typeof n){const e=wr(n,"enabled");void 0!==e&&!0!==e||(t=!0)}return t}isFeatureBeta(e){(0,ie.A)(e);const t=`passbolt.plugins.${e}.isInBeta`;return wr(this.settings,t)||!1}getPluginSettings(e){const t=`passbolt.plugins.${e}`;return wr(this.settings,t)}getRememberMeOptions(){return(this.getPluginSettings("rememberMe")||{}).options||{}}get hasRememberMeUntilILogoutOption(){return void 0!==(this.getRememberMeOptions()||{})[-1]}getServerTimezone(){return wr(this.settings,"passbolt.app.server_timezone")}get termsLink(){const e=wr(this.settings,"passbolt.legal.terms.url");return!!e&&kr(e)}get privacyLink(){const e=wr(this.settings,"passbolt.legal.privacy_policy.url");return!!e&&kr(e)}get registrationPublic(){return!0===wr(this.settings,"passbolt.registration.public")}get debug(){return!0===wr(this.settings,"app.debug")}get url(){return wr(this.settings,"app.url")||""}get version(){return wr(this.settings,"app.version.number")}get isCommunityEdition(){return"ce"===wr(this.settings,"passbolt.edition")}get locale(){return wr(this.settings,"app.locale")||Sr.DEFAULT_LOCALE.locale}async setLocale(e){this.settings.app.locale=e}get supportedLocales(){return wr(this.settings,"passbolt.plugins.locale.options")||Sr.DEFAULT_SUPPORTED_LOCALES}get generatorConfiguration(){return wr(this.settings,"passbolt.plugins.generator.configuration")}get emailValidateRegex(){return this.settings?.passbolt?.email?.validate?.regex||null}static get DEFAULT_SUPPORTED_LOCALES(){return[Sr.DEFAULT_LOCALE]}static get DEFAULT_LOCALE(){return{locale:"en-UK",label:"English"}}}class Cr{static validate(e){return"string"==typeof e&&Da()("^[\\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 _r{constructor(e){if("string"!=typeof e)throw Error("The regex should be a string.");this.regex=new(Da())(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 Sr&&e.emailValidateRegex?new _r(e.emailValidateRegex):Cr}}function Tr(){return Tr=Object.assign?Object.assign.bind():function(e){for(var t=1;t{}});class Ir 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(Ar.Provider,{value:this.state},this.props.children)}}function Rr(e){return class extends n.Component{render(){return n.createElement(Ar.Consumer,null,t=>n.createElement(e,Tr({passwordPoliciesContext:t},this.props)))}}}Ir.propTypes={context:i().any,children:i().any},N(Ir);class Pr 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 Pr.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=pr.strength(this.props.entropy);return n.createElement(n.Fragment,null,e.label)}getProgresseBarStyle(e){return{width:`${Pr.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"})))))}}Pr.defaultProps={isMinimumEntropyRequired:!0},Pr.propTypes={targetEntropy:i().number.isRequired,isMinimumEntropyRequired:i().bool.isRequired,entropy:i().number,error:i().bool,t:i().func};const Dr=(0,f.CI)("common")(Pr);class Or 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 vr(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}=gr(e);return n?pr.entropyPassphrase(t,a):pr.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 yr||e instanceof Er))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(Wa,{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(Dr,{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(Wa,{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(dn,{disabled:this.hasAllInputDisabled(),onClick:this.props.onClose}),n.createElement(ii,{disabled:this.hasAllInputDisabled(),processing:this.state.processing,value:this.translate("Generate & Apply")})))}}Or.propTypes={context:i().any,onUpdateOrganizationKey:i().func,onClose:i().func,t:i().func,passwordPoliciesContext:i().object};const Mr=N(h(Rr((0,f.CI)("common")(Or))));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},yi(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},yi(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(Qi,null),$a(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(Vr,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}Gr.propTypes={context:i().object,dialogContext:i().any,administrationWorkspaceContext:i().object,adminAccountRecoveryContext:i().object,t:i().func};const Br=N(h(Ne(Ki((0,f.CI)("common")(Gr)))));class Wr 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(pa,{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(bs,null),n.createElement(f.x6,null,"In case of passphrase loss.")),n.createElement("li",null,n.createElement(bs,null),n.createElement(f.x6,null,"In case of private key loss.")),n.createElement("li",null,n.createElement(bs,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")))))),$a(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(Vr,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}Wr.propTypes={context:i().object,t:i().func};const Hr=N((0,f.CI)("common")(Wr)),$r={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 Yr(e,t){const a=[];for(let n=0;n(!a||e.host===a)&&e.port===t)}const Jr={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:Yr(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])};Jr.defaultConfiguration=Zr(Jr,587,"email-smtp.eu-central-1.amazonaws.com");const Xr={id:"elastic-email",name:"ElasticEmail",icon:"elastic-email.svg",help_page:"https://help.elasticemail.com/en/articles/4803409-smtp-settings",availableConfigurations:Yr(["smtp.elasticemail.com","smtp25.elasticemail.com"],[25,2525,587])};Xr.defaultConfiguration=Zr(Xr,587,"smtp.elasticemail.com");const Qr={id:"google-workspace",name:"Google Workspace",icon:"gmail.svg",help_page:"https://support.google.com/a/answer/2956491",availableConfigurations:Yr(["smtp-relay.gmail.com"],[25,587])};Qr.defaultConfiguration=Zr(Qr,587);const eo={id:"google-mail",name:"Google Mail",icon:"gmail.svg",help_page:"https://support.google.com/a/answer/2956491",availableConfigurations:Yr(["smtp.gmail.com"],[587])};eo.defaultConfiguration=Zr(eo,587);const to={id:"mailgun",name:"MailGun",icon:"mailgun.svg",help_page:"https://documentation.mailgun.com/en/latest/quickstart-sending.html",availableConfigurations:Yr(["smtp.mailgun.com"],[587])};to.defaultConfiguration=to.availableConfigurations[0];const ao={id:"mailjet",name:"Mailjet",icon:"mailjet.svg",help_page:"https://dev.mailjet.com/smtp-relay/configuration/",availableConfigurations:Yr(["in-v3.mailjet.com"],[25,2525,587,588])};ao.defaultConfiguration=Zr(ao,587);const no={id:"mandrill",name:"Mandrill",icon:"mandrill.svg",help_page:"https://mailchimp.com/developer/transactional/docs/smtp-integration/",availableConfigurations:Yr(["smtp.mandrillapp.com"],[25,2525,587])};no.defaultConfiguration=Zr(no,587);const so={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:Yr(["smtp.office365.com"],[25,587])};so.defaultConfiguration=Zr(so,587);const io={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:Yr(["smtp-mail.outlook.com"],[587])};io.defaultConfiguration=Zr(io,587);const ro={id:"sendgrid",name:"Sendgrid",icon:"sendgrid.svg",help_page:"https://docs.sendgrid.com/for-developers/sending-email/integrating-with-the-smtp-api",availableConfigurations:Yr(["smtp.sendgrid.net"],[25,2525,587])};ro.defaultConfiguration=Zr(ro,587);const oo={id:"sendinblue",name:"Sendinblue",icon:"sendinblue.svg",help_page:"https://help.sendinblue.com/hc/en-us/articles/209462765",availableConfigurations:Yr(["smtp-relay.sendinblue.com"],[25,587])};oo.defaultConfiguration=Zr(oo,587);const lo={id:"zoho",name:"Zoho",icon:"zoho.svg",help_page:"https://www.zoho.com/mail/help/zoho-smtp.html",availableConfigurations:Yr(["smtp.zoho.eu","smtppro.zoho.eu"],[587])};lo.defaultConfiguration=Zr(lo,587,"smtp.zoho.eu");const co=[Jr,Xr,eo,Qr,to,ao,no,so,io,ro,oo,lo,{id:"other",name:"Other",icon:null,availableConfigurations:[],defaultConfiguration:{host:"",port:"",tls:!0}}];class mo extends Xt{constructor(e){super(e,mo.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 ta(e)}async create(e){this.assertNonEmptyData(e);const t=await this.apiClient.create(e);return t.body.tls=Boolean(t.body.tls),new ta(t)}}const uo=mo,po=class extends he{static getSchema(){return{type:"object",required:[...Eo.getSchema().required],properties:{...Eo.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"}},ho=class extends he{static getSchema(){return{type:"object",required:[...Eo.getSchema().required,"username"],properties:{...Eo.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"}},go=class extends he{static getSchema(){return{type:"object",required:[...Eo.getSchema().required,"username","password"],properties:{...Eo.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"}},bo=class extends he{static getSchema(){return{type:"object",required:[...Eo.getSchema().required,"oauth_username","tenant_id","client_id","client_secret"],properties:{...Eo.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"}},yo="default",fo="file",Eo=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:[yo,"env","db",fo]},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 bo(e,t):"username"in e&&null!==e.username?"password"in e&&null!==e.password?new go(e,t):new ho(e,t):new po(e,t)}static get ENTITY_NAME(){return"SmtpSettings"}static get SETTINGS_SOURCE_DEFAULT(){return yo}static get SETTINGS_SOURCE_ENV(){return"env"}static get SETTINGS_SOURCE_DB(){return"db"}static get SETTINGS_SOURCE_FILE(){return fo}},vo=class{constructor(e){this.smtpSettingsApiService=new uo(e)}async find(){const e=await this.smtpSettingsApiService.find();return Eo.createFromSettings(e.body)}},wo=class{constructor(e){this.smtpSettingsApiService=new uo(e)}async save(e){const t=await this.smtpSettingsApiService.create(e.toDto());return Eo.createFromSettings(t.body)}},ko=["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 xo=a(3975);const So="(?:[_\\p{L}0-9][-_\\p{L}0-9]*\\.)*(?:[\\p{L}0-9][-\\p{L}0-9]{0,62})\\.(?:(?:[a-z]{2}\\.)?[a-z]{2,})",Co=class{static extractDomainFromEmail(e){const t=Da()(`(?<=@)${So}`);return Da().match(e,t)||""}static isProfessional(e){return!ko.includes(e)}static checkDomainValidity(e){if(!Da()(`^${So}$`).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 Da()(`^${So}$`).test(e)||(0,xo.A)({exact:!0}).test(e)}},_o="none",No="username",To="username_password",Ao="oauth",Io=[po,ho,go,bo],Ro=[...new Set(Io.flatMap(e=>Object.keys(e.getDefaultData())))];class Po extends he{static getSchema(){const e=Eo.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&&(Co.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 _o:return po;case No:return ho;case To:return go;case Ao:return bo;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?Ao:null===this._props.username||void 0===this._props.username?_o:null===this._props.password||void 0===this._props.password?No:To}static createDefault(){return new Po({host:"",port:"",tls:!0,client:"",sender_email:"",sender_name:"Passbolt",...go.getDefaultData()},{validate:!1})}static get ENTITY_NAME(){return"SmtpSettingsForm"}static get AUTHENTICATION_METHOD_NONE(){return _o}static get AUTHENTICATION_METHOD_USERNAME(){return No}static get AUTHENTICATION_METHOD_USERNAME_PASSWORD(){return To}static get AUTHENTICATION_METHOD_OAUTH(){return Ao}static get AUTH_FIELDS(){return Ro}}const Do=Po;class Oo extends Xt{constructor(e){super(e,Oo.RESOURCE_NAME)}static get RESOURCE_NAME(){return"smtp/email"}async create(e){this.assertNonEmptyData(e);const t=await this.apiClient.create(e);return new ta(t)}}const Mo=Oo,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 Fo=a(1811);function jo(){return jo=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 qo extends n.Component{constructor(e){super(e),this.state=this.defaultState;const t=e.context.getApiClientOptions();this.findSmtpSettingsService=new vo(t),this.saveSmtpSettingsService=new wo(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,Fo.A)(e=>this.formSettings?.validate({validateBuildRules:{siteSettings:this.props.context.siteSettings}}));hasSettingsChanges=(0,Fo.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=Do.createDefault().toFormDto()}e.sender_email=e.sender_email??this.props.context.loggedInUser.username,this.originalSettings=new Do(e,{validate:!1});const t=this.originalSettings.toFormDto();if(t.host&&t.port){const e=this.originalSettings.detectProvider(co);this.originalSettings.set("provider",e,{validate:!1})}this.formSettings=new Do(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=Eo.createFromSettings(e);await this.saveSmtpSettingsService.save(t),this.props.actionFeedbackContext.displaySuccess(this.props.t("The SMTP settings have been saved successfully")),this.originalSettings=new Do(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=Eo.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(co);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()===Do.AUTHENTICATION_METHOD_OAUTH&&this.formSettings.changeAuthenticationMethod(Do.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(co);this.formSettings.set("provider",t,{validate:!1}),"office-365"!==t&&this.formSettings.getAuthenticationMethod()===Do.AUTHENTICATION_METHOD_OAUTH&&this.formSettings.changeAuthenticationMethod(Do.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(Lo.Provider,{value:this.state},this.props.children)}}qo.propTypes={context:i().any,dialogContext:i().object,actionFeedbackContext:i().object,children:i().any,t:i().func};const zo=N(h(m((0,f.CI)("common")(qo))));function Ko(e){return class extends n.Component{render(){return n.createElement(Lo.Consumer,null,t=>n.createElement(e,jo({adminSmtpSettingsContext:t},this.props)))}}}const Vo="form",Go="error",Bo="success";class Wo extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.bindCallbacks()}get defaultState(){return{uiState:Vo,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:Bo,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:Go,debugDetails:this.formatDebug(a),displayLogs:!0})}handleDisplayLogsClick(){this.setState({displayLogs:!this.state.displayLogs})}handleRetryClick(){this.setState({uiState:Vo})}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===Vo&&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(dn,{disabled:this.hasAllInputDisabled(),onClick:this.props.handleClose}),n.createElement(ii,{disabled:this.hasAllInputDisabled(),processing:this.state.processing,value:this.translate("Send")}))),this.state.uiState===Go&&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===Bo&&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"))))))}}Wo.propTypes={context:i().object,adminSmtpSettingsContext:i().object,handleClose:i().func,t:i().func};const Ho=N(Ko((0,f.CI)("common")(Wo)));var $o,Yo;function Zo(){return Zo=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 co.map(e=>({value:e.id,label:e.name}))}get authenticationMethodList(){const e=this.props.adminSmtpSettingsContext.getCurrentSmtpSettings(),t=[{value:nl,label:this.translate("None")},{value:sl,label:this.translate("Username only")},{value:il,label:this.translate("Username & password")}];return"office-365"===e?.provider&&t.push({value:rl,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===sl||this.authenticationMethod===il}shouldDisplayPassword(){return this.authenticationMethod===il}shouldDisplayOAuth(){return this.authenticationMethod===rl}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=co.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"},co.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(wi,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(cn,{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(cn,{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(Wa,{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(Wa,{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(cn,{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(Qo,null)),$a(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(ds,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(al,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(ds,null),n.createElement("span",null,n.createElement(f.x6,null,"More informations"))))),document.getElementById("administration-help-panel")))}}ol.propTypes={context:i().object,dialogContext:i().any,administrationWorkspaceContext:i().object,adminSmtpSettingsContext:i().object,t:i().func};const ll=N(Ko(h(Ne((0,f.CI)("common")(ol))))),cl=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()]}},ml=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)}},dl=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)}},ul=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())}}},pl=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{Co.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)=>{cl.listValues(this.fields).filter(e=>e===t&&""!==e).length>1&&e.set(a,this.translate("This domain already exist"))})}};class hl 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&&cl.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(dn,{onClick:this.handleClose,disabled:e}),n.createElement(ii,{value:this.props.t("Save"),disabled:e,processing:e,warning:!0}))))}}hl.propTypes={context:i().any,onSubmit:i().func,adminSelfRegistrationContext:i().object,onClose:i().func,t:i().func};const gl=N(kl((0,f.CI)("common")(hl)));class bl 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(dn,{onClick:this.handleClose,disabled:e}),n.createElement(ii,{value:this.props.t("Save"),disabled:e,processing:e,warning:!0}))))}}bl.propTypes={adminSelfRegistrationContext:i().object,onClose:i().func,onSubmit:i().func,t:i().func};const yl=kl((0,f.CI)("common")(bl));function fl(){return fl=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 vl extends n.Component{constructor(e){super(e),this.state=this.defaultState;const t=e.context.getApiClientOptions();this.selfRegistrationService=new ml(t),this.selfRegistrationFormService=new pl(this.props.t)}get defaultState(){return{errors:new Map,submitted:!1,currentSettings:null,focus:!1,saved:!1,domains:new dl,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 dl(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=cl.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=cl.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=cl.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 ul(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(gl,{domains:this.getAllowedDomains(),onSubmit:()=>this.saveSettings(),onClose:()=>this.handleCloseDialog()})}displayConfirmDeletionDialog(){this.props.dialogContext.open(yl,{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(El.Provider,{value:this.state},this.props.children)}}vl.propTypes={context:i().any,children:i().any,t:i().any,dialogContext:i().any,actionFeedbackContext:i().object};const wl=N(h(m((0,f.CI)("common")(vl))));function kl(e){return class extends n.Component{render(){return n.createElement(El.Consumer,null,t=>n.createElement(e,fl({adminSelfRegistrationContext:t},this.props)))}}}const xl=new Map;function Sl(e){if("string"!=typeof e)return console.warn("useDynamicRefs: Cannot set ref without key");const t=n.createRef();return xl.set(e,t),t}function Cl(e){return e?xl.get(e):console.warn("useDynamicRefs: Cannot get ref without key")}var _l=a(6459),Nl=a.n(_l);class Tl 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"))))}}Tl.propTypes={adminSelfRegistrationContext:i().object,t:i().func};const Al=(0,f.CI)("common")(kl(Tl));var Il;function Rl(){return Rl=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)=>{Co.isProfessional(e)||t.set(a,"This is not a safe professional domain")}),this.setState({warnings:t})}setupSettings(){const e=new dl(this.props.adminSelfRegistrationContext.getCurrentSettings());if(this.props.adminSelfRegistrationContext.setDomains(e),this.assertNotProfessionalDomains(e.allowedDomains),0===e.allowedDomains.size){const e=Co.extractDomainFromEmail(this.currentUser?.username);Co.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=Co.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.")),cl.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(Ml,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(Pl,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(Al,null)),$a(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(ds,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 Fl=N(h(kl(Ne((0,f.CI)("common")(Ul))))),jl=[{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"}}],Ll="form",ql="success";class zl extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.bindCallbacks()}get defaultState(){return{uiState:Ll,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:ql,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===Ll&&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===ql&&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(dn,{disabled:this.hasAllInputDisabled(),onClick:this.handleCloseDialog}),n.createElement(ii,{disabled:!this.canSaveSettings(),processing:this.state.processing,value:this.translate("Save settings")}))))}}zl.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 Kl=N(fc(m((0,f.CI)("common")(zl))));class Vl 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(dn,{disabled:e,onClick:this.props.onClose}),n.createElement(ii,{warning:!0,disabled:e,processing:this.state.processing,value:this.props.t("Disable")}))))}}Vl.propTypes={adminSsoContext:i().object,onClose:i().func,t:i().func};const Gl=fc((0,f.CI)("common")(Vl)),Bl=["https://login.microsoftonline.com","https://login.microsoftonline.us","https://login.partner.microsoftonline.cn"];class Wl extends se{constructor(e,t={}){const a=Wl.sanitizeDto(e);super(ae.validate(Wl.ENTITY_NAME,a,Wl.getSchema()),t)}static getSchema(){return{type:"object",required:["url","client_id","tenant_id","client_secret","client_secret_expiry"],properties:{url:{type:"string",enum:Bl},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 Bl}}const Hl=Wl;class $l 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 Hl.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 $l(a,{validate:!1})}static createDefault(e={}){return new $l(e,{validate:!1})}static get ENTITY_NAME(){return"AzureSsoSettingsForm"}}const Yl=$l,Zl=/^https:\/\/.+[^/]$/;class Jl extends se{constructor(e,t={}){super(ae.validate(Jl.ENTITY_NAME,e,Jl.getSchema()),t)}static getSchema(){return{type:"object",required:["url","openid_configuration_path","scope","client_id","client_secret"],properties:{url:{type:"string",pattern:Zl},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 Xl=Jl;class Ql extends he{static getSchema(){const e=Xl.getSchema();return{...e,properties:{id:{type:"string"},...e.properties}}}get provider(){return Xl.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 Ql(a,{validate:!1})}static createDefault(e={}){return new Ql(e,{validate:!1})}static get ENTITY_NAME(){return"OAuth2SsoSettingsForm"}}const ec=Ql,tc=["https://accounts.google.com"];class ac extends se{constructor(e,t={}){super(ae.validate(ac.ENTITY_NAME,e,ac.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 tc}}const nc=ac;class sc extends he{static getSchema(){const e=nc.getSchema();return{...e,properties:{id:{type:"string",format:"uuid"},...e.properties}}}get provider(){return nc.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 sc(a,{validate:!1})}static createDefault(e={}){return new sc(e,{validate:!1})}static get ENTITY_NAME(){return"GoogleSsoSettingsForm"}}const ic=sc,rc=/^https:\/\/.+[^/]$/;class oc extends se{constructor(e,t={}){super(ae.validate(oc.ENTITY_NAME,e,oc.getSchema()),t)}static getSchema(){return{type:"object",required:["url","openid_configuration_path","scope","client_id","client_secret"],properties:{url:{type:"string",pattern:rc},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 lc=oc;class cc extends he{static getSchema(){const e=lc.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 lc.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 cc(a,{validate:!1})}static createDefault(e={}){return new cc(e,{validate:!1})}}const mc=cc,dc=["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"],uc=class extends he{static getSchema(){return{type:"object",required:["url","environment_id","client_id","client_secret","email_claim"],properties:{url:{type:"string",enum:dc},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 dc}};class pc extends he{static getSchema(){const e=uc.getSchema();return{...e,properties:{id:{type:"string"},...e.properties}}}get provider(){return uc.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 pc(a,{validate:!1})}static createDefault(e={}){return new pc(e,{validate:!1})}static get SCOPE(){return"openid profile email"}static get ENTITY_NAME(){return"PingOneSsoSettingsForm"}}const hc=pc;function gc(){return gc=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 yc 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,Fo.A)(e=>this.formSettings?.validate());hasSettingsChanges=(0,Fo.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 Hl.PROVIDER_ID:return Yl.fromEntityDto(e);case nc.PROVIDER_ID:return ic.fromEntityDto(e);case Xl.PROVIDER_ID:return ec.fromEntityDto(e);case lc.PROVIDER_ID:return mc.fromEntityDto(e);case uc.PROVIDER_ID:return hc.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=jl.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(Gl)}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=jl.find(t=>t.id===e.provider);this.props.dialogContext.open(Kl,{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(bc.Provider,{value:this.state},this.props.children)}}function fc(e){return class extends n.Component{render(){return n.createElement(bc.Consumer,null,t=>n.createElement(e,gc({adminSsoContext:t},this.props)))}}}yc.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")(yc))));class Ec 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"))))}}Ec.propTypes={adminSsoContext:i().object};const vc=fc((0,f.CI)("common")(Ec));var wc;function kc(){return kc=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},copy:()=>{}});class Ic 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(Ac.Provider,{value:this.state},this.props.children)}}function Rc(e){return class extends n.Component{render(){return n.createElement(Ac.Consumer,null,t=>n.createElement(e,Tc({clipboardContext:t},this.props)))}}}Ic.propTypes={context:i().any.isRequired,actionFeedbackContext:i().any.isRequired,children:i().any,t:i().func},N(m((0,f.CI)("common")(Ic)));class Pc 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(cn,{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(xc,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(Wa,{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(_c,{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(cn,{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(cn,{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."))))))}}Pc.propTypes={adminSsoContext:i().object,actionFeedbackContext:i().any,context:i().any,clipboardContext:i().object,t:i().func};const Dc=N(m(fc(Rc((0,f.CI)("common")(Pc)))));class Oc 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 uc.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(cn,{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(xc,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(Wa,{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:hc.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."))))}}Vc.propTypes={adminSsoContext:i().object,clipboardContext:i().object,context:i().any,t:i().func};const Gc=N(Rc(fc((0,f.CI)("common")(Vc))));class Bc 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 jl.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=jl.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(cn,{id:"sso-provider-input",name:"provider",items:this.supportedSsoProviders,value:t?.provider,onChange:this.handleProviderInputChange})),t?.provider===Hl.PROVIDER_ID&&n.createElement(Dc,null),t?.provider===nc.PROVIDER_ID&&n.createElement(Mc,null),t?.provider===Xl.PROVIDER_ID&&n.createElement(Fc,null),t?.provider===lc.PROVIDER_ID&&n.createElement(Lc,null),t?.provider===uc.PROVIDER_ID&&n.createElement(Gc,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(vc,null),$a(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(ds,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),t?.provider===Hl.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(Kc,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),t?.provider===nc.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(Kc,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),t?.provider===lc.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(Kc,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),t?.provider===uc.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(Kc,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation"))))),document.getElementById("administration-help-panel")))}}Bc.propTypes={administrationWorkspaceContext:i().object,adminSsoContext:i().object,actionFeedbackContext:i().any,context:i().any,t:i().func};const Wc=N(m(Ne(fc((0,f.CI)("common")(Bc)))));class Hc 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(pa,{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(bs,null),n.createElement(f.x6,null,"Reduce password fatigue and simplify login.")),n.createElement("li",null,n.createElement(bs,null),n.createElement(f.x6,null,"Centralise user authentication management.")),n.createElement("li",null,n.createElement(bs,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")))))),$a(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(ds,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}Hc.propTypes={context:i().any,t:i().func};const $c=N((0,f.CI)("common")(Hc)),Yc=class{constructor(e={remember_me_for_a_month:!1}){this.policy=e.policy,this.rememberMeForAMonth=e.remember_me_for_a_month}},Zc=class{constructor(e={rememberMeForAMonth:!1}){this.policy=e.policy||"opt-in",this.remember_me_for_a_month=e.rememberMeForAMonth}};function Jc(){return Jc=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},getSettings:()=>{},setSettings:()=>{},hasSettingsChanges:()=>{},findSettings:()=>{},setProcessing:()=>{},isProcessing:()=>{},clearContext:()=>{},save:()=>{}});class Qc 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 Yc,currentSettings:new Yc,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 Yc(t);this.setState({currentSettings:a,settings:a},e),this.setProcessing(!1)}async save(){this.setProcessing(!0);const e=new Zc(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(Xc.Provider,{value:this.state},this.props.children)}}Qc.propTypes={context:i().any,children:i().any,t:i().any,actionFeedbackContext:i().object};const em=N(Qc);function tm(e){return class extends n.Component{render(){return n.createElement(Xc.Consumer,null,t=>n.createElement(e,Jc({adminMfaPolicyContext:t},this.props)))}}}class am 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"))))}}am.propTypes={adminMfaPolicyContext:i().object,actionFeedbackContext:i().object,t:i().func};const nm=tm(m((0,f.CI)("common")(am)));class sm 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(nm,null),$a(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(ds,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}sm.propTypes={context:i().object,administrationWorkspaceContext:i().object,adminMfaPolicyContext:i().object,t:i().func};const im=N(Ne(tm((0,f.CI)("common")(sm))));class rm 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(pa,{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(bs,null),n.createElement(f.x6,null,"Strengthen user authentication.")),n.createElement("li",null,n.createElement(bs,null),n.createElement(f.x6,null,"Protect against unauthorised access.")),n.createElement("li",null,n.createElement(bs,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")))))),$a(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(Ea,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}rm.propTypes={context:i().object,t:i().func};const om=N((0,f.CI)("common")(rm));class lm extends se{constructor(e,t={}){super(ae.validate(lm.ENTITY_NAME,e,lm.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 cm=lm;class mm extends se{constructor(e,t={}){super(ae.validate(mm.ENTITY_NAME,e,mm.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 dm=mm;class um extends se{constructor(e,t={}){super(ae.validate(um.ENTITY_NAME,e,um.getSchema()),t),this._props.action&&(this._action=new cm(this._props.action,{clone:!1})),delete this._props.action,this._props.ui_action&&(this._ui_action=new dm(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:[um.FOREIGN_MODEL_ACTION,um.FOREIGN_MODEL_UI_ACTION]},foreign_id:{type:"string",format:"uuid"},control_function:{type:"string",enum:[K,V,G]},action:cm.getSchema(),ui_action:dm.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(um.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,um.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 pm=um;class hm{static error(e){console.error(e);try{e instanceof Error&&"function"==typeof e.toJSON&&console.log(`Error: ${e.message}\nError structure: ${JSON.stringify(hm.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=hm.serializeError(e.cause)),e instanceof Z&&Array.isArray(e.errors)&&(n.errors=e.errors.map(e=>hm.serializeError(e))),n}}const gm=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.`;hm.error(new Error(a,{cause:t}))}}},bm=class extends gm{get entityClass(){return pm}constructor(e=[],t={}){super(e,t)}static getSchema(){return{type:"array",items:pm.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 vm extends n.Component{constructor(e){super(e),this.state=this.defaultState;const t=e.context.getApiClientOptions();this.rbacApiService=new ym(t)}get defaultState(){return{processing:!1,rbacs:null,rbacsUpdated:new bm([]),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 pm(e)));const n=new bm([]);this.setState({rbacs:a,rbacsUpdated:n})}finally{this.setProcessing(!1)}}render(){return n.createElement(Em.Provider,{value:this.state},this.props.children)}}vm.propTypes={context:i().any,children:i().any};const wm=N(vm);function km(e){return class extends n.Component{render(){return n.createElement(Em.Consumer,null,t=>n.createElement(e,fm({adminRbacContext:t},this.props)))}}}class xm 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"))))}}xm.propTypes={context:i().object,adminRbacContext:i().object,actionFeedbackContext:i().object,t:i().func};const Sm=km(m((0,f.CI)("common")(xm)));class Cm 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 Tm 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(cn,{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(cn,{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.")))))}}Tm.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 Am=(0,f.CI)("common")(Tm);class Im extends Xt{constructor(e){super(e,Im.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 ta({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 ta(t)}async update(e,t){if(!e)throw new TypeError("Role update failed, role id is required.");if(!wn(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 ta(a)}async delete(e){if(!wn(e))throw new TypeError("Role deletion failed, roleId is not a valid uuid.");const t=await this.apiClient.delete(e);return new ta(t)}}var Rm;function Pm(){return Pm=Object.assign?Object.assign.bind():function(e){for(var t=1;tthis.roleEntity.validate(e));verifyDataHealth=(0,Fo.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(dn,{disabled:this.hasAllInputDisabled(),onClick:this.handleClose}),n.createElement(ii,{disabled:this.hasAllInputDisabled(),processing:this.state.processing,value:this.translate("Save")}))))}}zm.propTypes={onClose:i().func,onSubmit:i().func.isRequired,t:i().func};const Km=(0,f.CI)("common")(zm);function Vm(){return Vm=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},onClose:()=>{}});class Bm 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(Gm.Provider,{value:this.state},n.createElement("div",{className:"dropdown",ref:this.dropdownRef},this.props.children))}}function Wm(e){return class extends n.Component{render(){return n.createElement(Gm.Consumer,null,t=>n.createElement(e,Vm({dropdownContext:t},this.props)))}}}Bm.propTypes={children:i().any};class Hm extends n.Component{render(){return n.createElement(Bm,null,this.props.children)}}Hm.propTypes={children:i().any.isRequired};const $m=Hm;class Ym 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)}}Ym.defaultProps={disabled:!1,direction:"right",className:"button-dropdown"},Ym.propTypes={className:i().string,disabled:i().bool,direction:i().string,dropdownContext:i().any,children:i().any};const Zm=Wm(Ym);class Jm 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)}}Jm.defaultProps={direction:"right"},Jm.propTypes={direction:i().string,className:i().string,dropdownContext:i().any,children:i().any};const Xm=Wm(Jm);class Qm 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))))}}Qm.defaultProps={keepOpenOnClick:!1},Qm.propTypes={separator:i().bool,keepOpenOnClick:i().bool,dropdownContext:i().any,children:i().any};const ed=Wm(Qm);class td 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(dn,{disabled:this.hasAllInputDisabled(),onClick:this.handleClose}),n.createElement(ii,{disabled:this.hasAllInputDisabled(),processing:this.state.processing,value:this.translate("Delete"),warning:!0}))))}}td.propTypes={onClose:i().func,onSubmit:i().func,role:i().instanceOf(ge).isRequired,t:i().func};const ad=(0,f.CI)("common")(td);class nd 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,Fo.A)(e=>this.roleEntity.validate(e));verifyDataHealth=(0,Fo.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(dn,{disabled:this.hasAllInputDisabled(),onClick:this.handleClose}),n.createElement(ii,{disabled:this.hasAllInputDisabled(),processing:this.state.processing,value:this.translate("Save")}))))}}nd.propTypes={onClose:i().func,onSubmit:i().func.isRequired,role:i().instanceOf(ge).isRequired,t:i().func};const sd=(0,f.CI)("common")(nd);class id 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(dn,{disabled:this.hasAllInputDisabled(),onClick:this.handleClose}),n.createElement(ii,{disabled:this.hasAllInputDisabled(),processing:this.state.processing,value:this.translate("Ok")}))))}}id.propTypes={onClose:i().func,role:i().instanceOf(ge).isRequired,usersCount:i().number.isRequired,t:i().func};const rd=(0,f.CI)("common")(id);class od 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 bm(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 pm(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(Km,{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(rd,{role:t,usersCount:a.length}):this.props.dialogContext.open(ad,{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(sd,{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(Dm,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($m,null,n.createElement(Zm,{className:"more button-action-icon link no-border"},n.createElement(Um,null)),n.createElement(Xm,{className:"menu-action-contextual",direction:"left"},n.createElement(ed,null,n.createElement("button",{id:"rename_role_action",type:"button",className:"no-border",onClick:t=>this.handleRenameRoleClick(t,e)},n.createElement(qm,null),n.createElement("span",null,n.createElement(f.x6,null,"Rename")))),n.createElement(ed,null,n.createElement("button",{id:"delete_role_action",type:"button",className:"no-border",onClick:t=>this.handleDeleteRoleClick(t,e)},n.createElement(Ml,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(_m,{label:this.props.t("Group management"),level:1,rolesCount:a},n.createElement(Am,{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(_m,{label:this.props.t("Account recovery request"),level:1,rolesCount:a},n.createElement(Am,{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(Am,{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(Am,{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(_m,{label:this.props.t("Resources"),level:1,rolesCount:a},(this.canIUseImport||this.canIUseExport)&&n.createElement(_m,{label:this.props.t("Import/Export"),level:2,rolesCount:a},this.canIUseImport&&n.createElement(Am,{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(Am,{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(_m,{label:this.props.t("Password"),level:2,rolesCount:a},this.canIUsePreviewPassword&&n.createElement(Am,{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(Am,{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(_m,{label:this.props.t("Metadata"),level:2,rolesCount:a},n.createElement(Am,{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(Am,{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(_m,{label:this.props.t("Organization"),level:2,rolesCount:a},this.canIUseFolders&&n.createElement(Am,{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(Am,{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(_m,{label:this.props.t("Sharing"),level:2,rolesCount:a},n.createElement(Am,{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(Am,{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(_m,{label:this.props.t("Users"),level:1,rolesCount:a},n.createElement(Am,{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(_m,{label:this.props.t("User settings"),level:1,rolesCount:a},this.canIUseMobile&&n.createElement(Am,{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(Am,{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(Sm,null),$a(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(ds,null),n.createElement("span",null,n.createElement(f.x6,null,"Read RBAC doc")))),document.getElementById("administration-help-panel")))}}od.defaultProps={RoleApiService:Im,RbacApiService:ym,UserApiService:xn},od.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 ld=N(km(Ne(h(m((0,f.CI)("common")(od)))))),cd=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}},md=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 dd(){return dd=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 pd extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.hasDataBeenValidated=!1}get defaultState(){return{settings:new md,errors:{},currentSettings:new md,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 md(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(ud.Provider,{value:this.state},this.props.children)}}function hd(e){return class extends n.Component{render(){return n.createElement(ud.Consumer,null,t=>n.createElement(e,dd({adminPasswordPoliciesContext:t},this.props)))}}}pd.propTypes={context:i().any,children:i().any,t:i().any,actionFeedbackContext:i().object},N((0,f.CI)("common")(pd));class gd 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 cd(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"))))}}gd.propTypes={adminPasswordPoliciesContext:i().object,passwordPoliciesContext:i().object,actionFeedbackContext:i().object,t:i().func};const bd=hd(Rr(m((0,f.CI)("common")(gd)))),yd={COLOR_1:fd("#BA2809"),COLOR_2:fd("#FFA724"),COLOR_3:fd("#0EAA00")};function fd(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 Ed 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=pr.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=yd.COLOR_2,a=yd.COLOR_3):(t=yd.COLOR_1,a=yd.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})))}}Ed.defaultProps={entropy:null},Ed.propTypes={entropy:i().number,error:i().bool};const vd=(0,f.CI)("common")(Ed);class wd 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(vd,{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(cn,{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(bd,null),$a(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(Vr,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation"))))),document.getElementById("administration-help-panel")))}}wd.propTypes={context:i().object,administrationWorkspaceContext:i().object,adminPasswordPoliciesContext:i().object,t:i().func};const kd=N(Ne(hd((0,f.CI)("common")(wd))));class xd 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(pa,{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(bs,null),n.createElement(f.x6,null,"Reduce the risk of weak passwords.")),n.createElement("li",null,n.createElement(bs,null),n.createElement(f.x6,null,"Enforce complexity requirements.")),n.createElement("li",null,n.createElement(bs,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")))))),$a(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(Vr,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation"))))),document.getElementById("administration-help-panel")))}}xd.propTypes={context:i().object,t:i().func};const Sd=N((0,f.CI)("common")(xd));class Cd extends se{constructor(e,t={}){super(ae.validate(Cd.ENTITY_NAME,e,Cd.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 Cd(t)}}const _d=Cd;class Nd{constructor(e={}){this.external_dictionary_check=e?.external_dictionary_check,this.entropy_minimum=e?.entropy_minimum}static getSchema(){const e=_d.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 Td=Nd;function Ad(){return Ad=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},setSettings:()=>{},findSettings:()=>{},isProcessing:()=>{},validateData:()=>{},save:()=>{},getErrors:()=>{},hasSettingsChanges:()=>{}});class Rd extends n.Component{constructor(e){super(e),this.state=this.defaultState}get defaultState(){return{processing:!1,errors:null,hasBeenValidated:!1,isDataModified:!1,settings:new Td,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=Td.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=Td.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=Td.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(Id.Provider,{value:this.state},this.props.children)}}function Pd(e){return class extends n.Component{render(){return n.createElement(Id.Consumer,null,t=>n.createElement(e,Ad({adminUserPassphrasePoliciesContext:t},this.props)))}}}Rd.propTypes={context:i().any,children:i().any,t:i().any},N((0,f.CI)("common")(Rd));class Dd 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"))))}}Dd.propTypes={adminUserPassphrasePoliciesContext:i().object,actionFeedbackContext:i().object,dialogContext:i().any,t:i().func};const Od=Pd(m(h((0,f.CI)("common")(Dd))));class Md 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)))))}}Md.propTypes={value:i().number.isRequired,id:i().string.isRequired,onChange:i().func,disabled:i().bool};const Ud=(0,f.CI)("common")(Md);class Fd 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(Od,null),$a(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(Vr,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}Fd.propTypes={context:i().object,administrationWorkspaceContext:i().object,adminUserPassphrasePoliciesContext:i().object,t:i().func};const jd=N(Ne(Pd((0,f.CI)("common")(Fd))));class Ld 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(pa,{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(bs,null),n.createElement(f.x6,null,"Mitigate risks associated with weak passphrases.")),n.createElement("li",null,n.createElement(bs,null),n.createElement(f.x6,null,"Customise minimum length and complexity.")),n.createElement("li",null,n.createElement(bs,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")))))),$a(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(Vr,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation"))))),document.getElementById("administration-help-panel")))}}Ld.propTypes={context:i().object,t:i().func};const qd=N((0,f.CI)("common")(Ld));class zd extends se{constructor(e,t={}){super(ae.validate(zd.ENTITY_NAME,e,zd.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 zd(t)}}const Kd=zd;class Vd extends se{constructor(e,t={}){super(ae.validate(Vd.ENTITY_NAME,e,Vd.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 Vd(t)}}const Gd=Vd;class Bd{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?Gd.getSchema():Kd.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 Bd(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 Bd(a)}validate(e=!1){const t=new X,a=Bd.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 Wd=Bd;function Hd(){return Hd=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 Yd 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 Wd,featureToggleEnabled:!1,settings:new Wd,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=Wd.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,Hd({adminPasswordExpiryContext:t},this.props)))}}}Yd.propTypes={context:i().any,children:i().any,t:i().any},N((0,f.CI)("common")(Yd));class Jd 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"))))}}Jd.propTypes={adminPasswordExpiryContext:i().object,actionFeedbackContext:i().object,dialogContext:i().any,t:i().func};const Xd=m(Zd(h((0,f.CI)("common")(Jd))));class Qd 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.")))))))}}Qd.propTypes={context:i().object,adminPasswordExpiryContext:i().object,actionFeedbackContext:i().object,dialogContext:i().object,t:i().func};const eu=N(Zd(m(h((0,f.CI)("common")(Qd)))));class tu 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(eu,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(Xd,null),$a(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(Vr,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}tu.propTypes={context:i().object,administrationWorkspaceContext:i().object,adminPasswordExpiryContext:i().object,t:i().func};const au=N(Ne(Zd((0,f.CI)("common")(tu))));class nu 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)))))}}nu.propTypes={errorCode:i().number.isRequired,t:i().func};const su=(0,f.CI)("common")(nu),iu=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 ru extends se{constructor(e,t={}){super(ae.validate(ru.ENTITY_NAME,e,ru.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 ou=ru;class lu extends se{constructor(e,t={}){super(ae.validate(lu.ENTITY_NAME,e,lu.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 cu=lu;class mu extends se{constructor(e,t={}){super(ae.validate(mu.ENTITY_NAME,e,mu.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 du=mu;class uu extends se{constructor(e,t={}){super(ae.validate(uu.ENTITY_NAME,e,uu.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 pu=uu;class hu extends se{constructor(e,t={}){super(ae.validate(hu.ENTITY_NAME,e,hu.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 gu=hu;class bu extends se{constructor(e,t={}){super(ae.validate(bu.ENTITY_NAME,e,bu.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 yu=bu;class fu extends se{constructor(e,t={}){super(ae.validate(fu.ENTITY_NAME,e,fu.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 Eu=fu;class vu extends se{constructor(e,t={}){super(ae.validate(vu.ENTITY_NAME,e,vu.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 wu=vu;class ku extends se{constructor(e,t={}){super(ae.validate(ku.ENTITY_NAME,e,ku.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 xu=ku;class Su extends se{constructor(e,t={}){super(ae.validate(Su.ENTITY_NAME,e,Su.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 Cu=Su;class _u extends se{constructor(e,t={}){super(ae.validate(_u.ENTITY_NAME,e,_u.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=_u;class Tu extends se{constructor(e,t={}){super(ae.validate(Tu.ENTITY_NAME,e,Tu.getSchema()),t),this._props.ssl&&(this._ssl=new ou(this._props.ssl,{clone:!1}),delete this._props.ssl),this._props.database&&(this._database=new cu(this._props.database,{clone:!1}),delete this._props.database),this._props.application&&(this._application=new du(this._props.application,{clone:!1}),delete this._props.application),this._props.gpg&&(this._gpg=new pu(this._props.gpg,{clone:!1}),delete this._props.gpg),this._props.environment&&(this._environment=new gu(this._props.environment,{clone:!1}),delete this._props.environment),this._props.configFile&&(this._configFile=new yu(this._props.configFile,{clone:!1}),delete this._props.configFile),this._props.core&&(this._core=new Eu(this._props.core,{clone:!1}),delete this._props.core),this._props.smtpSettings&&(this._smtpSettings=new wu(this._props.smtpSettings,{clone:!1}),delete this._props.smtpSettings),this._props.directorySync&&(this._directorySync=new xu(this._props.directorySync,{clone:!1}),delete this._props.directorySync),this._props.sso&&(this._sso=new Cu(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:cu.getSchema(),ssl:ou.getSchema(),application:du.getSchema(),gpg:pu.getSchema(),environment:gu.getSchema(),configFile:yu.getSchema(),core:Eu.getSchema(),smtpSettings:wu.getSchema(),directorySync:xu.getSchema(),sso:Cu.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 Au=Tu;function Iu(){return Iu=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},isProcessing:()=>{},loadHealthcheckData:()=>{},clearContext:()=>{},isHealthcheckEndpointEnabled:()=>{}});class Pu extends n.Component{constructor(e){super(e),this.state=this.defaultState;const t=e.context.getApiClientOptions();this.healthcheckService=new iu(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 Au(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(Ru.Provider,{value:this.state},this.props.children)}}Pu.propTypes={context:i().any,actionFeedbackContext:i().any,children:i().any};const Du=N(m(Pu));function Ou(e){return class extends n.Component{render(){return n.createElement(Ru.Consumer,null,t=>n.createElement(e,Iu({adminHealthcheckContext:t},this.props)))}}}var Mu,Uu,Fu;function ju(){return ju=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(Gu,null),n.createElement(f.x6,null,"Some default content is present")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,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(Gu,null),n.createElement(f.x6,null,"Cache is working")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,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(Gu,null),n.createElement(f.x6,null,"Unique value set for security.salt")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,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(Gu,null),n.createElement(f.x6,null,"The application config file is present")):n.createElement("span",{className:"healthcheck-warning"},n.createElement(Qu,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(Gu,null),n.createElement(f.x6,null,"The passbolt config file is present")):n.createElement("span",{className:"healthcheck-warning"},n.createElement(Qu,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(Gu,null),n.createElement(f.x6,null,"PCRE compiled with unicode support")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,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(Gu,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(Hu,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(Gu,null),n.createElement(f.x6,null,"The logs directory and its content are writable")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,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(Gu,null),n.createElement(f.x6,null,"The environment variable GNUPGHOME is set to ",t)):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,null),n.createElement(f.x6,null,"The environment variable GNUPGHOME is set to ",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(Gu,null),n.createElement(f.x6,null,"The directory ",t," containing the keyring is writable by the webserver user")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,null),n.createElement(f.x6,null,"The directory ",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(Gu,null),n.createElement(f.x6,null,"The server key fingerprint matches the one defined in ",t)):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,null),n.createElement(f.x6,null,"The server key fingerprint doesn't matches the one defined in ",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(Gu,null),n.createElement(f.x6,null,"The server public key defined in the ",t," (or environment variables) is in the keyring")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,null),n.createElement(f.x6,null,"The server public key defined in the ",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(Gu,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(Hu,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(Zu,null),n.createElement(f.x6,null,"The Self Registration plugin is enabled")):n.createElement("span",{className:"healthcheck-info"},n.createElement(Zu,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"}))),b=()=>{const t=e.application.configPath.toString();return!0===e.application.registrationClosed.isRegistrationPublicRemovedFromPassbolt?n.createElement("span",{className:"healthcheck-success"},n.createElement(Gu,null),n.createElement(f.x6,null,"The deprecated self registration public settings was not found in ",t)):n.createElement("span",{className:"healthcheck-warning"},n.createElement(Qu,null),n.createElement(f.x6,null,"The deprecated self registration public settings was found in ",t),n.createElement(Mt,{message:this.props.t("You may remove the passbolt.registration.public setting")},n.createElement(jt,{className:"baseline svg-icon"})))},y=()=>!0===e.application.hostAvailabilityCheckEnabled?n.createElement("span",{className:"healthcheck-success"},n.createElement(Gu,null),n.createElement(f.x6,null,"Host availability will be checked")):n.createElement("span",{className:"healthcheck-warning"},n.createElement(Qu,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(Gu,null),n.createElement(f.x6,null,"The SMTP Settings source is: ",{smtpSettingsSource:t})):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,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(Gu,null),n.createElement(f.x6,null,"The SMTP Settings plugin endpoints are disabled")):n.createElement("span",{className:"healthcheck-warning"},n.createElement(Qu,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(Gu,null),n.createElement(f.x6,null,"The endpoints for updating the users directory configurations are disabled.")):n.createElement("span",{className:"healthcheck-warning"},n.createElement(Qu,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(Gu,null),n.createElement(f.x6,null,"SSL certification validation for SSO instance is enabled.")):n.createElement("span",{className:"healthcheck-warning"},n.createElement(Qu,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"}))),x=()=>!0===e.metadata.canDecryptMetadataPrivateKey?n.createElement("span",{className:"healthcheck-success"},n.createElement(Gu,null),n.createElement(f.x6,null,"The server is able to decrypt the metadata private key.")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,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"}))),S=()=>!0===e.metadata.canValidatePrivateMetadataKey?n.createElement("span",{className:"healthcheck-success"},n.createElement(Gu,null),n.createElement(f.x6,null,"The server metadata private key is valid.")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,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"}))),C=()=>!0===e.metadata.isServerHasAccessToMetadataKey?n.createElement("span",{className:"healthcheck-success"},n.createElement(Gu,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(Hu,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"}))),_=()=>!0===e.metadata.noActiveMetadataKey?n.createElement("span",{className:"healthcheck-success"},n.createElement(Gu,null),n.createElement(f.x6,null,"Active metadata key found or not required.")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,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(gn,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(Gu,null),n.createElement(f.x6,null,"PHP version ",{phpVersion:t}))}return n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,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(Gu,null),n.createElement(f.x6,null,"GD or Imagick extension is installed")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,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(Gu,null),n.createElement(f.x6,null,"Intl extension is installed")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,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(Gu,null),n.createElement(f.x6,null,"Mbstring extension is installed")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,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(Hu,null),n.createElement(f.x6,null,"Debug mode is on"),n.createElement(Mt,{message:n.createElement(f.x6,null,"Set debug = false; in ",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(Gu,null),n.createElement(f.x6,null,"Full base url is set to ",t))}{const t=e.application.configPath.toString();return n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,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 ",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(Gu,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(Hu,null),n.createElement(f.x6,null,"App.fullBaseUrl does not validate"),n.createElement(Mt,{message:n.createElement(f.x6,null,"Edit App.fullBaseUrl in ",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(Gu,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(Hu,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 ",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(Gu,null),n.createElement(f.x6,null,"SSL peer certificate validates")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,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(Gu,null),n.createElement(f.x6,null,"Hostname is matching SSL certificate")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,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(Gu,null),n.createElement(f.x6,null,"Not using a self-signed certificate")):n.createElement("span",{className:"healthcheck-warning"},n.createElement(Qu,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(Gu,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(Hu,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 ",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(Gu,null),n.createElement(f.x6,{count:t},{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(Gu,null),n.createElement(f.x6,null,"PHP GPG Module is installed and loaded")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,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(Gu,null),n.createElement(f.x6,null,"The public key file is defined in ",t," and readable.")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,null),n.createElement(f.x6,null,"The public key file is not defined in ",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"," ",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(Gu,null),n.createElement(f.x6,null,"The private key file is defined in ",t," and readable.")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,null),n.createElement(f.x6,null,"The private key file is not defined in ",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"," ",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(Gu,null),n.createElement(f.x6,null,"The public key can be used to encrypt a message")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,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(Gu,null),n.createElement(f.x6,null,"The public key can be used to sign a message")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,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(Gu,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(Hu,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(Gu,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(Hu,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(Gu,null),n.createElement(f.x6,null,"The public key can be used to verify a signature")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,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(Gu,null),n.createElement(f.x6,null,"The server public key format is Gopengpg compatible")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,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(Gu,null),n.createElement(f.x6,null,"The server private key format is Gopengpg compatible")):n.createElement("span",{className:"healthcheck-fail"},n.createElement(Hu,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(Gu,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(Hu,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(Hu,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(Gu,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(Hu,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 ",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(Gu,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(Hu,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 ",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(Gu,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(Hu,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 ",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(Gu,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(Hu,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 ",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(Zu,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(Zu,null),n.createElement(f.x6,null,"The Self Registration provider is: ",{selfRegistrationProvider:t}))}})()),n.createElement("div",null,b()),n.createElement("div",null,y()),n.createElement("div",null,(()=>{if(!0===e.application.jsProd)return n.createElement("span",{className:"healthcheck-success"},n.createElement(Gu,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(Qu,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 ",t)},n.createElement(jt,{className:"baseline svg-icon"})))}})()),n.createElement("div",null,!0===e.application.emailNotificationEnabled?n.createElement("span",{className:"healthcheck-success"},n.createElement(Gu,null),n.createElement(f.x6,null,"All email notifications will be sent")):n.createElement("span",{className:"healthcheck-warning"},n.createElement(Qu,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(Gu,null),n.createElement(f.x6,null,"The SMTP Settings plugin is enabled")):n.createElement("span",{className:"healthcheck-warning"},n.createElement(Qu,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(Gu,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(Hu,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(Gu,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,x()),n.createElement("div",null,S()),n.createElement("div",null,C()),n.createElement("div",null,_()))))))():n.createElement("div",null,n.createElement(f.x6,null,"The health check API endpoint has been disabled in the server configuration."))),$a(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(Gu,null)," ",n.createElement(f.x6,null,"Everything is running as expected.")),n.createElement("div",{className:"healthcheck-warning"},n.createElement(Qu,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(Hu,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(Zu,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(ds,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation"))))),document.getElementById("administration-help-panel"))))}}ep.propTypes={context:i().object,adminHealthcheckContext:i().any,children:i().any,administrationWorkspaceContext:i().object,t:i().func};const tp=N(Ne(Ou((0,f.CI)("common")(ep)))),ap="v4",np="v5";class sp 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:[ap,np]},default_folder_type:{type:"string",enum:[ap,np]},default_tag_type:{type:"string",enum:[ap,np]},default_comment_type:{type:"string",enum:[ap,np]},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 sp({default_resource_types:ap,default_folder_type:ap,default_tag_type:ap,default_comment_type:ap,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 sp({default_resource_types:ap,default_folder_type:ap,default_tag_type:ap,default_comment_type:ap,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 sp({default_resource_types:np,default_folder_type:ap,default_tag_type:ap,default_comment_type:ap,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===np}get isDefaultResourceTypeV4(){return this._props.default_resource_types===ap}get allowV5V4Downgrade(){return this._props.allow_v5_v4_downgrade}get allowV4V5Upgrade(){return this._props.allow_v4_v5_upgrade}}const ip=sp,rp="keepass-icon-set",op="passbolt-icon-set",lp="password-string",cp="password-and-description",mp="password-description-totp",dp="totp",up="v5-default",pp="v5-password-string",hp="v5-default-with-totp",gp="v5-totp-standalone",bp="v5-custom-fields",yp="v5-note",fp="v5-pin-code",Ep={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}},vp={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}}}},wp={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"}}}}}},kp={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:wp.secret.properties.totp}}},xp={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:[rp,op]},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}}}}}}},Sp={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:[rp,op]},value:{type:"number",minimum:0,nullable:!0},background_color:{type:"string",nullable:!0}}},custom_fields:xp.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:xp.secret.properties.custom_fields}}},Cp={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:[rp,op]},value:{type:"number",minimum:0,nullable:!0},background_color:{type:"string",nullable:!0}}}}},secret:{type:"string",maxLength:4096}},_p={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:[rp,op]},value:{type:"number",minimum:0,nullable:!0},background_color:{type:"string",nullable:!0}}},custom_fields:xp.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:wp.secret.properties.totp,custom_fields:xp.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:[rp,op]},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"}}}}}},Tp={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:[rp,op]},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}}}},Ap={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:[rp,op]},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}}}},Ip={[lp]:pp,[cp]:up,[mp]:hp,[dp]:gp},Rp=new class{get SCHEMAS(){return{[lp]:Ep,[cp]:vp,[mp]:kp,[dp]:wp,[up]:Sp,[pp]:Cp,[hp]:_p,[gp]:Np,[bp]:xp,[yp]:Tp,[fp]:Ap}}},Pp=[lp,cp,mp,up,hp,pp],Dp=[mp,dp,hp,gp],Op=[dp,gp],Mp=[lp,pp],Up=[cp,mp,up,hp,yp,fp],Fp=[lp,up,hp,pp,gp,bp,yp,fp],jp=[up,pp,hp,gp,bp,yp],Lp=[up,hp,bp];class qp extends he{marshall(){if("string"!=typeof this._props.slug||!(this._props.slug in Rp.SCHEMAS))return void delete this._props.definition;const e=Rp.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:[rp,op]},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=qp.getSchema().properties.deleted;t?.nullable&&null===e||ae.validateProp("deleted",e,t),this._props.deleted=e}hasTotp(){return Dp.includes(this.slug)}hasPassword(){return Pp.includes(this.slug)}hasCustomFields(){return Lp.includes(this.slug)}hasPinCode(){return fp===this.slug}isStandalonePinCode(){return this.hasPinCode()}isStandaloneTotp(){return Op.includes(this.slug)}isPasswordString(){return Mp.includes(this.slug)}hasSecretDescription(){return Up.includes(this.slug)}hasMetadataDescription(){return Fp.includes(this.slug)}hasMetadataUris(){return jp.includes(this.slug)}get version(){return this.slug.startsWith("v5")?np:ap}isV5(){return this.version===np}isV4(){return this.version===ap}isDeleted(){return void 0!==this._props.deleted&&null!==this._props.deleted}}const zp=qp,Kp=[lp,cp,mp,dp,up,hp,pp,gp,bp,yp,fp],Vp=class extends gm{get entityClass(){return zp}constructor(e=[],t={}){super(e,t)}static getSchema(){return{type:"array",items:zp.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",Pp)}filterByTOTPResourceTypes(){this.filterByPropertyValueIn("slug",Dp)}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=ap){return this.items.some(t=>t.hasPassword()&&t.version===e)}hasSomeTotpResourceTypes(e=ap){return this.items.some(t=>t.hasTotp()&&t.version===e)}hasSomeCustomFieldsResourceTypes(e=ap){return this.items.some(t=>t.hasCustomFields()&&t.version===e)}hasSomeNoteResourceTypes(e=ap){return this.items.some(t=>t.hasSecretDescription()&&t.version===e)}hasSomePinCodeResourceTypes(e=ap){return this.items.some(t=>t.hasPinCode()&&t.version===e)}hasSomeMetadataDescriptionResourceTypes(e=ap){return this.items.some(t=>t.hasMetadataDescription()&&t.version===e)}hasSomeOfVersion(e=ap){return this.items.some(t=>t.version===e)}getResourceTypeMatchingResource(e,t=ap){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={}){Kp.includes(e?.slug)&&super.push(e,t,a)}},Gp=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 Bp extends he{static getSchema(){return{type:"object",required:[Bp.AVATAR_URL_SIZE_MEDIUM,Bp.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 Wp=Bp,Hp=class extends he{constructor(e={},t={}){super(e,t),this._props.url&&(this._url=new Wp(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:Wp.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 $p extends he{constructor(e={},t={}){super(e,t),this._props.avatar&&(this._avatar=new Hp(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:Hp.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($p.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 Yp=$p;class Zp extends he{constructor(e,t={}){super(e,t),this._props.profile&&(this._profile=new Yp(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 Gp(this._props.gpgkey,{...t,clone:!1}),delete this._props.gpgkey)}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"},role:ge.getSchema(),profile:Yp.getSchema(),gpgkey:Gp.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()),t):t}toJSON(){return this.toDto(Zp.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}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:Yp.ALL_CONTAIN_OPTIONS,role:!0,gpgkey:!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}}const Jp=Zp,Xp=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 Qp extends he{constructor(e,t={}){super(e,t),this._props.data&&"string"!=typeof this._props.data&&(this._data=new Xp(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 Xp?a.toDto():a,e?(this._creator&&e.creator&&(t.creator=this._creator.toDto(Jp.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(Jp.ALL_CONTAIN_OPTIONS)}cloneForSharing(e){const t={user_id:e,metadata_key_id:this.metadataKeyId,data:this.data};return new Qp(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 Xp(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 eh=Qp,th=class extends gm{get entityClass(){return eh}constructor(e=[],t={}){super(e,t)}static getSchema(){return{type:"array",items:eh.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)}},ah=class extends he{constructor(e,t={}){super(e,t),this._props.metadata_private_keys&&(this._metadata_private_keys=new th(this._props.metadata_private_keys,{...t,clone:!1}),delete this._props.metadata_private_keys,this.assertSameMetadataKeyId()),this._props.creator&&(this._creator=new Jp(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:th.getSchema(),creator:Jp.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(Jp.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(Jp.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}}},nh=class extends gm{get entityClass(){return ah}constructor(e=[],t={}){super(e,t)}static getSchema(){return{type:"array",items:ah.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)}},sh=["default_resource_types","allow_creation_of_v5_resources","allow_creation_of_v4_resources","allow_v4_v5_upgrade","allow_v5_v4_downgrade"],ih=class extends ip{toFormDto(){return sh.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 Vp))throw new TypeError("The parameter 'resourceTypes' is not a valid 'ResourceTypesCollection' type.");if(!(t instanceof nh))throw new TypeError("The parameter 'metadataKeysCollection' is not a valid 'MetadataKeysCollection' type.");const n=e.hasSomeOfVersion(ap),s=e.hasSomeOfVersion(np);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}},rh=class extends gm{get entityClass(){return eh}constructor(e=[],t={}){super(e,t)}static getSchema(){return{type:"array",items:eh.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 oh 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:rh.getSchema()}}}static get associations(){return{metadata_private_keys:rh}}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 oh({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 rh))throw new TypeError("The metadataPrivateKeysCollection is not of MetadataPrivateKeysCollection type");this._metadataPrivateKeys=e}static get ALL_CONTAIN_OPTIONS(){return{metadata_private_keys:!0}}}const lh=oh,ch=class{constructor(e){this.port=e}async findKeysSettings(){const e=await this.port.request("passbolt.metadata.find-metadata-keys-settings");return new lh(e)}async findTypesSettings(){const e=await this.port.request("passbolt.metadata.find-metadata-types-settings");return new ip(e)}async saveTypesSettings(e){if(!(e instanceof ip))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 ip(t)}async saveKeysSettings(e){if(!(e instanceof lh))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 lh(t)}};class mh 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"))))}}mh.propTypes={isProcessing:i().bool,onSaveRequested:i().func,t:i().func};const dh=(0,f.CI)("common")(mh);function uh(){return uh=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},resourceTypes:null,updateLocalStorage:()=>{}});class hh 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 Vp(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(ph.Provider,{value:this.state},this.props.children)}}function gh(e){return class extends n.Component{render(){return n.createElement(ph.Consumer,null,t=>n.createElement(e,uh({resourceTypesLocalStorageContext:t,resourceTypes:t.get()},this.props)))}}}hh.propTypes={context:i().any,children:i().any},N(hh);class bh extends se{constructor(e,t={}){const a=bh.sanitizeDto(e);super(ae.validate(bh.ENTITY_NAME,a,bh.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,Fo.A)((e,t,a)=>this.formSettings?.verifyHealth(t,a));hasSettingsChanges=(0,Fo.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 ih(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(dh,{onSaveRequested:this.save,isProcessing:this.state.isProcessing}),$a(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(ds,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}wh.propTypes={context:i().object,actionFeedbackContext:i().object,dialogContext:i().object,createPortal:i().func,metadataSettingsServiceWorkerService:i().object,metadataKeysServiceWorkerService:i().object,resourceTypes:i().instanceOf(Vp),t:i().func};const kh=N(m(h(gh((0,f.CI)("common")(wh)))));var xh;function Sh(){return Sh=Object.assign?Object.assign.bind():function(e){for(var t=1;te.id).sort().sort((e,t)=>{if(e===t)throw new ce(0,Ih.RULE_UNIQUE_ID,`Gpgkey fingerprint ${e} already exists.`)}),this._props.forEach(e=>{this._items.push(new yh(e,{clone:!1}))}),this._props=null}static getSchema(){return{type:"array",items:yh.getSchema()}}static get ENTITY_NAME(){return"externalGpgKey"}static get RULE_UNIQUE_ID(){return"fingerprint"}}const Rh=Ih,Ph=class{constructor(e){this.port=e}async keyInfo(e){const t=await this.port.request("passbolt.keyring.get-key-info",e);return new yh(t)}async keysInfo(e=[]){const t=[];for(const a of e){const e=await this.keyInfo(a);t.push(e)}return new Rh(t)}},Dh=class extends lh{constructor(e,t={}){super(e,t),this._props.generated_metadata_key&&(this._generated_metadata_key=new Eh(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:{...lh.getSchema().properties,generated_metadata_key:Eh.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 Eh))throw new TypeError("The parameter `generatedMetadataKey` should be of type ExternalGpgKeyPairEntity.");this._generated_metadata_key=e}};class Oh 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(gn,null)))}}Oh.propTypes={isProcessing:i().bool,isDisabled:i().bool,onSaveRequested:i().func,t:i().func};const Mh=(0,f.CI)("common")(Oh);class Uh 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(Ah,{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},yi(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"))))}}Uh.propTypes={context:i().object,metadataKeyInfo:i().object,onConfirm:i().func,onClose:i().func,t:i().func};const Fh=N((0,f.CI)("common")(Uh));class jh extends n.Component{originalSettings=null;formSettings=null;constructor(e){super(e),this.metadataSettingsServiceWorkerService=e.metadataSettingsServiceWorkerService??new ch(e.context.port),this.metadataKeysServiceWorkerService=e.metadataKeysServiceWorkerService??new vh(e.context.port),this.gpgServiceWorkerService=e.gpgServiceWorkerService??new Ph(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 Dh(e.toDto(),{validate:!1}),this.formSettings=new Dh(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 nh(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,Fo.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 ah({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(Fh,{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,Fo.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 lh(this.formSettings.toDto()),t=await this.metadataSettingsServiceWorkerService.saveKeysSettings(e);this.originalSettings=new Dh({...this.originalSettings.toDto(),...t.toDto()}),this.formSettings=new Dh({...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(Ah,{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},yi(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(Ah,{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},yi(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:yi(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(Mh,{onSaveRequested:this.save,isProcessing:this.state.isProcessing,isDisabled:this.hasAllInputDisabled()}),$a(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(ds,null),n.createElement("span",null,n.createElement(f.x6,null,"Read the documentation")))),document.getElementById("administration-help-panel")))}}jh.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 Lh=N(h(m((0,f.CI)("common")(jh)))),qh=class extends he{static getSchema(){return{type:"object",required:["migrate_resources_to_v5","migrate_folders_to_v5","migrate_tags_to_v5","migrate_comments_to_v5","migrate_personal_content"],properties:{migrate_resources_to_v5:{type:"boolean"},migrate_folders_to_v5:{type:"boolean"},migrate_tags_to_v5:{type:"boolean"},migrate_comments_to_v5:{type:"boolean"},migrate_personal_content:{type:"boolean"}}}}marshall(){this._props.migrate_resources_to_v5=this._props.migrate_resources_to_v5??!0,this._props.migrate_folders_to_v5=this._props.migrate_folders_to_v5??!1,this._props.migrate_tags_to_v5=this._props.migrate_tags_to_v5??!1,this._props.migrate_comments_to_v5=this._props.migrate_comments_to_v5??!1,this._props.migrate_personal_content=this._props.migrate_personal_content??!1}get migrateResources(){return!this._props.migrate_resources_to_v5}get migrateFolders(){return!this._props.migrate_folders_to_v5}get migrateTags(){return!this._props.migrate_tags_to_v5}get migrateComments(){return!this._props.migrate_comments_to_v5}get sharedContentOnly(){return!this._props.migrate_personal_content}},zh=class extends qh{verifyHealth(e,t,a){if(void 0===e)return null;if(void 0===t)return null;if(void 0===a)return null;if(!(e instanceof Vp))throw new TypeError("The parameter 'resourceTypesCollection' is not a valid 'ResourceTypesCollection' type.");if(!(t instanceof ip))throw new TypeError("The parameter 'metadataTypesSettings' is not a valid 'MetadataTypesSettingsEntity' type.");if(!(a instanceof nh))throw new TypeError("The parameter 'metadataKeysCollection' is not a valid 'MetadataKeysCollection' type.");let n=this._verifyGlobalHealth(a);return n=this._verifyMigrateResourcesToV5Health(n,e,t,a),n=this._verifyMigrateFoldersToV5Health(n,t,a),n=this._verifyMigrateTagsToV5Health(n,t,a),n=this._verifyMigrateCommentsToV5Health(n,t,a),n}_verifyGlobalHealth(e){if(e.items.filter(e=>!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(np);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===ap).every(e=>t.hasOneWithSlug(Ip[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}},Kh=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 Qt(t)}async migrate(e,t){await this.port.request("passbolt.metadata.migrate-resources-metadata",e,t)}};class Vh 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"))))}}Vh.propTypes={cancel:i().func,confirm:i().func,onClose:i().func,t:i().func};const Gh=(0,f.CI)("common")(Vh);class Bh 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 zh({}),this.metadataSettingsServiceWorkerService=e.metadataSettingsServiceWorkerService??new ch(e.context.port),this.metadataKeysServiceWorkerService=e.metadataKeysServiceWorkerService??new vh(e.context.port),this.metadataMigrateContentServiceWorkerService=e.metadataMigrateContentServiceWorkerService??new Kh(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,Fo.A)(e=>this.formSettings?.validate());verifyDataHealth=(0,Fo.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(Gh,{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(ni,{name:"warning"}),this.state.isReady&&!this.hasPendingMigration&&n.createElement(ni,{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")))),$a(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")))}}Bh.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(Vp),t:i().func};const Wh=N(m(h(gh(h((0,f.CI)("common")(Bh)))))),Hh={passwordV4:[lp,cp],totpV4:[dp],passwordV5:[up,pp],totpV5:[gp],customFieldsV5:[bp],noteV5:[yp],pinCodeV5:[fp]},$h={passwordV4:[lp,cp,mp],totpV4:[dp,mp],passwordV5:[up,pp,hp],totpV5:[gp,hp],customFieldsV5:[bp],noteV5:[yp],pinCodeV5:[fp]};class Yh extends he{constructor(e,t){super(e,t),this._props.resource_types&&(this._resource_types=new Vp(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:Vp.getSchema()}}}static createFormResourcesTypesCollection(e){if(!(e instanceof Vp))throw new TypeError("The parameter 'resource_types' is not a valid 'ResourceTypesCollection' type.");const t=e.items.filter(e=>!e.isDeleted()),a=new Vp(t),n=this._areAllResourceTypesAvailable(Hh.passwordV4,a),s=this._areAllResourceTypesAvailable(Hh.passwordV5,a),i=this._areAllResourceTypesAvailable(Hh.totpV4,a),r=this._areAllResourceTypesAvailable(Hh.totpV5,a),o=this._areAllResourceTypesAvailable(Hh.customFieldsV5,a),l=this._areAllResourceTypesAvailable(Hh.noteV5,a),c=this._areAllResourceTypesAvailable(Hh.pinCodeV5,a),m=this._getResourcesCountForResourceTypeFamily($h.passwordV4,e),d=this._getResourcesCountForResourceTypeFamily($h.passwordV5,e),u=this._getResourcesCountForResourceTypeFamily($h.totpV4,e),p=this._getResourcesCountForResourceTypeFamily($h.totpV5,e),h=this._getResourcesCountForResourceTypeFamily($h.customFieldsV5,a),g=this._getResourcesCountForResourceTypeFamily($h.noteV5,e),b=this._getResourcesCountForResourceTypeFamily($h.pinCodeV5,e),y=e.hasSomeOfVersion("v4"),f=e.hasSomeOfVersion("v5");return new Yh({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:b,custom_fields_v5_count:h,has_v4_resource_types:y,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 ip))throw new TypeError("The parameter 'metadataTypesSettings' is not a valid 'MetadataTypesSettingsEntity' type.");if(!(t instanceof nh))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===bp||this._props.note_v5&&e.slug===yp||this._props.pin_code_v5&&e.slug===fp),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,Fo.A)((e,t,a)=>this.formSettings?.verifyHealth(t,a));hasSettingsChanges=(0,Fo.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=Zh.createFormResourcesTypesCollection(t),this.formSettings=new Zh(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(eg,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(sg,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(og,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(mg,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(pg,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(eg,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(sg,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")))),$a(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")))}}hg.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 gg=N(m(h((0,f.CI)("common")(hg))));class bg 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(pa,null)),this.props.description&&n.createElement("span",{className:"info",title:this.props.description},this.props.description)))}}bg.defaultProps={isBeta:!1,proTeasing:!1},bg.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 yg=bg;var fg;function Eg(){return Eg=Object.assign?Object.assign.bind():function(e){for(var t=1;tn.createElement(yg,{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}))))))}}Zb.propTypes={context:i().object,navigationContext:i().object,administrationEncryptedMetadataGettingStartedContext:i().object,metadataGettingStartedSettings:i().object,t:i().func};const Jb=N(ca(Ke((0,f.CI)("common")(Zb))));var Xb;function Qb(){return Qb=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 xy 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")))))}}xy.propTypes={shouldDisplayWarning:i().bool.isRequired};const Sy=xy;class Cy{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 _y(){return _y=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},getAllRoles:()=>{},refreshRoles:()=>{}});class Ty extends n.Component{constructor(e){super(e),this.state=this.defaultState(),this.runningLocalStorageUpdatePromise=null,this.roleServiceWorkerService=new Cy(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(Ny.Provider,{value:this.state},this.props.children)}}Ty.propTypes={context:i().any,children:i().any},Ty.displayName="RoleContextProvider",N(Ty);class Ay extends n.Component{originalSettings=null;formSettings=null;scimSettingsService=null;constructor(e){super(e),this.state=this.defaultState,this.bindCallbacks(),this.scimSettingsService=e.scimSettingsServiceWorkerService??new wy(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:ky(e,this.props.t,{withUsername:!0})}))}async findScimSettings(){this.setState({isProcessing:!0});try{const e=await this.scimSettingsService.findSettings();e&&(this.originalSettings=new vy(e,{validate:!1}),this.formSettings=new vy(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=vy.createFromDefault(this.adminUsers[0].id),this.setState({settings:this.formSettings.toDto()})}handleToggleEnabled(){this.state.enabled||(this.formSettings=vy.createFromDefault(this.adminUsers[0].id),this.setState({settings:this.formSettings.toDto()})),this.setState({enabled:!this.state.enabled})}hasSettingsChanges=(0,Fo.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=fy.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 vy(e,{validate:!1}):null,this.originalSettings=e?new vy(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,_y({roleContext:t,roles:t.getAllRoles()},this.props)))}}}((0,f.CI)("common")(Ay)))))));class Ry 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(pa,{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(bs,null),n.createElement(f.x6,null,"Efficiently manage user identities in the cloud.")),n.createElement("li",null,n.createElement(bs,null),n.createElement(f.x6,null,"Simplify onboarding and offboarding processes.")),n.createElement("li",null,n.createElement(bs,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")))))))}}Ry.propTypes={context:i().object,t:i().func};const Py=N((0,f.CI)("common")(Ry));class Dy 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 Dy({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 Oy=Dy;class My{constructor(e){this.port=e}async findSettings(){const e=await this.port.request("passbolt.secret-revisions.find-settings");return new Oy(e)}async saveSettings(e){if(!(e instanceof Oy))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 Oy(t)}async deleteSettings(){await this.port.request("passbolt.secret-revisions.delete-settings")}}class Uy extends n.Component{originalSettings=null;formSettings=null;constructor(e){super(e),this.secretRevisionsSettingsServiceWorkerService=new My(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 Oy(this.originalSettings.toDto(),{validate:!1});const e=this.formSettings.toDto();this.setState({settings:e,isFeatureEnabled:this.originalSettings.isFeatureEnabled,isProcessing:!1})}validateForm=(0,Fo.A)(e=>this.formSettings?.validate());hasSettingsChanges=(0,Fo.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=Oy.createFromDefault(),this.formSettings=new Oy(this.originalSettings.toDto(),{validate:!1})}async saveSettings(){const e=this.formSettings.toDto();this.originalSettings=new Oy(e,{validate:!1}),this.originalSettings=await this.secretRevisionsSettingsServiceWorkerService.saveSettings(new Oy(e)),this.formSettings=new Oy(this.originalSettings.toDto(),{validate:!1})}render(){const e=this.state.hasAlreadyBeenValidated?this.validateForm(this.state.settings):null,t=this.hasSettingsChanges(this.state.settings,this.state.isFeatureEnabled),a=e?.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.")),a&&n.createElement("div",{id:"maxRevisions-error",className:"error-message"},n.createElement(f.x6,null,"The history length must be between 1 and ",this.maxRevisionsLimitToDisplay,".")))))),t&&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")))))}}Uy.propTypes={context:i().object,dialogContext:i().object,actionFeedbackContext:i().object,t:i().func};const Fy=N(m(h((0,f.CI)("common")(Uy))));function jy(){return jy=Object.assign?Object.assign.bind():function(e){for(var t=1;t{},close:()=>{}});class qy 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(Ly.Provider,{value:this.state},this.props.children)}}function zy(e){return class extends n.Component{render(){return n.createElement(Ly.Consumer,null,t=>n.createElement(e,jy({announcementContext:t},this.props)))}}}function Ky(){return Ky=Object.assign?Object.assign.bind():function(e){for(var t=1;tn.createElement(t,Ky({key:e,onClose:()=>this.close(e)},a))),this.props.children)}}Vy.propTypes={announcementContext:i().any,children:i().any};const Gy=zy(Vy);class By 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(Gy,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(Ch,null)),n.createElement("span",{className:"title administration"},n.createElement(f.x6,null,"Organisation settings")))),n.createElement("div",{className:"sidebar-content-left"},n.createElement(ga,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(uy,{isUserAdmin:!0,isUserWorkspaceVisible:!0,currentWorkspace:my}),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(an,null)),n.createElement("div",{className:"main-page"},this.isHttpError403&&n.createElement(su,{errorCode:403}),this.isHttpError404&&n.createElement(su,{errorCode:404}),this.isHomePageSelected()&&n.createElement(Jb,null),this.isMfaSelected()&&n.createElement(Za,null),this.isMfaPolicySelected()&&(this.isCommunityEdition()?n.createElement(om,null):n.createElement(im,null)),this.isPasswordPoliciesSelected()&&(this.isCommunityEdition()?n.createElement(Sd,null):n.createElement(kd,null)),this.isUserDirectorySelected()&&(this.isCommunityEdition()?n.createElement(fs,null):n.createElement(ps,null)),this.isEmailNotificationsSelected()&&n.createElement(Is,null),this.isSubscriptionSelected()&&(this.isCommunityEdition()?n.createElement(Ci,null):n.createElement(xi,null)),this.isInternationalizationSelected()&&n.createElement(ji,null),this.isAccountRecoverySelected()&&(this.isCommunityEdition()?n.createElement(Hr,null):n.createElement(Br,null)),this.isSmtpSettingsSelected()&&n.createElement(ll,null),this.isSelfRegistrationSelected()&&n.createElement(Fl,null),this.isSsoSelected()&&(this.isCommunityEdition()?n.createElement($c,null):n.createElement(Wc,null)),this.isRbacSelected()&&n.createElement(ld,null),this.isUserPassphrasePoliciesSelected()&&(this.isCommunityEdition()?n.createElement(qd,null):n.createElement(jd,null)),this.isPasswordExpirySelected()&&n.createElement(au,null),this.isHealthcheckSelected()&&n.createElement(tp,null),this.isContentTypesEncryptedMetadataSelected()&&n.createElement(kh,null),this.isContentTypesMetadataKeySelected()&&n.createElement(Lh,null),this.isMigrateMetadataSelected()&&n.createElement(Wh,null),this.isAllowContentTypesSelected()&&n.createElement(gg,null),this.isGetStartedMetadataSelected()&&n.createElement(gy,null),this.isScimSelected()&&(this.isCommunityEdition()?n.createElement(Py,null):n.createElement(Iy,null)),this.isSecretHistorySelected()&&n.createElement(Fy,null))),n.createElement(S.Switch,null,n.createElement(S.Route,{exact:!0,path:["/app/administration","/app/administration/scim-teasing","/app/administration/secret-history"]}),n.createElement(S.Route,null,n.createElement("div",{className:"help-panel"},n.createElement("div",{className:"sidebar-help",id:"administration-help-panel"}),n.createElement(Nh,null)))))))))}}By.propTypes={context:i().any,administrationWorkspaceContext:i().object,navigationContext:i().any};const Wy=N(Ke(Ne(By)));class Hy 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"))))}}Hy.propTypes={context:i().any,t:i().func};const $y=N((0,S.withRouter)((0,f.CI)("common")(Hy)));class Yy 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($y)}render(){return n.createElement(n.Fragment,null)}}Yy.propTypes={context:i().any,dialogContext:i().any};const Zy=N(h(Yy));class Jy 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))}}Jy.propTypes={children:i().node,className:i().string,canClose:i().bool,onClose:i().func};const Xy=(0,f.CI)("common")(Jy);class Qy extends n.Component{render(){return n.createElement(Xy,{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},yi(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"))))}}Qy.propTypes={context:i().any,expiry:i().string,navigationContext:i().any,onClose:i().func,t:i().func};const ef=N(Ke(zy((0,f.CI)("common")(Qy))));class tf extends n.Component{render(){return n.createElement(Xy,{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"))))}}tf.propTypes={navigationContext:i().any,onClose:i().func,i18n:i().any};const af=Ke(zy((0,f.CI)("common")(tf)));class nf extends n.Component{render(){return n.createElement(Xy,{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"))))}}nf.propTypes={navigationContext:i().any,onClose:i().func,i18n:i().any};const sf=Ke(zy((0,f.CI)("common")(nf)));class rf 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(ef,{expiry:e.expiry})}catch(e){"PassboltSubscriptionError"===e.name?this.props.announcementContext.show(af):this.props.announcementContext.show(sf)}}hideSubscriptionAnnouncement(){const e=[ef,af,sf];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 cf extends Error{constructor(e,t={}){super(e),this.name="PassboltSubscriptionError",this.subscription=t}}const mf=cf,df=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 uf extends n.Component{constructor(e){super(e),this.state=this.defaultState,this.authLogoutService=new df(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 lf).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 bm});const t=this.getApiClientOptions(),a=new ym(t),n=(await a.findMe({ui_action:!0,action:!0})).body,s=new bm(n,!0);this.setState({rbacs:s})}async getSiteSettings(){const e=this.getApiClientOptions().setResourceName("settings"),t=new pt(e),a=await t.findAll(),n=new Sr(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 mf(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)}}uf.propTypes={children:i().any};const pf=uf;var hf=a(2635),gf=a(1347);class bf extends n.Component{constructor(e){super(e),this.state=this.defaultState}get defaultState(){return{ready:!1}}async componentDidMount(){await(0,hf.Yx)(f.r9).use(gf.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,hf.v2)(this.locale)}get isReady(){return this.state.ready}render(){return n.createElement(n.Fragment,null,this.isReady&&this.props.children)}}bf.propTypes={context:i().any,loadingPath:i().any,children:i().any};const yf=N(bf);class ff{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 lf).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 Ef extends n.Component{render(){const e=new ff;return n.createElement(pf,null,n.createElement(T.Consumer,null,t=>n.createElement(yf,{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(qy,null,n.createElement(y,null,n.createElement(k,null),n.createElement(Zy,null),t.loggedInUser&&"admin"===t.loggedInUser.role.name&&t.siteSettings.canIUse("ee")&&n.createElement(of,null),n.createElement(x.Kd,{basename:t.basename},n.createElement(ze,null,n.createElement(S.Switch,null,n.createElement(S.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(S.Route,{path:"/app/administration"},n.createElement(Ce,null,n.createElement(zo,null,n.createElement(Fe,null),n.createElement(Dn,null,n.createElement(wl,null,n.createElement(Oe,null),n.createElement(Ia,null,n.createElement(em,null,n.createElement(Cs,null,n.createElement(Di,null,n.createElement(wm,null,n.createElement(Du,null,n.createElement(la,{service:new na(t.getApiClientOptions())},n.createElement(Wy,null))))))))))))))))))))))))))}}const vf=Ef;var wf=a(5338);const kf=document.createElement("div");document.body.appendChild(kf),(0,wf.H)(kf).render(n.createElement(vf,null))}},s={};function i(e){var t=s[e];if(void 0!==t)return t.exports;if(void 0===n[e]){var a=new Error("Cannot find module '"+e+"'");throw a.code="MODULE_NOT_FOUND",a}var r=s[e]={exports:{}};return n[e].call(r.exports,r,r.exports,i),r.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(1939));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 81cefbf4c2..1ba8603949 100644 --- a/webroot/locales/cs-CZ/common.json +++ b/webroot/locales/cs-CZ/common.json @@ -1770,6 +1770,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.", @@ -1778,6 +1780,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.", @@ -2030,4 +2034,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 947f120b13..d55815d08f 100644 --- a/webroot/locales/de-DE/common.json +++ b/webroot/locales/de-DE/common.json @@ -1770,6 +1770,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.", @@ -1778,6 +1780,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.", @@ -1960,4 +1964,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 afcfabe82e..0e15203fa3 100644 --- a/webroot/locales/en-UK/common.json +++ b/webroot/locales/en-UK/common.json @@ -1840,6 +1840,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.", @@ -1848,6 +1850,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 1af821301b..3256184ea6 100644 --- a/webroot/locales/es-ES/common.json +++ b/webroot/locales/es-ES/common.json @@ -1770,6 +1770,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.", @@ -1778,6 +1780,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.", @@ -1960,4 +1964,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 1341d44faf..d1356356c1 100644 --- a/webroot/locales/fr-FR/common.json +++ b/webroot/locales/fr-FR/common.json @@ -1770,6 +1770,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.", @@ -1778,6 +1780,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.", @@ -1960,4 +1964,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 55da8aee72..4a13dce8a8 100644 --- a/webroot/locales/it-IT/common.json +++ b/webroot/locales/it-IT/common.json @@ -1770,6 +1770,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.", @@ -1778,6 +1780,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.", @@ -1960,4 +1964,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 ca0dcc9d70..485a5a13c9 100644 --- a/webroot/locales/ja-JP/common.json +++ b/webroot/locales/ja-JP/common.json @@ -1770,6 +1770,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.": "フォルダが更新されたら、アクセス権を持つユーザーに通知します。", @@ -1778,6 +1780,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.": "ユーザーが復旧を完了した場合、すべての管理者に通知します。", @@ -1925,4 +1929,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 51a242640b..23cc8f43e7 100644 --- a/webroot/locales/ko-KR/common.json +++ b/webroot/locales/ko-KR/common.json @@ -1770,6 +1770,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.": "폴더가 업데이트되면 폴더에 대한 접근 권한을 가진 사용자에게 알립니다.", @@ -1778,6 +1780,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.": "사용자가 복구를 완료하면 모든 관리자에게 알립니다.", @@ -1925,4 +1929,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 87e24f01c9..bbe39ebd60 100644 --- a/webroot/locales/lt-LT/common.json +++ b/webroot/locales/lt-LT/common.json @@ -1770,6 +1770,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", @@ -1778,6 +1780,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.", @@ -2030,4 +2034,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 afdef1b0c0..3cf9cf7531 100644 --- a/webroot/locales/nl-NL/common.json +++ b/webroot/locales/nl-NL/common.json @@ -1770,6 +1770,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.", @@ -1778,6 +1780,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.", @@ -1960,4 +1964,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 a0375bf606..c7ce3525c0 100644 --- a/webroot/locales/pl-PL/common.json +++ b/webroot/locales/pl-PL/common.json @@ -1770,6 +1770,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.", @@ -1778,6 +1780,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.", @@ -2030,4 +2034,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 e8fb4ff84b..2c23249f4e 100644 --- a/webroot/locales/pt-BR/common.json +++ b/webroot/locales/pt-BR/common.json @@ -1770,6 +1770,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.", @@ -1778,6 +1780,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.", @@ -1960,4 +1964,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 0b0497e05c..2ec5549f9f 100644 --- a/webroot/locales/ro-RO/common.json +++ b/webroot/locales/ro-RO/common.json @@ -1770,6 +1770,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.", @@ -1778,6 +1780,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.", @@ -1995,4 +1999,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 41c683a26f..ca905265cf 100644 --- a/webroot/locales/ru-RU/common.json +++ b/webroot/locales/ru-RU/common.json @@ -1770,6 +1770,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.": "При обновлении папки уведомлять пользователей, имеющих к ней доступ.", @@ -1778,6 +1780,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.": "При завершении восстановления пользователем уведомлять всех администраторов.", @@ -2030,4 +2034,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 320b7d28c3..0c8a1080e3 100644 --- a/webroot/locales/sl-SI/common.json +++ b/webroot/locales/sl-SI/common.json @@ -1770,6 +1770,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.", @@ -1778,6 +1780,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.", @@ -2030,4 +2034,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 d0ccf4d9b3..1e9f58c7de 100644 --- a/webroot/locales/sv-SE/common.json +++ b/webroot/locales/sv-SE/common.json @@ -1770,6 +1770,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.", @@ -1778,6 +1780,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.", @@ -1960,4 +1964,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 c4f002ab8f..3ab85b6859 100644 --- a/webroot/locales/uk-UA/common.json +++ b/webroot/locales/uk-UA/common.json @@ -1770,6 +1770,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.": "Коли теку оновлено, повідомити користувачів які мають доступ до неї.", @@ -1778,6 +1780,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.": "Коли користувач завершив відновлення, повідомити усіх адміністраторів.", @@ -2030,4 +2034,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 +}