Skip to content

Guard loadAccount() responses against stale rehydration after a session lock #2813

@JakeUrban

Description

@JakeUrban

Follow-up from #2082 (auto-lock UI flip).

Context

PR #2802 added a background→popup SESSION_LOCKED broadcast plus a lockAccount reducer so all open extension UIs flip to the unlock screen as soon as the idle alarm fires. Internal review-fix round 1 identified that several call sites still do const result = await loadAccount(); dispatch(saveAccount(result)); with no guard against the response arriving after a lock event. Specifically:

  • extension/src/popup/helpers/hooks/useGetAppData.tsx:67-73
  • extension/src/popup/helpers/hooks/useGetSubmitAccountData.tsx:27-37
  • extension/src/popup/helpers/hooks/useGetRecoverAccountData.ts:25-35

If the user is auto-locked while one of these requests is in flight, the late response can saveAccount(...) over the cleared state, briefly rehydrating private-key state in the redux store after we've intentionally cleared it.

The fix in #2802 keeps the navigation push race-free (the listener dispatches lockAccount synchronously before navigating), so this issue does not block the UI flip. But it is a latent correctness bug that the lock broadcast made more visible.

What needs to happen

Introduce a session-epoch guard (or equivalent invalidation token) shared by the auth slice and the data-loading hooks, such that saveAccount(result) only applies when result.epoch === currentEpoch. lockAccount / signOut / account-switch reducers increment the epoch, invalidating in-flight loads.

Add tests covering:

  • loadAccount() resolves after a SESSION_LOCKED broadcast — store remains locked.
  • loadAccount() resolves after signOut — store remains signed-out.

Dependencies

None. Independent of #2082 and the broadcast-generalization follow-up.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    follow-upFollow-up from another issue or PR

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions