import { NextResponse } from 'next/server' import type { NextRequest } from 'next/server' import { unsealData } from 'iron-session' import { sessionOptions, type SessionData } from '@/lib/session' const protectedRoutes = ['/dashboard', '/products', '/todos', '/ideas', '/settings', '/solo'] const authRoutes = ['/login', '/register'] const SAFE_METHODS = new Set(['GET', 'HEAD', 'OPTIONS']) // Paden die demo MAY aanroepen ook al zijn het non-GET — worden ingevuld na ST-1110.4 const DEMO_WRITE_ALLOWLIST = [ '/api/cron/', // machine-auth, irrelevant for demo ] export async function proxy(request: NextRequest) { const { pathname, method } = { pathname: request.nextUrl.pathname, method: request.method } // Demo-guard: block non-GET API writes for demo users (defense in depth) if ( pathname.startsWith('/api/') && !SAFE_METHODS.has(method) && !DEMO_WRITE_ALLOWLIST.some(p => pathname.startsWith(p)) ) { const raw = request.cookies.get(sessionOptions.cookieName)?.value if (raw) { const session = await unsealData(raw, { password: sessionOptions.password as string }) if (session.isDemo) { return NextResponse.json( { error: 'Niet beschikbaar in demo-modus' }, { status: 403 } ) } } } // Route protection: check cookie existence only — full validation in layout.tsx const hasSession = !!request.cookies.get(sessionOptions.cookieName)?.value const isProtected = protectedRoutes.some(r => pathname.startsWith(r)) const isAuthRoute = authRoutes.some(r => pathname.startsWith(r)) if (isProtected && !hasSession) { return NextResponse.redirect(new URL('/login', request.url)) } if (isAuthRoute && hasSession) { return NextResponse.redirect(new URL('/dashboard', request.url)) } return NextResponse.next() } export const config = { matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'], }