Harden dashboard session handling and de-duplicate the demo route tree - #745
Merged
Jambox11 merged 1 commit intoAug 30, 2026
Conversation
|
@nasarajoe 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! 🚀 |
This was referenced Aug 31, 2026
Jambox11
pushed a commit
that referenced
this pull request
Aug 31, 2026
Expands the refresh-route test suite from 7 to 15 tests, covering gaps identified during the #745 audit: - Cookie secure flag when NODE_ENV=production - Caller's cookie header forwarded to upstream backend - Upstream auth headers (x-api-key, x-api-secret) propagated - Request body forwarded to backend - extractSessionToken handling all three response keys (token, accessToken, sessionToken) - No cookie set when backend response has no token field - Descriptive error message present in 503 response Also adds src/app/api/** to the default vitest coverage include list so route handler tests count toward reported coverage numbers. 🤖 Generated with Codebuff Co-authored-by: Codebuff <noreply@codebuff.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
Four related fixes to the developer-dashboard auth/session path and the parallel
/demo/dashboardtree. Without these, a stale or half-rehydrated session could render the real dashboard, wallet requests could go out unauthenticated on a token refresh, and the duplicate demo route tree could silently drift from production.#624 — Use
useSessionGuardon dashboard pagesThe documented client-side stale-session guard (
src/hooks/useSessionGuard.ts) was never imported —AuthGuardcarried a second, parallel copy of the same redirect logic.AuthGuardnow delegates its redirect touseSessionGuard().DashboardLayoutwraps every real/dashboard/*route inAuthGuard(requireAuthdefaults totrue;/demo/dashboard/*passesrequireAuth={false}), so the guard now runs across the whole production dashboard tree, with the demo tree as the explicit opt-out.src/hooks/__tests__/useSessionGuard.test.ts(loading / authenticated / unauthenticated / custom redirect target).AuthGuard.test.tsxstrengthened to assert the/login?callbackUrl=…redirect fires through the hook.#629 — Align
useWalletstoken storage key withAuthContextgetStoredAccessToken()already reads the shared session store (loadSession()→sessionStorage["mux-auth-session"]), which is exactly whereAuthContext.signInpersists the bearer block viasaveSession. Added an explicit round-trip regression test that drives the samecreateSession → saveSessioncallAuthContextmakes and assertsuseWalletssends that token — and keeps the existing "legacylocalStoragekey is ignored" guard.#630 — Retry
fetchWithAuthafter/api/auth/refreshon 401fetchWithAuthpreviously cleared the session and redirected on the first 401, unlikesrc/lib/api.jswhich refreshes and retries.fetchWithAuthnowPOSTs to/api/auth/refresh(refresh token pulled from the shared session store), persists any rotatedaccessToken, and retries the original request once with the new bearer token.mux_auth_sessioncookie) andwindow.location.replaceto/login?callbackUrl=….fetchWithAuth.test.tsrewritten: passthrough, refresh + retry with rotated token, cookie-only refresh, refresh-fails → redirect, retry-still-401 → redirect.#631 — De-duplicate
/demo/dashboardvs/dashboardsrc/app/demo/dashboard/api-keys/page.tsxis now a thinexport { default } from "@/app/dashboard/api-keys/page"— it was a near-identical copy that had drifted to a stale "Settings" page header.src/app/demo/dashboard/__tests__/route-parity.test.tsenumerates both route trees and fails if a route exists on only one side, unless it is in a reason-tagged allowlist (PROD_ONLY:api-keys/[id]/usage,settings/team;DEMO_ONLY:users). Adding a route to only one tree now requires a conscious, reviewed decision.Production vs demo/mock split
Explicit and unchanged in spirit:
requireAuthonDashboardLayoutgates the real tree;/demo/*opts out and sources mock data (useWallets({ demo: true }),/api/demo/*). No new secrets, noNEXT_PUBLIC_*token, no cookie-only auth without server verification./api/auth/refreshstill returns503in a production build with no backend.Docs
README.md—fetchWithAuthrefresh/retry contract,useSessionGuardwiring, demo/prod route split.src/docs/API_Hooks.md— same, plus a new "Stale-session guard (Use useSessionGuard on dashboard pages #624)" section.Tests
New/changed test files pass (
pnpm test <files>):useSessionGuard,AuthGuard,fetchWithAuth,useWallets,route-parity— 33 tests green. Runnable via the existingpnpm testscript.Closes #624
Closes #629
Closes #630
Closes #631