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
@@ -68,6 +68,7 @@ class FindAcoPermissionsForDisplayController {
68
68
  } else if (acoType === PermissionEntity.ACO_FOLDER) {
69
69
  // TODO: Should be adapted when API V5 can return permissions with folder id to use the same service than resources
70
70
  const folderEntity = await this.findFolderService.findByIdWithPermissions(acoId);
71
+ folderEntity.permissions.sort();
71
72
  return folderEntity.permissions;
72
73
  }
73
74
  }
@@ -0,0 +1,53 @@
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 ResourceInProgressCacheService from "../../service/cache/resourceInProgressCache.service";
16
+
17
+ class ConsumeInProgressCreationResourceController {
18
+ /**
19
+ * ConsumeInProgressCreationResourceController constructor
20
+ * @param {Worker} worker
21
+ * @param {string} requestId uuid
22
+ */
23
+ constructor(worker, requestId) {
24
+ this.worker = worker;
25
+ this.requestId = requestId;
26
+ }
27
+
28
+ /**
29
+ * Controller executor.
30
+ * @returns {Promise<void>}
31
+ */
32
+ async _exec() {
33
+ try {
34
+ const result = await this.exec.apply(this, arguments);
35
+ this.worker.port.emit(this.requestId, 'SUCCESS', result);
36
+ } catch (error) {
37
+ console.error(error);
38
+ this.worker.port.emit(this.requestId, 'ERROR', error);
39
+ }
40
+ }
41
+
42
+ /**
43
+ * Consume the resource in progress and handle URIs.
44
+ *
45
+ * @returns {Promise<{resourceDto>}}
46
+ */
47
+ async exec() {
48
+ const resourceInProgress = await ResourceInProgressCacheService.consume() || {};
49
+ return resourceInProgress;
50
+ }
51
+ }
52
+
53
+ export default ConsumeInProgressCreationResourceController;
@@ -0,0 +1,40 @@
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
+ import ConsumeInProgressCreationResourceController from "./consumeInProgressCreationResourceController";
15
+ import ResourceInProgressCacheService from "../../service/cache/resourceInProgressCache.service";
16
+ import ExternalResourceEntity from "../../model/entity/resource/external/externalResourceEntity";
17
+ import {defaultExternalResourceDto} from "../../model/entity/resource/external/externalResourceEntity.test.data";
18
+
19
+ describe("ConsumeInProgressCreationResourceController", () => {
20
+ describe("::exec", () => {
21
+ it("should return the resource in cache and clear the cache", async() => {
22
+ expect.assertions(3);
23
+
24
+ const fakeResource = new ExternalResourceEntity(defaultExternalResourceDto());
25
+ jest.spyOn(ResourceInProgressCacheService, "consume");
26
+
27
+ const controller = new ConsumeInProgressCreationResourceController();
28
+
29
+ let result = await controller.exec();
30
+
31
+ expect(result).toEqual({});
32
+
33
+ await ResourceInProgressCacheService.set(fakeResource, Number.MAX_SAFE_INTEGER);
34
+ result = await controller.exec();
35
+ expect(result).toEqual(fakeResource.toDto());
36
+
37
+ expect(ResourceInProgressCacheService.consume).toHaveBeenCalled();
38
+ });
39
+ });
40
+ });
@@ -0,0 +1,64 @@
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 resourceInProgressCacheService from "../../service/cache/resourceInProgressCache.service";
16
+ import BrowserTabService from "../../service/ui/browserTab.service";
17
+
18
+ class PrepareResourceController {
19
+ /**
20
+ * PrepareResourceController constructor
21
+ * @param {Worker} worker
22
+ * @param {string} requestId uuid
23
+ */
24
+ constructor(worker, requestId) {
25
+ this.worker = worker;
26
+ this.requestId = requestId;
27
+ }
28
+
29
+ /**
30
+ * Controller executor.
31
+ * @returns {Promise<void>}
32
+ */
33
+ async _exec() {
34
+ try {
35
+ const result = await this.exec.apply(this, arguments);
36
+ this.worker.port.emit(this.requestId, 'SUCCESS', result);
37
+ } catch (error) {
38
+ console.error(error);
39
+ this.worker.port.emit(this.requestId, 'ERROR', error);
40
+ }
41
+ }
42
+
43
+ /**
44
+ * Prepare to create a new resource.
45
+ *
46
+ * @param {string} tabId The tab id
47
+ * @returns {Promise<{name: string, uri: sttring} | resourceDto>}
48
+ */
49
+ async exec(tabId) {
50
+ const resourceInProgress = await resourceInProgressCacheService.consume();
51
+ if (resourceInProgress !== null) {
52
+ return resourceInProgress;
53
+ }
54
+
55
+ // Retrieve resource name and uri from tab.
56
+ const tab = tabId
57
+ ? await BrowserTabService.getById(tabId)
58
+ : await BrowserTabService.getCurrent();
59
+
60
+ return {name: tab.title, uris: [tab.url]};
61
+ }
62
+ }
63
+
64
+ export default PrepareResourceController;
@@ -0,0 +1,73 @@
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
+ import BrowserTabService from "../../service/ui/browserTab.service";
15
+ import PrepareResourceController from "./prepareResourceController";
16
+ import {defaultResourceDto} from "passbolt-styleguide/src/shared/models/entity/resource/resourceEntity.test.data";
17
+
18
+ describe("PrepareResourceController", () => {
19
+ describe("::exec", () => {
20
+ it("should return the resource in cache and clear the cache", async() => {
21
+ expect.assertions(2);
22
+
23
+ const controller = new PrepareResourceController();
24
+ const expectedResult = defaultResourceDto();
25
+
26
+ await browser.storage.session.set({"resourceInProgress": expectedResult});
27
+
28
+ const result = await controller.exec();
29
+
30
+ expect(result).toStrictEqual(expectedResult);
31
+
32
+ const cache = await browser.storage.session.get("resourceInProgress");
33
+ expect(cache["resourceInProgress"]).toBeFalsy();
34
+ });
35
+
36
+ it("should return the information from the tab if the cache is empty", async() => {
37
+ expect.assertions(2);
38
+
39
+ const controller = new PrepareResourceController();
40
+ const mockedTabInfo = {
41
+ title: "page from test",
42
+ url: 'https://www.passbolt.com',
43
+ };
44
+
45
+ await browser.storage.session.set({"resourceInProgress": null});
46
+ jest.spyOn(BrowserTabService, "getCurrent").mockImplementation(() => mockedTabInfo);
47
+
48
+ const result = await controller.exec();
49
+
50
+ expect(result.name).toStrictEqual(mockedTabInfo.title);
51
+ expect(result.uris).toStrictEqual([mockedTabInfo.url]);
52
+ });
53
+
54
+ it("should return the information from the tab given a tabId if the cache is empty", async() => {
55
+ expect.assertions(2);
56
+
57
+ const controller = new PrepareResourceController();
58
+ const mockedTabInfo = {
59
+ title: "page from test",
60
+ url: 'https://www.passbolt.com',
61
+ };
62
+ const tabId = 42;
63
+
64
+ await browser.storage.session.set({"resourceInProgress": null});
65
+ jest.spyOn(BrowserTabService, "getById").mockImplementation(() => mockedTabInfo);
66
+
67
+ const result = await controller.exec(tabId);
68
+
69
+ expect(result.name).toStrictEqual(mockedTabInfo.title);
70
+ expect(result.uris).toStrictEqual([mockedTabInfo.url]);
71
+ });
72
+ });
73
+ });
@@ -0,0 +1,67 @@
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
+ import DeleteResourceService from "../../service/resource/delete/deleteResourceService";
15
+ import ProgressService from "../../service/progress/progressService";
16
+ import i18n from "../../sdk/i18n";
17
+
18
+ class ResourceDeleteController {
19
+ /**
20
+ * ResourceDeleteController constructor
21
+ * @param {Worker} worker
22
+ * @param {string} requestId
23
+ * @param {ApiClientOptions} apiClientOptions the api client options
24
+ * @param {AccountEntity} account The account associated to the worker.clientOptions
25
+ */
26
+ constructor(worker, requestId, apiClientOptions, account) {
27
+ this.worker = worker;
28
+ this.requestId = requestId;
29
+ this.progressService = new ProgressService(this.worker, i18n.t("Delete Resources"));
30
+ this.resourceDeleteService = new DeleteResourceService(account, apiClientOptions, this.progressService);
31
+ }
32
+
33
+ /**
34
+ * Controller executor.
35
+ * @param {Array<string>} resourceIds The resourceIds to delete
36
+ * @returns {Promise<void>}
37
+ */
38
+ async _exec(resourceIds) {
39
+ try {
40
+ await this.exec(resourceIds);
41
+ this.worker.port.emit(this.requestId, 'SUCCESS');
42
+ } catch (error) {
43
+ console.error(error);
44
+ this.worker.port.emit(this.requestId, 'ERROR', error);
45
+ }
46
+ }
47
+
48
+ /**
49
+ * Delete resources.
50
+ * @param {Array<string>} resourceIds The resourceIds
51
+ * @returns {Promise<void>}
52
+ */
53
+ async exec(resourceIds) {
54
+ const steps = 2;
55
+ this.progressService.start(steps, i18n.t('Deleting Resource(s)'));
56
+ this.progressService.title = i18n.t("Delete {{count}} resource(s)", {count: resourceIds.length});
57
+
58
+ try {
59
+ await this.resourceDeleteService.deleteResources(resourceIds);
60
+ this.progressService.finishStep(i18n.t('Done!'), true);
61
+ } finally {
62
+ this.progressService.close();
63
+ }
64
+ }
65
+ }
66
+
67
+ export default ResourceDeleteController;
@@ -0,0 +1,114 @@
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
+ import {defaultApiClientOptions} from "passbolt-styleguide/src/shared/lib/apiClient/apiClientOptions.test.data";
15
+ import AccountEntity from "../../model/entity/account/accountEntity";
16
+ import {defaultAccountDto} from "../../model/entity/account/accountEntity.test.data";
17
+ import ResourceDeleteController from "./resourceDeleteController";
18
+ import {enableFetchMocks} from "jest-fetch-mock";
19
+ import {v4 as uuidv4} from "uuid";
20
+
21
+ jest.mock("../../service/progress/progressService");
22
+
23
+ beforeEach(() => {
24
+ enableFetchMocks();
25
+ fetch.resetMocks();
26
+ });
27
+
28
+ describe("ResourceDeleteController", () => {
29
+ let controller, worker;
30
+
31
+ beforeEach(() => {
32
+ worker = {
33
+ port: {
34
+ emit: jest.fn()
35
+ }
36
+ };
37
+ });
38
+
39
+ describe("::exec", () => {
40
+ it("should call deletion of IDs for the requested ids", async() => {
41
+ expect.assertions(6);
42
+ const account = new AccountEntity(defaultAccountDto());
43
+ const apiClientOptions = defaultApiClientOptions();
44
+ controller = new ResourceDeleteController(worker, null, apiClientOptions, account);
45
+
46
+ const resourceId1 = uuidv4();
47
+ const resourceId2 = uuidv4();
48
+ const resourceId3 = uuidv4();
49
+
50
+ jest.spyOn(controller.resourceDeleteService, "deleteResources").mockImplementation(() => {});
51
+
52
+ await controller.exec([resourceId1, resourceId2, resourceId3]);
53
+
54
+ expect(controller.progressService.start).toHaveBeenCalledTimes(1);
55
+ expect(controller.progressService.start).toHaveBeenCalledWith(2, "Deleting Resource(s)");
56
+ expect(controller.progressService.close).toHaveBeenCalledTimes(1);
57
+ expect(controller.progressService.finishStep).toHaveBeenCalledTimes(1);
58
+
59
+ expect(controller.resourceDeleteService.deleteResources).toHaveBeenCalledTimes(1);
60
+ expect(controller.resourceDeleteService.deleteResources).toHaveBeenCalledWith([resourceId1, resourceId2, resourceId3]);
61
+ });
62
+
63
+ it("Should close progressService when delete succeeds", async() => {
64
+ expect.assertions(1);
65
+
66
+ const account = new AccountEntity(defaultAccountDto());
67
+ const apiClientOptions = defaultApiClientOptions();
68
+ controller = new ResourceDeleteController(worker, null, apiClientOptions, account);
69
+
70
+ const resourceId1 = uuidv4();
71
+ const resourceId2 = uuidv4();
72
+ const resourceId3 = uuidv4();
73
+
74
+ jest.spyOn(controller.resourceDeleteService, "deleteResources").mockImplementation(() => {});
75
+
76
+ await controller.exec([resourceId1, resourceId2, resourceId3]);
77
+ expect(controller.progressService.close).toHaveBeenCalledTimes(1);
78
+ });
79
+
80
+ it("Should close progressService when deletion fails", async() => {
81
+ expect.assertions(1);
82
+ const account = new AccountEntity(defaultAccountDto());
83
+ const apiClientOptions = defaultApiClientOptions();
84
+ controller = new ResourceDeleteController(worker, null, apiClientOptions, account);
85
+
86
+ const resourceId1 = uuidv4();
87
+ const resourceId2 = uuidv4();
88
+ const resourceId3 = uuidv4();
89
+
90
+ jest.spyOn(controller.resourceDeleteService, "deleteResources").mockImplementation(() => { throw new Error(); });
91
+
92
+ try {
93
+ await controller.exec([resourceId1, resourceId2, resourceId3]);
94
+ } catch {
95
+ expect(controller.progressService.close).toHaveBeenCalledTimes(1);
96
+ }
97
+ });
98
+
99
+ it("Should throw an error if the resource IDs are not valid UUID array", async() => {
100
+ expect.assertions(1);
101
+
102
+ const account = new AccountEntity(defaultAccountDto());
103
+ const apiClientOptions = defaultApiClientOptions();
104
+ const controller = new ResourceDeleteController(null, null, apiClientOptions, account);
105
+
106
+ const expectedError = new TypeError("The given parameter is not a valid array of uuid");
107
+ try {
108
+ await controller.exec("42");
109
+ } catch (e) {
110
+ expect(e).toStrictEqual(expectedError);
111
+ }
112
+ });
113
+ });
114
+ });
@@ -68,7 +68,7 @@ class ResourceUpdateLocalStorageController {
68
68
  }
69
69
  const passphrase = await this.getPassphraseService.getPassphrase(this.worker);
70
70
  await PassphraseStorageService.set(passphrase, 60);
71
- await this.findAndUpdateResourcesLocalStorage.findAndUpdateAll();
71
+ await this.findAndUpdateResourcesLocalStorage.findAndUpdateAll({}, passphrase);
72
72
  }
73
73
  }
74
74
  }
@@ -65,7 +65,7 @@ describe("ResourceUpdateLocalStorageController", () => {
65
65
  });
66
66
 
67
67
  it("requests the user passphrase whenever the decryption of the metadata requires it and try to load the data again", async() => {
68
- expect.assertions(1);
68
+ expect.assertions(4);
69
69
 
70
70
  jest.spyOn(ResourceService.prototype, "findAll").mockImplementation(() => [defaultResourceDto(
71
71
  {
@@ -79,10 +79,14 @@ describe("ResourceUpdateLocalStorageController", () => {
79
79
  jest.spyOn(ResourceTypeService.prototype, "findAll").mockImplementation(() => resourceTypesCollectionDto());
80
80
  jest.spyOn(GetPassphraseService.prototype, "requestPassphrase").mockImplementation(() => pgpKeys.ada.passphrase);
81
81
  jest.spyOn(PassphraseStorageService, "set").mockImplementation(() => {});
82
+ jest.spyOn(controller.findAndUpdateResourcesLocalStorage, "findAndUpdateAll");
82
83
 
83
84
  await controller._exec();
84
85
 
85
86
  expect(PassphraseStorageService.set).toHaveBeenCalledWith(pgpKeys.ada.passphrase, 60);
87
+ expect(controller.findAndUpdateResourcesLocalStorage.findAndUpdateAll).toHaveBeenCalledTimes(2);
88
+ expect(controller.findAndUpdateResourcesLocalStorage.findAndUpdateAll).toHaveBeenNthCalledWith(1, {"updatePeriodThreshold": 10000});
89
+ expect(controller.findAndUpdateResourcesLocalStorage.findAndUpdateAll).toHaveBeenNthCalledWith(2, {}, pgpKeys.ada.passphrase);
86
90
  });
87
91
  });
88
92
  });
@@ -80,19 +80,9 @@ class SignInSetupController {
80
80
  await PassphraseStorageService.set(temporaryAccount.passphrase, 60);
81
81
  }
82
82
  await PostLoginService.exec();
83
- await this.redirectToApp(temporaryAccount.account.domain);
84
83
  // Clear all data in the temporary account session storage
85
84
  await AccountTemporarySessionStorageService.remove();
86
85
  }
87
-
88
- /**
89
- * Redirect the user to the application
90
- * @param {string} url The url
91
- * @returns {Promise<void>}
92
- */
93
- async redirectToApp(url) {
94
- browser.tabs.update(this.worker.tab.id, {url});
95
- }
96
86
  }
97
87
 
98
88
  export default SignInSetupController;
@@ -37,10 +37,6 @@ beforeEach(() => {
37
37
 
38
38
  describe("SignInSetupController", () => {
39
39
  describe("SignInSetupController::exec", () => {
40
- it.todo("Should sign-in the user.");
41
-
42
- it.todo("Should redirect the user to the application.");
43
-
44
40
  it("Should throw an exception if the passphrase is not a valid.", async() => {
45
41
  const account = new AccountEntity(defaultAccountDto());
46
42
  const controller = new SignInSetupController({port: {_port: {name: "test"}}}, null, defaultApiClientOptions());
@@ -80,6 +76,7 @@ describe("SignInSetupController", () => {
80
76
  }, 10000);
81
77
 
82
78
  it("Should ask for SSO kits generation.", async() => {
79
+ expect.assertions(6);
83
80
  const organizationSettings = anonymousOrganizationSettings();
84
81
  organizationSettings.passbolt.plugins.sso = {
85
82
  enabled: true
@@ -89,7 +86,6 @@ describe("SignInSetupController", () => {
89
86
  jest.spyOn(browser.cookies, "get").mockImplementationOnce(() => ({value: "csrf-token"}));
90
87
  jest.spyOn(PassphraseStorageService, "set").mockImplementation(async() => {});
91
88
  jest.spyOn(PostLoginService, "exec").mockImplementation(async() => {});
92
- jest.spyOn(browser.tabs, "update");
93
89
  jest.spyOn(KeepSessionAliveService, "start").mockImplementation(async() => {});
94
90
 
95
91
  SsoDataStorage.setMockedData(null);
@@ -104,14 +100,12 @@ describe("SignInSetupController", () => {
104
100
  jest.spyOn(controller.authVerifyLoginChallengeService, "verifyAndValidateLoginChallenge").mockImplementationOnce(jest.fn());
105
101
  jest.spyOn(AccountTemporarySessionStorageService, "remove");
106
102
 
107
- expect.assertions(7);
108
103
  await controller.exec(true);
109
104
  expect(controller.authVerifyLoginChallengeService.verifyAndValidateLoginChallenge).toHaveBeenCalledWith(account.userKeyFingerprint, account.userPrivateArmoredKey, "ada@passbolt.com");
110
105
  expect(PassphraseStorageService.set).toHaveBeenCalledWith("ada@passbolt.com", -1);
111
106
  expect(PostLoginService.exec).toHaveBeenCalled();
112
107
  expect(GenerateSsoKitService.generate).toHaveBeenCalledWith("ada@passbolt.com", "azure");
113
108
  expect(GenerateSsoKitService.generate).toHaveBeenCalledTimes(1);
114
- expect(browser.tabs.update).toHaveBeenCalledWith(1, {url: account.domain});
115
109
  expect(AccountTemporarySessionStorageService.remove).toHaveBeenCalledTimes(1);
116
110
  }, 10000);
117
111
 
@@ -141,18 +135,23 @@ describe("SignInSetupController", () => {
141
135
  });
142
136
 
143
137
  it("Should remember the passphrase during 1 minutes if not requested by the user.", async() => {
144
- jest.spyOn(browser.cookies, "get").mockImplementationOnce(() => ({value: "csrf-token"}));
145
- jest.spyOn(PassphraseStorageService, "set");
146
- await MockExtension.withConfiguredAccount();
138
+ expect.assertions(3);
139
+
140
+ const userKeyInfo = pgpKeys.ada;
141
+ const passphrase = userKeyInfo.passphrase;
142
+ await MockExtension.withConfiguredAccount(userKeyInfo);
147
143
  const account = new AccountEntity(defaultAccountDto());
148
144
  const controller = new SignInSetupController({tab: {id: 1}, port: {_port: {name: "test"}}}, null, defaultApiClientOptions());
149
-
150
- jest.spyOn(AccountTemporarySessionStorageService, "get").mockImplementationOnce(() => ({account: account, passphrase: "ada@passbolt.com"}));
145
+ jest.spyOn(browser.cookies, "get").mockImplementationOnce(() => ({value: "csrf-token"}));
146
+ jest.spyOn(PassphraseStorageService, "set");
147
+ jest.spyOn(AccountTemporarySessionStorageService, "get").mockImplementationOnce(() => ({account, passphrase}));
151
148
  jest.spyOn(controller.authVerifyLoginChallengeService, "verifyAndValidateLoginChallenge").mockImplementationOnce(jest.fn());
152
149
 
153
150
  await controller.exec();
154
151
 
155
152
  expect(PassphraseStorageService.set).toHaveBeenCalledWith("ada@passbolt.com", 60);
153
+ expect(controller.authVerifyLoginChallengeService.verifyAndValidateLoginChallenge).toHaveBeenCalledTimes(1);
154
+ expect(controller.authVerifyLoginChallengeService.verifyAndValidateLoginChallenge).toHaveBeenCalledWith(userKeyInfo.fingerprint, userKeyInfo.private, passphrase);
156
155
  });
157
156
  });
158
157
  });
@@ -25,6 +25,7 @@ export function withAzureSsoSettings(data = {}) {
25
25
  client_secret_expiry: "2022-11-02 00:00:00",
26
26
  email_claim: "email",
27
27
  prompt: "login",
28
+ login_hint: true,
28
29
  },
29
30
  };
30
31
 
@@ -40,7 +40,7 @@ class WebIntegrationController {
40
40
  const url = new URL(resourceToSave.url);
41
41
  const resourceDto = {
42
42
  name: resourceToSave.name,
43
- uri: `${url.protocol}//${url.host}${url.pathname}`,
43
+ uris: [`${url.protocol}//${url.host}${url.pathname}`],
44
44
  username: resourceToSave.username,
45
45
  secret_clear: resourceToSave.password
46
46
  };
@@ -67,8 +67,12 @@ import FindMetadataMigrateResourcesController from "../controller/migrateMetadat
67
67
  import MigrateMetadataResourcesController from "../controller/migrateMetadata/migrateMetadataResourcesController";
68
68
  import DownloadOrganizationGeneratedKey from "../controller/accountRecovery/downloadOrganizationGenerateKeyController";
69
69
  import ShareMetadataKeyPrivateController from "../controller/metadata/shareMetadataKeyPrivateController";
70
+ import GetOrFindMetadataKeysSettingsController from "../controller/metadata/getOrFindMetadataKeysSettingsController";
70
71
  import CopyToClipboardController from "../controller/clipboard/copyToClipboardController";
71
72
  import CopyTemporarilyToClipboardController from "../controller/clipboard/copyTemporarilyToClipboardController";
73
+ import FindMetadataGettingStartedSettingsController from "../controller/metadata/findMetadataGettingStartedSettingsController";
74
+ import EnableEncryptedMetadataForExistingInstanceController from "../controller/metadata/enableEncryptedMetadataForExistingInstanceController";
75
+ import KeepCleartextMetadataForExistingInstanceController from "../controller/metadata/keepCleartextMetadataForExistingInstanceController";
72
76
 
73
77
  const listen = function(worker, apiClientOptions, account) {
74
78
  /*
@@ -316,6 +320,17 @@ const listen = function(worker, apiClientOptions, account) {
316
320
  await controller._exec();
317
321
  });
318
322
 
323
+ /*
324
+ * Get or find metadata keys settings.
325
+ *
326
+ * @listens passbolt.metadata.get-or-find-metadata-keys-settings
327
+ * @param requestId {uuid} The request identifier
328
+ */
329
+ worker.port.on('passbolt.metadata.get-or-find-metadata-keys-settings', async requestId => {
330
+ const controller = new GetOrFindMetadataKeysSettingsController(worker, requestId, apiClientOptions, account);
331
+ await controller._exec();
332
+ });
333
+
319
334
  /*
320
335
  * Generate metadata key.
321
336
  *
@@ -436,6 +451,38 @@ const listen = function(worker, apiClientOptions, account) {
436
451
  await controller._exec(userId);
437
452
  });
438
453
 
454
+ /*
455
+ * Find metadata getting started settings.
456
+ *
457
+ * @listens passbolt.metadata.find-getting-started-settings
458
+ * @param requestId {uuid} The request identifier
459
+ */
460
+ worker.port.on('passbolt.metadata.find-getting-started-settings', async requestId => {
461
+ const controller = new FindMetadataGettingStartedSettingsController(worker, requestId, apiClientOptions);
462
+ await controller._exec();
463
+ });
464
+
465
+ /*
466
+ * Configure metadata to enable encrypted metadata for existing instances.
467
+ *
468
+ * @listens passbolt.metadata.enable-encrypted-metadata-for-existing-instance
469
+ * @param requestId {uuid} The request identifier
470
+ */
471
+ worker.port.on('passbolt.metadata.enable-encrypted-metadata-for-existing-instance', async requestId => {
472
+ const controller = new EnableEncryptedMetadataForExistingInstanceController(worker, requestId, apiClientOptions, account);
473
+ await controller._exec();
474
+ });
475
+
476
+ /*
477
+ * Configure metadata to keep legacy cleartext metadata for existing instances
478
+ *
479
+ * @listens passbolt.metadata.keep-cleartext-metadata-for-existing-instance
480
+ * @param requestId {uuid} The request identifier
481
+ */
482
+ worker.port.on('passbolt.metadata.keep-cleartext-metadata-for-existing-instance', async requestId => {
483
+ const controller = new KeepCleartextMetadataForExistingInstanceController(worker, requestId, apiClientOptions, account);
484
+ await controller._exec();
485
+ });
439
486
 
440
487
  /*
441
488
  * ==================================================================================
@@ -22,6 +22,7 @@ import AuthLogoutController from "../controller/auth/authLogoutController";
22
22
  import GetServerKeyController from "../controller/auth/getServerKeyController";
23
23
  import ReplaceServerKeyController from "../controller/auth/replaceServerKeyController";
24
24
  import ReloadTabController from "../controller/tab/reloadTabController";
25
+ import RedirectPostLoginController from "../controller/auth/redirectPostLoginController";
25
26
 
26
27
  /**
27
28
  * Listens to the authentication events
@@ -129,14 +130,9 @@ const listen = function(worker, apiClientOptions, account) {
129
130
  * @listens passbolt.auth.post-login-redirect
130
131
  * @param requestId {uuid} The request identifier
131
132
  */
132
- worker.port.on('passbolt.auth.post-login-redirect', requestId => {
133
- let url = account.domain;
134
- const redirectTo = (new URL(worker.tab.url)).searchParams.get('redirect');
135
- if (/^\/[A-Za-z0-9\-\/]*$/.test(redirectTo)) {
136
- url = `${url}${redirectTo}`;
137
- }
138
- chrome.tabs.update(worker.tab.id, {url: url});
139
- worker.port.emit(requestId, 'SUCCESS');
133
+ worker.port.on('passbolt.auth.post-login-redirect', async requestId => {
134
+ const controller = new RedirectPostLoginController(worker, requestId, account);
135
+ await controller._exec();
140
136
  });
141
137
 
142
138
  /*