passbolt-browser-extension 5.10.3 → 5.11.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/.gitlab-ci/jobs/publish.yml +11 -1
- package/.gitlab-ci/scripts/bin/publish_npm.sh +1 -5
- package/.pre-commit-config.yaml +5 -0
- package/CHANGELOG.md +49 -0
- package/RELEASE_NOTES.md +78 -104
- package/build-safari-extension/Passbolt-Safari-Extension/Passbolt - password manager Extension/services/fetch/fetchService.swift +90 -2
- package/eslint.config.mjs +0 -6
- package/package.json +11 -13
- package/src/all/background_page/controller/auth/authLogoutController.js +11 -2
- package/src/all/background_page/controller/auth/authLogoutController.test.js +14 -5
- package/src/all/background_page/controller/group/groupCreateController.js +58 -0
- package/src/all/background_page/controller/group/groupCreateController.test.js +67 -0
- package/src/all/background_page/controller/tab/openResourceUriTabController.js +60 -0
- package/src/all/background_page/controller/tab/openResourceUriTabController.test.js +108 -0
- package/src/all/background_page/error/timeoutError.js +23 -0
- package/src/all/background_page/event/appEvents.js +12 -0
- package/src/all/background_page/event/groupEvents.js +3 -10
- package/src/all/background_page/model/entity/resource/resourceEntity.js +1 -1
- package/src/all/background_page/model/entity/sso/ssoLoginUrlEntity.js +2 -0
- package/src/all/background_page/model/entity/sso/ssoLoginUrlEntity.test.js +2 -0
- package/src/all/background_page/model/group/groupModel.js +0 -15
- package/src/all/background_page/service/api/group/groupApiService.js +6 -3
- package/src/all/background_page/service/auth/authVerifyLoginChallengeService.test.js +1 -1
- package/src/all/background_page/service/auth/decryptUserAuthTokenService.js +2 -2
- package/src/all/background_page/service/group/createGroupService.js +48 -0
- package/src/all/background_page/service/group/createGroupService.test.js +68 -0
- package/src/all/background_page/service/tab/tabService.js +37 -5
- package/src/all/background_page/service/tab/tabService.test.js +132 -1
- package/src/all/background_page/utils/format/formDataUtils.js +0 -16
- package/src/all/background_page/utils/format/formDataUtils.test.data.js +0 -7
- package/src/all/background_page/utils/format/formDataUtils.test.js +1 -39
- package/src/all/background_page/utils/promise/promiseTimeoutService.js +3 -1
- package/src/all/background_page/vendors/locutus/stripslashes.js +25 -0
- package/src/all/background_page/vendors/locutus/stripslashes.test.js +64 -0
- package/src/all/background_page/vendors/locutus/urldecode.js +21 -0
- package/src/all/background_page/vendors/locutus/urldecode.test.js +64 -0
- package/src/all/background_page/vendors/locutus/urlencode.test.data.js +23 -0
- package/src/all/contentScripts/js/app/App.js +11 -0
- package/src/all/contentScripts/js/app/Login.js +11 -0
- package/src/chrome/manifest.json +1 -1
- package/src/chrome-mv3/manifest.json +1 -1
- package/src/firefox/manifest.json +5 -2
- package/src/safari/common/polyfill/fetchPolyfill.js +1 -1
- package/src/safari/common/polyfill/fetchPolyfill.test.js +8 -4
- package/src/safari/manifest.json +1 -1
|
@@ -39,7 +39,17 @@ publish-edge:
|
|
|
39
39
|
|
|
40
40
|
publish-to-npmjs:
|
|
41
41
|
stage: publish
|
|
42
|
-
image: ${CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX}/node:
|
|
42
|
+
image: ${CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX}/node:24
|
|
43
|
+
id_tokens:
|
|
44
|
+
NPM_ID_TOKEN:
|
|
45
|
+
aud: "npm:registry.npmjs.org"
|
|
46
|
+
SIGSTORE_ID_TOKEN:
|
|
47
|
+
aud: sigstore
|
|
48
|
+
when: manual
|
|
49
|
+
resource_group: publish/npm
|
|
50
|
+
environment:
|
|
51
|
+
name: publish/npm
|
|
52
|
+
url: https://www.npmjs.com/package/passbolt-browser-extension
|
|
43
53
|
rules:
|
|
44
54
|
- if: "$CI_COMMIT_TAG"
|
|
45
55
|
script:
|
|
@@ -9,10 +9,6 @@ CI_SCRIPTS_DIR=$(dirname "$0")/..
|
|
|
9
9
|
# shellcheck source=.gitlab-ci/scripts/lib/version-check.sh
|
|
10
10
|
source "$CI_SCRIPTS_DIR"/lib/version-check.sh
|
|
11
11
|
|
|
12
|
-
echo //registry.npmjs.org/:_authToken="$NPM_PUBLISH_TOKEN" > .npmrc
|
|
13
|
-
echo email="$NPM_PUBLISH_EMAIL" >> .npmrc
|
|
14
|
-
echo always-auth=true >> .npmrc
|
|
15
|
-
|
|
16
12
|
if is_release_candidate "$CI_COMMIT_TAG"; then
|
|
17
13
|
npm publish --tag next
|
|
18
14
|
elif is_release_alpha "$CI_COMMIT_TAG"; then
|
|
@@ -23,4 +19,4 @@ elif is_stable "$CI_COMMIT_TAG"; then
|
|
|
23
19
|
npm publish
|
|
24
20
|
else
|
|
25
21
|
echo "The tag format is not supported"
|
|
26
|
-
fi
|
|
22
|
+
fi
|
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,55 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [5.11.0] - 2026-04-07
|
|
8
|
+
### Added
|
|
9
|
+
- PB-49733 SMTP-OAUTH - WP2.1 Update SmtpSettingsService to SmtpSettingsApiService
|
|
10
|
+
- PB-49734 SMTP-OAUTH - WP1.1 Create the SmtpSettingsEntity
|
|
11
|
+
- PB-49737 SMTP-OAUTH - WP2.2 Update SmtpTestSettingsService to SmtpTestSettingsApiService
|
|
12
|
+
- PB-49738 SMTP-OAUTH - WP2.3 Split SmtpSettingsModel to new architecture pattern
|
|
13
|
+
- PB-49739 SMTP-OAUTH - WP2.4 Split SmtpTestSettingsModel to new architecture pattern
|
|
14
|
+
- PB-49740 SMTP-OAUTH - WP3.1 Adapt context with the new SMTP entities
|
|
15
|
+
- PB-49741 SMTP-OAUTH - WP3.2 Adapt ManageSmtpAdministationSettings to handle the new OAUTH fields
|
|
16
|
+
- PB-50058 OAuth SMTP: add the new styleguide to backend
|
|
17
|
+
- PB-50135 SSO with PingOne
|
|
18
|
+
- PB-50157 Enable avatar upload for Safari
|
|
19
|
+
- PB-50254 SCIM-WP1.2 Adapt form to handle the new date field and display warning message when expired
|
|
20
|
+
- PB-50263 Add a username selector compatible with ProxMox
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
- PB-46678 Fix quickaccess closing issue on Safari
|
|
24
|
+
- PB-49237 DisplayUserBadgeMenu attention required should be displayed on Administration page served by API
|
|
25
|
+
- PB-49287 When deleting a user, the URL must changed not to reference the deleted user id
|
|
26
|
+
- PB-49476 Fix autofill for websites using identifier as name for username field
|
|
27
|
+
- PB-49619 Fix username input field selector for OVH
|
|
28
|
+
- PB-49849 Sync generator password policy with the administration after save
|
|
29
|
+
- PB-49866 Fix the expiry column in the resource workspace grid is not present anymore
|
|
30
|
+
- PB-49882 Fix username input field selector for Supermicro IPMI WebUI
|
|
31
|
+
- PB-50023 Fix multifield OTP selector matching hidden inputs
|
|
32
|
+
- PB-50077 Fix React router issue that reloads the page unexpectedly
|
|
33
|
+
- PB-50177 Fix autofill issues for two websites
|
|
34
|
+
|
|
35
|
+
### Maintenance
|
|
36
|
+
- PB-49129 Delegate tab opening to service worker in order to send all cookie via Safari
|
|
37
|
+
- PB-49459 Timeouts not cleared properly when filtering resources/users grids by keywords
|
|
38
|
+
- PB-49705 Add missing TOTP unit tests
|
|
39
|
+
- PB-49730 Setup an environment for publishing to npmjs registry
|
|
40
|
+
- PB-49998 Add required `data_collection_permissions` for Firefox and set it to `none`
|
|
41
|
+
- PB-50013 Make Safari download custom avatars
|
|
42
|
+
- PB-50118 Major upgrade for locutus (Critical) - passbolt-browser-extension
|
|
43
|
+
- PB-50158 Add Safari enablement through a feature flag
|
|
44
|
+
- PB-50200 Move the logic of passbolt.groups.create to GroupCreateController
|
|
45
|
+
- PB-50201 Update group create call in groupApiService to contain "my_group_user" as urlOptions
|
|
46
|
+
- PB-50202 Add supported formats documentation link in export dialog
|
|
47
|
+
- PB-50225 Create a CreateGroupService.js file and move the create call to api service inside it
|
|
48
|
+
- PB-50338 - Fix phantom @babel/preset-react
|
|
49
|
+
|
|
50
|
+
### Security
|
|
51
|
+
- PB-49608 Fix ReDoS vulnerability in PGP armor regex validation
|
|
52
|
+
- PB-50271 Fix GHSA-25h7-pfq9-p65f - HIGH CVSS3.1
|
|
53
|
+
- PB-50272 Fix brace-expansion vulnerabilities
|
|
54
|
+
|
|
55
|
+
|
|
7
56
|
## [5.9.0] - 2026-01-21
|
|
8
57
|
### Fixed
|
|
9
58
|
- PB-43511 Display the "Migrate metadata" admin home page card icon with a 2px stroke width
|
package/RELEASE_NOTES.md
CHANGED
|
@@ -1,123 +1,97 @@
|
|
|
1
|
-
Passbolt 5.
|
|
1
|
+
Passbolt 5.11.0 introduces improvements to enterprise authentication and integration capabilities, alongside continued security hardening.
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
This release adds support for OAuth-based SMTP authentication for Microsoft Exchange Online and expands SSO coverage with PingOne. It also includes the finalisation of SCIM following external audit fixes.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## SMTP OAuth support for Microsoft Exchange Online
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Passbolt 5.11 introduces OAuth 2.0 support for SMTP with Microsoft Exchange Online, replacing legacy username/password authentication.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Administrators can configure the OAuth (Client Credentials) method by registering an application in Microsoft Entra ID and providing the required tenant ID, client ID, client secret, and service account email.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
At runtime, Passbolt retrieves short-lived access tokens to authenticate SMTP connections without user interaction, improving security and aligning with modern authentication standards.
|
|
12
12
|
|
|
13
|
-
This version also releases modernization of the tag codebase. This allows us to present these tags in the grid but also paves the way for further improvement of this feature.
|
|
14
13
|
|
|
15
|
-
|
|
14
|
+
## PingOne SSO support (Passbolt Pro)
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
the CSV exports are disabled by default (import is still working) and can be reenabled via a server configuration
|
|
19
|
-
When CSV exports are enabled, a confirmation checkbox is displayed to ensure the users know what are the risks of this kind of export. Exported values are not modified to keep data integrity
|
|
16
|
+
Passbolt 5.11 adds support for PingOne as a new SSO provider, enabling organisations to authenticate users via their existing Ping Identity infrastructure.
|
|
20
17
|
|
|
21
|
-
|
|
18
|
+
The integration is based on OpenID Connect (OIDC) using the Authorization Code flow, with Passbolt delegating authentication to PingOne and receiving a verified user identity via ID tokens.
|
|
22
19
|
|
|
23
|
-
|
|
20
|
+
Administrators can configure PingOne from the SSO settings using the required environment ID, client ID, client secret, and base URL, with a dry-run option available to validate the setup before activation. Once enabled, users are redirected to PingOne for authentication and seamlessly logged into Passbolt, including during account recovery.
|
|
24
21
|
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
This addition expands Passbolt’s SSO coverage for enterprise environments and removes a key adoption blocker for organisations standardised on Ping Identity.
|
|
23
|
+
|
|
24
|
+
## SCIM: audit fixes and general availability (Passbolt Pro)
|
|
25
|
+
|
|
26
|
+
Following the external security audit conducted by Cure53, this release includes fixes addressing the identified findings in the SCIM provisioning implementation.
|
|
27
|
+
|
|
28
|
+
With these changes, SCIM is now considered stable and exits beta.
|
|
29
|
+
|
|
30
|
+
The audit-driven improvements strengthen validation, error handling, and overall robustness of the provisioning flow. SCIM is now ready for production use in environments requiring automated user lifecycle management.
|
|
31
|
+
|
|
32
|
+
## Security improvements
|
|
33
|
+
|
|
34
|
+
This release continues the ongoing security hardening effort across the platform.
|
|
35
|
+
|
|
36
|
+
In addition to the SCIM audit fixes, improvements have been made to align with external audit recommendations and reduce potential attack surface in authentication and integration layers.
|
|
37
|
+
|
|
38
|
+
## Maintenance & performance
|
|
39
|
+
|
|
40
|
+
This release includes general performance improvements, particularly around background job processing and email delivery workflows.
|
|
41
|
+
|
|
42
|
+
Email-related operations are now more efficient and better distributed, reducing bottlenecks in high-load environments.
|
|
43
|
+
|
|
44
|
+
As usual, additional optimisations are already in progress for upcoming releases.
|
|
45
|
+
|
|
46
|
+
## Conclusion
|
|
47
|
+
|
|
48
|
+
As usual, the release is also packed with additional improvements and fixes. Check out the changelog to learn more.
|
|
49
|
+
|
|
50
|
+
Many thanks to everyone who provided feedback, reported bugs, and contributed to making passbolt better!
|
|
27
51
|
|
|
28
52
|
### Added
|
|
29
|
-
- PB-
|
|
30
|
-
- PB-
|
|
31
|
-
- PB-
|
|
32
|
-
- PB-
|
|
33
|
-
- PB-
|
|
34
|
-
- PB-
|
|
35
|
-
- PB-
|
|
36
|
-
- PB-
|
|
37
|
-
- PB-
|
|
38
|
-
- PB-
|
|
39
|
-
- PB-
|
|
40
|
-
- PB-
|
|
41
|
-
- PB-45869 SAF - WP2.13 Implement file download using the native messaging
|
|
42
|
-
- PB-45870 SAF - WP2.14 Implement a custom fetch using the native messaging
|
|
43
|
-
- PB-46265 SAF - WP2.15 Fix authentication with MFA in the quickaccess
|
|
44
|
-
- PB-46679 SAF - Fix bold font rendering
|
|
45
|
-
- PB-47765 Tags modernization
|
|
46
|
-
- PB-47777 Migrate tags logic from components to TagServiceWorkerService
|
|
47
|
-
- PB-47789 REACT18 - Update ReactDom render to createRoot
|
|
48
|
-
- PB-47992 REACT 18 - migration of ResourceWorkspaceContext
|
|
49
|
-
- PB-48158 REACT 18 - Implement the migration of Dialog and Progress Contexts
|
|
50
|
-
- PB-48240 REACT18 - UserWorkspace migration
|
|
51
|
-
- PB-48252 REACT18 - Migrate ExtAppContext
|
|
52
|
-
- PB-48253 SAF - Temporarily remove Avatar download to avoid user being signed out
|
|
53
|
-
- PB-48258 SAF - Temporarily remove "upload avatar" feature
|
|
54
|
-
- PB-48337 REACT18 - Update contexts that should use functional update
|
|
55
|
-
- PB-48338 REACT18 - Update shared components that should use functional update
|
|
56
|
-
- PB-48339 REACT18 - Update quickaccess components that should use functional update
|
|
57
|
-
- PB-48340 REACT18 - Update authentication components that should use functional update
|
|
58
|
-
- PB-48342 REACT18 - Update user setting components that should use functional update
|
|
59
|
-
- PB-48343 REACT18 - Update administration components that should use functional update
|
|
60
|
-
- PB-48360 REACT18 - Update resource components that should use functional update
|
|
61
|
-
- PB-48363 REACT18 - Update user components that should use functional update
|
|
62
|
-
- PB-48366 REACT18 - Remove await set state in contexts
|
|
63
|
-
- PB-48384 REACT18 - Remove await setState in components and apps
|
|
64
|
-
- PB-48404 REACT18 - Object.assign should use functional set state for context
|
|
65
|
-
- PB-48408 CSV - WP1.2 Add a warning message when user is selecting a CSV format on the button
|
|
66
|
-
- PB-48416 CSV - WP2.9 Check if the setting is enabled when displaying the csv format on exportFormats
|
|
67
|
-
- PB-48419 REACT18 - Update the components to use functional setState
|
|
68
|
-
- PB-48425 REACT18 - Form validation should not check errors in the state for component
|
|
69
|
-
- PB-48470 Create ColumnTagsModel component
|
|
70
|
-
- PB-48471 TAGRID-1.2 Create CellTags component and make it resizable
|
|
71
|
-
- PB-48472 TAGRID-1.3 Add ColumnTagsModel and CellTags to DisplayResourcesList
|
|
72
|
-
- PB-48473 TAGRID-1.4 Clicking on a tag should filter the workspace
|
|
73
|
-
- PB-48521 Harmonise tags style
|
|
74
|
-
- PB-48553 SAF - Use webNavigation instead of tab update to improve navigation performances
|
|
75
|
-
- PB-49070 REACT18 - Migrate SSOContext for react-extension
|
|
76
|
-
- PB-49085 REACT18 - Migrate tests to remove legacyRoot true
|
|
77
|
-
- PB-49092 TAGRID-1.6 Hovering the tag on the resource detail should display tooltip
|
|
78
|
-
- PB-49106 CSV - WP2.2 Implement the exportPoliciesSettingsEntity
|
|
79
|
-
- PB-49107 CSV - WP2.3 Implement the exportPoliciesSettingsApiService
|
|
80
|
-
- PB-49108 CSV - WP2.4 Implement the findExportPoliciesSettingsService
|
|
81
|
-
- PB-49109 CSV - WP2.5 Implement findExportPoliciesSettingsController
|
|
82
|
-
- PB-49110 CSV - WP2.7 Implement exportPoliciesSettingsServiceWorkerService
|
|
83
|
-
- PB-49134 REACT18 - Migrate ApiAppContext
|
|
84
|
-
- PB-49137 CSV - WP2.8 Implement the ExportPoliciesContext
|
|
85
|
-
- PB-49138 CSV - WP2.6 Add event to find export policies settings
|
|
86
|
-
- PB-49172 REACT18 - Rename method in DisplaySelfRegistrationAdminstration
|
|
87
|
-
- PB-49248 REACT 18 - Revert functional setstate
|
|
88
|
-
- PB-49262 REACT18 - revert functional setstate in contexts and components
|
|
89
|
-
- PB-49270 SAF - Fix Safari Users settings for Duo MFA configuration
|
|
90
|
-
- PB-49293 TOTP Autofill
|
|
91
|
-
- PB-49294 Send TOTP through port to fill from in-form menu or quickaccess
|
|
53
|
+
- PB-49733 SMTP-OAUTH - WP2.1 Update SmtpSettingsService to SmtpSettingsApiService
|
|
54
|
+
- PB-49734 SMTP-OAUTH - WP1.1 Create the SmtpSettingsEntity
|
|
55
|
+
- PB-49737 SMTP-OAUTH - WP2.2 Update SmtpTestSettingsService to SmtpTestSettingsApiService
|
|
56
|
+
- PB-49738 SMTP-OAUTH - WP2.3 Split SmtpSettingsModel to new architecture pattern
|
|
57
|
+
- PB-49739 SMTP-OAUTH - WP2.4 Split SmtpTestSettingsModel to new architecture pattern
|
|
58
|
+
- PB-49740 SMTP-OAUTH - WP3.1 Adapt context with the new SMTP entities
|
|
59
|
+
- PB-49741 SMTP-OAUTH - WP3.2 Adapt ManageSmtpAdministationSettings to handle the new OAUTH fields
|
|
60
|
+
- PB-50058 OAuth SMTP: add the new styleguide to backend
|
|
61
|
+
- PB-50135 SSO with PingOne
|
|
62
|
+
- PB-50157 Enable avatar upload for Safari
|
|
63
|
+
- PB-50254 SCIM-WP1.2 Adapt form to handle the new date field and display warning message when expired
|
|
64
|
+
- PB-50263 Add a username selector compatible with ProxMox
|
|
92
65
|
|
|
93
66
|
### Fixed
|
|
94
|
-
- PB-
|
|
95
|
-
- PB-
|
|
67
|
+
- PB-46678 Fix quickaccess closing issue on Safari
|
|
68
|
+
- PB-49237 DisplayUserBadgeMenu attention required should be displayed on Administration page served by API
|
|
69
|
+
- PB-49287 When deleting a user, the URL must changed not to reference the deleted user id
|
|
70
|
+
- PB-49476 Fix autofill for websites using identifier as name for username field
|
|
71
|
+
- PB-49619 Fix username input field selector for OVH
|
|
72
|
+
- PB-49849 Sync generator password policy with the administration after save
|
|
73
|
+
- PB-49866 Fix the expiry column in the resource workspace grid is not present anymore
|
|
74
|
+
- PB-49882 Fix username input field selector for Supermicro IPMI WebUI
|
|
75
|
+
- PB-50023 Fix multifield OTP selector matching hidden inputs
|
|
76
|
+
- PB-50077 Fix React router issue that reloads the page unexpectedly
|
|
77
|
+
- PB-50177 Fix autofill issues for two websites
|
|
96
78
|
|
|
97
79
|
### Maintenance
|
|
98
|
-
- PB-
|
|
99
|
-
- PB-
|
|
100
|
-
- PB-
|
|
101
|
-
- PB-
|
|
102
|
-
- PB-
|
|
103
|
-
- PB-
|
|
104
|
-
- PB-
|
|
105
|
-
- PB-
|
|
106
|
-
- PB-
|
|
80
|
+
- PB-49129 Delegate tab opening to service worker in order to send all cookie via Safari
|
|
81
|
+
- PB-49459 Timeouts not cleared properly when filtering resources/users grids by keywords
|
|
82
|
+
- PB-49705 Add missing TOTP unit tests
|
|
83
|
+
- PB-49730 Setup an environment for publishing to npmjs registry
|
|
84
|
+
- PB-49998 Add required `data_collection_permissions` for Firefox and set it to `none`
|
|
85
|
+
- PB-50013 Make Safari download custom avatars
|
|
86
|
+
- PB-50118 Major upgrade for locutus (Critical) - passbolt-browser-extension
|
|
87
|
+
- PB-50158 Add Safari enablement through a feature flag
|
|
88
|
+
- PB-50200 Move the logic of passbolt.groups.create to GroupCreateController
|
|
89
|
+
- PB-50201 Update group create call in groupApiService to contain "my_group_user" as urlOptions
|
|
90
|
+
- PB-50202 Add supported formats documentation link in export dialog
|
|
91
|
+
- PB-50225 Create a CreateGroupService.js file and move the create call to api service inside it
|
|
92
|
+
- PB-50338 - Fix phantom @babel/preset-react
|
|
107
93
|
|
|
108
94
|
### Security
|
|
109
|
-
- PB-
|
|
110
|
-
- PB-
|
|
111
|
-
- PB-
|
|
112
|
-
- PB-48257 Small upgrade for lodash (Medium) - all projects
|
|
113
|
-
- PB-48527 Small upgrade for locutus (Critical) - passbolt-windows
|
|
114
|
-
- PB-48535 NPM - Remove now unnecessary overrides in package.json for styleguide and bext
|
|
115
|
-
- PB-49119 Remove dev phantom dependencies - node-fetch
|
|
116
|
-
- PB-49120 Remove dev phantom dependencies - history
|
|
117
|
-
- PB-49121 Remove dev phantom dependencies - expect
|
|
118
|
-
- PB-49369 Fix GCVE-0-2026-2391 - Medium CVSS4.0
|
|
119
|
-
- PB-49372 Fix GCVE-0-2025-68458 & GCVE-0-2025-68157 - LOW CVSS3.1
|
|
120
|
-
- PB-49373 Fix GCVE-0-2026-25547 - CRITICAL CVSS4.0
|
|
121
|
-
- PB-49432 Fix GCVE-0-2025-69873 - MEDIUM CVSS4.0
|
|
122
|
-
- PB-49452 Fix GHSA-3ppc-4f35-3m26 - HIGH CVSS4.0
|
|
123
|
-
- PB-49454 Update CSPs to allow inline <style> in SVGs
|
|
95
|
+
- PB-49608 Fix ReDoS vulnerability in PGP armor regex validation
|
|
96
|
+
- PB-50271 Fix GHSA-25h7-pfq9-p65f - HIGH CVSS3.1
|
|
97
|
+
- PB-50272 Fix brace-expansion vulnerabilities
|
|
@@ -23,6 +23,14 @@
|
|
|
23
23
|
|
|
24
24
|
import Foundation
|
|
25
25
|
|
|
26
|
+
private extension Data {
|
|
27
|
+
mutating func append(_ string: String) {
|
|
28
|
+
if let data = string.data(using: .utf8) {
|
|
29
|
+
append(data)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
26
34
|
final class FetchService {
|
|
27
35
|
|
|
28
36
|
// Runs a fetch on the API with profile isolation.
|
|
@@ -35,19 +43,31 @@ final class FetchService {
|
|
|
35
43
|
// profileUUID: The Safari profile UUID for session isolation
|
|
36
44
|
static func fetch(url: URL, options: [String: Any], profileUUID: String) async throws -> [String: Any] {
|
|
37
45
|
let method = options["method"] as? String ?? "GET"
|
|
38
|
-
let body = options["body"] as? String ?? ""
|
|
39
46
|
let headers = options["headers"] as? [String: String] ?? [:]
|
|
40
47
|
let cookies = options["cookies"] as? String
|
|
41
48
|
|
|
42
49
|
var httpRequest = URLRequest(url: url)
|
|
43
50
|
httpRequest.httpMethod = method
|
|
44
|
-
|
|
51
|
+
|
|
52
|
+
// Build the body: structured FormData array (may contain files) or plain string
|
|
53
|
+
if let formDataArray = options["body"] as? [[String: Any]] {
|
|
54
|
+
let boundary = UUID().uuidString
|
|
55
|
+
httpRequest.httpBody = buildMultipartBody(formDataArray: formDataArray, boundary: boundary)
|
|
56
|
+
httpRequest.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
|
|
57
|
+
} else {
|
|
58
|
+
let body = options["body"] as? String ?? ""
|
|
59
|
+
httpRequest.httpBody = body.data(using: .utf8)
|
|
60
|
+
}
|
|
45
61
|
|
|
46
62
|
// SECURITY: Add cache-control headers to prevent response caching
|
|
47
63
|
httpRequest.setValue("no-cache, no-store, must-revalidate", forHTTPHeaderField: "Cache-Control")
|
|
48
64
|
httpRequest.setValue("no-cache", forHTTPHeaderField: "Pragma")
|
|
49
65
|
|
|
50
66
|
for header in headers {
|
|
67
|
+
// Skip Content-Type when we already set it for multipart
|
|
68
|
+
if header.key.lowercased() == "content-type" && httpRequest.value(forHTTPHeaderField: "Content-Type")?.contains("multipart") == true {
|
|
69
|
+
continue
|
|
70
|
+
}
|
|
51
71
|
httpRequest.setValue(String(describing: header.value), forHTTPHeaderField: String(describing: header.key))
|
|
52
72
|
}
|
|
53
73
|
|
|
@@ -59,6 +79,74 @@ final class FetchService {
|
|
|
59
79
|
return try await doFetch(request: httpRequest, profileUUID: profileUUID)
|
|
60
80
|
}
|
|
61
81
|
|
|
82
|
+
/// Build a multipart/form-data body from the structured FormData array sent by JavaScript.
|
|
83
|
+
/// Each entry has: key, value, type ("SCALAR" or "FILE"), and optionally name (for files).
|
|
84
|
+
/// File values use the data URL format: "data:<mimeType>;base64,<base64Data>"
|
|
85
|
+
private static func buildMultipartBody(formDataArray: [[String: Any]], boundary: String) -> Data {
|
|
86
|
+
var body = Data()
|
|
87
|
+
|
|
88
|
+
for entry in formDataArray {
|
|
89
|
+
guard let key = entry["key"] as? String,
|
|
90
|
+
let value = entry["value"] as? String,
|
|
91
|
+
let type = entry["type"] as? String else {
|
|
92
|
+
continue
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
let sanitizedKey = sanitizeHeaderValue(key)
|
|
96
|
+
body.append("--\(boundary)\r\n")
|
|
97
|
+
|
|
98
|
+
if type == "FILE" {
|
|
99
|
+
let rawFilename = entry["name"] as? String ?? "file"
|
|
100
|
+
let sanitizedFilename = sanitizeFilename(rawFilename)
|
|
101
|
+
let (mimeType, fileData) = decodeDataURL(value)
|
|
102
|
+
let sanitizedMimeType = sanitizeHeaderValue(mimeType)
|
|
103
|
+
|
|
104
|
+
body.append("Content-Disposition: form-data; name=\"\(sanitizedKey)\"; filename=\"\(sanitizedFilename)\"\r\n")
|
|
105
|
+
body.append("Content-Type: \(sanitizedMimeType)\r\n\r\n")
|
|
106
|
+
body.append(fileData)
|
|
107
|
+
body.append("\r\n")
|
|
108
|
+
} else {
|
|
109
|
+
body.append("Content-Disposition: form-data; name=\"\(sanitizedKey)\"\r\n\r\n")
|
|
110
|
+
body.append("\(value)\r\n")
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
body.append("--\(boundary)--\r\n")
|
|
115
|
+
return body
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/// Sanitize a filename for use in Content-Disposition headers.
|
|
119
|
+
/// Strips path traversal components, quotes, and CRLF characters.
|
|
120
|
+
private static func sanitizeFilename(_ raw: String) -> String {
|
|
121
|
+
let nameOnly = raw.components(separatedBy: CharacterSet(charactersIn: "/\\")).last ?? "file"
|
|
122
|
+
return sanitizeHeaderValue(nameOnly)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/// Sanitize a value interpolated into an HTTP header by removing quotes and CRLF.
|
|
126
|
+
private static func sanitizeHeaderValue(_ raw: String) -> String {
|
|
127
|
+
raw.replacingOccurrences(of: "\"", with: "")
|
|
128
|
+
.replacingOccurrences(of: "\r", with: "")
|
|
129
|
+
.replacingOccurrences(of: "\n", with: "")
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/// Decode a data URL (e.g. "data:image/png;base64,iVBOR...") into its MIME type and binary data.
|
|
133
|
+
private static func decodeDataURL(_ dataURL: String) -> (mimeType: String, data: Data) {
|
|
134
|
+
let parts = dataURL.components(separatedBy: ",")
|
|
135
|
+
guard parts.count == 2,
|
|
136
|
+
let base64Data = Data(base64Encoded: parts[1]) else {
|
|
137
|
+
return ("application/octet-stream", Data())
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Extract MIME type from "data:image/png;base64"
|
|
141
|
+
let header = parts[0]
|
|
142
|
+
let mimeType = header
|
|
143
|
+
.replacingOccurrences(of: "data:", with: "")
|
|
144
|
+
.components(separatedBy: ";")
|
|
145
|
+
.first ?? "application/octet-stream"
|
|
146
|
+
|
|
147
|
+
return (mimeType, base64Data)
|
|
148
|
+
}
|
|
149
|
+
|
|
62
150
|
// The actual fetch sent to the API using a profile-isolated session
|
|
63
151
|
private static func doFetch(request: URLRequest, profileUUID: String) async throws -> [String: Any] {
|
|
64
152
|
// SECURITY: Use profile-specific session, NEVER URLSession.shared
|
package/eslint.config.mjs
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import globals from "globals";
|
|
2
|
-
import babelParser from "@babel/eslint-parser";
|
|
3
2
|
import path from "path";
|
|
4
3
|
import { fileURLToPath } from "url";
|
|
5
4
|
|
|
@@ -32,18 +31,13 @@ export default [
|
|
|
32
31
|
files: ["**/*.{js,jsx,mjs,cjs}"],
|
|
33
32
|
|
|
34
33
|
languageOptions: {
|
|
35
|
-
parser: babelParser,
|
|
36
34
|
ecmaVersion: 2024,
|
|
37
35
|
sourceType: "module",
|
|
38
36
|
|
|
39
37
|
parserOptions: {
|
|
40
|
-
requireConfigFile: false,
|
|
41
38
|
ecmaFeatures: {
|
|
42
39
|
jsx: true,
|
|
43
40
|
},
|
|
44
|
-
babelOptions: {
|
|
45
|
-
presets: ["@babel/preset-react"],
|
|
46
|
-
},
|
|
47
41
|
},
|
|
48
42
|
|
|
49
43
|
globals: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "passbolt-browser-extension",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.11.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",
|
|
@@ -19,10 +19,9 @@
|
|
|
19
19
|
"ip-regex": "^5.0.0",
|
|
20
20
|
"jssha": "~3.3.1",
|
|
21
21
|
"kdbxweb": "2.1.1",
|
|
22
|
-
"locutus": "~2.0.39",
|
|
23
22
|
"openpgp": "^6.1.1",
|
|
24
23
|
"papaparse": "^5.5.2",
|
|
25
|
-
"passbolt-styleguide": "5.
|
|
24
|
+
"passbolt-styleguide": "^5.11.3",
|
|
26
25
|
"react": "^18.3.1",
|
|
27
26
|
"react-dom": "^18.3.1",
|
|
28
27
|
"secrets-passbolt": "github:passbolt/secrets.js#v2.0.1",
|
|
@@ -33,31 +32,30 @@
|
|
|
33
32
|
},
|
|
34
33
|
"devDependencies": {
|
|
35
34
|
"@babel/core": "^7.23.2",
|
|
36
|
-
"@babel/eslint-parser": "^7.22.9",
|
|
37
35
|
"@babel/helpers": "^7.26.10",
|
|
38
36
|
"@babel/plugin-transform-runtime": "^7.22.9",
|
|
39
37
|
"@babel/preset-env": "^7.22.9",
|
|
40
|
-
"@babel/preset-react": "^7.
|
|
38
|
+
"@babel/preset-react": "^7.28.5",
|
|
41
39
|
"@babel/runtime": "^7.27.0",
|
|
42
40
|
"@babel/runtime-corejs3": "^7.26.10",
|
|
43
|
-
"@eslint/js": "^9.
|
|
41
|
+
"@eslint/js": "^9.39.4",
|
|
44
42
|
"@svgr/webpack": "^8.1.0",
|
|
45
43
|
"babel-jest": "^29.6.2",
|
|
46
44
|
"babel-loader": "^8.2.3",
|
|
47
45
|
"buffer": "^6.0.3",
|
|
48
46
|
"crx": "^5.0.1",
|
|
49
|
-
"eslint": "^9.
|
|
47
|
+
"eslint": "^9.39.4",
|
|
50
48
|
"eslint-config-prettier": "^10.1.8",
|
|
51
49
|
"eslint-import-resolver-alias": "^1.1.2",
|
|
52
50
|
"eslint-plugin-import": "^2.32.0",
|
|
53
|
-
"eslint-plugin-jest": "^29.
|
|
54
|
-
"eslint-plugin-n": "^17.
|
|
55
|
-
"eslint-plugin-no-unsanitized": "^4.1.
|
|
56
|
-
"eslint-plugin-prettier": "^5.5.
|
|
51
|
+
"eslint-plugin-jest": "^29.15.1",
|
|
52
|
+
"eslint-plugin-n": "^17.24.0",
|
|
53
|
+
"eslint-plugin-no-unsanitized": "^4.1.5",
|
|
54
|
+
"eslint-plugin-prettier": "^5.5.5",
|
|
57
55
|
"eslint-plugin-promise": "^7.2.1",
|
|
58
56
|
"eslint-plugin-react": "^7.37.5",
|
|
59
|
-
"eslint-plugin-regexp": "^
|
|
60
|
-
"eslint-plugin-security": "^
|
|
57
|
+
"eslint-plugin-regexp": "^3.1.0",
|
|
58
|
+
"eslint-plugin-security": "^4.0.0",
|
|
61
59
|
"filereader": "^0.10.3",
|
|
62
60
|
"formdata-node": "^6.0.3",
|
|
63
61
|
"globals": "^16.4.0",
|
|
@@ -54,8 +54,17 @@ class AuthLogoutController {
|
|
|
54
54
|
return;
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
/*
|
|
58
|
+
* Use tabs.reload instead of tabs.update to ensure the page is fully
|
|
59
|
+
* reloaded from the server. A tabs.update navigation may restore the
|
|
60
|
+
* page from the browser's Back/Forward Cache (BFCache), resulting in
|
|
61
|
+
* a stale page with a dead extension message port after sign-out.
|
|
62
|
+
*
|
|
63
|
+
* See: PB-50644
|
|
64
|
+
*/
|
|
65
|
+
await browser.tabs.reload(this.worker.tab.id);
|
|
66
|
+
// const url = this.apiClientOptions.getBaseUrl().toString();
|
|
67
|
+
// await browser.tabs.update(this.worker.tab.id, { url });
|
|
59
68
|
}
|
|
60
69
|
}
|
|
61
70
|
|
|
@@ -34,7 +34,7 @@ describe("AuthLogoutController", () => {
|
|
|
34
34
|
});
|
|
35
35
|
|
|
36
36
|
it("Should sign-out the user and redirect after.", async () => {
|
|
37
|
-
expect.assertions(
|
|
37
|
+
expect.assertions(2);
|
|
38
38
|
const logoutSpy = jest.spyOn(AuthModel.prototype, "logout").mockImplementation(() => {});
|
|
39
39
|
|
|
40
40
|
const worker = {
|
|
@@ -48,10 +48,19 @@ describe("AuthLogoutController", () => {
|
|
|
48
48
|
await controller.exec(true);
|
|
49
49
|
|
|
50
50
|
expect(logoutSpy).toHaveBeenCalledTimes(1);
|
|
51
|
-
expect(browser.tabs.
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
51
|
+
expect(browser.tabs.reload).toHaveBeenCalledTimes(1);
|
|
52
|
+
/*
|
|
53
|
+
* Use tabs.reload instead of tabs.update to ensure the page is fully
|
|
54
|
+
* reloaded from the server. A tabs.update navigation may restore the
|
|
55
|
+
* page from the browser's Back/Forward Cache (BFCache), resulting in
|
|
56
|
+
* a stale page with a dead extension message port after sign-out.
|
|
57
|
+
*
|
|
58
|
+
* See: PB-50644
|
|
59
|
+
*/
|
|
60
|
+
// expect(browser.tabs.update).toHaveBeenCalledTimes(1);
|
|
61
|
+
// expect(browser.tabs.update).toHaveBeenCalledWith(worker.tab.id, {
|
|
62
|
+
// url: apiClientOptions.getBaseUrl().toString(),
|
|
63
|
+
// });
|
|
55
64
|
});
|
|
56
65
|
});
|
|
57
66
|
});
|
|
@@ -0,0 +1,58 @@
|
|
|
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.11.0
|
|
13
|
+
*/
|
|
14
|
+
import CreateGroupService from "../../service/group/createGroupService";
|
|
15
|
+
import GroupEntity from "../../model/entity/group/groupEntity";
|
|
16
|
+
|
|
17
|
+
class GroupCreateController {
|
|
18
|
+
/**
|
|
19
|
+
* GroupCreateController constructor
|
|
20
|
+
*
|
|
21
|
+
* @param {Worker} worker
|
|
22
|
+
* @param {string} requestId
|
|
23
|
+
* @param {ApiClientOptions} apiClientOptions the api client options
|
|
24
|
+
* @param {AccountEntity} account The account associated to the worker.
|
|
25
|
+
*/
|
|
26
|
+
constructor(worker, requestId, apiClientOptions, account) {
|
|
27
|
+
this.worker = worker;
|
|
28
|
+
this.requestId = requestId;
|
|
29
|
+
this.createGroupService = new CreateGroupService(apiClientOptions, account);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Controller executor.
|
|
34
|
+
* @param {object} groupDto The group data
|
|
35
|
+
* @returns {Promise<void>}
|
|
36
|
+
*/
|
|
37
|
+
async _exec(groupDto) {
|
|
38
|
+
try {
|
|
39
|
+
const group = await this.exec(groupDto);
|
|
40
|
+
this.worker.port.emit(this.requestId, "SUCCESS", group);
|
|
41
|
+
} catch (error) {
|
|
42
|
+
console.error(error);
|
|
43
|
+
this.worker.port.emit(this.requestId, "ERROR", error);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Create a group.
|
|
49
|
+
* @param {object} groupDto The group data
|
|
50
|
+
* @returns {Promise<GroupEntity>}
|
|
51
|
+
*/
|
|
52
|
+
async exec(groupDto) {
|
|
53
|
+
const groupEntity = new GroupEntity(groupDto);
|
|
54
|
+
return this.createGroupService.create(groupEntity);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export default GroupCreateController;
|