Skip to content

[PM-31159] Full state service re-write - #1029

Merged
BTreston merged 17 commits into
mainfrom
ac/pm-31159-state-service
Apr 6, 2026
Merged

[PM-31159] Full state service re-write#1029
BTreston merged 17 commits into
mainfrom
ac/pm-31159-state-service

Conversation

@BTreston

@BTreston BTreston commented Mar 4, 2026

Copy link
Copy Markdown
Contributor

🎟️ Tracking

https://bitwarden.atlassian.net/browse/PM-31159

📔 Objective

This PR encompasses the totality of the state service re-write. This includes:

  • removing the old state service
  • complete re-write of state.service.ts
  • untangle state service dependencies on jslib
  • integrate only necessary core jslib services into the main directory structure
  • removed un-needed jslib service dependencies (e.g. crypto-service)
  • migrating state object to a flat key-value structure (rather than account based object hierarchy)
  • migrating necessary jslib state into DC app state (mostly electron related state).
  • add v5 state migration
  • re-export DC services for jslib compatibility (stub files)
  • consolidate all jslib state migration logic into DC's state migration service
  • eliminate unnecessary account based jslib models

📸 Screenshots

@BTreston
BTreston marked this pull request as ready for review March 4, 2026 19:15
@BTreston
BTreston requested a review from a team as a code owner March 4, 2026 19:15
@BTreston
BTreston requested review from JaredScar and eliykat March 4, 2026 19:15
@github-actions

github-actions Bot commented Mar 4, 2026

Copy link
Copy Markdown
Contributor

Logo
Checkmarx One – Scan Summary & Details5a15b87c-6826-4912-902d-c7e89e4e2ddf


New Issues (34) Checkmarx found the following issues in this Pull Request
# Severity Issue Source File / Package Checkmarx Insight
1 CRITICAL CVE-2026-29045 Npm-hono-4.12.3
detailsRecommended version: 4.12.4
Description: Hono is a Web application framework that provides support for any JavaScript runtime. Prior to version 4.12.4, when using serveStatic together with...
Attack Vector: NETWORK
Attack Complexity: LOW
Vulnerable Package
2 HIGH CVE-2025-13042 Npm-electron-39.2.1
detailsRecommended version: 39.8.4
Description: Inappropriate implementation in V8 in Google Chrome prior to 142.0.7444.166 allowed a remote attacker to potentially exploit heap corruption via a ...
Attack Vector: NETWORK
Attack Complexity: LOW
Vulnerable Package
3 HIGH CVE-2025-13223 Npm-electron-39.2.1
detailsRecommended version: 39.8.4
Description: Type Confusion in V8 in Google Chrome prior to 142.0.7444.175 allowed a remote attacker to potentially exploit heap corruption via a crafted HTML p...
Attack Vector: NETWORK
Attack Complexity: LOW
Vulnerable Package
4 HIGH CVE-2025-13224 Npm-electron-39.2.1
detailsRecommended version: 39.8.4
Description: Type Confusion in V8 in Google Chrome prior to 142.0.7444.175 allowed a remote attacker to potentially exploit heap corruption via a crafted HTML p...
Attack Vector: NETWORK
Attack Complexity: LOW
Vulnerable Package
5 HIGH CVE-2025-13631 Npm-electron-39.2.1
detailsRecommended version: 39.8.4
Description: Inappropriate implementation in Google Updater in Google Chrome on Mac prior to 143.0.7499.41 allowed a remote attacker to perform Privilege Escala...
Attack Vector: NETWORK
Attack Complexity: LOW
Vulnerable Package
6 HIGH CVE-2025-13633 Npm-electron-39.2.1
detailsRecommended version: 39.8.4
Description: Use After Free in Digital Credentials in Google Chrome prior to 143.0.7499.41 allowed a remote attacker who had compromised the renderer process to...
Attack Vector: NETWORK
Attack Complexity: LOW
Vulnerable Package
7 HIGH CVE-2025-13638 Npm-electron-39.2.1
detailsRecommended version: 39.8.4
Description: Use After Free in Media Stream in Google Chrome prior to 143.0.7499.41 allowed a remote attacker to potentially exploit heap corruption via a craft...
Attack Vector: NETWORK
Attack Complexity: LOW
Vulnerable Package
8 HIGH CVE-2025-13639 Npm-electron-39.2.1
detailsRecommended version: 39.8.4
Description: Inappropriate implementation in WebRTC in Google Chrome prior to 143.0.7499.41 allowed a remote attacker to perform arbitrary read/write via a craf...
Attack Vector: NETWORK
Attack Complexity: LOW
Vulnerable Package
9 HIGH CVE-2025-13720 Npm-electron-39.2.1
detailsRecommended version: 39.8.4
Description: Bad cast in Loader in Google Chrome prior to 143.0.7499.41 allowed a remote attacker who had compromised the renderer process to potentially exploi...
Attack Vector: NETWORK
Attack Complexity: LOW
Vulnerable Package
10 HIGH CVE-2025-13721 Npm-electron-39.2.1
detailsRecommended version: 39.8.4
Description: Race in v8 in Google Chrome prior to 143.0.7499.41 allowed a remote attacker to potentially exploit heap corruption via a crafted HTML page.
Attack Vector: NETWORK
Attack Complexity: HIGH
Vulnerable Package
11 HIGH CVE-2026-0628 Npm-electron-39.2.1
detailsRecommended version: 39.8.4
Description: Insufficient policy enforcement in WebView tag in Google Chrome prior to 143.0.7499.192 allowed an attacker who convinced a user to install a malic...
Attack Vector: NETWORK
Attack Complexity: LOW
Vulnerable Package
12 HIGH CVE-2026-1861 Npm-electron-39.2.1
detailsRecommended version: 39.8.4
Description: Heap Buffer Overflow in libvpx in Google Chrome prior to 144.0.7559.132 allowed a remote attacker to potentially exploit heap corruption via a craf...
Attack Vector: NETWORK
Attack Complexity: LOW
Vulnerable Package
13 HIGH CVE-2026-25536 Npm-@modelcontextprotocol/sdk-1.25.2
detailsRecommended version: 1.26.0
Description: MCP TypeScript SDK is the official TypeScript SDK for Model Context Protocol servers and clients. From version 1.10.0 through 1.25.3, cross-client ...
Attack Vector: NETWORK
Attack Complexity: LOW
Vulnerable Package
14 HIGH CVE-2026-2650 Npm-electron-39.2.1
detailsRecommended version: 39.8.4
Description: Heap Buffer Overflow in Media in Google Chrome prior to 145.0.7632.109 allowed a remote attacker to potentially exploit heap corruption via a craft...
Attack Vector: NETWORK
Attack Complexity: LOW
Vulnerable Package
15 HIGH CVE-2026-27970 Npm-@angular/core-21.1.1
detailsRecommended version: 21.2.4
Description: Angular is a development platform for building mobile and desktop web applications using TypeScript, JavaScript, and other languages. Versions prio...
Attack Vector: NETWORK
Attack Complexity: LOW
Vulnerable Package
16 HIGH CVE-2026-29063 Npm-immutable-5.1.4
detailsRecommended version: 5.1.5
Description: Immutable.js provides many Persistent Immutable data structures. 3.x prior to versions 3.8.3, 4.x prior to versions 4.3.7, and 5.x prior to versio...
Attack Vector: NETWORK
Attack Complexity: LOW
Vulnerable Package
17 HIGH CVE-2026-29087 Npm-@hono/node-server-1.19.9
detailsRecommended version: 1.19.10
Description: When using @hono/node-server's static file serving together with route-based middleware protections (e.g. protecting /admin/*), inconsistent URL de...
Attack Vector: NETWORK
Attack Complexity: LOW
Vulnerable Package
18 HIGH CVE-2026-32141 Npm-flatted-3.3.3
detailsRecommended version: 3.4.2
Description: flatted is a circular JSON parser. Prior to 3.4.0, flatted's "parse()" function uses a recursive "revive()" phase to resolve circular references in...
Attack Vector: NETWORK
Attack Complexity: LOW
Vulnerable Package
19 HIGH CVE-2026-32635 Npm-@angular/compiler-21.1.1
detailsRecommended version: 21.2.4
Description: A Cross-Site Scripting (XSS) vulnerability has been identified in the Angular runtime and compiler. It occurs when the application uses a security-...
Attack Vector: NETWORK
Attack Complexity: LOW
Vulnerable Package
20 HIGH CVE-2026-32635 Npm-@angular/core-21.1.1
detailsRecommended version: 21.2.4
Description: A Cross-Site Scripting (XSS) vulnerability has been identified in the Angular runtime and compiler. It occurs when the application uses a security-...
Attack Vector: NETWORK
Attack Complexity: LOW
Vulnerable Package
21 HIGH CVE-2026-33228 Npm-flatted-3.3.3
detailsRecommended version: 3.4.2
Description: The "parse()" function in flatted can use attacker-controlled string values from the parsed JSON as direct array index keys, without validating t...
Attack Vector: NETWORK
Attack Complexity: LOW
Vulnerable Package
22 HIGH CVE-2026-33671 Npm-picomatch-4.0.3
detailsDescription: `picomatch` is vulnerable to Regular Expression Denial of Service (ReDoS) when processing crafted extglob patterns. Certain patterns using extglob ...
Attack Vector: NETWORK
Attack Complexity: LOW
Vulnerable Package
23 HIGH CVE-2026-33671 Npm-picomatch-2.3.1
detailsDescription: `picomatch` is vulnerable to Regular Expression Denial of Service (ReDoS) when processing crafted extglob patterns. Certain patterns using extglob ...
Attack Vector: NETWORK
Attack Complexity: LOW
Vulnerable Package
24 HIGH Cxf5fb15b0-6576 Npm-serialize-javascript-6.0.2
detailsRecommended version: 7.0.3
Description: serialize-javascript through 7.0.2 contains a code injection vulnerability due to improper escaping of "RegExp.flags" during serialization. Althoug...
Attack Vector: NETWORK
Attack Complexity: HIGH
Vulnerable Package
25 MEDIUM CVE-2025-13632 Npm-electron-39.2.1
detailsRecommended version: 39.8.4
Description: Inappropriate implementation in DevTools in Google Chrome prior to 143.0.7499.41 allowed an attacker who convinced a user to install a malicious ex...
Attack Vector: NETWORK
Attack Complexity: LOW
Vulnerable Package
26 MEDIUM CVE-2025-13635 Npm-electron-39.2.1
detailsRecommended version: 39.8.4
Description: Inappropriate implementation in Downloads in Google Chrome prior to 143.0.7499.41 allowed a local attacker to perform UI spoofing via a crafted HTM...
Attack Vector: LOCAL
Attack Complexity: LOW
Vulnerable Package
27 MEDIUM CVE-2025-13636 Npm-electron-39.2.1
detailsRecommended version: 39.8.4
Description: Inappropriate implementation in Split View in Google Chrome prior to 143.0.7499.41 allowed a remote attacker who convinced a user to engage in spec...
Attack Vector: NETWORK
Attack Complexity: LOW
Vulnerable Package
28 MEDIUM CVE-2025-13637 Npm-electron-39.2.1
detailsRecommended version: 39.8.4
Description: Inappropriate implementation in Downloads in Google Chrome prior to 143.0.7499.41 allowed a remote attacker who convinced a user to engage in speci...
Attack Vector: NETWORK
Attack Complexity: LOW
Vulnerable Package
29 MEDIUM CVE-2026-29085 Npm-hono-4.12.3
detailsRecommended version: 4.12.4
Description: Hono is a Web application framework that provides support for any JavaScript runtime. Prior to version 4.12.4, when using streamSSE() in Streaming ...
Attack Vector: NETWORK
Attack Complexity: LOW
Vulnerable Package
30 MEDIUM CVE-2026-29086 Npm-hono-4.12.3
detailsRecommended version: 4.12.4
Description: Hono is a Web application framework that provides support for any JavaScript runtime. Prior to version 4.12.4, the "setCookie()" utility did not va...
Attack Vector: NETWORK
Attack Complexity: LOW
Vulnerable Package
31 MEDIUM CVE-2026-3449 Npm-@tootallnate/once-2.0.0
detailsRecommended version: 3.0.1
Description: Versions of the package @tootallnate/once prior to 3.0.1 are vulnerable to Incorrect Control Flow Scoping in promise resolving when AbortSignal opt...
Attack Vector: LOCAL
Attack Complexity: LOW
Vulnerable Package
32 MEDIUM Use_Of_Hardcoded_Password /src/services/state-service/default-state.service.spec.ts: 63
detailsThe application uses the hard-coded password "secret-password" for authentication purposes, either using it to verify users' identities, or to ac...
Attack Vector
33 LOW CVE-2025-13640 Npm-electron-39.2.1
detailsRecommended version: 39.8.4
Description: Inappropriate implementation in Passwords in Google Chrome prior to 143.0.7499.41 allowed a local attacker to bypass authentication via physical ac...
Attack Vector: PHYSICAL
Attack Complexity: LOW
Vulnerable Package
34 LOW CVE-2025-69873 Npm-ajv-8.17.1
detailsRecommended version: 8.18.0
Description: ajv (Another JSON Schema Validator) through version 8.17.1 is vulnerable to Regular Expression Denial of Service (ReDoS) when the "$data" option is...
Attack Vector: LOCAL
Attack Complexity: HIGH
Vulnerable Package

@codecov

codecov Bot commented Mar 4, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 67.90123% with 156 lines in your changes missing coverage. Please review.
✅ Project coverage is 25.68%. Comparing base (444c9d5) to head (0d91212).
⚠️ Report is 34 commits behind head on main.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
src/services/environment/environment.service.ts 0.00% 49 Missing ⚠️
src/app/accounts/environment.component.ts 0.00% 25 Missing ⚠️
...rc/services/state-service/default-state.service.ts 88.57% 20 Missing and 4 partials ⚠️
src/app/services/services.module.ts 0.00% 18 Missing ⚠️
...c/services/state-service/stateMigration.service.ts 83.33% 3 Missing and 14 partials ⚠️
src/bwdc.ts 0.00% 8 Missing ⚠️
src/commands/config.command.ts 0.00% 5 Missing ⚠️
src/abstractions/environment.service.ts 0.00% 3 Missing ⚠️
src/app/app.component.ts 0.00% 2 Missing ⚠️
src/main.ts 0.00% 2 Missing ⚠️
... and 2 more
Additional details and impacted files
@@            Coverage Diff             @@
##            main    #1029       +/-   ##
==========================================
+ Coverage   6.79%   25.68%   +18.89%     
==========================================
  Files         67       73        +6     
  Lines       2798     2955      +157     
  Branches     483      539       +56     
==========================================
+ Hits         190      759      +569     
+ Misses      2576     2072      -504     
- Partials      32      124       +92     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@eliykat eliykat left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for tackling this! I think spending some time getting proper tests on stateService and stateMigrationService will give us some peace of mind that we won't get an influx of tickets on release.

Comment thread src/bwdc.ts Outdated
Comment thread src/app/services/services.module.ts Outdated
Comment thread src/app/services/services.module.ts Outdated
Comment thread src/app/services/services.module.ts Outdated
Comment thread src/app/services/services.module.ts Outdated
Comment thread src/services/state-service/stateMigration.service.ts
Comment thread src/services/state-service/stateMigration.service.ts
Comment thread src/services/state-service/stateMigration.service.ts
Comment thread src/services/state-service/stateMigration.service.ts Outdated
Comment thread src/services/environment/environment.service.ts Outdated
Comment thread src/bwdc.ts
@BTreston
BTreston requested a review from eliykat March 11, 2026 19:50
Comment thread src/services/state-service/default-state.service.spec.ts Fixed
Comment thread src/services/state-service/stateMigration.service.spec.ts Fixed
Comment thread src/services/state-service/stateMigration.service.spec.ts Fixed
@BTreston

Copy link
Copy Markdown
Contributor Author

@eliykat this is ready for another look when you have a moment, thanks.

- State v4 was never properly migrated, handle migration directly from v3
- fix access token not properly migrated
- fix environment urls not properly migrated
- update tests
- fix fresh install (missing state version) being set to v1 -> v5 (current)

@eliykat eliykat left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great job improving the tests for StateService and StateMigrationService in particular.

Comment thread src/services/state-service/default-state.service.ts
Comment thread src/abstractions/state.service.ts
Comment thread src/models/state.model.ts
Comment on lines +60 to +68
const ldapConfig = { ...account.directoryConfigurations.ldap };
if (
useSecureStorageForSecrets &&
ldapConfig.password &&
ldapConfig.password !== StoredSecurely
) {
await this.secureStorageService.save(SecureStorageKeys.ldap, ldapConfig.password);
ldapConfig.password = StoredSecurely;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this necessary? As long as we're migrating from plain storage to plain storage, and from secure storage to secure storage, I don't think we need to read the useSecureStorageForSecrets value. It'll just maintain wherever they have secrets stored at the moment.

Comment thread src/services/state-service/stateMigration.service.ts
@eliykat

eliykat commented Mar 21, 2026

Copy link
Copy Markdown
Member

I can't see that this comment has been addressed. Is it that the current secure storage prepends the orgId, and we're now dropping that?

@BTreston

Copy link
Copy Markdown
Contributor Author

I can't see that this comment has been addressed. Is it that the current secure storage prepends the orgId, and we're now dropping that?

Yes, sorry I forgot the address this in a comment. That is correct, they were prepended with the org id and this moved them off of that.

- Rename state.service.ts to default-state.service.ts
- Rename state.service.spec.ts to default-state.service.spec.ts
- Clean up state service interface to remove unused StorageOptions
- More type saftey for storage keys
- Clean up migration logic
Comment thread src/services/state-service/default-state.service.spec.ts Dismissed
@BTreston
BTreston requested a review from eliykat March 23, 2026 16:02

@eliykat eliykat left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only 1 actual change below, then feel free to pass to QA. I can approve when I'm back from OOO next week but that doesn't need to hold up QA.

Comment on lines +6 to +9
get: <T>(key: StorageKey | SecureStorageKey, options?: StorageOptions) => Promise<T>;
has: (key: StorageKey | SecureStorageKey, options?: StorageOptions) => Promise<boolean>;
save: (key: StorageKey | SecureStorageKey, obj: any, options?: StorageOptions) => Promise<any>;
remove: (key: StorageKey | SecureStorageKey, options?: StorageOptions) => Promise<any>;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

d'oh. Didn't realise both Storage and SecureStorage implemented the same interface, so this doesn't prevent keys from being mixed up between them. oh well :)

Comment thread src/services/state-service/stateMigration.service.ts
Comment on lines +77 to +78
await this.secureStorageService.save(SecureStorageKeys.ldap, ldapConfig.password);
ldapConfig.password = StoredSecurely;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Secure storage keys are migrated below, so I meant we don't have to deal with them at all here.

This section: migrate old plaintext keys -> new plaintext keys
Below: migrate secure storage keys -> secure storage keys

So here I would just do:

const ldapConfig = { ...account.directoryConfigurations.ldap };
await this.set(StorageKeys.directoryLdap, ldapConfig);

... and so on.

Let me know if this doesn't work for whatever reason.

@BTreston
BTreston requested a review from eliykat March 26, 2026 18:52
@sonarqubecloud

Copy link
Copy Markdown

@eliykat eliykat left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work on this, thanks!

@BTreston
BTreston merged commit 5e32170 into main Apr 6, 2026
39 of 41 checks passed
@BTreston
BTreston deleted the ac/pm-31159-state-service branch April 6, 2026 18:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants