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.
Files changed (282) hide show
  1. package/.devcontainer/Dockerfile +33 -3
  2. package/.devcontainer/devcontainer-lock.json +9 -0
  3. package/.devcontainer/post-start.sh +1 -2
  4. package/.github/workflows/codeql-analysis.yml +2 -1
  5. package/.github/workflows/release_candidate.yaml +3 -1
  6. package/.gitlab-ci.yml +1 -0
  7. package/CHANGELOG.md +202 -70
  8. package/CODEOWNERS +2 -0
  9. package/RELEASE_NOTES.md +4 -2
  10. package/package.json +9 -7
  11. package/renovate.json +6 -0
  12. package/src/all/background_page/controller/InformMenuController/InformMenuController.js +2 -5
  13. package/src/all/background_page/controller/InformMenuController/InformMenuController.test.js +31 -1
  14. package/src/all/background_page/controller/account/getAndInitializeAccountLocaleController.js +1 -1
  15. package/src/all/background_page/controller/account/getAndInitializeAccountLocaleController.test.js +6 -14
  16. package/src/all/background_page/controller/account/updatePrivateKeyController.js +7 -5
  17. package/src/all/background_page/controller/account/updatePrivateKeyController.test.js +18 -13
  18. package/src/all/background_page/controller/accountRecovery/accountRecoveryGenerateOrganizationKeyController.js +4 -2
  19. package/src/all/background_page/controller/accountRecovery/accountRecoveryGenerateOrganizationKeyController.test.js +25 -2
  20. package/src/all/background_page/controller/accountRecovery/accountRecoveryLoginController.js +1 -1
  21. package/src/all/background_page/controller/accountRecovery/accountRecoveryLoginController.test.js +10 -5
  22. package/src/all/background_page/controller/accountRecovery/recoverAccountController.js +6 -2
  23. package/src/all/background_page/controller/accountRecovery/recoverAccountController.test.js +11 -4
  24. package/src/all/background_page/controller/auth/authCheckStatus.test.data.js +6 -6
  25. package/src/all/background_page/controller/auth/authCheckStatusController.js +11 -3
  26. package/src/all/background_page/controller/auth/authCheckStatusController.test.js +74 -44
  27. package/src/all/background_page/controller/auth/authIsMfaRequiredController.js +11 -3
  28. package/src/all/background_page/controller/auth/authIsMfaRequiredController.test.js +18 -9
  29. package/src/all/background_page/controller/auth/authLoginController.js +1 -1
  30. package/src/all/background_page/controller/auth/authLoginController.test.js +10 -5
  31. package/src/all/background_page/controller/autofill/AutofillController.js +3 -3
  32. package/src/all/background_page/controller/autofill/AutofillController.test.js +20 -12
  33. package/src/all/background_page/controller/export/exportResourcesFileController.js +6 -3
  34. package/src/all/background_page/controller/export/exportResourcesFileController.test.js +34 -4
  35. package/src/all/background_page/controller/extension/onExtensionInstalledController.js +8 -2
  36. package/src/all/background_page/controller/extension/onExtensionInstalledController.test.js +5 -1
  37. package/src/all/background_page/controller/group/{getOrFindGroupsController.js → findGroupsByIdsForShareController.js} +9 -10
  38. package/src/all/background_page/controller/group/{getOrFindGroupsController.test.js → findGroupsByIdsForShareController.test.js} +8 -8
  39. package/src/all/background_page/controller/group/groupUpdateController.test.js +1 -0
  40. package/src/all/background_page/controller/import/importResourcesFileController.test.js +8 -1
  41. package/src/all/background_page/controller/informCallToActionController/informCallToActionController.js +2 -2
  42. package/src/all/background_page/controller/informCallToActionController/informCallToActionController.test.js +7 -4
  43. package/src/all/background_page/controller/locale/getLocaleController.js +3 -2
  44. package/src/all/background_page/controller/metadata/findMetadataTypesSettingsController.test.js +9 -15
  45. package/src/all/background_page/controller/metadata/getMetadataTypesSettingsController.test.js +9 -15
  46. package/src/all/background_page/controller/metadata/getOrFindMetadataKeysSettingsController.test.js +12 -22
  47. package/src/all/background_page/controller/metadata/shareMetadataKeyPrivateController.test.js +14 -2
  48. package/src/all/background_page/controller/move/moveFolderController.test.js +8 -0
  49. package/src/all/background_page/controller/move/moveResourcesController.test.js +8 -0
  50. package/src/all/background_page/controller/passwordExpiry/getOrFindPasswordExpirySettingsController.test.js +13 -8
  51. package/src/all/background_page/controller/passwordExpiry/savePasswordExpirySettingsController.js +4 -4
  52. package/src/all/background_page/controller/passwordExpiry/savePasswordExpirySettingsController.test.js +8 -10
  53. package/src/all/background_page/controller/permission/findPermissionsByIdsForShareController.js +62 -0
  54. package/src/all/background_page/controller/permission/findPermissionsByIdsForShareController.test.js +71 -0
  55. package/src/all/background_page/controller/recover/generateRecoverAccountRecoveryRequestKeyController.js +1 -1
  56. package/src/all/background_page/controller/resource/resourceCreateController.js +11 -4
  57. package/src/all/background_page/controller/resource/resourceCreateController.test.js +12 -1
  58. package/src/all/background_page/controller/resource/resourceUpdateController.js +11 -4
  59. package/src/all/background_page/controller/resource/resourceUpdateController.test.js +35 -2
  60. package/src/all/background_page/controller/resourceType/getResourceTypesController.js +5 -4
  61. package/src/all/background_page/controller/resourceType/getResourceTypesController.test.js +5 -2
  62. package/src/all/background_page/controller/resourceType/updateAllResourceTypesDeletedStatusController.js +3 -2
  63. package/src/all/background_page/controller/resourceType/updateAllResourceTypesDeletedStatusController.test.js +16 -3
  64. package/src/all/background_page/controller/secret/findSecretByResourceIdController.js +3 -3
  65. package/src/all/background_page/controller/secret/findSecretByResourceIdController.test.js +24 -0
  66. package/src/all/background_page/controller/secretRevision/findResourceSecretRevisionsForDisplayController.js +2 -1
  67. package/src/all/background_page/controller/setup/generateSetupKeyPairController.js +6 -3
  68. package/src/all/background_page/controller/setup/generateSetupKeyPairController.test.js +11 -1
  69. package/src/all/background_page/controller/setup/getAndInitSetupLocaleController.js +1 -1
  70. package/src/all/background_page/controller/setup/getAndInitSetupLocaleController.test.js +14 -18
  71. package/src/all/background_page/controller/setup/setSetupLocaleController.js +1 -1
  72. package/src/all/background_page/controller/setup/setSetupLocaleController.test.js +6 -10
  73. package/src/all/background_page/controller/setup/signInSetupController.js +6 -2
  74. package/src/all/background_page/controller/setup/signInSetupController.test.js +10 -5
  75. package/src/all/background_page/controller/share/shareOneFolderController.test.js +8 -0
  76. package/src/all/background_page/controller/share/shareResourcesController.test.js +9 -1
  77. package/src/all/background_page/controller/siteSettings/getOrFindSiteSettingsController.js +59 -0
  78. package/src/all/background_page/controller/siteSettings/getOrFindSiteSettingsController.test.js +150 -0
  79. package/src/all/background_page/controller/{group/getOrFindGroupsUsersController.js → user/getOrFindAllUsersController.js} +12 -17
  80. package/src/all/background_page/controller/user/getOrFindAllUsersController.test.js +55 -0
  81. package/src/all/background_page/controller/user/getOrFindLoggedInUserController.js +3 -3
  82. package/src/all/background_page/controller/user/getOrFindLoggedInUserController.test.js +19 -15
  83. package/src/all/background_page/controller/user/updateUserLocalStorageController.test.js +8 -5
  84. package/src/all/background_page/event/accountRecoveryEvents.js +4 -4
  85. package/src/all/background_page/event/appEvents.js +7 -2
  86. package/src/all/background_page/event/authEvents.js +2 -2
  87. package/src/all/background_page/event/groupEvents.js +4 -17
  88. package/src/all/background_page/event/informCallToActionEvents.js +1 -1
  89. package/src/all/background_page/event/informMenuEvents.js +1 -1
  90. package/src/all/background_page/event/localeEvents.js +4 -3
  91. package/src/all/background_page/event/permissionEvents.js +13 -0
  92. package/src/all/background_page/event/recoverEvents.js +4 -4
  93. package/src/all/background_page/event/resourceEvents.js +6 -15
  94. package/src/all/background_page/event/resourceTypeEvents.js +4 -3
  95. package/src/all/background_page/event/setupEvents.js +4 -4
  96. package/src/all/background_page/event/siteSettingsEvents.js +29 -0
  97. package/src/all/background_page/event/userEvents.js +4 -8
  98. package/src/all/background_page/index.js +0 -37
  99. package/src/all/background_page/model/entity/account/abstractAccountEntity.js +2 -2
  100. package/src/all/background_page/model/entity/account/accountAccountRecoveryEntity.js +7 -17
  101. package/src/all/background_page/model/entity/account/accountEntity.js +7 -14
  102. package/src/all/background_page/model/entity/account/accountKitEntity.js +1 -2
  103. package/src/all/background_page/model/entity/account/accountRecoverEntity.js +4 -14
  104. package/src/all/background_page/model/entity/account/accountSetupEntity.js +4 -14
  105. package/src/all/background_page/model/entity/account/accountTemporaryEntity.js +2 -5
  106. package/src/all/background_page/model/entity/gpgkey/generate/generateGpgKeyPairOptionsEntity.test.js +5 -5
  107. package/src/all/background_page/model/entity/localStorage/localStorageMetadataEntity.js +49 -0
  108. package/src/all/background_page/model/entity/localStorage/localStorageMetadataEntity.test.data.js +23 -0
  109. package/src/all/background_page/model/entity/localStorage/localStorageMetadataEntity.test.js +51 -0
  110. package/src/all/background_page/model/entity/{organizationSettings/organizationSettingsEntity.js → siteSettings/siteSettingsEntity.js} +17 -24
  111. package/src/all/background_page/model/entity/{organizationSettings/organizationSettingsEntity.test.data.js → siteSettings/siteSettingsEntity.test.data.js} +9 -9
  112. package/src/all/background_page/model/entity/{organizationSettings/organizationSettingsEntity.test.js → siteSettings/siteSettingsEntity.test.js} +30 -39
  113. package/src/all/background_page/model/entity/user/userEntity.test.js +6 -6
  114. package/src/all/background_page/model/export/resources/resourcesKdbxExporter.js +40 -3
  115. package/src/all/background_page/model/export/resources/resourcesKdbxExporter.test.js +122 -0
  116. package/src/all/background_page/model/import/resources/resourcesKdbxImportParser.js +1 -1
  117. package/src/all/background_page/model/locale/localeModel.js +13 -8
  118. package/src/all/background_page/model/passwordExpiry/passwordExpirySettingsModel.js +6 -6
  119. package/src/all/background_page/model/passwordExpiry/passwordExpirySettingsModel.test.js +3 -2
  120. package/src/all/background_page/model/resource/resourceModel.js +4 -4
  121. package/src/all/background_page/model/user/userModel.js +7 -28
  122. package/src/all/background_page/model/user/userModel.test.js +51 -99
  123. package/src/all/background_page/pagemod/appBootstrapPagemod.js +4 -1
  124. package/src/all/background_page/pagemod/appBootstrapPagemod.test.js +5 -2
  125. package/src/all/background_page/pagemod/appPagemod.js +32 -6
  126. package/src/all/background_page/pagemod/appPagemod.test.js +22 -10
  127. package/src/all/background_page/pagemod/authPagemod.js +2 -10
  128. package/src/all/background_page/pagemod/authPagemod.test.js +4 -4
  129. package/src/all/background_page/pagemod/pagemodManager.test.js +5 -2
  130. package/src/all/background_page/pagemod/quickAccessPagemod.js +2 -2
  131. package/src/all/background_page/pagemod/quickAccessPagemod.test.js +4 -4
  132. package/src/all/background_page/pagemod/recoverPagemod.js +2 -2
  133. package/src/all/background_page/pagemod/recoverPagemod.test.js +6 -0
  134. package/src/all/background_page/pagemod/setupPagemod.js +2 -2
  135. package/src/all/background_page/pagemod/setupPagemod.test.js +6 -0
  136. package/src/all/background_page/pagemod/webIntegrationPagemod.js +21 -2
  137. package/src/all/background_page/pagemod/webIntegrationPagemod.test.js +16 -25
  138. package/src/all/background_page/service/account/getActiveAccountService.js +2 -3
  139. package/src/all/background_page/service/account/getLegacyAccountService.js +3 -14
  140. package/src/all/background_page/service/account/updateSsoCredentialsService.js +9 -5
  141. package/src/all/background_page/service/api/group/groupApiService.js +9 -16
  142. package/src/all/background_page/service/api/group/groupApiService.test.js +59 -26
  143. package/src/all/background_page/service/api/siteSettings/siteSettingsApiService.js +46 -0
  144. package/src/all/background_page/service/api/siteSettings/siteSettingsApiService.test.js +63 -0
  145. package/src/all/background_page/service/auth/checkAuthStatusService.js +27 -14
  146. package/src/all/background_page/service/auth/checkAuthStatusService.test.js +80 -62
  147. package/src/all/background_page/service/auth/postLoginService.js +3 -3
  148. package/src/all/background_page/service/auth/postLoginService.test.js +4 -4
  149. package/src/all/background_page/service/auth/startLoopAuthSessionCheckService.js +5 -1
  150. package/src/all/background_page/service/auth/startLoopAuthSessionCheckService.test.js +14 -8
  151. package/src/all/background_page/service/authenticationStatusService.js +13 -18
  152. package/src/all/background_page/service/authenticationStatusService.test.js +9 -6
  153. package/src/all/background_page/service/crypto/generateGpgKeyPairService.test.js +5 -5
  154. package/src/all/background_page/service/crypto/getGpgKeyCreationDateService.js +7 -6
  155. package/src/all/background_page/service/crypto/getGpgKeyCreationDateService.test.js +10 -7
  156. package/src/all/background_page/service/extension/onExtensionUpdateAvailableService.js +7 -2
  157. package/src/all/background_page/service/extension/onExtensionUpdateAvailableService.test.js +5 -5
  158. package/src/all/background_page/service/group/findGroupsService.js +42 -1
  159. package/src/all/background_page/service/group/findGroupsService.test.js +82 -0
  160. package/src/all/background_page/service/group/groupUpdateSecretsCryptoService.js +82 -0
  161. package/src/all/background_page/service/group/groupUpdateSecretsCryptoService.test.js +102 -0
  162. package/src/all/background_page/service/group/groupUpdateService.js +49 -78
  163. package/src/all/background_page/service/group/groupUpdateService.test.js +136 -0
  164. package/src/all/background_page/service/localStorage/localStorageService.js +8 -6
  165. package/src/all/background_page/service/localStorage/localStorageService.test.js +33 -15
  166. package/src/all/background_page/service/local_storage/abstractLocalStorage.js +193 -0
  167. package/src/all/background_page/service/local_storage/abstractLocalStorage.test.data.js +45 -0
  168. package/src/all/background_page/service/local_storage/abstractLocalStorage.test.js +271 -0
  169. package/src/all/background_page/service/local_storage/activeSessionLocalStorage.js +105 -0
  170. package/src/all/background_page/service/local_storage/activeSessionLocalStorage.test.js +153 -0
  171. package/src/all/background_page/service/local_storage/rbacLocalStorage.js +10 -82
  172. package/src/all/background_page/service/local_storage/rbacLocalStorage.test.js +8 -8
  173. package/src/all/background_page/service/local_storage/resourceTypeLocalStorage.js +10 -43
  174. package/src/all/background_page/service/local_storage/resourceTypeLocalStorage.test.js +68 -0
  175. package/src/all/background_page/service/local_storage/siteSettingsLocalStorage.js +104 -0
  176. package/src/all/background_page/service/local_storage/siteSettingsLocalStorage.test.js +114 -0
  177. package/src/all/background_page/service/local_storage/userMeLocalStorage.js +50 -0
  178. package/src/all/background_page/service/{sessionStorage/userMeSessionStorageService.test.js → local_storage/userMeLocalStorage.test.js} +55 -36
  179. package/src/all/background_page/service/metadata/encryptMetadataService.js +3 -3
  180. package/src/all/background_page/service/metadata/encryptMetadataService.test.js +11 -11
  181. package/src/all/background_page/service/metadata/findAndUpdateMetadataSettingsLocalStorageService.js +4 -4
  182. package/src/all/background_page/service/metadata/findAndUpdateMetadataSettingsLocalStorageService.test.js +18 -16
  183. package/src/all/background_page/service/metadata/getOrFindMetadataSettingsService.test.js +6 -8
  184. package/src/all/background_page/service/metadata/rotateMetadata/rotateResourcesMetadataKeyService.test.js +4 -4
  185. package/src/all/background_page/service/metadata/shareMetadataKeyPrivateService.js +3 -3
  186. package/src/all/background_page/service/metadata/shareMetadataKeyPrivateService.test.js +1 -1
  187. package/src/all/background_page/service/metadata/verifyOrTrustMetadataKeyService.js +4 -4
  188. package/src/all/background_page/service/metadata/verifyOrTrustMetadataKeyService.test.js +9 -7
  189. package/src/all/background_page/service/migrateMetadata/migrateMetadataResourcesService.js +4 -4
  190. package/src/all/background_page/service/migrateMetadata/migrateMetadataResourcesService.test.js +6 -6
  191. package/src/all/background_page/service/rbac/findAndUpdateRbacsLocalStorageService.js +2 -2
  192. package/src/all/background_page/service/rbac/getOrFindRbacService.js +1 -1
  193. package/src/all/background_page/service/resource/create/resourceCreateService.js +41 -51
  194. package/src/all/background_page/service/resource/create/resourceCreateService.test.js +100 -98
  195. package/src/all/background_page/service/resource/export/exportResourcesService.js +7 -7
  196. package/src/all/background_page/service/resource/findAndUpdateResourcesLocalStorageService.js +4 -4
  197. package/src/all/background_page/service/resource/findResourcesService.js +13 -16
  198. package/src/all/background_page/service/resource/findResourcesService.test.js +12 -11
  199. package/src/all/background_page/service/resource/getOrFindResourcesService.js +3 -3
  200. package/src/all/background_page/service/resource/import/ImportResourcesService.js +9 -9
  201. package/src/all/background_page/service/resource/import/ImportResourcesService.test.js +30 -15
  202. package/src/all/background_page/service/resource/update/resourceUpdateService.js +38 -19
  203. package/src/all/background_page/service/resource/update/resourceUpdateService.test.js +64 -31
  204. package/src/all/background_page/service/resourceType/getOrFindResourceTypesService.js +49 -0
  205. package/src/all/background_page/service/resourceType/getOrFindResourceTypesService.test.js +61 -0
  206. package/src/all/background_page/service/resourceType/getSecretSchemaResourceTypeService.js +44 -0
  207. package/src/all/background_page/service/resourceType/updateResourceTypesService.js +6 -4
  208. package/src/all/background_page/service/resourceType/updateResourceTypesService.test.js +19 -14
  209. package/src/all/background_page/service/secretRevisions/findAndDecryptSecretRevisionsService.js +5 -4
  210. package/src/all/background_page/service/secretRevisions/findAndDecryptSecretRevisionsService.test.js +16 -9
  211. package/src/all/background_page/service/share/shareResourceService.js +4 -4
  212. package/src/all/background_page/service/share/shareResourceService.test.js +6 -6
  213. package/src/all/background_page/service/siteSettings/findAndUpdateSiteSettingsLocalStorageService.js +77 -0
  214. package/src/all/background_page/service/siteSettings/findAndUpdateSiteSettingsLocalStorageService.test.js +130 -0
  215. package/src/all/background_page/service/siteSettings/findSiteSettingsService.js +47 -0
  216. package/src/all/background_page/service/siteSettings/findSiteSettingsService.test.js +68 -0
  217. package/src/all/background_page/service/siteSettings/getOrFindSiteSettingsService.js +84 -0
  218. package/src/all/background_page/service/siteSettings/getOrFindSiteSettingsService.test.js +175 -0
  219. package/src/all/background_page/service/siteSettings/siteSettingsRuntimeCache.js +70 -0
  220. package/src/all/background_page/service/sso/generateSsoKitService.test.js +2 -2
  221. package/src/all/background_page/service/toolbar/toolbarService.js +6 -4
  222. package/src/all/background_page/service/toolbar/toolbarService.test.js +14 -13
  223. package/src/all/background_page/service/user/findAndUpdateUsersLocalStorageService.js +4 -4
  224. package/src/all/background_page/service/user/findAndUpdateUsersLocalStorageService.test.js +3 -3
  225. package/src/all/background_page/service/user/getOrFindMeService.js +64 -0
  226. package/src/all/background_page/service/user/getOrFindMeService.test.js +65 -0
  227. package/src/all/background_page/service/userKeyPolicies/findUserKeyPoliciesSettingsService.js +5 -4
  228. package/src/all/background_page/service/userKeyPolicies/findUserKeyPoliciesSettingsService.test.js +12 -11
  229. package/src/all/background_page/service/validator/appEmailValidatorService.js +11 -6
  230. package/src/all/background_page/service/validator/appEmailValidatorService.test.js +11 -11
  231. package/src/all/common/polyfill/browserPolyfill.js +8 -8
  232. package/src/all/locales/cs-CZ/common.json +1 -4
  233. package/src/all/locales/de-DE/common.json +1 -4
  234. package/src/all/locales/en-UK/common.json +0 -3
  235. package/src/all/locales/es-ES/common.json +1 -4
  236. package/src/all/locales/fr-FR/common.json +1 -4
  237. package/src/all/locales/it-IT/common.json +1 -4
  238. package/src/all/locales/ja-JP/common.json +1 -4
  239. package/src/all/locales/ko-KR/common.json +0 -3
  240. package/src/all/locales/lt-LT/common.json +1 -4
  241. package/src/all/locales/nl-NL/common.json +1 -4
  242. package/src/all/locales/pl-PL/common.json +1 -4
  243. package/src/all/locales/pt-BR/common.json +1 -4
  244. package/src/all/locales/ro-RO/common.json +1 -4
  245. package/src/all/locales/ru-RU/common.json +1 -4
  246. package/src/all/locales/sl-SI/common.json +1 -4
  247. package/src/all/locales/sv-SE/common.json +1 -4
  248. package/src/all/locales/uk-UA/common.json +1 -4
  249. package/src/all/webAccessibleResources/js/app/QuickAccess.js +7 -0
  250. package/src/chrome/manifest.json +1 -1
  251. package/src/chrome-mv3/manifest.json +1 -1
  252. package/src/chrome-mv3/offscreens/service/group/addUsersToGroupOffscreenService.js +132 -0
  253. package/src/chrome-mv3/offscreens/service/group/addUsersToGroupOffscreenService.test.js +125 -0
  254. package/src/chrome-mv3/offscreens/service/offscreen/handleOffscreenRequestService.js +4 -0
  255. package/src/chrome-mv3/serviceWorker/service/addUsersToGroup/requestAddUsersToGroupOffscreenService.js +83 -0
  256. package/src/chrome-mv3/serviceWorker/service/addUsersToGroup/requestAddUsersToGroupOffscreenService.test.js +116 -0
  257. package/src/chrome-mv3/serviceWorker/service/addUsersToGroup/responseAddUsersToGroupOffscreenService.js +99 -0
  258. package/src/chrome-mv3/serviceWorker/service/addUsersToGroup/responseAddUsersToGroupOffscreenService.test.data.js +45 -0
  259. package/src/chrome-mv3/serviceWorker/service/addUsersToGroup/responseAddUsersToGroupOffscreenService.test.js +87 -0
  260. package/src/chrome-mv3/serviceWorker/service/network/requestFetchOffscreenService.js +0 -1
  261. package/src/chrome-mv3/serviceWorker/service/offscreen/handleOffscreenResponseService.js +15 -0
  262. package/src/firefox/manifest.json +1 -1
  263. package/src/safari/background_page/index.js +0 -37
  264. package/src/safari/common/polyfill/safariBrowserPolyfill.js +10 -10
  265. package/src/safari/manifest.json +1 -1
  266. package/test/jest.setup.js +4 -2
  267. package/src/all/background_page/controller/group/getOrFindGroupsUsersController.test.js +0 -69
  268. package/src/all/background_page/controller/organizationSettings/getOrganizationSettingsController.js +0 -55
  269. package/src/all/background_page/controller/organizationSettings/getOrganizationSettingsController.test.js +0 -45
  270. package/src/all/background_page/controller/resource/findAllByIdsForDisplayPermissionsController.js +0 -76
  271. package/src/all/background_page/controller/resource/findAllByIdsForDisplayPermissionsController.test.js +0 -102
  272. package/src/all/background_page/event/organizationSettingsEvents.js +0 -37
  273. package/src/all/background_page/model/organizationSettings/organizationSettingsModel.js +0 -93
  274. package/src/all/background_page/model/resourceType/resourceTypeModel.js +0 -72
  275. package/src/all/background_page/model/resourceType/resourceTypeModel.test.js +0 -101
  276. package/src/all/background_page/service/api/organizationSettings/organizationSettingsService.js +0 -58
  277. package/src/all/background_page/service/group/getOrFindGroupsService.js +0 -65
  278. package/src/all/background_page/service/group/getOrFindGroupsService.test.js +0 -168
  279. package/src/all/background_page/service/group/getOrFindGroupsUsersService.js +0 -51
  280. package/src/all/background_page/service/group/getOrFindGroupsUsersService.test.js +0 -94
  281. package/src/all/background_page/service/local_storage/authStatusLocalStorage.js +0 -70
  282. 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.resourceTypeModel = new ResourceTypeModel(apiClientOptions);
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.resourceTypeModel.getOrFindAll();
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, permissionChanges, passphrase);
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
- // Share the resource with the metadata decrypted
84
- await this.share(createdResource, passphrase, destinationFolder, permissionChanges);
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
- * Share the resource.
126
- *
127
- * @param {ResourceEntity} resource The resource to share.
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, permissionChanges, passphrase) {
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 = !permissionChanges.length;
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} changesLength number of permissions changes
154
+ * @param {number} permissionChangesLength number of permission changes that will be applied after create
164
155
  * @private
165
156
  */
166
- updateGoals(shouldEncryptMetadata, changesLength = 0) {
167
- const stepToCreate = shouldEncryptMetadata ? 4 : 3;
168
- // 1 inline step ("Calculate permissions") + shareAll's fixed internal steps.
169
- const shareSteps = changesLength > 0 ? 1 + PROGRESS_STEPS_SHARE_RESOURCES_SHARE_ALL : 0;
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 into shared folder parent", async () => {
367
- expect.assertions(1);
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
- const shareResourceChanges = {
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
- .spyOn(FindFoldersService.prototype, "findByIdWithPermissions")
382
- .mockImplementation(
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
- jest.spyOn(resourceCreateService, "share");
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.share).toHaveBeenCalledTimes(1);
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 the resource V5 into shared folder parent", async () => {
401
- expect.assertions(5);
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(() => mockPassboltResponse([resourceDto]));
432
- jest
433
- .spyOn(FindFoldersService.prototype, "findByIdWithPermissions")
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
- expect(resourceEntityUpdated.isMetadataDecrypted()).toBeFalsy();
454
- await decryptMetadataService.decryptOneWithSharedKey(resourceEntityUpdated);
485
+ const privateKeyDecrypted = await OpenpgpAssertion.readKeyOrFail(pgpKeys.ada.private_decrypted);
486
+ await decryptMetadataService.decryptMetadataWithGpgKey(resourceEntityUpdated, privateKeyDecrypted);
455
487
 
456
- expect(resourceCreateService.share).toHaveBeenCalledTimes(1);
457
- //Metadata decrypted should be equal
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 create the resource V5 into personal folder parent", async () => {
465
- expect.assertions(6);
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
- // Decrypt metadata
510
- const resourceEntityUpdated = new ResourceEntity(resourceToAPI);
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.resourceTypeModel = new ResourceTypeModel(apiClientOptions);
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<void>}
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.resourceTypeModel.getOrFindAll();
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<void>}
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
 
@@ -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.resourceTypeModel = new ResourceTypeModel(apiClientOptions);
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.resourceTypeModel.getOrFindAll();
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.resourceTypeModel.getOrFindAll();
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.resourceTypeModel.getOrFindAll();
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 all resources by ids with permissions.
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 findAllByIdsWithPermissions(resourcesIds) {
183
+ async findAllPermissionsByIdsForShare(resourcesIds) {
182
184
  assertArrayUUID(resourcesIds);
183
185
 
184
186
  const contains = {
185
- permission: true,
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 for display permissions.
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 findAllByIdsForDisplayPermissions(resourcesIds, passphrase = null) {
199
+ async findAllByIdsWithPermissions(resourcesIds) {
200
200
  assertArrayUUID(resourcesIds);
201
201
 
202
202
  const contains = {
203
203
  permission: true,
204
- "permissions.user.profile": true,
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 resources;
207
+ return this.findAllByIds(resourcesIds, contains);
211
208
  }
212
209
 
213
210
  /**