passbolt-browser-extension 5.1.0 → 5.1.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 (22) hide show
  1. package/CHANGELOG.md +14 -1
  2. package/RELEASE_NOTES.md +10 -75
  3. package/doc/browser-extension-class-diagram.md +104 -24
  4. package/package.json +9 -4
  5. package/src/all/background_page/controller/accountRecovery/accountRecoveryGenerateOrganizationKeyController.js +3 -12
  6. package/src/all/background_page/controller/crypto/validatePrivateGpgKeySetupController.js +4 -4
  7. package/src/all/background_page/controller/setup/generateSetupKeyPairController.js +15 -6
  8. package/src/all/background_page/controller/setup/generateSetupKeyPairController.test.js +40 -0
  9. package/src/all/background_page/model/entity/gpgkey/generate/generateGpgKeyPairOptionsEntity.js +143 -41
  10. package/src/all/background_page/model/entity/gpgkey/generate/generateGpgKeyPairOptionsEntity.test.js +216 -54
  11. package/src/all/background_page/model/entity/organizationSettings/organizationSettingsEntity.test.data.js +5 -0
  12. package/src/all/background_page/service/accountRecovery/validateOrganizationPublicKeyService.js +2 -2
  13. package/src/all/background_page/service/api/accountRecovery/validateAccountRecoveryOrganizationPrivateKeyService.js +1 -0
  14. package/src/all/background_page/service/api/userKeyPolicies/userKeyPoliciesSettingsApiService.js +52 -0
  15. package/src/all/background_page/service/api/userKeyPolicies/userKeyPoliciesSettingsApiService.test.js +69 -0
  16. package/src/all/background_page/service/crypto/generateGpgKeyPairService.js +2 -1
  17. package/src/all/background_page/service/userKeyPolicies/findUserKeyPoliciesSettingsService.js +59 -0
  18. package/src/all/background_page/service/userKeyPolicies/findUserKeyPoliciesSettingsService.test.js +123 -0
  19. package/src/chrome/manifest.json +1 -1
  20. package/src/chrome-mv3/manifest.json +1 -1
  21. package/src/firefox/manifest.json +1 -1
  22. package/src/safari/manifest.json +1 -1
package/CHANGELOG.md CHANGED
@@ -4,6 +4,18 @@ This project adheres to [Semantic Versioning](http://semver.org/).
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [5.1.1] - 2025-05-21
8
+
9
+ ### Added
10
+ - PB-41365 Support options for ECC Key generation
11
+
12
+ ### Fixed
13
+ - PB-41760 On some conditions, scrollbars can appear and break the design
14
+ - PB-42561 The folder tree caret when scrolling appeared in the wrong orientation
15
+
16
+ ### Security
17
+ - PB-42613 Upgrade browser extension OpenPGP.js to the latest version
18
+
7
19
  ## [5.1.0] - 2025-05-12
8
20
 
9
21
  ### Added
@@ -2153,7 +2165,8 @@ self registration settings option in the left-side bar
2153
2165
  - LU: Logged in user
2154
2166
 
2155
2167
  ## [4.12.0] - 2024-03-10
2156
- [Unreleased]: https://github.com/passbolt/passbolt_browser_extension/compare/v5.1.0...HEAD
2168
+ [Unreleased]: https://github.com/passbolt/passbolt_browser_extension/compare/v5.1.1...HEAD
2169
+ [5.1.1]: https://github.com/passbolt/passbolt_browser_extension/compare/v5.1.0...v5.1.1
2157
2170
  [5.1.0]: https://github.com/passbolt/passbolt_browser_extension/compare/v5.0.1...v5.1.0
2158
2171
  [5.0.1]: https://github.com/passbolt/passbolt_browser_extension/compare/v5.0.0...v5.0.1
2159
2172
  [5.0.0]: https://github.com/passbolt/passbolt_browser_extension/compare/v4.12.0...v5.0.0
package/RELEASE_NOTES.md CHANGED
@@ -1,84 +1,19 @@
1
- Song: https://www.youtube.com/watch?v=d9WHUTKMD8k
1
+ Song: https://www.youtube.com/watch?v=Nbav4oWMqEY
2
2
 
3
- The 5.1 release adds support for encrypted resource metadata features as an opt-in feature. Early adopters can turn it on, test real-world workflows and feed back improvements, while more cautious teams, or teams with a lot of custom integrations, can wait until they are ready.
3
+ Passbolt v5.1.1 is a security release that upgrades the OpenPGP.js library to address a recently discovered vulnerability. While the impact of this issue is minimal, OpenPGP.js is a cornerstone of the extension, so the update is essential.
4
4
 
5
- This is a major milestone for the product, further extending Passbolt’s security model to improve confidentiality for the contextual information surrounding credentials. This means that metadata such as names, login URLs, and similar fields are now also cryptographically protected. As is customary for high-risk security features, this implementation has been audited by security researchers from Cure53 with a public report publication coming soon.
5
+ The release also includes fixes for several bugs reported by the community after the major v5 redesign.
6
6
 
7
- To ensure a smooth and cautious rollout, the feature is released in beta with v5.1 and is scheduled for stable release in v5.2. If you want to know more about how to enable it and start testing, a blog article published shortly, will provide a step-by-step guidance on how to activate the feature and a deeper dive into what’s changed.
7
+ As always, thank you to everyone who provided bug reports and feedback, and a special thanks to the OpenPGP.js team for the timely heads-up and patch.
8
8
 
9
- Additionally, the password expiry feature is now enabled by default for new installations. This capability is considered a security best practice, helping organizations enforce rotation policies and mitigate risks associated with long-lived shared credentials. For existing instances, administrators can enable this feature manually from the administration workspace. To learn more, check out the blog article: [Passbolt’s New Automation of Shared Passwords Expiry](https://www.passbolt.com/blog/passbolts-new-automation-of-shared-passwords-expiry).
10
-
11
- As usual, this release also includes a few bug fixes and performance improvements, like a faster folder tree that handles 5,000+ folders for the ones that are running a tight ship.
12
-
13
- As always, thank you to our community for your feedback, contributions, and bug reports. A special thanks to the CakePHP maintainers for the fast post v5 upgrade support!
14
9
 
15
10
  ### Added
16
- - PB-41340 Add dedicated input to fix autofill on specific website
17
- - PB-41734 SPKD-1.1 Rename metadata private key getter/setter dataSignedByCurrentUser & ensure constructor pass options to its parent class to ensure validation can be disabled
18
- - PB-41735 SPKD-1.2 Verify the metadata public key entity fingerprint is equal to the armored key fingerprint in FindMetadataKeysService findAll
19
- - PB-41737 SPKD-1.3 Verify metadata private key data entity fingerprint with armored key fingerprint in DecryptMetadataPrivateKeysService decryptOne
20
- - PB-41738 SPKD-1.4 Assert metadata keys collection fingerprints public/private integrity in DecryptMetadataPrivateKeysService decryptAllFromMetadataKeysCollection
21
- - PB-41739 SPKD-1.5 Adapt DecryptMessageService.decrypt to return the raw OpenPGP decryption result, including signatures, without throwing an error when signature verification fails
22
- - PB-41740 SPKD-1.7 Implement findVerifiedSignatureForGpgKey in src/all/background_page/service/crypto/findSignatures utils to retrieve a signature for a given OpenPGP key
23
- - PB-41741 SPKD-1.8 Check current user signature when decrypting Metadata Private Key Data
24
- - PB-41742 SPKD-1.6 Implement ExternalGpgSignatureEntity to carry OpenPGP signature data
25
- - PB-41743 SPKD-1.9 Implement MetadataTrustedKeyEntity to carry the information relative to a trusted metadata key
26
- - PB-41744 SPKD-1.10 Implement TrustedMetadataKeyLocalStorage to support the persistence of the trusted metadata key
27
- - PB-41746 SPKD-2.1 Implement bext ConfirmMetadataKeyContentCodeService to request user to confirm trusted metadata keys changes
28
- - PB-41747 SPKD-2.2 Implement confirm metadata key event handler and dialog on the web application
29
- - PB-41748 SPKD-2.3 Implement confirm metadata key event handler and dialog on the quick application
30
- - PB-41749 SPKD-2.4 Implement GetMetadataTrustedKeyService get to retrieve the trusted metadata key from the local storage
31
- - PB-41753 SPKD-2.8 Implement VerifyOrTrustMetadataKeyService verifyTrustedOrTrustNewMetadataKey to verify that the current active metadata key is trusted or request the user to trust it
32
- - PB-41750 SPKD-2.5 Implement MetadataPrivateKeyApiService update to update a trusted metadata key on the API
33
- - PB-41751 SPKD-2.6 Implement UpdateMetadataKeyPrivateService update function to update a trusted metadata key
34
- - PB-41752 SPKD-2.7 Implement TrustMetadataKeyService trust to trust a new metadata key
35
- - PB-41847 SPKD-2.18 Add creator field to metadataKeyEntity test data
36
- - PB-41916 SPKD-2.19 Flush Metadata Keys Settings storage when a user is signed-out
37
- - PB-41918 SPKD-2.20 Adapt EncryptMessageService.encrypt so that it can sign a message with a specified date
38
- - PB-41919 SPKD-2.21 Adapt EncryptMetadataPrivateKeysService.encryptOne so that it can sign a message with a specified date
39
- - PB-41958 SPKD-2.10 Verify and trust metadata key prior to encrypt metadata
40
- - PB-41961 SPKD-2.21 Add in diagram TrustMetadataKeyService
41
- - PB-41962 SPKD-2.22 Add unit test and in the diagram for VerifyOrTrustMetadataKeyService
11
+ - PB-41365 Support options for ECC Key generation
12
+
42
13
 
43
14
  ### Fixed
44
- - PB-35383 refresh folders list after delete parent folder and keep items inside
45
- - PB-39607 metadata migration should encrypt metadata with user's key when encrypting a personal resource
46
- - PB-40181 The session keys cache items are missing modified field
47
- - PB-41296 on a fresh install + first login after setup (firefox + debian) going to the user workspace crashes as roles are not defined
48
- - PB-41304 import password errors (UAT required & fix)
49
- - PB-41305 clicking on folder parent in location of a resource in the right sidebar just close the panel
50
- - PB-41407 account recovery in user profile can crash when clicking on review
51
- - PB-41638 Hide administration workspace shifter on desktop app
52
- - PB-41716 Permalink when paste in url and local storage is not loaded yet
53
- - PB-41753 safer key public distribution confirmation in quickaccess
54
- - PB-41776 password input with show icon can display a broken UI
55
- - PB-41841 user workspace displays a blank screen when accessing a user's URL directly from the browser
56
- - PB-41846 Other type resource dialog TOTP does not open a TOTP but a password + totp
57
- - PB-42030 'where to find my account kit' does no open the browser for help
58
- - PB-42033 design of security token in input field could be broken with some characters
59
- - PB-42046 set empty translations with their default string
60
- - PB-42105 import of resources process always uses shared metadata key instead of personal key
61
- - PB-42106 throw an error while decrypting resource metadata if the decrypted metadata object type is not valid
62
- - PB-41378 UI minor bug: multiple resource select, right sidebar cropped
63
- - PB-41435 Display the folder context menu above the “More” button
64
- - PB-41551 Show a disabled style when dragging an item over an invalid drop target
65
- - PB-41550 Refresh the folder tree after the folder‑hierarchy cache updates (order issue)
66
- - PB-41627 UI bug: Note formatting in the right sidebar
67
- - PB-41759 Browser extension should enforce object_type on metadata of resource creation / edition
15
+ - PB-41760 On some conditions, scrollbars can appear and break the design
16
+ - PB-42561 The folder tree caret when scrolling appeared in the wrong orientation
68
17
 
69
- ### Maintenance
70
- - PB-38199 Update administration page Role-Based Access Control save behavior
71
- - PB-41346 Remove mfa settings screens from API
72
- - PB-41366 ECC-1.1 Update browser extension outdated OpenPGP.js to version 6
73
- - PB-41384 Upgrade vulnerable lib on bext 'image-size'
74
- - PB-41385 2.1 Display react list for folder tree
75
- - PB-41386 2.2 Folders updated should be refreshed in the folder tree
76
- - PB-41387 2.3 Navigate to a folder form route should scroll the folder tree to see the selected folder
77
- - PB-41388 2.4 Update the padding according to the depth of the folder
78
- - PB-41414 WP4-14.2 Migrate import account kit screen
79
- - PB-41646 UI adjustment: All tables should have a 0.8rem gap
80
- - PB-41648 UI adjustment: Name column size in grid should be large by default
81
- - PB-41647 UI adjustment: All dialog & setting primary should have a regular font weight
82
- - PB-41653 UI adjustment: Grid select column, padding left & right 1.6rem
83
- - PB-41709 Add activity diagram to verify metadata keys
84
- - PB-41720 Add licence on SVG in the folder svg on the styleguide
18
+ ### Security
19
+ - PB-42613 Upgrade browser extension OpenPGP.js to the latest version
@@ -529,7 +529,7 @@ classDiagram
529
529
  -string props.expires
530
530
  -string props.created
531
531
  -string props.algorithm
532
- -number props.length
532
+ -integer props.length
533
533
  -string props.curve
534
534
  -boolean props.private
535
535
  -boolean props.revoked
@@ -541,7 +541,7 @@ classDiagram
541
541
  +get isValid() boolean
542
542
  +get created() string
543
543
  +get algorithm() string
544
- +get length() number
544
+ +get length() integer
545
545
  +get curve() string
546
546
  +get revoked() boolean
547
547
  +get private() boolean
@@ -562,28 +562,6 @@ classDiagram
562
562
  +get created() string
563
563
  }
564
564
 
565
- class GpgkeyEntity {
566
- -uuid props.id
567
- -uuid props.user_id
568
- -string props.fingerprint
569
- -string props.armored_key
570
- -boolean props.deleted
571
- -string props.type
572
- -string props.uid
573
- -integer props.bits
574
- -string props.key_created
575
- -string props.expires
576
- -string props.created
577
- -string props.modified
578
- +get id() string
579
- +get userId() string
580
- +get armoredKey() string
581
- +get fingerprint() boolean
582
- +get created() string
583
- +get modified() string
584
- +get isDeleted() boolean
585
- }
586
-
587
565
  class GroupsUsersCollection {
588
566
  +getById(string id) GroupUserEntity
589
567
  +getGroupUserByUserId(string userId) GroupUserEntity
@@ -931,6 +909,99 @@ classDiagram
931
909
  }
932
910
  }
933
911
 
912
+ namespace GpgKeyNs {
913
+ %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
914
+ %% GpgKey controllers
915
+ %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
916
+
917
+ class GenerateSetupKeyPairController {
918
+ +exec(object generateGpgKeyDto) Promise
919
+ }
920
+
921
+ class AccountRecoveryGenerateOrganizationKeyController {
922
+ +exec(generateGpgKeyPairOptionsDto object) Promise~ExternalGpgKeyPairEntity~
923
+ }
924
+
925
+ %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
926
+ %% GpgKey services
927
+ %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
928
+
929
+ class FindUserKeyPoliciesSettingsService {
930
+ +findSettingsAsGuest(userId string, authenticationToken string) Promise~UserKeyPoliciesSettingsEntity~
931
+ }
932
+
933
+ %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
934
+ %% GpgKey models
935
+ %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
936
+
937
+ class UserKeyPoliciesSettingsApiService {
938
+ +findSettingsAsGuest(userId string, authenticationToken string) Promise~object~
939
+ }
940
+
941
+ class UserKeyPoliciesSettingsEntity {
942
+ -string props.preferred_key_type
943
+ -string props.source
944
+
945
+ +get preferredKeyType() string
946
+ +get source() string|null
947
+
948
+ +createFromDefault(data: object)$ UserKeyPoliciesSettingsEntity
949
+ }
950
+
951
+ class GenerateGpgKeyPairOptionsEntity {
952
+ -string props.preferred_key_type
953
+ -string props.source
954
+ -string props.name
955
+ -string props.email
956
+ -string props.passphrase
957
+ -string props.type
958
+ -integer props.keySize
959
+ -string props.curve
960
+ -integer props.date
961
+
962
+ +toGenerateOpenpgpKeyDto() object
963
+ +get userId() string
964
+ +get name() string
965
+ +get email() string
966
+ +get type() string
967
+ +get passphrase() string
968
+ +get curve() string|null
969
+ +get rsaBits() integer|null
970
+ +get date() Date
971
+ +createForUserKeyGeneration(apiGpgKeyType string, generateGpgKeyPairDto object)$ GenerateGpgKeyPairOptionsEntity
972
+ +createForOrkKeyGeneration(generateGpgKeyPairDto object)$ GenerateGpgKeyPairOptionsEntity
973
+ +get ENTITY_NAME() string
974
+ +get DEFAULT_RSA_KEY_SIZE() integer
975
+ +get DEFAULT_KEY_TYPE() string
976
+ +get DEFAULT_ECC_KEY_CURVE() string
977
+ +get KEY_TYPE_RSA() string
978
+ +get KEY_TYPE_ECC() string
979
+ +get KEY_CURVE_ED25519() string
980
+ }
981
+
982
+ class GpgkeyEntity {
983
+ -uuid props.id
984
+ -uuid props.user_id
985
+ -string props.fingerprint
986
+ -string props.armored_key
987
+ -boolean props.deleted
988
+ -string props.type
989
+ -string props.uid
990
+ -integer props.bits
991
+ -string props.key_created
992
+ -string props.expires
993
+ -string props.created
994
+ -string props.modified
995
+ +get id() string
996
+ +get userId() string
997
+ +get armoredKey() string
998
+ +get fingerprint() boolean
999
+ +get created() string
1000
+ +get modified() string
1001
+ +get isDeleted() boolean
1002
+ }
1003
+ }
1004
+
934
1005
  %% Resource controllers relationships
935
1006
  CreateResourceController*--CreateResourceService
936
1007
  %% CreateResourceController*--GetPassphraseService
@@ -1095,4 +1166,13 @@ classDiagram
1095
1166
  ShareResourceService*--ShareService
1096
1167
  %% Share models relationships.
1097
1168
  style ShareService fill:#DEE5D4
1169
+
1170
+ %% GpgKey controllers relationships
1171
+ GenerateSetupKeyPairController*--FindUserKeyPoliciesSettingsService
1172
+ GenerateSetupKeyPairController*--GenerateGpgKeyPairService
1173
+ GenerateSetupKeyPairController*--GenerateGpgKeyPairOptionsEntity
1174
+ AccountRecoveryGenerateOrganizationKeyController*--GenerateGpgKeyPairService
1175
+ AccountRecoveryGenerateOrganizationKeyController*--GenerateGpgKeyPairOptionsEntity
1176
+ %% GpgKey services relationships
1177
+ FindUserKeyPoliciesSettingsService*--UserKeyPoliciesSettingsApiService
1098
1178
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "passbolt-browser-extension",
3
- "version": "5.1.0",
3
+ "version": "5.1.1",
4
4
  "license": "AGPL-3.0",
5
5
  "copyright": "Copyright 2025 Passbolt SA",
6
6
  "description": "Passbolt web extension for the open source password manager for teams",
@@ -20,9 +20,9 @@
20
20
  "jssha": "~3.3.1",
21
21
  "kdbxweb": "2.1.1",
22
22
  "locutus": "~2.0.9",
23
- "openpgp": "6.1",
23
+ "openpgp": "^6.1.1",
24
24
  "papaparse": "^5.2.0",
25
- "passbolt-styleguide": "^5.1.2",
25
+ "passbolt-styleguide": "^5.1.3",
26
26
  "react": "17.0.2",
27
27
  "react-dom": "17.0.2",
28
28
  "secrets-passbolt": "github:passbolt/secrets.js#v2.0.1",
@@ -70,7 +70,12 @@
70
70
  "webpack-cli": "^5.1.4"
71
71
  },
72
72
  "overrides": {
73
- "image-size": "^2.0.2"
73
+ "image-size": "^2.0.2",
74
+ "i18next-parser": {
75
+ "cheerio": {
76
+ "undici": "6.21.2"
77
+ }
78
+ }
74
79
  },
75
80
  "scripts": {
76
81
  "build": "npx grunt build",
@@ -15,12 +15,6 @@ import GetGpgKeyCreationDateService from "../../service/crypto/getGpgKeyCreation
15
15
  import GenerateGpgKeyPairOptionsEntity from "../../model/entity/gpgkey/generate/generateGpgKeyPairOptionsEntity";
16
16
  import GenerateGpgKeyPairService from "../../service/crypto/generateGpgKeyPairService";
17
17
 
18
- /**
19
- * The account recovery organization key size.
20
- * @type {number}
21
- */
22
- const ACCOUNT_RECOVERY_ORGANIZATION_KEY_SIZE = 4096;
23
-
24
18
  /**
25
19
  * Controller related to the generation of the account recovery organization key
26
20
  */
@@ -58,14 +52,11 @@ class AccountRecoveryGenerateOrganizationKeyController {
58
52
  * @returns {Promise<ExternalGpgKeyPairEntity>}
59
53
  */
60
54
  async exec(generateGpgKeyPairOptionsDto = {}) {
61
- // Enforce the key size & type.
62
- const enforcedGenerateGpgKeyPairOptionsDto = {
63
- type: GenerateGpgKeyPairOptionsEntity.TYPE_RSA,
64
- keySize: ACCOUNT_RECOVERY_ORGANIZATION_KEY_SIZE,
55
+ generateGpgKeyPairOptionsDto = {
56
+ ...generateGpgKeyPairOptionsDto,
65
57
  date: await GetGpgKeyCreationDateService.getDate(this.apiClientOptions),
66
58
  };
67
- Object.assign(generateGpgKeyPairOptionsDto, enforcedGenerateGpgKeyPairOptionsDto);
68
- const generateKeyPairOptions = new GenerateGpgKeyPairOptionsEntity(generateGpgKeyPairOptionsDto);
59
+ const generateKeyPairOptions = GenerateGpgKeyPairOptionsEntity.createForOrkKeyGeneration(generateGpgKeyPairOptionsDto);
69
60
  return GenerateGpgKeyPairService.generateKeyPair(generateKeyPairOptions);
70
61
  }
71
62
  }
@@ -15,7 +15,7 @@ import {OpenpgpAssertion} from "../../utils/openpgp/openpgpAssertions";
15
15
  import i18n from "../../sdk/i18n";
16
16
  import GetGpgKeyInfoService from "../../service/crypto/getGpgKeyInfoService";
17
17
  import GenerateGpgKeyPairOptionsEntity from "../../model/entity/gpgkey/generate/generateGpgKeyPairOptionsEntity";
18
-
18
+ import {GPG_KEY_TYPE_RSA} from "passbolt-styleguide/src/shared/models/entity/gpgkey/gpgkeyEntity";
19
19
 
20
20
  class ValidatePrivateGpgKeySetupController {
21
21
  /**
@@ -75,9 +75,9 @@ class ValidatePrivateGpgKeySetupController {
75
75
  throw new Error(i18n.t("The private key should not have an expiry date."));
76
76
  }
77
77
 
78
- if (keyInfo.algorithm === GenerateGpgKeyPairOptionsEntity.TYPE_RSA) {
79
- if (keyInfo.length < GenerateGpgKeyPairOptionsEntity.DEFAULT_KEY_SIZE) {
80
- throw new Error(i18n.t("An RSA key should have a length of {{size}} bits minimum.", {size: GenerateGpgKeyPairOptionsEntity.DEFAULT_KEY_SIZE}));
78
+ if (keyInfo.algorithm === GPG_KEY_TYPE_RSA) {
79
+ if (keyInfo.length < GenerateGpgKeyPairOptionsEntity.DEFAULT_RSA_KEY_SIZE) {
80
+ throw new Error(i18n.t("An RSA key should have a length of {{size}} bits minimum.", {size: GenerateGpgKeyPairOptionsEntity.DEFAULT_RSA_KEY_SIZE}));
81
81
  }
82
82
  } else {
83
83
  if (!keyInfo.curve) {
@@ -17,6 +17,8 @@ import GenerateGpgKeyPairService from "../../service/crypto/generateGpgKeyPairSe
17
17
  import {OpenpgpAssertion} from "../../utils/openpgp/openpgpAssertions";
18
18
  import AccountTemporarySessionStorageService from "../../service/sessionStorage/accountTemporarySessionStorageService";
19
19
  import FindAccountTemporaryService from "../../service/account/findAccountTemporaryService";
20
+ import FindUserKeyPoliciesSettingsService
21
+ from "../../service/userKeyPolicies/findUserKeyPoliciesSettingsService";
20
22
 
21
23
  /**
22
24
  * @typedef {({passphrase: string})} GenerateKeyPairPassphraseDto
@@ -35,6 +37,7 @@ class GenerateSetupKeyPairController {
35
37
  this.apiClientOptions = apiClientOptions;
36
38
  // The temporary account stored in the session storage
37
39
  this.temporaryAccount = null;
40
+ this.findUserKeyPoliciesSettingsService = new FindUserKeyPoliciesSettingsService(apiClientOptions);
38
41
  }
39
42
 
40
43
  /**
@@ -55,12 +58,12 @@ class GenerateSetupKeyPairController {
55
58
  /**
56
59
  * Generate a key pair and associate to the account being set up.
57
60
  *
58
- * @param {GenerateKeyPairPassphraseDto} passphraseDto
61
+ * @param {GenerateKeyPairPassphraseDto} generateGpgKeyDto
59
62
  * @returns {Promise<void>}
60
63
  */
61
- async exec(passphraseDto) {
64
+ async exec(generateGpgKeyDto) {
62
65
  this.temporaryAccount = await FindAccountTemporaryService.exec(this.worker.port._port.name);
63
- const generateGpgKeyPairOptionsEntity = await this._buildGenerateKeyPairOptionsEntity(passphraseDto.passphrase);
66
+ const generateGpgKeyPairOptionsEntity = await this._buildGenerateKeyPairOptionsEntity(generateGpgKeyDto.passphrase);
64
67
  const keyPair = await GenerateGpgKeyPairService.generateKeyPair(generateGpgKeyPairOptionsEntity);
65
68
  const generatedPublicKey = await OpenpgpAssertion.readKeyOrFail(keyPair.publicKey.armoredKey);
66
69
 
@@ -68,7 +71,7 @@ class GenerateSetupKeyPairController {
68
71
  this.temporaryAccount.account.userPrivateArmoredKey = keyPair.privateKey.armoredKey;
69
72
  this.temporaryAccount.account.userPublicArmoredKey = keyPair.publicKey.armoredKey;
70
73
  // The passphrase will be later use to sign in the user.
71
- this.temporaryAccount.passphrase = passphraseDto.passphrase;
74
+ this.temporaryAccount.passphrase = generateGpgKeyDto.passphrase;
72
75
  // Update all data in the temporary account stored
73
76
  await AccountTemporarySessionStorageService.set(this.temporaryAccount);
74
77
  }
@@ -82,12 +85,18 @@ class GenerateSetupKeyPairController {
82
85
  * @private
83
86
  */
84
87
  async _buildGenerateKeyPairOptionsEntity(passphrase) {
85
- return new GenerateGpgKeyPairOptionsEntity({
88
+ const userId = this.temporaryAccount.account.userId;
89
+ const authenticationToken = this.temporaryAccount.account.authenticationTokenToken;
90
+ const userKeyPoliciesSettings = await this.findUserKeyPoliciesSettingsService.findSettingsAsGuest(userId, authenticationToken);
91
+
92
+ const generateKeyPairOptionsDto = {
86
93
  name: `${this.temporaryAccount.account.firstName} ${this.temporaryAccount.account.lastName}`,
87
94
  email: this.temporaryAccount.account.username,
88
95
  passphrase: passphrase,
89
96
  date: await GetGpgKeyCreationDateService.getDate(this.apiClientOptions),
90
- });
97
+ };
98
+
99
+ return GenerateGpgKeyPairOptionsEntity.createForUserKeyGeneration(userKeyPoliciesSettings, generateKeyPairOptionsDto);
91
100
  }
92
101
  }
93
102
 
@@ -23,6 +23,8 @@ import {defaultApiClientOptions} from "passbolt-styleguide/src/shared/lib/apiCli
23
23
  import AccountTemporarySessionStorageService from "../../service/sessionStorage/accountTemporarySessionStorageService";
24
24
  import {v4 as uuidv4} from "uuid";
25
25
  import AccountTemporaryEntity from "../../model/entity/account/accountTemporaryEntity";
26
+ import UserKeyPoliciesSettingsEntity from "passbolt-styleguide/src/shared/models/entity/userKeyPolicies/UserKeyPoliciesSettingsEntity";
27
+ import {defaultUserKeyPoliciesSettingsDto} from "passbolt-styleguide/src/shared/models/entity/userKeyPolicies/UserKeyPoliciesSettingsEntity.test.data";
26
28
 
27
29
  describe("GenerateSetupKeyPairController", () => {
28
30
  describe("GenerateSetupKeyPairController::exec", () => {
@@ -101,6 +103,44 @@ describe("GenerateSetupKeyPairController", () => {
101
103
  expect(expectedAccount.passphrase).toStrictEqual(generateKeyPairDto.passphrase);
102
104
  }, 10000);
103
105
 
106
+ it("Should generate an ECC gpg key pair and update the account accordingly.", async() => {
107
+ expect.assertions(11);
108
+ await MockExtension.withConfiguredAccount();
109
+ const generateKeyPairDto = {passphrase: "What a great passphrase!"};
110
+ const workerId = uuidv4();
111
+ const setupAccountDto = startAccountSetupDto();
112
+ const temporaryAccountEntity = new AccountTemporaryEntity({account: setupAccountDto, worker_id: workerId});
113
+ await AccountTemporarySessionStorageService.set(temporaryAccountEntity);
114
+ const controller = new GenerateSetupKeyPairController({port: {_port: {name: workerId}}}, null, defaultApiClientOptions());
115
+ jest.spyOn(controller.findUserKeyPoliciesSettingsService, "findSettingsAsGuest").mockImplementation(() => new UserKeyPoliciesSettingsEntity(defaultUserKeyPoliciesSettingsDto()));
116
+
117
+ await controller.exec(generateKeyPairDto);
118
+ const account = (await AccountTemporarySessionStorageService.get(workerId)).account;
119
+ const accountPublicKey = await OpenpgpAssertion.readKeyOrFail(account.userPublicArmoredKey);
120
+ const accountPrivateKey = await OpenpgpAssertion.readKeyOrFail(account.userPrivateArmoredKey);
121
+ const publicKeyInfo = await GetGpgKeyInfoService.getKeyInfo(accountPublicKey);
122
+ const privateKeyInfo = await GetGpgKeyInfoService.getKeyInfo(accountPrivateKey);
123
+
124
+ const expectedUserIds = [{
125
+ name: `${account.firstName} ${account.lastName}`,
126
+ email: account.username
127
+ }];
128
+ expect(privateKeyInfo.fingerprint).toBe(publicKeyInfo.fingerprint);
129
+ expect(publicKeyInfo.private).toBe(false);
130
+ expect(privateKeyInfo.private).toBe(true);
131
+ expect(publicKeyInfo.length).toBe(256);
132
+ expect(privateKeyInfo.length).toBe(256);
133
+ expect(privateKeyInfo.userIds).toStrictEqual(expectedUserIds);
134
+ expect(privateKeyInfo.algorithm).toStrictEqual("eddsa");
135
+ expect(publicKeyInfo.algorithm).toStrictEqual("eddsa");
136
+ expect(publicKeyInfo.curve).toStrictEqual("ed25519");
137
+ expect(publicKeyInfo.curve).toStrictEqual("ed25519");
138
+
139
+ const userPrivateKey = await OpenpgpAssertion.readKeyOrFail(account.userPrivateArmoredKey);
140
+ const decryptedPrivateKey = await DecryptPrivateKeyService.decrypt(userPrivateKey, generateKeyPairDto.passphrase);
141
+ expect(decryptedPrivateKey).not.toBeNull();
142
+ }, 10000);
143
+
104
144
  it("Should raise an error if no account has been found.", async() => {
105
145
  const controller = new GenerateSetupKeyPairController({port: {_port: {name: "test"}}}, null, defaultApiClientOptions());
106
146
  expect.assertions(1);