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.
- package/CHANGELOG.md +14 -1
- package/RELEASE_NOTES.md +10 -75
- package/doc/browser-extension-class-diagram.md +104 -24
- package/package.json +9 -4
- package/src/all/background_page/controller/accountRecovery/accountRecoveryGenerateOrganizationKeyController.js +3 -12
- package/src/all/background_page/controller/crypto/validatePrivateGpgKeySetupController.js +4 -4
- package/src/all/background_page/controller/setup/generateSetupKeyPairController.js +15 -6
- package/src/all/background_page/controller/setup/generateSetupKeyPairController.test.js +40 -0
- package/src/all/background_page/model/entity/gpgkey/generate/generateGpgKeyPairOptionsEntity.js +143 -41
- package/src/all/background_page/model/entity/gpgkey/generate/generateGpgKeyPairOptionsEntity.test.js +216 -54
- package/src/all/background_page/model/entity/organizationSettings/organizationSettingsEntity.test.data.js +5 -0
- package/src/all/background_page/service/accountRecovery/validateOrganizationPublicKeyService.js +2 -2
- package/src/all/background_page/service/api/accountRecovery/validateAccountRecoveryOrganizationPrivateKeyService.js +1 -0
- package/src/all/background_page/service/api/userKeyPolicies/userKeyPoliciesSettingsApiService.js +52 -0
- package/src/all/background_page/service/api/userKeyPolicies/userKeyPoliciesSettingsApiService.test.js +69 -0
- package/src/all/background_page/service/crypto/generateGpgKeyPairService.js +2 -1
- package/src/all/background_page/service/userKeyPolicies/findUserKeyPoliciesSettingsService.js +59 -0
- package/src/all/background_page/service/userKeyPolicies/findUserKeyPoliciesSettingsService.test.js +123 -0
- package/src/chrome/manifest.json +1 -1
- package/src/chrome-mv3/manifest.json +1 -1
- package/src/firefox/manifest.json +1 -1
- 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.
|
|
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=
|
|
1
|
+
Song: https://www.youtube.com/watch?v=Nbav4oWMqEY
|
|
2
2
|
|
|
3
|
-
|
|
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
|
-
|
|
5
|
+
The release also includes fixes for several bugs reported by the community after the major v5 redesign.
|
|
6
6
|
|
|
7
|
-
|
|
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-
|
|
17
|
-
|
|
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-
|
|
45
|
-
- PB-
|
|
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
|
-
###
|
|
70
|
-
- PB-
|
|
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
|
-
-
|
|
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()
|
|
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.
|
|
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.
|
|
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
|
-
|
|
62
|
-
|
|
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
|
-
|
|
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 ===
|
|
79
|
-
if (keyInfo.length < GenerateGpgKeyPairOptionsEntity.
|
|
80
|
-
throw new Error(i18n.t("An RSA key should have a length of {{size}} bits minimum.", {size: GenerateGpgKeyPairOptionsEntity.
|
|
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}
|
|
61
|
+
* @param {GenerateKeyPairPassphraseDto} generateGpgKeyDto
|
|
59
62
|
* @returns {Promise<void>}
|
|
60
63
|
*/
|
|
61
|
-
async exec(
|
|
64
|
+
async exec(generateGpgKeyDto) {
|
|
62
65
|
this.temporaryAccount = await FindAccountTemporaryService.exec(this.worker.port._port.name);
|
|
63
|
-
const generateGpgKeyPairOptionsEntity = await this._buildGenerateKeyPairOptionsEntity(
|
|
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 =
|
|
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
|
-
|
|
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);
|