docs(02-01): complete Auth.js admin session plan summary

- SUMMARY.md for plan 02-01: next-auth@4 CredentialsProvider + proxy guard
- Documents two auto-fixed deviations (Next.js 16 proxy export name, Suspense boundary)
- Self-check PASSED: all files and commits verified
This commit is contained in:
Simone Cavalli
2026-05-15 10:43:30 +02:00
parent 69f8a7eae3
commit e7279ee957
@@ -0,0 +1,92 @@
---
phase: "02-admin-area-interactive-features"
plan: 01
subsystem: "auth"
tags: [next-auth, credentials, jwt, admin, session, middleware]
dependency_graph:
requires: []
provides: [admin-session-auth, admin-login-page, proxy-admin-guard]
affects: [src/proxy.ts, src/lib/auth.ts]
tech_stack:
added: [next-auth@4]
patterns: [CredentialsProvider, JWT session strategy, edge proxy guard]
key_files:
created:
- src/lib/auth.ts
- src/app/api/auth/[...nextauth]/route.ts
- src/app/admin/login/page.tsx
modified:
- src/proxy.ts
- package.json
- package-lock.json
- .env.local
decisions:
- "Keep proxy export named 'proxy' (not 'middleware') — Next.js 16 renamed the middleware concept back to proxy, breaking the plan's rename instruction"
- "Wrap useSearchParams() in Suspense boundary — required by Next.js App Router for static prerendering"
- "Single admin user, env-var credentials only — no DB users table (stateless JWT)"
metrics:
duration: "~15 minutes"
completed: "2026-05-15T08:42:35Z"
tasks_completed: 2
files_changed: 7
---
# Phase 02 Plan 01: Auth.js Admin Session + Proxy Guard Summary
Auth.js v4 CredentialsProvider with JWT sessions gates the entire /admin/* area using env-var credentials (no DB users table), with an edge proxy guard in src/proxy.ts that validates sessions via getToken() before any admin page code runs.
## What Was Built
### Task 1: next-auth@4 installation and auth config
- Installed `next-auth@4` (stable; v5 still RC as of 2026-05-15)
- Created `src/lib/auth.ts` — NextAuthOptions with CredentialsProvider reading `ADMIN_EMAIL` + `ADMIN_PASSWORD` from env vars; JWT session strategy (stateless, no DB adapter)
- Created `src/app/api/auth/[...nextauth]/route.ts` — NextAuth catch-all handler (GET + POST)
- Updated `.env.local` with `NEXTAUTH_URL`, `NEXTAUTH_SECRET` (32-byte base64), `ADMIN_EMAIL`, `ADMIN_PASSWORD`
### Task 2: Proxy guard and login page
- Extended `src/proxy.ts` with `/admin/*` session guard using `getToken()` from `next-auth/jwt`
- `/admin/login` and `/api/auth/*` exempted from the guard (pass-through)
- Unauthenticated `/admin/*` requests redirect to `/admin/login?callbackUrl=<original-path>`
- `/c/:path*` client token validation logic preserved verbatim from Phase 1
- matcher updated: `["/admin/:path*", "/c/:path*"]`
- Created `src/app/admin/login/page.tsx` — email+password Client Component with `signIn('credentials')`, inline error display ("Email o password non corretti."), redirect on success
## Commits
| Task | Commit | Description |
|------|--------|-------------|
| 1 | 5d363a6 | feat(02-01): install next-auth@4, configure CredentialsProvider auth |
| 2 | 69f8a7e | feat(02-01): extend proxy.ts with admin session guard, add login page |
## Deviations from Plan
### Auto-fixed Issues
**1. [Rule 1 - Bug] Next.js 16 proxy export name is 'proxy', not 'middleware'**
- **Found during:** Task 2 first build attempt
- **Issue:** The plan instructed renaming the export to `middleware` (Next.js 15 convention), but this project runs Next.js 16.2.6, which introduced the `proxy` concept and requires the function to be named `proxy`. The build failed with: "Proxy is missing expected function export name"
- **Fix:** Kept the export name as `proxy` — consistent with the existing Phase 1 file and Next.js 16 API
- **Files modified:** `src/proxy.ts`
**2. [Rule 1 - Bug] useSearchParams() requires Suspense boundary in App Router**
- **Found during:** Task 2 second build attempt
- **Issue:** `useSearchParams()` in a Client Component causes a build failure during static page generation without a Suspense boundary. Error: "useSearchParams() should be wrapped in a suspense boundary at page /admin/login"
- **Fix:** Extracted the form into `AdminLoginForm` component; wrapped it in `<Suspense>` inside the default export `AdminLoginPage`
- **Files modified:** `src/app/admin/login/page.tsx`
## Known Stubs
None — all implemented functionality is complete and functional.
## Threat Surface Scan
No new security surface beyond what was planned in the threat model:
- T-02-01: Mitigated — CredentialsProvider validates against env vars server-side
- T-02-02: Mitigated — JWT signed with NEXTAUTH_SECRET, verified via getToken() on every /admin request
- T-02-03: Mitigated — ADMIN_PASSWORD stored only in .env.local (gitignored) and Vercel secrets
- T-02-04: Accepted — /api/auth/* exempt by design, NextAuth handles its own CSRF
- T-02-05: Accepted — No rate limiting in v1
## Self-Check: PASSED
All created files exist on disk. Both task commits (5d363a6, 69f8a7e) verified in git log.