import { NextResponse } from "next/server"; import type { NextRequest } from "next/server"; // PWA static assets — must bypass auth entirely. // If the SW or manifest gets a 302→login, the browser registers the login // page as the service worker, which breaks auth for the entire PWA session. const pwaAssets = [ "/sw.js", "/sw.js.map", "/manifest.webmanifest", "/~offline", "/icons/", "/serwist-", ]; // Public routes that don't require authentication const publicRoutes = [ "/", "/pricing", "/privacy", "/terms", "/login", "/admin-login", "/m", "/invite", "/verify", "/api/auth/signin", "/api/admin/auth", "/api/onboarding", "/api/profile", ]; // Protected API routes that need authentication const protectedApiRoutes = [ "/api/children", "/api/logs", "/api/growth", "/api/vaccinations", "/api/medicines", "/api/allergies", "/api/illnesses", "/api/visits", "/api/family", "/api/families", "/api/invites", "/api/notifications", "/api/upload", "/api/chat", "/api/history", "/api/family/members", ]; export function middleware(request: NextRequest) { const { pathname } = request.nextUrl; // Always pass PWA assets through — never redirect to login for (const asset of pwaAssets) { if (pathname === asset || pathname.startsWith(asset)) { return NextResponse.next(); } } // Always allow public routes for (const route of publicRoutes) { if (pathname === route || pathname.startsWith(route + "/")) { return NextResponse.next(); } } // Check session cookie for protected routes const sessionToken = request.cookies.get("tia_session")?.value; const adminSessionToken = request.cookies.get("tia_admin_session")?.value; // Allow admin routes with admin session if (pathname.startsWith("/api/admin") && adminSessionToken) { return NextResponse.next(); } // For protected API routes, require session for (const route of protectedApiRoutes) { if (pathname.startsWith(route)) { if (!sessionToken && !adminSessionToken) { return NextResponse.json({ error: "Authentication required" }, { status: 401 }); } break; } } return NextResponse.next(); } export const config = { matcher: [ "/api/:path*", "/((?!_next/static|_next/image|favicon.ico).*)", ], };