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
* feat: add session expiry warning toast before token refresh
Display a warning toast 2 minutes before session expires, giving
users a chance to extend their session via an action button. The
warning is dismissed automatically when the refresh timer fires
or when the component unmounts.
* fix: deduplicate concurrent refresh calls via shared in-flight promise
Move the in-flight guard from showSessionWarning's onClick into
refreshToken() itself using a ref-held promise. Both the toast action
and the background auto-refresh timer now share the same in-flight
request, preventing a race where a timer-triggered refresh could race
with a user-triggered one and log the user out on a transient 401.
Also adds a test covering the button+timer race scenario.
* fix: address CodeRabbit minor review comments
- updateToken() now returns boolean to propagate whether the token was
actually accepted (prevents false 'Session extended' on subdomain mismatch)
- refreshToken() propagates updateToken's boolean instead of unconditionally
returning true after a successful fetch
- Add warningActionInFlightRef to showSessionWarning onClick to prevent
duplicate toast chains when the user clicks rapidly (fetch is already
deduped; this guards the .then() handler attachment)
- Replace vi.runAllTimersAsync() with vi.advanceTimersByTimeAsync(0) in
success test to avoid triggering newly-scheduled long-delay timers
* fix: prevent stale refresh from reviving cleared session and keep CTA on failure
- Add auth generation counter (authGenerationRef) to updateToken; any
in-flight refresh captured a generation at call time and discards its
result if the generation changed (logout, 401, or tenant mismatch cleared
auth while the request was in flight)
- Only dismiss the session warning toast when the background timer-triggered
refresh actually succeeds; keeps the 'Extend session' CTA visible as a
manual recovery path when refresh fails transiently
- Update test: mock a successful fetch for the refresh-timer-dismisses-toast
case; add new test asserting toast stays visible on 5xx failure
* fix: reject already-expired tokens returned by the refresh endpoint
If /api/auth/refresh returns a token whose exp is already in the past,
the previous code would accept it as success and immediately re-enter
the expired-token refresh path on the next render. Guard with
isTokenExpired(parsed) before calling updateToken().
---------
Co-authored-by: Ben Coombs <bjcoombs@users.noreply.github.com>
0 commit comments