passbolt-browser-extension 5.4.1 → 5.5.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 (70) hide show
  1. package/CHANGELOG.md +29 -1
  2. package/RELEASE_NOTES.md +45 -8
  3. package/package.json +3 -3
  4. package/src/all/background_page/controller/metadata/saveMetadataKeysSettingsController.js +6 -1
  5. package/src/all/background_page/controller/metadata/saveMetadataKeysSettingsController.test.js +34 -1
  6. package/src/all/background_page/controller/metadata/shareMetadataKeyPrivateController.js +1 -1
  7. package/src/all/background_page/controller/scimSettings/createScimSettingsController.js +56 -0
  8. package/src/all/background_page/controller/scimSettings/createScimSettingsController.test.js +64 -0
  9. package/src/all/background_page/controller/scimSettings/disableScimSettingsController.js +56 -0
  10. package/src/all/background_page/controller/scimSettings/disableScimSettingsController.test.js +51 -0
  11. package/src/all/background_page/controller/scimSettings/findScimSettingsController.js +53 -0
  12. package/src/all/background_page/controller/scimSettings/findScimSettingsController.test.js +49 -0
  13. package/src/all/background_page/controller/scimSettings/updateScimSettingsController.js +60 -0
  14. package/src/all/background_page/controller/scimSettings/updateScimSettingsController.test.js +58 -0
  15. package/src/all/background_page/event/appEvents.js +69 -0
  16. package/src/all/background_page/sdk/port/portManager.test.data.js +2 -2
  17. package/src/all/background_page/service/api/metadata/metadataKeysSettingsApiService.js +1 -1
  18. package/src/all/background_page/service/api/metadata/metadataPrivateKeyApiService.js +1 -1
  19. package/src/all/background_page/service/api/metadata/metadataPrivateKeyApiService.test.js +2 -2
  20. package/src/all/background_page/service/api/scimSettings/scimSettingsApiService.js +100 -0
  21. package/src/all/background_page/service/api/scimSettings/scimSettingsApiService.test.data.js +78 -0
  22. package/src/all/background_page/service/api/scimSettings/scimSettingsApiService.test.js +156 -0
  23. package/src/all/background_page/service/auth/postLoginService.js +3 -0
  24. package/src/all/background_page/service/auth/postLoginService.test.js +5 -1
  25. package/src/all/background_page/service/browser/browserService.js +13 -0
  26. package/src/all/background_page/service/extension/onExtensionUpdateAvailableService.js +13 -3
  27. package/src/all/background_page/service/extension/onExtensionUpdateAvailableService.test.js +97 -3
  28. package/src/all/background_page/service/local_storage/browserExtensionUpdatedLocalStorage.js +66 -0
  29. package/src/all/background_page/service/local_storage/browserExtensionUpdatedLocalStorage.test.js +132 -0
  30. package/src/all/background_page/service/metadata/saveMetadataSettingsService.js +90 -2
  31. package/src/all/background_page/service/metadata/saveMetadataSettingsService.test.js +92 -5
  32. package/src/all/background_page/service/metadata/shareMetadataKeyPrivateService.js +86 -5
  33. package/src/all/background_page/service/metadata/shareMetadataKeyPrivateService.test.js +110 -8
  34. package/src/all/background_page/service/scimSettings/disableScimSettingsService.js +39 -0
  35. package/src/all/background_page/service/scimSettings/disableScimSettingsService.test.js +71 -0
  36. package/src/all/background_page/service/scimSettings/enableScimSettingsService.js +42 -0
  37. package/src/all/background_page/service/scimSettings/enableScimSettingsService.test.js +83 -0
  38. package/src/all/background_page/service/scimSettings/findScimSettingsService.js +41 -0
  39. package/src/all/background_page/service/scimSettings/findScimSettingsService.test.js +77 -0
  40. package/src/all/background_page/service/scimSettings/updateScimSettingsService.js +43 -0
  41. package/src/all/background_page/service/scimSettings/updateScimSettingsService.test.js +92 -0
  42. package/src/all/background_page/service/serviceWorkerReloadService/serviceWorkerReloadService.js +51 -0
  43. package/src/all/background_page/service/serviceWorkerReloadService/serviceWorkerReloadService.test.js +54 -0
  44. package/src/all/background_page/service/user/findUsersService.js +11 -0
  45. package/src/all/background_page/service/user/findUsersService.test.js +15 -0
  46. package/src/all/locales/cs-CZ/common.json +10 -6
  47. package/src/all/locales/de-DE/common.json +10 -6
  48. package/src/all/locales/en-UK/common.json +4 -0
  49. package/src/all/locales/es-ES/common.json +9 -5
  50. package/src/all/locales/fr-FR/common.json +4 -0
  51. package/src/all/locales/it-IT/common.json +4 -0
  52. package/src/all/locales/ja-JP/common.json +4 -0
  53. package/src/all/locales/ko-KR/common.json +10 -6
  54. package/src/all/locales/lt-LT/common.json +4 -0
  55. package/src/all/locales/nl-NL/common.json +4 -0
  56. package/src/all/locales/pl-PL/common.json +4 -0
  57. package/src/all/locales/pt-BR/common.json +6 -2
  58. package/src/all/locales/ro-RO/common.json +4 -0
  59. package/src/all/locales/ru-RU/common.json +4 -0
  60. package/src/all/locales/sl-SI/common.json +4 -0
  61. package/src/all/locales/sv-SE/common.json +4 -0
  62. package/src/all/locales/uk-UA/common.json +4 -0
  63. package/src/chrome/manifest.json +1 -1
  64. package/src/chrome-mv3/index.js +15 -0
  65. package/src/chrome-mv3/manifest.json +1 -1
  66. package/src/firefox/manifest.json +1 -1
  67. package/src/safari/manifest.json +1 -1
  68. package/src/all/background_page/model/entity/metadata/shareMetadataPrivateKeysCollection.js +0 -103
  69. package/src/all/background_page/model/entity/metadata/shareMetadataPrivateKeysCollection.test.data.js +0 -88
  70. package/src/all/background_page/model/entity/metadata/shareMetadataPrivateKeysCollection.test.js +0 -192
package/CHANGELOG.md CHANGED
@@ -4,7 +4,35 @@ This project adheres to [Semantic Versioning](http://semver.org/).
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
- ## [5.4.1] - 2025-08-14
7
+ ## [5.5.0] - 2025-09-10
8
+ ### Added
9
+ - PB-43921 - Increase directory sync report dialog size
10
+ - PB-44816 Pro teasing - WP1.1 Create DisplaySubscriptionKeyTeasing component
11
+ - PB-44817 Pro teasing - WP1.2 Create DisplayPasswordPoliciesAdministrationTeasing
12
+ - PB-44818 Pro teasing - WP1.3 Create DisplayAdministrationUserPassphrasePoliciesTeasing
13
+ - PB-44819 Pro teasing - WP1.4 Create ManageAccountRecoveryAdministrationSettingsTeasing
14
+ - PB-44820 Pro teasing - WP1.5 Create ManageSsoSettingsTeasing
15
+ - PB-44821 Pro teasing - WP1.6 Create DisplayMfaPolicyAdministrationTeasing
16
+ - PB-44822 Pro teasing - WP1.7 Create DisplayUserDirectoryAdministrationTeasing
17
+ - PB-44823 Pro teasing - WP1.8 Create DisplayScimAdministrationTeasing
18
+ - PB-44826 Pro teasing - WP2.1 Add teasing property and new route on AdministrationHomePage
19
+ - PB-44827 Pro teasing - WP2.2 Update the DisplayAdministrationMenu to display teasing Icon on PRO menu for CE
20
+ - PB-44393 ZK - WP5.1 As an administrator I should be able to enable zero knowledge mode
21
+ - PB-44646 ZK - WP5.3 Add share metadata private keys to MetadataKeysSettingsEntity
22
+ - PB-44641 ZK - WP5.4 Create UpdateMetadataSettingsPrivateKeyService to to be able to disabled zero knowledge mode
23
+ - PB-44631 ZK - WP5.5 Update SaveMetadataKeysSettingsController to be able to disabled zero knowledge mode
24
+ - PB-44757 ZK - WP5.6 As an administrator with missing metadata keys I should not be able to change metadata settings
25
+ - PB-44630 - SCIM administration screen
26
+
27
+ ### Fixed
28
+ - PB-44638 - Password expiry should not be removed when password is not updated
29
+ - PB-44604 - Fix regular expression on public key metadata validation
30
+ - PB-44707 - Fix service worker not restarting after browser extension update on Chrome
31
+ - PB-45060 - Fix custom fields json schema properties type
32
+ - PB-44933 - Fix setup a new user should have missing key set
33
+
34
+ ### Maintenance
35
+ - PB-44594 - Upgrade xregexp to 5.1.2
8
36
  - PB-44638 Password expiry should not be removed when password is not updated
9
37
  - PB-44668 The create menu import operation should be actionable when encrypted metadata plugin is not available
10
38
 
package/RELEASE_NOTES.md CHANGED
@@ -1,15 +1,52 @@
1
- Release song: https://www.youtube.com/watch?v=6tpGC4lgpMg
1
+ Release song: https://youtu.be/L3Wo8jcNrkQ?si=HiNK6kSFC-aMFMJe
2
2
 
3
- This hot-fix addresses several issues introduced in recent v5.x releases.
3
+ Passbolt 5.5.0 is a feature release candidate that lets administrators run encrypted metadata in zero-knowledge mode and adds SCIM provisioning (beta) for easier user management.
4
4
 
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.
5
+ # Zero-knowledge
6
+ Zero-knowledge for encrypted metadata is intended for organisations that prioritise maximum privacy and can do without server-side auditability. In this mode, the server never receives the shared metadata private key and therefore cannot access any resource metadata.
6
7
 
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
+ When a new user joins, the server does not automatically share the key with them. Instead, administrators are notified by email once the user has completed their activation and is ready to receive access. From the Users & Groups workspace, administrators can then review the situation and share the key when the time is right.
8
9
 
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
+ Until a user receives the key, their experience is intentionally limited: actions that depend on the shared metadata key, such as sharing a resource, moving a private item into a shared folder, or creating content meant to be shared, are blocked.
10
11
 
11
- We thank the community for promptly reporting these issues.
12
+ To know more about the encrypted metadata zero-knowledge mode, check out this [blog post](https://www.passbolt.com/blog/the-road-to-passbolt-v5-encrypted-metadata-and-other-core-security-changes-2).
13
+
14
+ # SCIM (beta)
15
+ This release also introduces SCIM 2.0 (beta) to automate user provisioning with your identity provider. The first iteration focuses on Microsoft Entra ID (Azure AD) and is available on Passbolt Pro.
16
+
17
+ With SCIM, administrators can create, update, and deactivate users directly from their identity provider, without ever touching the Passbolt UI. For now, only user synchronisation is supported, while group synchronisation will follow in a future update.
18
+
19
+ Note that Okta should work out of the box, though some journeys may still need polish, such as the user deactivation.
20
+
21
+ Several bugs reported by the community have also been fixed. As always, thank you to everyone who took the time to file issues and suggest improvements. Checkout the changelog for more information.
22
+
23
+ ### Added
24
+ - PB-43921 - Increase directory sync report dialog size
25
+ - PB-44816 Pro teasing - WP1.1 Create DisplaySubscriptionKeyTeasing component
26
+ - PB-44817 Pro teasing - WP1.2 Create DisplayPasswordPoliciesAdministrationTeasing
27
+ - PB-44818 Pro teasing - WP1.3 Create DisplayAdministrationUserPassphrasePoliciesTeasing
28
+ - PB-44819 Pro teasing - WP1.4 Create ManageAccountRecoveryAdministrationSettingsTeasing
29
+ - PB-44820 Pro teasing - WP1.5 Create ManageSsoSettingsTeasing
30
+ - PB-44821 Pro teasing - WP1.6 Create DisplayMfaPolicyAdministrationTeasing
31
+ - PB-44822 Pro teasing - WP1.7 Create DisplayUserDirectoryAdministrationTeasing
32
+ - PB-44823 Pro teasing - WP1.8 Create DisplayScimAdministrationTeasing
33
+ - PB-44826 Pro teasing - WP2.1 Add teasing property and new route on AdministrationHomePage
34
+ - PB-44827 Pro teasing - WP2.2 Update the DisplayAdministrationMenu to display teasing Icon on PRO menu for CE
35
+ - PB-44393 ZK - WP5.1 As an administrator I should be able to enable zero knowledge mode
36
+ - PB-44646 ZK - WP5.3 Add share metadata private keys to MetadataKeysSettingsEntity
37
+ - PB-44641 ZK - WP5.4 Create UpdateMetadataSettingsPrivateKeyService to to be able to disabled zero knowledge mode
38
+ - PB-44631 ZK - WP5.5 Update SaveMetadataKeysSettingsController to be able to disabled zero knowledge mode
39
+ - PB-44757 ZK - WP5.6 As an administrator with missing metadata keys I should not be able to change metadata settings
40
+ - PB-44630 - SCIM administration screen
12
41
 
13
42
  ### Fixed
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
43
+ - PB-44638 - Password expiry should not be removed when password is not updated
44
+ - PB-44604 - Fix regular expression on public key metadata validation
45
+ - PB-44707 - Fix service worker not restarting after browser extension update on Chrome
46
+ - PB-45060 - Fix custom fields json schema properties type
47
+ - PB-44933 - Fix setup a new user should have missing key set
48
+
49
+ ### Maintenance
50
+ - PB-44594 - Upgrade xregexp to 5.1.2
51
+ - PB-44638 Password expiry should not be removed when password is not updated
52
+ - PB-44668 The create menu import operation should be actionable when encrypted metadata plugin is not available
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "passbolt-browser-extension",
3
- "version": "5.4.1",
3
+ "version": "5.5.0",
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,13 +22,13 @@
22
22
  "locutus": "~2.0.9",
23
23
  "openpgp": "^6.1.1",
24
24
  "papaparse": "^5.5.2",
25
- "passbolt-styleguide": "^5.4.4",
25
+ "passbolt-styleguide": "^v5.5.2",
26
26
  "react": "17.0.2",
27
27
  "react-dom": "17.0.2",
28
28
  "secrets-passbolt": "github:passbolt/secrets.js#v2.0.1",
29
29
  "validator": "^13.7.0",
30
30
  "webextension-polyfill": "^0.10.0",
31
- "xregexp": "~5.1.0"
31
+ "xregexp": "~5.1.2"
32
32
  },
33
33
  "devDependencies": {
34
34
  "@babel/core": "^7.23.2",
@@ -14,6 +14,8 @@
14
14
  import SaveMetadataSettingsService from "../../service/metadata/saveMetadataSettingsService";
15
15
  import MetadataKeysSettingsEntity
16
16
  from "passbolt-styleguide/src/shared/models/entity/metadata/metadataKeysSettingsEntity";
17
+ import FindMetadataSettingsService from "../../service/metadata/findMetadataSettingsService";
18
+ import GetPassphraseService from "../../service/passphrase/getPassphraseService";
17
19
 
18
20
  class SaveMetadataKeysSettingsController {
19
21
  /**
@@ -27,6 +29,8 @@ class SaveMetadataKeysSettingsController {
27
29
  this.worker = worker;
28
30
  this.requestId = requestId;
29
31
  this.saveMetadaSettingsService = new SaveMetadataSettingsService(account, apiClientOptions);
32
+ this.findMetadataSettingsService = new FindMetadataSettingsService(apiClientOptions);
33
+ this.getPassphraseService = new GetPassphraseService(account);
30
34
  }
31
35
 
32
36
  /**
@@ -50,8 +54,9 @@ class SaveMetadataKeysSettingsController {
50
54
  * @throws {EntityValidationError} If the settings dto does not validate against MetadataKeysSettingsEntity
51
55
  */
52
56
  async exec(dto) {
57
+ const passphrase = await this.getPassphraseService.getPassphrase(this.worker);
53
58
  const settings = new MetadataKeysSettingsEntity(dto);
54
- return this.saveMetadaSettingsService.saveKeysSettings(settings);
59
+ return this.saveMetadaSettingsService.saveKeysSettings(settings, passphrase);
55
60
  }
56
61
  }
57
62
 
@@ -21,13 +21,17 @@ import {
21
21
  } from "passbolt-styleguide/src/shared/models/entity/metadata/metadataKeysSettingsEntity.test.data";
22
22
  import MetadataKeysSettingsEntity
23
23
  from "passbolt-styleguide/src/shared/models/entity/metadata/metadataKeysSettingsEntity";
24
+ import {pgpKeys} from "passbolt-styleguide/test/fixture/pgpKeys/keys";
25
+ import RoleEntity from "passbolt-styleguide/src/shared/models/entity/role/roleEntity";
24
26
 
25
27
  describe("SaveMetadataKeysController", () => {
26
28
  describe("::exec", () => {
27
29
  let controller, account, apiClientOptions;
28
30
 
29
31
  beforeEach(async() => {
30
- account = new AccountEntity(defaultAccountDto());
32
+ account = new AccountEntity(defaultAccountDto({
33
+ role_name: RoleEntity.ROLE_ADMIN
34
+ }));
31
35
  apiClientOptions = defaultApiClientOptions();
32
36
  controller = new SaveMetadataKeysController(null, null, apiClientOptions, account);
33
37
  // flush account related storage before each.
@@ -41,6 +45,10 @@ describe("SaveMetadataKeysController", () => {
41
45
  // mock metadata keys settings api service.
42
46
  jest.spyOn(controller.saveMetadaSettingsService.metadataKeysSettingsApiService, "save")
43
47
  .mockImplementation(settings => settings.toDto());
48
+ jest.spyOn(controller.saveMetadaSettingsService.findMetadataSettingsService.metadataKeysSettingsApiService, "findSettings")
49
+ .mockImplementation(() => defaultMetadataKeysSettingsDto());
50
+ // mock passphrase
51
+ jest.spyOn(controller.getPassphraseService, "getPassphrase").mockImplementationOnce(() => pgpKeys.ada.passphrase);
44
52
  // spy on local storage service
45
53
  jest.spyOn(controller.saveMetadaSettingsService.metadataKeysSettingsLocalStorage, "set");
46
54
 
@@ -53,8 +61,33 @@ describe("SaveMetadataKeysController", () => {
53
61
  .toHaveBeenCalledWith(new MetadataKeysSettingsEntity(metadataKeysSettingsDto));
54
62
  });
55
63
 
64
+ it("saves metadata keys settings and update the local storage with it when go back from zero knowledge to user friendly mode.", async() => {
65
+ expect.assertions(3);
66
+
67
+ const metadataKeysSettingsDto = defaultMetadataKeysSettingsDto();
68
+ // mock metadata keys settings api service.
69
+ jest.spyOn(controller.saveMetadaSettingsService.metadataKeysSettingsApiService, "save")
70
+ .mockImplementation(settings => settings.toDto());
71
+ jest.spyOn(controller.saveMetadaSettingsService.findMetadataSettingsService.metadataKeysSettingsApiService, "findSettings")
72
+ .mockImplementation(() => defaultMetadataKeysSettingsDto());
73
+ // spy on local storage service
74
+ jest.spyOn(controller.saveMetadaSettingsService.metadataKeysSettingsLocalStorage, "set");
75
+ // mock passphrase
76
+ jest.spyOn(controller.getPassphraseService, "getPassphrase").mockImplementationOnce(() => pgpKeys.ada.passphrase);
77
+
78
+ const savedMetadataKeysSettings = await controller.exec(metadataKeysSettingsDto);
79
+
80
+ expect(savedMetadataKeysSettings).toBeInstanceOf(MetadataKeysSettingsEntity);
81
+ expect(controller.saveMetadaSettingsService.metadataKeysSettingsApiService.save)
82
+ .toHaveBeenCalledWith(new MetadataKeysSettingsEntity(metadataKeysSettingsDto));
83
+ expect(controller.saveMetadaSettingsService.metadataKeysSettingsLocalStorage.set)
84
+ .toHaveBeenCalledWith(new MetadataKeysSettingsEntity(metadataKeysSettingsDto));
85
+ });
86
+
56
87
  it("throws if the parameters are not valid.", async() => {
57
88
  expect.assertions(1);
89
+ // mock passphrase
90
+ jest.spyOn(controller.getPassphraseService, "getPassphrase").mockImplementationOnce(() => pgpKeys.ada.passphrase);
58
91
  await expect(() => controller.exec("invalid metadata keys settings entity", {}))
59
92
  .toThrowEntityValidationError("allow_usage_of_personal_keys", "required");
60
93
  });
@@ -57,7 +57,7 @@ class ShareMetadataKeyPrivateController {
57
57
 
58
58
  const passphrase = await this.getPassphraseService.getPassphrase(this.worker);
59
59
  await this.verifyOrTrustMetadataKeyService.verifyTrustedOrTrustNewMetadataKey(passphrase);
60
- await this.shareMetadataKeyPrivateService.shareMissing(userId, passphrase);
60
+ await this.shareMetadataKeyPrivateService.shareOneMissing(userId, passphrase);
61
61
  }
62
62
  }
63
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.5.0
13
+ */
14
+
15
+ import ScimSettingsEntity from "passbolt-styleguide/src/shared/models/entity/scimSettings/scimSettingsEntity";
16
+ import EnableScimSettingsService from "../../service/scimSettings/enableScimSettingsService";
17
+
18
+ class CreateScimSettingsController {
19
+ /**
20
+ * @constructor
21
+ * @param {Worker} worker
22
+ * @param {string} requestId
23
+ * @param {ApiClientOptions} apiClientOptions the api client options
24
+ */
25
+ constructor(worker, requestId, apiClientOptions) {
26
+ this.worker = worker;
27
+ this.requestId = requestId;
28
+ this.enableScimSettingsService = new EnableScimSettingsService(apiClientOptions);
29
+ }
30
+
31
+ /**
32
+ * Controller executor.
33
+ * @returns {Promise<void>}
34
+ */
35
+ async _exec(data) {
36
+ try {
37
+ const result = await this.exec(data);
38
+ this.worker.port.emit(this.requestId, 'SUCCESS', result);
39
+ } catch (error) {
40
+ console.error(error);
41
+ this.worker.port.emit(this.requestId, 'ERROR', error);
42
+ }
43
+ }
44
+
45
+ /**
46
+ * Create SCIM settings.
47
+ * @param {Object} data
48
+ * @returns {Promise<*>} SCIM settings
49
+ */
50
+ async exec(data) {
51
+ const scimSettingForCreation = ScimSettingsEntity.createFromScimSettingsCreation(data);
52
+ return await this.enableScimSettingsService.enable(scimSettingForCreation);
53
+ }
54
+ }
55
+
56
+ export default CreateScimSettingsController;
@@ -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.5.0
13
+ */
14
+
15
+ import expect from "expect";
16
+ import CreateScimSettingsController from "./createScimSettingsController";
17
+ import ScimSettingsEntity from "passbolt-styleguide/src/shared/models/entity/scimSettings/scimSettingsEntity";
18
+ import {defaultApiClientOptions} from "passbolt-styleguide/src/shared/lib/apiClient/apiClientOptions.test.data";
19
+ import {defaultScimSettingsDto, scimSettingsWithoutSecretTokenDto} from "../../service/api/scimSettings/scimSettingsApiService.test.data";
20
+ import EntityValidationError from "passbolt-styleguide/src/shared/models/entity/abstract/entityValidationError";
21
+
22
+ describe("CreateScimSettingsController", () => {
23
+ let apiClientOptions, controller;
24
+
25
+ beforeEach(() => {
26
+ apiClientOptions = defaultApiClientOptions();
27
+ controller = new CreateScimSettingsController(null, null, apiClientOptions);
28
+ });
29
+
30
+ describe("::exec", () => {
31
+ it("should create SCIM settings", async() => {
32
+ expect.assertions(3);
33
+ const scimSettingsDto = defaultScimSettingsDto();
34
+ const scimSettingsEntity = new ScimSettingsEntity(scimSettingsDto);
35
+ jest.spyOn(controller.enableScimSettingsService, "enable").mockResolvedValue(scimSettingsEntity);
36
+
37
+ const result = await controller.exec(scimSettingsDto);
38
+
39
+ expect(result).toEqual(scimSettingsEntity);
40
+ expect(controller.enableScimSettingsService.enable).toHaveBeenCalledWith(scimSettingsEntity);
41
+ expect(result).toBeInstanceOf(ScimSettingsEntity);
42
+ });
43
+
44
+ it("should handle errors when creating SCIM settings", async() => {
45
+ expect.assertions(2);
46
+ const error = new Error("Failed to create SCIM settings");
47
+ jest.spyOn(controller.enableScimSettingsService, "enable").mockRejectedValue(error);
48
+
49
+ await expect(controller.exec(defaultScimSettingsDto())).rejects.toThrow(error);
50
+ expect(controller.enableScimSettingsService.enable).toHaveBeenCalled();
51
+ });
52
+
53
+ it("should throw error if secret_token is missing", async() => {
54
+ expect.assertions(2);
55
+ jest.spyOn(controller.enableScimSettingsService, "enable");
56
+
57
+ const scimSettingsDto = scimSettingsWithoutSecretTokenDto();
58
+ delete scimSettingsDto.secret_token;
59
+
60
+ await expect(controller.exec(scimSettingsDto)).rejects.toThrowError(EntityValidationError);
61
+ expect(controller.enableScimSettingsService.enable).not.toHaveBeenCalled();
62
+ });
63
+ });
64
+ });
@@ -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.5.0
13
+ */
14
+
15
+ import DisableScimSettingsService from "../../service/scimSettings/disableScimSettingsService";
16
+ import {assertUuid} from "../../utils/assertions";
17
+
18
+ class DisableScimSettingsController {
19
+ /**
20
+ * @constructor
21
+ * @param {Worker} worker
22
+ * @param {string} requestId
23
+ * @param {ApiClientOptions} apiClientOptions the api client options
24
+ */
25
+ constructor(worker, requestId, apiClientOptions) {
26
+ this.worker = worker;
27
+ this.requestId = requestId;
28
+ this.disableScimSettingsService = new DisableScimSettingsService(apiClientOptions);
29
+ }
30
+
31
+ /**
32
+ * Controller executor.
33
+ * @returns {Promise<void>}
34
+ */
35
+ async _exec(id) {
36
+ try {
37
+ const result = await this.exec(id);
38
+ this.worker.port.emit(this.requestId, 'SUCCESS', result);
39
+ } catch (error) {
40
+ console.error(error);
41
+ this.worker.port.emit(this.requestId, 'ERROR', error);
42
+ }
43
+ }
44
+
45
+ /**
46
+ * Disable SCIM settings.
47
+ * @param {string} id
48
+ * @returns {Promise<*>} SCIM settings
49
+ */
50
+ async exec(id) {
51
+ assertUuid(id);
52
+ return this.disableScimSettingsService.disable(id);
53
+ }
54
+ }
55
+
56
+ export default DisableScimSettingsController;
@@ -0,0 +1,51 @@
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.5.0
13
+ */
14
+
15
+ import expect from "expect";
16
+ import DisableScimSettingsController from "./disableScimSettingsController";
17
+ import {defaultApiClientOptions} from "passbolt-styleguide/src/shared/lib/apiClient/apiClientOptions.test.data";
18
+ import {v4 as uuidv4} from "uuid";
19
+
20
+ describe("DisableScimSettingsController", () => {
21
+ let apiClientOptions, controller;
22
+
23
+ beforeEach(() => {
24
+ apiClientOptions = defaultApiClientOptions();
25
+ controller = new DisableScimSettingsController(null, null, apiClientOptions);
26
+ });
27
+
28
+ describe("::exec", () => {
29
+ it("should disable SCIM settings", async() => {
30
+ expect.assertions(2);
31
+ const id = uuidv4();
32
+ const expectedResult = {success: true};
33
+ jest.spyOn(controller.disableScimSettingsService, "disable").mockResolvedValue(expectedResult);
34
+
35
+ const result = await controller.exec(id);
36
+
37
+ expect(result).toEqual(expectedResult);
38
+ expect(controller.disableScimSettingsService.disable).toHaveBeenCalledWith(id);
39
+ });
40
+
41
+ it("should handle errors when disabling SCIM settings", async() => {
42
+ expect.assertions(2);
43
+ const error = new Error("Failed to disable SCIM settings");
44
+ const id = uuidv4();
45
+ jest.spyOn(controller.disableScimSettingsService, "disable").mockRejectedValue(error);
46
+
47
+ await expect(controller.exec(id)).rejects.toThrow(error);
48
+ expect(controller.disableScimSettingsService.disable).toHaveBeenCalledWith(id);
49
+ });
50
+ });
51
+ });
@@ -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.5.0
13
+ */
14
+
15
+ import FindScimSettingsService from "../../service/scimSettings/findScimSettingsService";
16
+
17
+ class FindScimSettingsController {
18
+ /**
19
+ * @constructor
20
+ * @param {Worker} worker
21
+ * @param {string} requestId
22
+ * @param {ApiClientOptions} apiClientOptions the api client options
23
+ */
24
+ constructor(worker, requestId, apiClientOptions) {
25
+ this.worker = worker;
26
+ this.requestId = requestId;
27
+ this.findScimSettingsService = new FindScimSettingsService(apiClientOptions);
28
+ }
29
+
30
+ /**
31
+ * Controller executor.
32
+ * @returns {Promise<void>}
33
+ */
34
+ async _exec() {
35
+ try {
36
+ const result = await this.exec();
37
+ this.worker.port.emit(this.requestId, 'SUCCESS', result);
38
+ } catch (error) {
39
+ console.error(error);
40
+ this.worker.port.emit(this.requestId, 'ERROR', error);
41
+ }
42
+ }
43
+
44
+ /**
45
+ * Find SCIM settings.
46
+ * @returns {Promise<*>} SCIM settings
47
+ */
48
+ async exec() {
49
+ return await this.findScimSettingsService.get();
50
+ }
51
+ }
52
+
53
+ export default FindScimSettingsController;
@@ -0,0 +1,49 @@
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.5.0
13
+ */
14
+
15
+ import expect from "expect";
16
+ import FindScimSettingsController from "./findScimSettingsController";
17
+ import ScimSettingsEntity from "passbolt-styleguide/src/shared/models/entity/scimSettings/scimSettingsEntity";
18
+ import {defaultApiClientOptions} from "passbolt-styleguide/src/shared/lib/apiClient/apiClientOptions.test.data";
19
+ import {defaultScimSettingsDto} from "../../service/api/scimSettings/scimSettingsApiService.test.data";
20
+
21
+ describe("FindScimSettingsController", () => {
22
+ let apiClientOptions, controller;
23
+
24
+ beforeEach(() => {
25
+ apiClientOptions = defaultApiClientOptions();
26
+ controller = new FindScimSettingsController(null, null, apiClientOptions);
27
+ });
28
+
29
+ describe("::exec", () => {
30
+ it("should find SCIM settings", async() => {
31
+ const scimSettingsDto = defaultScimSettingsDto();
32
+ const scimSettingsEntity = new ScimSettingsEntity(scimSettingsDto);
33
+ jest.spyOn(controller.findScimSettingsService, "get").mockResolvedValue(scimSettingsEntity);
34
+
35
+ const result = await controller.exec();
36
+
37
+ expect(result).toEqual(scimSettingsEntity);
38
+ expect(controller.findScimSettingsService.get).toHaveBeenCalled();
39
+ });
40
+
41
+ it("should handle errors when finding SCIM settings", async() => {
42
+ const error = new Error("Failed to find SCIM settings");
43
+ jest.spyOn(controller.findScimSettingsService, "get").mockRejectedValue(error);
44
+
45
+ await expect(controller.exec()).rejects.toThrow(error);
46
+ expect(controller.findScimSettingsService.get).toHaveBeenCalled();
47
+ });
48
+ });
49
+ });
@@ -0,0 +1,60 @@
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.5.0
13
+ */
14
+
15
+ import ScimSettingsEntity from "passbolt-styleguide/src/shared/models/entity/scimSettings/scimSettingsEntity";
16
+ import UpdateScimSettingsService from "../../service/scimSettings/updateScimSettingsService";
17
+ import {assertUuid} from "../../utils/assertions";
18
+
19
+ class UpdateScimSettingsController {
20
+ /**
21
+ * @constructor
22
+ * @param {Worker} worker
23
+ * @param {string} requestId
24
+ * @param {ApiClientOptions} apiClientOptions the api client options
25
+ */
26
+ constructor(worker, requestId, apiClientOptions) {
27
+ this.worker = worker;
28
+ this.requestId = requestId;
29
+ this.updateScimSettingsService = new UpdateScimSettingsService(apiClientOptions);
30
+ }
31
+
32
+ /**
33
+ * Controller executor.
34
+ * @returns {Promise<void>}
35
+ */
36
+ async _exec(id, data) {
37
+ try {
38
+ const result = await this.exec(id, data);
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
+ * Update SCIM settings.
48
+ * @param {string} id
49
+ * @param {Object} data
50
+ * @returns {Promise<*>} SCIM settings
51
+ */
52
+ async exec(id, data) {
53
+ assertUuid(id);
54
+
55
+ const scimSettingForUpdating = ScimSettingsEntity.createFromScimSettingsUpdate(data);
56
+ return await this.updateScimSettingsService.update(id, scimSettingForUpdating);
57
+ }
58
+ }
59
+
60
+ export default UpdateScimSettingsController;