Commit 83c8c70
fix: force token refresh and clear cookies on failure to avoid logout loop (#511)
* fix: force token refresh and clear cookies on failure to avoid logout loop
Switch the token-refresh route from `auth.api.getAccessToken` (which only
refreshes inside Better Auth's 5s threshold) to `auth.api.refreshToken`
(unconditional refresh). This eliminates the 5–10s race window where the
caller's near-expiry margin would redirect to the route but Better Auth
would return 200 OK with no Set-Cookie, sending the browser back into a
redirect loop ("page isn't redirecting properly").
On refresh failure, call `auth.api.signOut` and forward its Set-Cookie
headers onto the /signin redirect so `session_token` and `account_data`
are actually cleared — otherwise the stale account_data cookie keeps
`isTokenNearExpiry` returning true and the user can fall back into the
loop on the next navigation.
Also export the handler as both GET and POST: Next.js `redirect()` uses
307 (method-preserving) outside Server Actions, so a redirect triggered
from a Server Component render that follows a Server Action POST would
otherwise hit this route as POST and 405.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore: bump next + transitive deps to clear pnpm audit advisories
- next 16.2.3 → 16.2.6 (clears GHSA advisories for App Router middleware
bypass, image-API DoS, SSRF, RSC cache poisoning, beforeInteractive XSS,
etc.)
- pnpm.overrides: hono ≥4.12.18 (cache middleware Vary leakage, CSS-in-style
injection, JWT NumericDate validation)
- pnpm.overrides: kysely ≥0.28.17 (JSON-path traversal)
- pnpm.overrides: fast-uri ≥3.1.2 (path traversal + host confusion via ajv)
- pnpm.overrides: ip-address ≥10.1.1 (XSS in Address6 HTML emitters via
@modelcontextprotocol/sdk → express-rate-limit)
`pnpm audit` now reports no known vulnerabilities.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix: pin kysely override to 0.28.x to satisfy better-auth adapter
kysely@0.29 dropped the root re-exports of `DEFAULT_MIGRATION_LOCK_TABLE`
and `DEFAULT_MIGRATION_TABLE` (moved under `kysely/migration`), which
@better-auth/kysely-adapter@1.6.2 still imports from the root entry. The
prior `kysely >=0.28.17` override therefore floated to 0.29.2 and broke
the Turbopack build with 12 module-export errors (this also cascaded into
the Playwright E2E job, which builds before running).
Pin to `>=0.28.17 <0.29.0`: still covers the JSON-path traversal CVE
(advisory GHSA, patched in 0.28.17) without bumping past the adapter's
compatibility line.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix: use 303 See Other for outbound redirects to avoid 405 on POST flow
`NextResponse.redirect()` defaults to 307 (method-preserving). Now that this
route also accepts POST (added in the previous commit), a refresh that
arrived via POST would have its outbound redirect to /catalog or /signin
sent as POST too — both of which only handle GET, producing 405.
Switch both the success and failure redirects to 303 See Other, which
unconditionally instructs the browser to follow with GET. Caught by Copilot
review on the PR.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent 1f4fa0c commit 83c8c70
4 files changed
Lines changed: 291 additions & 149 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
60 | 60 | | |
61 | 61 | | |
62 | 62 | | |
63 | | - | |
| 63 | + | |
64 | 64 | | |
65 | 65 | | |
66 | 66 | | |
| |||
116 | 116 | | |
117 | 117 | | |
118 | 118 | | |
119 | | - | |
| 119 | + | |
120 | 120 | | |
121 | 121 | | |
122 | 122 | | |
123 | 123 | | |
124 | | - | |
| 124 | + | |
125 | 125 | | |
126 | 126 | | |
127 | 127 | | |
128 | 128 | | |
129 | 129 | | |
130 | | - | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
131 | 133 | | |
132 | 134 | | |
133 | 135 | | |
0 commit comments