You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
fix(session): single flight refresh to avoid reuse detection logout #127
The auth API rotates refresh tokens and detects reuse. On reuse it does not just reject
the replayed token, it revokes the whole session chain, including the access token issued
by the legitimate rotation. A spike confirmed this: replaying a spent token returned 401 refresh_token_reused, and the previously working access token immediately began
returning 401.
That behaviour is correct, and it makes a client side guard mandatory rather than nice to
have. On mobile several screens can mount at once and race a refresh. Two concurrent
refreshes mean one of them replays a spent token, which signs the user out.
Scope
Ensure at most one refresh is in flight; concurrent callers await the same promise.
Callers that arrive during a refresh must receive the refreshed token, not trigger
another rotation.
Cover the race in tests, since it will not reproduce reliably by hand.
Notes
Applies to the web binding too. The web SDK is less exposed because the BFF holds the
refresh token, but the shared client should own the guard.
Shipped in #150: in bearer mode a 401 on an access call triggers one POST /refresh, concurrent callers await the same promise, the request is retried once, and a failed refresh clears the stored tokens. Covered by the transport tests, and exercised end to end against the adapter's reuse detection (a replayed refresh token answers 401 refresh_token_reused).
Activity
Bccorb commentedon Aug 1, 2026
Part of the React Native mobile template epic: fells-code/seamless-templates#40
feat(client): platform ports and a bearer transport with token custody
feat(client): platform ports and a bearer transport with token custody
Bccorb commentedon Sep 13, 2026
Shipped in #150: in bearer mode a 401 on an
accesscall triggers onePOST /refresh, concurrent callers await the same promise, the request is retried once, and a failed refresh clears the stored tokens. Covered by the transport tests, and exercised end to end against the adapter's reuse detection (a replayed refresh token answers401 refresh_token_reused).