passbolt-browser-extension 5.12.1 → 5.13.0

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 (198) hide show
  1. package/.devcontainer/safe-chain-config.json +2 -1
  2. package/.github/ISSUE_TEMPLATE/bug_report.md +30 -22
  3. package/.github/ISSUE_TEMPLATE/config.yml +11 -0
  4. package/.jpmignore +0 -1
  5. package/CHANGELOG.md +82 -1
  6. package/CONTRIBUTING.md +1 -12
  7. package/README.md +5 -16
  8. package/RELEASE_NOTES.md +2 -3
  9. package/SECURITY.md +7 -0
  10. package/i18next.config.js +28 -0
  11. package/jest.config.json +1 -0
  12. package/package.json +20 -40
  13. package/src/all/background_page/controller/accountRecovery/reviewRequestController.test.js +1 -1
  14. package/src/all/background_page/{event → controller/actionLog}/findAllForActionLogController.js +1 -1
  15. package/src/all/background_page/{event → controller/actionLog}/findAllForActionLogController.test.js +4 -4
  16. package/src/all/background_page/controller/export/exportResourcesFileController.test.js +7 -2
  17. package/src/all/background_page/controller/folder/folderCreateController.js +3 -1
  18. package/src/all/background_page/controller/group/findMyGroupsController.test.js +2 -2
  19. package/src/all/background_page/controller/group/getOrFindGroupsController.js +61 -0
  20. package/src/all/background_page/controller/group/getOrFindGroupsController.test.js +69 -0
  21. package/src/all/background_page/controller/group/getOrFindGroupsUsersController.js +62 -0
  22. package/src/all/background_page/controller/group/getOrFindGroupsUsersController.test.js +69 -0
  23. package/src/all/background_page/controller/group/groupCreateController.js +1 -1
  24. package/src/all/background_page/controller/group/groupCreateController.test.js +1 -1
  25. package/src/all/background_page/controller/group/groupUpdateController.js +1 -1
  26. package/src/all/background_page/controller/group/updateAllGroupsLocalStorageController.test.js +1 -1
  27. package/src/all/background_page/controller/keyring/synchroniseKeyringController.js +51 -0
  28. package/src/all/background_page/controller/keyring/synchroniseKeyringController.test.js +49 -0
  29. package/src/all/background_page/controller/metadata/shareMetadataKeyPrivateController.test.js +1 -1
  30. package/src/all/background_page/controller/move/moveFolderController.js +0 -2
  31. package/src/all/background_page/controller/permission/FindAcoPermissionsForDisplayController.js +1 -1
  32. package/src/all/background_page/controller/permission/FindAcoPermissionsForDisplayController.test.js +2 -2
  33. package/src/all/background_page/controller/resource/findAllByIdsForDisplayPermissionsController.test.js +8 -3
  34. package/src/all/background_page/controller/resource/findAllIdsByIsSharedWithGroupController.test.js +9 -4
  35. package/src/all/background_page/controller/resource/resourceUpdateController.test.js +1 -2
  36. package/src/all/background_page/controller/resourceLocalStorage/resourceUpdateLocalStorageController.test.js +5 -2
  37. package/src/all/background_page/controller/share/findFoldersForShareController.js +66 -0
  38. package/src/all/background_page/controller/share/findFoldersForShareController.test.js +70 -0
  39. package/src/all/background_page/controller/share/searchUsersAndGroupsController.js +4 -4
  40. package/src/all/background_page/controller/share/searchUsersAndGroupsController.test.js +8 -23
  41. package/src/all/background_page/controller/share/shareResourcesController.test.js +2 -2
  42. package/src/all/background_page/controller/subscription/createSubscriptionKeyController.js +63 -0
  43. package/src/all/background_page/controller/subscription/createSubscriptionKeyController.test.js +56 -0
  44. package/src/all/background_page/controller/subscription/deleteSubscriptionKeyController.js +55 -0
  45. package/src/all/background_page/controller/subscription/deleteSubscriptionKeyController.test.js +50 -0
  46. package/src/all/background_page/controller/user/deleteUserController.test.js +1 -1
  47. package/src/all/background_page/controller/user/getOrFindUsersController.js +61 -0
  48. package/src/all/background_page/controller/user/getOrFindUsersController.test.js +69 -0
  49. package/src/all/background_page/error/deleteDryRunError.js +1 -1
  50. package/src/all/background_page/event/actionLogEvents.js +1 -1
  51. package/src/all/background_page/event/appEvents.js +25 -0
  52. package/src/all/background_page/event/groupEvents.js +26 -0
  53. package/src/all/background_page/event/keyringEvents.js +12 -0
  54. package/src/all/background_page/event/shareEvents.js +3 -9
  55. package/src/all/background_page/event/userEvents.js +13 -0
  56. package/src/all/background_page/model/config.js +12 -2
  57. package/src/all/background_page/model/entity/folder/folderEntity.js +2 -2
  58. package/src/all/background_page/model/entity/folder/folderEntity.test.js +2 -2
  59. package/src/all/background_page/model/entity/folder/foldersCollection.test.js +1 -1
  60. package/src/all/background_page/model/entity/group/update/groupUpdateEntity.js +1 -1
  61. package/src/all/background_page/model/entity/group/update/groupUpdateEntity.test.js +1 -1
  62. package/src/all/background_page/model/entity/permission/actionLog/updatedPermissionEntity.js +2 -2
  63. package/src/all/background_page/model/entity/permission/actionLog/updatedPermissionEntity.test.data.js +1 -1
  64. package/src/all/background_page/model/entity/permission/change/permissionChangeEntity.js +1 -1
  65. package/src/all/background_page/model/entity/permission/change/permissionChangesCollection.js +2 -2
  66. package/src/all/background_page/model/entity/permission/change/permissionChangesCollection.test.js +2 -2
  67. package/src/all/background_page/model/entity/resource/resourceEntity.js +2 -2
  68. package/src/all/background_page/model/entity/resource/resourceEntity.test.js +1 -1
  69. package/src/all/background_page/model/entity/user/userEntity.js +16 -377
  70. package/src/all/background_page/model/entity/user/userEntity.test.js +22 -297
  71. package/src/all/background_page/model/entity/userAndGroupSearchResultEntity/userAndGroupSearchResultEntity.js +1 -1
  72. package/src/all/background_page/model/folder/folderModel.js +5 -154
  73. package/src/all/background_page/model/group/groupModel.js +1 -1
  74. package/src/all/background_page/model/keyring.js +52 -17
  75. package/src/all/background_page/model/keyring.test.js +110 -0
  76. package/src/all/background_page/model/resource/resourceModel.js +2 -55
  77. package/src/all/background_page/model/setup/setupModel.js +2 -2
  78. package/src/all/background_page/model/user/userModel.js +18 -15
  79. package/src/all/background_page/model/user/userModel.test.js +1 -3
  80. package/src/all/background_page/service/api/abstract/abstractService.js +3 -17
  81. package/src/all/background_page/service/api/edition/passboltEditionApiService.js +64 -0
  82. package/src/all/background_page/service/api/edition/passboltEditionApiService.test.js +99 -0
  83. package/src/all/background_page/service/api/group/groupApiService.js +22 -23
  84. package/src/all/background_page/service/api/group/groupApiService.test.js +70 -0
  85. package/src/all/background_page/service/api/resource/resourceService.js +18 -12
  86. package/src/all/background_page/service/api/share/{shareService.js → shareApiService.js} +10 -7
  87. package/src/all/background_page/service/api/share/{shareService.test.js → shareApiService.test.js} +5 -5
  88. package/src/all/background_page/service/group/createGroupService.js +1 -1
  89. package/src/all/background_page/service/group/createGroupService.test.js +1 -1
  90. package/src/all/background_page/service/group/findAndUpdateGroupsLocalStorageService.js +56 -1
  91. package/src/all/background_page/service/group/findAndUpdateGroupsLocalStorageService.test.js +84 -2
  92. package/src/all/background_page/service/group/findGroupsService.js +5 -9
  93. package/src/all/background_page/service/group/findGroupsService.test.data.js +1 -1
  94. package/src/all/background_page/service/group/findGroupsService.test.js +10 -15
  95. package/src/all/background_page/service/group/getOrFindGroupsService.js +65 -0
  96. package/src/all/background_page/service/group/getOrFindGroupsService.test.js +168 -0
  97. package/src/all/background_page/service/group/getOrFindGroupsUsersService.js +51 -0
  98. package/src/all/background_page/service/group/getOrFindGroupsUsersService.test.js +94 -0
  99. package/src/all/background_page/service/group/groupUpdateService.js +5 -3
  100. package/src/all/background_page/service/group/groupUpdateService.test.js +10 -2
  101. package/src/all/background_page/service/local_storage/groupLocalStorage.js +2 -2
  102. package/src/all/background_page/service/local_storage/groupLocalStorage.test.js +3 -3
  103. package/src/all/background_page/service/local_storage/userLocalStorage.js +57 -36
  104. package/src/all/background_page/service/local_storage/userLocalStorage.test.js +282 -0
  105. package/src/all/background_page/service/metadata/createMetadataKeyService.test.js +1 -1
  106. package/src/all/background_page/service/metadata/saveMetadataSettingsService.test.js +1 -1
  107. package/src/all/background_page/service/metadata/shareMetadataKeyPrivateService.test.js +1 -1
  108. package/src/all/background_page/service/migrateMetadata/migrateMetadataResourcesService.js +1 -1
  109. package/src/all/background_page/service/move/calculatePermissionsChangesForMoveService.js +113 -0
  110. package/src/all/background_page/service/move/calculatePermissionsChangesForMoveService.test.data.js +38 -0
  111. package/src/all/background_page/service/move/calculatePermissionsChangesForMoveService.test.js +158 -0
  112. package/src/all/background_page/service/move/moveOneFolderService.js +6 -7
  113. package/src/all/background_page/service/move/moveOneFolderService.test.js +90 -90
  114. package/src/all/background_page/service/move/moveResourcesService.js +2 -5
  115. package/src/all/background_page/service/permission/findPermissionsService.js +1 -1
  116. package/src/all/background_page/service/resource/create/resourceCreateService.js +13 -31
  117. package/src/all/background_page/service/resource/create/resourceCreateService.test.js +25 -18
  118. package/src/all/background_page/service/resource/export/exportResourcesService.test.js +13 -4
  119. package/src/all/background_page/service/resource/findAndUpdateResourcesLocalStorageService.test.js +35 -28
  120. package/src/all/background_page/service/resource/findResourcesService.js +78 -2
  121. package/src/all/background_page/service/resource/findResourcesService.test.data.js +1 -1
  122. package/src/all/background_page/service/resource/findResourcesService.test.js +90 -31
  123. package/src/all/background_page/service/resource/getOrFindResourcesService.test.js +18 -8
  124. package/src/all/background_page/service/session_storage/keepSessionAliveService.js +3 -3
  125. package/src/all/background_page/service/session_storage/keepSessionAliveService.test.js +5 -3
  126. package/src/all/background_page/service/share/searchUsersAndGroupsService.js +41 -0
  127. package/src/all/background_page/service/share/searchUsersAndGroupsService.test.js +64 -0
  128. package/src/all/background_page/service/share/shareFoldersService.js +3 -3
  129. package/src/all/background_page/service/share/shareFoldersService.test.js +3 -3
  130. package/src/all/background_page/service/share/shareResourceService.js +4 -4
  131. package/src/all/background_page/service/share/shareResourceService.test.js +8 -8
  132. package/src/all/background_page/service/subscription/createSubscriptionKeyService.js +57 -0
  133. package/src/all/background_page/service/subscription/createSubscriptionKeyService.test.js +111 -0
  134. package/src/all/background_page/service/subscription/deleteSubscriptionKeyService.js +35 -0
  135. package/src/all/background_page/service/subscription/deleteSubscriptionKeyService.test.js +55 -0
  136. package/src/all/background_page/service/user/deleteUserService.js +4 -4
  137. package/src/all/background_page/service/user/deleteUserService.test.js +10 -10
  138. package/src/all/background_page/service/user/findAndUpdateUsersLocalStorageService.js +81 -0
  139. package/src/all/background_page/service/user/findAndUpdateUsersLocalStorageService.test.js +132 -0
  140. package/src/all/background_page/service/user/findUsersService.js +6 -6
  141. package/src/all/background_page/service/user/findUsersService.test.js +39 -38
  142. package/src/all/background_page/service/user/getOrFindUsersService.js +60 -0
  143. package/src/all/background_page/service/user/getOrFindUsersService.test.js +110 -0
  144. package/src/all/background_page/utils/assertions.js +1 -0
  145. package/src/all/locales/ko-KR/common.json +1 -1
  146. package/src/chrome/manifest.json +1 -1
  147. package/src/chrome-mv3/manifest.json +1 -1
  148. package/src/firefox/manifest.json +3 -3
  149. package/src/safari/manifest.json +2 -2
  150. package/test/jest.env-setup.js +31 -0
  151. package/webpack/applyOutputClean.js +69 -0
  152. package/webpack/base.config.js +33 -0
  153. package/webpack/common-blocks.js +91 -0
  154. package/webpack/expectedBuildArtifacts.js +51 -0
  155. package/webpack/i18nextExtractionPlugin.js +43 -0
  156. package/webpack/passboltEnvPlugin.js +41 -0
  157. package/webpack/webExtPlugin/index.js +75 -0
  158. package/webpack.chromium-mv2.config.js +40 -0
  159. package/webpack.chromium-mv3.config.js +40 -0
  160. package/webpack.common.config.js +186 -0
  161. package/webpack.config.js +38 -0
  162. package/webpack.firefox.config.js +40 -0
  163. package/webpack.mv2.config.js +65 -0
  164. package/webpack.mv3.config.js +99 -0
  165. package/webpack.safari-background-page.config.js +66 -57
  166. package/webpack.safari.config.js +44 -0
  167. package/Gruntfile.js +0 -471
  168. package/am_i_compromised.py +0 -1036
  169. package/am_i_compromised.sh +0 -688
  170. package/i18next-parser.config.js +0 -22
  171. package/src/all/background_page/config/config.json +0 -7
  172. package/src/all/background_page/config/config.json.debug +0 -7
  173. package/src/all/background_page/config/config.json.default +0 -7
  174. package/src/all/background_page/model/entity/group/groupEntity.js +0 -241
  175. package/src/all/background_page/model/entity/group/groupEntity.test.js +0 -136
  176. package/src/all/background_page/model/entity/group/groupsCollection.js +0 -166
  177. package/src/all/background_page/model/entity/group/groupsCollection.test.data.js +0 -34
  178. package/src/all/background_page/model/entity/group/groupsCollection.test.js +0 -227
  179. package/src/all/background_page/model/entity/permission/permissionEntity.js +0 -485
  180. package/src/all/background_page/model/entity/permission/permissionEntity.test.js +0 -263
  181. package/src/all/background_page/model/entity/permission/permissionsCollection.js +0 -486
  182. package/src/all/background_page/model/entity/permission/permissionsCollection.test.js +0 -700
  183. package/src/all/background_page/model/entity/user/usersCollection.js +0 -147
  184. package/src/all/background_page/model/entity/user/usersCollection.test.js +0 -223
  185. package/src/all/background_page/model/share/shareModel.js +0 -183
  186. package/src/all/background_page/model/share/shareModel.test.js +0 -61
  187. package/src/all/background_page/service/api/user/userService.js +0 -260
  188. package/src/all/background_page/service/resource/create/resourceCreateService.test.data.js +0 -55
  189. package/webpack-content-scripts.browser-integration.config.js +0 -57
  190. package/webpack-content-scripts.config.js +0 -61
  191. package/webpack-content-scripts.public-website-sign-in.config.js +0 -57
  192. package/webpack-data.config.js +0 -102
  193. package/webpack-data.download.config.js +0 -59
  194. package/webpack-data.in-form-call-to-action.config.js +0 -97
  195. package/webpack-data.in-form-menu.config.js +0 -97
  196. package/webpack-offscreens.config.js +0 -55
  197. package/webpack.background-page.config.js +0 -62
  198. package/webpack.service-worker.config.js +0 -65
@@ -0,0 +1,70 @@
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.13.0
13
+ */
14
+
15
+ import FindFoldersForShareController from "./findFoldersForShareController";
16
+ import FindFoldersService from "../../service/folder/findFoldersService";
17
+ import FoldersCollection from "../../model/entity/folder/foldersCollection";
18
+ import FolderService from "../../service/api/folder/folderService";
19
+ import { defaultFolderDto } from "passbolt-styleguide/src/shared/models/entity/folder/folderEntity.test.data";
20
+ import { defaultApiClientOptions } from "passbolt-styleguide/src/shared/lib/apiClient/apiClientOptions.test.data";
21
+ import { enableFetchMocks } from "jest-fetch-mock";
22
+ import { mockApiResponse } from "../../../../../test/mocks/mockApiResponse";
23
+
24
+ beforeEach(() => {
25
+ jest.clearAllMocks();
26
+ enableFetchMocks();
27
+ });
28
+
29
+ describe("FindFoldersForShareController", () => {
30
+ describe("FindFoldersForShareController::exec", () => {
31
+ it("requests the API with permission + permissions.user.profile + permissions.group contains and returns a FoldersCollection", async () => {
32
+ expect.assertions(6);
33
+
34
+ const folderDto1 = defaultFolderDto();
35
+ const folderDto2 = defaultFolderDto();
36
+ const serverResponseDto = [folderDto1, folderDto2];
37
+ const foldersIds = [folderDto1.id, folderDto2.id];
38
+
39
+ fetch.doMockOnceIf(/folders\.json/, async (request) => {
40
+ const url = new URL(request.url);
41
+ expect(url.searchParams.getAll("filter[has-id][]")).toStrictEqual(foldersIds);
42
+ expect(url.searchParams.get("contain[permission]")).toStrictEqual("1");
43
+ expect(url.searchParams.get("contain[permissions.user.profile]")).toStrictEqual("1");
44
+ expect(url.searchParams.get("contain[permissions.group]")).toStrictEqual("1");
45
+ return await mockApiResponse(serverResponseDto);
46
+ });
47
+
48
+ const controller = new FindFoldersForShareController(null, null, defaultApiClientOptions());
49
+ const result = await controller.exec(foldersIds);
50
+
51
+ expect(result).toBeInstanceOf(FoldersCollection);
52
+ expect(result).toStrictEqual(new FoldersCollection(serverResponseDto));
53
+ });
54
+
55
+ it("rejects with a TypeError when foldersIds is not an array of UUIDs", async () => {
56
+ expect.assertions(1);
57
+ const controller = new FindFoldersForShareController(null, null, defaultApiClientOptions());
58
+ await expect(controller.exec(["not-a-uuid"])).rejects.toThrow(TypeError);
59
+ });
60
+ });
61
+
62
+ describe("FindFoldersForShareController::constructor", () => {
63
+ it("instantiates a FindFoldersService backed by a FolderService", () => {
64
+ expect.assertions(2);
65
+ const controller = new FindFoldersForShareController(null, null, defaultApiClientOptions());
66
+ expect(controller.findFoldersService).toBeInstanceOf(FindFoldersService);
67
+ expect(controller.findFoldersService.folderService).toBeInstanceOf(FolderService);
68
+ });
69
+ });
70
+ });
@@ -12,12 +12,12 @@
12
12
  * @since 4.9.0
13
13
  */
14
14
 
15
- import ShareModel from "../../model/share/shareModel";
15
+ import SearchUsersAndGroupsService from "../../service/share/searchUsersAndGroupsService";
16
16
  import { assertString } from "../../utils/assertions";
17
17
 
18
18
  class SearchUsersAndGroupsController {
19
19
  /**
20
- * DeleteLocalSsoKitController constructor
20
+ * SearchUsersAndGroupsController constructor
21
21
  * @param {Worker} worker
22
22
  * @param {string} requestId uuid
23
23
  * @param {ApiClientOptions} apiClientOptions
@@ -25,7 +25,7 @@ class SearchUsersAndGroupsController {
25
25
  constructor(worker, requestId, apiClientOptions) {
26
26
  this.worker = worker;
27
27
  this.requestId = requestId;
28
- this.shareModel = new ShareModel(apiClientOptions);
28
+ this.searchUsersAndGroupsService = new SearchUsersAndGroupsService(apiClientOptions);
29
29
  }
30
30
 
31
31
  /**
@@ -51,7 +51,7 @@ class SearchUsersAndGroupsController {
51
51
  */
52
52
  async exec(keyword) {
53
53
  assertString(keyword, "keyword is not a valid string");
54
- return await this.shareModel.search(keyword);
54
+ return await this.searchUsersAndGroupsService.search(keyword);
55
55
  }
56
56
  }
57
57
 
@@ -19,49 +19,34 @@ import {
19
19
  defaultGroupSearchResultDto,
20
20
  } from "../../model/entity/userAndGroupSearchResultEntity/userAndGroupSearchResultEntity.test.data";
21
21
  import { defaultApiClientOptions } from "passbolt-styleguide/src/shared/lib/apiClient/apiClientOptions.test.data";
22
- import { enableFetchMocks } from "jest-fetch-mock";
23
- import { mockApiResponse } from "../../../../../test/mocks/mockApiResponse";
24
-
25
- jest.mock("../../service/progress/progressService");
26
- jest.mock("../../service/passphrase/getPassphraseService");
27
22
 
28
23
  beforeEach(() => {
29
24
  jest.clearAllMocks();
30
- enableFetchMocks();
31
25
  });
32
26
 
33
27
  describe("SearchUsersAndGroupsController", () => {
34
28
  describe("SearchUsersAndGroupsController::exec", () => {
35
- it("Request the API the right way and returns the a collection", async () => {
36
- expect.assertions(5);
29
+ it("should delegate to SearchUsersAndGroupsService and return the result", async () => {
30
+ expect.assertions(3);
37
31
 
38
32
  const serverResponseDto = [defaultUserSearchResultDto(), defaultGroupSearchResultDto()];
39
-
33
+ const expectedResult = new UserAndGroupSearchResultsCollection(serverResponseDto);
40
34
  const searchedKeyword = "test";
41
35
 
42
- fetch.doMockOnceIf(/share\/search-aros\.json/, async (request) => {
43
- const url = new URL(request.url);
44
- expect(url.searchParams.get("filter[search]")).toStrictEqual(searchedKeyword);
45
- expect(url.searchParams.get("contain[profile]")).toStrictEqual("1");
46
- expect(url.searchParams.get("contain[user_count]")).toStrictEqual("1");
47
- return await mockApiResponse(serverResponseDto);
48
- });
36
+ const controller = new SearchUsersAndGroupsController(null, null, defaultApiClientOptions());
37
+ jest.spyOn(controller.searchUsersAndGroupsService, "search").mockResolvedValue(expectedResult);
49
38
 
50
- const apiClientOptions = defaultApiClientOptions();
51
- const controller = new SearchUsersAndGroupsController(null, null, apiClientOptions);
52
39
  const result = await controller.exec(searchedKeyword);
53
40
 
54
- const expectedResult = new UserAndGroupSearchResultsCollection(serverResponseDto);
55
-
56
- expect(result).toBeInstanceOf(UserAndGroupSearchResultsCollection);
41
+ expect(controller.searchUsersAndGroupsService.search).toHaveBeenCalledTimes(1);
42
+ expect(controller.searchUsersAndGroupsService.search).toHaveBeenCalledWith(searchedKeyword);
57
43
  expect(result).toStrictEqual(expectedResult);
58
44
  });
59
45
 
60
46
  it("should throw an error if the keyword is not a valid string", async () => {
61
47
  expect.assertions(1);
62
48
 
63
- const apiClientOptions = defaultApiClientOptions();
64
- const controller = new SearchUsersAndGroupsController(null, null, apiClientOptions);
49
+ const controller = new SearchUsersAndGroupsController(null, null, defaultApiClientOptions());
65
50
 
66
51
  try {
67
52
  await controller.exec(1);
@@ -89,7 +89,7 @@ describe("ShareResourcesController", () => {
89
89
  .mockImplementation(() => new ResourceTypesCollection(resourceTypesCollectionDto()));
90
90
  // Mock request simulating the share.
91
91
  jest
92
- .spyOn(controller.shareResourceService.shareService, "simulateShareResource")
92
+ .spyOn(controller.shareResourceService.shareApiService, "simulateShareResource")
93
93
  .mockImplementation(() => simulateShareSecretsChangesDto([pgpKeys.carol.userId], []));
94
94
  // Mock find all for share.
95
95
  const secretDto = plaintextSecretPasswordAndDescriptionDto();
@@ -111,7 +111,7 @@ describe("ShareResourcesController", () => {
111
111
  // Mock the share request.
112
112
  let shareRequestData;
113
113
  jest
114
- .spyOn(controller.shareResourceService.shareService, "shareResource")
114
+ .spyOn(controller.shareResourceService.shareApiService, "shareResource")
115
115
  .mockImplementation((resourceId, data) => {
116
116
  shareRequestData = data;
117
117
  return {};
@@ -0,0 +1,63 @@
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.13.0
13
+ */
14
+
15
+ import UpdateSubscriptionEntity from "../../model/entity/subscription/update/updateSubscriptionEntity";
16
+ import PostLogoutService from "../../service/auth/postLogoutService";
17
+ import CreateSubscriptionKeyService from "../../service/subscription/createSubscriptionKeyService";
18
+
19
+ export default class CreateSubscriptionKeyController {
20
+ /**
21
+ * @constructor
22
+ * @param {Worker} worker
23
+ * @param {string} requestId
24
+ * @param {ApiClientOptions} apiClientOptions
25
+ */
26
+ constructor(worker, requestId, apiClientOptions) {
27
+ this.worker = worker;
28
+ this.requestId = requestId;
29
+
30
+ this.createSubscriptionService = new CreateSubscriptionKeyService(apiClientOptions);
31
+ }
32
+
33
+ /**
34
+ * Controller executor
35
+ * @returns {Promise<void>}
36
+ */
37
+ async _exec() {
38
+ try {
39
+ const result = await this.exec.apply(this, arguments);
40
+ this.worker.port.emit(this.requestId, "SUCCESS", result);
41
+ } catch (error) {
42
+ console.error(error);
43
+ this.worker.port.emit(this.requestId, "ERROR", error);
44
+ }
45
+ }
46
+
47
+ /**
48
+ * Create the subscription key (upgrade CE to PRO).
49
+ * @param {{ data: string }} subscriptionKeyDto The new subscription key
50
+ * @returns {Promise<SubscriptionEntity>} The subscription key
51
+ * @throws {Error} Throws an error when encountering any network error
52
+ * @throws {ValidationError} Throws an error if subscriptionKeyDto format is incorrect
53
+ * @throws {PassboltSubscriptionError} Throws `PassboltSubscriptionError` when subscription is already expired or user limit reached
54
+ */
55
+ async exec(subscriptionKeyDto) {
56
+ const subscriptionKeyEntity = new UpdateSubscriptionEntity(subscriptionKeyDto);
57
+ const subscriptionEntity = await this.createSubscriptionService.create(subscriptionKeyEntity);
58
+
59
+ await PostLogoutService.exec();
60
+
61
+ return subscriptionEntity;
62
+ }
63
+ }
@@ -0,0 +1,56 @@
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.13.0
13
+ */
14
+
15
+ import SubscriptionEntity from "passbolt-styleguide/src/shared/models/entity/subscription/subscriptionEntity";
16
+ import { defaultApiClientOptions } from "passbolt-styleguide/src/shared/lib/apiClient/apiClientOptions.test.data";
17
+ import { mockSubscriptionUpdated } from "passbolt-styleguide/src/react-extension/components/Administration/DisplaySubscriptionKey/DisplaySubscriptionKey.test.data";
18
+
19
+ import CreateSubscriptionKeyController from "./createSubscriptionKeyController";
20
+ import PostLogoutService from "../../service/auth/postLogoutService";
21
+
22
+ describe("CreateSubscriptionKeyController", () => {
23
+ beforeEach(() => {
24
+ jest.clearAllMocks();
25
+ });
26
+
27
+ describe("::exec", () => {
28
+ it("should create the subscription key and log the user out", async () => {
29
+ expect.assertions(3);
30
+
31
+ const controller = new CreateSubscriptionKeyController(null, null, defaultApiClientOptions());
32
+ jest
33
+ .spyOn(controller.createSubscriptionService, "create")
34
+ .mockResolvedValue(new SubscriptionEntity(mockSubscriptionUpdated));
35
+ jest.spyOn(PostLogoutService, "exec").mockImplementation(async () => {});
36
+
37
+ const result = await controller.exec({ data: mockSubscriptionUpdated.data });
38
+
39
+ expect(result).toEqual(new SubscriptionEntity(mockSubscriptionUpdated));
40
+ expect(controller.createSubscriptionService.create).toHaveBeenCalledTimes(1);
41
+ expect(PostLogoutService.exec).toHaveBeenCalledTimes(1);
42
+ });
43
+
44
+ it("should not catch errors", async () => {
45
+ expect.assertions(2);
46
+
47
+ const expectedError = new Error("Something went wrong!");
48
+ const controller = new CreateSubscriptionKeyController(null, null, defaultApiClientOptions());
49
+ jest.spyOn(controller.createSubscriptionService, "create").mockRejectedValue(expectedError);
50
+ jest.spyOn(PostLogoutService, "exec").mockImplementation(async () => {});
51
+
52
+ await expect(controller.exec({ data: mockSubscriptionUpdated.data })).rejects.toStrictEqual(expectedError);
53
+ expect(PostLogoutService.exec).not.toHaveBeenCalled();
54
+ });
55
+ });
56
+ });
@@ -0,0 +1,55 @@
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.13.0
13
+ */
14
+
15
+ import PostLogoutService from "../../service/auth/postLogoutService";
16
+ import DeleteSubscriptionKeyService from "../../service/subscription/deleteSubscriptionKeyService";
17
+
18
+ export default class DeleteSubscriptionKeyController {
19
+ /**
20
+ * @constructor
21
+ * @param {Worker} worker
22
+ * @param {string} requestId
23
+ * @param {ApiClientOptions} apiClientOptions
24
+ */
25
+ constructor(worker, requestId, apiClientOptions) {
26
+ this.worker = worker;
27
+ this.requestId = requestId;
28
+
29
+ this.deleteSubscriptionService = new DeleteSubscriptionKeyService(apiClientOptions);
30
+ }
31
+
32
+ /**
33
+ * Controller executor
34
+ * @returns Promise<void>
35
+ */
36
+ async _exec() {
37
+ try {
38
+ const result = await this.exec.apply(this, arguments);
39
+ this.worker.port.emit(this.requestId, "SUCCESS", result);
40
+ } catch (error) {
41
+ console.error(error);
42
+ this.worker.port.emit(this.requestId, "ERROR", error);
43
+ }
44
+ }
45
+
46
+ /**
47
+ * Delete the subscription key (downgrade PRO to CE).
48
+ * @returns {Promise<void>}
49
+ * @throws {Error} Throws an error when encountering any network or server error
50
+ */
51
+ async exec() {
52
+ await this.deleteSubscriptionService.delete();
53
+ await PostLogoutService.exec();
54
+ }
55
+ }
@@ -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.13.0
13
+ */
14
+
15
+ import { defaultApiClientOptions } from "passbolt-styleguide/src/shared/lib/apiClient/apiClientOptions.test.data";
16
+
17
+ import DeleteSubscriptionKeyController from "./deleteSubscriptionKeyController";
18
+ import PostLogoutService from "../../service/auth/postLogoutService";
19
+
20
+ describe("DeleteSubscriptionKeyController", () => {
21
+ beforeEach(() => {
22
+ jest.clearAllMocks();
23
+ });
24
+
25
+ describe("::exec", () => {
26
+ it("should delete the subscription key and log the user out", async () => {
27
+ expect.assertions(3);
28
+
29
+ const controller = new DeleteSubscriptionKeyController(null, null, defaultApiClientOptions());
30
+ jest.spyOn(controller.deleteSubscriptionService, "delete").mockResolvedValue(undefined);
31
+ jest.spyOn(PostLogoutService, "exec").mockImplementation(async () => {});
32
+
33
+ await expect(controller.exec()).resolves.toBeUndefined();
34
+ expect(controller.deleteSubscriptionService.delete).toHaveBeenCalledTimes(1);
35
+ expect(PostLogoutService.exec).toHaveBeenCalledTimes(1);
36
+ });
37
+
38
+ it("should not catch errors", async () => {
39
+ expect.assertions(2);
40
+
41
+ const expectedError = new Error("Something went wrong!");
42
+ const controller = new DeleteSubscriptionKeyController(null, null, defaultApiClientOptions());
43
+ jest.spyOn(controller.deleteSubscriptionService, "delete").mockRejectedValue(expectedError);
44
+ jest.spyOn(PostLogoutService, "exec").mockImplementation(async () => {});
45
+
46
+ await expect(controller.exec()).rejects.toStrictEqual(expectedError);
47
+ expect(PostLogoutService.exec).not.toHaveBeenCalled();
48
+ });
49
+ });
50
+ });
@@ -31,7 +31,7 @@ import MetadataKeysCollection from "passbolt-styleguide/src/shared/models/entity
31
31
  import { defaultUserDto } from "passbolt-styleguide/src/shared/models/entity/user/userEntity.test.data";
32
32
  import DeleteUserController from "./deleteUserController";
33
33
  import UserLocalStorage from "../../service/local_storage/userLocalStorage";
34
- import UsersCollection from "../../model/entity/user/usersCollection";
34
+ import UsersCollection from "passbolt-styleguide/src/shared/models/entity/user/usersCollection";
35
35
 
36
36
  beforeEach(() => {
37
37
  enableFetchMocks();
@@ -0,0 +1,61 @@
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.13.0
13
+ */
14
+ import GetOrFindUsersService from "../../service/user/getOrFindUsersService";
15
+ import { assertArrayUUID } from "../../utils/assertions";
16
+
17
+ /**
18
+ * Controller for the `passbolt.users.get-by-ids` event. Returns the users matching the given ids,
19
+ * served from the local storage cache when available and otherwise fetched from the API.
20
+ */
21
+ class GetOrFindUsersController {
22
+ /**
23
+ * Constructor.
24
+ * @param {Worker} worker The associated worker.
25
+ * @param {string} requestId The associated request id.
26
+ * @param {ApiClientOptions} apiClientOptions The api client options.
27
+ * @param {AccountEntity} account The user account.
28
+ */
29
+ constructor(worker, requestId, apiClientOptions, account) {
30
+ this.worker = worker;
31
+ this.requestId = requestId;
32
+ this.getOrFindUsersService = new GetOrFindUsersService(account, apiClientOptions);
33
+ }
34
+
35
+ /**
36
+ * Controller executor.
37
+ * @param {Array<string>} userIds The ids of the users to retrieve.
38
+ * @returns {Promise<void>}
39
+ */
40
+ async _exec(userIds) {
41
+ try {
42
+ const result = await this.exec(userIds);
43
+ this.worker.port.emit(this.requestId, "SUCCESS", result);
44
+ } catch (error) {
45
+ console.error(error);
46
+ this.worker.port.emit(this.requestId, "ERROR", error);
47
+ }
48
+ }
49
+
50
+ /**
51
+ * Find all the users matching the given ids.
52
+ * @param {Array<string>} userIds The ids of the users to retrieve.
53
+ * @returns {Promise<UsersCollection>}
54
+ */
55
+ async exec(userIds) {
56
+ assertArrayUUID(userIds);
57
+ return this.getOrFindUsersService.getOrFindByIds(userIds);
58
+ }
59
+ }
60
+
61
+ export default GetOrFindUsersController;
@@ -0,0 +1,69 @@
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.13.0
13
+ */
14
+
15
+ import AccountEntity from "../../model/entity/account/accountEntity";
16
+ import { defaultAccountDto } from "../../model/entity/account/accountEntity.test.data";
17
+ import { defaultApiClientOptions } from "passbolt-styleguide/src/shared/lib/apiClient/apiClientOptions.test.data";
18
+ import GetOrFindUsersController from "./getOrFindUsersController";
19
+ import UsersCollection from "passbolt-styleguide/src/shared/models/entity/user/usersCollection";
20
+ import { defaultUsersDtos } from "passbolt-styleguide/src/shared/models/entity/user/usersCollection.test.data";
21
+
22
+ beforeEach(() => {
23
+ jest.clearAllMocks();
24
+ });
25
+
26
+ describe("GetOrFindUsersController", () => {
27
+ describe("::exec", () => {
28
+ it("Should retrieve the users matching the given ids.", async () => {
29
+ expect.assertions(3);
30
+
31
+ const account = new AccountEntity(defaultAccountDto());
32
+ const usersDto = defaultUsersDtos();
33
+ const usersCollection = new UsersCollection(usersDto);
34
+ const requestedIds = [usersDto[1].id, usersDto[3].id];
35
+ const controller = new GetOrFindUsersController(null, null, defaultApiClientOptions(), account);
36
+ jest.spyOn(controller.getOrFindUsersService, "getOrFindByIds").mockImplementation(() => usersCollection);
37
+
38
+ const result = await controller.exec(requestedIds);
39
+
40
+ expect(result).toBeInstanceOf(UsersCollection);
41
+ expect(result).toStrictEqual(usersCollection);
42
+ expect(controller.getOrFindUsersService.getOrFindByIds).toHaveBeenCalledWith(requestedIds);
43
+ });
44
+
45
+ it("Should let error been thrown from the service if any.", async () => {
46
+ expect.assertions(1);
47
+
48
+ const account = new AccountEntity(defaultAccountDto());
49
+ const controller = new GetOrFindUsersController(null, null, defaultApiClientOptions(), account);
50
+ const requestedIds = [defaultUsersDtos()[0].id];
51
+ jest.spyOn(controller.getOrFindUsersService, "getOrFindByIds").mockImplementation(() => {
52
+ throw new Error("Something went wrong!");
53
+ });
54
+
55
+ await expect(() => controller.exec(requestedIds)).rejects.toThrow();
56
+ });
57
+
58
+ it("Should assert its parameter.", async () => {
59
+ expect.assertions(1);
60
+
61
+ const account = new AccountEntity(defaultAccountDto());
62
+ const controller = new GetOrFindUsersController(null, null, defaultApiClientOptions(), account);
63
+
64
+ await expect(() => controller.exec(["not-a-uuid"])).rejects.toThrow(
65
+ "The given parameter is not a valid array of uuid",
66
+ );
67
+ });
68
+ });
69
+ });
@@ -11,7 +11,7 @@
11
11
  * @link https://www.passbolt.com Passbolt(tm)
12
12
  * @since 3.0.0
13
13
  */
14
- import GroupsCollection from "../model/entity/group/groupsCollection";
14
+ import GroupsCollection from "passbolt-styleguide/src/shared/models/entity/group/groupsCollection";
15
15
  import ResourcesCollection from "../model/entity/resource/resourcesCollection";
16
16
  import FoldersCollection from "../model/entity/folder/foldersCollection";
17
17
  import "./error.js";
@@ -10,7 +10,7 @@
10
10
  * @license https://opensource.org/licenses/AGPL-3.0 AGPL License
11
11
  * @link https://www.passbolt.com Passbolt(tm)
12
12
  */
13
- import FindAllForActionLogController from "./findAllForActionLogController";
13
+ import FindAllForActionLogController from "../controller/actionLog/findAllForActionLogController";
14
14
 
15
15
  /**
16
16
  * Listens to the action logs events
@@ -73,6 +73,8 @@ import FindResourceSecretRevisionsForDisplayController from "../controller/secre
73
73
  import DeleteSecretRevisionsSettingsController from "../controller/secretRevision/deleteSecretRevisionsSettingsController";
74
74
  import SaveSecretRevisionsSettingsController from "../controller/secretRevision/saveSecretRevisionsSettingsController";
75
75
  import FindExportPoliciesSettingsController from "../controller/exportPolicies/findExportPoliciesSettingsController";
76
+ import CreateSubscriptionKeyController from "../controller/subscription/createSubscriptionKeyController";
77
+ import DeleteSubscriptionKeyController from "../controller/subscription/deleteSubscriptionKeyController";
76
78
  import FindSubscriptionKeyController from "../controller/subscription/findSubscriptionKeyController";
77
79
  import UpdateSubscriptionKeyController from "../controller/subscription/updateSubscriptionKeyController";
78
80
  import FindTagsController from "../controller/tag/findTagsController";
@@ -771,6 +773,29 @@ const listen = function (worker, apiClientOptions, account) {
771
773
  await subscriptionController._exec(subscriptionKeyDto);
772
774
  });
773
775
 
776
+ /**
777
+ * Create the subscription key (upgrade CE to PRO).
778
+ *
779
+ * @listens passbolt.subscription.create
780
+ * @param requestId {uuid} The request identifier
781
+ * @param subscriptionKeyDto {{ data: string }} The new subscription key
782
+ */
783
+ worker.port.on("passbolt.subscription.create", async (requestId, subscriptionKeyDto) => {
784
+ const subscriptionController = new CreateSubscriptionKeyController(worker, requestId, apiClientOptions);
785
+ await subscriptionController._exec(subscriptionKeyDto);
786
+ });
787
+
788
+ /**
789
+ * Delete the subscription (downgrade PRO to CE).
790
+ *
791
+ * @listens passbolt.subscription.downgrade
792
+ * @param requestId {uuid} The request identifier
793
+ */
794
+ worker.port.on("passbolt.subscription.downgrade", async (requestId) => {
795
+ const subscriptionController = new DeleteSubscriptionKeyController(worker, requestId, apiClientOptions);
796
+ await subscriptionController._exec();
797
+ });
798
+
774
799
  /**
775
800
  * Find all the tags
776
801
  *
@@ -16,6 +16,8 @@ import GroupsUpdateController from "../controller/group/groupUpdateController";
16
16
  import GroupCreateController from "../controller/group/groupCreateController";
17
17
  import GroupDeleteTransferEntity from "../model/entity/group/transfer/groupDeleteTransferEntity";
18
18
  import FindMyGroupsController from "../controller/group/findMyGroupsController";
19
+ import GetOrFindGroupsController from "../controller/group/getOrFindGroupsController";
20
+ import GetOrFindGroupsUsersController from "../controller/group/getOrFindGroupsUsersController";
19
21
  import UpdateAllGroupsLocalStorageController from "../controller/group/updateAllGroupsLocalStorageController";
20
22
 
21
23
  /**
@@ -48,6 +50,30 @@ const listen = function (worker, apiClientOptions, account) {
48
50
  controller._exec();
49
51
  });
50
52
 
53
+ /*
54
+ * Find groups by their ids.
55
+ *
56
+ * @listens passbolt.groups.get-by-ids
57
+ * @param {uuid} requestId The request identifier
58
+ * @param {Array<uuid>} groupIds The ids of the groups to retrieve
59
+ */
60
+ worker.port.on("passbolt.groups.get-by-ids", async (requestId, groupIds) => {
61
+ const controller = new GetOrFindGroupsController(worker, requestId, apiClientOptions, account);
62
+ controller._exec(groupIds);
63
+ });
64
+
65
+ /*
66
+ * Find the members of a group given its id.
67
+ *
68
+ * @listens passbolt.groups_users.get-by-group-id
69
+ * @param {uuid} requestId The request identifier
70
+ * @param {uuid} groupId The id of the group whose members are requested
71
+ */
72
+ worker.port.on("passbolt.groups_users.get-by-group-id", async (requestId, groupId) => {
73
+ const controller = new GetOrFindGroupsUsersController(worker, requestId, apiClientOptions, account);
74
+ controller._exec(groupId);
75
+ });
76
+
51
77
  /*
52
78
  * ==================================================================================
53
79
  * CRUD