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
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
* @since 4.10.0
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
-
import FindFoldersService from "../../folder/findFoldersService";
|
|
16
15
|
import { OpenpgpAssertion } from "../../../utils/openpgp/openpgpAssertions";
|
|
17
16
|
import EncryptMessageService from "../../crypto/encryptMessageService";
|
|
18
17
|
import ResourceSecretsCollection from "../../../model/entity/secret/resource/resourceSecretsCollection";
|
|
@@ -22,10 +21,12 @@ import ResourceLocalStorage from "../../local_storage/resourceLocalStorage";
|
|
|
22
21
|
import i18n from "../../../sdk/i18n";
|
|
23
22
|
import ResourceModel from "../../../model/resource/resourceModel";
|
|
24
23
|
import DecryptPrivateKeyService from "../../crypto/decryptPrivateKeyService";
|
|
25
|
-
import ResourceTypeModel from "../../../model/resourceType/resourceTypeModel";
|
|
26
24
|
import EncryptMetadataKeysService from "../../metadata/encryptMetadataService";
|
|
27
25
|
import PermissionChangesCollection from "../../../model/entity/permission/change/permissionChangesCollection";
|
|
28
26
|
import ShareResourceService, { PROGRESS_STEPS_SHARE_RESOURCES_SHARE_ALL } from "../../share/shareResourceService";
|
|
27
|
+
import GetOrFindResourceTypesService from "../../resourceType/getOrFindResourceTypesService";
|
|
28
|
+
import PermissionsCollection from "passbolt-styleguide/src/shared/models/entity/permission/permissionsCollection";
|
|
29
|
+
import PermissionEntity from "passbolt-styleguide/src/shared/models/entity/permission/permissionEntity";
|
|
29
30
|
|
|
30
31
|
class ResourceCreateService {
|
|
31
32
|
/**
|
|
@@ -36,8 +37,7 @@ class ResourceCreateService {
|
|
|
36
37
|
constructor(account, apiClientOptions, progressService) {
|
|
37
38
|
this.account = account;
|
|
38
39
|
this.resourceService = new ResourceService(apiClientOptions);
|
|
39
|
-
this.
|
|
40
|
-
this.findFoldersService = new FindFoldersService(apiClientOptions);
|
|
40
|
+
this.getOrFindResourceTypesService = new GetOrFindResourceTypesService(account, apiClientOptions);
|
|
41
41
|
this.progressService = progressService;
|
|
42
42
|
this.resourceModel = new ResourceModel(apiClientOptions, this.account);
|
|
43
43
|
this.encryptMetadataKeysService = new EncryptMetadataKeysService(apiClientOptions, this.account);
|
|
@@ -45,34 +45,28 @@ class ResourceCreateService {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
/**
|
|
48
|
-
* Create a resource
|
|
49
|
-
*
|
|
48
|
+
* Create a resource operator-only, then optionally extend the share with the caller-provided
|
|
49
|
+
* permission changes (spec-mandated safe order: no secret is encrypted for an ARO the caller
|
|
50
|
+
* hasn't confirmed).
|
|
50
51
|
* @param {object} resourceDto The resource data
|
|
51
52
|
* @param {string|object} secretDto The secret to encrypt
|
|
52
53
|
* @param {string} passphrase The user passphrase
|
|
54
|
+
* @param {Array<object>} [permissionChanges] Optional permission changes to apply after create.
|
|
53
55
|
* @return {Promise<ResourceEntity>} resourceEntity
|
|
54
56
|
*/
|
|
55
|
-
async create(resourceDto, secretDto, passphrase) {
|
|
57
|
+
async create(resourceDto, secretDto, passphrase, permissionChanges) {
|
|
58
|
+
// Port serialization replaces an omitted arg with `null`, sliding past a `= []` default;
|
|
59
|
+
// normalize defensively so the rest of the method can assume an array.
|
|
60
|
+
permissionChanges = permissionChanges ?? [];
|
|
56
61
|
const resource = new ResourceEntity(resourceDto);
|
|
57
|
-
const resourceTypes = await this.
|
|
62
|
+
const resourceTypes = await this.getOrFindResourceTypesService.getOrFindAll();
|
|
58
63
|
const resourceType = resourceTypes.getFirstById(resource.resourceTypeId);
|
|
59
64
|
// Keep a copy of the metadata. It will be used after creation on the API, to persist it decrypted into the local storage.
|
|
60
65
|
const resourceMetadata = resource.metadata;
|
|
61
66
|
// Get private key decrypted to encrypt data
|
|
62
67
|
const privateKey = await DecryptPrivateKeyService.decryptArmoredKey(this.account.userPrivateArmoredKey, passphrase);
|
|
63
|
-
let permissionChanges = new PermissionChangesCollection([]);
|
|
64
|
-
let destinationFolder;
|
|
65
|
-
if (resource.folderParentId) {
|
|
66
|
-
destinationFolder = await this.findFoldersService.findByIdWithPermissions(resource.folderParentId);
|
|
67
|
-
if (
|
|
68
|
-
destinationFolder.permissions.length > 1 ||
|
|
69
|
-
destinationFolder.permissions.items[0].aroForeignKey !== this.account.userId
|
|
70
|
-
) {
|
|
71
|
-
permissionChanges = destinationFolder.permissions;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
68
|
this.updateGoals(resourceType.isV5(), permissionChanges.length);
|
|
75
|
-
await this.encryptMetadata(resource, resourceType,
|
|
69
|
+
await this.encryptMetadata(resource, resourceType, passphrase);
|
|
76
70
|
await this.buildAndEncryptUserSecret(resource, secretDto, privateKey);
|
|
77
71
|
const createdResource = await this.save(resource, resourceType);
|
|
78
72
|
// If resource v5, metadata will be returned encrypted, replace it with the original decrypted copy.
|
|
@@ -80,8 +74,23 @@ class ResourceCreateService {
|
|
|
80
74
|
createdResource.metadata = resourceMetadata;
|
|
81
75
|
}
|
|
82
76
|
await ResourceLocalStorage.addResource(createdResource);
|
|
83
|
-
|
|
84
|
-
|
|
77
|
+
|
|
78
|
+
const isAnOperatorPersonalResource =
|
|
79
|
+
permissionChanges.length === 1 &&
|
|
80
|
+
permissionChanges[0].aro === PermissionEntity.ARO_USER &&
|
|
81
|
+
permissionChanges[0].aro_foreign_key === this.account.userId;
|
|
82
|
+
|
|
83
|
+
if (!isAnOperatorPersonalResource && permissionChanges.length > 0) {
|
|
84
|
+
// The styleguide can't know the resource id at confirm time so the deltas arrive with
|
|
85
|
+
// aco_foreign_key unset (or null). Stamp the real id before handing them to the share API.
|
|
86
|
+
const stampedChanges = permissionChanges.map((change) => ({ ...change, aco_foreign_key: createdResource.id }));
|
|
87
|
+
const originalPermissionSet = new PermissionsCollection([createdResource.permission]);
|
|
88
|
+
const permissionChangesToApply = PermissionChangesCollection.calculateChanges(
|
|
89
|
+
originalPermissionSet,
|
|
90
|
+
new PermissionsCollection(stampedChanges),
|
|
91
|
+
);
|
|
92
|
+
await this.shareResourceService.shareAll([createdResource.id], permissionChangesToApply, passphrase);
|
|
93
|
+
}
|
|
85
94
|
return createdResource;
|
|
86
95
|
}
|
|
87
96
|
|
|
@@ -122,52 +131,33 @@ class ResourceCreateService {
|
|
|
122
131
|
}
|
|
123
132
|
|
|
124
133
|
/**
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
* @param {string} passphrase The user passphrase
|
|
129
|
-
* @param {FolderEntity} folder The folder entity
|
|
130
|
-
* @param {PermissionChangesCollection} permissionChangesFromFolder The permission changes
|
|
131
|
-
* @returns {Promise<void>}
|
|
132
|
-
* @private
|
|
133
|
-
*/
|
|
134
|
-
async share(resource, passphrase, folder, permissionChangesFromFolder) {
|
|
135
|
-
if (!folder || !permissionChangesFromFolder.length) {
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
await this.progressService.finishStep(i18n.t("Calculate permissions"), true);
|
|
139
|
-
const permissionChanges = await this.resourceModel.calculatePermissionsChangesForCreate(resource, folder);
|
|
140
|
-
await this.shareResourceService.shareAll([resource.id], permissionChanges, passphrase);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Encrypt resource metadata if v5.
|
|
134
|
+
* Encrypt resource metadata if v5. The resource is always created as `personal` at this stage —
|
|
135
|
+
* the workflow extends sharing afterwards via `passbolt.share.resources.save`, which re-encrypts
|
|
136
|
+
* the metadata with the shared key when (and only when) the resource actually gets shared.
|
|
145
137
|
* @param {ResourceEntity} resource The resource
|
|
146
138
|
* @param {ResourceTypeEntity} resourceType The resource type
|
|
147
|
-
* @param {PermissionChangesCollection} permissionChanges The permission changes
|
|
148
139
|
* @param {string} passphrase The user passphrase
|
|
149
140
|
* @private
|
|
150
141
|
*/
|
|
151
|
-
async encryptMetadata(resource, resourceType,
|
|
142
|
+
async encryptMetadata(resource, resourceType, passphrase) {
|
|
152
143
|
if (!resourceType.isV5()) {
|
|
153
144
|
return;
|
|
154
145
|
}
|
|
155
146
|
await this.progressService.finishStep(i18n.t("Encrypting Metadata"), true);
|
|
156
|
-
resource.personal =
|
|
147
|
+
resource.personal = true;
|
|
157
148
|
await this.encryptMetadataKeysService.encryptOneForForeignModel(resource, passphrase);
|
|
158
149
|
}
|
|
159
150
|
|
|
160
151
|
/**
|
|
161
152
|
* Update goals
|
|
162
153
|
* @param {boolean} shouldEncryptMetadata if metadata should be encrypted
|
|
163
|
-
* @param {number}
|
|
154
|
+
* @param {number} permissionChangesLength number of permission changes that will be applied after create
|
|
164
155
|
* @private
|
|
165
156
|
*/
|
|
166
|
-
updateGoals(shouldEncryptMetadata,
|
|
167
|
-
const
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
this.progressService.updateGoals(stepToCreate + shareSteps);
|
|
157
|
+
updateGoals(shouldEncryptMetadata, permissionChangesLength = 0) {
|
|
158
|
+
const stepsToCreate = shouldEncryptMetadata ? 4 : 3;
|
|
159
|
+
const shareSteps = permissionChangesLength > 0 ? PROGRESS_STEPS_SHARE_RESOURCES_SHARE_ALL : 0;
|
|
160
|
+
this.progressService.updateGoals(stepsToCreate + shareSteps);
|
|
171
161
|
}
|
|
172
162
|
}
|
|
173
163
|
|
|
@@ -28,7 +28,6 @@ import ResourceEntity from "../../../model/entity/resource/resourceEntity";
|
|
|
28
28
|
import ResourceLocalStorage from "../../local_storage/resourceLocalStorage";
|
|
29
29
|
import Keyring from "../../../model/keyring";
|
|
30
30
|
import ProgressService from "../../progress/progressService";
|
|
31
|
-
import { defaultFolderDto } from "passbolt-styleguide/src/shared/models/entity/folder/folderEntity.test.data";
|
|
32
31
|
import ResourceService from "../../api/resource/resourceService";
|
|
33
32
|
import DecryptMessageService from "../../crypto/decryptMessageService";
|
|
34
33
|
import { OpenpgpAssertion } from "../../../utils/openpgp/openpgpAssertions";
|
|
@@ -46,16 +45,11 @@ import {
|
|
|
46
45
|
plaintextSecretTotpDto,
|
|
47
46
|
} from "passbolt-styleguide/src/shared/models/entity/plaintextSecret/plaintextSecretEntity.test.data";
|
|
48
47
|
import FindFoldersService from "../../folder/findFoldersService";
|
|
49
|
-
import FolderEntity from "../../../model/entity/folder/folderEntity";
|
|
50
48
|
import ShareApiService from "../../api/share/shareApiService";
|
|
51
|
-
import MetadataKeysCollection from "passbolt-styleguide/src/shared/models/entity/metadata/metadataKeysCollection";
|
|
52
|
-
import { defaultDecryptedSharedMetadataKeysDtos } from "passbolt-styleguide/src/shared/models/entity/metadata/metadataKeysCollection.test.data";
|
|
53
49
|
import ResourceSecretsCollection from "../../../model/entity/secret/resource/resourceSecretsCollection";
|
|
54
50
|
import DecryptMetadataService from "../../metadata/decryptMetadataService";
|
|
55
51
|
import GetDecryptedUserPrivateKeyService from "../../account/getDecryptedUserPrivateKeyService";
|
|
56
52
|
import { defaultMetadataKeysSettingsDto } from "passbolt-styleguide/src/shared/models/entity/metadata/metadataKeysSettingsEntity.test.data";
|
|
57
|
-
import { ownerFolderPermissionDto } from "passbolt-styleguide/src/shared/models/entity/permission/permissionEntity.test.data";
|
|
58
|
-
import { mockPassboltResponse } from "passbolt-styleguide/test/mocks/mockApiResponse";
|
|
59
53
|
|
|
60
54
|
jest.mock("../../../service/progress/progressService");
|
|
61
55
|
|
|
@@ -363,42 +357,94 @@ describe("ResourceCreateService", () => {
|
|
|
363
357
|
return expect(promise).rejects.toThrow("The secret should be maximum 4096 characters in length.");
|
|
364
358
|
});
|
|
365
359
|
|
|
366
|
-
it("Should create the resource
|
|
367
|
-
expect.assertions(
|
|
360
|
+
it("Should create the resource operator-only and skip the share step when no permissionChanges are passed", async () => {
|
|
361
|
+
expect.assertions(3);
|
|
368
362
|
|
|
369
363
|
const folderId = uuidv4();
|
|
370
364
|
const resourceDto = defaultResourceDto({ folder_parent_id: folderId });
|
|
371
|
-
|
|
372
|
-
changes: {
|
|
373
|
-
added: [],
|
|
374
|
-
removed: [],
|
|
375
|
-
},
|
|
376
|
-
};
|
|
377
|
-
|
|
378
|
-
jest.spyOn(ResourceService.prototype, "findAll").mockImplementation(() => mockPassboltResponse([resourceDto]));
|
|
365
|
+
jest.spyOn(ResourceService.prototype, "findAll").mockImplementation(() => [resourceDto]);
|
|
379
366
|
jest.spyOn(ResourceService.prototype, "create").mockImplementation(() => resourceDto);
|
|
380
|
-
jest
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
async () => new FolderEntity(defaultFolderDto({ id: folderId }, { withPermissions: true })),
|
|
384
|
-
);
|
|
385
|
-
jest.spyOn(ShareApiService.prototype, "simulateShareResource").mockImplementation(() => shareResourceChanges);
|
|
386
|
-
jest.spyOn(ShareApiService.prototype, "shareFolder").mockImplementation(() => shareResourceChanges);
|
|
387
|
-
jest.spyOn(ShareApiService.prototype, "shareResource").mockImplementation(() => jest.fn());
|
|
367
|
+
jest.spyOn(FindFoldersService.prototype, "findByIdWithPermissions");
|
|
368
|
+
jest.spyOn(ShareApiService.prototype, "shareResource");
|
|
369
|
+
jest.spyOn(resourceCreateService.shareResourceService, "shareAll");
|
|
388
370
|
|
|
389
|
-
|
|
371
|
+
await resourceCreateService.create(
|
|
372
|
+
resourceDto,
|
|
373
|
+
plaintextSecretPasswordStringDto().password,
|
|
374
|
+
pgpKeys.ada.passphrase,
|
|
375
|
+
);
|
|
376
|
+
|
|
377
|
+
// No parent folder permission lookup, no implicit inheritance, no share step — the resource
|
|
378
|
+
// is created with only the operator's secret encrypted. Sharing is opt-in via the new
|
|
379
|
+
// `permissionChanges` argument.
|
|
380
|
+
expect(FindFoldersService.prototype.findByIdWithPermissions).not.toHaveBeenCalled();
|
|
381
|
+
expect(ShareApiService.prototype.shareResource).not.toHaveBeenCalled();
|
|
382
|
+
expect(resourceCreateService.shareResourceService.shareAll).not.toHaveBeenCalled();
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
it("Should create the resource operator-only and then run shareResourceService.shareAll when permissionChanges are passed", async () => {
|
|
386
|
+
expect.assertions(3);
|
|
387
|
+
|
|
388
|
+
const folderId = uuidv4();
|
|
389
|
+
const createdResourceId = uuidv4();
|
|
390
|
+
const resourceDto = defaultResourceDto({ id: createdResourceId, folder_parent_id: folderId });
|
|
391
|
+
const operatorId = resourceDto.permission.aro_foreign_key;
|
|
392
|
+
const otherUserId = uuidv4();
|
|
393
|
+
const permissionChanges = [
|
|
394
|
+
{
|
|
395
|
+
is_new: true,
|
|
396
|
+
aro: "User",
|
|
397
|
+
aro_foreign_key: operatorId,
|
|
398
|
+
aco: "Resource",
|
|
399
|
+
aco_foreign_key: createdResourceId,
|
|
400
|
+
type: 1,
|
|
401
|
+
},
|
|
402
|
+
{
|
|
403
|
+
is_new: true,
|
|
404
|
+
aro: "User",
|
|
405
|
+
aro_foreign_key: otherUserId,
|
|
406
|
+
aco: "Resource",
|
|
407
|
+
aco_foreign_key: createdResourceId,
|
|
408
|
+
type: 15,
|
|
409
|
+
},
|
|
410
|
+
];
|
|
411
|
+
jest.spyOn(ResourceService.prototype, "findAll").mockImplementation(() => [resourceDto]);
|
|
412
|
+
jest.spyOn(ResourceService.prototype, "create").mockImplementation(() => resourceDto);
|
|
413
|
+
jest.spyOn(resourceCreateService.shareResourceService, "shareAll").mockImplementation(() => {});
|
|
390
414
|
|
|
391
415
|
await resourceCreateService.create(
|
|
392
416
|
resourceDto,
|
|
393
417
|
plaintextSecretPasswordStringDto().password,
|
|
394
418
|
pgpKeys.ada.passphrase,
|
|
419
|
+
permissionChanges,
|
|
395
420
|
);
|
|
396
421
|
|
|
397
|
-
expect(resourceCreateService.
|
|
422
|
+
expect(resourceCreateService.shareResourceService.shareAll).toHaveBeenCalledTimes(1);
|
|
423
|
+
const [resourcesIds, changesCollection] = resourceCreateService.shareResourceService.shareAll.mock.calls[0];
|
|
424
|
+
expect(resourcesIds).toEqual([createdResourceId]);
|
|
425
|
+
// The service wraps the caller's plain DTO list into a PermissionChangesCollection before
|
|
426
|
+
// handing it to shareAll. We check the aro/aco wiring; `is_new` is implied for new rows and
|
|
427
|
+
// normalized away by the collection.
|
|
428
|
+
expect(changesCollection.toDto()).toEqual([
|
|
429
|
+
expect.objectContaining({
|
|
430
|
+
aro: "User",
|
|
431
|
+
aro_foreign_key: operatorId,
|
|
432
|
+
aco: "Resource",
|
|
433
|
+
aco_foreign_key: createdResourceId,
|
|
434
|
+
type: 1,
|
|
435
|
+
}),
|
|
436
|
+
expect.objectContaining({
|
|
437
|
+
aro: "User",
|
|
438
|
+
aro_foreign_key: otherUserId,
|
|
439
|
+
aco: "Resource",
|
|
440
|
+
aco_foreign_key: createdResourceId,
|
|
441
|
+
type: 15,
|
|
442
|
+
}),
|
|
443
|
+
]);
|
|
398
444
|
});
|
|
399
445
|
|
|
400
|
-
it("Should create
|
|
401
|
-
expect.assertions(
|
|
446
|
+
it("Should create a V5 resource with personal metadata even when the parent folder is shared (workflow re-shares it afterwards)", async () => {
|
|
447
|
+
expect.assertions(4);
|
|
402
448
|
|
|
403
449
|
let resourceToAPI, resourceLocalStorageExpected;
|
|
404
450
|
const folderId = uuidv4();
|
|
@@ -407,85 +453,55 @@ describe("ResourceCreateService", () => {
|
|
|
407
453
|
resource_type_id: TEST_RESOURCE_TYPE_V5_DEFAULT,
|
|
408
454
|
});
|
|
409
455
|
const plaintextDto = plaintextSecretPasswordDescriptionTotpDto();
|
|
456
|
+
const metadataKeysSettingsDto = defaultMetadataKeysSettingsDto();
|
|
410
457
|
const decryptMetadataService = new DecryptMetadataService(apiClientOptions, account);
|
|
411
|
-
const shareResourceChanges = {
|
|
412
|
-
changes: {
|
|
413
|
-
added: [],
|
|
414
|
-
removed: [],
|
|
415
|
-
},
|
|
416
|
-
};
|
|
417
|
-
const metadataKeysDtos = defaultDecryptedSharedMetadataKeysDtos({ armored_key: pgpKeys.metadataKey.public });
|
|
418
|
-
const metadataKeys = new MetadataKeysCollection(metadataKeysDtos);
|
|
419
458
|
|
|
459
|
+
jest
|
|
460
|
+
.spyOn(
|
|
461
|
+
resourceCreateService.encryptMetadataKeysService.getOrFindMetadataSettingsService
|
|
462
|
+
.findAndUpdateMetadataSettingsLocalStorageService.findMetadataSettingsService
|
|
463
|
+
.metadataKeysSettingsApiService,
|
|
464
|
+
"findSettings",
|
|
465
|
+
)
|
|
466
|
+
.mockImplementation(() => metadataKeysSettingsDto);
|
|
420
467
|
jest.spyOn(ResourceService.prototype, "create").mockImplementation((resource) => {
|
|
421
|
-
//Used to check the data sent to API
|
|
422
468
|
resourceToAPI = resource;
|
|
423
469
|
const resourceEntity = new ResourceEntity(resourceDto);
|
|
424
470
|
resourceEntity.secrets = new ResourceSecretsCollection([resourceToAPI.secrets[0]]);
|
|
425
|
-
resourceEntity.metadataKeyId = resourceToAPI.metadata_key_id;
|
|
426
471
|
resourceEntity.metadataKeyType = resourceToAPI.metadata_key_type;
|
|
427
472
|
resourceLocalStorageExpected = resourceEntity.toDto(ResourceLocalStorage.DEFAULT_CONTAIN);
|
|
428
473
|
resourceEntity.metadata = resourceToAPI.metadata;
|
|
429
474
|
return resourceEntity.toDto(ResourceLocalStorage.DEFAULT_CONTAIN);
|
|
430
475
|
});
|
|
431
|
-
jest.spyOn(ResourceService.prototype, "findAll").mockImplementation(() =>
|
|
432
|
-
jest
|
|
433
|
-
|
|
434
|
-
.mockImplementation(
|
|
435
|
-
async () => new FolderEntity(defaultFolderDto({ id: folderId }, { withPermissions: { count: 2 } })),
|
|
436
|
-
);
|
|
437
|
-
jest.spyOn(ShareApiService.prototype, "simulateShareResource").mockImplementation(() => shareResourceChanges);
|
|
438
|
-
jest.spyOn(ShareApiService.prototype, "shareFolder").mockImplementation(() => shareResourceChanges);
|
|
439
|
-
jest.spyOn(ShareApiService.prototype, "shareResource").mockImplementation(() => jest.fn());
|
|
440
|
-
jest
|
|
441
|
-
.spyOn(resourceCreateService.encryptMetadataKeysService.getOrFindMetadataKeysService, "getOrFindAll")
|
|
442
|
-
.mockImplementation(() => metadataKeys);
|
|
443
|
-
jest
|
|
444
|
-
.spyOn(decryptMetadataService.getOrFindMetadataKeysService, "getOrFindAll")
|
|
445
|
-
.mockImplementation(() => metadataKeys);
|
|
446
|
-
|
|
447
|
-
jest.spyOn(resourceCreateService, "share");
|
|
476
|
+
jest.spyOn(ResourceService.prototype, "findAll").mockImplementation(() => [resourceDto]);
|
|
477
|
+
jest.spyOn(FindFoldersService.prototype, "findByIdWithPermissions");
|
|
478
|
+
jest.spyOn(ShareApiService.prototype, "shareResource");
|
|
448
479
|
|
|
449
480
|
await resourceCreateService.create(resourceDto, plaintextDto, pgpKeys.ada.passphrase);
|
|
450
481
|
|
|
451
|
-
// Decrypt metadata
|
|
482
|
+
// Decrypt metadata: the resource is created personal, so its metadata is encrypted with the
|
|
483
|
+
// operator's personal key, not the shared metadata key.
|
|
452
484
|
const resourceEntityUpdated = new ResourceEntity(resourceToAPI);
|
|
453
|
-
|
|
454
|
-
await decryptMetadataService.
|
|
485
|
+
const privateKeyDecrypted = await OpenpgpAssertion.readKeyOrFail(pgpKeys.ada.private_decrypted);
|
|
486
|
+
await decryptMetadataService.decryptMetadataWithGpgKey(resourceEntityUpdated, privateKeyDecrypted);
|
|
455
487
|
|
|
456
|
-
expect(
|
|
457
|
-
|
|
488
|
+
expect(FindFoldersService.prototype.findByIdWithPermissions).not.toHaveBeenCalled();
|
|
489
|
+
expect(ShareApiService.prototype.shareResource).not.toHaveBeenCalled();
|
|
458
490
|
expect(resourceEntityUpdated.metadata.toDto()).toEqual(resourceDto.metadata);
|
|
459
|
-
// Resource local storage should add the resource
|
|
460
491
|
expect(ResourceLocalStorage.addResource).toHaveBeenCalledWith(new ResourceEntity(resourceLocalStorageExpected));
|
|
461
|
-
expect(resourceCreateService.progressService.updateGoals).toHaveBeenCalledWith(13);
|
|
462
492
|
});
|
|
463
493
|
|
|
464
|
-
it("Should
|
|
465
|
-
expect.assertions(
|
|
494
|
+
it("Should call updateGoals with the operator-only step count regardless of whether the parent folder is set", async () => {
|
|
495
|
+
expect.assertions(1);
|
|
466
496
|
|
|
467
|
-
let resourceToAPI, resourceLocalStorageExpected;
|
|
468
497
|
const folderId = uuidv4();
|
|
469
|
-
const permissionDto = ownerFolderPermissionDto({ aco_foreign_key: folderId, aro_foreign_key: account.userId });
|
|
470
|
-
const folderDto = defaultFolderDto({ id: folderId, permission: permissionDto, permissions: [permissionDto] });
|
|
471
498
|
const resourceDto = defaultResourceDto({
|
|
472
499
|
folder_parent_id: folderId,
|
|
473
500
|
resource_type_id: TEST_RESOURCE_TYPE_V5_DEFAULT,
|
|
474
501
|
});
|
|
475
502
|
const plaintextDto = plaintextSecretPasswordDescriptionTotpDto();
|
|
476
503
|
const metadataKeysSettingsDto = defaultMetadataKeysSettingsDto();
|
|
477
|
-
const decryptMetadataService = new DecryptMetadataService(apiClientOptions, account);
|
|
478
504
|
|
|
479
|
-
jest.spyOn(ResourceService.prototype, "create").mockImplementation((resource) => {
|
|
480
|
-
//Used to check the data sent to API
|
|
481
|
-
resourceToAPI = resource;
|
|
482
|
-
const resourceEntity = new ResourceEntity(resourceDto);
|
|
483
|
-
resourceEntity.secrets = new ResourceSecretsCollection([resourceToAPI.secrets[0]]);
|
|
484
|
-
resourceEntity.metadataKeyType = resourceToAPI.metadata_key_type;
|
|
485
|
-
resourceLocalStorageExpected = resourceEntity.toDto(ResourceLocalStorage.DEFAULT_CONTAIN);
|
|
486
|
-
resourceEntity.metadata = resourceToAPI.metadata;
|
|
487
|
-
return resourceEntity.toDto(ResourceLocalStorage.DEFAULT_CONTAIN);
|
|
488
|
-
});
|
|
489
505
|
jest
|
|
490
506
|
.spyOn(
|
|
491
507
|
resourceCreateService.encryptMetadataKeysService.getOrFindMetadataSettingsService
|
|
@@ -494,30 +510,16 @@ describe("ResourceCreateService", () => {
|
|
|
494
510
|
"findSettings",
|
|
495
511
|
)
|
|
496
512
|
.mockImplementation(() => metadataKeysSettingsDto);
|
|
513
|
+
jest.spyOn(ResourceService.prototype, "create").mockImplementation(() => {
|
|
514
|
+
const resourceEntity = new ResourceEntity(resourceDto);
|
|
515
|
+
return resourceEntity.toDto(ResourceLocalStorage.DEFAULT_CONTAIN);
|
|
516
|
+
});
|
|
497
517
|
jest.spyOn(ResourceService.prototype, "findAll").mockImplementation(() => [resourceDto]);
|
|
498
|
-
jest
|
|
499
|
-
.spyOn(FindFoldersService.prototype, "findByIdWithPermissions")
|
|
500
|
-
.mockImplementation(async () => new FolderEntity(folderDto));
|
|
501
|
-
jest.spyOn(resourceCreateService.shareResourceService, "shareAll");
|
|
502
|
-
jest.spyOn(resourceCreateService, "share");
|
|
503
|
-
//Decrypt secret
|
|
504
|
-
const decryptionKey = await OpenpgpAssertion.readKeyOrFail(pgpKeys.ada.private_decrypted);
|
|
505
|
-
jest.spyOn(GetDecryptedUserPrivateKeyService, "getKey").mockImplementationOnce(async () => decryptionKey);
|
|
506
518
|
|
|
507
519
|
await resourceCreateService.create(resourceDto, plaintextDto, pgpKeys.ada.passphrase);
|
|
508
520
|
|
|
509
|
-
//
|
|
510
|
-
|
|
511
|
-
expect(resourceEntityUpdated.isMetadataDecrypted()).toBeFalsy();
|
|
512
|
-
const privateKeyDecrypted = await OpenpgpAssertion.readKeyOrFail(pgpKeys.ada.private_decrypted);
|
|
513
|
-
await decryptMetadataService.decryptMetadataWithGpgKey(resourceEntityUpdated, privateKeyDecrypted);
|
|
514
|
-
|
|
515
|
-
expect(resourceCreateService.share).toHaveBeenCalledTimes(1);
|
|
516
|
-
expect(resourceCreateService.shareResourceService.shareAll).toHaveBeenCalledTimes(0);
|
|
517
|
-
//Metadata decrypted should be equal
|
|
518
|
-
expect(resourceEntityUpdated.metadata.toDto()).toEqual(resourceDto.metadata);
|
|
519
|
-
// Resource local storage should add the resource
|
|
520
|
-
expect(ResourceLocalStorage.addResource).toHaveBeenCalledWith(new ResourceEntity(resourceLocalStorageExpected));
|
|
521
|
+
// Operator-only V5: 4 steps (encrypt metadata + encrypt secret + create + local storage),
|
|
522
|
+
// no share-related steps anymore.
|
|
521
523
|
expect(resourceCreateService.progressService.updateGoals).toHaveBeenCalledWith(4);
|
|
522
524
|
});
|
|
523
525
|
});
|
|
@@ -18,13 +18,13 @@ import ExternalResourcesCollection from "../../../model/entity/resource/external
|
|
|
18
18
|
import ExternalTotpEntity from "../../../model/entity/totp/externalTotpEntity";
|
|
19
19
|
import ResourcesExporter from "../../../model/export/resourcesExporter";
|
|
20
20
|
import FolderModel from "../../../model/folder/folderModel";
|
|
21
|
-
import ResourceTypeModel from "../../../model/resourceType/resourceTypeModel";
|
|
22
21
|
import i18n from "../../../sdk/i18n";
|
|
23
22
|
import DecryptPrivateKeyService from "../../crypto/decryptPrivateKeyService";
|
|
24
23
|
import DecryptMetadataService from "../../metadata/decryptMetadataService";
|
|
25
24
|
import DecryptAndParseResourceSecretService from "../../secret/decryptAndParseResourceSecretService";
|
|
26
25
|
import FindResourcesService from "../findResourcesService";
|
|
27
26
|
import CustomFieldsCollection from "passbolt-styleguide/src/shared/models/entity/customField/customFieldsCollection";
|
|
27
|
+
import GetOrFindResourceTypesService from "../../resourceType/getOrFindResourceTypesService";
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
30
|
* The service aim to export the resources to a file.
|
|
@@ -42,7 +42,7 @@ class ExportResourcesService {
|
|
|
42
42
|
this.findResourcesService = new FindResourcesService(account, apiClientOptions);
|
|
43
43
|
this.decryptMetadataService = new DecryptMetadataService(apiClientOptions, account);
|
|
44
44
|
// Models
|
|
45
|
-
this.
|
|
45
|
+
this.getOrfindResourceTypesService = new GetOrFindResourceTypesService(account, apiClientOptions);
|
|
46
46
|
this.folderModel = new FolderModel(apiClientOptions, account);
|
|
47
47
|
}
|
|
48
48
|
|
|
@@ -50,12 +50,12 @@ class ExportResourcesService {
|
|
|
50
50
|
* Export resources to file and return the exported format
|
|
51
51
|
* @param {ExportResourcesFileEntity} exportResourcesFileEntity The export entity
|
|
52
52
|
* @param {String} passphrase the user passphrase
|
|
53
|
-
* @return {Promise<
|
|
53
|
+
* @return {Promise<Array>} The custom fields renamed to avoid conflicting with reserved field names
|
|
54
54
|
*/
|
|
55
55
|
async exportToFile(exportResourcesFileEntity, passphrase) {
|
|
56
56
|
const privateKey = await DecryptPrivateKeyService.decryptArmoredKey(this.account.userPrivateArmoredKey, passphrase);
|
|
57
57
|
await this.decryptSecrets(exportResourcesFileEntity, privateKey);
|
|
58
|
-
await this.export(exportResourcesFileEntity);
|
|
58
|
+
return await this.export(exportResourcesFileEntity);
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
/**
|
|
@@ -94,7 +94,7 @@ class ExportResourcesService {
|
|
|
94
94
|
async decryptSecrets(exportResourcesFileEntity, privateKey) {
|
|
95
95
|
let i = 0;
|
|
96
96
|
|
|
97
|
-
const resourceTypesCollection = await this.
|
|
97
|
+
const resourceTypesCollection = await this.getOrfindResourceTypesService.getOrFindAll();
|
|
98
98
|
for (const exportResourceEntity of exportResourcesFileEntity.exportResources.items) {
|
|
99
99
|
i++;
|
|
100
100
|
await this.progressService.finishStep(
|
|
@@ -143,12 +143,12 @@ class ExportResourcesService {
|
|
|
143
143
|
/**
|
|
144
144
|
* Export
|
|
145
145
|
* @param {ExportResourcesFileEntity} exportResourcesFileEntity The export object
|
|
146
|
-
* @returns {Promise<
|
|
146
|
+
* @returns {Promise<Array>} The custom fields renamed to avoid conflicting with reserved field names
|
|
147
147
|
* @private
|
|
148
148
|
*/
|
|
149
149
|
async export(exportResourcesFileEntity) {
|
|
150
150
|
const exporter = new ResourcesExporter();
|
|
151
|
-
await exporter.export(exportResourcesFileEntity);
|
|
151
|
+
return await exporter.export(exportResourcesFileEntity);
|
|
152
152
|
}
|
|
153
153
|
}
|
|
154
154
|
|
package/src/all/background_page/service/resource/findAndUpdateResourcesLocalStorageService.js
CHANGED
|
@@ -15,8 +15,8 @@ import ResourceLocalStorage from "../local_storage/resourceLocalStorage";
|
|
|
15
15
|
import { assertNumber, assertUuid } from "../../utils/assertions";
|
|
16
16
|
import FindResourcesService from "./findResourcesService";
|
|
17
17
|
import ResourcesCollection from "../../model/entity/resource/resourcesCollection";
|
|
18
|
-
import ResourceTypeModel from "../../model/resourceType/resourceTypeModel";
|
|
19
18
|
import DecryptMetadataService from "../metadata/decryptMetadataService";
|
|
19
|
+
import GetOrFindResourceTypesService from "../resourceType/getOrFindResourceTypesService";
|
|
20
20
|
|
|
21
21
|
const RESOURCES_UPDATE_ALL_LS_LOCK_PREFIX = "RESOURCES_UPDATE_LS_LOCK_";
|
|
22
22
|
|
|
@@ -39,7 +39,7 @@ class FindAndUpdateResourcesLocalStorage {
|
|
|
39
39
|
constructor(account, apiClientOptions) {
|
|
40
40
|
this.account = account;
|
|
41
41
|
this.findResourcesServices = new FindResourcesService(account, apiClientOptions);
|
|
42
|
-
this.
|
|
42
|
+
this.getOrFindResourceTypesService = new GetOrFindResourceTypesService(account, apiClientOptions);
|
|
43
43
|
this.decryptMetadataService = new DecryptMetadataService(apiClientOptions, account);
|
|
44
44
|
}
|
|
45
45
|
|
|
@@ -89,7 +89,7 @@ class FindAndUpdateResourcesLocalStorage {
|
|
|
89
89
|
});
|
|
90
90
|
|
|
91
91
|
const updatedResourcesCollection = await this.findResourcesServices.findAllForLocalStorage();
|
|
92
|
-
const resourceTypes = await this.
|
|
92
|
+
const resourceTypes = await this.getOrFindResourceTypesService.getOrFindAll();
|
|
93
93
|
updatedResourcesCollection.filterByResourceTypes(resourceTypes);
|
|
94
94
|
updatedResourcesCollection.setDecryptedMetadataFromCollection(localResourcesCollection);
|
|
95
95
|
|
|
@@ -135,7 +135,7 @@ class FindAndUpdateResourcesLocalStorage {
|
|
|
135
135
|
*/
|
|
136
136
|
async findAndUpdateAllByParentFolderId(parentFolderId, passphrase = null) {
|
|
137
137
|
assertUuid(parentFolderId);
|
|
138
|
-
const resourceTypes = await this.
|
|
138
|
+
const resourceTypes = await this.getOrFindResourceTypesService.getOrFindAll();
|
|
139
139
|
|
|
140
140
|
const apiResourcesCollection =
|
|
141
141
|
await this.findResourcesServices.findAllByParentFolderIdForLocalStorage(parentFolderId);
|
|
@@ -14,13 +14,13 @@
|
|
|
14
14
|
import ResourceService from "../api/resource/resourceService";
|
|
15
15
|
import ResourceLocalStorage from "../local_storage/resourceLocalStorage";
|
|
16
16
|
import ResourcesCollection from "../../model/entity/resource/resourcesCollection";
|
|
17
|
-
import ResourceTypeModel from "../../model/resourceType/resourceTypeModel";
|
|
18
17
|
import { assertArrayUUID, assertUuid } from "../../utils/assertions";
|
|
19
18
|
import ExecuteConcurrentlyService from "../execute/executeConcurrentlyService";
|
|
20
19
|
import splitBySize from "../../utils/array/splitBySize";
|
|
21
20
|
import ResourceEntity from "../../model/entity/resource/resourceEntity";
|
|
22
21
|
import DecryptMetadataService from "../metadata/decryptMetadataService";
|
|
23
22
|
import { assertNumber } from "passbolt-styleguide/src/shared/utils/assertions";
|
|
23
|
+
import GetOrFindResourceTypesService from "../resourceType/getOrFindResourceTypesService";
|
|
24
24
|
|
|
25
25
|
const DEFAULT_PAGE_SIZE = 10_000;
|
|
26
26
|
|
|
@@ -36,8 +36,8 @@ export default class FindResourcesService {
|
|
|
36
36
|
constructor(account, apiClientOptions) {
|
|
37
37
|
this.account = account;
|
|
38
38
|
this.resourceService = new ResourceService(apiClientOptions);
|
|
39
|
-
this.resourceTypeModel = new ResourceTypeModel(apiClientOptions);
|
|
40
39
|
this.decryptMetadataService = new DecryptMetadataService(apiClientOptions, account);
|
|
40
|
+
this.getOrFindResourceTypesService = new GetOrFindResourceTypesService(account, apiClientOptions);
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
/**
|
|
@@ -145,7 +145,7 @@ export default class FindResourcesService {
|
|
|
145
145
|
{ "is-shared-with-group": groupId },
|
|
146
146
|
true,
|
|
147
147
|
);
|
|
148
|
-
const resourceTypes = await this.
|
|
148
|
+
const resourceTypes = await this.getOrFindResourceTypesService.getOrFindAll();
|
|
149
149
|
resources.filterByResourceTypes(resourceTypes);
|
|
150
150
|
|
|
151
151
|
await this.decryptMetadataService.decryptAllFromForeignModels(resources, passphrase, {
|
|
@@ -174,40 +174,37 @@ export default class FindResourcesService {
|
|
|
174
174
|
}
|
|
175
175
|
|
|
176
176
|
/**
|
|
177
|
-
* Retrieve
|
|
177
|
+
* Retrieve resources by ids with their permissions (embedding each permission's user profile or
|
|
178
|
+
* group), tailored for the share process. The metadata is intentionally not requested nor
|
|
179
|
+
* decrypted, so no passphrase prompt is triggered.
|
|
178
180
|
* @param {Array<string>} resourcesIds The resource ids to retrieve.
|
|
179
181
|
* @returns {Promise<ResourcesCollection>}
|
|
180
182
|
*/
|
|
181
|
-
async
|
|
183
|
+
async findAllPermissionsByIdsForShare(resourcesIds) {
|
|
182
184
|
assertArrayUUID(resourcesIds);
|
|
183
185
|
|
|
184
186
|
const contains = {
|
|
185
|
-
|
|
186
|
-
permissions: true,
|
|
187
|
+
"permissions.user.profile": true,
|
|
188
|
+
"permissions.group": true,
|
|
187
189
|
};
|
|
188
190
|
|
|
189
191
|
return this.findAllByIds(resourcesIds, contains);
|
|
190
192
|
}
|
|
191
193
|
|
|
192
194
|
/**
|
|
193
|
-
* Retrieve all resources by ids
|
|
195
|
+
* Retrieve all resources by ids with permissions.
|
|
194
196
|
* @param {Array<string>} resourcesIds The resource ids to retrieve.
|
|
195
|
-
* @param {string|null} [passphrase = null] The passphrase to use to decrypt the metadata. Marked as optional as it
|
|
196
|
-
* might be available in the passphrase session storage.
|
|
197
197
|
* @returns {Promise<ResourcesCollection>}
|
|
198
198
|
*/
|
|
199
|
-
async
|
|
199
|
+
async findAllByIdsWithPermissions(resourcesIds) {
|
|
200
200
|
assertArrayUUID(resourcesIds);
|
|
201
201
|
|
|
202
202
|
const contains = {
|
|
203
203
|
permission: true,
|
|
204
|
-
|
|
205
|
-
"permissions.group": true,
|
|
204
|
+
permissions: true,
|
|
206
205
|
};
|
|
207
|
-
const resources = await this.findAllByIds(resourcesIds, contains);
|
|
208
|
-
await this.decryptMetadataService.decryptAllFromForeignModels(resources, passphrase);
|
|
209
206
|
|
|
210
|
-
return
|
|
207
|
+
return this.findAllByIds(resourcesIds, contains);
|
|
211
208
|
}
|
|
212
209
|
|
|
213
210
|
/**
|