docs: learning — Auth.js v5 Edge split + session expiry redirect pattern

This commit is contained in:
2026-04-03 10:42:31 +02:00
parent bf8577dbaf
commit 339ae47540
+36
View File
@@ -7,6 +7,42 @@
## Learnings
### 2026-04-03 | Auth | Session expiry redirect — Auth.js v5 + Edge runtime split
**Problem:** Auth.js `authorize()` callback uses `@node-rs/argon2` (native module, not Edge-compatible). Using `auth()` directly in `middleware.ts` would pull argon2 into the Edge bundle and crash.
**Solution — split config pattern:**
- `auth.config.ts` — edge-safe subset: `pages`, `session`, `cookies`, no providers, no callbacks that touch DB or argon2
- `auth-edge.ts``NextAuth(authConfig)` with the lean config; used only by middleware
- `auth.ts` — spreads `authConfig`, adds Credentials provider + argon2 callbacks + prisma session tracking
**Middleware wrapping:**
```ts
import { auth } from "./server/auth-edge.js";
export default auth(function middleware(request) {
if (!isPublicPath(pathname) && !request.auth) {
return NextResponse.redirect(new URL("/auth/signin", request.url));
}
// CSP logic...
});
```
**Three-layer defence:**
1. Middleware — server-side redirect before page renders
2. `SessionGuard` client component — `useSession()``router.replace()` on SPA navigation
3. `QueryCache` / `MutationCache` in TRPCProvider — UNAUTHORIZED tRPC errors → `window.location.replace()`
**Test mock pattern for middleware tests:**
```ts
vi.mock("./server/auth-edge.js", () => ({
auth: (handler) => (req) =>
handler(Object.assign(req, { auth: { user: { id: "test-user" } } })),
}));
```
Needed because `vi.resetModules()` inside the helper function doesn't re-apply top-level mocks — always declare `vi.mock(...)` at file scope.
---
### 2026-04-02 | DevOps | Gitea API token location
**Token:** `~/.gitea-token` (chmod 600, never committed to repo)