LumenDev Invoice file map for auth. Reusable pattern (templates, packages, env contract): [[Resources/Tech/Auth.js/Auth.js Next.js JWT Google MongoDB adapter pattern]]. This note lists this repo’s paths and APIs only. App operator detail: docs/utility/authentication.md, AGENTS.md.
| Layer | File | Role |
| ----- | ---- | ---- |
| Edge-safe config | src/auth.config.ts | No mongodb import. Exports NextAuthConfig: Google provider, pages.signIn, session.strategy: "jwt", trustHost, JWT/session callbacks that copy user.id into token and session.user.id. Consumed by middleware only. |
| Full app auth | src/auth.ts | NextAuth({ ...authConfig, adapter: MongoDBAdapter(clientPromise) }) → exports handlers, auth, signIn, signOut. |
Middleware must not load the MongoDB driver (historically Edge / bundle issues). Route handlers and auth() run in Node and can use the adapter.
session.strategy: "jwt" in auth.config.ts).maxAge: 30 * 24 * 60 * 60 (30 days).src/types/next-auth.d.ts extends Session.user with required id: string; JWT module adds optional id on the token.jwt sets token.id from user.id on first sign-in; session copies token.id to session.user.id.| Path | Implementation |
| ---- | -------------- |
| Auth catch-all | src/app/api/auth/[...nextauth]/route.ts re-exports GET / POST from handlers in src/auth.ts. |
| Sign-in UI | src/app/sign-in/page.tsx — client page; signIn("google", { callbackUrl }) via next-auth/react; callbackUrl from query or default /. |
File: src/middleware.ts.
auth via NextAuth(authConfig) only (no adapter).pathname under /api/auth, /_next, /sign-in, /favicon.ico./api/*: respond 401 JSON { error: "Unauthorized" }./sign-in with callbackUrl = path + search.config.matcher in file).requireSession)File: src/lib/requireSession.ts. Imports auth from @/auth (full config + adapter).
requireSession() → { session } or { error: NextResponse.json(..., 401) } if session.user.id missing.requireSessionResponse() → null or a 401 response (helper variant).Used in (grep-verified): src/app/api/invoices/route.ts, invoices/[id]/route.ts, invoices/[id]/activity/route.ts, invoices/next-number/route.ts, invoices/migrate/route.ts, projects/route.ts, projects/[id]/route.ts, settings/company/route.ts.
Migrate: POST /api/invoices/migrate remains session-protected and should only run when NODE_ENV === "development" (app policy — see handler).
src/lib/mongodb-auth.ts — native MongoClient, MONGODB_URI (fallback mongodb://localhost:27017/lumendev-invoice in code if env unset; startup assertEnv still requires MONGODB_URI in practice)._mongoAuthClientPromise reuse to avoid connection spam during HMR.users, accounts, sessions, verification_tokens, etc.) live in the same database as Mongoose — not the same ODM; two persistence stacks on one URI.src/components/AuthSessionProvider.tsx — wraps app with SessionProvider from next-auth/react.src/app/layout.tsx wraps children with AuthSessionProvider so client hooks and signIn work under App Router.Strict validation: src/env.ts assertEnv() — imported from next.config.ts so next dev / next build / next start exit if missing:
AUTH_SECRET or NEXTAUTH_SECRETAUTH_GOOGLE_ID, AUTH_GOOGLE_SECRETMONGODB_URIAUTH_URL or NEXTAUTH_URLAUTH_TRUST_HOST: not in assertEnv; trustHost in config is true when NODE_ENV === "development" or AUTH_TRUST_HOST===true (needed on Vercel previews / inferred host). Detail: app AGENTS.md and docs/utility/authentication.md.
docs/utility/authentication.md, AGENTS.md, src/auth.ts, src/auth.config.ts, src/middleware.ts