passbolt-styleguide 3.3.3 → 3.4.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 +4 -4
- package/build/css/public.min.css +5 -6
- package/build/css/themes/default/api_authentication.min.css +3 -3
- package/build/css/themes/default/api_cloud.min.css +3 -7
- package/build/css/themes/default/api_main.min.css +4 -9
- package/build/css/themes/default/api_reports.min.css +4 -9
- package/build/css/themes/default/api_webinstaller.min.css +4 -9
- package/build/css/themes/default/ext_app.min.css +4 -9
- package/build/css/themes/default/ext_authentication.min.css +3 -3
- package/build/css/themes/default/ext_external.min.css +3 -3
- package/build/css/themes/default/ext_in_form_cta.min.css +9 -0
- package/build/css/themes/default/ext_in_form_menu.min.css +9 -0
- package/build/css/themes/default/ext_quickaccess.min.css +3 -3
- package/build/css/themes/midgar/api_authentication.min.css +9 -0
- package/build/css/themes/midgar/api_main.min.css +4 -9
- package/build/css/themes/midgar/api_reports.min.css +4 -9
- package/build/css/themes/midgar/ext_app.min.css +4 -9
- package/build/css/themes/midgar/ext_authentication.min.css +3 -3
- package/build/css/themes/midgar/ext_in_form_cta.min.css +9 -0
- package/build/css/themes/midgar/ext_in_form_menu.min.css +9 -0
- package/build/css/themes/midgar/ext_quickaccess.min.css +3 -3
- package/build/js/dist/api-app.js +1 -1
- package/build/js/dist/api-app.js.LICENSE.txt +5 -5
- package/build/js/dist/api-recover.js +1 -1
- package/build/js/dist/api-recover.js.LICENSE.txt +0 -28
- package/build/js/dist/api-setup.js +1 -1
- package/build/js/dist/api-setup.js.LICENSE.txt +0 -15
- package/build/js/dist/api-triage.js +1 -1
- package/build/js/dist/api-triage.js.LICENSE.txt +0 -14
- package/build/js/dist/api-vendors.js +1 -1
- package/build/js/dist/api-vendors.js.LICENSE.txt +146 -84
- package/package.json +31 -26
- package/src/img/controls/chevron-down_blue.svg +3 -0
- package/src/img/diagrams/functional_overview.png +0 -0
- package/src/img/diagrams/functional_overview.svg +4 -0
- package/src/img/diagrams/howitworks.svg +2797 -0
- package/src/img/diagrams/mobile-transfer.svg +296 -0
- package/src/img/diagrams/sequence_diagram_form_authenticate.png +0 -0
- package/src/img/diagrams/sequence_diagram_gpg_authenticate.png +0 -0
- package/src/img/diagrams/totp.svg +251 -0
- package/src/img/illustrations/pin_passbolt.gif +0 -0
- package/src/img/illustrations/wave-pin_my_extension.svg +1 -0
- package/src/img/logo/icon-32-badge-1.png +0 -0
- package/src/img/logo/icon-32-badge-2.png +0 -0
- package/src/img/logo/icon-32-badge-3.png +0 -0
- package/src/img/logo/icon-32-badge-4.png +0 -0
- package/src/img/logo/icon-32-badge-5+.png +0 -0
- package/src/img/logo/icon-32-badge-5.png +0 -0
- package/src/img/logo/icon-32-signout.png +0 -0
- package/src/img/logo/icon-badge-1.svg +1 -0
- package/src/img/logo/icon-badge-2.svg +1 -0
- package/src/img/logo/icon-badge-3.svg +1 -0
- package/src/img/logo/icon-badge-4.svg +1 -0
- package/src/img/logo/icon-badge-5+.svg +1 -0
- package/src/img/logo/icon-badge-5.svg +1 -0
- package/src/img/logo/icon-inactive.svg +1 -0
- package/src/img/logo/icon-without-badge.svg +1 -0
- package/src/img/third_party/ChromeWebStore_black.svg +1 -0
- package/src/img/third_party/ChromeWebStore_white.svg +1 -0
- package/src/img/third_party/edge-addon-black.svg +1 -0
- package/src/img/third_party/edge-addon-white.svg +1 -0
- package/src/locales/de-DE/common.json +820 -0
- package/src/locales/en-UK/common.json +86 -20
- package/src/locales/fr/common.json +750 -0
- package/src/locales/fr-FR/common.json +92 -22
- package/src/locales/sv-SE/common.json +820 -0
- package/src/react-extension/ExtApp.js +16 -10
- package/src/react-extension/ExtBootstrapApp.js +1 -0
- package/src/react-extension/components/Administration/DisplayAdministrationMenu/DisplayAdministrationMenu.js +2 -2
- package/src/react-extension/components/Administration/DisplayAdministrationMenu/DisplayAdministrationMenu.test.js +2 -2
- package/src/react-extension/components/Administration/DisplayAdministrationWorkspaceBreadcrumb/DisplayAdministrationWorkspaceBreadcrumb.js +1 -1
- package/src/react-extension/components/Administration/DisplayAdministrationWorkspaceBreadcrumb/DisplayAdministrationWorkspaceBreadcrumb.test.js +1 -1
- package/src/react-extension/components/Administration/DisplayEmailNotificationsAdministration/DisplayEmailNotificationsAdministration.js +22 -8
- package/src/react-extension/components/Administration/DisplayEmailNotificationsAdministration/DisplayEmailNotificationsAdministration.test.data.js +3 -0
- package/src/react-extension/components/Administration/DisplayInternationalizationAdministration/DisplayInternationalizationAdministration.js +10 -8
- package/src/react-extension/components/Administration/DisplayMfaAdministration/DisplayMfaAdministration.js +21 -19
- package/src/react-extension/components/Administration/DisplayMfaAdministration/DisplayMfaAdministration.test.page.js +6 -6
- package/src/react-extension/components/Administration/DisplayMfaAdministration/DisplayMfaAdministration.test.stories.js +0 -1
- package/src/react-extension/components/Administration/DisplaySimulateSynchronizeUserDirectoryAdministration/DisplaySimulateSynchronizeUserDirectoryAdministration.js +1 -1
- package/src/react-extension/components/Administration/DisplaySimulateSynchronizeUserDirectoryAdministration/DisplaySimulateSynchronizeUserDirectoryAdministration.test.js +1 -1
- package/src/react-extension/components/Administration/DisplaySimulateSynchronizeUserDirectoryAdministration/DisplaySimulateSynchronizeUserDirectoryAdministration.test.stories.js +5 -8
- package/src/react-extension/components/Administration/DisplaySubscriptionKey/DisplaySubscriptionKey.js +20 -38
- package/src/react-extension/components/Administration/DisplaySubscriptionKey/DisplaySubscriptionKey.test.data.js +4 -1
- package/src/react-extension/components/Administration/DisplaySubscriptionKey/DisplaySubscriptionKey.test.js +4 -4
- package/src/react-extension/components/Administration/DisplaySynchronizeUserDirectoryAdministration/DisplaySynchronizeUserDirectoryAdministration.js +1 -1
- package/src/react-extension/components/Administration/DisplaySynchronizeUserDirectoryAdministration/DisplaySynchronizeUserDirectoryAdministration.test.js +1 -1
- package/src/react-extension/components/Administration/DisplayTestUserDirectoryAdministration/DisplayTestUserDirectoryAdministration.test.js +2 -3
- package/src/react-extension/components/Administration/DisplayTestUserDirectoryAdministration/DisplayTestUserDirectoryAdministration.test.stories.js +5 -9
- package/src/react-extension/components/Administration/DisplayUserDirectoryAdministration/DisplayUserDirectoryAdministration.js +34 -32
- package/src/react-extension/components/Administration/DisplayUserDirectoryAdministration/DisplayUserDirectoryAdministration.test.js +1 -1
- package/src/react-extension/components/Administration/DisplayUserDirectoryAdministration/DisplayUserDirectoryAdministration.test.stories.js +0 -3
- package/src/react-extension/components/Administration/EditSubscriptionKey/EditSubscriptionKey.js +1 -1
- package/src/react-extension/components/Administration/EditSubscriptionKey/EditSubscriptionKey.test.page.js +2 -2
- package/src/react-extension/components/Authentication/AskForAuthenticationHelp/AskForAuthenticationHelp.js +1 -1
- package/src/react-extension/components/Authentication/AskForAuthenticationHelp/AskForAuthenticationHelp.test.stories.js +12 -15
- package/src/react-extension/components/Authentication/CheckMailBox/CheckMailBox.js +2 -2
- package/src/react-extension/components/Authentication/CheckMailBox/CheckMailBox.test.js +1 -1
- package/src/react-extension/components/Authentication/CheckMailBox/CheckMailbox.test.stories.js +12 -14
- package/src/react-extension/components/Authentication/CheckPassphrase/CheckPassphrase.js +2 -1
- package/src/react-extension/components/Authentication/CheckPassphrase/CheckPassphrase.test.stories.js +12 -15
- package/src/react-extension/components/Authentication/ChooseSecurityToken/ChooseSecurityToken.js +1 -2
- package/src/react-extension/components/Authentication/ChooseSecurityToken/ChooseSecurityToken.test.stories.js +12 -15
- package/src/react-extension/components/Authentication/CreateGpgKey/CreateGpgKey.js +9 -19
- package/src/react-extension/components/Authentication/CreateGpgKey/CreateGpgKey.test.stories.js +12 -15
- package/src/react-extension/components/Authentication/DisplayBrowserNotSupported/DisplayBrowserNotSupported.test.stories.js +12 -15
- package/src/react-extension/components/Authentication/DisplayExpiredTokenError/DisplayExpiredTokenError.test.stories.js +12 -15
- package/src/react-extension/components/Authentication/DisplayRequireInvitationError/DisplayRequireInvitationError.test.stories.js +12 -15
- package/src/react-extension/components/Authentication/DisplayUnexpectedError/DisplayUnexpectedError.test.stories.js +12 -15
- package/src/react-extension/components/Authentication/DownloadRecoveryKit/DownloadRecoveryKit.js +1 -1
- package/src/react-extension/components/Authentication/DownloadRecoveryKit/DownloadRecoveryKit.test.stories.js +12 -15
- package/src/react-extension/components/Authentication/EnterNameForm/EnterNameForm.test.stories.js +12 -15
- package/src/react-extension/components/Authentication/EnterUsernameForm/EnterUsernameForm.test.stories.js +12 -15
- package/src/react-extension/components/Authentication/HandleSessionExpired/HandleSessionExpired.test.data.js +14 -0
- package/src/react-extension/components/Authentication/HandleSessionExpired/HandleSessionExpired.test.js +65 -0
- package/src/react-extension/components/Authentication/HandleSessionExpired/HandleSessionExpired.test.page.js +38 -0
- package/src/react-extension/components/Authentication/ImportGpgKey/ImportGpgKey.test.stories.js +12 -15
- package/src/react-extension/components/Authentication/InstallExtension/InstallExtension.js +15 -6
- package/src/react-extension/components/Authentication/InstallExtension/InstallExtension.test.js +27 -0
- package/src/react-extension/components/Authentication/InstallExtension/InstallExtension.test.stories.js +12 -15
- package/src/react-extension/components/Authentication/IntroduceSetupExtension/IntroduceSetupExtension.js +107 -0
- package/src/react-extension/components/Authentication/IntroduceSetupExtension/IntroduceSetupExtension.test.data.js +11 -0
- package/src/react-extension/components/Authentication/IntroduceSetupExtension/IntroduceSetupExtension.test.js +65 -0
- package/src/react-extension/components/Authentication/IntroduceSetupExtension/IntroduceSetupExtension.test.page.js +73 -0
- package/src/react-extension/components/Authentication/IntroduceSetupExtension/IntroduceSetupExtension.test.stories.js +34 -0
- package/src/react-extension/components/Authentication/NotifyExpiredSession/NotifyExpiredSession.test.stories.js +8 -11
- package/src/react-extension/components/AuthenticationLogin/AcceptLoginServerKeyChange/AcceptLoginServerKeyChange.js +1 -1
- package/src/react-extension/components/AuthenticationLogin/AcceptLoginServerKeyChange/AcceptLoginServerKeyChange.test.stories.js +12 -15
- package/src/react-extension/components/AuthenticationLogin/DisplayLoginError/DisplayLoginError.test.stories.js +12 -15
- package/src/react-extension/components/AuthenticationLogin/DisplayLoginInProgress/DisplayLoginProgress.test.stories.js +12 -15
- package/src/react-extension/components/AuthenticationLogin/Login/Login.js +3 -1
- package/src/react-extension/components/AuthenticationLogin/Login/Login.test.stories.js +12 -15
- package/src/react-extension/components/AuthenticationPassphrase/InputPassphrase/InputPassphrase.js +2 -1
- package/src/react-extension/components/AuthenticationPassphrase/InputPassphrase/InputPassphrase.test.js +1 -1
- package/src/react-extension/components/AuthenticationPassphrase/InputPassphrase/InputPassphrase.test.stories.js +5 -11
- package/src/react-extension/components/AuthenticationRecover/RecoverAuthentication/RecoverAuthentication.js +5 -1
- package/src/react-extension/components/AuthenticationSetup/SetupAuthentication/SetupAuthentication.js +4 -0
- package/src/react-extension/components/Common/ActionFeedback/DisplayActionFeedbacks.test.data.js +0 -2
- package/src/react-extension/components/Common/ActionFeedback/DisplayActionFeedbacks.test.js +4 -5
- package/src/react-extension/components/Common/ActionFeedback/DisplayActionFeedbacks.test.page.js +0 -1
- package/src/react-extension/components/Common/Avatar/UserAvatar.js +2 -1
- package/src/react-extension/components/Common/Error/ShowErrorDetails/ShowErrorDetails.js +126 -0
- package/src/react-extension/components/Common/Icons/AnimatedFeedback.js +58 -0
- package/src/react-extension/components/Common/Icons/Icon.js +16 -0
- package/src/react-extension/components/Common/Icons/Icon.test.stories.js +78 -0
- package/src/react-extension/components/Common/Inputs/FormSubmitButton/FormSubmitButton.js +4 -0
- package/src/react-extension/components/Common/Loading/LoadingSpinner/LoadingSpinner.js +2 -1
- package/src/react-extension/components/Common/Menu/DisplayMainMenu.js +2 -4
- package/src/react-extension/components/Common/Navigation/Search/SearchBar.js +1 -1
- package/src/react-extension/components/Common/Progress/DisplayProgress/DisplayProgress.js +1 -1
- package/src/react-extension/components/Common/Progress/DisplayProgress/DisplayProgress.test.js +1 -1
- package/src/react-extension/components/Common/Progress/DisplayProgress/DisplayProgress.test.stories.js +34 -0
- package/src/react-extension/components/Common/Tab/Tab.js +65 -0
- package/src/react-extension/components/Common/Tab/Tabs.js +87 -0
- package/src/react-extension/components/Resource/CreateResource/CreateResource.js +85 -66
- package/src/react-extension/components/Resource/CreateResource/CreateResource.test.data.js +80 -1
- package/src/react-extension/components/Resource/CreateResource/CreateResource.test.js +18 -39
- package/src/react-extension/components/Resource/CreateResource/CreateResource.test.page.js +27 -8
- package/src/react-extension/components/Resource/CreateResource/CreateResource.test.stories.js +70 -4
- package/src/react-extension/components/Resource/DeleteResource/DeleteResource.js +1 -1
- package/src/react-extension/components/Resource/DisplayResourcesList/DisplayDragResource.js +68 -0
- package/src/react-extension/components/Resource/DisplayResourcesList/DisplayResourcesList.js +20 -47
- package/src/react-extension/components/Resource/DisplayResourcesList/DisplayResourcesList.test.page.js +4 -1
- package/src/react-extension/components/Resource/DisplayResourcesWorkspace/DisplayResourcesWorkspaceMenu.js +2 -2
- package/src/react-extension/components/Resource/DisplayResourcesWorkspace/DisplayResourcesWorkspaceMenu.test.data.js +1 -7
- package/src/react-extension/components/Resource/EditResource/EditResource.js +93 -68
- package/src/react-extension/components/Resource/EditResource/EditResource.test.data.js +80 -1
- package/src/react-extension/components/Resource/EditResource/EditResource.test.js +10 -39
- package/src/react-extension/components/Resource/EditResource/EditResource.test.page.js +26 -11
- package/src/react-extension/components/Resource/ExportResources/ExportResources.js +1 -1
- package/src/react-extension/components/Resource/ExportResources/ExportResources.test.stories.js +5 -11
- package/src/react-extension/components/Resource/ExportResources/ExportResourcesCredentials.js +10 -12
- package/src/react-extension/components/Resource/ExportResources/ExportResourcesCredentials.test.stories.js +5 -11
- package/src/react-extension/components/Resource/FilterResourcesByBreadcrumb/FilterResourcesByBreadcrumb.js +4 -4
- package/src/react-extension/components/Resource/FilterResourcesByBreadcrumb/FilterResourcesByBreadcrumb.test.stories.js +0 -1
- package/src/react-extension/components/Resource/FilterResourcesByFolders/DisplayDragFolderItem.js +109 -0
- package/src/react-extension/components/Resource/FilterResourcesByFolders/FilterResourcesByFolders.js +41 -193
- package/src/react-extension/components/Resource/FilterResourcesByFolders/FilterResourcesByFolders.test.data.js +10 -5
- package/src/react-extension/components/Resource/FilterResourcesByFolders/FilterResourcesByFolders.test.js +9 -12
- package/src/react-extension/components/Resource/FilterResourcesByFolders/FilterResourcesByFolders.test.page.js +6 -2
- package/src/react-extension/components/Resource/FilterResourcesByFolders/FilterResourcesByFolders.test.stories.js +0 -1
- package/src/react-extension/components/Resource/FilterResourcesByFolders/FilterResourcesByFoldersItem.js +83 -58
- package/src/react-extension/components/Resource/FilterResourcesByFolders/FilterResourcesByFoldersItem.test.data.js +52 -59
- package/src/react-extension/components/Resource/FilterResourcesByFolders/FilterResourcesByFoldersItem.test.js +25 -20
- package/src/react-extension/components/Resource/FilterResourcesByFolders/FilterResourcesByFoldersItem.test.page.js +11 -5
- package/src/react-extension/components/Resource/FilterResourcesByFolders/FilterResourcesByFoldersItemContextualMenu.js +1 -1
- package/src/react-extension/components/Resource/FilterResourcesByFolders/FilterResourcesByRootFolderContextualMenu.js +7 -2
- package/src/react-extension/components/Resource/FilterResourcesByFolders/FilterResourcesByRootFolderContextualMenu.test.js +3 -7
- package/src/react-extension/components/Resource/FilterResourcesByGroups/FilterResourcesByGroups.js +1 -1
- package/src/react-extension/components/Resource/FilterResourcesByShortcuts/FilterResourcesByShortcuts.js +1 -1
- package/src/react-extension/components/Resource/FilterResourcesByShortcuts/FilterResourcesByShortcuts.test.page.js +1 -1
- package/src/react-extension/components/Resource/FilterResourcesByShortcuts/FilterResourcesByShortcuts.test.stories.js +0 -1
- package/src/react-extension/components/Resource/FilterResourcesByTags/FilterResourcesByTags.js +1 -1
- package/src/react-extension/components/Resource/FilterResourcesByTags/FilterResourcesByTags.test.data.js +47 -0
- package/src/react-extension/components/Resource/FilterResourcesByTags/FilterResourcesByTags.test.js +34 -3
- package/src/react-extension/components/Resource/FilterResourcesByTags/FilterResourcesByTags.test.page.js +46 -9
- package/src/react-extension/components/Resource/FilterResourcesByTags/FilterResourcesByTags.test.stories.js +0 -1
- package/src/react-extension/components/Resource/FilterResourcesByTags/FilterResourcesByTagsList.js +124 -4
- package/src/react-extension/components/Resource/FilterResourcesByText/FilterResourcesByText.test.stories.js +0 -2
- package/src/react-extension/components/Resource/ImportResources/ImportResources.js +6 -5
- package/src/react-extension/components/Resource/ImportResources/ImportResourcesKeyUnlock.js +10 -12
- package/src/react-extension/components/Resource/ImportResources/ImportResourcesKeyUnlock.test.stories.js +5 -11
- package/src/react-extension/components/Resource/ImportResources/ImportResourcesResult.js +3 -3
- package/src/react-extension/components/Resource/ImportResources/ImportResourcesResult.test.js +3 -3
- package/src/react-extension/components/Resource/ImportResources/ImportResourcesResult.test.stories.js +5 -11
- package/src/react-extension/components/ResourceComment/AddResourceComment/AddResourceComment.js +1 -1
- package/src/react-extension/components/ResourceComment/AddResourceComment/AddResourceComment.test.page.object.js +1 -1
- package/src/react-extension/components/ResourceComment/AddResourceComment/AddResourceComment.test.stories.js +8 -14
- package/src/react-extension/components/ResourceComment/ConfirmResourceCommentDeletion/ConfirmResourceCommentDeletion.test.stories.js +5 -11
- package/src/react-extension/components/ResourceComment/DisplayResourceCommentList/DisplayResourceCommentList.test.stories.js +8 -14
- package/src/react-extension/components/ResourceDescription/EditResourceDescription/EditResourceDescription.js +9 -8
- package/src/react-extension/components/ResourceDescription/EditResourceDescription/EditResourceDescription.test.page.js +1 -1
- package/src/react-extension/components/ResourceDescription/EditResourceDescription/EditResourceDescription.test.stories.js +8 -15
- package/src/react-extension/components/ResourceDetails/DisplayResourceDetails/DisplayResourceDetailsActivity.test.stories.js +0 -1
- package/src/react-extension/components/ResourceDetails/DisplayResourceDetails/DisplayResourceDetailsDescription.js +1 -1
- package/src/react-extension/components/ResourceDetails/DisplayResourceDetails/DisplayResourceDetailsDescription.test.stories.js +0 -1
- package/src/react-extension/components/ResourceDetails/DisplayResourceDetails/DisplayResourceDetailsTag.test.js +1 -1
- package/src/react-extension/components/ResourceDetails/DisplayResourceDetails/DisplayResourceDetailsTag.test.stories.js +0 -1
- package/src/react-extension/components/ResourceFolder/CreateResourceFolder/CreateResourceFolder.js +2 -2
- package/src/react-extension/components/ResourceFolder/CreateResourceFolder/CreateResourceFolder.test.page.js +1 -1
- package/src/react-extension/components/ResourceFolder/CreateResourceFolder/CreateResourceFolder.test.stories.js +0 -3
- package/src/react-extension/components/ResourceFolder/DefineResourceFolderMoveStrategy/DefineResourceFolderMoveStrategy.test.stories.js +0 -6
- package/src/react-extension/components/ResourceFolder/DeleteResourceFolder/DeleteResourceFolder.test.stories.js +0 -5
- package/src/react-extension/components/ResourceFolder/RenameResourceFolder/RenameResourceFolder.js +1 -1
- package/src/react-extension/components/ResourceFolder/RenameResourceFolder/RenameResourceFolder.test.page.js +1 -1
- package/src/react-extension/components/ResourceFolder/RenameResourceFolder/RenameResourceFolder.test.stories.js +0 -7
- package/src/react-extension/components/ResourceFolderDetails/DisplayResourceFolderDetails/DisplayResourceFolderDetailsActivity.test.stories.js +0 -2
- package/src/react-extension/components/ResourceFolderDetails/DisplayResourceFolderDetails/DisplayResourceFolderDetailsInformation.test.stories.js +0 -2
- package/src/react-extension/components/ResourceFolderDetails/DisplayResourceFolderDetails/DisplayResourceFolderDetailsPermissions.test.stories.js +0 -2
- package/src/react-extension/components/ResourcePassword/GenerateResourcePassword/ConfigurePassphraseGenerator.js +150 -0
- package/src/react-extension/components/ResourcePassword/GenerateResourcePassword/ConfigurePassphraseGenerator.test.stories.js +30 -0
- package/src/react-extension/components/ResourcePassword/GenerateResourcePassword/ConfigurePasswordGenerator.js +191 -0
- package/src/react-extension/components/ResourcePassword/GenerateResourcePassword/ConfigurePasswordGenerator.test.stories.js +73 -0
- package/src/react-extension/components/ResourcePassword/GenerateResourcePassword/GenerateResourcePassword.js +296 -0
- package/src/react-extension/components/ResourcePassword/GenerateResourcePassword/GenerateResourcePassword.test.stories.js +112 -0
- package/src/react-extension/components/ResourceTag/DeleteResourceTag/DeleteResourceTag.test.stories.js +0 -2
- package/src/react-extension/components/ResourceTag/EditResourceTag/EditResourceTag.js +1 -1
- package/src/react-extension/components/ResourceTag/EditResourceTag/EditResourceTag.test.page.js +1 -1
- package/src/react-extension/components/ResourceTag/EditResourceTag/EditResourceTag.test.stories.js +0 -4
- package/src/react-extension/components/ResourceTag/EditResourceTags/EditResourceTags.js +2 -2
- package/src/react-extension/components/ResourceTag/EditResourceTags/EditResourceTags.test.page.js +1 -1
- package/src/react-extension/components/ResourceTag/EditResourceTags/EditResourceTagsItemViewer.js +5 -1
- package/src/react-extension/components/Share/ShareDialog.test.page.js +1 -1
- package/src/react-extension/components/Share/ShareDialog.test.stories.js +12 -10
- package/src/react-extension/components/User/ConfirmDisableUserMFA/ConfirmDisableUserMFA.test.stories.js +5 -9
- package/src/react-extension/components/User/CreateUser/CreateUser.js +4 -4
- package/src/react-extension/components/User/CreateUser/CreateUser.test.page.js +3 -3
- package/src/react-extension/components/User/CreateUser/CreateUser.test.stories.js +3 -1
- package/src/react-extension/components/User/DeleteUser/DeleteUser.test.stories.js +5 -8
- package/src/react-extension/components/User/DeleteUser/DeleteUserWithConflicts.test.stories.js +5 -8
- package/src/react-extension/components/User/DisplayUserWorkspaceActions/DisplayUserWorkspaceActions.js +2 -2
- package/src/react-extension/components/User/DisplayUserWorkspaceActions/DisplayUserWorkspaceActions.test.page.js +1 -1
- package/src/react-extension/components/User/DisplayUsers/DisplayUsers.js +35 -2
- package/src/react-extension/components/User/DisplayUsers/DisplayUsers.test.data.js +2 -1
- package/src/react-extension/components/User/DisplayUsers/DisplayUsers.test.js +6 -0
- package/src/react-extension/components/User/DisplayUsers/DisplayUsers.test.page.js +19 -6
- package/src/react-extension/components/User/EditUser/EditUser.js +3 -3
- package/src/react-extension/components/User/EditUser/EditUser.test.page.js +2 -2
- package/src/react-extension/components/User/EditUser/EditUser.test.stories.js +3 -1
- package/src/react-extension/components/User/FilterUsersByBreadcrumb/FilterUsersByBreadcrumb.js +2 -2
- package/src/react-extension/components/User/FilterUsersByBreadcrumb/FilterUsersByBreadcrumb.test.js +1 -1
- package/src/react-extension/components/User/FilterUsersByBreadcrumb/FilterUsersByBreadcrumb.test.stories.js +5 -8
- package/src/react-extension/components/User/FilterUsersByGroups/FilterUsersByGroup.js +1 -1
- package/src/react-extension/components/User/FilterUsersByShortcut/FilterUsersByShortcut.js +1 -1
- package/src/react-extension/components/User/FilterUsersByShortcut/FilterUsersByShortcut.test.stories.js +0 -1
- package/src/react-extension/components/User/FilterUsersByText/FilterUsersByText.test.stories.js +0 -2
- package/src/react-extension/components/UserDetails/DisplayUserDetailsGroups/DisplayUserDetailsGroups.test.stories.js +8 -11
- package/src/react-extension/components/UserDetails/DisplayUserDetailsInformation/DisplayUserDetailsInformation.test.stories.js +8 -11
- package/src/react-extension/components/UserDetails/DisplayUserDetailsPublicKey/DisplayUserDetailsPublicKey.test.stories.js +8 -12
- package/src/react-extension/components/UserGroup/CreateUserGroup/CreateUserGroup.js +1 -1
- package/src/react-extension/components/UserGroup/CreateUserGroup/CreateUserGroup.test.page.js +2 -2
- package/src/react-extension/components/UserGroup/CreateUserGroup/CreateUserGroup.test.stories.js +5 -8
- package/src/react-extension/components/UserGroup/DeleteUserGroup/DeleteUserGroup.test.stories.js +5 -8
- package/src/react-extension/components/UserGroup/DeleteUserGroup/DeleteUserGroupWithConflicts.test.stories.js +5 -8
- package/src/react-extension/components/UserGroup/DisplayUserGroupDetailsInformation/DisplayUserGroupDetailsInformation.test.stories.js +8 -11
- package/src/react-extension/components/UserGroup/DisplayUserGroupDetailsMembers/DisplayUserGroupDetailsMembers.test.stories.js +8 -11
- package/src/react-extension/components/UserGroup/EditUserGroup/EditUserGroup.js +11 -3
- package/src/react-extension/components/UserGroup/EditUserGroup/EditUserGroup.test.data.js +7 -0
- package/src/react-extension/components/UserGroup/EditUserGroup/EditUserGroup.test.page.js +1 -1
- package/src/react-extension/components/UserGroup/EditUserGroup/EditUserGroup.test.stories.js +12 -8
- package/src/react-extension/components/UserSetting/ChangeUserPassphrase/ConfirmPassphrase.js +92 -21
- package/src/react-extension/components/UserSetting/ChangeUserPassphrase/ConfirmPassphrase.test.data.js +6 -0
- package/src/react-extension/components/UserSetting/ChangeUserPassphrase/ConfirmPassphrase.test.js +2 -2
- package/src/react-extension/components/UserSetting/ChangeUserPassphrase/ConfirmPassphrase.test.page.js +1 -1
- package/src/react-extension/components/UserSetting/ChangeUserPassphrase/DisplayChangePassphraseIntroduction.js +12 -10
- package/src/react-extension/components/UserSetting/ChangeUserPassphrase/DownloadRecoveryKit.js +4 -10
- package/src/react-extension/components/UserSetting/ChangeUserPassphrase/EnterNewPassphrase.js +65 -25
- package/src/react-extension/components/UserSetting/ChangeUserPassphrase/EnterNewPassphrase.test.data.js +6 -0
- package/src/react-extension/components/UserSetting/ChangeUserPassphrase/EnterNewPassphrase.test.js +1 -1
- package/src/react-extension/components/UserSetting/ChangeUserPassphrase/EnterNewPassphrase.test.page.js +1 -1
- package/src/react-extension/components/UserSetting/ChangeUserSecurityToken/ChangeUserSecurityToken.js +14 -13
- package/src/react-extension/components/UserSetting/ChangeUserSecurityToken/ChangeUserSecurityToken.test.stories.js +5 -8
- package/src/react-extension/components/UserSetting/DisplayUserGpgInformation/DisplayUserGpgInformation.js +21 -6
- package/src/react-extension/components/UserSetting/DisplayUserGpgInformation/DisplayUserGpgInformation.test.stories.js +5 -8
- package/src/react-extension/components/UserSetting/DisplayUserProfile/DisplayUserProfile.js +1 -1
- package/src/react-extension/components/UserSetting/DisplayUserProfile/DisplayUserProfile.test.stories.js +5 -8
- package/src/react-extension/components/UserSetting/DisplayUserSettingsWorkspace/DisplayUserSettingsWorkspace.js +13 -1
- package/src/react-extension/components/UserSetting/DisplayUserSettingsWorkspaceBreadcrumb/DisplayUserSettingsWorkspaceBreadcrumb.js +2 -1
- package/src/react-extension/components/UserSetting/DisplayUserSettingsWorkspaceBreadcrumb/DisplayUserSettingsWorkspaceBreadcrumb.test.stories.js +5 -8
- package/src/react-extension/components/UserSetting/DisplayUserTheme/DisplayUserTheme.test.stories.js +5 -8
- package/src/react-extension/components/UserSetting/EditUserProfile/EditUserProfile.js +3 -3
- package/src/react-extension/components/UserSetting/EditUserProfile/EditUserProfile.test.stories.js +5 -8
- package/src/react-extension/components/UserSetting/NavigateIntoUserSettingsWorkspace/NavigateIntoUserSettingsWorkspace.js +26 -4
- package/src/react-extension/components/UserSetting/NavigateIntoUserSettingsWorkspace/NavigateIntoUserSettingsWorkspace.test.stories.js +7 -10
- package/src/react-extension/components/UserSetting/TransferToMobile/TransferToMobile.js +749 -0
- package/src/react-extension/components/UserSetting/TransferToMobile/TransferToMobile.test.data.js +32 -0
- package/src/react-extension/components/UserSetting/TransferToMobile/TransferToMobile.test.js +60 -0
- package/src/react-extension/components/UserSetting/TransferToMobile/TransferToMobile.test.page.js +110 -0
- package/src/react-extension/components/UserSetting/UploadUserProfileAvatar/UploadUserProfileAvatar.js +3 -2
- package/src/react-extension/components/UserSetting/UploadUserProfileAvatar/UploadUserProfileAvatar.test.stories.js +5 -8
- package/src/react-extension/contexts/AdministrationWorkspaceContext.js +2 -2
- package/src/react-extension/contexts/ApiAppContext.js +1 -1
- package/src/react-extension/contexts/ApiRecoverContext.js +1 -1
- package/src/react-extension/contexts/ApiSetupContext.js +1 -1
- package/src/react-extension/contexts/AuthenticationContext.js +21 -2
- package/src/react-extension/contexts/AuthenticationContext.test.js +40 -0
- package/src/react-extension/contexts/DragContext.js +122 -0
- package/src/react-extension/contexts/DragContext.test.js +53 -0
- package/src/react-extension/contexts/NavigationContext.js +11 -0
- package/src/react-extension/contexts/ResourcePasswordGeneratorContext.js +144 -0
- package/src/react-extension/contexts/ResourceWorkspaceContext.js +5 -4
- package/src/react-extension/contexts/ResourceWorkspaceContext.test.data.js +0 -1
- package/src/react-extension/contexts/ResourceWorkspaceContext.test.page.js +0 -1
- package/src/react-extension/contexts/UserWorkspaceContext.js +31 -4
- package/src/react-extension/contexts/UserWorkspaceContext.test.data.js +17 -287
- package/src/react-extension/lib/Crypto/sha512.js +17 -0
- package/src/react-extension/test/fixture/Settings/siteSettings.js +6 -0
- package/src/react-extension/test/mock/components/Internationalisation/MockTranslationProvider.js +42 -7
- package/src/react-quickaccess/ExtQuickAccess.js +75 -28
- package/src/react-quickaccess/components/AnimatedSwitch/AnimatedSwitch.js +22 -5
- package/src/react-quickaccess/components/ExtensionSetup/SetupExtensionInProgress/SetupExtensionInProgress.js +41 -0
- package/src/react-quickaccess/components/ExtensionSetup/SetupExtensionInProgress/SetupExtensionInProgressPage.test.stories.js +23 -0
- package/src/react-quickaccess/components/FilterResourcesByFavoritePage/FilterResourcesByFavoritePage.js +8 -4
- package/src/react-quickaccess/components/FilterResourcesByFavoritePage/FilterResourcesByFavoritePage.test.stories.js +7 -7
- package/src/react-quickaccess/components/FilterResourcesByGroupPage/FilterResourcesByGroupPage.js +10 -6
- package/src/react-quickaccess/components/FilterResourcesByGroupPage/FilterResourcesByGroupPage.test.stories.js +9 -5
- package/src/react-quickaccess/components/FilterResourcesByItemsIOwnPage/FilterResourcesByItemsIOwnPage.js +10 -7
- package/src/react-quickaccess/components/FilterResourcesByItemsIOwnPage/FilterResourcesByItemsIOwnPage.test.stories.js +7 -7
- package/src/react-quickaccess/components/FilterResourcesByRecentlyModifiedPage/FilterResourcesByRecentlyModifiedPage.js +10 -7
- package/src/react-quickaccess/components/FilterResourcesByRecentlyModifiedPage/FilterResourcesByRecentlyModifiedPage.test.stories.js +7 -7
- package/src/react-quickaccess/components/FilterResourcesBySharedWithMePage/FilterResourcesBySharedWithMePage.js +10 -7
- package/src/react-quickaccess/components/FilterResourcesBySharedWithMePage/FilterResourcesBySharedWithMePage.test.stories.js +7 -7
- package/src/react-quickaccess/components/FilterResourcesByTagPage/FilterResourcesByTagPage.js +10 -7
- package/src/react-quickaccess/components/FilterResourcesByTagPage/FilterResourcesByTagPage.test.stories.js +9 -5
- package/src/react-quickaccess/components/GeneratePasswordPage/ConfigurePassphraseGenerator.js +150 -0
- package/src/react-quickaccess/components/GeneratePasswordPage/ConfigurePassphraseGenerator.test.data.js +20 -0
- package/src/react-quickaccess/components/GeneratePasswordPage/ConfigurePassphraseGenerator.test.js +67 -0
- package/src/react-quickaccess/components/GeneratePasswordPage/ConfigurePassphraseGenerator.test.page.js +109 -0
- package/src/react-quickaccess/components/GeneratePasswordPage/ConfigurePasswordGenerator.js +189 -0
- package/src/react-quickaccess/components/GeneratePasswordPage/ConfigurePasswordGenerator.test.data.js +40 -0
- package/src/react-quickaccess/components/GeneratePasswordPage/ConfigurePasswordGenerator.test.js +67 -0
- package/src/react-quickaccess/components/GeneratePasswordPage/ConfigurePasswordGenerator.test.page.js +121 -0
- package/src/react-quickaccess/components/GeneratePasswordPage/GeneratePasswordPage.js +304 -0
- package/src/react-quickaccess/components/GeneratePasswordPage/GeneratePasswordPage.test.data.js +102 -0
- package/src/react-quickaccess/components/GeneratePasswordPage/GeneratePasswordPage.test.js +76 -0
- package/src/react-quickaccess/components/GeneratePasswordPage/GeneratePasswordPage.test.page.js +158 -0
- package/src/react-quickaccess/components/Header/Header.js +10 -8
- package/src/react-quickaccess/components/Header/Header.test.stories.js +4 -7
- package/src/react-quickaccess/components/HomePage/HomePage.js +40 -11
- package/src/react-quickaccess/components/HomePage/HomePage.test.stories.js +14 -10
- package/src/react-quickaccess/components/HomePage/canSuggestUrl.js +8 -3
- package/src/react-quickaccess/components/HomePage/canSuggestUrl.test.js +6 -0
- package/src/react-quickaccess/components/LoginPage/LoginPage.js +58 -18
- package/src/react-quickaccess/components/LoginPage/LoginPage.test.stories.js +4 -6
- package/src/react-quickaccess/components/ManageQuickAccessMode/ManageQuickAccessMode.js +103 -0
- package/src/react-quickaccess/components/MoreFiltersPage/MoreFiltersPage.js +2 -2
- package/src/react-quickaccess/components/MoreFiltersPage/MoreFiltersPage.test.stories.js +4 -6
- package/src/react-quickaccess/components/PassphraseDialog/PassphraseDialog.js +5 -3
- package/src/react-quickaccess/components/PassphraseDialog/PassphraseDialog.test.stories.js +6 -6
- package/src/react-quickaccess/components/PrivateRoute/PrivateRoute.js +1 -0
- package/src/react-quickaccess/components/ResourceAutoSave/SaveResource.js +234 -0
- package/src/react-quickaccess/components/ResourceAutoSave/SaveResource.test.data.js +28 -0
- package/src/react-quickaccess/components/ResourceAutoSave/SaveResource.test.stories.js +44 -0
- package/src/react-quickaccess/components/ResourceCreatePage/ResourceCreatePage.js +166 -39
- package/src/react-quickaccess/components/ResourceCreatePage/ResourceCreatePage.test.data.js +108 -2
- package/src/react-quickaccess/components/ResourceCreatePage/ResourceCreatePage.test.js +28 -25
- package/src/react-quickaccess/components/ResourceCreatePage/ResourceCreatePage.test.stories.js +6 -6
- package/src/react-quickaccess/components/ResourceViewPage/ResourceViewPage.js +6 -3
- package/src/react-quickaccess/components/ResourceViewPage/ResourceViewPage.test.stories.js +5 -3
- package/src/react-quickaccess/components/Search/Search.js +13 -1
- package/src/react-quickaccess/components/Search/Search.test.stories.js +4 -6
- package/src/react-quickaccess/contexts/PrepareResourceContext.js +221 -0
- package/src/react-web-integration/AuthLogin/AuthLogin.js +72 -0
- package/src/react-web-integration/Autofill/Autofill.js +331 -0
- package/src/react-web-integration/BrowserIntegrationBootstrap.js +64 -0
- package/src/react-web-integration/Events/Quickaccess/QuickAccessEvent.js +24 -0
- package/src/react-web-integration/ExtInFormCallToAction.js +56 -0
- package/src/react-web-integration/ExtInFormMenu.js +70 -0
- package/src/react-web-integration/components/AskInFormMenuDisplay/AskInFormMenuDisplay.js +161 -0
- package/src/react-web-integration/components/AskInFormMenuDisplay/AskInFormMenuDisplay.test.data.js +39 -0
- package/src/react-web-integration/components/AskInFormMenuDisplay/AskInFormMenuDisplay.test.js +48 -0
- package/src/react-web-integration/components/AskInFormMenuDisplay/AskInFormMenuDisplay.test.page.js +42 -0
- package/src/react-web-integration/components/AskInFormMenuDisplay/AskInFormMenuDisplay.test.stories.js +91 -0
- package/src/react-web-integration/components/DisplayInFormMenu/DisplayInFormMenu.js +360 -0
- package/src/react-web-integration/components/DisplayInFormMenu/DisplayInFormMenu.test.stories.js +198 -0
- package/src/react-web-integration/components/DisplayInFormMenu/DisplayInFormMenuItem.js +103 -0
- package/src/react-web-integration/contexts/AppContext.js +39 -0
- package/src/react-web-integration/lib/Dom/DomUtils.js +94 -0
- package/src/react-web-integration/lib/InForm/InFormCallToActionField.js +263 -0
- package/src/react-web-integration/lib/InForm/InFormCredentialsFormField.js +118 -0
- package/src/react-web-integration/lib/InForm/InFormFieldSelector.js +77 -0
- package/src/react-web-integration/lib/InForm/InFormManager.js +253 -0
- package/src/react-web-integration/lib/InForm/InformManager.test.data.js +46 -0
- package/src/react-web-integration/lib/InForm/InformManager.test.js +82 -0
- package/src/react-web-integration/lib/InForm/InformManager.test.page.js +116 -0
- package/src/react-web-integration/lib/InForm/InformMenuField.js +182 -0
- package/src/shared/components/Internationalisation/TranslationProvider.js +145 -0
- package/src/shared/lib/Browser/detectBrowserName.js +2 -1
- package/src/shared/lib/Secret/SecretComplexity.js +2 -2
- package/src/shared/lib/SecretGenerator/PassphraseGenerator.js +112 -0
- package/src/shared/lib/SecretGenerator/PassphraseGenerator.test.js +48 -0
- package/src/shared/lib/SecretGenerator/PassphraseGeneratorWords.js +7789 -0
- package/src/shared/lib/SecretGenerator/PasswordGenerator.js +103 -0
- package/src/shared/lib/SecretGenerator/SecretGenerator.js +45 -0
- package/src/shared/lib/SecretGenerator/SecretGeneratorComplexity.js +190 -0
- package/src/shared/lib/SecretGenerator/SecretGeneratorComplexity.test.js +95 -0
- package/src/shared/lib/Settings/SiteSettings.js +8 -0
- package/src/shared/lib/apiClient/apiClient.test.js +1 -1
- package/.babelrc +0 -11
- package/.editorconfig +0 -13
- package/.eslintrc.json +0 -197
- package/.gitlab-ci.yml +0 -28
- package/.jest.config.json +0 -6
- package/.jest.setup.js +0 -8
- package/.jest.transform.js +0 -7
- package/.storybook/main.js +0 -15
- package/.storybook/preview-body.html +0 -5
- package/.storybook/preview.js +0 -6
- package/Gruntfile.js +0 -199
- package/build/css/themes/default/ext_config_debug.min.css +0 -13
- package/build/css/themes/default/ext_legacy.min.css +0 -13
- package/build/css/themes/midgar/ext_legacy.min.css +0 -13
- package/crowdin.yml +0 -4
- package/docker-compose-dev.yml +0 -10
- package/jest.config.json +0 -6
- package/src/img/controls/colorpicker/marker.png +0 -0
- package/src/img/controls/colorpicker/mask.png +0 -0
- package/src/img/controls/colorpicker/wheel.png +0 -0
- package/src/img/controls/overlay-opacity-50.png +0 -0
- package/src/img/third_party/ChromeWebStore_black.png +0 -0
- package/src/img/third_party/ChromeWebStore_white.png +0 -0
- package/src/js/accordion.js +0 -10
- package/src/js/autocomplete.js +0 -241
- package/src/js/autocomplete.min.js +0 -3
- package/src/js/bootstrap-scrollspy.js +0 -172
- package/src/js/chosen.jquery.js +0 -1356
- package/src/js/colorpicker.js +0 -32
- package/src/js/download.js +0 -128
- package/src/js/farbtastic.js +0 -345
- package/src/js/swiper.min.js +0 -18
- package/src/react-quickaccess/components/Internationalisation/TranslationProvider.js +0 -151
- package/storybook-static/favicon.ico +0 -0
- package/storybook-static/iframe.html +0 -133
- package/storybook-static/index.html +0 -47
- package/storybook-static/main.2d01924b12554c6c15af.bundle.js +0 -1
- package/storybook-static/main.b0c44c8759149ccf4f67.bundle.js +0 -3
- package/storybook-static/main.b0c44c8759149ccf4f67.bundle.js.LICENSE.txt +0 -153
- package/storybook-static/main.b0c44c8759149ccf4f67.bundle.js.map +0 -1
- package/storybook-static/runtime~main.6a9b04192e3176eff72a.bundle.js +0 -1
- package/storybook-static/runtime~main.b0c44c8759149ccf4f67.bundle.js +0 -2
- package/storybook-static/runtime~main.b0c44c8759149ccf4f67.bundle.js.map +0 -1
- package/storybook-static/static/media/chosen-sprite.6768c197.png +0 -0
- package/storybook-static/static/media/chosen-sprite@2x.a0b7f3f1.png +0 -0
- package/storybook-static/static/media/dot_black.a2c44078.svg +0 -6
- package/storybook-static/static/media/dot_red.7b34541d.svg +0 -6
- package/storybook-static/static/media/dot_white.f60f7331.svg +0 -6
- package/storybook-static/static/media/fontawesome-webfont.1e59d233.ttf +0 -0
- package/storybook-static/static/media/fontawesome-webfont.20fd1704.woff2 +0 -0
- package/storybook-static/static/media/fontawesome-webfont.8b43027f.eot +0 -0
- package/storybook-static/static/media/fontawesome-webfont.c1e38fd9.svg +0 -2671
- package/storybook-static/static/media/fontawesome-webfont.f691f37e.woff +0 -0
- package/storybook-static/static/media/infinite-bar.f5327dc3.gif +0 -0
- package/storybook-static/static/media/loading_dark.ea474c7f.svg +0 -21
- package/storybook-static/static/media/loading_light.061977b5.svg +0 -15
- package/storybook-static/static/media/logo.e2b062a5.svg +0 -1
- package/storybook-static/static/media/logo_white.cb32e694.svg +0 -1
- package/storybook-static/static/media/opensans-bold.a6b4768c.woff +0 -0
- package/storybook-static/static/media/opensans-regular.7812bd0b.woff +0 -0
- package/storybook-static/static/media/passphrase_intro.37a1ba4e.png +0 -0
- package/storybook-static/vendors~main.4abf29e4f956d5befb41.bundle.js +0 -2
- package/storybook-static/vendors~main.4abf29e4f956d5befb41.bundle.js.LICENSE.txt +0 -105
- package/storybook-static/vendors~main.b0c44c8759149ccf4f67.bundle.js +0 -3
- package/storybook-static/vendors~main.b0c44c8759149ccf4f67.bundle.js.LICENSE.txt +0 -145
- package/storybook-static/vendors~main.b0c44c8759149ccf4f67.bundle.js.map +0 -1
- package/webpack-api.config.js +0 -83
- package/webpack-ext.config.js +0 -84
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Passbolt ~ Open source password manager for teams
|
|
3
|
+
* Copyright (c) 2021 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) 2021 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.3.0
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import InFormCallToActionField from "./InFormCallToActionField";
|
|
16
|
+
import InFormFieldSelector from "./InFormFieldSelector";
|
|
17
|
+
import InFormMenuField from "./InformMenuField";
|
|
18
|
+
import {fireEvent} from "@testing-library/dom/dist/events";
|
|
19
|
+
import InFormCredentialsFormField from "./InFormCredentialsFormField";
|
|
20
|
+
/**
|
|
21
|
+
* Manages the in-form web integration including call-to-action and menu
|
|
22
|
+
*/
|
|
23
|
+
class InFormManager {
|
|
24
|
+
/**
|
|
25
|
+
* Default constructor
|
|
26
|
+
*/
|
|
27
|
+
constructor() {
|
|
28
|
+
/** In-form username and password callToActionFields in the target page*/
|
|
29
|
+
this.callToActionFields = [];
|
|
30
|
+
/** In-form menu menuField in the target page*/
|
|
31
|
+
this.menuField = null;
|
|
32
|
+
/** In-form form fields in the target page*/
|
|
33
|
+
this.credentialsFormFields = [];
|
|
34
|
+
/** Mutation observer to detect any change on the DOM */
|
|
35
|
+
this.mutationObserver = null;
|
|
36
|
+
|
|
37
|
+
this.bindCallbacks();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Initializes the in-form manager
|
|
42
|
+
*/
|
|
43
|
+
initialize() {
|
|
44
|
+
this.findAndSetAuthenticationFields();
|
|
45
|
+
this.handleDomChange();
|
|
46
|
+
this.handleInformCallToActionRepositionEvent();
|
|
47
|
+
this.handlePortDisconnectEvent();
|
|
48
|
+
this.handleInFormMenuInsertionEvent();
|
|
49
|
+
this.handleInFormMenuRemoveEvent();
|
|
50
|
+
this.handleInformCallToActionClickEvent();
|
|
51
|
+
this.handleGetLastCallToActionClickedInput();
|
|
52
|
+
this.handleGetCurrentCredentials();
|
|
53
|
+
this.handleFillCredentials();
|
|
54
|
+
this.handleFillPassword();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Binds the callbacks
|
|
59
|
+
*/
|
|
60
|
+
bindCallbacks() {
|
|
61
|
+
this.findAndSetAuthenticationFields = this.findAndSetAuthenticationFields.bind(this);
|
|
62
|
+
this.handleInformCallToActionClickEvent = this.handleInformCallToActionClickEvent.bind(this);
|
|
63
|
+
this.clean = this.clean.bind(this);
|
|
64
|
+
this.destroy = this.destroy.bind(this);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Find authentication fields in the document and set them as object properties
|
|
69
|
+
*/
|
|
70
|
+
findAndSetAuthenticationFields() {
|
|
71
|
+
this.findAndSetUsernameAndPasswordFields();
|
|
72
|
+
this.findAndSetCredentialsFormFields();
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Find authentication callToActionFields in the document and set them as object properties
|
|
77
|
+
*/
|
|
78
|
+
findAndSetUsernameAndPasswordFields() {
|
|
79
|
+
/* We find the username / passwords DOM callToActionFields.
|
|
80
|
+
* If it was previously found, we reuse the same InformUsernameField, otherwise we create one
|
|
81
|
+
* Else we clean and reset callToActionFields
|
|
82
|
+
*/
|
|
83
|
+
const newUsernameFields = InFormCallToActionField.findAll(InFormFieldSelector.USERNAME_FIELD_SELECTOR);
|
|
84
|
+
const newPasswordFields = InFormCallToActionField.findAll(InFormFieldSelector.PASSWORD_FIELD_SELECTOR);
|
|
85
|
+
const newFields = newUsernameFields.concat(newPasswordFields);
|
|
86
|
+
if (newFields.length > 0) {
|
|
87
|
+
this.callToActionFields = newFields.map(newField => {
|
|
88
|
+
const matchField = fieldToMatch => callToActionField => callToActionField.field === fieldToMatch;
|
|
89
|
+
const existingField = this.callToActionFields.find(matchField(newField));
|
|
90
|
+
const fieldType = newField.matches(InFormFieldSelector.USERNAME_FIELD_SELECTOR) ? 'username' : 'password';
|
|
91
|
+
return existingField || new InFormCallToActionField(newField, fieldType);
|
|
92
|
+
});
|
|
93
|
+
} else {
|
|
94
|
+
this.clean();
|
|
95
|
+
this.callToActionFields = [];
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Find authentication formFields in the document and set them as object properties
|
|
101
|
+
*/
|
|
102
|
+
findAndSetCredentialsFormFields() {
|
|
103
|
+
/* We find the form DOM formFields.
|
|
104
|
+
* If it was previously found, we reuse the same InformFormField, otherwise we create one
|
|
105
|
+
*/
|
|
106
|
+
const newCredentialsFormFields = InFormCredentialsFormField.findAll();
|
|
107
|
+
this.credentialsFormFields = newCredentialsFormFields.map(newField => {
|
|
108
|
+
const matchField = fieldToMatch => credentialsFormField => credentialsFormField.field === fieldToMatch;
|
|
109
|
+
const existingField = this.credentialsFormFields.find(matchField(newField));
|
|
110
|
+
const usernameField = this.callToActionFields.find(callToActionField => callToActionField.fieldType === 'username' && newField.contains(callToActionField.field));
|
|
111
|
+
const passwordField = this.callToActionFields.find(callToActionField => callToActionField.fieldType === 'password' && newField.contains(callToActionField.field));
|
|
112
|
+
return existingField || new InFormCredentialsFormField(newField, usernameField?.field, passwordField?.field);
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Clean the DOM of in-form entities
|
|
118
|
+
*/
|
|
119
|
+
clean() {
|
|
120
|
+
this.callToActionFields.forEach(field => field.removeCallToActionIframe());
|
|
121
|
+
this.menuField?.removeMenuIframe();
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Whenever the DOM changes
|
|
126
|
+
*/
|
|
127
|
+
handleDomChange() {
|
|
128
|
+
const updateAuthenticationFields = () => {
|
|
129
|
+
this.findAndSetAuthenticationFields();
|
|
130
|
+
this.handleInformCallToActionClickEvent();
|
|
131
|
+
}
|
|
132
|
+
// Search again for authentication callToActionFields to attach when the DOM changes
|
|
133
|
+
this.mutationObserver = new MutationObserver(updateAuthenticationFields);
|
|
134
|
+
this.mutationObserver.observe(document.body, { attributes: true, childList: true, subtree: true });
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Whenever the username / password callToActionFields change its position, reposition the call-to-action
|
|
139
|
+
*/
|
|
140
|
+
handleInformCallToActionRepositionEvent() {
|
|
141
|
+
window.addEventListener('resize', this.clean);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Whenever the user clicks on the in-form call-to-action, it inserts the in-form menu iframe
|
|
146
|
+
*/
|
|
147
|
+
handleInFormMenuInsertionEvent() {
|
|
148
|
+
port.on('passbolt.in-form-menu.open', () => {
|
|
149
|
+
this.menuField = new InFormMenuField(this.lastCallToActionFieldClicked.field);
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Whenever the user clicks on the in-form menu, it removes the in-form menu iframe
|
|
155
|
+
*/
|
|
156
|
+
handleInFormMenuRemoveEvent() {
|
|
157
|
+
port.on('passbolt.in-form-menu.close', () => {
|
|
158
|
+
this.menuField.removeMenuIframe();
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Handle the click on the in-form call-to-action (iframe)
|
|
164
|
+
*/
|
|
165
|
+
handleInformCallToActionClickEvent() {
|
|
166
|
+
const setLastCallToActionFieldClicked = callToActionField => callToActionField.onClick(() => this.lastCallToActionFieldClicked = callToActionField);
|
|
167
|
+
this.callToActionFields.forEach(setLastCallToActionFieldClicked);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/** Whenever one requires to get the type and value of the input attached to the last call-to-action performed */
|
|
171
|
+
handleGetLastCallToActionClickedInput() {
|
|
172
|
+
port.on('passbolt.web-integration.last-performed-call-to-action-input', (requestId) => {
|
|
173
|
+
port.emit(requestId, 'SUCCESS', {type: this.lastCallToActionFieldClicked.fieldType, value: this.lastCallToActionFieldClicked.field.value})
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/** Whenever one requires to get the current credentials */
|
|
178
|
+
handleGetCurrentCredentials() {
|
|
179
|
+
port.on('passbolt.web-integration.get-credentials', (requestId) => {
|
|
180
|
+
const currentFieldType = this.lastCallToActionFieldClicked?.fieldType;
|
|
181
|
+
const isUsernameType = currentFieldType === 'username';
|
|
182
|
+
const isPasswordType = currentFieldType === 'password';
|
|
183
|
+
let username = null;
|
|
184
|
+
let password = null;
|
|
185
|
+
if (!isUsernameType) {
|
|
186
|
+
username = this.callToActionFields.find(field => field.fieldType === 'username')?.field.value;
|
|
187
|
+
password = this.lastCallToActionFieldClicked?.field.value;
|
|
188
|
+
}
|
|
189
|
+
if (!isPasswordType) {
|
|
190
|
+
username = this.lastCallToActionFieldClicked?.field.value;
|
|
191
|
+
password = this.callToActionFields.find(field => field.fieldType === 'password')?.field.value;
|
|
192
|
+
}
|
|
193
|
+
port.emit(requestId, 'SUCCESS', {username, password});
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Whenever one requests to fill the current page form with given credentials
|
|
199
|
+
*/
|
|
200
|
+
handleFillCredentials() {
|
|
201
|
+
port.on('passbolt.web-integration.fill-credentials', ({username, password}) => {
|
|
202
|
+
const currentFieldType = this.lastCallToActionFieldClicked?.fieldType;
|
|
203
|
+
const isUsernameType = currentFieldType === 'username';
|
|
204
|
+
const isPasswordType = currentFieldType === 'password';
|
|
205
|
+
if (!isUsernameType) {
|
|
206
|
+
const usernameField = this.callToActionFields.find(field => field.fieldType === 'username')?.field;
|
|
207
|
+
fireEvent.input(usernameField, { target: { value: username } });
|
|
208
|
+
fireEvent.input( this.lastCallToActionFieldClicked.field, { target: { value: password } });
|
|
209
|
+
}
|
|
210
|
+
if (!isPasswordType) {
|
|
211
|
+
const passwordField = this.callToActionFields.find(field => field.fieldType === 'password')?.field;
|
|
212
|
+
fireEvent.input( this.lastCallToActionFieldClicked.field, { target: { value: username } });
|
|
213
|
+
fireEvent.input(passwordField, { target: { value: password } });
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Whenever one requests to fill the current page form with a password
|
|
220
|
+
*/
|
|
221
|
+
handleFillPassword() {
|
|
222
|
+
port.on('passbolt.web-integration.fill-password', password => {
|
|
223
|
+
this.callToActionFields
|
|
224
|
+
.filter(callToActionField => callToActionField.fieldType === 'password')
|
|
225
|
+
.forEach(callToActionField => fireEvent.input(callToActionField.field, { target: { value: password }}));
|
|
226
|
+
this.menuField.removeMenuIframe();
|
|
227
|
+
// Listen the auto-save on the appropriate form field
|
|
228
|
+
const formField = this.credentialsFormFields.find(formField => formField.field.contains(this.lastCallToActionFieldClicked.field));
|
|
229
|
+
formField?.handleAutoSaveEvent();
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Remove all event, observer and iframe
|
|
235
|
+
*/
|
|
236
|
+
destroy() {
|
|
237
|
+
this.mutationObserver.disconnect();
|
|
238
|
+
this.callToActionFields.forEach(field => field.destroy());
|
|
239
|
+
this.menuField?.destroy();
|
|
240
|
+
this.credentialsFormFields.forEach(field => field.destroy());
|
|
241
|
+
window.removeEventListener('resize', this.clean);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Whenever the port is disconnected due to an update of the extension
|
|
246
|
+
*/
|
|
247
|
+
handlePortDisconnectEvent() {
|
|
248
|
+
port._port.onDisconnect.addListener(this.destroy)
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
export default new InFormManager();
|
|
253
|
+
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Passbolt ~ Open source password manager for teams
|
|
3
|
+
* Copyright (c) 2021 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) 2021 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.3.0
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import MockPort from "../../../react-extension/test/mock/MockPort";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Create a login form in DOM
|
|
19
|
+
* @type {string}
|
|
20
|
+
*/
|
|
21
|
+
export const domElementBasicLogin =
|
|
22
|
+
'<div>' +
|
|
23
|
+
' <input type="text" id="username" name="usename" />' +
|
|
24
|
+
' <input type="password" id="password" name="password" />' +
|
|
25
|
+
'</div>';
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Create a login form in DOM
|
|
29
|
+
* @type {string}
|
|
30
|
+
*/
|
|
31
|
+
export const domElementWithNoUsernamePassword =
|
|
32
|
+
'<div>' +
|
|
33
|
+
' <input type="text" id="search" name="search" />' +
|
|
34
|
+
'</div>';
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Mock global variable in window
|
|
38
|
+
*/
|
|
39
|
+
export const initializeWindow = () => {
|
|
40
|
+
window.port = new MockPort();
|
|
41
|
+
window.port._port = {
|
|
42
|
+
onDisconnect: {
|
|
43
|
+
addListener: () => {}
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Passbolt ~ Open source password manager for teams
|
|
3
|
+
* Copyright (c) 2021 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) 2021 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.3.0
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Unit tests on InformManager in regard of specifications
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import {domElementBasicLogin, domElementWithNoUsernamePassword, initializeWindow} from "./InformManager.test.data";
|
|
20
|
+
import InformManagerPage from "./InformManager.test.page";
|
|
21
|
+
import InFormManager from "./InFormManager";
|
|
22
|
+
|
|
23
|
+
beforeEach(() => {
|
|
24
|
+
jest.resetModules();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
describe("InformManager", () => {
|
|
28
|
+
// mock port in window
|
|
29
|
+
initializeWindow();
|
|
30
|
+
|
|
31
|
+
afterEach(() => {
|
|
32
|
+
InFormManager.destroy();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it("As LU I should see the inform call to action", async() => {
|
|
36
|
+
// Set up document body
|
|
37
|
+
document.body.innerHTML = domElementBasicLogin; // The Dom
|
|
38
|
+
const informManager = new InformManagerPage();
|
|
39
|
+
expect(informManager.iframesLength).toBe(0);
|
|
40
|
+
await informManager.focusOnUsername();
|
|
41
|
+
expect(informManager.iframesLength).toBe(1);
|
|
42
|
+
await informManager.mouseOverOnPassword();
|
|
43
|
+
expect(informManager.iframesLength).toBe(2);
|
|
44
|
+
await informManager.blurOnUsername();
|
|
45
|
+
expect(informManager.iframesLength).toBe(1);
|
|
46
|
+
await informManager.blurOnPassword();
|
|
47
|
+
expect(informManager.iframesLength).toBe(0);
|
|
48
|
+
await informManager.focusOnPassword();
|
|
49
|
+
expect(informManager.iframesLength).toBe(1);
|
|
50
|
+
await informManager.mouseOverOnUsername();
|
|
51
|
+
expect(informManager.iframesLength).toBe(2);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it("As LU I should see the inform call to action when I clicked on it", async() => {
|
|
55
|
+
// Set up document body
|
|
56
|
+
document.body.innerHTML = domElementBasicLogin; // The Dom
|
|
57
|
+
const informManager = new InformManagerPage();
|
|
58
|
+
expect(informManager.iframesLength).toBe(0);
|
|
59
|
+
await informManager.focusOnUsername();
|
|
60
|
+
expect(informManager.iframesLength).toBe(1);
|
|
61
|
+
await informManager.clickOnInformCallToAction();
|
|
62
|
+
expect(informManager.iframesLength).toBe(1);
|
|
63
|
+
await informManager.blurOnUsername();
|
|
64
|
+
expect(informManager.iframesLength).toBe(0);
|
|
65
|
+
await informManager.focusOnPassword();
|
|
66
|
+
expect(informManager.iframesLength).toBe(1);
|
|
67
|
+
await informManager.clickOnInformCallToAction();
|
|
68
|
+
expect(informManager.iframesLength).toBe(1);
|
|
69
|
+
await informManager.blurOnPassword();
|
|
70
|
+
expect(informManager.iframesLength).toBe(0);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it("As LU I shouldn't see the inform call to action on a page with no login form", async() => {
|
|
74
|
+
// Set up document body
|
|
75
|
+
document.body.innerHTML = domElementWithNoUsernamePassword; // The Dom
|
|
76
|
+
const informManager = new InformManagerPage();
|
|
77
|
+
expect(informManager.iframesLength).toBe(0);
|
|
78
|
+
await informManager.focusOnSearch();
|
|
79
|
+
expect(informManager.iframesLength).toBe(0);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Passbolt ~ Open source password manager for teams
|
|
3
|
+
* Copyright (c) 2021 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) 2021 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.3.0
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The InformManager component represented as a page
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import InFormManager from "./InFormManager";
|
|
20
|
+
import {fireEvent, waitFor} from "@testing-library/react";
|
|
21
|
+
|
|
22
|
+
export default class InformManagerPage {
|
|
23
|
+
/**
|
|
24
|
+
* Default constructor
|
|
25
|
+
*/
|
|
26
|
+
constructor() {
|
|
27
|
+
InFormManager.initialize();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
destroy() {
|
|
31
|
+
InFormManager.destroy();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Returns the username element
|
|
36
|
+
*/
|
|
37
|
+
get username() {
|
|
38
|
+
return document.querySelector('#username');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Returns the password element
|
|
43
|
+
*/
|
|
44
|
+
get password() {
|
|
45
|
+
return document.querySelector('#password');
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Returns the search element
|
|
50
|
+
*/
|
|
51
|
+
get search() {
|
|
52
|
+
return document.querySelector('#search');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Returns the iframe call to action
|
|
57
|
+
*/
|
|
58
|
+
get iframesCallToAction() {
|
|
59
|
+
return document.querySelector('iframe');
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Returns the iframe length
|
|
64
|
+
*/
|
|
65
|
+
get iframesLength() {
|
|
66
|
+
return document.querySelectorAll('iframe').length;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** Blur on the username element */
|
|
70
|
+
async blurOnUsername() {
|
|
71
|
+
fireEvent.blur(this.username);
|
|
72
|
+
await waitFor(() => {});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** Blur on the password element */
|
|
76
|
+
async blurOnPassword() {
|
|
77
|
+
fireEvent.blur(this.password);
|
|
78
|
+
await waitFor(() => {});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** Focus on the username element */
|
|
82
|
+
async focusOnUsername() {
|
|
83
|
+
fireEvent.focus(this.username);
|
|
84
|
+
await waitFor(() => {});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** Focus on the password element */
|
|
88
|
+
async focusOnPassword() {
|
|
89
|
+
fireEvent.focus(this.password);
|
|
90
|
+
await waitFor(() => {});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** Focus on the search element */
|
|
94
|
+
async focusOnSearch() {
|
|
95
|
+
fireEvent.focus(this.search);
|
|
96
|
+
await waitFor(() => {});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** Mouse over on the username element */
|
|
100
|
+
async mouseOverOnUsername() {
|
|
101
|
+
fireEvent.mouseOver(this.username);
|
|
102
|
+
await waitFor(() => {});
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** Mouse over on the password element */
|
|
106
|
+
async mouseOverOnPassword() {
|
|
107
|
+
fireEvent.mouseOver(this.password);
|
|
108
|
+
await waitFor(() => {});
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
async clickOnInformCallToAction() {
|
|
112
|
+
const leftClick = {button: 0};
|
|
113
|
+
fireEvent.click(this.iframesCallToAction, leftClick);
|
|
114
|
+
await waitFor(() => {});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Passbolt ~ Open source password manager for teams
|
|
3
|
+
* Copyright (c) 2021 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) 2021 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.3.0
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import {v4 as uuidv4} from "uuid";
|
|
16
|
+
import browser from "webextension-polyfill";
|
|
17
|
+
import DomUtils from "../Dom/DomUtils";
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* An InFormMenuField is represented by a DOM element identified as a menu field
|
|
21
|
+
*/
|
|
22
|
+
class InFormMenuField {
|
|
23
|
+
/**
|
|
24
|
+
* Default constructor
|
|
25
|
+
* @param field
|
|
26
|
+
*/
|
|
27
|
+
constructor(field) {
|
|
28
|
+
/** The field to which the in-form is attached */
|
|
29
|
+
this.field = field;
|
|
30
|
+
/** An unique identifier for the iframe */
|
|
31
|
+
this.iframeId = uuidv4();
|
|
32
|
+
/** Flag telling if the user is mousing over the menu (iframe) */
|
|
33
|
+
this.isMenuMousingOver = false;
|
|
34
|
+
/** In-form menu click watcher */
|
|
35
|
+
this.menuClickWatcher = null;
|
|
36
|
+
/** The scrollable field parent */
|
|
37
|
+
this.scrollableFieldParent = null;
|
|
38
|
+
|
|
39
|
+
this.bindCallbacks();
|
|
40
|
+
this.insertInformMenuIframe();
|
|
41
|
+
this.handleRemoveEvent();
|
|
42
|
+
this.handleScrollEvent();
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Binds methods callbacks
|
|
47
|
+
*/
|
|
48
|
+
bindCallbacks() {
|
|
49
|
+
this.removeInFormMenu = this.removeInFormMenu.bind(this);
|
|
50
|
+
this.removeMenuIframe = this.removeMenuIframe.bind(this);
|
|
51
|
+
this.destroy = this.destroy.bind(this);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** MENU INSERTION */
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Insert an in-form menu iframe
|
|
58
|
+
*/
|
|
59
|
+
insertInformMenuIframe() {
|
|
60
|
+
const iframes = document.querySelectorAll('iframe');
|
|
61
|
+
// Use of Array prototype some method cause NodeList is not an array !
|
|
62
|
+
const iframeId = this.iframeId;
|
|
63
|
+
const isIframeAlreadyInserted = Array.prototype.some.call(iframes, iframe => iframe.id === iframeId);
|
|
64
|
+
if (!isIframeAlreadyInserted) {
|
|
65
|
+
const iframe = this.createMenuIframe();
|
|
66
|
+
this.handleMenuClicked(iframe);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Create an iframe dedicated to the menu
|
|
72
|
+
* @return {HTMLIFrameElement} The created iframe
|
|
73
|
+
*/
|
|
74
|
+
createMenuIframe() {
|
|
75
|
+
const iframe = document.createElement('iframe');
|
|
76
|
+
document.body.appendChild(iframe);
|
|
77
|
+
const browserExtensionUrl = browser.runtime.getURL("/");
|
|
78
|
+
const {top, left} = this.calculateIframePosition();
|
|
79
|
+
iframe.id = this.iframeId;
|
|
80
|
+
iframe.style.position = "fixed";
|
|
81
|
+
iframe.style.top = top + 'px'
|
|
82
|
+
iframe.style.left = left + 'px';
|
|
83
|
+
iframe.style.border = 0;
|
|
84
|
+
iframe.style.width = '370px'; // width of the menu 350px + 20px to display shadows
|
|
85
|
+
iframe.style.height = '220px'; // For 3 items in a row to be display
|
|
86
|
+
iframe.style.zIndex = "1000";
|
|
87
|
+
iframe.contentWindow.location = `${browserExtensionUrl}data/passbolt-iframe-in-form-menu.html?passbolt=passbolt-iframe-in-form-menu`;
|
|
88
|
+
return iframe;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Calculates the position on the screen of the DOM field
|
|
93
|
+
* @return {{top: number, left: number}}
|
|
94
|
+
*/
|
|
95
|
+
calculateIframePosition() {
|
|
96
|
+
let x = 0;
|
|
97
|
+
let y = 0;
|
|
98
|
+
let currentElement = this.field;
|
|
99
|
+
const {height, width} = this.field.getBoundingClientRect();
|
|
100
|
+
const {top: topBody, left: leftBody} = document.documentElement.getBoundingClientRect();
|
|
101
|
+
// We loop to calculate the cumulated position of the field
|
|
102
|
+
// from its ancestors and itself differential offset / scroll position
|
|
103
|
+
while( currentElement && !isNaN( currentElement.offsetLeft ) && !isNaN( currentElement.offsetTop ) ) {
|
|
104
|
+
x += currentElement.offsetLeft - currentElement.scrollLeft;
|
|
105
|
+
y += currentElement.offsetTop - currentElement.scrollTop;
|
|
106
|
+
currentElement = currentElement.offsetParent;
|
|
107
|
+
}
|
|
108
|
+
// Then we add the body offset (notably in case of window scroll) + some local adjustments (margin / vertical aligment ) to align with the call to action icon
|
|
109
|
+
x = x + leftBody + width - 367; // (-370 width of the iframe + 10 to adjust with the shadow) (-7 adjustment of the call to action menu (18-25))
|
|
110
|
+
y = y + topBody + height; // Calculate the middle position of the input, 8 is the half of the iframe height
|
|
111
|
+
return { top: y, left: x };
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Whenever the user clicked on the call-to-action iframe
|
|
116
|
+
* @param iframe The menu iframe
|
|
117
|
+
*/
|
|
118
|
+
handleMenuClicked(iframe) {
|
|
119
|
+
/* We need to know which iframe the user click on. We cannot add a listener on iframe
|
|
120
|
+
* since there are from different domains (target page vs extension pagemods)
|
|
121
|
+
*/
|
|
122
|
+
iframe.addEventListener('mouseover', () => this.isMenuMousingOver = true);
|
|
123
|
+
iframe.addEventListener('mouseout', () => this.isMenuMousingOver = false);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/** MENU REMOVE */
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Whenever the menu must be removed
|
|
130
|
+
*/
|
|
131
|
+
handleRemoveEvent() {
|
|
132
|
+
this.field.addEventListener("blur", this.removeInFormMenu);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Removes the in-form menu iframe from the field
|
|
137
|
+
*/
|
|
138
|
+
removeInFormMenu() {
|
|
139
|
+
const isIframeMouseOver = this.isMenuMousingOver;
|
|
140
|
+
const isActiveElement = document.activeElement === this.field;
|
|
141
|
+
if (!isIframeMouseOver && !isActiveElement) {
|
|
142
|
+
this.removeMenuIframe();
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Remove the menu (iframe)
|
|
148
|
+
*/
|
|
149
|
+
removeMenuIframe() {
|
|
150
|
+
const iframes = document.querySelectorAll('iframe');
|
|
151
|
+
iframes.forEach(iframe => {
|
|
152
|
+
const identifierToMatch = this.iframeId
|
|
153
|
+
if (iframe.id === identifierToMatch) {
|
|
154
|
+
iframe.parentNode.removeChild(iframe);
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/** SCROLL REPOSITION */
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Whenever the user scrolls the page
|
|
163
|
+
*/
|
|
164
|
+
handleScrollEvent() {
|
|
165
|
+
// Remove the in form menu
|
|
166
|
+
this.scrollableFieldParent = DomUtils.getScrollParent(this.field);
|
|
167
|
+
this.scrollableFieldParent.addEventListener('scroll', this.removeMenuIframe);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/** DESTROY */
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Remove all listener and iframe to clean the page and avoid issue on extension update
|
|
174
|
+
*/
|
|
175
|
+
destroy() {
|
|
176
|
+
this.field.removeEventListener("blur", this.removeInFormMenu);
|
|
177
|
+
this.scrollableFieldParent.removeEventListener('scroll', this.removeMenuIframe);
|
|
178
|
+
this.removeMenuIframe();
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export default InFormMenuField;
|