⚠ This page is served via a proxy. Original site: https://github.com
This service does not collect credentials or authentication data.
Skip to content

New accessToken from refreshAuthTokens() not persisted to vault #7805

@lwin-kyaw

Description

@lwin-kyaw

Description

When refreshAuthTokens() is called to refresh expired tokens, the new accessToken is only stored in the in-memory state via authenticate(), but is never persisted to the vault. This causes the new accessToken to be overwritten by the old accessToken from the vault when the user unlocks their wallet via submitPassword().

Root Cause Analysis

  1. accessToken storage architecture:
    • accessToken has persist: false in state metadata, meaning it's not persisted directly to storage
    • Instead, accessToken is persisted inside the encrypted vault (see VaultData type)
  2. refreshAuthTokens() flow:
    • Calls #refreshJWTToken() which returns new idTokens, accessToken, and metadataAccessToken
    • Calls authenticate() which only updates state.accessToken in memory
    • Missing: No call to #updateVault() to persist the new accessToken to the encrypted vault
  3. submitPassword() flow:
    • Calls #unlockVaultAndGetVaultData() which decrypts the vault
    • Restores state.accessToken from the vault data
    • Since the vault still contains the OLD accessToken, the refreshed token is lost

Steps to Reproduce

  1. Setup: User is authenticated with seedless onboarding and has an existing vault with stored accessToken
  2. Trigger token refresh:
    • Wait for or simulate accessToken expiration
    • Call refreshAuthTokens() method
    • Verify state.accessToken is updated with the new token (in-memory)
  3. Lock the wallet:
    • Call setLocked() or equivalent to lock the wallet
  4. Unlock the wallet:
    • Call submitPassword(password) to unlock
  5. Observe the bug:
    • state.accessToken is now the OLD token from the vault, not the refreshed token
    • Any API calls using accessToken may fail due to using the stale token

Expected Behavior

After calling refreshAuthTokens(), the new accessToken should be persisted to the vault so that subsequent submitPassword() calls restore the refreshed token.

Actual Behavior

The new accessToken from refreshAuthTokens() exists only in memory and is lost when:

  • The wallet is locked and unlocked
  • The app is restarted (since persist: false)

Impact

  • Authentication failures: Services relying on accessToken will fail after wallet unlock
  • Poor user experience: Users may need to re-authenticate unexpectedly
  • Token inconsistency: metadataAccessToken and refreshToken are correctly persisted, but accessToken is not

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions