Skip to content

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

Open
BTreston wants to merge 12 commits intomainfrom
ac/pm-31159-state-service
Open

[PM-31159] Full state service re-write#1029
BTreston wants to merge 12 commits intomainfrom
ac/pm-31159-state-service

Conversation

@BTreston
Copy link
Contributor

@BTreston BTreston commented Mar 4, 2026

🎟️ 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
Copy link
Contributor

github-actions bot commented Mar 4, 2026

Logo
Checkmarx One – Scan Summary & Detailscb762d28-126b-4697-be68-c3109f4971fe


New Issues (30) 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 CRITICAL CVE-2026-3545 Npm-electron-39.2.1
detailsDescription: Insufficient data validation in Navigation in Google Chrome prior to 145.0.7632.159 allowed a remote attacker to potentially perform a sandbox esca...
Attack Vector: NETWORK
Attack Complexity: LOW
Vulnerable Package
3 HIGH CVE-2025-13042 Npm-electron-39.2.1
detailsRecommended version: 41.0.0
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
4 HIGH CVE-2025-13223 Npm-electron-39.2.1
detailsRecommended version: 41.0.0
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-13224 Npm-electron-39.2.1
detailsRecommended version: 41.0.0
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
6 HIGH CVE-2025-13631 Npm-electron-39.2.1
detailsRecommended version: 41.0.0
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
7 HIGH CVE-2025-13633 Npm-electron-39.2.1
detailsRecommended version: 41.0.0
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
8 HIGH CVE-2025-13638 Npm-electron-39.2.1
detailsRecommended version: 41.0.0
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
9 HIGH CVE-2025-13639 Npm-electron-39.2.1
detailsRecommended version: 41.0.0
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
10 HIGH CVE-2025-13720 Npm-electron-39.2.1
detailsRecommended version: 41.0.0
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
11 HIGH CVE-2025-13721 Npm-electron-39.2.1
detailsRecommended version: 41.0.0
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
12 HIGH CVE-2026-0628 Npm-electron-39.2.1
detailsRecommended version: 41.0.0
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
13 HIGH CVE-2026-1861 Npm-electron-39.2.1
detailsRecommended version: 41.0.0
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
14 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
15 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
16 HIGH CVE-2026-31802 Npm-tar-6.2.1
detailsRecommended version: 7.5.11
Description: node-tar is a full-featured Tar for Node.js. Prior to version 7.5.11, tar (npm) can be tricked into creating a symlink that points outside the extr...
Attack Vector: LOCAL
Attack Complexity: LOW
Vulnerable Package
17 HIGH CVE-2026-31802 Npm-tar-7.5.9
detailsRecommended version: 7.5.11
Description: node-tar is a full-featured Tar for Node.js. Prior to version 7.5.11, tar (npm) can be tricked into creating a symlink that points outside the extr...
Attack Vector: LOCAL
Attack Complexity: LOW
Vulnerable Package
18 HIGH CVE-2026-3536 Npm-electron-39.2.1
detailsDescription: Integer overflow in ANGLE in Google Chrome prior to 145.0.7632.159 allowed a remote attacker to potentially perform out of bounds memory access via...
Attack Vector: NETWORK
Attack Complexity: LOW
Vulnerable Package
19 HIGH CVE-2026-3540 Npm-electron-39.2.1
detailsRecommended version: 41.0.0
Description: Inappropriate implementation in WebAudio in Google Chrome prior to 145.0.7632.159 allowed a remote attacker to perform out of bounds memory access ...
Attack Vector: NETWORK
Attack Complexity: LOW
Vulnerable Package
20 HIGH CVE-2026-3543 Npm-electron-39.2.1
detailsRecommended version: 41.0.0
Description: Inappropriate implementation in V8 in Google Chrome prior to 145.0.7632.159 allowed a remote attacker to potentially perform out of bounds memory a...
Attack Vector: NETWORK
Attack Complexity: LOW
Vulnerable Package
21 MEDIUM CVE-2025-13632 Npm-electron-39.2.1
detailsRecommended version: 41.0.0
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
22 MEDIUM CVE-2025-13635 Npm-electron-39.2.1
detailsRecommended version: 41.0.0
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
23 MEDIUM CVE-2025-13636 Npm-electron-39.2.1
detailsRecommended version: 41.0.0
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
24 MEDIUM CVE-2025-13637 Npm-electron-39.2.1
detailsRecommended version: 41.0.0
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
25 MEDIUM CVE-2026-2317 Npm-electron-39.2.1
detailsRecommended version: 41.0.0
Description: Inappropriate implementation in Animation in Google Chrome prior to 145.0.7632.45 allowed a remote attacker to leak cross-origin data via a crafted...
Attack Vector: NETWORK
Attack Complexity: LOW
Vulnerable Package
26 MEDIUM Use_Of_Hardcoded_Password /src/services/state-service/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
27 MEDIUM Use_Of_Hardcoded_Password /src/services/state-service/stateMigration.service.spec.ts: 373
detailsThe application uses the hard-coded password "super-secret" for authentication purposes, either using it to verify users' identities, or to acces...
Attack Vector
28 MEDIUM Use_Of_Hardcoded_Password /src/services/state-service/stateMigration.service.spec.ts: 368
detailsThe application uses the hard-coded password "user-ldap-pass" for authentication purposes, either using it to verify users' identities, or to ac...
Attack Vector
29 LOW CVE-2025-13640 Npm-electron-39.2.1
detailsRecommended version: 41.0.0
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
30 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
Copy link

codecov bot commented Mar 4, 2026

Codecov Report

❌ Patch coverage is 70.47244% with 150 lines in your changes missing coverage. Please review.
✅ Project coverage is 25.90%. Comparing base (444c9d5) to head (d553f75).
⚠️ Report is 6 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 ⚠️
src/services/state-service/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 91.12% 1 Missing and 10 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.90%   +19.11%     
==========================================
  Files         67       73        +6     
  Lines       2798     2957      +159     
  Branches     483      535       +52     
==========================================
+ Hits         190      766      +576     
+ Misses      2576     2074      -502     
- Partials      32      117       +85     

☔ 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.

Copy link
Member

@eliykat eliykat left a comment

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.

Copy link
Member

Choose a reason for hiding this comment

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

I think we should consider removing the old migrations and just throwing if the stateVersion is not the minimum we expect. Account switching was released ~4 years ago, if you haven't opened DC since then you can just go download a fresh copy. Please check with Priya though.

Then you could just delete the legacy keys rather than moving them to their own file.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We have the okay from Priya 👍

Copy link
Member

Choose a reason for hiding this comment

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

Any ideas for testing this? e.g. could you configure the current DC version, then copy/paste your actual data.json into the code, then run a migration and assert the outcome?

I believe we have tests for it in the clients repo - the migration service has evolved a bit but should still give you the idea.

Copy link
Member

Choose a reason for hiding this comment

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

Assuming the secure storage keys are changing, we're missing the following migrations:

- accessToken
- refreshToken
- apiKeyClientId
- apiKeyClientSecret
- twoFactorToken (if required)

Comment on lines +304 to +305
// @TODO Keep old key for now - will remove in future release
// await this.secureStorageService.remove(oldKey);
Copy link
Member

Choose a reason for hiding this comment

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

I don't disagree, but this migration will only run once. This would need to be done in a separately versioned migration.

Comment on lines +19 to +33
const normalized = new EnvironmentUrls();

for (const [key, value] of Object.entries(urls)) {
if (!value || typeof value !== "string") {
continue;
}

let url = value.trim();
url = url.replace(/\/+$/, ""); // Remove trailing slashes

if (!/^https?:\/\//i.test(url)) {
url = `https://${url}`;
}

normalized[key as keyof EnvironmentUrls] = url;
Copy link
Member

@eliykat eliykat Mar 7, 2026

Choose a reason for hiding this comment

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

This was neater in its own private method. I think Claude may be over-optimizing.

@BTreston BTreston requested a review from eliykat March 11, 2026 19:50
@BTreston
Copy link
Contributor Author

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

@sonarqubecloud
Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
E Security Rating on New Code (required ≥ D)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

@eliykat
Copy link
Member

eliykat commented Mar 14, 2026

Code Review Summary

Overall Assessment: This PR implements a well-structured rewrite of the state service, moving from an account-based hierarchy to a simpler flat key-value structure. The changes are comprehensive and include proper test coverage.

What was reviewed:

  • State service implementation (state.service.ts)
  • State migration logic (stateMigration.service.ts)
  • Token service integration
  • Environment service changes
  • CLI and Electron main process integration
  • Test coverage for state and migration services

Strengths:

  • Clean architecture: The flat key-value approach significantly simplifies state management
  • Proper secret handling: Credentials are correctly stored in secure storage with StoredSecurely placeholders in regular storage
  • Comprehensive migration: The v4 -> v5 migration handles edge cases including null account data, partial data, and Azure -> Entra ID backwards compatibility
  • Good test coverage: Unit tests properly verify secure storage behavior, migration paths, and round-trip operations
  • Minimum version enforcement: Migration correctly throws for state versions below v4, preventing data corruption from very old installations

Items verified as non-issues:

  • main.ts null dependencies: The Electron main process creates DefaultStateService with null secureStorageService and stateMigrationService. This is safe because:
    • Only window/tray methods are called, which use storageService (not secureStorageService)
    • init() is never called on this instance, so null stateMigrationService doesn't cause issues

Minor observations (not blocking):

  • The migration intentionally keeps old {userId}_* secure storage keys for removal in a future v5->v6 migration - this is documented in comments
  • The getConfiguration() switch statement has no default case, but invalid DirectoryType values would return undefined which is handled by callers

The PR addresses the previous review feedback well and the implementation is solid. No blocking issues found.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants