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
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Passbolt ~ Open source password manager for teams
3
+ * Copyright (c) Passbolt SA (https://www.passbolt.com)
4
+ *
5
+ * Licensed under GNU Affero General Public License version 3 of the or any later version.
6
+ * For full copyright and license information, please see the LICENSE.txt
7
+ * Redistributions of files must retain the above copyright notice.
8
+ *
9
+ * @copyright Copyright (c) Passbolt SA (https://www.passbolt.com)
10
+ * @license https://opensource.org/licenses/AGPL-3.0 AGPL License
11
+ * @link https://www.passbolt.com Passbolt(tm)
12
+ * @since 6.0.0
13
+ */
14
+ import { assertUuid } from "../../utils/assertions";
15
+ import GetOrFindResourceTypesService from "./getOrFindResourceTypesService";
16
+
17
+ /**
18
+ * The service aims to get users from the local storage if it is set, or retrieve them from the API and
19
+ * set the local storage.
20
+ */
21
+ class GetSecretSchemaResourceTypeService {
22
+ /**
23
+ * Constructor.
24
+ * @param {AccountEntity} account The user account.
25
+ * @param {ApiClientOptions} apiClientOptions The api client options.
26
+ */
27
+ constructor(account, apiClientOptions) {
28
+ this.getOrFindResourceTypesService = new GetOrFindResourceTypesService(account, apiClientOptions);
29
+ }
30
+
31
+ /**
32
+ * Get secret schema by resource type id.
33
+ * @returns {Promise<object>}
34
+ */
35
+ async getByResourceTypeId(resourceTypeId) {
36
+ assertUuid(resourceTypeId, "The resource type id should be a valid UUID");
37
+
38
+ const resourceTypes = await this.getOrFindResourceTypesService.getOrFindAll();
39
+ const type = resourceTypes.getFirst("id", resourceTypeId);
40
+ return type?.definition?.secret;
41
+ }
42
+ }
43
+
44
+ export default GetSecretSchemaResourceTypeService;
@@ -14,7 +14,7 @@
14
14
  import ResourceTypesCollection from "passbolt-styleguide/src/shared/models/entity/resourceType/resourceTypesCollection";
15
15
  import { assertType, assertUuid } from "../../utils/assertions";
16
16
  import ResourceTypeService from "../api/resourceType/resourceTypeService";
17
- import ResourceTypeModel from "../../model/resourceType/resourceTypeModel";
17
+ import ResourceTypeLocalStorage from "../local_storage/resourceTypeLocalStorage";
18
18
 
19
19
  /**
20
20
  * The service aims to get resources from the local storage if it is set, or retrieve them from the API and
@@ -23,11 +23,12 @@ import ResourceTypeModel from "../../model/resourceType/resourceTypeModel";
23
23
  export default class UpdateResourceTypesService {
24
24
  /**
25
25
  * @constructor
26
+ * @param {AccountEntity} account The account
26
27
  * @param {ApiClientOptions} apiClientOptions The api client options
27
28
  */
28
- constructor(apiClientOptions) {
29
+ constructor(account, apiClientOptions) {
29
30
  this.resourceTypeService = new ResourceTypeService(apiClientOptions);
30
- this.resourceTypeModel = new ResourceTypeModel(apiClientOptions);
31
+ this.resourceTypeLocalStorage = new ResourceTypeLocalStorage(account);
31
32
  }
32
33
 
33
34
  /**
@@ -103,6 +104,7 @@ export default class UpdateResourceTypesService {
103
104
  await this.deleteAll(new ResourceTypesCollection(resourceTypesToDelete, { validate: false }));
104
105
  await this.undeleteAll(new ResourceTypesCollection(resourceTypesToUndelete, { validate: false }));
105
106
 
106
- await this.resourceTypeModel.updateLocalStorage();
107
+ const resourceTypeDtos = await this.resourceTypeService.findAll();
108
+ await this.resourceTypeLocalStorage.setData(new ResourceTypesCollection(resourceTypeDtos));
107
109
  }
108
110
  }
@@ -17,23 +17,26 @@ import UpdateResourceTypesService from "./updateResourceTypesService";
17
17
  import { v4 as uuidV4 } from "uuid";
18
18
  import ResourceTypesCollection from "passbolt-styleguide/src/shared/models/entity/resourceType/resourceTypesCollection";
19
19
  import { resourceTypesCollectionDto } from "passbolt-styleguide/src/shared/models/entity/resourceType/resourceTypesCollection.test.data";
20
+ import AccountEntity from "../../model/entity/account/accountEntity";
21
+ import { defaultAccountDto } from "../../model/entity/account/accountEntity.test.data";
20
22
 
21
23
  beforeEach(() => {
22
24
  jest.clearAllMocks();
23
25
  });
24
26
 
25
27
  describe("UpdateResourceTypesService", () => {
26
- let apiClientOptions;
28
+ let account, apiClientOptions;
27
29
 
28
30
  beforeEach(async () => {
29
31
  apiClientOptions = defaultApiClientOptions();
32
+ account = new AccountEntity(defaultAccountDto());
30
33
  });
31
34
 
32
35
  describe("::delete", () => {
33
36
  it("should assert its parameters", async () => {
34
37
  expect.assertions(1);
35
38
 
36
- const service = new UpdateResourceTypesService(apiClientOptions);
39
+ const service = new UpdateResourceTypesService(account, apiClientOptions);
37
40
  expect(() => service.delete("test")).rejects.toThrow("The given parameter is not a valid UUID");
38
41
  });
39
42
 
@@ -41,7 +44,7 @@ describe("UpdateResourceTypesService", () => {
41
44
  expect.assertions(2);
42
45
 
43
46
  const expectedId = uuidV4();
44
- const service = new UpdateResourceTypesService(apiClientOptions);
47
+ const service = new UpdateResourceTypesService(account, apiClientOptions);
45
48
  jest.spyOn(service.resourceTypeService, "delete").mockImplementation(() => {});
46
49
 
47
50
  await service.delete(expectedId);
@@ -55,7 +58,7 @@ describe("UpdateResourceTypesService", () => {
55
58
  it("should assert its parameters", async () => {
56
59
  expect.assertions(1);
57
60
 
58
- const service = new UpdateResourceTypesService(apiClientOptions);
61
+ const service = new UpdateResourceTypesService(account, apiClientOptions);
59
62
  expect(() => service.undelete("test")).rejects.toThrow("The given parameter is not a valid UUID");
60
63
  });
61
64
 
@@ -63,7 +66,7 @@ describe("UpdateResourceTypesService", () => {
63
66
  expect.assertions(2);
64
67
 
65
68
  const expectedId = uuidV4();
66
- const service = new UpdateResourceTypesService(apiClientOptions);
69
+ const service = new UpdateResourceTypesService(account, apiClientOptions);
67
70
  jest.spyOn(service.resourceTypeService, "undelete").mockImplementation(() => {});
68
71
 
69
72
  await service.undelete(expectedId);
@@ -77,7 +80,7 @@ describe("UpdateResourceTypesService", () => {
77
80
  it("should assert its parameters", async () => {
78
81
  expect.assertions(1);
79
82
 
80
- const service = new UpdateResourceTypesService(apiClientOptions);
83
+ const service = new UpdateResourceTypesService(account, apiClientOptions);
81
84
  expect(() => service.deleteAll("test")).rejects.toThrow(
82
85
  "The resourceTypesCollection parameter should be a valid ResourceTypesCollection",
83
86
  );
@@ -89,7 +92,7 @@ describe("UpdateResourceTypesService", () => {
89
92
  expect.assertions(1 + resourceTypesDto.length);
90
93
 
91
94
  const resourcesTypesCollection = new ResourceTypesCollection(resourceTypesDto);
92
- const service = new UpdateResourceTypesService(apiClientOptions);
95
+ const service = new UpdateResourceTypesService(account, apiClientOptions);
93
96
 
94
97
  jest.spyOn(service.resourceTypeService, "delete").mockImplementation(() => {});
95
98
 
@@ -106,7 +109,7 @@ describe("UpdateResourceTypesService", () => {
106
109
  it("should assert its parameters", async () => {
107
110
  expect.assertions(1);
108
111
 
109
- const service = new UpdateResourceTypesService(apiClientOptions);
112
+ const service = new UpdateResourceTypesService(account, apiClientOptions);
110
113
  expect(() => service.undeleteAll("test")).rejects.toThrow(
111
114
  "The resourceTypesCollection parameter should be a valid ResourceTypesCollection",
112
115
  );
@@ -118,7 +121,7 @@ describe("UpdateResourceTypesService", () => {
118
121
  expect.assertions(1 + resourceTypesDto.length);
119
122
 
120
123
  const resourcesTypesCollection = new ResourceTypesCollection(resourceTypesDto);
121
- const service = new UpdateResourceTypesService(apiClientOptions);
124
+ const service = new UpdateResourceTypesService(account, apiClientOptions);
122
125
 
123
126
  jest.spyOn(service.resourceTypeService, "undelete").mockImplementation(() => {});
124
127
 
@@ -135,14 +138,14 @@ describe("UpdateResourceTypesService", () => {
135
138
  it("should assert its parameters", async () => {
136
139
  expect.assertions(1);
137
140
 
138
- const service = new UpdateResourceTypesService(apiClientOptions);
141
+ const service = new UpdateResourceTypesService(account, apiClientOptions);
139
142
  expect(() => service.updateAllDeletedStatus("test")).rejects.toThrow(
140
143
  "The resourceTypesCollection parameter should be a valid ResourceTypesCollection",
141
144
  );
142
145
  });
143
146
 
144
147
  it("should call for the right service with the right arguments.", async () => {
145
- expect.assertions(14);
148
+ expect.assertions(15);
146
149
  const resourceTypesDto = resourceTypesCollectionDto();
147
150
  for (let i = 0; i < resourceTypesDto.length; i += 2) {
148
151
  resourceTypesDto[i].deleted = "2025-02-24T09:00:00+00:00";
@@ -150,10 +153,11 @@ describe("UpdateResourceTypesService", () => {
150
153
 
151
154
  const resourcesTypesCollection = new ResourceTypesCollection(resourceTypesDto);
152
155
 
153
- const service = new UpdateResourceTypesService(apiClientOptions);
156
+ const service = new UpdateResourceTypesService(account, apiClientOptions);
154
157
  jest.spyOn(service.resourceTypeService, "delete").mockImplementation(() => {});
155
158
  jest.spyOn(service.resourceTypeService, "undelete").mockImplementation(() => {});
156
- jest.spyOn(service.resourceTypeModel, "updateLocalStorage").mockImplementation(() => {});
159
+ jest.spyOn(service.resourceTypeService, "findAll").mockImplementation(() => {});
160
+ jest.spyOn(service.resourceTypeLocalStorage, "setData").mockImplementation(() => {});
157
161
 
158
162
  await service.updateAllDeletedStatus(resourcesTypesCollection);
159
163
 
@@ -172,7 +176,8 @@ describe("UpdateResourceTypesService", () => {
172
176
  expect(service.resourceTypeService.undelete).toHaveBeenCalledWith(resourceTypesDto[9].id);
173
177
  expect(service.resourceTypeService.delete).toHaveBeenCalledWith(resourceTypesDto[10].id);
174
178
 
175
- expect(service.resourceTypeModel.updateLocalStorage).toHaveBeenCalledTimes(1);
179
+ expect(service.resourceTypeService.findAll).toHaveBeenCalledTimes(1);
180
+ expect(service.resourceTypeLocalStorage.setData).toHaveBeenCalledTimes(1);
176
181
  });
177
182
  });
178
183
  });
@@ -12,20 +12,21 @@
12
12
  * @since 5.7.0
13
13
  */
14
14
 
15
- import ResourceTypeModel from "../../model/resourceType/resourceTypeModel";
16
15
  import { assertString, assertUuid } from "../../utils/assertions";
17
16
  import GetDecryptedUserPrivateKeyService from "../account/getDecryptedUserPrivateKeyService";
18
17
  import DecryptSecretsService from "../crypto/decryptSecretsService";
19
18
  import FindSecretRevisionsService from "./findSecretRevisionsService";
19
+ import GetOrFindResourceTypesService from "../resourceType/getOrFindResourceTypesService";
20
20
 
21
21
  export default class FindAndDecryptSecretRevisionsService {
22
22
  /**
23
23
  * @constructor
24
+ * @param {AccountEntity} account
24
25
  * @param {ApiClientOptions} apiClientOptions
25
26
  */
26
- constructor(apiClientOptions) {
27
+ constructor(account, apiClientOptions) {
27
28
  this.findSecretRevisionsService = new FindSecretRevisionsService(apiClientOptions);
28
- this.resourceTypeModel = new ResourceTypeModel(apiClientOptions);
29
+ this.getOrFindResourceTypesService = new GetOrFindResourceTypesService(account, apiClientOptions);
29
30
  }
30
31
 
31
32
  /**
@@ -42,7 +43,7 @@ export default class FindAndDecryptSecretRevisionsService {
42
43
  assertString(passphrase);
43
44
 
44
45
  const decryptedKey = await GetDecryptedUserPrivateKeyService.getKey(passphrase);
45
- const resourceTypesCollection = await this.resourceTypeModel.getOrFindAll();
46
+ const resourceTypesCollection = await this.getOrFindResourceTypesService.getOrFindAll();
46
47
  const contains = {
47
48
  secret: true,
48
49
  creator: true,
@@ -25,6 +25,8 @@ import FindAndDecryptSecretRevisionsService from "./findAndDecryptSecretRevision
25
25
  import { v4 as uuidv4 } from "uuid";
26
26
  import DecryptMessageService from "../crypto/decryptMessageService";
27
27
  import { OpenpgpAssertion } from "../../utils/openpgp/openpgpAssertions";
28
+ import AccountEntity from "../../model/entity/account/accountEntity";
29
+ import { defaultAccountDto } from "../../model/entity/account/accountEntity.test.data";
28
30
 
29
31
  describe("FindAndDecryptSecretRevisionsService", () => {
30
32
  describe("::findAllByResourceIdAndDecryptForDisplay", () => {
@@ -32,6 +34,7 @@ describe("FindAndDecryptSecretRevisionsService", () => {
32
34
  expect.assertions(8);
33
35
 
34
36
  await MockExtension.withConfiguredAccount(pgpKeys.ada);
37
+ const account = new AccountEntity(defaultAccountDto());
35
38
 
36
39
  const encryptedSecretDto = minimalDto().data;
37
40
  const pgpMessage = await OpenpgpAssertion.readMessageOrFail(encryptedSecretDto);
@@ -57,8 +60,8 @@ describe("FindAndDecryptSecretRevisionsService", () => {
57
60
  const resourceSecretRevisions = new ResourceSecretRevisionsCollection(
58
61
  defaultResourceSecretRevisionsDtos({ resource_id }, { count: 4, withSecrets: true, withCreator: true }),
59
62
  );
60
- const service = new FindAndDecryptSecretRevisionsService(defaultApiClientOptions());
61
- jest.spyOn(service.resourceTypeModel, "getOrFindAll").mockReturnValue(resourceTypesCollection);
63
+ const service = new FindAndDecryptSecretRevisionsService(account, defaultApiClientOptions());
64
+ jest.spyOn(service.getOrFindResourceTypesService, "getOrFindAll").mockReturnValue(resourceTypesCollection);
62
65
  jest.spyOn(service.findSecretRevisionsService, "findAllByResourceId").mockReturnValue(resourceSecretRevisions);
63
66
  jest.spyOn(OpenpgpAssertion, "readMessageOrFail").mockReturnValue(pgpMessage);
64
67
 
@@ -83,14 +86,15 @@ describe("FindAndDecryptSecretRevisionsService", () => {
83
86
  expect.assertions(2);
84
87
 
85
88
  await MockExtension.withConfiguredAccount(pgpKeys.ada);
89
+ const account = new AccountEntity(defaultAccountDto());
86
90
 
87
91
  const resource_id = uuidv4();
88
92
  const encryptedSecretDto = minimalDto().data;
89
93
  const resourceSecretRevisions = new ResourceSecretRevisionsCollection([]);
90
94
 
91
- const service = new FindAndDecryptSecretRevisionsService(defaultApiClientOptions());
95
+ const service = new FindAndDecryptSecretRevisionsService(account, defaultApiClientOptions());
92
96
  jest
93
- .spyOn(service.resourceTypeModel, "getOrFindAll")
97
+ .spyOn(service.getOrFindResourceTypesService, "getOrFindAll")
94
98
  .mockReturnValue(new ResourceTypesCollection(resourceTypesCollectionDto()));
95
99
  jest.spyOn(service.findSecretRevisionsService, "findAllByResourceId").mockReturnValue(resourceSecretRevisions);
96
100
  jest.spyOn(DecryptMessageService, "decrypt").mockImplementation(() => encryptedSecretDto);
@@ -107,6 +111,7 @@ describe("FindAndDecryptSecretRevisionsService", () => {
107
111
  expect.assertions(2);
108
112
 
109
113
  await MockExtension.withConfiguredAccount(pgpKeys.ada);
114
+ const account = new AccountEntity(defaultAccountDto());
110
115
 
111
116
  const resource_id = uuidv4();
112
117
  const encryptedSecretDto = minimalDto().data;
@@ -114,9 +119,9 @@ describe("FindAndDecryptSecretRevisionsService", () => {
114
119
  defaultResourceSecretRevisionsDtos({ resource_id }, { count: 4, withSecrets: true, withCreator: true }),
115
120
  );
116
121
 
117
- const service = new FindAndDecryptSecretRevisionsService(defaultApiClientOptions());
122
+ const service = new FindAndDecryptSecretRevisionsService(account, defaultApiClientOptions());
118
123
  jest
119
- .spyOn(service.resourceTypeModel, "getOrFindAll")
124
+ .spyOn(service.getOrFindResourceTypesService, "getOrFindAll")
120
125
  .mockReturnValue(new ResourceTypesCollection(resourceTypesCollectionDto()));
121
126
  jest.spyOn(service.findSecretRevisionsService, "findAllByResourceId").mockReturnValue(resourceSecretRevisions);
122
127
  jest.spyOn(DecryptMessageService, "decrypt").mockImplementation(() => encryptedSecretDto);
@@ -133,6 +138,7 @@ describe("FindAndDecryptSecretRevisionsService", () => {
133
138
  expect.assertions(1);
134
139
 
135
140
  await MockExtension.withConfiguredAccount(pgpKeys.ada);
141
+ const account = new AccountEntity(defaultAccountDto());
136
142
  const passphrase = pgpKeys.admin.passphrase;
137
143
 
138
144
  const resource_id = uuidv4();
@@ -141,9 +147,9 @@ describe("FindAndDecryptSecretRevisionsService", () => {
141
147
  defaultResourceSecretRevisionsDtos({ resource_id }, { count: 4, withSecrets: true, withCreator: true }),
142
148
  );
143
149
 
144
- const service = new FindAndDecryptSecretRevisionsService(defaultApiClientOptions());
150
+ const service = new FindAndDecryptSecretRevisionsService(account, defaultApiClientOptions());
145
151
  jest
146
- .spyOn(service.resourceTypeModel, "getOrFindAll")
152
+ .spyOn(service.getOrFindResourceTypesService, "getOrFindAll")
147
153
  .mockReturnValue(new ResourceTypesCollection(resourceTypesCollectionDto()));
148
154
  jest.spyOn(service.findSecretRevisionsService, "findAllByResourceId").mockReturnValue(resourceSecretRevisions);
149
155
  jest.spyOn(DecryptMessageService, "decrypt").mockImplementation(() => encryptedSecretDto);
@@ -154,7 +160,8 @@ describe("FindAndDecryptSecretRevisionsService", () => {
154
160
  it("should assert its parameters", async () => {
155
161
  expect.assertions(4);
156
162
 
157
- const service = new FindAndDecryptSecretRevisionsService(defaultApiClientOptions());
163
+ const account = new AccountEntity(defaultAccountDto());
164
+ const service = new FindAndDecryptSecretRevisionsService(account, defaultApiClientOptions());
158
165
 
159
166
  await expect(() => service.findAllByResourceIdAndDecryptForDisplay(42, "passphrase")).rejects.toThrow();
160
167
  await expect(() => service.findAllByResourceIdAndDecryptForDisplay(null, "passphrase")).rejects.toThrow();
@@ -29,7 +29,6 @@ import {
29
29
  } from "../../utils/assertions";
30
30
  import DecryptPrivateKeyService from "../crypto/decryptPrivateKeyService";
31
31
  import PermissionChangesCollection from "../../model/entity/permission/change/permissionChangesCollection";
32
- import ResourceTypeModel from "../../model/resourceType/resourceTypeModel";
33
32
  import ResourceService from "../api/resource/resourceService";
34
33
  import ResourceLocalStorage from "../local_storage/resourceLocalStorage";
35
34
  import EncryptMetadataService from "../metadata/encryptMetadataService";
@@ -39,6 +38,7 @@ import { RESOURCE_TYPE_VERSION_5 } from "passbolt-styleguide/src/shared/models/e
39
38
  import ExecuteConcurrentlyService from "../execute/executeConcurrentlyService";
40
39
  import NeededSecretsCollection from "../../model/entity/secret/needed/neededSecretsCollection";
41
40
  import SecretsCollection from "passbolt-styleguide/src/shared/models/entity/secret/secretsCollection";
41
+ import GetOrFindResourceTypesService from "../resourceType/getOrFindResourceTypesService";
42
42
 
43
43
  export const PROGRESS_STEPS_SHARE_RESOURCES_SHARE_ALL = 8;
44
44
 
@@ -55,7 +55,7 @@ class ShareResourceService {
55
55
  this.shareApiService = new ShareApiService(apiClientOptions);
56
56
  this.findResourcesService = new FindResourcesService(account, apiClientOptions);
57
57
  this.findAndUpdateResourcesLocalStorage = new FindAndUpdateResourcesLocalStorage(account, apiClientOptions);
58
- this.resourceTypeModel = new ResourceTypeModel(apiClientOptions);
58
+ this.getOrFindResourceTypesService = new GetOrFindResourceTypesService(account, apiClientOptions);
59
59
  this.resourceService = new ResourceService(apiClientOptions);
60
60
  this.encryptMetadataService = new EncryptMetadataService(apiClientOptions, account);
61
61
  this.getOrFindResourcesService = new GetOrFindResourcesService(account, apiClientOptions);
@@ -107,7 +107,7 @@ class ShareResourceService {
107
107
  async updatePersonalMetadataToSharedMetadata(resourcesIds, permissionChanges, passphrase) {
108
108
  this.progressService.finishStep(i18n.t("Updating resources metadata"), true);
109
109
  const resourcesToUpdate = await this.getOrFindResourcesService.getOrFindByIds(resourcesIds);
110
- const resourceTypes = await this.resourceTypeModel.getOrFindAll();
110
+ const resourceTypes = await this.getOrFindResourceTypesService.getOrFindAll();
111
111
  const resourceIdMetadataToShare = permissionChanges.items
112
112
  .filter((permissionChange) => !permissionChange.isDeleted)
113
113
  .map((permissionChange) => permissionChange.acoForeignKey);
@@ -154,7 +154,7 @@ class ShareResourceService {
154
154
  * @private
155
155
  */
156
156
  async simulateShare(permissionChanges) {
157
- this.progressService.finishStep(i18n.t("Calculating secrets"), true);
157
+ await this.progressService.finishStep(i18n.t("Calculating secrets"), true);
158
158
  const concurrentlyExecutionService = new ExecuteConcurrentlyService();
159
159
  const neededSecretsDto = [];
160
160
  const resourceIds = [...new Set(permissionChanges.extract("aco_foreign_key"))];
@@ -54,12 +54,12 @@ import PermissionChangesCollection from "../../model/entity/permission/change/pe
54
54
  import MockPort from "passbolt-styleguide/src/react-extension/test/mock/MockPort";
55
55
  import ProgressService from "../progress/progressService";
56
56
  import { METADATA_KEY_TYPE_METADATA_KEY, METADATA_KEY_TYPE_USER_KEY } from "../../model/entity/resource/resourceEntity";
57
- import ResourceTypeModel from "../../model/resourceType/resourceTypeModel";
58
57
  import { defaultMetadataKeysSettingsDto } from "passbolt-styleguide/src/shared/models/entity/metadata/metadataKeysSettingsEntity.test.data";
59
58
  import { defaultMetadataPrivateKeyDto } from "passbolt-styleguide/src/shared/models/entity/metadata/metadataPrivateKeyEntity.test.data";
60
59
  import { defaultMetadataKeyDto } from "passbolt-styleguide/src/shared/models/entity/metadata/metadataKeyEntity.test.data";
61
60
  import MetadataKeysCollection from "passbolt-styleguide/src/shared/models/entity/metadata/metadataKeysCollection";
62
61
  import MetadataKeysSettingsEntity from "passbolt-styleguide/src/shared/models/entity/metadata/metadataKeysSettingsEntity";
62
+ import GetOrFindResourceTypesService from "../resourceType/getOrFindResourceTypesService";
63
63
 
64
64
  beforeEach(() => {
65
65
  MetadataKeysSessionStorage._runtimeCachedData = {};
@@ -165,7 +165,7 @@ describe("ShareResourceService", () => {
165
165
 
166
166
  // Mock request retrieving the resource types.
167
167
  jest
168
- .spyOn(service.resourceTypeModel, "getOrFindAll")
168
+ .spyOn(GetOrFindResourceTypesService.prototype, "getOrFindAll")
169
169
  .mockImplementation(() => new ResourceTypesCollection(resourceTypesCollectionDto()));
170
170
 
171
171
  // Mock the share request.
@@ -302,7 +302,7 @@ describe("ShareResourceService", () => {
302
302
 
303
303
  // Mock request retrieving the resource types.
304
304
  jest
305
- .spyOn(service.resourceTypeModel, "getOrFindAll")
305
+ .spyOn(GetOrFindResourceTypesService.prototype, "getOrFindAll")
306
306
  .mockImplementation(() => new ResourceTypesCollection(resourceTypesCollectionDto()));
307
307
 
308
308
  // Mock the share request.
@@ -410,7 +410,7 @@ describe("ShareResourceService", () => {
410
410
 
411
411
  // Mock service retrieving the resource types.
412
412
  jest
413
- .spyOn(ResourceTypeModel.prototype, "getOrFindAll")
413
+ .spyOn(GetOrFindResourceTypesService.prototype, "getOrFindAll")
414
414
  .mockImplementation(() => new ResourceTypesCollection(resourceTypesCollectionDto()));
415
415
 
416
416
  // Mock service retrieving metadata keys settings.
@@ -670,7 +670,7 @@ describe("ShareResourceService", () => {
670
670
 
671
671
  // Mock service retrieving the resource types.
672
672
  jest
673
- .spyOn(ResourceTypeModel.prototype, "getOrFindAll")
673
+ .spyOn(GetOrFindResourceTypesService.prototype, "getOrFindAll")
674
674
  .mockImplementation(() => new ResourceTypesCollection(resourceTypesCollectionDto()));
675
675
 
676
676
  // Mock service retrieving metadata keys settings.
@@ -750,7 +750,7 @@ describe("ShareResourceService", () => {
750
750
 
751
751
  // Mock request retrieving the resource types.
752
752
  jest
753
- .spyOn(service.resourceTypeModel, "getOrFindAll")
753
+ .spyOn(GetOrFindResourceTypesService.prototype, "getOrFindAll")
754
754
  .mockImplementation(() => new ResourceTypesCollection(resourceTypesCollectionDto()));
755
755
 
756
756
  // Mock the share request.
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Passbolt ~ Open source password manager for teams
3
+ * Copyright (c) Passbolt SA (https://www.passbolt.com)
4
+ *
5
+ * Licensed under GNU Affero General Public License version 3 of the or any later version.
6
+ * For full copyright and license information, please see the LICENSE.txt
7
+ * Redistributions of files must retain the above copyright notice.
8
+ *
9
+ * @copyright Copyright (c) Passbolt SA (https://www.passbolt.com)
10
+ * @license https://opensource.org/licenses/AGPL-3.0 AGPL License
11
+ * @link https://www.passbolt.com Passbolt(tm)
12
+ * @since 6.0.0
13
+ */
14
+ import SiteSettingsEntity from "passbolt-styleguide/src/shared/models/entity/siteSettings/siteSettingsEntity";
15
+ import SiteSettingsLocalStorage from "../local_storage/siteSettingsLocalStorage";
16
+ import FindSiteSettingsService from "./findSiteSettingsService";
17
+ import SiteSettingsRuntimeCache from "./siteSettingsRuntimeCache";
18
+ import CheckAuthStatusService from "../auth/checkAuthStatusService";
19
+
20
+ const FIND_AND_UPDATE_SITE_SETTINGS_LS_LOCK_PREFIX = "FIND_AND_UPDATE_SITE_SETTINGS_LS_LOCK-";
21
+
22
+ /**
23
+ * Fetches site settings from the API. Always updates the in-memory SiteSettingsRuntimeCache.
24
+ * For authenticated sessions, also writes to SiteSettingsLocalStorage (the offline-mode
25
+ * store). Unauthenticated sessions never touch SiteSettingsLocalStorage.
26
+ *
27
+ * Concurrent calls coalesce via navigator.locks — only the first hits the API, the rest
28
+ * wait and return what the leader wrote to SiteSettingsRuntimeCache.
29
+ */
30
+ export default class FindAndUpdateSiteSettingsLocalStorageService {
31
+ /**
32
+ * @param {AccountEntity} account
33
+ * @param {ApiClientOptions} apiClientOptions
34
+ */
35
+ constructor(account, apiClientOptions) {
36
+ this.account = account;
37
+ this.findSiteSettingsService = new FindSiteSettingsService(apiClientOptions);
38
+ this.siteSettingsLocalStorage = new SiteSettingsLocalStorage(account);
39
+ this.checkAuthStatusService = new CheckAuthStatusService(account, apiClientOptions);
40
+ }
41
+
42
+ /**
43
+ * @returns {Promise<SiteSettingsEntity|null>} the leader returns the freshly fetched
44
+ * entity; coalesced waiters return the entity from SiteSettingsRuntimeCache (or null
45
+ * if the leader failed before writing).
46
+ */
47
+ async findAndUpdateAll() {
48
+ const lockKey = `${FIND_AND_UPDATE_SITE_SETTINGS_LS_LOCK_PREFIX}${this.account.id}`;
49
+
50
+ return await navigator.locks.request(lockKey, { ifAvailable: true }, async (lock) => {
51
+ // Another caller is already refreshing: wait on a shared lock and return what they wrote.
52
+ if (!lock) {
53
+ return await navigator.locks.request(lockKey, { mode: "shared" }, async () => {
54
+ const dto = SiteSettingsRuntimeCache.get();
55
+ return dto ? new SiteSettingsEntity(dto) : null;
56
+ });
57
+ }
58
+
59
+ const siteSettings = await this.findSiteSettingsService.findSiteSettings();
60
+
61
+ // Authenticated sessions persist to SiteSettingsLocalStorage (the offline-mode store);
62
+ // Anonymous sessions only get the in-memory runtime cache below.
63
+ const activeSession = await this.checkAuthStatusService.checkAuthStatus();
64
+ if (activeSession.isAuthenticated) {
65
+ await this.siteSettingsLocalStorage.set(siteSettings);
66
+ }
67
+ /*
68
+ * PB-53134:
69
+ * Set a cache of site setting without account id as a key to get the cache in AppEmailValidatorService
70
+ * This is very sensitive as the AppEmailValidatorService valid the username of account entity.
71
+ */
72
+ SiteSettingsRuntimeCache.set(siteSettings);
73
+
74
+ return siteSettings;
75
+ });
76
+ }
77
+ }
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Passbolt ~ Open source password manager for teams
3
+ * Copyright (c) Passbolt SA (https://www.passbolt.com)
4
+ *
5
+ * Licensed under GNU Affero General Public License version 3 of the or any later version.
6
+ * For full copyright and license information, please see the LICENSE.txt
7
+ * Redistributions of files must retain the above copyright notice.
8
+ *
9
+ * @copyright Copyright (c) Passbolt SA (https://www.passbolt.com)
10
+ * @license https://opensource.org/licenses/AGPL-3.0 AGPL License
11
+ * @link https://www.passbolt.com Passbolt(tm)
12
+ * @since 6.0.0
13
+ */
14
+ import SiteSettingsEntity from "passbolt-styleguide/src/shared/models/entity/siteSettings/siteSettingsEntity";
15
+ import { defaultApiClientOptions } from "passbolt-styleguide/src/shared/lib/apiClient/apiClientOptions.test.data";
16
+ import AccountEntity from "../../model/entity/account/accountEntity";
17
+ import { defaultAccountDto } from "../../model/entity/account/accountEntity.test.data";
18
+ import { defaultProSiteSettings } from "passbolt-styleguide/src/shared/models/entity/siteSettings/siteSettingsEntity.test.data";
19
+ import SiteSettingsLocalStorage from "../local_storage/siteSettingsLocalStorage";
20
+ import SiteSettingsRuntimeCache from "./siteSettingsRuntimeCache";
21
+ import FindAndUpdateSiteSettingsLocalStorageService from "./findAndUpdateSiteSettingsLocalStorageService";
22
+ import OnlineSessionEntity from "passbolt-styleguide/src/shared/models/entity/session/onlineSessionEntity";
23
+
24
+ const readBrowserStorage = async (storageKey) => {
25
+ const data = await browser.storage.local.get([storageKey]);
26
+ return data[storageKey];
27
+ };
28
+
29
+ beforeEach(() => {
30
+ jest.clearAllMocks();
31
+ SiteSettingsRuntimeCache.flushAll();
32
+ SiteSettingsLocalStorage._runtimeCachedData = {};
33
+ });
34
+
35
+ describe("FindAndUpdateSiteSettingsLocalStorageService", () => {
36
+ let account, apiClientOptions, service;
37
+
38
+ beforeEach(async () => {
39
+ account = new AccountEntity(defaultAccountDto());
40
+ apiClientOptions = defaultApiClientOptions();
41
+ service = new FindAndUpdateSiteSettingsLocalStorageService(account, apiClientOptions);
42
+ await service.siteSettingsLocalStorage.flush();
43
+ });
44
+
45
+ describe("::findAndUpdateAll — runtime cache", () => {
46
+ it("always updates SiteSettingsRuntimeCache regardless of auth status", async () => {
47
+ expect.assertions(2);
48
+ const dto = defaultProSiteSettings();
49
+ jest
50
+ .spyOn(service.checkAuthStatusService, "checkAuthStatus")
51
+ .mockResolvedValue(new OnlineSessionEntity({ is_authenticated: false }));
52
+ jest.spyOn(service.findSiteSettingsService, "findSiteSettings").mockResolvedValue(new SiteSettingsEntity(dto));
53
+
54
+ const result = await service.findAndUpdateAll();
55
+
56
+ expect(result.toDto()).toEqual(dto);
57
+ expect(SiteSettingsRuntimeCache.get(account.id)).toEqual(dto);
58
+ });
59
+ });
60
+
61
+ describe("::findAndUpdateAll — local storage gate", () => {
62
+ it("writes SiteSettingsLocalStorage when authenticated", async () => {
63
+ expect.assertions(2);
64
+ const dto = defaultProSiteSettings();
65
+ jest
66
+ .spyOn(service.checkAuthStatusService, "checkAuthStatus")
67
+ .mockResolvedValue(new OnlineSessionEntity({ is_authenticated: true }));
68
+ jest.spyOn(service.findSiteSettingsService, "findSiteSettings").mockResolvedValue(new SiteSettingsEntity(dto));
69
+
70
+ await service.findAndUpdateAll();
71
+
72
+ expect(await readBrowserStorage(service.siteSettingsLocalStorage.storageKey)).toEqual(dto);
73
+ expect(SiteSettingsLocalStorage._runtimeCachedData[account.id]).toEqual(dto);
74
+ });
75
+
76
+ it("does not touch SiteSettingsLocalStorage when not authenticated", async () => {
77
+ expect.assertions(2);
78
+ const dto = defaultProSiteSettings();
79
+ jest
80
+ .spyOn(service.checkAuthStatusService, "checkAuthStatus")
81
+ .mockResolvedValue(new OnlineSessionEntity({ is_authenticated: false }));
82
+
83
+ jest.spyOn(service.findSiteSettingsService, "findSiteSettings").mockResolvedValue(new SiteSettingsEntity(dto));
84
+
85
+ await service.findAndUpdateAll();
86
+
87
+ expect(await readBrowserStorage(service.siteSettingsLocalStorage.storageKey)).toBeUndefined();
88
+ expect(SiteSettingsLocalStorage._runtimeCachedData[account.id]).toBeUndefined();
89
+ });
90
+ });
91
+
92
+ describe("::findAndUpdateAll — concurrency", () => {
93
+ it("coalesces concurrent calls into one API hit per account", async () => {
94
+ expect.assertions(4);
95
+ const dto = defaultProSiteSettings();
96
+ jest
97
+ .spyOn(service.checkAuthStatusService, "checkAuthStatus")
98
+ .mockResolvedValue(new OnlineSessionEntity({ is_authenticated: true }));
99
+
100
+ const apiSpy = jest
101
+ .spyOn(service.findSiteSettingsService, "findSiteSettings")
102
+ .mockResolvedValue(new SiteSettingsEntity(dto));
103
+
104
+ const results = await Promise.all([
105
+ service.findAndUpdateAll(),
106
+ service.findAndUpdateAll(),
107
+ service.findAndUpdateAll(),
108
+ ]);
109
+
110
+ expect(apiSpy).toHaveBeenCalledTimes(1);
111
+ results.forEach((r) => expect(r?.toDto()).toEqual(dto));
112
+ });
113
+ });
114
+
115
+ describe("::findAndUpdateAll — error propagation", () => {
116
+ it("propagates API errors and leaves both caches untouched", async () => {
117
+ expect.assertions(4);
118
+ jest
119
+ .spyOn(service.checkAuthStatusService, "checkAuthStatus")
120
+ .mockResolvedValue(new OnlineSessionEntity({ is_authenticated: true }));
121
+
122
+ jest.spyOn(service.findSiteSettingsService, "findSiteSettings").mockRejectedValue(new Error("API down"));
123
+
124
+ await expect(service.findAndUpdateAll()).rejects.toThrow("API down");
125
+ expect(await readBrowserStorage(service.siteSettingsLocalStorage.storageKey)).toBeUndefined();
126
+ expect(SiteSettingsLocalStorage._runtimeCachedData[account.id]).toBeUndefined();
127
+ expect(SiteSettingsRuntimeCache.get(account.id)).toBeNull();
128
+ });
129
+ });
130
+ });