passbolt-browser-extension 5.3.2 → 5.4.1

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 (173) hide show
  1. package/CHANGELOG.md +58 -1
  2. package/README.md +2 -2
  3. package/RELEASE_NOTES.md +8 -30
  4. package/crowdin.yml +1 -0
  5. package/package.json +4 -3
  6. package/src/all/_locales/cs/messages.json +10 -0
  7. package/src/all/background_page/controller/InformMenuController/InformMenuController.js +3 -3
  8. package/src/all/background_page/controller/auth/redirectPostLoginController.js +57 -0
  9. package/src/all/background_page/controller/auth/redirectPostLoginController.test.js +82 -0
  10. package/src/all/background_page/controller/auth/redirectToAdminWorkspaceController.js +50 -0
  11. package/src/all/background_page/controller/auth/redirectToAdminWorkspaceController.test.js +45 -0
  12. package/src/all/background_page/controller/comment/createCommentController.js +3 -3
  13. package/src/all/background_page/controller/comment/createCommentController.test.js +5 -5
  14. package/src/all/background_page/controller/comment/deleteCommentController.js +3 -3
  15. package/src/all/background_page/controller/comment/deleteCommentController.test.js +3 -3
  16. package/src/all/background_page/controller/comment/getCommentsByRessourceIdController.js +3 -3
  17. package/src/all/background_page/controller/comment/getCommentsByRessourceidController.test.js +2 -2
  18. package/src/all/background_page/controller/import/importResourcesFileController.test.js +23 -23
  19. package/src/all/background_page/controller/metadata/enableEncryptedMetadataForExistingInstanceController.js +54 -0
  20. package/src/all/background_page/controller/metadata/enableEncryptedMetadataForExistingInstanceController.test.js +54 -0
  21. package/src/all/background_page/controller/metadata/enableMetadataSetupSettingsController.js +54 -0
  22. package/src/all/background_page/controller/metadata/enableMetadataSetupSettingsController.test.js +64 -0
  23. package/src/all/background_page/controller/metadata/findAllNonDeletedMetadataKeysController.js +2 -3
  24. package/src/all/background_page/controller/metadata/findMetadataGettingStartedSettingsController.js +50 -0
  25. package/src/all/background_page/controller/metadata/findMetadataGettingStartedSettingsController.test.js +33 -0
  26. package/src/all/background_page/controller/metadata/findMetadataSetupSettingsController.js +50 -0
  27. package/src/all/background_page/controller/metadata/findMetadataSetupSettingsController.test.js +42 -0
  28. package/src/all/background_page/controller/metadata/keepCleartextMetadataForExistingInstanceController.js +51 -0
  29. package/src/all/background_page/controller/metadata/keepCleartextMetadataForExistingInstanceController.test.js +47 -0
  30. package/src/all/background_page/controller/permission/FindAcoPermissionsForDisplayController.js +1 -0
  31. package/src/all/background_page/controller/quickaccess/consumeInProgressCreationResourceController.js +53 -0
  32. package/src/all/background_page/controller/quickaccess/consumeInProgressCreationResourceController.test.js +40 -0
  33. package/src/all/background_page/controller/quickaccess/prepareResourceController.js +64 -0
  34. package/src/all/background_page/controller/quickaccess/prepareResourceController.test.js +73 -0
  35. package/src/all/background_page/controller/resource/resourceDeleteController.js +67 -0
  36. package/src/all/background_page/controller/resource/resourceDeleteController.test.js +114 -0
  37. package/src/all/background_page/controller/resourceLocalStorage/resourceUpdateLocalStorageController.js +1 -1
  38. package/src/all/background_page/controller/resourceLocalStorage/resourceUpdateLocalStorageController.test.js +5 -1
  39. package/src/all/background_page/controller/setup/signInSetupController.js +0 -10
  40. package/src/all/background_page/controller/setup/signInSetupController.test.js +11 -12
  41. package/src/all/background_page/controller/sso/saveSsoSettingsAsDraftController.test.data.js +1 -0
  42. package/src/all/background_page/controller/webIntegration/webIntegrationController.js +1 -1
  43. package/src/all/background_page/event/appEvents.js +47 -0
  44. package/src/all/background_page/event/authEvents.js +4 -8
  45. package/src/all/background_page/event/informMenuEvents.js +31 -0
  46. package/src/all/background_page/event/quickAccessEvents.js +18 -23
  47. package/src/all/background_page/event/recoverEvents.js +12 -0
  48. package/src/all/background_page/event/resourceEvents.js +4 -11
  49. package/src/all/background_page/event/setupEvents.js +55 -0
  50. package/src/all/background_page/model/comment/{commentModel.js → commentService.js} +6 -2
  51. package/src/all/background_page/model/comment/commentService.test.js +98 -0
  52. package/src/all/background_page/model/entity/actionLog/actionLogsCollection.js +3 -3
  53. package/src/all/background_page/model/entity/actionLog/permissionsUpdatedActionLogEntity.js +4 -0
  54. package/src/all/background_page/model/entity/import/importResourcesFileEntity.test.data.js +3 -3
  55. package/src/all/background_page/model/entity/organizationSettings/organizationSettingsEntity.test.data.js +4 -0
  56. package/src/all/background_page/model/entity/permission/actionLog/updatedPermissionEntity.test.data.js +23 -0
  57. package/src/all/background_page/model/entity/permission/actionLog/updatedPermissionEntity.test.js +18 -33
  58. package/src/all/background_page/model/entity/permission/actionLog/updatedPermissionsCollection.js +71 -2
  59. package/src/all/background_page/model/entity/permission/actionLog/updatedPermissionsCollection.test.js +204 -0
  60. package/src/all/background_page/model/entity/permission/permissionsCollection.js +78 -0
  61. package/src/all/background_page/model/entity/permission/permissionsCollection.test.js +139 -7
  62. package/src/all/background_page/model/entity/plaintext/plaintextEntity.js +9 -0
  63. package/src/all/background_page/model/entity/resource/external/externalResourceEntity.js +65 -8
  64. package/src/all/background_page/model/entity/resource/external/externalResourceEntity.test.data.js +5 -4
  65. package/src/all/background_page/model/entity/resource/external/externalResourceEntity.test.js +72 -16
  66. package/src/all/background_page/model/entity/resource/external/externalResourcesCollection.test.js +2 -1
  67. package/src/all/background_page/model/entity/totp/externalTotpEntity.js +2 -2
  68. package/src/all/background_page/model/entity/totp/totpEntity.test.js +1 -1
  69. package/src/all/background_page/model/export/resources/csvRowComposer/csv1PasswordRowComposer.test.js +2 -2
  70. package/src/all/background_page/model/export/resources/csvRowComposer/csv1passwordRowComposer.js +5 -1
  71. package/src/all/background_page/model/export/resources/csvRowComposer/csvBitWardenRowComposer.js +9 -1
  72. package/src/all/background_page/model/export/resources/csvRowComposer/csvBitWardenRowComposer.test.js +6 -4
  73. package/src/all/background_page/model/export/resources/csvRowComposer/csvChromiumRowComposer.js +5 -1
  74. package/src/all/background_page/model/export/resources/csvRowComposer/csvChromiumRowComposer.test.js +3 -2
  75. package/src/all/background_page/model/export/resources/csvRowComposer/csvDashlaneRowComposer.js +5 -1
  76. package/src/all/background_page/model/export/resources/csvRowComposer/csvDashlaneRowComposer.test.js +2 -3
  77. package/src/all/background_page/model/export/resources/csvRowComposer/csvKdbxRowComposer.js +3 -1
  78. package/src/all/background_page/model/export/resources/csvRowComposer/csvKdbxRowComposer.test.js +6 -4
  79. package/src/all/background_page/model/export/resources/csvRowComposer/csvLastPassRowComposer.js +5 -1
  80. package/src/all/background_page/model/export/resources/csvRowComposer/csvLastPassRowComposer.test.js +2 -3
  81. package/src/all/background_page/model/export/resources/csvRowComposer/csvLogMeOnceRowComposer.js +5 -1
  82. package/src/all/background_page/model/export/resources/csvRowComposer/csvLogMeOnceRowComposer.test.js +2 -3
  83. package/src/all/background_page/model/export/resources/csvRowComposer/csvMozillaPlatformRowComposer.js +6 -2
  84. package/src/all/background_page/model/export/resources/csvRowComposer/csvMozillaPlatformRowComposer.test.js +2 -2
  85. package/src/all/background_page/model/export/resources/csvRowComposer/csvNordpassRowComposer.js +5 -1
  86. package/src/all/background_page/model/export/resources/csvRowComposer/csvNordpassRowComposer.test.js +2 -2
  87. package/src/all/background_page/model/export/resources/csvRowComposer/csvSafariRowComposer.js +5 -1
  88. package/src/all/background_page/model/export/resources/csvRowComposer/csvSafariRowComposer.test.js +2 -2
  89. package/src/all/background_page/model/export/resources/resourcesKdbxExporter.js +44 -2
  90. package/src/all/background_page/model/export/resources/resourcesKdbxExporter.test.js +24 -3
  91. package/src/all/background_page/model/import/resources/csvRowParser/abstractCsvRowParser.js +1 -1
  92. package/src/all/background_page/model/import/resources/csvRowParser/csv1PasswordRowParser.js +5 -3
  93. package/src/all/background_page/model/import/resources/csvRowParser/csv1PasswordRowParser.test.js +3 -2
  94. package/src/all/background_page/model/import/resources/csvRowParser/csvBitWardenRowParser.js +22 -3
  95. package/src/all/background_page/model/import/resources/csvRowParser/csvBitWardenRowParser.test.js +92 -4
  96. package/src/all/background_page/model/import/resources/csvRowParser/csvChromiumRowParser.js +4 -2
  97. package/src/all/background_page/model/import/resources/csvRowParser/csvChromiumRowParser.test.js +2 -2
  98. package/src/all/background_page/model/import/resources/csvRowParser/csvDashlaneRowParser.js +4 -2
  99. package/src/all/background_page/model/import/resources/csvRowParser/csvDashlaneRowParser.test.js +3 -2
  100. package/src/all/background_page/model/import/resources/csvRowParser/csvKdbxRowParser.js +5 -3
  101. package/src/all/background_page/model/import/resources/csvRowParser/csvKdbxRowParser.test.js +4 -4
  102. package/src/all/background_page/model/import/resources/csvRowParser/csvLastPassRowParser.js +4 -2
  103. package/src/all/background_page/model/import/resources/csvRowParser/csvLastPassRowParser.test.js +2 -2
  104. package/src/all/background_page/model/import/resources/csvRowParser/csvLogMeOnceRowParser.js +5 -2
  105. package/src/all/background_page/model/import/resources/csvRowParser/csvLogMeOnceRowParser.test.js +2 -2
  106. package/src/all/background_page/model/import/resources/csvRowParser/csvMozillaPlatformRowParser.js +5 -3
  107. package/src/all/background_page/model/import/resources/csvRowParser/csvMozillaPlatformRowParser.test.js +2 -2
  108. package/src/all/background_page/model/import/resources/csvRowParser/csvNordpassRowParser.js +4 -2
  109. package/src/all/background_page/model/import/resources/csvRowParser/csvNordpassRowParser.test.js +2 -2
  110. package/src/all/background_page/model/import/resources/csvRowParser/csvSafariRowParser.js +4 -2
  111. package/src/all/background_page/model/import/resources/csvRowParser/csvSafariRowParser.test.js +2 -2
  112. package/src/all/background_page/model/import/resources/kdbx/kdbx-custom-fields-with-uris.kdbx +0 -0
  113. package/src/all/background_page/model/import/resources/kdbx/kdbx-multiple-uris-with-33-entries.kdbx +0 -0
  114. package/src/all/background_page/model/import/resources/kdbx/kdbx-multiple-uris.kdbx +0 -0
  115. package/src/all/background_page/model/import/resources/kdbx/kdbx-with-protected-custom-fields.kdbx +0 -0
  116. package/src/all/background_page/model/import/resources/resourcesCsvImportParser.test.js +1 -1
  117. package/src/all/background_page/model/import/resources/resourcesKdbxImportParser.js +124 -41
  118. package/src/all/background_page/model/import/resources/resourcesKdbxImportParser.test.js +133 -1
  119. package/src/all/background_page/model/import/resourcesImportParser.test.js +0 -1
  120. package/src/all/background_page/model/resource/resourceModel.js +0 -68
  121. package/src/all/background_page/service/api/comment/commentApiService.test.js +1 -1
  122. package/src/all/background_page/service/api/metadata/metadataSetupSettingsApiService.js +40 -0
  123. package/src/all/background_page/service/api/metadata/metadataSetupSettingsApiService.test.js +54 -0
  124. package/src/all/background_page/service/api/setup/setupService.js +2 -2
  125. package/src/all/background_page/service/api/setup/setupService.test.js +132 -0
  126. package/src/all/background_page/service/local_storage/resourceLocalStorage.js +25 -1
  127. package/src/all/background_page/service/local_storage/resourceLocalStorage.test.js +54 -0
  128. package/src/all/background_page/service/metadata/configureMetadataSettingsService.js +100 -0
  129. package/src/all/background_page/service/metadata/configureMetadataSettingsService.test.js +265 -0
  130. package/src/all/background_page/service/metadata/createMetadataKeyService.js +1 -1
  131. package/src/all/background_page/service/metadata/decryptMetadataPrivateKeysService.js +3 -19
  132. package/src/all/background_page/service/metadata/decryptMetadataService.js +5 -3
  133. package/src/all/background_page/service/metadata/decryptMetadataService.test.js +31 -24
  134. package/src/all/background_page/service/metadata/encryptMetadataService.js +2 -18
  135. package/src/all/background_page/service/metadata/findAndUpdateMetadataKeysSessionStorageService.js +5 -2
  136. package/src/all/background_page/service/metadata/findAndUpdateMetadataKeysSessionStorageService.test.js +4 -6
  137. package/src/all/background_page/service/metadata/findMetadataKeysService.js +8 -12
  138. package/src/all/background_page/service/metadata/findMetadataKeysService.test.js +21 -47
  139. package/src/all/background_page/service/metadata/findMetadataSetupSettingsService.js +45 -0
  140. package/src/all/background_page/service/metadata/findMetadataSetupSettingsService.test.js +68 -0
  141. package/src/all/background_page/service/metadata/generateMetadataKeyService.js +1 -1
  142. package/src/all/background_page/service/metadata/verifyOrTrustMetadataKeyService.test.js +16 -0
  143. package/src/all/background_page/service/passphrase/getPassphraseService.js +13 -0
  144. package/src/all/background_page/service/permission/findPermissionsService.js +3 -1
  145. package/src/all/background_page/service/resource/delete/deleteResourceService.js +60 -0
  146. package/src/all/background_page/service/resource/delete/deleteResourceService.test.js +75 -0
  147. package/src/all/background_page/service/resource/export/exportResourcesService.js +22 -0
  148. package/src/all/background_page/service/resource/export/exportResourcesService.test.js +48 -1
  149. package/src/all/background_page/service/resource/import/ImportResourcesService.js +34 -3
  150. package/src/all/background_page/service/resource/import/ImportResourcesService.test.js +55 -13
  151. package/src/all/background_page/service/sessionKey/decryptSessionKeysBundlesService.js +2 -18
  152. package/src/all/background_page/service/sessionKey/encryptSessionKeysBundlesService.js +1 -17
  153. package/src/all/locales/cs-CZ/common.json +130 -0
  154. package/src/all/locales/de-DE/common.json +11 -5
  155. package/src/all/locales/en-UK/common.json +6 -0
  156. package/src/all/locales/es-ES/common.json +6 -0
  157. package/src/all/locales/fr-FR/common.json +6 -0
  158. package/src/all/locales/it-IT/common.json +6 -0
  159. package/src/all/locales/ja-JP/common.json +6 -0
  160. package/src/all/locales/ko-KR/common.json +6 -0
  161. package/src/all/locales/lt-LT/common.json +6 -0
  162. package/src/all/locales/nl-NL/common.json +6 -0
  163. package/src/all/locales/pl-PL/common.json +6 -0
  164. package/src/all/locales/pt-BR/common.json +6 -0
  165. package/src/all/locales/ro-RO/common.json +6 -0
  166. package/src/all/locales/ru-RU/common.json +6 -0
  167. package/src/all/locales/sl-SI/common.json +6 -0
  168. package/src/all/locales/sv-SE/common.json +6 -0
  169. package/src/all/locales/uk-UA/common.json +6 -0
  170. package/src/chrome/manifest.json +1 -1
  171. package/src/chrome-mv3/manifest.json +1 -1
  172. package/src/firefox/manifest.json +1 -1
  173. package/src/safari/manifest.json +1 -1
package/CHANGELOG.md CHANGED
@@ -4,6 +4,61 @@ This project adheres to [Semantic Versioning](http://semver.org/).
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [5.4.1] - 2025-08-14
8
+ - PB-44638 Password expiry should not be removed when password is not updated
9
+ - PB-44668 The create menu import operation should be actionable when encrypted metadata plugin is not available
10
+
11
+ ## [5.4.0] - 2025-08-13
12
+ ### Added
13
+ - PB-44201: E2EE The organisation settings offer now a simplified way to activate metadata encryption and the new resource types
14
+ - PB-42205: E2EE encrypted metadata and new resource types are activated by default after the first administrator setup
15
+ - PB-43255: Add support for multiple uri import export on kdbx files
16
+ - PB-43110: ZK - WP4.2 As a signed-in user I should not be allowed to upgrade resources with missing key situation
17
+ - PB-43712: Translate the application in Czech
18
+ - PB-43939: ZK - WP3.2 Add an app event to get or find the metadata keys settings
19
+ - PB-43980: Add support for custom field import export on kdbx files
20
+ - PB-44080: ZK - WP4.1 Create a dialog explaining the missing key situation
21
+ - PB-44081: ZK - WP4.3 As a signed-in user I should not be allowed to create resources with missing key situation in the resource workspace
22
+ - PB-44090: ZK - WP4.4 As a signed-in user I should not be allowed to edit resources with missing key situation
23
+ - PB-44091: ZK - WP4.5 As a signed-in user I should not be allowed to share resources with missing key situation
24
+ - PB-44094: ZK - WP4.6 As a signed-in user I should not be allowed to import resources with missing key situation
25
+ - PB-44095: ZK - WP4.7 As a signed-in user I should not be allowed to move resources with missing key situation
26
+ - PB-44096: ZK - WP4.8 As a signed-in user I should not be allowed to move folders with missing key situation
27
+ - PB-44097: ZK - WP4.9 Display a page explaining the missing key situation on the quick app
28
+ - PB-44098: ZK - WP4.10 As a signed-in user I should not be allowed to create resources with missing key situation in the quick app
29
+ - PB-44099: ZK - WP4.11 As a signed-in user I should not be allowed to generate password on the inform menu
30
+ - PB-44206: ZK - WP4.14 As administrators I cannot trigger the encrypted metadata migration if I have missing metadata keys
31
+ - PB-44211: ZK - WP3.5 Add MetadataKeysSettingsLocalStorageContextProvider to the App and the quick-app and the inform menu
32
+ - PB-44212: CU - WP5.2 Update ExternalResourceEntity buildDtoFromResourceEntityDto to support custom fields
33
+ - PB-44286: ZK - WP3.6 Add a quick app and inform menu event to get the metadata keys settings
34
+ - PB-44295: ZK - WP4.15 As a signed-in user with missing keys I should not be able to create resource if metadata shared key is enforced on the inform menu
35
+ - PB-44296: ZK - WP4.16 As a signed-in user I should not be allowed to move shared folders into personal folders with missing key situation
36
+ - PB-44327: Display sub-folders in breadcrumbs
37
+ - PB-44374: Extend notes v5 max length to 50_000
38
+
39
+ ### Fixed
40
+ - PB-43296: Displaying resource activities should not crash the application when a resource activity does not have related user or group
41
+ - PB-43652: The sentence to change the passphrase in the user settings workspace should have a space after.
42
+ - PB-43657: Resources loading became noticeably slower after migrating to encrypted
43
+ - PB-43667: Cancelling the user passphrase request should not trigger an error when sharing missing metadata key
44
+ - PB-43676: Cancelling the user passphrase should not freeze the create resource dialog
45
+ - PB-43719: After importing resources from Bitwarden the URIs are not separated correctly
46
+ - PB-43784: Display the progression of the encryption of metadata in the import dialog
47
+ - PB-43906: User should be notified of any errors while loading comments
48
+ - PB-44079: Update/Create a method in resourceLocalStorage.js to bulk delete resources
49
+ - PB-44161: As a user I should not see the resource description and note warning message if only one of them is concerned
50
+ - PB-44273: Activities are not loaded when new resource is clicked after load more activities of a previous resource
51
+
52
+ ### Maintenance
53
+ - PB-43585: Azure SSO login_hint settings can now be configured
54
+ - PB-43908: Move logic of commentModel file to a service and update assertions in controllers
55
+ - PB-44076: Create a Controller to handle Resource Delete
56
+ - PB-44077: Create a dedicated Service to handle resource deletion
57
+ - PB-44396: the endpoint complete/recover.json is now used instead of the legacy endpoint
58
+
59
+ ### Security
60
+ - PB-43730: Upgrade vulnerable library brace-expansion
61
+
7
62
  ## [5.3.2] - 2025-07-17
8
63
  ### Added
9
64
  - PB-25265 Flush clipboard strategy
@@ -2305,7 +2360,9 @@ self registration settings option in the left-side bar
2305
2360
  - AP: User with plugin installed
2306
2361
  - LU: Logged in user
2307
2362
 
2308
- [Unreleased]: https://github.com/passbolt/passbolt_browser_extension/compare/v5.3.2...HEAD
2363
+ [Unreleased]: https://github.com/passbolt/passbolt_browser_extension/compare/v5.4.1...HEAD
2364
+ [5.4.0]: https://github.com/passbolt/passbolt_browser_extension/compare/v5.4.0...v5.4.1
2365
+ [5.4.0]: https://github.com/passbolt/passbolt_browser_extension/compare/v5.3.3...v5.4.0
2309
2366
  [5.3.2]: https://github.com/passbolt/passbolt_browser_extension/compare/v5.3.0...v5.3.2
2310
2367
  [5.3.0]: https://github.com/passbolt/passbolt_browser_extension/compare/v5.2.0...v5.3.0
2311
2368
  [5.2.0]: https://github.com/passbolt/passbolt_browser_extension/compare/v5.1.1...v5.2.0
package/README.md CHANGED
@@ -5,14 +5,14 @@
5
5
  /_/ \__,_/____/____/_.___/\____/_/\__/
6
6
 
7
7
  Open source password manager for teams
8
- (c) 2021 Passbolt SA
8
+ (c) 2025 Passbolt SA
9
9
  https://www.passbolt.com
10
10
 
11
11
  ## License
12
12
 
13
13
  Passbolt - Open source password manager for teams
14
14
 
15
- (c) 2022 Passbolt SA
15
+ (c) 2025 Passbolt SA
16
16
 
17
17
  This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General
18
18
  Public License (AGPL) as published by the Free Software Foundation version 3.
package/RELEASE_NOTES.md CHANGED
@@ -1,37 +1,15 @@
1
- Release song: https://www.youtube.com/watch?v=-GxmblM_jss
1
+ Release song: https://www.youtube.com/watch?v=6tpGC4lgpMg
2
2
 
3
- Passbolt v5.3.2 is a security release designed to strengthen the security posture of your organization. It introduces a clipboard flushing feature, adds safeguards around SSO settings, and addresses issues related to encrypted metadata.
3
+ This hot-fix addresses several issues introduced in recent v5.x releases.
4
4
 
5
- The new clipboard flush timer lets you copy secrets just long enough to use them; clipboard data is automatically cleared when the countdown (30s) expires, significantly reducing the risk of accidental exposure or leaks from forgotten clipboard content.
5
+ Since v5.3, organizations running Passbolt on servers with a locale different from en-UK could encounter issues to update or later to use the application, which have now been resolved.
6
6
 
7
- Additionally, SSO admin-settings edit endpoints of self-hosted instances can now be locked, reducing potential exposure to scans if an administrator account is compromised. You can verify if this protection is active, and get instructions on how to set it up, by running the health check via the server command line.
7
+ It also fixes a problem where organizations that had manually disabled encrypted metadata using the kill switch available to system administrators were unable to initiate imports credentials from the web application. This was a side effect of recent work preparing for the upcoming zero-knowledge capability, which will further strengthen the encrypted metadata feature introduced earlier.
8
8
 
9
- This update also resolves several encrypted metadata issues, moving the feature closer to general availability. Organizations can now enable encrypted metadata even if users have imported their own more complex keys (e.g. keys that were set to expire at some point), streamlining adoption for advanced users. Admin changes are smoother too: if the original metadata-enabling administrator leaves, newly invited users will still receive the metadata key automatically, removing the need for manual distribution. Lastly, users who owned shared resources using the new encrypted metadata format can now be deleted without issue, as ownership transfer is now handled correctly during the deletion process.
9
+ Finally, since v5.0, resources whose secrets had been modified, irrespective of whether the secret was a password, a TOTP, or a secure note, have had their expiration dates automatically rotated, which was not the expected behaviour. The expected behaviour is now restored: the expiration date is rotated only when the password is edited.
10
10
 
11
- A big thank you to all testers who helped refine these features. If you’re new to any of them, we welcome your feedback on the community forum or through your usual support channels!
12
-
13
- ### Added
14
- - PB-25265 Flush clipboard strategy
15
- - PB-43095 Display the metadata issue in the HealthCheck served by the UI
16
- - PB-43403 Search resources should take into account available custom fields information in the web application
17
-
18
- ### Improved
19
- - PB-43474 As LU I should be able to clear the search field with a button
11
+ We thank the community for promptly reporting these issues.
20
12
 
21
13
  ### Fixed
22
- - PB-43916 Fix hitting the key enter on the search fields
23
- - PB-43996 Users should access encrypted metadata section of the administration guide on the help site when clicking on the documentation CTA from the sidebar
24
-
25
- ### Maintenance
26
- - PB-43491 The resource activities should use a service worker service to request the service worker
27
- - PB-43496 The user should be notified if an error occurs while displaying additional resource activities
28
- - PB-43501 Cover ActionLogService API service and rename class as per naming convention
29
- - PB-43502 Move logic of ActionLogModel into FindActionLogService
30
- - PB-43506 Move logic of event passbolt.actionlogs.find-all-for into its dedicated Controller
31
- - PB-43738 Create DeleteUserService to call the userService deleteDryRun
32
- - PB-43739 Create DeleteDryRunUserController to call the DeleteUserService
33
- - PB-43750 An unexpected error should be displayed on delete user
34
- - PB-43904 Add a service to request or send data CommentsServiceWorkerService
35
- - PB-43907 Add tests for commentService API service and rename the service class as per naming convention
36
- - PB-43938 Create a GetOrFindMetadataKeysSettingsController to retrieve the metadata keys settings
37
- - PB-43940 Create a MetadataKeysSettingsLocalStorageContextProvider to retrieve the metadata keys settings
14
+ PB-44638 Password expiry should not be removed when password is not updated
15
+ PB-44668 The create menu import operation should be actionable when encrypted metadata plugin is not available
package/crowdin.yml CHANGED
@@ -20,4 +20,5 @@ export_languages:
20
20
  - sl
21
21
  - sv
22
22
  - uk
23
+ - cs
23
24
  commit_message: '[skip-ci]'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "passbolt-browser-extension",
3
- "version": "5.3.2",
3
+ "version": "5.4.1",
4
4
  "license": "AGPL-3.0",
5
5
  "copyright": "Copyright 2025 Passbolt SA",
6
6
  "description": "Passbolt web extension for the open source password manager for teams",
@@ -22,7 +22,7 @@
22
22
  "locutus": "~2.0.9",
23
23
  "openpgp": "^6.1.1",
24
24
  "papaparse": "^5.5.2",
25
- "passbolt-styleguide": "^5.3.2",
25
+ "passbolt-styleguide": "^5.4.4",
26
26
  "react": "17.0.2",
27
27
  "react-dom": "17.0.2",
28
28
  "secrets-passbolt": "github:passbolt/secrets.js#v2.0.1",
@@ -75,7 +75,8 @@
75
75
  "cheerio": {
76
76
  "undici": "6.21.2"
77
77
  }
78
- }
78
+ },
79
+ "brace-expansion": "^1.1.12"
79
80
  },
80
81
  "scripts": {
81
82
  "build": "npx grunt build",
@@ -0,0 +1,10 @@
1
+ {
2
+ "appName": {
3
+ "message": "Passbolt - Open source správce hesel",
4
+ "description": "The application name of the extension, displayed in the web store. 45 characters max."
5
+ },
6
+ "appDescription": {
7
+ "message": "Rozšíření Passbolt pro open source správce hesel pro týmy.",
8
+ "description": "The description of the extension, displayed in the web store. 85 characters max."
9
+ }
10
+ }
@@ -88,13 +88,13 @@ class InformMenuController {
88
88
  const webIntegrationWorker = await WorkerService.get('WebIntegration', this.worker.tab.id);
89
89
  const {username, password: secret_clear} = await webIntegrationWorker.port.request('passbolt.web-integration.get-credentials');
90
90
 
91
- // Retrieve resource name and uri from tab.
91
+ // Retrieve resource name and uris from tab.
92
92
  const tab = await BrowserTabService.getCurrent();
93
93
  const name = tab.title;
94
- const uri = tab.url.substr(0, ResourceMetadataEntity.URI_MAX_LENGTH);
94
+ const uris = [tab.url.substr(0, ResourceMetadataEntity.URI_MAX_LENGTH)];
95
95
 
96
96
  // Store the resource to save in cache.
97
- const resourceDto = {name: name, username: username, uri: uri, secret_clear: secret_clear};
97
+ const resourceDto = {name: name, username: username, uris: uris, secret_clear: secret_clear};
98
98
  const resource = new ExternalResourceEntity(resourceDto);
99
99
  await ResourceInProgressCacheService.set(resource);
100
100
 
@@ -0,0 +1,57 @@
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 5.4.0
13
+ */
14
+
15
+ export default class RedirectPostLoginController {
16
+ /**
17
+ * @constructor
18
+ * @param {Worker} worker
19
+ * @param {string} requestId
20
+ * @param {AbstractAccountEntity} apiClientOptions the api client options
21
+ */
22
+ constructor(worker, requestId, account) {
23
+ this.worker = worker;
24
+ this.requestId = requestId;
25
+ this.account = account;
26
+ }
27
+
28
+ /**
29
+ * Controller executor.
30
+ * @returns {Promise<void>}
31
+ */
32
+ async _exec() {
33
+ try {
34
+ await this.exec();
35
+ this.worker.port.emit(this.requestId, 'SUCCESS');
36
+ } catch (error) {
37
+ console.error(error);
38
+ this.worker.port.emit(this.requestId, 'ERROR', error);
39
+ }
40
+ }
41
+
42
+ /**
43
+ * Redirects the user to the app main page
44
+ * or to the redirect url if a `redirect` parameter is given in the worker URL.
45
+ * @returns {Promise<void>}
46
+ */
47
+ async exec() {
48
+ const workerUrl = new URL(this.worker.tab.url);
49
+ const redirectTo = workerUrl.searchParams.get("redirect");
50
+
51
+ const url = /^\/[A-Za-z0-9\-\/]*$/.test(redirectTo)
52
+ ? `${this.account.domain}${redirectTo}`
53
+ : this.account.domain;
54
+
55
+ chrome.tabs.update(this.worker.tab.id, {url});
56
+ }
57
+ }
@@ -0,0 +1,82 @@
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 5.4.0
13
+ */
14
+
15
+ import AccountEntity from "../../model/entity/account/accountEntity";
16
+ import {defaultAccountDto} from "../../model/entity/account/accountEntity.test.data";
17
+ import RedirectPostLoginController from "./redirectPostLoginController";
18
+
19
+ beforeEach(() => {
20
+ jest.resetAllMocks();
21
+ });
22
+
23
+ describe("RedirectPostLoginController", () => {
24
+ describe("::exec", () => {
25
+ it("should redirect to the main entry point if no redirect is set", async() => {
26
+ expect.assertions(2);
27
+
28
+ const worker = {
29
+ tab: {
30
+ id: 42,
31
+ url: "https://www.passbolt.com/test",
32
+ },
33
+ };
34
+ const account = new AccountEntity(defaultAccountDto());
35
+ const controller = new RedirectPostLoginController(worker, null, account);
36
+ jest.spyOn(chrome.tabs, "update").mockImplementation(() => {});
37
+
38
+ await controller.exec();
39
+
40
+ expect(chrome.tabs.update).toHaveBeenCalledTimes(1);
41
+ expect(chrome.tabs.update).toHaveBeenCalledWith(worker.tab.id, {url: account.domain});
42
+ });
43
+
44
+ it("should redirect to the given URL if a redirect is set", async() => {
45
+ expect.assertions(2);
46
+
47
+ const worker = {
48
+ tab: {
49
+ id: 42,
50
+ url: "https://www.passbolt.com/test?redirect=/app/administration",
51
+ },
52
+ };
53
+ const account = new AccountEntity(defaultAccountDto());
54
+ const controller = new RedirectPostLoginController(worker, null, account);
55
+ jest.spyOn(chrome.tabs, "update").mockImplementation(() => {});
56
+
57
+ await controller.exec();
58
+
59
+ expect(chrome.tabs.update).toHaveBeenCalledTimes(1);
60
+ expect(chrome.tabs.update).toHaveBeenCalledWith(worker.tab.id, {url: `${account.domain}/app/administration`});
61
+ });
62
+
63
+ it("should not redirect to the given URL if it is not valid", async() => {
64
+ expect.assertions(2);
65
+
66
+ const worker = {
67
+ tab: {
68
+ id: 42,
69
+ url: "https://www.passbolt.com/test?redirect=https://localhost",
70
+ },
71
+ };
72
+ const account = new AccountEntity(defaultAccountDto());
73
+ const controller = new RedirectPostLoginController(worker, null, account);
74
+ jest.spyOn(chrome.tabs, "update").mockImplementation(() => {});
75
+
76
+ await controller.exec();
77
+
78
+ expect(chrome.tabs.update).toHaveBeenCalledTimes(1);
79
+ expect(chrome.tabs.update).toHaveBeenCalledWith(worker.tab.id, {url: account.domain});
80
+ });
81
+ });
82
+ });
@@ -0,0 +1,50 @@
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 5.4.0
13
+ */
14
+
15
+ export default class RedirectToAdminWorkspaceController {
16
+ /**
17
+ * @constructor
18
+ * @param {Worker} worker
19
+ * @param {string} requestId
20
+ * @param {AbstractAccountEntity} apiClientOptions the api client options
21
+ */
22
+ constructor(worker, requestId, account) {
23
+ this.worker = worker;
24
+ this.requestId = requestId;
25
+ this.account = account;
26
+ }
27
+
28
+ /**
29
+ * Controller executor.
30
+ * @returns {Promise<void>}
31
+ */
32
+ async _exec() {
33
+ try {
34
+ await this.exec();
35
+ this.worker.port.emit(this.requestId, 'SUCCESS');
36
+ } catch (error) {
37
+ console.error(error);
38
+ this.worker.port.emit(this.requestId, 'ERROR', error);
39
+ }
40
+ }
41
+
42
+ /**
43
+ * Redirects the user to the admin workspace
44
+ * @returns {Promise<void>}
45
+ */
46
+ async exec() {
47
+ const url = `${this.account.domain}/app/administration`;
48
+ chrome.tabs.update(this.worker.tab.id, {url});
49
+ }
50
+ }
@@ -0,0 +1,45 @@
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 5.4.0
13
+ */
14
+
15
+ import AccountEntity from "../../model/entity/account/accountEntity";
16
+ import {defaultAccountDto} from "../../model/entity/account/accountEntity.test.data";
17
+ import RedirectToAdminWorkspaceController from "./redirectToAdminWorkspaceController";
18
+
19
+ beforeEach(() => {
20
+ jest.resetAllMocks();
21
+ });
22
+
23
+ describe("RedirectToAdminWorkspaceController", () => {
24
+ describe("::exec", () => {
25
+ it("should redirect to the administration workspace", async() => {
26
+ expect.assertions(2);
27
+
28
+ const worker = {
29
+ tab: {
30
+ id: 42,
31
+ },
32
+ };
33
+ const account = new AccountEntity(defaultAccountDto());
34
+ const expectedUrl = `${account.domain}/app/administration`;
35
+ console.log(expectedUrl);
36
+ const controller = new RedirectToAdminWorkspaceController(worker, null, account);
37
+ jest.spyOn(chrome.tabs, "update").mockImplementation(() => {});
38
+
39
+ await controller.exec();
40
+
41
+ expect(chrome.tabs.update).toHaveBeenCalledTimes(1);
42
+ expect(chrome.tabs.update).toHaveBeenCalledWith(worker.tab.id, {url: expectedUrl});
43
+ });
44
+ });
45
+ });
@@ -12,7 +12,7 @@
12
12
  * @since 3.8.0
13
13
  */
14
14
 
15
- import CommentModel from "../../model/comment/commentModel";
15
+ import CommentService from "../../model/comment/commentService";
16
16
  import CommentEntity from "../../model/entity/comment/commentEntity";
17
17
 
18
18
  class CreateCommentController {
@@ -25,7 +25,7 @@ class CreateCommentController {
25
25
  constructor(worker, requestId, apiClientOptions) {
26
26
  this.worker = worker;
27
27
  this.requestId = requestId;
28
- this.commentModel = new CommentModel(apiClientOptions);
28
+ this.commentService = new CommentService(apiClientOptions);
29
29
  }
30
30
 
31
31
  /**
@@ -50,7 +50,7 @@ class CreateCommentController {
50
50
  * @return {Promise<CommentEntity>} The created comment.
51
51
  */
52
52
  async exec(commentDto) {
53
- return this.commentModel.create(new CommentEntity(commentDto));
53
+ return this.commentService.create(new CommentEntity(commentDto));
54
54
  }
55
55
  }
56
56
 
@@ -19,7 +19,7 @@ import {mockApiResponse} from "../../../../../test/mocks/mockApiResponse";
19
19
  import CreateCommentController from "./createCommentController";
20
20
  import {v4 as uuidv4} from "uuid";
21
21
  import EntityValidationError from "passbolt-styleguide/src/shared/models/entity/abstract/entityValidationError";
22
- import CommentModel from "../../model/comment/commentModel";
22
+ import CommentService from "../../model/comment/commentService";
23
23
  import {defaultCommentDto} from "passbolt-styleguide/src/shared/models/entity/comment/commentEntity.test.data";
24
24
 
25
25
  beforeEach(async() => {
@@ -52,14 +52,14 @@ describe("CreateCommentController", () => {
52
52
 
53
53
  expect(controller.worker).toBe(mockedWorker);
54
54
  expect(controller.requestId).toBe(requestId);
55
- expect(controller.commentModel).toEqual(expect.objectContaining(new CommentModel(apiClientOption)));
55
+ expect(controller.commentService).toEqual(expect.objectContaining(new CommentService(apiClientOption)));
56
56
  });
57
57
  });
58
58
  describe("CreateCommentController::exec", () => {
59
59
  it("Should create the comment and send the result back.", async() => {
60
60
  fetchCommentsMock();
61
61
  const controller = new CreateCommentController(null, null, defaultApiClientOptions());
62
- const spy = jest.spyOn(controller.commentModel, "create");
62
+ const spy = jest.spyOn(controller.commentService, "create");
63
63
  const createdComment = await controller.exec(mockApiCreation);
64
64
 
65
65
  expect.assertions(2);
@@ -72,7 +72,7 @@ describe("CreateCommentController", () => {
72
72
  const mockedError = new TypeError("Unable to reach the server, an unexpected error occurred");
73
73
  fetch.doMock(() => { throw mockedError; });
74
74
  const controller = new CreateCommentController(mockedWorker, null, defaultApiClientOptions());
75
- const spy = jest.spyOn(controller.commentModel, "create");
75
+ const spy = jest.spyOn(controller.commentService, "create");
76
76
 
77
77
  expect.assertions(2);
78
78
 
@@ -93,7 +93,7 @@ describe("CreateCommentController", () => {
93
93
  const mockedError = new TypeError("Unable to reach the server, you are not connected to the network");
94
94
  fetch.doMock(() => { throw mockedError; });
95
95
  const controller = new CreateCommentController(mockedWorker, null, defaultApiClientOptions());
96
- const spy = jest.spyOn(controller.commentModel, "create");
96
+ const spy = jest.spyOn(controller.commentService, "create");
97
97
 
98
98
  expect.assertions(2);
99
99
 
@@ -12,7 +12,7 @@
12
12
  * @since 3.8.0
13
13
  */
14
14
 
15
- import CommentModel from "../../model/comment/commentModel";
15
+ import CommentService from "../../model/comment/commentService";
16
16
  import Validator from "validator";
17
17
 
18
18
  class DeleteCommentController {
@@ -25,7 +25,7 @@ class DeleteCommentController {
25
25
  constructor(worker, requestId, apiClientOptions) {
26
26
  this.worker = worker;
27
27
  this.requestId = requestId;
28
- this.commentModel = new CommentModel(apiClientOptions);
28
+ this.commentService = new CommentService(apiClientOptions);
29
29
  }
30
30
 
31
31
  /**
@@ -59,7 +59,7 @@ class DeleteCommentController {
59
59
  throw new Error("The comment id should be a valid uuid.");
60
60
  }
61
61
 
62
- await this.commentModel.delete(commentId);
62
+ await this.commentService.delete(commentId);
63
63
  }
64
64
  }
65
65
 
@@ -17,7 +17,7 @@ import DeleteCommentController from "./deleteCommentController";
17
17
  import {defaultApiClientOptions} from "passbolt-styleguide/src/shared/lib/apiClient/apiClientOptions.test.data";
18
18
  import {mockApiResponse} from "../../../../../test/mocks/mockApiResponse";
19
19
  import {enableFetchMocks} from "jest-fetch-mock";
20
- import CommentModel from "../../model/comment/commentModel";
20
+ import CommentService from "../../model/comment/commentService";
21
21
  import MockExtension from "../../../../../test/mocks/mockExtension";
22
22
 
23
23
  const mockedWorker = {
@@ -47,7 +47,7 @@ describe("DeleteCommentController", () => {
47
47
 
48
48
  expect(controller.worker).toBe(mockedWorker);
49
49
  expect(controller.requestId).toBe(requestId);
50
- expect(controller.commentModel).toEqual(expect.objectContaining(new CommentModel(apiClientOption)));
50
+ expect(controller.commentService).toEqual(expect.objectContaining(new CommentService(apiClientOption)));
51
51
  });
52
52
  });
53
53
  describe("DeleteCommentController::exec", () => {
@@ -55,7 +55,7 @@ describe("DeleteCommentController", () => {
55
55
  fetchCommentsMock();
56
56
 
57
57
  const controller = new DeleteCommentController(mockedWorker, null, defaultApiClientOptions());
58
- const spy = jest.spyOn(controller.commentModel, "delete");
58
+ const spy = jest.spyOn(controller.commentService, "delete");
59
59
  await controller.exec(id);
60
60
 
61
61
  expect.assertions(2);
@@ -12,7 +12,7 @@
12
12
  * @since 3.8.0
13
13
  */
14
14
 
15
- import CommentModel from "../../model/comment/commentModel";
15
+ import CommentService from "../../model/comment/commentService";
16
16
  import Validator from "validator";
17
17
 
18
18
  class GetCommentsByRessourceController {
@@ -25,7 +25,7 @@ class GetCommentsByRessourceController {
25
25
  constructor(worker, requestId, apiClientOptions) {
26
26
  this.worker = worker;
27
27
  this.requestId = requestId;
28
- this.commentModel = new CommentModel(apiClientOptions);
28
+ this.commentService = new CommentService(apiClientOptions);
29
29
  }
30
30
 
31
31
  /**
@@ -60,7 +60,7 @@ class GetCommentsByRessourceController {
60
60
  throw new TypeError("The resource id should be a valid uuid.");
61
61
  }
62
62
 
63
- return this.commentModel.findAllByResourceId(resourceId);
63
+ return this.commentService.findAllByResourceId(resourceId);
64
64
  }
65
65
  }
66
66
 
@@ -48,7 +48,7 @@ describe("GetCommentsByRessourceController", () => {
48
48
 
49
49
  expect(controller.worker).toBe(mockedWorker);
50
50
  expect(controller.requestId).toBe(requestId);
51
- expect(controller.commentModel).toBeDefined();
51
+ expect(controller.commentService).toBeDefined();
52
52
  });
53
53
  });
54
54
  describe("GetCommentsByRessourceController::exec", () => {
@@ -58,7 +58,7 @@ describe("GetCommentsByRessourceController", () => {
58
58
  fetchCommentsMock();
59
59
  const resourceId = uuidv4();
60
60
  const controller = new GetCommentsByRessourceController(null, null, defaultApiClientOptions());
61
- const spy = jest.spyOn(controller.commentModel, "findAllByResourceId");
61
+ const spy = jest.spyOn(controller.commentService, "findAllByResourceId");
62
62
  const commentsCollectionDto = await controller.exec(resourceId);
63
63
 
64
64
  expect(commentsCollectionDto.items.length).toBe(4);