Skip to content

fix(frontend): update AuthContext user + isAuthenticated on silent token refresh (#560)#600

Merged
feyishola merged 2 commits into
Servora:mainfrom
Cybermaxi7:fix/auth-context-refresh-state
Jun 29, 2026
Merged

fix(frontend): update AuthContext user + isAuthenticated on silent token refresh (#560)#600
feyishola merged 2 commits into
Servora:mainfrom
Cybermaxi7:fix/auth-context-refresh-state

Conversation

@Cybermaxi7

Copy link
Copy Markdown
Contributor

closes #560\

The token-refresh interceptor in endpoints.ts wrote the new access token to tokenStorage and called notifyTokenRefreshed, but AuthContext's callback only ran setIsLoading(false) (a no-op when already loaded). Because isAuthenticated was derived by reading tokenStorage directly during render, nothing re-rendered after a background refresh, so consumers kept seeing stale/false auth state until the next 5-minute expiry check.

  • AuthContext: track the access token in React state (accessToken) and derive isAuthenticated from it, so it is reactive. The refresh callback now updates the reactive token (and the user, when the refresh response carries one) and re-renders consumers immediately. login/clearAuth/expiry-check keep the reactive token in sync; the callback is torn down on unmount.
  • tokens.ts: TokenRefreshCallback now forwards an optional user.
  • endpoints.ts: pass refreshResponse.user to notifyTokenRefreshed so the user object is refreshed too, not just the token.

Tests: AuthContext.test.tsx (4 cases) — refresh flips isAuthenticated to true and sets the user; user object updates from the refresh; expired refreshed token is ignored. All pass; tsc --noEmit clean on the changed files.

NOTE: npm run build is pre-existing-broken on main due to an unresolved merge conflict marker in src/pages/Verify.tsx (line 1 <<), unrelated to this change.

…ken refresh (Servora#560)

The token-refresh interceptor in endpoints.ts wrote the new access token to
tokenStorage and called notifyTokenRefreshed, but AuthContext's callback only
ran setIsLoading(false) (a no-op when already loaded). Because isAuthenticated
was derived by reading tokenStorage directly during render, nothing re-rendered
after a background refresh, so consumers kept seeing stale/false auth state
until the next 5-minute expiry check.

- AuthContext: track the access token in React state (`accessToken`) and derive
  isAuthenticated from it, so it is reactive. The refresh callback now updates
  the reactive token (and the user, when the refresh response carries one) and
  re-renders consumers immediately. login/clearAuth/expiry-check keep the
  reactive token in sync; the callback is torn down on unmount.
- tokens.ts: TokenRefreshCallback now forwards an optional `user`.
- endpoints.ts: pass refreshResponse.user to notifyTokenRefreshed so the user
  object is refreshed too, not just the token.

Tests: AuthContext.test.tsx (4 cases) — refresh flips isAuthenticated to true
and sets the user; user object updates from the refresh; expired refreshed token
is ignored. All pass; tsc --noEmit clean on the changed files.

NOTE: `npm run build` is pre-existing-broken on main due to an unresolved merge
conflict marker in src/pages/Verify.tsx (line 1 `<<`), unrelated to this change.
@drips-wave

drips-wave Bot commented Jun 28, 2026

Copy link
Copy Markdown

@Cybermaxi7 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@feyishola

Copy link
Copy Markdown
Contributor

@Cybermaxi7 pls resolve conflicts

@feyishola feyishola merged commit 0994b52 into Servora:main Jun 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AuthContext token refresh does not update user state in context

2 participants