passbolt-styleguide 3.8.4 → 3.9.0-alpha2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/css/help.min.css +3 -3
- package/build/css/public.min.css +3 -3
- package/build/css/themes/default/api_authentication.min.css +3 -3
- package/build/css/themes/default/api_cloud.min.css +3 -3
- package/build/css/themes/default/api_main.min.css +3 -3
- package/build/css/themes/default/api_reports.min.css +3 -3
- package/build/css/themes/default/api_webinstaller.min.css +3 -3
- package/build/css/themes/default/ext_app.min.css +3 -3
- package/build/css/themes/default/ext_authentication.min.css +3 -3
- package/build/css/themes/default/ext_external.min.css +2 -2
- package/build/css/themes/default/ext_in_form_cta.min.css +3 -3
- package/build/css/themes/default/ext_in_form_menu.min.css +3 -3
- package/build/css/themes/default/ext_quickaccess.min.css +3 -3
- package/build/css/themes/midgar/api_authentication.min.css +3 -3
- package/build/css/themes/midgar/api_main.min.css +3 -3
- package/build/css/themes/midgar/api_reports.min.css +3 -3
- package/build/css/themes/midgar/ext_app.min.css +3 -3
- package/build/css/themes/midgar/ext_authentication.min.css +3 -3
- package/build/css/themes/midgar/ext_in_form_cta.min.css +3 -3
- package/build/css/themes/midgar/ext_in_form_menu.min.css +3 -3
- package/build/css/themes/midgar/ext_quickaccess.min.css +3 -3
- package/build/css/themes/solarized_dark/api_authentication.min.css +1 -1
- package/build/css/themes/solarized_dark/api_main.min.css +1 -1
- package/build/css/themes/solarized_dark/api_reports.min.css +1 -1
- package/build/css/themes/solarized_dark/ext_app.min.css +1 -1
- package/build/css/themes/solarized_dark/ext_authentication.min.css +1 -1
- package/build/css/themes/solarized_dark/ext_in_form_cta.min.css +1 -1
- package/build/css/themes/solarized_dark/ext_in_form_menu.min.css +1 -1
- package/build/css/themes/solarized_dark/ext_quickaccess.min.css +1 -1
- package/build/css/themes/solarized_light/api_authentication.min.css +1 -1
- package/build/css/themes/solarized_light/api_main.min.css +1 -1
- package/build/css/themes/solarized_light/api_reports.min.css +1 -1
- package/build/css/themes/solarized_light/ext_app.min.css +1 -1
- package/build/css/themes/solarized_light/ext_authentication.min.css +1 -1
- package/build/css/themes/solarized_light/ext_in_form_cta.min.css +1 -1
- package/build/css/themes/solarized_light/ext_in_form_menu.min.css +1 -1
- package/build/css/themes/solarized_light/ext_quickaccess.min.css +1 -1
- package/build/js/dist/api-account-recovery.js +1 -1
- package/build/js/dist/api-app.js +1 -1
- package/build/js/dist/api-app.js.LICENSE.txt +75 -5
- package/build/js/dist/api-feedback.js +2 -0
- package/build/js/dist/api-feedback.js.LICENSE.txt +45 -0
- package/build/js/dist/api-recover.js +1 -1
- package/build/js/dist/api-setup.js +1 -1
- package/build/js/dist/api-triage.js +1 -1
- package/build/js/dist/api-vendors.js +1 -1
- package/build/js/dist/api-vendors.js.LICENSE.txt +19 -9
- package/build/js/dist/src/locales/de-DE/common.json +995 -0
- package/build/js/dist/src/locales/en-UK/common.json +1061 -0
- package/build/js/dist/src/locales/es-ES/common.json +995 -0
- package/build/js/dist/src/locales/fr-FR/common.json +995 -0
- package/build/js/dist/src/locales/ja-JP/common.json +980 -0
- package/build/js/dist/src/locales/lt-LT/common.json +1025 -0
- package/build/js/dist/src/locales/nl-NL/common.json +995 -0
- package/build/js/dist/src/locales/pl-PL/common.json +1025 -0
- package/build/js/dist/src/locales/sv-SE/common.json +995 -0
- package/package.json +18 -1
- package/src/img/controls/attention.svg +1 -0
- package/src/locales/en-UK/common.json +80 -16
- package/src/react-extension/ApiApp.js +17 -5
- package/src/react-extension/ApiFeedback.entry.js +24 -0
- package/src/react-extension/ExtApp.js +12 -5
- package/src/react-extension/ExtAuthenticationLogin.js +17 -15
- package/src/react-extension/ExtAuthenticationLogin.test.stories.js +59 -0
- package/src/react-extension/ExtBootstrapApp.js +1 -0
- package/src/react-extension/components/Administration/AdministrationWorkspace.js +24 -0
- package/src/react-extension/components/Administration/AdministrationWorkspace.test.data.js +3 -3
- package/src/react-extension/components/Administration/AdministrationWorkspace.test.js +13 -1
- package/src/react-extension/components/Administration/AdministrationWorkspace.test.page.js +7 -0
- package/src/react-extension/components/Administration/ConfirmDeleteSsoSettingsDialog/ConfirmDeleteSsoSettingsDialog.js +101 -0
- package/src/react-extension/components/Administration/ConfirmDeleteSsoSettingsDialog/ConfirmDeleteSsoSettingsDialog.test.data.js +23 -0
- package/src/react-extension/components/Administration/ConfirmDeleteSsoSettingsDialog/ConfirmDeleteSsoSettingsDialog.test.stories.js +27 -0
- package/src/react-extension/components/Administration/ConfirmSaveAccountRecoverySettings/ConfirmSaveAccountRecoverySettings.js +1 -1
- package/src/react-extension/components/Administration/DisplayAdministrationMenu/DisplayAdministrationMenu.js +78 -2
- package/src/react-extension/components/Administration/DisplayAdministrationMenu/DisplayAdministrationMenu.test.data.js +3 -1
- package/src/react-extension/components/Administration/DisplayAdministrationMenu/DisplayAdministrationMenu.test.js +60 -0
- package/src/react-extension/components/Administration/DisplayAdministrationMenu/DisplayAdministrationMenu.test.page.js +23 -4
- package/src/react-extension/components/Administration/DisplayAdministrationWorkspaceActions/DisplayAdministrationInternationalisationActions/DisplayAdministrationInternationalisationActions.js +125 -0
- package/src/react-extension/components/Administration/DisplayAdministrationWorkspaceActions/DisplayAdministrationMfaActions/DisplayAdministrationMfaActions.js +131 -0
- package/src/react-extension/components/Administration/DisplayAdministrationWorkspaceActions/DisplayAdministrationSelfRegistrationActions/DisplayAdministrationSelfRegistrationActions.js +103 -0
- package/src/react-extension/components/Administration/DisplayAdministrationWorkspaceActions/DisplayAdministrationSsoActions/DisplayAdministrationSsoActions.js +91 -0
- package/src/react-extension/components/Administration/DisplayAdministrationWorkspaceActions/DisplayAdministrationSubscriptionActions/DisplayAdministrationSubscriptionActions.js +85 -0
- package/src/react-extension/components/Administration/DisplayAdministrationWorkspaceActions/DisplayAdministrationUserDirectoryActions/DisplayAdministrationUserDirectoryActions.js +228 -0
- package/src/react-extension/components/Administration/DisplayAdministrationWorkspaceBreadcrumb/DisplayAdministrationWorkspaceBreadcrumb.js +4 -0
- package/src/react-extension/components/Administration/DisplayAdministrationWorkspaceBreadcrumb/DisplayAdministrationWorkspaceBreadcrumb.test.js +9 -0
- package/src/react-extension/components/Administration/DisplayEmailNotificationsAdministration/DisplayEmailNotificationsAdministration.js +3 -3
- package/src/react-extension/components/Administration/DisplayEmailNotificationsAdministration/DisplayEmailNotificationsAdministration.test.data.js +14 -0
- package/src/react-extension/components/Administration/DisplayEmailNotificationsAdministration/DisplayEmailNotificationsAdministration.test.page.js +0 -17
- package/src/react-extension/components/Administration/DisplayInternationalizationAdministration/DisplayInternationalizationAdministration.js +18 -115
- package/src/react-extension/components/Administration/DisplayInternationalizationAdministration/DisplayInternationalizationAdministration.test.data.js +11 -13
- package/src/react-extension/components/Administration/DisplayInternationalizationAdministration/DisplayInternationalizationAdministration.test.js +38 -43
- package/src/react-extension/components/Administration/DisplayInternationalizationAdministration/DisplayInternationalizationAdministration.test.page.js +47 -10
- package/src/react-extension/components/Administration/DisplayInternationalizationAdministration/DisplayInternationalizationAdministration.test.stories.js +10 -43
- package/src/react-extension/components/Administration/DisplayMfaAdministration/DisplayMfaAdministration.js +82 -367
- package/src/react-extension/components/Administration/DisplayMfaAdministration/DisplayMfaAdministration.test.data.js +128 -42
- package/src/react-extension/components/Administration/DisplayMfaAdministration/DisplayMfaAdministration.test.js +75 -121
- package/src/react-extension/components/Administration/DisplayMfaAdministration/DisplayMfaAdministration.test.page.js +46 -16
- package/src/react-extension/components/Administration/DisplayMfaAdministration/DisplayMfaAdministration.test.stories.js +18 -14
- package/src/react-extension/components/Administration/DisplaySelfRegistrationAdministration/ConfirmDeletionSelfRegistrationSettings/ConfirmDeletionSelfRegistrationSettings.js +103 -0
- package/src/react-extension/components/Administration/DisplaySelfRegistrationAdministration/ConfirmDeletionSelfRegistrationSettings/ConfirmDeletionSelfRegistrationSettings.test.js +53 -0
- package/src/react-extension/components/Administration/DisplaySelfRegistrationAdministration/ConfirmDeletionSelfRegistrationSettings/ConfirmDeletionSelfRegistrationSettings.test.page.js +81 -0
- package/src/react-extension/components/Administration/DisplaySelfRegistrationAdministration/ConfirmDeletionSelfRegistrationSettings/ConfirmDeletionSelfRegistrationSettings.test.stories.js +34 -0
- package/src/react-extension/components/Administration/DisplaySelfRegistrationAdministration/ConfirmSaveSelfRegistrationSettings/ConfirmSaveSelfRegistrationSettings.js +125 -0
- package/src/react-extension/components/Administration/DisplaySelfRegistrationAdministration/ConfirmSaveSelfRegistrationSettings/ConfirmSaveSelfRegistrationSettings.test.data.js +63 -0
- package/src/react-extension/components/Administration/DisplaySelfRegistrationAdministration/ConfirmSaveSelfRegistrationSettings/ConfirmSaveSelfRegistrationSettings.test.js +54 -0
- package/src/react-extension/components/Administration/DisplaySelfRegistrationAdministration/ConfirmSaveSelfRegistrationSettings/ConfirmSaveSelfRegistrationSettings.test.page.js +88 -0
- package/src/react-extension/components/Administration/DisplaySelfRegistrationAdministration/ConfirmSaveSelfRegistrationSettings/ConfirmSaveSelfRegistrationSettings.test.stories.js +35 -0
- package/src/react-extension/components/Administration/DisplaySelfRegistrationAdministration/DisplaySelfRegistrationAdministration.js +381 -0
- package/src/react-extension/components/Administration/DisplaySelfRegistrationAdministration/DisplaySelfRegistrationAdministration.test.data.js +69 -0
- package/src/react-extension/components/Administration/DisplaySelfRegistrationAdministration/DisplaySelfRegistrationAdministration.test.js +332 -0
- package/src/react-extension/components/Administration/DisplaySelfRegistrationAdministration/DisplaySelfRegistrationAdministration.test.page.js +247 -0
- package/src/react-extension/components/Administration/DisplaySelfRegistrationAdministration/DisplaySelfRegistrationAdministration.test.stories.js +72 -0
- package/src/react-extension/components/Administration/DisplaySimulateSynchronizeUserDirectoryAdministration/DisplaySimulateSynchronizeUserDirectoryAdministration.js +19 -19
- package/src/react-extension/components/Administration/DisplaySimulateSynchronizeUserDirectoryAdministration/DisplaySimulateSynchronizeUserDirectoryAdministration.test.data.js +1717 -1729
- package/src/react-extension/components/Administration/DisplaySimulateSynchronizeUserDirectoryAdministration/DisplaySimulateSynchronizeUserDirectoryAdministration.test.js +11 -3
- package/src/react-extension/components/Administration/DisplaySimulateSynchronizeUserDirectoryAdministration/DisplaySimulateSynchronizeUserDirectoryAdministration.test.page.js +4 -1
- package/src/react-extension/components/Administration/DisplaySimulateSynchronizeUserDirectoryAdministration/DisplaySimulateSynchronizeUserDirectoryAdministration.test.stories.js +11 -1784
- package/src/react-extension/components/Administration/DisplaySubscriptionKey/DisplaySubscriptionKey.js +41 -140
- package/src/react-extension/components/Administration/DisplaySubscriptionKey/DisplaySubscriptionKey.test.data.js +15 -3
- package/src/react-extension/components/Administration/DisplaySubscriptionKey/DisplaySubscriptionKey.test.js +22 -49
- package/src/react-extension/components/Administration/DisplaySubscriptionKey/DisplaySubscriptionKey.test.page.js +19 -11
- package/src/react-extension/components/Administration/DisplaySubscriptionKey/DisplaySubscriptionKey.test.stories.js +9 -3
- package/src/react-extension/components/Administration/DisplaySynchronizeUserDirectoryAdministration/DisplaySynchronizeUserDirectoryAdministration.js +5 -6
- package/src/react-extension/components/Administration/DisplaySynchronizeUserDirectoryAdministration/DisplaySynchronizeUserDirectoryAdministration.test.data.js +1717 -1728
- package/src/react-extension/components/Administration/DisplaySynchronizeUserDirectoryAdministration/DisplaySynchronizeUserDirectoryAdministration.test.js +11 -3
- package/src/react-extension/components/Administration/DisplaySynchronizeUserDirectoryAdministration/DisplaySynchronizeUserDirectoryAdministration.test.page.js +4 -1
- package/src/react-extension/components/Administration/DisplaySynchronizeUserDirectoryAdministration/DisplaySynchronizeUserDirectoryAdministration.test.stories.js +11 -1784
- package/src/react-extension/components/Administration/DisplayUserDirectoryAdministration/DisplayUserDirectoryAdministration.js +362 -835
- package/src/react-extension/components/Administration/DisplayUserDirectoryAdministration/DisplayUserDirectoryAdministration.test.data.js +427 -418
- package/src/react-extension/components/Administration/DisplayUserDirectoryAdministration/DisplayUserDirectoryAdministration.test.js +134 -175
- package/src/react-extension/components/Administration/DisplayUserDirectoryAdministration/DisplayUserDirectoryAdministration.test.page.js +108 -11
- package/src/react-extension/components/Administration/DisplayUserDirectoryAdministration/DisplayUserDirectoryAdministration.test.stories.js +17 -25
- package/src/react-extension/components/Administration/EditSubscriptionKey/EditSubscriptionKey.js +4 -2
- package/src/react-extension/components/Administration/ManageAccountRecoveryAdministrationSettings/ManageAccountRecoveryAdministrationSettings.js +3 -3
- package/src/react-extension/components/Administration/ManageAccountRecoveryAdministrationSettings/ManageAccountRecoveryAdministrationSettings.test.js +1 -1
- package/src/react-extension/components/Administration/ManageSmtpAdministrationSettings/ManageSmtpAdministrationSettings.js +32 -7
- package/src/react-extension/components/Administration/ManageSmtpAdministrationSettings/ManageSmtpAdministrationSettings.test.data.js +0 -3
- package/src/react-extension/components/Administration/ManageSmtpAdministrationSettings/ManageSmtpAdministrationSettings.test.js +145 -1
- package/src/react-extension/components/Administration/ManageSmtpAdministrationSettings/ManageSmtpAdministrationSettings.test.page.js +52 -1
- package/src/react-extension/components/Administration/ManageSmtpAdministrationSettings/ManageSmtpAdministrationSettings.test.stories.js +15 -0
- package/src/react-extension/components/Administration/ManageSsoSettings/ManageSsoSettings.js +340 -0
- package/src/react-extension/components/Administration/ManageSsoSettings/ManageSsoSettings.test.data.js +56 -0
- package/src/react-extension/components/Administration/ManageSsoSettings/ManageSsoSettings.test.js +223 -0
- package/src/react-extension/components/Administration/ManageSsoSettings/ManageSsoSettings.test.page.js +235 -0
- package/src/react-extension/components/Administration/ManageSsoSettings/ManageSsoSettings.test.stories.js +55 -0
- package/src/react-extension/components/Administration/ManageSsoSettings/SsoProviders.data.js +34 -0
- package/src/react-extension/components/Administration/SelectAccountRecoveryOrganizationKey/GenerateOrganizationKey.js +12 -3
- package/src/react-extension/components/Administration/SelectAccountRecoveryOrganizationKey/GenerateOrganizationKey.test.js +27 -0
- package/src/react-extension/components/Administration/SelectAccountRecoveryOrganizationKey/SelectAccountRecoveryOrganizationKey.test.page.js +8 -0
- package/src/react-extension/components/Administration/TestSsoSettingsDialog/TestSsoSettingsDialog.js +197 -0
- package/src/react-extension/components/Administration/TestSsoSettingsDialog/TestSsoSettingsDialog.test.data.js +37 -0
- package/src/react-extension/components/Administration/TestSsoSettingsDialog/TestSsoSettingsDialog.test.js +187 -0
- package/src/react-extension/components/Administration/TestSsoSettingsDialog/TestSsoSettingsDialog.test.page.js +120 -0
- package/src/react-extension/components/Administration/TestSsoSettingsDialog/TestSsoSettingsDialog.test.stories.js +31 -0
- package/src/react-extension/components/Authentication/CheckPassphrase/CheckPassphrase.js +9 -5
- package/src/react-extension/components/Authentication/CheckPassphrase/CheckPassphrase.test.data.js +4 -0
- package/src/react-extension/components/Authentication/CheckPassphrase/CheckPassphrase.test.js +11 -42
- package/src/react-extension/components/Authentication/CheckPassphrase/CheckPassphrase.test.page.js +1 -0
- package/src/react-extension/components/Authentication/CreateGpgKey/CreateGpgKey.js +9 -5
- package/src/react-extension/components/Authentication/CreateGpgKey/CreateGpgKey.test.data.js +4 -0
- package/src/react-extension/components/Authentication/CreateGpgKey/CreateGpgKey.test.js +16 -2
- package/src/react-extension/components/Authentication/CreateGpgKey/CreateGpgKey.test.page.js +17 -1
- package/src/react-extension/components/AuthenticationLogin/Login/Login.js +159 -61
- package/src/react-extension/components/AuthenticationLogin/Login/Login.test.data.js +14 -11
- package/src/react-extension/components/AuthenticationLogin/Login/Login.test.js +79 -0
- package/src/react-extension/components/AuthenticationLogin/Login/Login.test.page.js +16 -0
- package/src/react-extension/components/AuthenticationLogin/OrchestrateLogin/OrchestrateLoginBoxMain.js +2 -0
- package/src/react-extension/components/AuthenticationSetup/SetupAuthentication/SetupAuthentication.js +4 -0
- package/src/react-extension/components/Common/Error/ApiError/ApiError.js +119 -0
- package/src/react-extension/components/Common/Error/ApiError/ApiError.test.js +43 -0
- package/src/react-extension/components/Common/Error/ApiError/ApiError.test.page.js +108 -0
- package/src/react-extension/components/Common/Error/ApiError/ApiError.test.stories.js +39 -0
- package/src/react-extension/components/Common/Inputs/Autocomplete/Autocomplete.test.js +12 -0
- package/src/react-extension/components/Common/Inputs/Autocomplete/AutocompleteItem.js +2 -2
- package/src/react-extension/components/Common/Legacy/HandleLegacyAppjs.js +1 -1
- package/src/react-extension/components/Common/Navigation/Header/Logo.js +13 -1
- package/src/react-extension/components/Resource/CreateResource/CreateResource.js +103 -30
- package/src/react-extension/components/Resource/CreateResource/CreateResource.test.js +44 -10
- package/src/react-extension/components/Resource/CreateResource/CreateResource.test.page.js +35 -7
- package/src/react-extension/components/Resource/DisplayResourcesList/DisplayResourcesList.js +3 -3
- package/src/react-extension/components/Resource/DisplayResourcesList/DisplayResourcesListContextualMenu.js +6 -5
- package/src/react-extension/components/Resource/DisplayResourcesWorkspace/DisplayResourcesWorkspaceMenu.js +5 -4
- package/src/react-extension/components/Resource/EditResource/EditResource.js +95 -23
- package/src/react-extension/components/Resource/EditResource/EditResource.test.js +45 -13
- package/src/react-extension/components/Resource/EditResource/EditResource.test.page.js +35 -2
- package/src/react-extension/components/ResourceDetails/DisplayResourceDetails/DisplayResourceDetails.js +2 -1
- package/src/react-extension/components/ResourceDetails/DisplayResourceDetails/DisplayResourceDetailsInformation.js +3 -2
- package/src/react-extension/components/ResourceFolder/CreateResourceFolder/CreateResourceFolder.js +23 -2
- package/src/react-extension/components/ResourceFolder/CreateResourceFolder/CreateResourceFolder.test.js +8 -0
- package/src/react-extension/components/ResourceFolder/CreateResourceFolder/CreateResourceFolder.test.page.js +26 -2
- package/src/react-extension/components/ResourceFolder/RenameResourceFolder/RenameResourceFolder.js +22 -1
- package/src/react-extension/components/ResourceFolder/RenameResourceFolder/RenameResourceFolder.test.js +8 -0
- package/src/react-extension/components/ResourceFolder/RenameResourceFolder/RenameResourceFolder.test.page.js +25 -2
- package/src/react-extension/components/ResourceFolderDetails/DisplayResourceFolderDetails/DisplayResourceFolderDetails.js +2 -1
- package/src/react-extension/components/ResourcePassword/GenerateResourcePassword/GenerateResourcePassword.js +2 -1
- package/src/react-extension/components/ResourceTag/EditResourceTag/EditResourceTag.js +14 -1
- package/src/react-extension/components/ResourceTag/EditResourceTag/EditResourceTag.test.js +8 -0
- package/src/react-extension/components/ResourceTag/EditResourceTag/EditResourceTag.test.page.js +12 -0
- package/src/react-extension/components/User/CreateUser/CreateUser.js +42 -3
- package/src/react-extension/components/User/CreateUser/CreateUser.test.js +16 -0
- package/src/react-extension/components/User/CreateUser/CreateUser.test.page.js +26 -0
- package/src/react-extension/components/User/DisplayUserWorkspaceActions/DisplayUserWorkspaceActions.js +2 -1
- package/src/react-extension/components/User/DisplayUsersContextualMenu/DisplayUsersContextualMenu.js +5 -5
- package/src/react-extension/components/User/EditUser/EditUser.js +29 -2
- package/src/react-extension/components/User/EditUser/EditUser.test.js +12 -0
- package/src/react-extension/components/User/EditUser/EditUser.test.page.js +26 -0
- package/src/react-extension/components/UserDetails/DisplayUserDetails/DisplayUserDetails.js +2 -1
- package/src/react-extension/components/UserDetails/DisplayUserDetails/DisplayUserDetails.test.data.js +1332 -1331
- package/src/react-extension/components/UserDetails/DisplayUserDetailsPublicKey/DisplayUserDetailsPublicKey.js +2 -1
- package/src/react-extension/components/UserGroup/CreateUserGroup/CreateUserGroup.js +19 -1
- package/src/react-extension/components/UserGroup/CreateUserGroup/CreateUserGroup.test.js +9 -0
- package/src/react-extension/components/UserGroup/CreateUserGroup/CreateUserGroup.test.page.js +12 -0
- package/src/react-extension/components/UserGroup/DisplayUserGroupDetails/DisplayUserGroupDetails.js +2 -1
- package/src/react-extension/components/UserGroup/EditUserGroup/EditUserGroup.js +16 -1
- package/src/react-extension/components/UserGroup/EditUserGroup/EditUserGroup.test.js +8 -0
- package/src/react-extension/components/UserGroup/EditUserGroup/EditUserGroup.test.page.js +26 -1
- package/src/react-extension/components/UserSetting/ChangeUserPassphrase/ConfirmPassphrase.js +1 -1
- package/src/react-extension/components/UserSetting/ChangeUserPassphrase/EnterNewPassphrase.js +6 -4
- package/src/react-extension/components/UserSetting/ChangeUserPassphrase/EnterNewPassphrase.test.data.js +4 -1
- package/src/react-extension/components/UserSetting/ChangeUserPassphrase/EnterNewPassphrase.test.js +21 -11
- package/src/react-extension/components/UserSetting/ChangeUserPassphrase/EnterNewPassphrase.test.page.js +10 -1
- package/src/react-extension/contexts/AdminSmtpSettingsContext.js +2 -0
- package/src/react-extension/contexts/AdminSmtpSettingsContext.test.data.js +13 -0
- package/src/react-extension/contexts/AdminSmtpSettingsContext.test.js +3 -1
- package/src/react-extension/contexts/AdminSsoContext.js +558 -0
- package/src/react-extension/contexts/AdminSsoContext.test.data.js +51 -0
- package/src/react-extension/contexts/Administration/AdministrationInternationalizationContext/AdministrationInternationalizationContext.js +194 -0
- package/src/react-extension/contexts/Administration/AdministrationInternationalizationContext/AdministrationInternationalizationContext.test.js +111 -0
- package/src/react-extension/contexts/Administration/AdministrationMfa/AdministrationMfaContext.js +265 -0
- package/src/react-extension/contexts/Administration/AdministrationMfa/AdministrationMfaContext.test.js +178 -0
- package/src/react-extension/contexts/Administration/AdministrationSelfRegistration/AdministrationSelfRegistrationContext.js +453 -0
- package/src/react-extension/contexts/Administration/AdministrationSelfRegistration/AdministrationSelfRegistrationContext.test.js +218 -0
- package/src/react-extension/contexts/Administration/AdministrationSubscription/AdministrationSubscription.js +168 -0
- package/src/react-extension/contexts/Administration/AdministrationSubscription/AdministrationSubscription.test.js +73 -0
- package/src/react-extension/contexts/Administration/AdministrationUserDirectory/AdministrationUserDirectoryContext.js +353 -0
- package/src/react-extension/contexts/Administration/AdministrationUserDirectory/AdministrationUserDirectoryContext.test.js +220 -0
- package/src/react-extension/contexts/AdministrationWorkspaceContext.js +17 -178
- package/src/react-extension/contexts/AdministrationWorkspaceContext.test.js +0 -26
- package/src/react-extension/contexts/ApiAppContext.test.data.js +4 -2
- package/src/react-extension/contexts/Authentication/AuthenticationLoginContext.js +54 -4
- package/src/react-extension/contexts/Authentication/AuthenticationLoginContext.test.data.js +10 -1
- package/src/react-extension/contexts/Authentication/AuthenticationLoginContext.test.js +92 -14
- package/src/react-extension/contexts/Authentication/AuthenticationSetupContext.js +1 -0
- package/src/react-extension/contexts/NavigationContext.js +34 -0
- package/src/react-extension/contexts/SsoContext.js +151 -0
- package/src/react-extension/contexts/SsoContext.test.data.js +36 -0
- package/src/react-extension/contexts/SsoContext.test.js +104 -0
- package/src/react-extension/lib/Domain/DomainUtil.js +70 -0
- package/src/react-extension/lib/Domain/DomainUtil.test.js +129 -0
- package/src/react-extension/lib/Domain/Domains.js +6113 -0
- package/src/react-extension/lib/Error/InputValidator.js +24 -0
- package/src/react-extension/lib/Map/DynamicRef.js +49 -0
- package/src/react-extension/lib/Map/DynamicRef.test.js +56 -0
- package/src/react-extension/lib/Map/MapObject.js +48 -0
- package/src/react-extension/lib/Map/MapObject.test.js +43 -0
- package/src/react-quickaccess/ExtQuickAccess.js +7 -4
- package/src/react-quickaccess/components/GeneratePasswordPage/GeneratePasswordPage.js +3 -1
- package/src/react-quickaccess/components/GeneratePasswordPage/GeneratePasswordPage.test.data.js +4 -0
- package/src/react-quickaccess/components/LoginPage/LoginPage.js +115 -4
- package/src/react-quickaccess/components/LoginPage/LoginPage.test.data.js +10 -0
- package/src/react-quickaccess/components/LoginPage/LoginPage.test.stories.js +30 -3
- package/src/react-quickaccess/components/ResourceAutoSave/SaveResource.js +33 -1
- package/src/react-quickaccess/components/ResourceAutoSave/SaveResource.test.data.js +25 -0
- package/src/react-quickaccess/components/ResourceAutoSave/SaveResource.test.js +60 -0
- package/src/react-quickaccess/components/ResourceAutoSave/SaveResource.test.page.js +60 -0
- package/src/react-quickaccess/components/ResourceCreatePage/ResourceCreatePage.js +33 -1
- package/src/react-quickaccess/components/ResourceCreatePage/ResourceCreatePage.test.js +36 -7
- package/src/react-quickaccess/components/ResourceViewPage/ResourceViewPage.js +3 -2
- package/src/react-quickaccess/contexts/SsoContext.js +150 -0
- package/src/react-web-integration/lib/InForm/InFormFieldSelector.js +5 -0
- package/src/shared/constants/inputs.const.js +30 -0
- package/src/shared/lib/Browser/clipBoard.js +45 -0
- package/src/shared/lib/Browser/clipBoard.test.js +59 -0
- package/src/shared/models/Mfa/Duo.js +36 -0
- package/src/shared/models/Mfa/Duo.test.js +59 -0
- package/src/shared/models/Mfa/MfaDTO.js +51 -0
- package/src/shared/models/Mfa/MfaDTO.test.js +48 -0
- package/src/shared/models/Mfa/MfaEnumeration.js +17 -0
- package/src/shared/models/Mfa/MfaModel.js +48 -0
- package/src/shared/models/Mfa/MfaModel.test.js +37 -0
- package/src/shared/models/Mfa/Yubikey.js +35 -0
- package/src/shared/models/Mfa/Yubikey.test.js +47 -0
- package/src/shared/models/selfRegistration/SelfRegistrationDomainsViewModel.js +55 -0
- package/src/shared/models/selfRegistration/SelfRegistrationDomainsViewModel.test.js +37 -0
- package/src/shared/models/selfRegistration/SelfRegistrationDto.js +42 -0
- package/src/shared/models/selfRegistration/SelfRegistrationDto.test.js +48 -0
- package/src/shared/models/selfRegistration/SelfRegistrationEnumeration.js +17 -0
- package/src/shared/models/subscription/SubscriptionDto.js +34 -0
- package/src/shared/models/subscription/SubscriptionDto.test.js +31 -0
- package/src/shared/models/subscription/SubscriptionModel.js +33 -0
- package/src/shared/models/subscription/SubscriptionModel.test.js +48 -0
- package/src/shared/models/user/UserModel.js +37 -0
- package/src/shared/models/userDirectory/UserDirectoryDTO.js +57 -0
- package/src/shared/models/userDirectory/UserDirectoryDTO.test.js +40 -0
- package/src/shared/models/userDirectory/UserDirectoryEnum.js +22 -0
- package/src/shared/models/userDirectory/UserDirectoryModel.js +64 -0
- package/src/shared/models/userDirectory/UserDirectoryModel.test.js +37 -0
- package/src/shared/services/actions/subscription/SubscriptionActionService.js +69 -0
- package/src/shared/services/actions/subscription/SubscriptionActionService.test.js +73 -0
- package/src/shared/services/api/Internationalisation/InternationalisationService.js +46 -0
- package/src/shared/services/api/Mfa/MfaService.js +54 -0
- package/src/shared/services/{accountRecovery → api/accountRecovery}/ApiAppAccountRecoveryUserService.js +2 -2
- package/src/shared/services/{accountRecovery → api/accountRecovery}/ExtAppAccountRecoveryUserService.js +0 -0
- package/src/shared/services/api/secrets/pownedService.js +64 -0
- package/src/shared/services/api/secrets/pownedService.test.js +63 -0
- package/src/shared/services/api/selfRegistration/selfRegistrationService.js +64 -0
- package/src/shared/services/api/user/UserService.js +45 -0
- package/src/shared/services/api/userDirectory/UserDirectoryService.js +108 -0
- package/src/shared/services/forms/Mfa/MfaFormService.js +195 -0
- package/src/shared/services/forms/Mfa/MfaFormService.test.js +341 -0
- package/src/shared/services/forms/selfRegistration/SelfRegistrationFormService.js +92 -0
- package/src/shared/services/forms/selfRegistration/SelfRegistrationFormService.test.js +101 -0
- package/src/shared/services/forms/userDirectory/UserDirectoryFormService.js +118 -0
- package/src/shared/services/forms/userDirectory/UserDirectoryFormService.test.js +128 -0
- package/src/react-extension/components/Administration/DisplayAdministrationWorkspaceActions/DisplayAdministrationWorkspaceActions.js +0 -205
- package/src/react-extension/components/Administration/DisplayAdministrationWorkspaceActions/DisplayAdministrationWorkspaceActions.test.data.js +0 -37
- package/src/react-extension/components/Administration/DisplayAdministrationWorkspaceActions/DisplayAdministrationWorkspaceActions.test.js +0 -197
- package/src/react-extension/components/Administration/DisplayAdministrationWorkspaceActions/DisplayAdministrationWorkspaceActions.test.page.js +0 -133
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Passbolt ~ Open source password manager for teams
|
|
3
|
+
* Copyright (c) 2020 Passbolt SA (https://www.passbolt.com)
|
|
4
|
+
*
|
|
5
|
+
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
|
6
|
+
* For full copyright and license information, please see the LICENSE.txt
|
|
7
|
+
* Redistributions of files must retain the above copyright notice.
|
|
8
|
+
*
|
|
9
|
+
* @copyright Copyright (c) 2020 Passbolt SA (https://www.passbolt.com)
|
|
10
|
+
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
|
11
|
+
* @link https://www.passbolt.com Passbolt(tm)
|
|
12
|
+
* @since 3.9.0
|
|
13
|
+
*/
|
|
14
|
+
import ApiErrorPage from "./ApiError.test.page";
|
|
15
|
+
import {waitFor} from "@testing-library/dom";
|
|
16
|
+
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
jest.resetModules();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
describe("ApiError", () => {
|
|
22
|
+
it('Should display the given error log message from the content of the page', async() => {
|
|
23
|
+
expect.assertions(6);
|
|
24
|
+
const props = {
|
|
25
|
+
errorDetails: "This is an error message to be displayed in the log details"
|
|
26
|
+
};
|
|
27
|
+
const page = new ApiErrorPage(props);
|
|
28
|
+
await waitFor(() => {});
|
|
29
|
+
|
|
30
|
+
expect(page.exists()).toBeTruthy();
|
|
31
|
+
expect(page.logToggle).toBeTruthy();
|
|
32
|
+
expect(page.logDetails).toBeFalsy();
|
|
33
|
+
|
|
34
|
+
await page.clickOnLogToggle();
|
|
35
|
+
|
|
36
|
+
expect(page.logDetails).toBeTruthy();
|
|
37
|
+
expect(page.logDetails.value).toStrictEqual(props.errorDetails);
|
|
38
|
+
|
|
39
|
+
await page.clickOnLogToggle();
|
|
40
|
+
|
|
41
|
+
expect(page.logDetails).toBeFalsy();
|
|
42
|
+
});
|
|
43
|
+
});
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Passbolt ~ Open source password manager for teams
|
|
3
|
+
* Copyright (c) 2022 Passbolt SA (https://www.passbolt.com)
|
|
4
|
+
*
|
|
5
|
+
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
|
6
|
+
* For full copyright and license information, please see the LICENSE.txt
|
|
7
|
+
* Redistributions of files must retain the above copyright notice.
|
|
8
|
+
*
|
|
9
|
+
* @copyright Copyright (c) 2022 Passbolt SA (https://www.passbolt.com)
|
|
10
|
+
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
|
11
|
+
* @link https://www.passbolt.com Passbolt(tm)
|
|
12
|
+
* @since 3.9.0
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import {fireEvent, render, waitFor} from "@testing-library/react";
|
|
16
|
+
import React from "react";
|
|
17
|
+
import MockTranslationProvider from "../../../../test/mock/components/Internationalisation/MockTranslationProvider";
|
|
18
|
+
import ApiError from "./ApiError";
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* The ApiErrorPage component represented as a page
|
|
22
|
+
*/
|
|
23
|
+
export default class ApiErrorPage {
|
|
24
|
+
/**
|
|
25
|
+
* Default constructor
|
|
26
|
+
* @param props Props to attach
|
|
27
|
+
*/
|
|
28
|
+
constructor({errorDetails, ...props}) {
|
|
29
|
+
this._page = render(
|
|
30
|
+
<MockTranslationProvider>
|
|
31
|
+
<>
|
|
32
|
+
<ApiError {...props}/>
|
|
33
|
+
<div id="api-error-details" className="visually-hidden">
|
|
34
|
+
{errorDetails}
|
|
35
|
+
</div>
|
|
36
|
+
</>
|
|
37
|
+
</MockTranslationProvider>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Shortcut method for the container querySelector.
|
|
43
|
+
* @param {string} stringSelector
|
|
44
|
+
* @returns {HTMLElement}
|
|
45
|
+
*/
|
|
46
|
+
select(stringSelector) {
|
|
47
|
+
return this._page.container.querySelector(stringSelector);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Returns true if the page exists.
|
|
52
|
+
* This means that it's loaded and the title text content is non empty.
|
|
53
|
+
* @returns {boolean}
|
|
54
|
+
*/
|
|
55
|
+
exists() {
|
|
56
|
+
return this.panel !== null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Simulates a click on the given HTML element.
|
|
61
|
+
* The clicks is consider done when the callback returns {true}.
|
|
62
|
+
* @param {HTMLElement} element The HTML element onto simulate the click
|
|
63
|
+
* @param {function} callback The callback to be used in the waitFor method to ensure the click is done (returns true when it's done)
|
|
64
|
+
* @returns {Promise<void>}
|
|
65
|
+
*/
|
|
66
|
+
async clickOn(element, callback) {
|
|
67
|
+
const leftClick = {button: 0};
|
|
68
|
+
fireEvent.click(element, leftClick);
|
|
69
|
+
await waitFor(() => {
|
|
70
|
+
if (!callback()) {
|
|
71
|
+
throw new Error("Page didn't react yet on the event.");
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Returns the main panel
|
|
78
|
+
* @return {HTMLElement}
|
|
79
|
+
*/
|
|
80
|
+
get panel() {
|
|
81
|
+
return this.select('.api-error-card');
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Returns the main panel
|
|
86
|
+
* @return {HTMLElement}
|
|
87
|
+
*/
|
|
88
|
+
get logToggle() {
|
|
89
|
+
return this.select('.api-error-card .accordion-header a');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Returns the textarea containing the log details
|
|
94
|
+
* @return {HTMLElement}
|
|
95
|
+
*/
|
|
96
|
+
get logDetails() {
|
|
97
|
+
return this.select('.api-error-card .accordion-content textarea');
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Simulates a click on the Log button toggle
|
|
102
|
+
* @return {Promise<void>}
|
|
103
|
+
*/
|
|
104
|
+
clickOnLogToggle() {
|
|
105
|
+
const isLogDetailsPresent = Boolean(this.logDetails);
|
|
106
|
+
return this.clickOn(this.logToggle, () => isLogDetailsPresent !== Boolean(this.logDetails));
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Passbolt ~ Open source password manager for teams
|
|
3
|
+
* Copyright (c) 2022 Passbolt SA (https://www.passbolt.com)
|
|
4
|
+
*
|
|
5
|
+
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
|
6
|
+
* For full copyright and license information, please see the LICENSE.txt
|
|
7
|
+
* Redistributions of files must retain the above copyright notice.
|
|
8
|
+
*
|
|
9
|
+
* @copyright Copyright (c) 2022 Passbolt SA (https://www.passbolt.com)
|
|
10
|
+
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
|
11
|
+
* @link https://www.passbolt.com Passbolt(tm)
|
|
12
|
+
* @since 3.9.0
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import React from "react";
|
|
16
|
+
import ApiError from "./ApiError";
|
|
17
|
+
|
|
18
|
+
export default {
|
|
19
|
+
title: 'Components/Common/Error/ApiError',
|
|
20
|
+
component: ApiError
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const Template = args =>
|
|
24
|
+
<div id="root">
|
|
25
|
+
<ApiError {...args}/>
|
|
26
|
+
<div id="api-error-details" className="visually-hidden">
|
|
27
|
+
{args.errorDetails}
|
|
28
|
+
</div>
|
|
29
|
+
</div>;
|
|
30
|
+
|
|
31
|
+
const parameters = {
|
|
32
|
+
css: "api_main"
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export const ErrorFeedback = Template.bind({});
|
|
36
|
+
ErrorFeedback.args = {
|
|
37
|
+
errorDetails: "AADSTS70011: The provided value for the input parameter 'scope' isn't valid. The scope https://example.contoso.com/activity.read isn't valid.\r\nTrace ID: 255d1aef-8c98-452f-ac51-23d051240864\r\nCorrelation ID: fb3d2015-bc17-4bb9-bb85-30c5cf1aaaa7\r\nTimestamp: 2016-01-09 02:02:12Z",
|
|
38
|
+
};
|
|
39
|
+
ErrorFeedback.parameters = parameters;
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
/**
|
|
16
16
|
* Unit tests on Autocomplete in regard of specifications
|
|
17
17
|
*/
|
|
18
|
+
import {groups} from "../../../UserDetails/DisplayUserDetails/DisplayUserDetails.test.data";
|
|
18
19
|
import {defaultProps} from "./Autocomplete.test.data";
|
|
19
20
|
import AutocompletePage from "./Autocomplete.test.page";
|
|
20
21
|
|
|
@@ -73,6 +74,17 @@ describe("See the Autocomplete", () => {
|
|
|
73
74
|
expect(props.onClose).toHaveBeenCalled();
|
|
74
75
|
});
|
|
75
76
|
|
|
77
|
+
it('As LU I should see an item with the number of user into the group', async() => {
|
|
78
|
+
expect.assertions(1);
|
|
79
|
+
const items = [
|
|
80
|
+
{name: "group", groups_users: groups}
|
|
81
|
+
];
|
|
82
|
+
const requestMockImpl = jest.fn(() => items);
|
|
83
|
+
jest.spyOn(props, 'searchCallback').mockImplementation(requestMockImpl);
|
|
84
|
+
await page.fillInput("at");
|
|
85
|
+
expect(page.getAutocompleteItemDetails(1)).toBe("10 group members");
|
|
86
|
+
});
|
|
87
|
+
|
|
76
88
|
it('As LU I should see autocomplete empty', async() => {
|
|
77
89
|
expect.assertions(3);
|
|
78
90
|
const requestMockImpl = jest.fn(() => []);
|
|
@@ -55,8 +55,8 @@ class AutocompleteItem extends Component {
|
|
|
55
55
|
const longId = this.props.user.gpgkey.fingerprint.substr(this.props.user.gpgkey.fingerprint.length - 16);
|
|
56
56
|
return longId.replace(/(.{4})/g, "$1 ");
|
|
57
57
|
} else {
|
|
58
|
-
if (this.props.group
|
|
59
|
-
return `${this.props.group.
|
|
58
|
+
if (this.props.group?.groups_users?.length > 1) {
|
|
59
|
+
return `${this.props.group.groups_users.length} group members`;
|
|
60
60
|
} else {
|
|
61
61
|
return `One group member`;
|
|
62
62
|
}
|
|
@@ -83,7 +83,7 @@ class HandleLegacyAppjs extends Component {
|
|
|
83
83
|
"/app/administration/users-directory",
|
|
84
84
|
"/app/administration/email-notification",
|
|
85
85
|
"/app/administration/internationalisation",
|
|
86
|
-
"/app/settings/mfa"
|
|
86
|
+
"/app/settings/mfa",
|
|
87
87
|
];
|
|
88
88
|
return apiPaths.some(apiPath => path.endsWith(apiPath));
|
|
89
89
|
}
|
|
@@ -21,7 +21,19 @@ class Logo extends Component {
|
|
|
21
21
|
render() {
|
|
22
22
|
return (
|
|
23
23
|
<div className="col1">
|
|
24
|
-
<div className="logo no-img">
|
|
24
|
+
<div className="logo-svg no-img">
|
|
25
|
+
<svg height="25px" fill="none" xmlns="http://www.w3.org/2000/svg" width="100%" viewBox="0 30 450 20">
|
|
26
|
+
<g clipPath="url(#clip0)">
|
|
27
|
+
<path d="M12.1114 26.4938V52.609h7.4182c4.9203 0 8.3266-1.0597 10.3704-3.1035 2.0438-2.0438 3.0278-5.5258 3.0278-10.2947 0-4.6175-.9083-7.8724-2.8007-9.7648-1.8924-2.0438-5.0717-2.9522-9.6891-2.9522h-8.3266zM0 16.5776h23.3144c7.0398 0 12.4899 2.0438 16.4261 6.2071 3.9362 4.1633 5.9043 9.9162 5.9043 17.2588 0 3.0278-.3785 5.8286-1.2111 8.3265-.8327 2.498-2.0438 4.8446-3.7091 6.8884-1.9681 2.498-4.3904 4.3147-7.1155 5.4501-2.8007 1.0598-6.4342 1.5896-11.0516 1.5896H12.1114v16.5775H0v-62.298zM70.0188 53.1389H85.158v-9.462H70.9272c-2.8008 0-4.7689.3785-5.8287 1.1354-1.0597.757-1.5896 2.1195-1.5896 4.0119 0 1.5896.4542 2.7251 1.2869 3.4063.8326.6056 2.5736.9084 5.223.9084zM53.9712 16.5776h24.7527c6.2827 0 10.9759 1.4383 14.1551 4.3147 3.1793 2.8765 4.7689 7.1155 4.7689 12.7927v28.6888H65.0985c-4.5417 0-8.0994-1.1354-10.5217-3.4063s-3.6334-5.5258-3.6334-9.7648c0-5.223 1.3625-8.9322 4.1633-11.203 2.8007-2.2709 7.4939-3.4064 14.0794-3.4064h15.8962v-1.1354c0-2.7251-.8326-4.6175-2.4222-5.7529-1.5897-1.1355-4.3904-1.6653-8.5537-1.6653H53.9712v-9.4621zM107.488 52.8356h25.51c2.271 0 3.936-.3784 4.92-1.0597 1.06-.6813 1.59-1.8167 1.59-3.4063 0-1.5897-.53-2.7251-1.59-3.4064-1.059-.7569-2.725-1.1354-4.92-1.1354h-10.446c-6.207 0-10.37-.9841-12.566-2.8765-2.195-1.8924-3.255-5.2987-3.255-10.0676 0-4.9202 1.287-8.5536 3.937-10.9002 2.649-2.3466 6.737-3.482 12.187-3.482h25.964v9.5377h-21.347c-3.482 0-5.753.3028-6.812.9083-1.06.6056-1.59 1.6654-1.59 3.255 0 1.4382.454 2.498 1.362 3.1035.909.6813 2.423.9841 4.391.9841h10.976c4.996 0 8.856 1.2111 11.43 3.5577 2.649 2.3466 3.936 5.6772 3.936 10.0676 0 4.239-1.211 7.721-3.558 10.3704-2.346 2.6493-5.298 4.0119-9.007 4.0119h-31.112v-9.4621zM159.113 52.8356h25.51c2.271 0 3.936-.3784 4.92-1.0597 1.06-.6813 1.59-1.8167 1.59-3.4063 0-1.5897-.53-2.7251-1.59-3.4064-1.059-.7569-2.725-1.1354-4.92-1.1354h-10.446c-6.207 0-10.37-.9841-12.566-2.8765-2.195-1.8924-3.255-5.2987-3.255-10.0676 0-4.9202 1.287-8.5536 3.937-10.9002 2.649-2.3466 6.737-3.482 12.187-3.482h25.964v9.5377h-21.347c-3.482 0-5.753.3028-6.812.9083-1.06.6056-1.59 1.6654-1.59 3.255 0 1.4382.454 2.498 1.362 3.1035.909.6813 2.423.9841 4.391.9841h10.976c4.996 0 8.856 1.2111 11.43 3.5577 2.649 2.3466 3.936 5.6772 3.936 10.0676 0 4.239-1.211 7.721-3.558 10.3704-2.346 2.6493-5.298 4.0119-9.007 4.0119h-31.263v-9.4621h.151zM223.607 0v16.5775h10.37c4.617 0 8.251.5298 11.052 1.6653 2.8 1.0597 5.147 2.8764 7.115 5.3744 1.665 2.1195 2.876 4.3904 3.709 6.9641.833 2.4979 1.211 5.2987 1.211 8.3265 0 7.3426-1.968 13.0955-5.904 17.2588-3.936 4.1633-9.386 6.2071-16.426 6.2071h-23.315V0h12.188zm7.342 26.4937h-7.418v26.1152h8.326c4.618 0 7.873-.9841 9.69-2.8765 1.892-1.9681 2.8-5.223 2.8-9.9162 0-4.7689-1.059-8.1752-3.103-10.219-1.968-2.1195-5.45-3.1035-10.295-3.1035zM274.172 39.5132c0 4.3904.984 7.721 3.027 10.219 2.044 2.4223 4.845 3.6334 8.554 3.6334 3.633 0 6.434-1.2111 8.554-3.6334 2.044-2.4223 3.103-5.8286 3.103-10.219s-1.059-7.721-3.103-10.1433c-2.044-2.4222-4.845-3.6334-8.554-3.6334-3.633 0-6.434 1.2112-8.554 3.6334-2.043 2.4223-3.027 5.8286-3.027 10.1433zm35.88 0c0 7.1912-2.196 12.9441-6.586 17.2588-4.39 4.2389-10.219 6.4341-17.637 6.4341-7.418 0-13.323-2.1195-17.713-6.4341-4.391-4.3147-6.586-9.9919-6.586-17.1831 0-7.1911 2.195-12.944 6.586-17.2587 4.39-4.3147 10.295-6.5099 17.713-6.5099 7.342 0 13.247 2.1952 17.637 6.5099 4.39 4.239 6.586 9.9919 6.586 17.183zM329.884 62.3737h-12.565V0h12.565v62.3737zM335.712 16.5775h8.554V0h12.111v16.5775h12.793v9.1592h-12.793v18.4699c0 3.4063.606 5.7529 1.742 7.1154 1.135 1.2869 3.179 1.9681 6.055 1.9681h4.996v9.1593h-11.127c-4.466 0-7.873-1.2112-10.295-3.7091-2.346-2.498-3.558-6.0557-3.558-10.6732V25.7367h-8.553v-9.1592h.075z" fill="var(--icon-color)"></path>
|
|
28
|
+
<path d="M446.532 30.884L419.433 5.52579c-2.347-2.19519-6.056-2.19519-8.478 0L393.923 21.4977c4.466 1.6653 7.948 5.3744 9.235 9.9919h23.012c1.211 0 2.119.984 2.119 2.1195v3.482c0 1.2111-.984 2.1195-2.119 2.1195h-2.649v4.9202c0 1.2112-.985 2.1195-2.12 2.1195h-5.829c-1.211 0-2.119-.984-2.119-2.1195v-4.9202h-10.219c-1.287 4.6932-4.769 8.478-9.311 10.0676l17.108 15.9719c2.346 2.1952 6.055 2.1952 8.478 0l27.023-25.3582c2.574-2.4223 2.574-6.5099 0-9.0079z" fill="#E10600"></path>
|
|
29
|
+
<path d="M388.927 28.3862c-1.135 0-2.195.3028-3.179.757-2.271 1.1354-3.86 3.482-3.86 6.2071 0 2.6493 1.438 4.9202 3.633 6.1314.984.5298 2.12.8326 3.331.8326 3.86 0 6.964-3.1035 6.964-6.964.151-3.7848-3.028-6.9641-6.889-6.9641z" fill="#E10600"></path>
|
|
30
|
+
</g>
|
|
31
|
+
<defs>
|
|
32
|
+
<clipPath id="clip0">
|
|
33
|
+
<path fill="#fff" d="M0 0h448.5v78.9511H0z"></path>
|
|
34
|
+
</clipPath>
|
|
35
|
+
</defs>
|
|
36
|
+
</svg>
|
|
25
37
|
<h1><span>Passbolt</span></h1>
|
|
26
38
|
</div>
|
|
27
39
|
</div>
|
|
@@ -31,13 +31,15 @@ import {SecretGenerator} from "../../../../shared/lib/SecretGenerator/SecretGene
|
|
|
31
31
|
import {withResourcePasswordGeneratorContext} from "../../../contexts/ResourcePasswordGeneratorContext";
|
|
32
32
|
import Password from "../../../../shared/components/Password/Password";
|
|
33
33
|
import PasswordComplexity from "../../../../shared/components/PasswordComplexity/PasswordComplexity";
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
34
|
+
import {maxSizeValidation} from "../../../lib/Error/InputValidator";
|
|
35
|
+
import {
|
|
36
|
+
RESOURCE_NAME_MAX_LENGTH,
|
|
37
|
+
RESOURCE_PASSWORD_MAX_LENGTH,
|
|
38
|
+
RESOURCE_URI_MAX_LENGTH,
|
|
39
|
+
RESOURCE_DESCRIPTION_MAX_LENGTH,
|
|
40
|
+
} from "../../../../shared/constants/inputs.const";
|
|
41
|
+
import debounce from "debounce-promise";
|
|
42
|
+
import PownedService from "../../../../shared/services/api/secrets/pownedService";
|
|
41
43
|
|
|
42
44
|
class CreateResource extends Component {
|
|
43
45
|
constructor() {
|
|
@@ -45,16 +47,21 @@ class CreateResource extends Component {
|
|
|
45
47
|
this.state = this.getDefaultState();
|
|
46
48
|
this.initEventHandlers();
|
|
47
49
|
this.createInputRef();
|
|
50
|
+
this.isPwndProcessingPromise = null;
|
|
51
|
+
this.evaluatePasswordIsInDictionaryDebounce = debounce(this.evaluatePasswordIsInDictionaryDebounce, 300);
|
|
48
52
|
}
|
|
49
53
|
|
|
50
54
|
getDefaultState() {
|
|
51
55
|
return {
|
|
52
56
|
name: "",
|
|
53
57
|
nameError: "",
|
|
58
|
+
nameWarning: "",
|
|
54
59
|
username: "",
|
|
55
60
|
usernameError: "",
|
|
61
|
+
usernameWarning: "",
|
|
56
62
|
uri: "",
|
|
57
63
|
uriError: "",
|
|
64
|
+
uriWarning: "",
|
|
58
65
|
password: "",
|
|
59
66
|
passwordError: "",
|
|
60
67
|
passwordWarning: "",
|
|
@@ -62,7 +69,9 @@ class CreateResource extends Component {
|
|
|
62
69
|
descriptionError: "",
|
|
63
70
|
descriptionWarning: "",
|
|
64
71
|
encryptDescription: false,
|
|
65
|
-
hasAlreadyBeenValidated: false // True if the form has already been submitted once
|
|
72
|
+
hasAlreadyBeenValidated: false, // True if the form has already been submitted once
|
|
73
|
+
isPwnedServiceAvailable: true,
|
|
74
|
+
passwordInDictionary: false
|
|
66
75
|
};
|
|
67
76
|
}
|
|
68
77
|
|
|
@@ -75,6 +84,8 @@ class CreateResource extends Component {
|
|
|
75
84
|
this.handleGeneratePasswordButtonClick = this.handleGeneratePasswordButtonClick.bind(this);
|
|
76
85
|
this.handleDescriptionToggle = this.handleDescriptionToggle.bind(this);
|
|
77
86
|
this.handleDescriptionInputKeyUp = this.handleDescriptionInputKeyUp.bind(this);
|
|
87
|
+
this.handleUriInputKeyUp = this.handleUriInputKeyUp.bind(this);
|
|
88
|
+
this.handleUsernameInputKeyUp = this.handleUsernameInputKeyUp.bind(this);
|
|
78
89
|
this.handleOpenGenerator = this.handleOpenGenerator.bind(this);
|
|
79
90
|
this.handleLastGeneratedPasswordChanged = this.handleLastGeneratedPasswordChanged.bind(this);
|
|
80
91
|
}
|
|
@@ -91,6 +102,7 @@ class CreateResource extends Component {
|
|
|
91
102
|
* Whenever the component has been mounted
|
|
92
103
|
*/
|
|
93
104
|
componentDidMount() {
|
|
105
|
+
this.pownedService = new PownedService(this.props.context.port);
|
|
94
106
|
if (this.isEncryptedDescriptionEnabled()) {
|
|
95
107
|
this.setState({encryptDescription: true});
|
|
96
108
|
}
|
|
@@ -101,7 +113,9 @@ class CreateResource extends Component {
|
|
|
101
113
|
* @param prevProps The previous component props
|
|
102
114
|
*/
|
|
103
115
|
componentDidUpdate(prevProps) {
|
|
104
|
-
this.handleLastGeneratedPasswordChanged(
|
|
116
|
+
this.handleLastGeneratedPasswordChanged(
|
|
117
|
+
prevProps.resourcePasswordGeneratorContext.lastGeneratedPassword
|
|
118
|
+
);
|
|
105
119
|
}
|
|
106
120
|
|
|
107
121
|
/*
|
|
@@ -111,7 +125,9 @@ class CreateResource extends Component {
|
|
|
111
125
|
*/
|
|
112
126
|
get currentGeneratorConfiguration() {
|
|
113
127
|
const type = this.props.resourcePasswordGeneratorContext.settings.default_generator;
|
|
114
|
-
return this.props.resourcePasswordGeneratorContext.settings.generators.find(
|
|
128
|
+
return this.props.resourcePasswordGeneratorContext.settings.generators.find(
|
|
129
|
+
generator => generator.type === type
|
|
130
|
+
);
|
|
115
131
|
}
|
|
116
132
|
|
|
117
133
|
/**
|
|
@@ -155,7 +171,6 @@ class CreateResource extends Component {
|
|
|
155
171
|
*/
|
|
156
172
|
async handleFormSubmit(event) {
|
|
157
173
|
event.preventDefault();
|
|
158
|
-
|
|
159
174
|
if (this.state.processing) {
|
|
160
175
|
return;
|
|
161
176
|
}
|
|
@@ -205,7 +220,7 @@ class CreateResource extends Component {
|
|
|
205
220
|
uriError: "",
|
|
206
221
|
usernameError: "",
|
|
207
222
|
passwordError: "",
|
|
208
|
-
descriptionError: ""
|
|
223
|
+
descriptionError: "",
|
|
209
224
|
});
|
|
210
225
|
|
|
211
226
|
// Validate the form inputs.
|
|
@@ -249,6 +264,17 @@ class CreateResource extends Component {
|
|
|
249
264
|
});
|
|
250
265
|
}
|
|
251
266
|
|
|
267
|
+
/**
|
|
268
|
+
* Evaluate to check if password is in a dictionary.
|
|
269
|
+
* @return {Promise}
|
|
270
|
+
*/
|
|
271
|
+
async evaluatePasswordIsInDictionaryDebounce() {
|
|
272
|
+
if (this.state.isPwnedServiceAvailable) {
|
|
273
|
+
const result = await this.pownedService.evaluateSecret(this.state.password);
|
|
274
|
+
this.setState({isPwnedServiceAvailable: result.isPwnedServiceAvailable, passwordInDictionary: result.inDictionary});
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
252
278
|
/*
|
|
253
279
|
* =============================================================
|
|
254
280
|
* Create resource
|
|
@@ -263,7 +289,7 @@ class CreateResource extends Component {
|
|
|
263
289
|
name: this.state.name,
|
|
264
290
|
username: this.state.username,
|
|
265
291
|
uri: this.state.uri,
|
|
266
|
-
folder_parent_id: this.props.context.resourceCreateDialogProps.folderParentId
|
|
292
|
+
folder_parent_id: this.props.context.resourceCreateDialogProps.folderParentId,
|
|
267
293
|
};
|
|
268
294
|
|
|
269
295
|
// No resource types, legacy case
|
|
@@ -369,7 +395,7 @@ class CreateResource extends Component {
|
|
|
369
395
|
*/
|
|
370
396
|
handleError(error) {
|
|
371
397
|
const errorDialogProps = {
|
|
372
|
-
error: error
|
|
398
|
+
error: error,
|
|
373
399
|
};
|
|
374
400
|
this.props.dialogContext.open(NotifyError, errorDialogProps);
|
|
375
401
|
}
|
|
@@ -420,8 +446,14 @@ class CreateResource extends Component {
|
|
|
420
446
|
const target = event.target;
|
|
421
447
|
const value = target.value;
|
|
422
448
|
const name = target.name;
|
|
449
|
+
|
|
450
|
+
if (name === "password") {
|
|
451
|
+
if (value.length) {
|
|
452
|
+
this.isPwndProcessingPromise = this.evaluatePasswordIsInDictionaryDebounce();
|
|
453
|
+
}
|
|
454
|
+
}
|
|
423
455
|
this.setState({
|
|
424
|
-
[name]: value
|
|
456
|
+
[name]: value,
|
|
425
457
|
});
|
|
426
458
|
}
|
|
427
459
|
|
|
@@ -432,6 +464,9 @@ class CreateResource extends Component {
|
|
|
432
464
|
if (this.state.hasAlreadyBeenValidated) {
|
|
433
465
|
const state = this.validateNameInput();
|
|
434
466
|
this.setState(state);
|
|
467
|
+
} else {
|
|
468
|
+
const nameWarning = maxSizeValidation(this.state.name, RESOURCE_NAME_MAX_LENGTH, this.translate);
|
|
469
|
+
this.setState({nameWarning});
|
|
435
470
|
}
|
|
436
471
|
}
|
|
437
472
|
|
|
@@ -443,9 +478,7 @@ class CreateResource extends Component {
|
|
|
443
478
|
const state = this.validatePasswordInput();
|
|
444
479
|
this.setState(state);
|
|
445
480
|
} else {
|
|
446
|
-
const
|
|
447
|
-
const warningMessage = this.translate("this is the maximum size for this field, make sure your data was not truncated");
|
|
448
|
-
const passwordWarning = hasResourcePasswordMaxLength ? warningMessage : '';
|
|
481
|
+
const passwordWarning = maxSizeValidation(this.state.password, RESOURCE_PASSWORD_MAX_LENGTH, this.translate);
|
|
449
482
|
this.setState({passwordWarning});
|
|
450
483
|
}
|
|
451
484
|
}
|
|
@@ -459,9 +492,10 @@ class CreateResource extends Component {
|
|
|
459
492
|
}
|
|
460
493
|
|
|
461
494
|
const password = SecretGenerator.generate(this.currentGeneratorConfiguration);
|
|
495
|
+
|
|
462
496
|
this.setState({
|
|
463
497
|
password: password,
|
|
464
|
-
passwordError: ""
|
|
498
|
+
passwordError: "",
|
|
465
499
|
});
|
|
466
500
|
}
|
|
467
501
|
|
|
@@ -498,20 +532,37 @@ class CreateResource extends Component {
|
|
|
498
532
|
*/
|
|
499
533
|
handleDescriptionInputKeyUp() {
|
|
500
534
|
if (!this.state.hasAlreadyBeenValidated) {
|
|
501
|
-
const
|
|
502
|
-
|
|
503
|
-
const warningMessage = this.translate("this is the maximum size for this field, make sure your data was not truncated");
|
|
504
|
-
const descriptionWarning = hasResourceDescriptionMaxLength ? warningMessage : '';
|
|
535
|
+
const descriptionWarning = maxSizeValidation(this.state.description, RESOURCE_DESCRIPTION_MAX_LENGTH, this.translate);
|
|
505
536
|
this.setState({descriptionWarning});
|
|
506
537
|
}
|
|
507
538
|
}
|
|
508
539
|
|
|
540
|
+
/**
|
|
541
|
+
* Whenever the user input keys in the name area
|
|
542
|
+
*/
|
|
543
|
+
handleUriInputKeyUp() {
|
|
544
|
+
if (!this.state.hasAlreadyBeenValidated) {
|
|
545
|
+
const uriWarning = maxSizeValidation(this.state.uri, RESOURCE_URI_MAX_LENGTH, this.translate);
|
|
546
|
+
this.setState({uriWarning});
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
/**
|
|
551
|
+
* Whenever the user input keys in the username area
|
|
552
|
+
*/
|
|
553
|
+
handleUsernameInputKeyUp() {
|
|
554
|
+
if (!this.state.hasAlreadyBeenValidated) {
|
|
555
|
+
const usernameWarning = maxSizeValidation(this.state.username, RESOURCE_NAME_MAX_LENGTH, this.translate);
|
|
556
|
+
this.setState({usernameWarning});
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
|
|
509
560
|
/**
|
|
510
561
|
* Returns true if the logged in user can use the password generator capability.
|
|
511
562
|
* @returns {boolean}
|
|
512
563
|
*/
|
|
513
564
|
get canUsePasswordGenerator() {
|
|
514
|
-
return this.props.context.siteSettings.canIUse(
|
|
565
|
+
return this.props.context.siteSettings.canIUse("passwordGenerator");
|
|
515
566
|
}
|
|
516
567
|
|
|
517
568
|
/**
|
|
@@ -536,7 +587,7 @@ class CreateResource extends Component {
|
|
|
536
587
|
<form onSubmit={this.handleFormSubmit} noValidate>
|
|
537
588
|
<div className="form-content">
|
|
538
589
|
<div className={`input text required ${this.state.nameError ? "error" : ""} ${this.state.processing ? 'disabled' : ''}`}>
|
|
539
|
-
<label htmlFor="create-password-form-name"><Trans>Name</Trans
|
|
590
|
+
<label htmlFor="create-password-form-name"><Trans>Name</Trans>{this.state.nameWarning && <Icon name="exclamation" />}</label>
|
|
540
591
|
<input id="create-password-form-name" name="name" type="text" value={this.state.name}
|
|
541
592
|
onKeyUp={this.handleNameInputKeyUp} onChange={this.handleInputChange}
|
|
542
593
|
disabled={this.state.processing} ref={this.nameInputRef} className="required fluid" maxLength="255"
|
|
@@ -544,29 +595,44 @@ class CreateResource extends Component {
|
|
|
544
595
|
{this.state.nameError &&
|
|
545
596
|
<div className="name error-message">{this.state.nameError}</div>
|
|
546
597
|
}
|
|
598
|
+
{this.state.nameWarning && (
|
|
599
|
+
<div className="name warning-message">
|
|
600
|
+
<strong><Trans>Warning:</Trans></strong> {this.state.nameWarning}
|
|
601
|
+
</div>
|
|
602
|
+
)}
|
|
547
603
|
</div>
|
|
548
604
|
<div className={`input text ${this.state.uriError ? "error" : ""} ${this.state.processing ? 'disabled' : ''}`}>
|
|
549
|
-
<label htmlFor="create-password-form-uri"><Trans>URI</Trans
|
|
550
|
-
<input id="create-password-form-uri" name="uri" className="fluid" maxLength="1024" type="text"
|
|
605
|
+
<label htmlFor="create-password-form-uri"><Trans>URI</Trans>{this.state.uriWarning && <Icon name="exclamation" />}</label>
|
|
606
|
+
<input id="create-password-form-uri" name="uri" className="fluid" maxLength="1024" type="text" onKeyUp={this.handleUriInputKeyUp}
|
|
551
607
|
autoComplete="off" value={this.state.uri} onChange={this.handleInputChange} placeholder={this.translate("URI")}
|
|
552
608
|
disabled={this.state.processing}/>
|
|
553
609
|
{this.state.uriError &&
|
|
554
610
|
<div className="error-message">{this.state.uriError}</div>
|
|
555
611
|
}
|
|
612
|
+
{this.state.uriWarning && (
|
|
613
|
+
<div className="uri warning-message">
|
|
614
|
+
<strong><Trans>Warning:</Trans></strong> {this.state.uriWarning}
|
|
615
|
+
</div>
|
|
616
|
+
)}
|
|
556
617
|
</div>
|
|
557
618
|
<div className={`input text ${this.state.usernameError ? "error" : ""} ${this.state.processing ? 'disabled' : ''}`}>
|
|
558
|
-
<label htmlFor="create-password-form-username"><Trans>Username</Trans
|
|
559
|
-
<input id="create-password-form-username" name="username" type="text" className="fluid" maxLength="255"
|
|
619
|
+
<label htmlFor="create-password-form-username"><Trans>Username</Trans>{this.state.usernameWarning && <Icon name="exclamation" />}</label>
|
|
620
|
+
<input id="create-password-form-username" name="username" type="text" className="fluid" maxLength="255" onKeyUp={this.handleUsernameInputKeyUp}
|
|
560
621
|
autoComplete="off" value={this.state.username} onChange={this.handleInputChange} placeholder={this.translate("Username")}
|
|
561
622
|
disabled={this.state.processing}/>
|
|
562
623
|
{this.state.usernameError &&
|
|
563
624
|
<div className="error-message">{this.state.usernameError}</div>
|
|
564
625
|
}
|
|
626
|
+
{this.state.usernameWarning && (
|
|
627
|
+
<div className="username warning-message">
|
|
628
|
+
<strong><Trans>Warning:</Trans></strong> {this.state.usernameWarning}
|
|
629
|
+
</div>
|
|
630
|
+
)}
|
|
565
631
|
</div>
|
|
566
632
|
<div className={`input-password-wrapper input required ${this.state.passwordError ? "error" : ""} ${this.state.processing ? 'disabled' : ''}`}>
|
|
567
633
|
<label htmlFor="create-password-form-password">
|
|
568
634
|
<Trans>Password</Trans>
|
|
569
|
-
{this.state.passwordWarning &&
|
|
635
|
+
{(this.state.passwordWarning || this.state.passwordInDictionary || !this.state.isPwnedServiceAvailable) &&
|
|
570
636
|
<Icon name="exclamation"/>
|
|
571
637
|
}
|
|
572
638
|
</label>
|
|
@@ -601,6 +667,12 @@ class CreateResource extends Component {
|
|
|
601
667
|
{this.state.passwordWarning &&
|
|
602
668
|
<div className="password warning-message"><strong><Trans>Warning:</Trans></strong> {this.state.passwordWarning}</div>
|
|
603
669
|
}
|
|
670
|
+
{!this.state.isPwnedServiceAvailable &&
|
|
671
|
+
<div className="pwned-password warning-message"><Trans>The pwnedpasswords service is unavailable, your password might be part of an exposed data breach</Trans></div>
|
|
672
|
+
}
|
|
673
|
+
{this.state.passwordInDictionary &&
|
|
674
|
+
<div className="pwned-password warning-message"><Trans>The password is part of an exposed data breach.</Trans></div>
|
|
675
|
+
}
|
|
604
676
|
</div>
|
|
605
677
|
<div className={`input textarea ${this.state.processing ? 'disabled' : ''}`}>
|
|
606
678
|
<label htmlFor="create-password-form-description"><Trans>Description</Trans>
|
|
@@ -660,3 +732,4 @@ CreateResource.propTypes = {
|
|
|
660
732
|
};
|
|
661
733
|
|
|
662
734
|
export default withResourcePasswordGeneratorContext(withAppContext(withActionFeedback(withRouter(withDialog(withTranslation('common')(CreateResource))))));
|
|
735
|
+
|