passbolt-browser-extension 5.13.0 → 5.14.2
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/.devcontainer/Dockerfile +33 -3
- package/.devcontainer/devcontainer-lock.json +9 -0
- package/.devcontainer/post-start.sh +1 -2
- package/.github/workflows/codeql-analysis.yml +2 -1
- package/.github/workflows/release_candidate.yaml +3 -1
- package/.gitlab-ci.yml +1 -0
- package/CHANGELOG.md +202 -70
- package/CODEOWNERS +2 -0
- package/RELEASE_NOTES.md +4 -2
- package/package.json +9 -7
- package/renovate.json +6 -0
- package/src/all/background_page/controller/InformMenuController/InformMenuController.js +2 -5
- package/src/all/background_page/controller/InformMenuController/InformMenuController.test.js +31 -1
- package/src/all/background_page/controller/account/getAndInitializeAccountLocaleController.js +1 -1
- package/src/all/background_page/controller/account/getAndInitializeAccountLocaleController.test.js +6 -14
- package/src/all/background_page/controller/account/updatePrivateKeyController.js +7 -5
- package/src/all/background_page/controller/account/updatePrivateKeyController.test.js +18 -13
- package/src/all/background_page/controller/accountRecovery/accountRecoveryGenerateOrganizationKeyController.js +4 -2
- package/src/all/background_page/controller/accountRecovery/accountRecoveryGenerateOrganizationKeyController.test.js +25 -2
- package/src/all/background_page/controller/accountRecovery/accountRecoveryLoginController.js +1 -1
- package/src/all/background_page/controller/accountRecovery/accountRecoveryLoginController.test.js +10 -5
- package/src/all/background_page/controller/accountRecovery/recoverAccountController.js +6 -2
- package/src/all/background_page/controller/accountRecovery/recoverAccountController.test.js +11 -4
- package/src/all/background_page/controller/auth/authCheckStatus.test.data.js +6 -6
- package/src/all/background_page/controller/auth/authCheckStatusController.js +11 -3
- package/src/all/background_page/controller/auth/authCheckStatusController.test.js +74 -44
- package/src/all/background_page/controller/auth/authIsMfaRequiredController.js +11 -3
- package/src/all/background_page/controller/auth/authIsMfaRequiredController.test.js +18 -9
- package/src/all/background_page/controller/auth/authLoginController.js +1 -1
- package/src/all/background_page/controller/auth/authLoginController.test.js +10 -5
- package/src/all/background_page/controller/autofill/AutofillController.js +3 -3
- package/src/all/background_page/controller/autofill/AutofillController.test.js +20 -12
- package/src/all/background_page/controller/export/exportResourcesFileController.js +6 -3
- package/src/all/background_page/controller/export/exportResourcesFileController.test.js +34 -4
- package/src/all/background_page/controller/extension/onExtensionInstalledController.js +8 -2
- package/src/all/background_page/controller/extension/onExtensionInstalledController.test.js +5 -1
- package/src/all/background_page/controller/group/{getOrFindGroupsController.js → findGroupsByIdsForShareController.js} +9 -10
- package/src/all/background_page/controller/group/{getOrFindGroupsController.test.js → findGroupsByIdsForShareController.test.js} +8 -8
- package/src/all/background_page/controller/group/groupUpdateController.test.js +1 -0
- package/src/all/background_page/controller/import/importResourcesFileController.test.js +8 -1
- package/src/all/background_page/controller/informCallToActionController/informCallToActionController.js +2 -2
- package/src/all/background_page/controller/informCallToActionController/informCallToActionController.test.js +7 -4
- package/src/all/background_page/controller/locale/getLocaleController.js +3 -2
- package/src/all/background_page/controller/metadata/findMetadataTypesSettingsController.test.js +9 -15
- package/src/all/background_page/controller/metadata/getMetadataTypesSettingsController.test.js +9 -15
- package/src/all/background_page/controller/metadata/getOrFindMetadataKeysSettingsController.test.js +12 -22
- package/src/all/background_page/controller/metadata/shareMetadataKeyPrivateController.test.js +14 -2
- package/src/all/background_page/controller/move/moveFolderController.test.js +8 -0
- package/src/all/background_page/controller/move/moveResourcesController.test.js +8 -0
- package/src/all/background_page/controller/passwordExpiry/getOrFindPasswordExpirySettingsController.test.js +13 -8
- package/src/all/background_page/controller/passwordExpiry/savePasswordExpirySettingsController.js +4 -4
- package/src/all/background_page/controller/passwordExpiry/savePasswordExpirySettingsController.test.js +8 -10
- package/src/all/background_page/controller/permission/findPermissionsByIdsForShareController.js +62 -0
- package/src/all/background_page/controller/permission/findPermissionsByIdsForShareController.test.js +71 -0
- package/src/all/background_page/controller/recover/generateRecoverAccountRecoveryRequestKeyController.js +1 -1
- package/src/all/background_page/controller/resource/resourceCreateController.js +11 -4
- package/src/all/background_page/controller/resource/resourceCreateController.test.js +12 -1
- package/src/all/background_page/controller/resource/resourceUpdateController.js +11 -4
- package/src/all/background_page/controller/resource/resourceUpdateController.test.js +35 -2
- package/src/all/background_page/controller/resourceType/getResourceTypesController.js +5 -4
- package/src/all/background_page/controller/resourceType/getResourceTypesController.test.js +5 -2
- package/src/all/background_page/controller/resourceType/updateAllResourceTypesDeletedStatusController.js +3 -2
- package/src/all/background_page/controller/resourceType/updateAllResourceTypesDeletedStatusController.test.js +16 -3
- package/src/all/background_page/controller/secret/findSecretByResourceIdController.js +3 -3
- package/src/all/background_page/controller/secret/findSecretByResourceIdController.test.js +24 -0
- package/src/all/background_page/controller/secretRevision/findResourceSecretRevisionsForDisplayController.js +2 -1
- package/src/all/background_page/controller/setup/generateSetupKeyPairController.js +6 -3
- package/src/all/background_page/controller/setup/generateSetupKeyPairController.test.js +11 -1
- package/src/all/background_page/controller/setup/getAndInitSetupLocaleController.js +1 -1
- package/src/all/background_page/controller/setup/getAndInitSetupLocaleController.test.js +14 -18
- package/src/all/background_page/controller/setup/setSetupLocaleController.js +1 -1
- package/src/all/background_page/controller/setup/setSetupLocaleController.test.js +6 -10
- package/src/all/background_page/controller/setup/signInSetupController.js +6 -2
- package/src/all/background_page/controller/setup/signInSetupController.test.js +10 -5
- package/src/all/background_page/controller/share/shareOneFolderController.test.js +8 -0
- package/src/all/background_page/controller/share/shareResourcesController.test.js +9 -1
- package/src/all/background_page/controller/siteSettings/getOrFindSiteSettingsController.js +59 -0
- package/src/all/background_page/controller/siteSettings/getOrFindSiteSettingsController.test.js +150 -0
- package/src/all/background_page/controller/{group/getOrFindGroupsUsersController.js → user/getOrFindAllUsersController.js} +12 -17
- package/src/all/background_page/controller/user/getOrFindAllUsersController.test.js +55 -0
- package/src/all/background_page/controller/user/getOrFindLoggedInUserController.js +3 -3
- package/src/all/background_page/controller/user/getOrFindLoggedInUserController.test.js +19 -15
- package/src/all/background_page/controller/user/updateUserLocalStorageController.test.js +8 -5
- package/src/all/background_page/event/accountRecoveryEvents.js +4 -4
- package/src/all/background_page/event/appEvents.js +7 -2
- package/src/all/background_page/event/authEvents.js +2 -2
- package/src/all/background_page/event/groupEvents.js +4 -17
- package/src/all/background_page/event/informCallToActionEvents.js +1 -1
- package/src/all/background_page/event/informMenuEvents.js +1 -1
- package/src/all/background_page/event/localeEvents.js +4 -3
- package/src/all/background_page/event/permissionEvents.js +13 -0
- package/src/all/background_page/event/recoverEvents.js +4 -4
- package/src/all/background_page/event/resourceEvents.js +6 -15
- package/src/all/background_page/event/resourceTypeEvents.js +4 -3
- package/src/all/background_page/event/setupEvents.js +4 -4
- package/src/all/background_page/event/siteSettingsEvents.js +29 -0
- package/src/all/background_page/event/userEvents.js +4 -8
- package/src/all/background_page/index.js +0 -37
- package/src/all/background_page/model/entity/account/abstractAccountEntity.js +2 -2
- package/src/all/background_page/model/entity/account/accountAccountRecoveryEntity.js +7 -17
- package/src/all/background_page/model/entity/account/accountEntity.js +7 -14
- package/src/all/background_page/model/entity/account/accountKitEntity.js +1 -2
- package/src/all/background_page/model/entity/account/accountRecoverEntity.js +4 -14
- package/src/all/background_page/model/entity/account/accountSetupEntity.js +4 -14
- package/src/all/background_page/model/entity/account/accountTemporaryEntity.js +2 -5
- package/src/all/background_page/model/entity/gpgkey/generate/generateGpgKeyPairOptionsEntity.test.js +5 -5
- package/src/all/background_page/model/entity/localStorage/localStorageMetadataEntity.js +49 -0
- package/src/all/background_page/model/entity/localStorage/localStorageMetadataEntity.test.data.js +23 -0
- package/src/all/background_page/model/entity/localStorage/localStorageMetadataEntity.test.js +51 -0
- package/src/all/background_page/model/entity/{organizationSettings/organizationSettingsEntity.js → siteSettings/siteSettingsEntity.js} +17 -24
- package/src/all/background_page/model/entity/{organizationSettings/organizationSettingsEntity.test.data.js → siteSettings/siteSettingsEntity.test.data.js} +9 -9
- package/src/all/background_page/model/entity/{organizationSettings/organizationSettingsEntity.test.js → siteSettings/siteSettingsEntity.test.js} +30 -39
- package/src/all/background_page/model/entity/user/userEntity.test.js +6 -6
- package/src/all/background_page/model/export/resources/resourcesKdbxExporter.js +40 -3
- package/src/all/background_page/model/export/resources/resourcesKdbxExporter.test.js +122 -0
- package/src/all/background_page/model/import/resources/resourcesKdbxImportParser.js +1 -1
- package/src/all/background_page/model/locale/localeModel.js +13 -8
- package/src/all/background_page/model/passwordExpiry/passwordExpirySettingsModel.js +6 -6
- package/src/all/background_page/model/passwordExpiry/passwordExpirySettingsModel.test.js +3 -2
- package/src/all/background_page/model/resource/resourceModel.js +4 -4
- package/src/all/background_page/model/user/userModel.js +7 -28
- package/src/all/background_page/model/user/userModel.test.js +51 -99
- package/src/all/background_page/pagemod/appBootstrapPagemod.js +4 -1
- package/src/all/background_page/pagemod/appBootstrapPagemod.test.js +5 -2
- package/src/all/background_page/pagemod/appPagemod.js +32 -6
- package/src/all/background_page/pagemod/appPagemod.test.js +22 -10
- package/src/all/background_page/pagemod/authPagemod.js +2 -10
- package/src/all/background_page/pagemod/authPagemod.test.js +4 -4
- package/src/all/background_page/pagemod/pagemodManager.test.js +5 -2
- package/src/all/background_page/pagemod/quickAccessPagemod.js +2 -2
- package/src/all/background_page/pagemod/quickAccessPagemod.test.js +4 -4
- package/src/all/background_page/pagemod/recoverPagemod.js +2 -2
- package/src/all/background_page/pagemod/recoverPagemod.test.js +6 -0
- package/src/all/background_page/pagemod/setupPagemod.js +2 -2
- package/src/all/background_page/pagemod/setupPagemod.test.js +6 -0
- package/src/all/background_page/pagemod/webIntegrationPagemod.js +21 -2
- package/src/all/background_page/pagemod/webIntegrationPagemod.test.js +16 -25
- package/src/all/background_page/service/account/getActiveAccountService.js +2 -3
- package/src/all/background_page/service/account/getLegacyAccountService.js +3 -14
- package/src/all/background_page/service/account/updateSsoCredentialsService.js +9 -5
- package/src/all/background_page/service/api/group/groupApiService.js +9 -16
- package/src/all/background_page/service/api/group/groupApiService.test.js +59 -26
- package/src/all/background_page/service/api/siteSettings/siteSettingsApiService.js +46 -0
- package/src/all/background_page/service/api/siteSettings/siteSettingsApiService.test.js +63 -0
- package/src/all/background_page/service/auth/checkAuthStatusService.js +27 -14
- package/src/all/background_page/service/auth/checkAuthStatusService.test.js +80 -62
- package/src/all/background_page/service/auth/postLoginService.js +3 -3
- package/src/all/background_page/service/auth/postLoginService.test.js +4 -4
- package/src/all/background_page/service/auth/startLoopAuthSessionCheckService.js +5 -1
- package/src/all/background_page/service/auth/startLoopAuthSessionCheckService.test.js +14 -8
- package/src/all/background_page/service/authenticationStatusService.js +13 -18
- package/src/all/background_page/service/authenticationStatusService.test.js +9 -6
- package/src/all/background_page/service/crypto/generateGpgKeyPairService.test.js +5 -5
- package/src/all/background_page/service/crypto/getGpgKeyCreationDateService.js +7 -6
- package/src/all/background_page/service/crypto/getGpgKeyCreationDateService.test.js +10 -7
- package/src/all/background_page/service/extension/onExtensionUpdateAvailableService.js +7 -2
- package/src/all/background_page/service/extension/onExtensionUpdateAvailableService.test.js +5 -5
- package/src/all/background_page/service/group/findGroupsService.js +42 -1
- package/src/all/background_page/service/group/findGroupsService.test.js +82 -0
- package/src/all/background_page/service/group/groupUpdateSecretsCryptoService.js +82 -0
- package/src/all/background_page/service/group/groupUpdateSecretsCryptoService.test.js +102 -0
- package/src/all/background_page/service/group/groupUpdateService.js +49 -78
- package/src/all/background_page/service/group/groupUpdateService.test.js +136 -0
- package/src/all/background_page/service/localStorage/localStorageService.js +8 -6
- package/src/all/background_page/service/localStorage/localStorageService.test.js +33 -15
- package/src/all/background_page/service/local_storage/abstractLocalStorage.js +193 -0
- package/src/all/background_page/service/local_storage/abstractLocalStorage.test.data.js +45 -0
- package/src/all/background_page/service/local_storage/abstractLocalStorage.test.js +271 -0
- package/src/all/background_page/service/local_storage/activeSessionLocalStorage.js +105 -0
- package/src/all/background_page/service/local_storage/activeSessionLocalStorage.test.js +153 -0
- package/src/all/background_page/service/local_storage/rbacLocalStorage.js +10 -82
- package/src/all/background_page/service/local_storage/rbacLocalStorage.test.js +8 -8
- package/src/all/background_page/service/local_storage/resourceTypeLocalStorage.js +10 -43
- package/src/all/background_page/service/local_storage/resourceTypeLocalStorage.test.js +68 -0
- package/src/all/background_page/service/local_storage/siteSettingsLocalStorage.js +104 -0
- package/src/all/background_page/service/local_storage/siteSettingsLocalStorage.test.js +114 -0
- package/src/all/background_page/service/local_storage/userMeLocalStorage.js +50 -0
- package/src/all/background_page/service/{sessionStorage/userMeSessionStorageService.test.js → local_storage/userMeLocalStorage.test.js} +55 -36
- package/src/all/background_page/service/metadata/encryptMetadataService.js +3 -3
- package/src/all/background_page/service/metadata/encryptMetadataService.test.js +11 -11
- package/src/all/background_page/service/metadata/findAndUpdateMetadataSettingsLocalStorageService.js +4 -4
- package/src/all/background_page/service/metadata/findAndUpdateMetadataSettingsLocalStorageService.test.js +18 -16
- package/src/all/background_page/service/metadata/getOrFindMetadataSettingsService.test.js +6 -8
- package/src/all/background_page/service/metadata/rotateMetadata/rotateResourcesMetadataKeyService.test.js +4 -4
- package/src/all/background_page/service/metadata/shareMetadataKeyPrivateService.js +3 -3
- package/src/all/background_page/service/metadata/shareMetadataKeyPrivateService.test.js +1 -1
- package/src/all/background_page/service/metadata/verifyOrTrustMetadataKeyService.js +4 -4
- package/src/all/background_page/service/metadata/verifyOrTrustMetadataKeyService.test.js +9 -7
- package/src/all/background_page/service/migrateMetadata/migrateMetadataResourcesService.js +4 -4
- package/src/all/background_page/service/migrateMetadata/migrateMetadataResourcesService.test.js +6 -6
- package/src/all/background_page/service/rbac/findAndUpdateRbacsLocalStorageService.js +2 -2
- package/src/all/background_page/service/rbac/getOrFindRbacService.js +1 -1
- package/src/all/background_page/service/resource/create/resourceCreateService.js +41 -51
- package/src/all/background_page/service/resource/create/resourceCreateService.test.js +100 -98
- package/src/all/background_page/service/resource/export/exportResourcesService.js +7 -7
- package/src/all/background_page/service/resource/findAndUpdateResourcesLocalStorageService.js +4 -4
- package/src/all/background_page/service/resource/findResourcesService.js +13 -16
- package/src/all/background_page/service/resource/findResourcesService.test.js +12 -11
- package/src/all/background_page/service/resource/getOrFindResourcesService.js +3 -3
- package/src/all/background_page/service/resource/import/ImportResourcesService.js +9 -9
- package/src/all/background_page/service/resource/import/ImportResourcesService.test.js +30 -15
- package/src/all/background_page/service/resource/update/resourceUpdateService.js +38 -19
- package/src/all/background_page/service/resource/update/resourceUpdateService.test.js +64 -31
- package/src/all/background_page/service/resourceType/getOrFindResourceTypesService.js +49 -0
- package/src/all/background_page/service/resourceType/getOrFindResourceTypesService.test.js +61 -0
- package/src/all/background_page/service/resourceType/getSecretSchemaResourceTypeService.js +44 -0
- package/src/all/background_page/service/resourceType/updateResourceTypesService.js +6 -4
- package/src/all/background_page/service/resourceType/updateResourceTypesService.test.js +19 -14
- package/src/all/background_page/service/secretRevisions/findAndDecryptSecretRevisionsService.js +5 -4
- package/src/all/background_page/service/secretRevisions/findAndDecryptSecretRevisionsService.test.js +16 -9
- package/src/all/background_page/service/share/shareResourceService.js +4 -4
- package/src/all/background_page/service/share/shareResourceService.test.js +6 -6
- package/src/all/background_page/service/siteSettings/findAndUpdateSiteSettingsLocalStorageService.js +77 -0
- package/src/all/background_page/service/siteSettings/findAndUpdateSiteSettingsLocalStorageService.test.js +130 -0
- package/src/all/background_page/service/siteSettings/findSiteSettingsService.js +47 -0
- package/src/all/background_page/service/siteSettings/findSiteSettingsService.test.js +68 -0
- package/src/all/background_page/service/siteSettings/getOrFindSiteSettingsService.js +84 -0
- package/src/all/background_page/service/siteSettings/getOrFindSiteSettingsService.test.js +175 -0
- package/src/all/background_page/service/siteSettings/siteSettingsRuntimeCache.js +70 -0
- package/src/all/background_page/service/sso/generateSsoKitService.test.js +2 -2
- package/src/all/background_page/service/toolbar/toolbarService.js +6 -4
- package/src/all/background_page/service/toolbar/toolbarService.test.js +14 -13
- package/src/all/background_page/service/user/findAndUpdateUsersLocalStorageService.js +4 -4
- package/src/all/background_page/service/user/findAndUpdateUsersLocalStorageService.test.js +3 -3
- package/src/all/background_page/service/user/getOrFindMeService.js +64 -0
- package/src/all/background_page/service/user/getOrFindMeService.test.js +65 -0
- package/src/all/background_page/service/userKeyPolicies/findUserKeyPoliciesSettingsService.js +5 -4
- package/src/all/background_page/service/userKeyPolicies/findUserKeyPoliciesSettingsService.test.js +12 -11
- package/src/all/background_page/service/validator/appEmailValidatorService.js +11 -6
- package/src/all/background_page/service/validator/appEmailValidatorService.test.js +11 -11
- package/src/all/common/polyfill/browserPolyfill.js +8 -8
- package/src/all/locales/cs-CZ/common.json +1 -4
- package/src/all/locales/de-DE/common.json +1 -4
- package/src/all/locales/en-UK/common.json +0 -3
- package/src/all/locales/es-ES/common.json +1 -4
- package/src/all/locales/fr-FR/common.json +1 -4
- package/src/all/locales/it-IT/common.json +1 -4
- package/src/all/locales/ja-JP/common.json +1 -4
- package/src/all/locales/ko-KR/common.json +0 -3
- package/src/all/locales/lt-LT/common.json +1 -4
- package/src/all/locales/nl-NL/common.json +1 -4
- package/src/all/locales/pl-PL/common.json +1 -4
- package/src/all/locales/pt-BR/common.json +1 -4
- package/src/all/locales/ro-RO/common.json +1 -4
- package/src/all/locales/ru-RU/common.json +1 -4
- package/src/all/locales/sl-SI/common.json +1 -4
- package/src/all/locales/sv-SE/common.json +1 -4
- package/src/all/locales/uk-UA/common.json +1 -4
- package/src/all/webAccessibleResources/js/app/QuickAccess.js +7 -0
- package/src/chrome/manifest.json +1 -1
- package/src/chrome-mv3/manifest.json +1 -1
- package/src/chrome-mv3/offscreens/service/group/addUsersToGroupOffscreenService.js +132 -0
- package/src/chrome-mv3/offscreens/service/group/addUsersToGroupOffscreenService.test.js +125 -0
- package/src/chrome-mv3/offscreens/service/offscreen/handleOffscreenRequestService.js +4 -0
- package/src/chrome-mv3/serviceWorker/service/addUsersToGroup/requestAddUsersToGroupOffscreenService.js +83 -0
- package/src/chrome-mv3/serviceWorker/service/addUsersToGroup/requestAddUsersToGroupOffscreenService.test.js +116 -0
- package/src/chrome-mv3/serviceWorker/service/addUsersToGroup/responseAddUsersToGroupOffscreenService.js +99 -0
- package/src/chrome-mv3/serviceWorker/service/addUsersToGroup/responseAddUsersToGroupOffscreenService.test.data.js +45 -0
- package/src/chrome-mv3/serviceWorker/service/addUsersToGroup/responseAddUsersToGroupOffscreenService.test.js +87 -0
- package/src/chrome-mv3/serviceWorker/service/network/requestFetchOffscreenService.js +0 -1
- package/src/chrome-mv3/serviceWorker/service/offscreen/handleOffscreenResponseService.js +15 -0
- package/src/firefox/manifest.json +1 -1
- package/src/safari/background_page/index.js +0 -37
- package/src/safari/common/polyfill/safariBrowserPolyfill.js +10 -10
- package/src/safari/manifest.json +1 -1
- package/test/jest.setup.js +4 -2
- package/src/all/background_page/controller/group/getOrFindGroupsUsersController.test.js +0 -69
- package/src/all/background_page/controller/organizationSettings/getOrganizationSettingsController.js +0 -55
- package/src/all/background_page/controller/organizationSettings/getOrganizationSettingsController.test.js +0 -45
- package/src/all/background_page/controller/resource/findAllByIdsForDisplayPermissionsController.js +0 -76
- package/src/all/background_page/controller/resource/findAllByIdsForDisplayPermissionsController.test.js +0 -102
- package/src/all/background_page/event/organizationSettingsEvents.js +0 -37
- package/src/all/background_page/model/organizationSettings/organizationSettingsModel.js +0 -93
- package/src/all/background_page/model/resourceType/resourceTypeModel.js +0 -72
- package/src/all/background_page/model/resourceType/resourceTypeModel.test.js +0 -101
- package/src/all/background_page/service/api/organizationSettings/organizationSettingsService.js +0 -58
- package/src/all/background_page/service/group/getOrFindGroupsService.js +0 -65
- package/src/all/background_page/service/group/getOrFindGroupsService.test.js +0 -168
- package/src/all/background_page/service/group/getOrFindGroupsUsersService.js +0 -51
- package/src/all/background_page/service/group/getOrFindGroupsUsersService.test.js +0 -94
- package/src/all/background_page/service/local_storage/authStatusLocalStorage.js +0 -70
- package/src/all/background_page/service/sessionStorage/userMeSessionStorageService.js +0 -94
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Passbolt ~ Open source password manager for teams
|
|
3
|
+
* Copyright (c) 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) 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 6.0.0
|
|
13
|
+
*/
|
|
14
|
+
import SiteSettingsEntity from "passbolt-styleguide/src/shared/models/entity/siteSettings/siteSettingsEntity";
|
|
15
|
+
import PassboltApiFetchError from "passbolt-styleguide/src/shared/lib/Error/PassboltApiFetchError";
|
|
16
|
+
import SiteSettingsApiService from "../api/siteSettings/siteSettingsApiService";
|
|
17
|
+
|
|
18
|
+
class FindSiteSettingsService {
|
|
19
|
+
/**
|
|
20
|
+
* @param {ApiClientOptions} apiClientOptions
|
|
21
|
+
*/
|
|
22
|
+
constructor(apiClientOptions) {
|
|
23
|
+
this.siteSettingsApiService = new SiteSettingsApiService(apiClientOptions);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Fetch the site settings from the API and return them as a SiteSettingsEntity.
|
|
28
|
+
* On the cloud, a disabled organization returns 403 — that case is normalized to a
|
|
29
|
+
* disabled site-settings entity to preserve historical behavior.
|
|
30
|
+
* @returns {Promise<SiteSettingsEntity>}
|
|
31
|
+
*/
|
|
32
|
+
async findSiteSettings() {
|
|
33
|
+
let dto;
|
|
34
|
+
try {
|
|
35
|
+
dto = await this.siteSettingsApiService.findSiteSettings();
|
|
36
|
+
} catch (error) {
|
|
37
|
+
if (error instanceof PassboltApiFetchError && error?.data?.code === 403) {
|
|
38
|
+
dto = SiteSettingsEntity.disabledSiteSettings;
|
|
39
|
+
} else {
|
|
40
|
+
throw error;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return new SiteSettingsEntity(dto);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export default FindSiteSettingsService;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Passbolt ~ Open source password manager for teams
|
|
3
|
+
* Copyright (c) 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) 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 6.0.0
|
|
13
|
+
*/
|
|
14
|
+
import SiteSettingsEntity from "passbolt-styleguide/src/shared/models/entity/siteSettings/siteSettingsEntity";
|
|
15
|
+
import PassboltApiFetchError from "passbolt-styleguide/src/shared/lib/Error/PassboltApiFetchError";
|
|
16
|
+
import { defaultApiClientOptions } from "passbolt-styleguide/src/shared/lib/apiClient/apiClientOptions.test.data";
|
|
17
|
+
import { defaultProSiteSettings } from "passbolt-styleguide/src/shared/models/entity/siteSettings/siteSettingsEntity.test.data";
|
|
18
|
+
import SiteSettingsApiService from "../api/siteSettings/siteSettingsApiService";
|
|
19
|
+
import FindSiteSettingsService from "./findSiteSettingsService";
|
|
20
|
+
|
|
21
|
+
beforeEach(() => {
|
|
22
|
+
jest.clearAllMocks();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
describe("FindSiteSettingsService", () => {
|
|
26
|
+
describe("::findSiteSettings", () => {
|
|
27
|
+
it("returns a SiteSettingsEntity built from the API DTO", async () => {
|
|
28
|
+
expect.assertions(2);
|
|
29
|
+
const dto = defaultProSiteSettings();
|
|
30
|
+
jest.spyOn(SiteSettingsApiService.prototype, "findSiteSettings").mockResolvedValue(dto);
|
|
31
|
+
|
|
32
|
+
const service = new FindSiteSettingsService(defaultApiClientOptions());
|
|
33
|
+
const entity = await service.findSiteSettings();
|
|
34
|
+
|
|
35
|
+
expect(entity).toBeInstanceOf(SiteSettingsEntity);
|
|
36
|
+
expect(entity.toDto()).toEqual(dto);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it("returns a disabled SiteSettingsEntity on 403 (cloud disabled-org)", async () => {
|
|
40
|
+
expect.assertions(2);
|
|
41
|
+
const error = new PassboltApiFetchError("Forbidden", { code: 403 });
|
|
42
|
+
jest.spyOn(SiteSettingsApiService.prototype, "findSiteSettings").mockRejectedValue(error);
|
|
43
|
+
|
|
44
|
+
const service = new FindSiteSettingsService(defaultApiClientOptions());
|
|
45
|
+
const entity = await service.findSiteSettings();
|
|
46
|
+
|
|
47
|
+
expect(entity).toBeInstanceOf(SiteSettingsEntity);
|
|
48
|
+
expect(entity.toDto()).toEqual({ status: "disabled" });
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it("rethrows non-403 API errors", async () => {
|
|
52
|
+
expect.assertions(1);
|
|
53
|
+
const error = new PassboltApiFetchError("Server error", { code: 500 });
|
|
54
|
+
jest.spyOn(SiteSettingsApiService.prototype, "findSiteSettings").mockRejectedValue(error);
|
|
55
|
+
|
|
56
|
+
const service = new FindSiteSettingsService(defaultApiClientOptions());
|
|
57
|
+
await expect(service.findSiteSettings()).rejects.toThrow(PassboltApiFetchError);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it("rethrows non-PassboltApiFetchError errors", async () => {
|
|
61
|
+
expect.assertions(1);
|
|
62
|
+
jest.spyOn(SiteSettingsApiService.prototype, "findSiteSettings").mockRejectedValue(new Error("network down"));
|
|
63
|
+
|
|
64
|
+
const service = new FindSiteSettingsService(defaultApiClientOptions());
|
|
65
|
+
await expect(service.findSiteSettings()).rejects.toThrow("network down");
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
});
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Passbolt ~ Open source password manager for teams
|
|
3
|
+
* Copyright (c) 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) 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 6.0.0
|
|
13
|
+
*/
|
|
14
|
+
import SiteSettingsEntity from "passbolt-styleguide/src/shared/models/entity/siteSettings/siteSettingsEntity";
|
|
15
|
+
import SiteSettingsLocalStorage from "../local_storage/siteSettingsLocalStorage";
|
|
16
|
+
import FindAndUpdateSiteSettingsLocalStorageService from "./findAndUpdateSiteSettingsLocalStorageService";
|
|
17
|
+
import SiteSettingsRuntimeCache from "./siteSettingsRuntimeCache";
|
|
18
|
+
import CheckAuthStatusService from "../auth/checkAuthStatusService";
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Read entry point for site settings. Successor of the legacy
|
|
22
|
+
* 'OrganizationSettingsModel.getOrFind'.
|
|
23
|
+
*
|
|
24
|
+
* On 'refreshCache=true' (default), the cache step is skipped — every call goes through
|
|
25
|
+
* to the API. Callers that explicitly opt into cached reads pass 'refreshCache=false',
|
|
26
|
+
* which picks the cache by authentication state:
|
|
27
|
+
* - Authenticated: SiteSettingsLocalStorage (the offline-mode store), else the API.
|
|
28
|
+
* - Anonymous: SiteSettingsRuntimeCache (in-memory; populated by any fetch this
|
|
29
|
+
* session), else the API.
|
|
30
|
+
*
|
|
31
|
+
* The API fall-through goes through FindAndUpdateSiteSettingsLocalStorageService, which
|
|
32
|
+
* refreshes the caches. Anonymous callers never read SiteSettingsLocalStorage.
|
|
33
|
+
*/
|
|
34
|
+
export default class GetOrFindSiteSettingsService {
|
|
35
|
+
/**
|
|
36
|
+
* @param {AccountEntity} account
|
|
37
|
+
* @param {ApiClientOptions} apiClientOptions
|
|
38
|
+
*/
|
|
39
|
+
constructor(account, apiClientOptions) {
|
|
40
|
+
this.account = account;
|
|
41
|
+
this.siteSettingsLocalStorage = new SiteSettingsLocalStorage(account);
|
|
42
|
+
this.findAndUpdateSiteSettingsLocalStorageService = new FindAndUpdateSiteSettingsLocalStorageService(
|
|
43
|
+
account,
|
|
44
|
+
apiClientOptions,
|
|
45
|
+
);
|
|
46
|
+
this.checkAuthStatusService = new CheckAuthStatusService(account, apiClientOptions);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* @param {boolean} [refreshCache=true] When true (default), bypass caches and hit the API.
|
|
51
|
+
* Pass false to read from the cache selected by authentication state (LS when
|
|
52
|
+
* authenticated, runtime cache when anonymous) before falling back to the API.
|
|
53
|
+
* @returns {Promise<SiteSettingsEntity>}
|
|
54
|
+
*/
|
|
55
|
+
async getOrFind(refreshCache = true) {
|
|
56
|
+
if (!refreshCache) {
|
|
57
|
+
const activeSession = await this.checkAuthStatusService.checkAuthStatus();
|
|
58
|
+
|
|
59
|
+
if (activeSession.isAuthenticated) {
|
|
60
|
+
const lsDto = await this.siteSettingsLocalStorage.get();
|
|
61
|
+
if (lsDto) {
|
|
62
|
+
const siteSettings = new SiteSettingsEntity(lsDto);
|
|
63
|
+
/*
|
|
64
|
+
* Mirror the persisted settings into the in-memory runtime cache. The cache is
|
|
65
|
+
* service-worker-lifetime and is flushed on login (postLoginService) and lost on
|
|
66
|
+
* service-worker restart, whereas SiteSettingsLocalStorage survives both. Seeding it
|
|
67
|
+
* here keeps AppEmailValidatorService.validate - which reads SiteSettingsRuntimeCache
|
|
68
|
+
* synchronously to validate account usernames - in sync with the persisted settings,
|
|
69
|
+
* so a custom email validation regex is honored even after the cache has been dropped.
|
|
70
|
+
*/
|
|
71
|
+
SiteSettingsRuntimeCache.set(siteSettings);
|
|
72
|
+
return siteSettings;
|
|
73
|
+
}
|
|
74
|
+
} else {
|
|
75
|
+
const cachedDto = SiteSettingsRuntimeCache.get(this.account.id);
|
|
76
|
+
if (cachedDto) {
|
|
77
|
+
return new SiteSettingsEntity(cachedDto);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return this.findAndUpdateSiteSettingsLocalStorageService.findAndUpdateAll();
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Passbolt ~ Open source password manager for teams
|
|
3
|
+
* Copyright (c) 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) 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 6.0.0
|
|
13
|
+
*/
|
|
14
|
+
import SiteSettingsEntity from "passbolt-styleguide/src/shared/models/entity/siteSettings/siteSettingsEntity";
|
|
15
|
+
import { defaultApiClientOptions } from "passbolt-styleguide/src/shared/lib/apiClient/apiClientOptions.test.data";
|
|
16
|
+
import AccountEntity from "../../model/entity/account/accountEntity";
|
|
17
|
+
import { defaultAccountDto } from "../../model/entity/account/accountEntity.test.data";
|
|
18
|
+
import { defaultProSiteSettings } from "passbolt-styleguide/src/shared/models/entity/siteSettings/siteSettingsEntity.test.data";
|
|
19
|
+
import SiteSettingsLocalStorage from "../local_storage/siteSettingsLocalStorage";
|
|
20
|
+
import SiteSettingsRuntimeCache from "./siteSettingsRuntimeCache";
|
|
21
|
+
import GetOrFindSiteSettingsService from "./getOrFindSiteSettingsService";
|
|
22
|
+
import OnlineSessionEntity from "passbolt-styleguide/src/shared/models/entity/session/onlineSessionEntity";
|
|
23
|
+
import CheckAuthStatusService from "../auth/checkAuthStatusService";
|
|
24
|
+
|
|
25
|
+
beforeEach(() => {
|
|
26
|
+
jest.clearAllMocks();
|
|
27
|
+
SiteSettingsRuntimeCache.flushAll();
|
|
28
|
+
SiteSettingsLocalStorage._runtimeCachedData = {};
|
|
29
|
+
// Default to "not authenticated" so anything that doesn't explicitly re-mock stays on the safe path.
|
|
30
|
+
jest
|
|
31
|
+
.spyOn(CheckAuthStatusService.prototype, "checkAuthStatus")
|
|
32
|
+
.mockResolvedValue(new OnlineSessionEntity({ is_authenticated: false }));
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
describe("GetOrFindSiteSettingsService", () => {
|
|
36
|
+
let account, apiClientOptions, service;
|
|
37
|
+
|
|
38
|
+
beforeEach(async () => {
|
|
39
|
+
account = new AccountEntity(defaultAccountDto());
|
|
40
|
+
apiClientOptions = defaultApiClientOptions();
|
|
41
|
+
service = new GetOrFindSiteSettingsService(account, apiClientOptions);
|
|
42
|
+
await service.siteSettingsLocalStorage.flush();
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
describe("::getOrFind (refreshCache=true, default)", () => {
|
|
46
|
+
it("always hits the API even when the runtime cache is populated", async () => {
|
|
47
|
+
expect.assertions(3);
|
|
48
|
+
const stale = new SiteSettingsEntity({ ...defaultProSiteSettings(), serverTimeDiff: 999 });
|
|
49
|
+
SiteSettingsRuntimeCache.set(stale);
|
|
50
|
+
|
|
51
|
+
const fresh = new SiteSettingsEntity(defaultProSiteSettings());
|
|
52
|
+
const apiSpy = jest
|
|
53
|
+
.spyOn(service.findAndUpdateSiteSettingsLocalStorageService.findSiteSettingsService, "findSiteSettings")
|
|
54
|
+
.mockResolvedValue(fresh);
|
|
55
|
+
|
|
56
|
+
const result = await service.getOrFind();
|
|
57
|
+
|
|
58
|
+
expect(apiSpy).toHaveBeenCalledTimes(1);
|
|
59
|
+
expect(result.toDto()).toEqual(fresh.toDto());
|
|
60
|
+
expect(SiteSettingsRuntimeCache.get()).toEqual(fresh.toDto());
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it("never reads local storage on this path", async () => {
|
|
64
|
+
expect.assertions(2);
|
|
65
|
+
const lsSpy = jest.spyOn(service.siteSettingsLocalStorage, "get");
|
|
66
|
+
const apiSpy = jest
|
|
67
|
+
.spyOn(service.findAndUpdateSiteSettingsLocalStorageService.findSiteSettingsService, "findSiteSettings")
|
|
68
|
+
.mockResolvedValue(new SiteSettingsEntity(defaultProSiteSettings()));
|
|
69
|
+
|
|
70
|
+
await service.getOrFind();
|
|
71
|
+
|
|
72
|
+
expect(lsSpy).not.toHaveBeenCalled();
|
|
73
|
+
expect(apiSpy).toHaveBeenCalledTimes(1);
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
describe("::getOrFind (refreshCache=false) — authenticated", () => {
|
|
78
|
+
beforeEach(() => {
|
|
79
|
+
jest
|
|
80
|
+
.spyOn(CheckAuthStatusService.prototype, "checkAuthStatus")
|
|
81
|
+
.mockResolvedValue(new OnlineSessionEntity({ is_authenticated: true }));
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it("returns from local storage when populated; no API call", async () => {
|
|
85
|
+
expect.assertions(3);
|
|
86
|
+
const dto = defaultProSiteSettings();
|
|
87
|
+
await service.siteSettingsLocalStorage.set(new SiteSettingsEntity(dto));
|
|
88
|
+
const apiSpy = jest.spyOn(
|
|
89
|
+
service.findAndUpdateSiteSettingsLocalStorageService.findSiteSettingsService,
|
|
90
|
+
"findSiteSettings",
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
const result = await service.getOrFind(false);
|
|
94
|
+
|
|
95
|
+
expect(result.toDto()).toEqual(dto);
|
|
96
|
+
expect(apiSpy).not.toHaveBeenCalled();
|
|
97
|
+
// The local storage read must also seed the runtime cache (see next test for why).
|
|
98
|
+
expect(SiteSettingsRuntimeCache.get()).toEqual(dto);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it("seeds the runtime cache from local storage so the synchronous username validator stays consistent", async () => {
|
|
102
|
+
/*
|
|
103
|
+
* Regression: SiteSettingsRuntimeCache is the ONLY store AppEmailValidatorService reads
|
|
104
|
+
* (synchronously, while constructing a user entity). It is flushed on login and lost on
|
|
105
|
+
* service-worker restart, whereas SiteSettingsLocalStorage survives both. An authenticated
|
|
106
|
+
* read that hits local storage must therefore repopulate the runtime cache, otherwise a
|
|
107
|
+
* custom email validation regex would be dropped and valid usernames rejected.
|
|
108
|
+
*/
|
|
109
|
+
expect.assertions(3);
|
|
110
|
+
const dto = defaultProSiteSettings();
|
|
111
|
+
await service.siteSettingsLocalStorage.set(new SiteSettingsEntity(dto));
|
|
112
|
+
// Emulate a flushed / post-restart runtime cache while local storage still holds the settings.
|
|
113
|
+
SiteSettingsRuntimeCache.flushAll();
|
|
114
|
+
expect(SiteSettingsRuntimeCache.get()).toBeNull();
|
|
115
|
+
const apiSpy = jest.spyOn(
|
|
116
|
+
service.findAndUpdateSiteSettingsLocalStorageService.findSiteSettingsService,
|
|
117
|
+
"findSiteSettings",
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
await service.getOrFind(false);
|
|
121
|
+
|
|
122
|
+
expect(SiteSettingsRuntimeCache.get()).toEqual(dto);
|
|
123
|
+
expect(apiSpy).not.toHaveBeenCalled();
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it("ignores the runtime cache and falls through to the API on a local storage miss", async () => {
|
|
127
|
+
expect.assertions(2);
|
|
128
|
+
// Populate the runtime cache but leave LS empty: an authenticated read must not use
|
|
129
|
+
// the runtime cache, so it falls through to the API.
|
|
130
|
+
SiteSettingsRuntimeCache.set(new SiteSettingsEntity({ ...defaultProSiteSettings(), serverTimeDiff: 999 }));
|
|
131
|
+
const dto = defaultProSiteSettings();
|
|
132
|
+
const apiSpy = jest
|
|
133
|
+
.spyOn(service.findAndUpdateSiteSettingsLocalStorageService.findSiteSettingsService, "findSiteSettings")
|
|
134
|
+
.mockResolvedValue(new SiteSettingsEntity(dto));
|
|
135
|
+
|
|
136
|
+
const result = await service.getOrFind(false);
|
|
137
|
+
|
|
138
|
+
expect(apiSpy).toHaveBeenCalledTimes(1);
|
|
139
|
+
expect(result.toDto()).toEqual(dto);
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
describe("::getOrFind (refreshCache=false) — unauthenticated", () => {
|
|
144
|
+
it("returns from the runtime cache when populated; no LS read; no API call", async () => {
|
|
145
|
+
expect.assertions(3);
|
|
146
|
+
const dto = defaultProSiteSettings();
|
|
147
|
+
SiteSettingsRuntimeCache.set(new SiteSettingsEntity(dto));
|
|
148
|
+
const lsSpy = jest.spyOn(service.siteSettingsLocalStorage, "get");
|
|
149
|
+
const apiSpy = jest.spyOn(
|
|
150
|
+
service.findAndUpdateSiteSettingsLocalStorageService.findSiteSettingsService,
|
|
151
|
+
"findSiteSettings",
|
|
152
|
+
);
|
|
153
|
+
|
|
154
|
+
const result = await service.getOrFind(false);
|
|
155
|
+
|
|
156
|
+
expect(result.toDto()).toEqual(dto);
|
|
157
|
+
expect(lsSpy).not.toHaveBeenCalled();
|
|
158
|
+
expect(apiSpy).not.toHaveBeenCalled();
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it("skips local storage entirely on runtime miss; falls through to the API", async () => {
|
|
162
|
+
expect.assertions(2);
|
|
163
|
+
const lsSpy = jest.spyOn(service.siteSettingsLocalStorage, "get");
|
|
164
|
+
const dto = defaultProSiteSettings();
|
|
165
|
+
jest
|
|
166
|
+
.spyOn(service.findAndUpdateSiteSettingsLocalStorageService.findSiteSettingsService, "findSiteSettings")
|
|
167
|
+
.mockResolvedValue(new SiteSettingsEntity(dto));
|
|
168
|
+
|
|
169
|
+
const result = await service.getOrFind(false);
|
|
170
|
+
|
|
171
|
+
expect(lsSpy).not.toHaveBeenCalled();
|
|
172
|
+
expect(result.toDto()).toEqual(dto);
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
});
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Passbolt ~ Open source password manager for teams
|
|
3
|
+
* Copyright (c) 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) 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 6.0.0
|
|
13
|
+
*/
|
|
14
|
+
import SiteSettingsEntity from "passbolt-styleguide/src/shared/models/entity/siteSettings/siteSettingsEntity";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Per-account in-memory cache of site settings DTOs. Successor of the legacy
|
|
18
|
+
* `OrganizationSettingsModel._settings`. Service-worker lifetime.
|
|
19
|
+
*
|
|
20
|
+
* Auth-agnostic: written by FindAndUpdateSiteSettingsLocalStorageService after every API
|
|
21
|
+
* fetch, and by GetOrFindSiteSettingsService when seeding from SiteSettingsLocalStorage
|
|
22
|
+
* on the offline-auth read path. Read by GetOrFindSiteSettingsService.
|
|
23
|
+
*
|
|
24
|
+
* Independent of SiteSettingsLocalStorage. The two caches answer different questions:
|
|
25
|
+
* - SiteSettingsLocalStorage._runtimeCachedData mirrors browser.storage.local exactly
|
|
26
|
+
* and always reflects auth sitesettings value.
|
|
27
|
+
* - SiteSettingsRuntimeCache holds the most recent API result for this service-worker
|
|
28
|
+
* lifetime, regardless of whether it was persisted to browser.storage.local.
|
|
29
|
+
* @private
|
|
30
|
+
*/
|
|
31
|
+
let _cache = {};
|
|
32
|
+
|
|
33
|
+
class SiteSettingsRuntimeCache {
|
|
34
|
+
/**
|
|
35
|
+
* Read the cached entry for the given account.
|
|
36
|
+
* @returns {object|null} the cached DTO, or null when absent.
|
|
37
|
+
*/
|
|
38
|
+
static get() {
|
|
39
|
+
return _cache.siteSettings || null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Write the cached entry for the given account.
|
|
44
|
+
* @param {SiteSettingsEntity} settings
|
|
45
|
+
* @throws {TypeError} If settings is not a SiteSettingsEntity.
|
|
46
|
+
*/
|
|
47
|
+
static set(settings) {
|
|
48
|
+
if (!(settings instanceof SiteSettingsEntity)) {
|
|
49
|
+
throw new TypeError("Parameter `settings` should be of type SiteSettingsEntity.");
|
|
50
|
+
}
|
|
51
|
+
_cache.siteSettings = settings.toDto();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Drop the cached entry for an account. Intended for session lifecycle hooks
|
|
56
|
+
* (logout / account switch).
|
|
57
|
+
*/
|
|
58
|
+
static flush() {
|
|
59
|
+
delete _cache.siteSettings;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Drop every cached entry. Intended for tests.
|
|
64
|
+
*/
|
|
65
|
+
static flushAll() {
|
|
66
|
+
_cache = {};
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export default SiteSettingsRuntimeCache;
|
|
@@ -15,7 +15,7 @@ import "../../../../../test/mocks/mockSsoDataStorage";
|
|
|
15
15
|
import SsoDataStorage from "../indexedDB_storage/ssoDataStorage";
|
|
16
16
|
import { withAzureSsoSettings } from "../../controller/sso/getCurrentSsoSettingsController.test.data";
|
|
17
17
|
import GenerateSsoKitService from "./generateSsoKitService";
|
|
18
|
-
import {
|
|
18
|
+
import { anonymousSiteSettings } from "passbolt-styleguide/src/shared/models/entity/siteSettings/siteSettingsEntity.test.data";
|
|
19
19
|
import { mockApiResponse } from "../../../../../test/mocks/mockApiResponse";
|
|
20
20
|
import { enableFetchMocks } from "jest-fetch-mock";
|
|
21
21
|
import SsoKitClientPartEntity from "../../model/entity/sso/ssoKitClientPartEntity";
|
|
@@ -30,7 +30,7 @@ beforeEach(async () => {
|
|
|
30
30
|
describe("GenerateSsoKitService", () => {
|
|
31
31
|
describe("GenerateSsoKitService::generate", () => {
|
|
32
32
|
const mockOrganisationSettings = (withSsoEnabled = true) => {
|
|
33
|
-
const organizationSettings =
|
|
33
|
+
const organizationSettings = anonymousSiteSettings();
|
|
34
34
|
organizationSettings.passbolt.plugins.sso = {
|
|
35
35
|
enabled: withSsoEnabled,
|
|
36
36
|
};
|
|
@@ -163,7 +163,9 @@ class ToolbarService {
|
|
|
163
163
|
async resetSuggestedResourcesBadge() {
|
|
164
164
|
this.tabUrl = null;
|
|
165
165
|
// Should do nothing if the user is not authenticated
|
|
166
|
-
|
|
166
|
+
const account = await GetActiveAccountService.get();
|
|
167
|
+
const apiClientOptions = BuildApiClientOptionsService.buildFromAccount(account);
|
|
168
|
+
if (!(await this.isUserAuthenticated(account, apiClientOptions))) {
|
|
167
169
|
return;
|
|
168
170
|
}
|
|
169
171
|
BrowserExtensionIconService.setSuggestedResourcesCount(0);
|
|
@@ -178,7 +180,7 @@ class ToolbarService {
|
|
|
178
180
|
const account = await GetActiveAccountService.get();
|
|
179
181
|
const apiClientOptions = BuildApiClientOptionsService.buildFromAccount(account);
|
|
180
182
|
// Should do nothing if the user is not authenticated
|
|
181
|
-
if (!(await this.isUserAuthenticated())) {
|
|
183
|
+
if (!(await this.isUserAuthenticated(account, apiClientOptions))) {
|
|
182
184
|
return;
|
|
183
185
|
}
|
|
184
186
|
|
|
@@ -225,9 +227,9 @@ class ToolbarService {
|
|
|
225
227
|
* Is the user authenticated
|
|
226
228
|
* @returns {Promise<{boolean}|boolean>}
|
|
227
229
|
*/
|
|
228
|
-
async isUserAuthenticated() {
|
|
230
|
+
async isUserAuthenticated(account, apiClientOptions) {
|
|
229
231
|
try {
|
|
230
|
-
const checkAuthStatusService = new CheckAuthStatusService();
|
|
232
|
+
const checkAuthStatusService = new CheckAuthStatusService(account, apiClientOptions);
|
|
231
233
|
// use the cached data as the worker could wake up every 30 secondes.
|
|
232
234
|
const authStatus = await checkAuthStatusService.checkAuthStatus(false);
|
|
233
235
|
return authStatus.isAuthenticated;
|
|
@@ -24,6 +24,7 @@ import ResourceTypeLocalStorage from "../local_storage/resourceTypeLocalStorage"
|
|
|
24
24
|
import CheckAuthStatusService from "../auth/checkAuthStatusService";
|
|
25
25
|
import User from "../../../../all/background_page/model/user";
|
|
26
26
|
import OpenWebsiteGettingStartedPageService from "../ui/openWebsiteGettingStartedPageService";
|
|
27
|
+
import OnlineSessionEntity from "passbolt-styleguide/src/shared/models/entity/session/onlineSessionEntity";
|
|
27
28
|
|
|
28
29
|
jest.useFakeTimers();
|
|
29
30
|
|
|
@@ -57,7 +58,7 @@ describe("ToolbarService", () => {
|
|
|
57
58
|
jest.spyOn(browser.tabs, "query").mockImplementation(() => [{ url: "https://www.wherever.com" }]);
|
|
58
59
|
jest.spyOn(GetLegacyAccountService, "get").mockImplementation(() => account);
|
|
59
60
|
jest.spyOn(ResourceLocalStorage, "get").mockImplementation(() => defaultResourceDtosCollection());
|
|
60
|
-
jest.spyOn(ResourceTypeLocalStorage, "
|
|
61
|
+
jest.spyOn(ResourceTypeLocalStorage.prototype, "getData").mockImplementation(() => resourceTypesCollectionDto());
|
|
61
62
|
jest
|
|
62
63
|
.spyOn(CheckAuthStatusService.prototype, "checkAuthStatus")
|
|
63
64
|
.mockImplementation(() => ({ isAuthenticated: true }));
|
|
@@ -76,7 +77,7 @@ describe("ToolbarService", () => {
|
|
|
76
77
|
jest.spyOn(browser.tabs, "query").mockImplementation(() => [{ url: "https://www.passbolt.com" }]);
|
|
77
78
|
jest.spyOn(GetLegacyAccountService, "get").mockImplementation(() => account);
|
|
78
79
|
jest.spyOn(ResourceLocalStorage, "get").mockImplementation(() => defaultResourceDtosCollection());
|
|
79
|
-
jest.spyOn(ResourceTypeLocalStorage, "
|
|
80
|
+
jest.spyOn(ResourceTypeLocalStorage.prototype, "getData").mockImplementation(() => resourceTypesCollectionDto());
|
|
80
81
|
jest
|
|
81
82
|
.spyOn(CheckAuthStatusService.prototype, "checkAuthStatus")
|
|
82
83
|
.mockImplementation(() => ({ isAuthenticated: true }));
|
|
@@ -97,10 +98,10 @@ describe("ToolbarService", () => {
|
|
|
97
98
|
jest.spyOn(browser.tabs, "query").mockImplementation(() => [{ url: "https://www.wherever.com" }]);
|
|
98
99
|
jest.spyOn(GetLegacyAccountService, "get").mockImplementation(() => account);
|
|
99
100
|
jest.spyOn(ResourceLocalStorage, "get").mockImplementation(() => defaultResourceDtosCollection());
|
|
100
|
-
jest.spyOn(ResourceTypeLocalStorage, "
|
|
101
|
+
jest.spyOn(ResourceTypeLocalStorage.prototype, "getData").mockImplementation(() => resourceTypesCollectionDto());
|
|
101
102
|
jest
|
|
102
103
|
.spyOn(CheckAuthStatusService.prototype, "checkAuthStatus")
|
|
103
|
-
.mockImplementation(() => ({
|
|
104
|
+
.mockImplementation(() => new OnlineSessionEntity({ is_authenticated: true }));
|
|
104
105
|
|
|
105
106
|
await toolbarService.handleUserLoggedIn();
|
|
106
107
|
await toolbarService.handleUserLoggedOut();
|
|
@@ -118,10 +119,10 @@ describe("ToolbarService", () => {
|
|
|
118
119
|
jest.spyOn(browser.tabs, "query").mockImplementationOnce(() => [{ url: "https://www.wherever.com" }]);
|
|
119
120
|
jest.spyOn(GetLegacyAccountService, "get").mockImplementation(() => account);
|
|
120
121
|
jest.spyOn(ResourceLocalStorage, "get").mockImplementation(() => defaultResourceDtosCollection());
|
|
121
|
-
jest.spyOn(ResourceTypeLocalStorage, "
|
|
122
|
+
jest.spyOn(ResourceTypeLocalStorage.prototype, "getData").mockImplementation(() => resourceTypesCollectionDto());
|
|
122
123
|
jest
|
|
123
124
|
.spyOn(CheckAuthStatusService.prototype, "checkAuthStatus")
|
|
124
|
-
.mockImplementation(() => ({
|
|
125
|
+
.mockImplementation(() => new OnlineSessionEntity({ is_authenticated: true }));
|
|
125
126
|
|
|
126
127
|
await toolbarService.handleUserLoggedIn();
|
|
127
128
|
|
|
@@ -141,10 +142,10 @@ describe("ToolbarService", () => {
|
|
|
141
142
|
jest.spyOn(browser.tabs, "query").mockImplementationOnce(() => [{ url: "https://www.wherever.com" }]);
|
|
142
143
|
jest.spyOn(GetLegacyAccountService, "get").mockImplementation(() => account);
|
|
143
144
|
jest.spyOn(ResourceLocalStorage, "get").mockImplementation(() => defaultResourceDtosCollection());
|
|
144
|
-
jest.spyOn(ResourceTypeLocalStorage, "
|
|
145
|
+
jest.spyOn(ResourceTypeLocalStorage.prototype, "getData").mockImplementation(() => resourceTypesCollectionDto());
|
|
145
146
|
jest
|
|
146
147
|
.spyOn(CheckAuthStatusService.prototype, "checkAuthStatus")
|
|
147
|
-
.mockImplementation(() => ({
|
|
148
|
+
.mockImplementation(() => new OnlineSessionEntity({ is_authenticated: true }));
|
|
148
149
|
|
|
149
150
|
await toolbarService.handleUserLoggedIn();
|
|
150
151
|
expect(browserExtensionIconServiceSetCountMock).toHaveBeenLastCalledWith(0);
|
|
@@ -163,10 +164,10 @@ describe("ToolbarService", () => {
|
|
|
163
164
|
jest.spyOn(browser.tabs, "query").mockImplementationOnce(() => [{ url: "https://www.wherever.com" }]);
|
|
164
165
|
jest.spyOn(GetLegacyAccountService, "get").mockImplementation(() => account);
|
|
165
166
|
jest.spyOn(ResourceLocalStorage, "get").mockImplementation(() => defaultResourceDtosCollection());
|
|
166
|
-
jest.spyOn(ResourceTypeLocalStorage, "
|
|
167
|
+
jest.spyOn(ResourceTypeLocalStorage.prototype, "getData").mockImplementation(() => resourceTypesCollectionDto());
|
|
167
168
|
jest
|
|
168
169
|
.spyOn(CheckAuthStatusService.prototype, "checkAuthStatus")
|
|
169
|
-
.mockImplementation(() => ({
|
|
170
|
+
.mockImplementation(() => new OnlineSessionEntity({ is_authenticated: true }));
|
|
170
171
|
|
|
171
172
|
await toolbarService.handleUserLoggedIn();
|
|
172
173
|
expect(browserExtensionIconServiceSetCountMock).toHaveBeenLastCalledWith(0);
|
|
@@ -183,10 +184,10 @@ describe("ToolbarService", () => {
|
|
|
183
184
|
jest.spyOn(browser.tabs, "query").mockImplementationOnce(() => [{ url: "https://www.passbolt.com" }]);
|
|
184
185
|
jest.spyOn(GetLegacyAccountService, "get").mockImplementation(() => account);
|
|
185
186
|
jest.spyOn(ResourceLocalStorage, "get").mockImplementation(() => defaultResourceDtosCollection());
|
|
186
|
-
jest.spyOn(ResourceTypeLocalStorage, "
|
|
187
|
+
jest.spyOn(ResourceTypeLocalStorage.prototype, "getData").mockImplementation(() => resourceTypesCollectionDto());
|
|
187
188
|
jest
|
|
188
189
|
.spyOn(CheckAuthStatusService.prototype, "checkAuthStatus")
|
|
189
|
-
.mockImplementation(() => ({
|
|
190
|
+
.mockImplementation(() => new OnlineSessionEntity({ is_authenticated: true }));
|
|
190
191
|
|
|
191
192
|
await toolbarService.handleUserLoggedIn();
|
|
192
193
|
expect(browserExtensionIconServiceSetCountMock).toHaveBeenLastCalledWith(4);
|
|
@@ -201,7 +202,7 @@ describe("ToolbarService", () => {
|
|
|
201
202
|
jest.spyOn(GetLegacyAccountService, "get").mockImplementation(() => account);
|
|
202
203
|
jest
|
|
203
204
|
.spyOn(CheckAuthStatusService.prototype, "checkAuthStatus")
|
|
204
|
-
.mockImplementation(() => ({
|
|
205
|
+
.mockImplementation(() => new OnlineSessionEntity({ is_authenticated: false }));
|
|
205
206
|
|
|
206
207
|
await toolbarService.handleSuggestedResourcesOnFocusedWindow(42);
|
|
207
208
|
expect(browserExtensionIconServiceSetCountMock).toHaveBeenCalledTimes(0);
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
import RoleEntity from "passbolt-styleguide/src/shared/models/entity/role/roleEntity";
|
|
15
15
|
import UsersCollection from "passbolt-styleguide/src/shared/models/entity/user/usersCollection";
|
|
16
|
-
import
|
|
16
|
+
import GetOrFindSiteSettingsService from "../siteSettings/getOrFindSiteSettingsService";
|
|
17
17
|
import UserLocalStorage from "../local_storage/userLocalStorage";
|
|
18
18
|
import FindUsersService from "./findUsersService";
|
|
19
19
|
|
|
@@ -31,7 +31,7 @@ class FindAndUpdateUsersLocalStorageService {
|
|
|
31
31
|
constructor(account, apiClientOptions) {
|
|
32
32
|
this.account = account;
|
|
33
33
|
this.findUsersService = new FindUsersService(account, apiClientOptions);
|
|
34
|
-
this.
|
|
34
|
+
this.getOrFindSiteSettingsService = new GetOrFindSiteSettingsService(account, apiClientOptions);
|
|
35
35
|
this.lockKey = `${USERS_UPDATE_ALL_LS_LOCK_PREFIX}-${this.account.id}`;
|
|
36
36
|
}
|
|
37
37
|
|
|
@@ -64,8 +64,8 @@ class FindAndUpdateUsersLocalStorageService {
|
|
|
64
64
|
};
|
|
65
65
|
if (this.account?.roleName === RoleEntity.ROLE_ADMIN) {
|
|
66
66
|
contains.is_mfa_enabled = true;
|
|
67
|
-
const
|
|
68
|
-
if (
|
|
67
|
+
const siteSettings = await this.getOrFindSiteSettingsService.getOrFind(false);
|
|
68
|
+
if (siteSettings.isPluginEnabled("metadata")) {
|
|
69
69
|
contains.missing_metadata_key_ids = true;
|
|
70
70
|
}
|
|
71
71
|
}
|
|
@@ -21,7 +21,7 @@ import FindAndUpdateUsersLocalStorageService from "./findAndUpdateUsersLocalStor
|
|
|
21
21
|
import FindUsersService from "./findUsersService";
|
|
22
22
|
import UsersCollection from "passbolt-styleguide/src/shared/models/entity/user/usersCollection";
|
|
23
23
|
import UserLocalStorage from "../local_storage/userLocalStorage";
|
|
24
|
-
import
|
|
24
|
+
import GetOrFindSiteSettingsService from "../siteSettings/getOrFindSiteSettingsService";
|
|
25
25
|
|
|
26
26
|
describe("FindAndUpdateUsersLocalStorageService", () => {
|
|
27
27
|
let service, account;
|
|
@@ -82,7 +82,7 @@ describe("FindAndUpdateUsersLocalStorageService", () => {
|
|
|
82
82
|
.spyOn(FindUsersService.prototype, "findAll")
|
|
83
83
|
.mockImplementation(() => new UsersCollection([]));
|
|
84
84
|
jest
|
|
85
|
-
.spyOn(
|
|
85
|
+
.spyOn(GetOrFindSiteSettingsService.prototype, "getOrFind")
|
|
86
86
|
.mockImplementation(() => ({ isPluginEnabled: (plugin) => plugin === "metadata" }));
|
|
87
87
|
|
|
88
88
|
await adminService.findAndUpdateAll();
|
|
@@ -100,7 +100,7 @@ describe("FindAndUpdateUsersLocalStorageService", () => {
|
|
|
100
100
|
.spyOn(FindUsersService.prototype, "findAll")
|
|
101
101
|
.mockImplementation(() => new UsersCollection([]));
|
|
102
102
|
jest
|
|
103
|
-
.spyOn(
|
|
103
|
+
.spyOn(GetOrFindSiteSettingsService.prototype, "getOrFind")
|
|
104
104
|
.mockImplementation(() => ({ isPluginEnabled: () => false }));
|
|
105
105
|
|
|
106
106
|
await adminService.findAndUpdateAll();
|