-
-
Notifications
You must be signed in to change notification settings - Fork 273
Labels
Description
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
accessTokenstorage architecture:accessTokenhaspersist: falsein state metadata, meaning it's not persisted directly to storage- Instead,
accessTokenis persisted inside the encrypted vault (seeVaultDatatype)
refreshAuthTokens()flow:- Calls
#refreshJWTToken()which returns newidTokens,accessToken, andmetadataAccessToken - Calls
authenticate()which only updatesstate.accessTokenin memory - Missing: No call to
#updateVault()to persist the newaccessTokento the encrypted vault
- Calls
submitPassword()flow:- Calls
#unlockVaultAndGetVaultData()which decrypts the vault - Restores
state.accessTokenfrom the vault data - Since the vault still contains the OLD
accessToken, the refreshed token is lost
- Calls
Steps to Reproduce
- Setup: User is authenticated with seedless onboarding and has an existing vault with stored
accessToken - Trigger token refresh:
- Wait for or simulate
accessTokenexpiration - Call
refreshAuthTokens()method - Verify
state.accessTokenis updated with the new token (in-memory)
- Wait for or simulate
- Lock the wallet:
- Call
setLocked()or equivalent to lock the wallet
- Call
- Unlock the wallet:
- Call
submitPassword(password)to unlock
- Call
- Observe the bug:
state.accessTokenis now the OLD token from the vault, not the refreshed token- Any API calls using
accessTokenmay 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
accessTokenwill fail after wallet unlock - Poor user experience: Users may need to re-authenticate unexpectedly
- Token inconsistency:
metadataAccessTokenandrefreshTokenare correctly persisted, butaccessTokenis not
Reactions are currently unavailable