import type { NextRequest } from 'next/server'; import { NextResponse } from 'next/server'; const OSS_TOKEN_COOKIE = 'dograh_auth_token'; // Paths that don't require authentication in OSS mode const PUBLIC_PATHS = ['/auth/login', '/auth/signup']; let cachedAuthProvider: string | null = null; async function fetchAuthProvider(): Promise { if (cachedAuthProvider) { return cachedAuthProvider; } try { const backendUrl = process.env.BACKEND_URL || 'http://localhost:8000'; const res = await fetch(`${backendUrl}/api/v1/health`); if (res.ok) { const data = await res.json(); cachedAuthProvider = (data.auth_provider as string) || 'local'; return cachedAuthProvider; } } catch { // Backend not reachable — fall back to local } cachedAuthProvider = 'local'; return cachedAuthProvider; } export async function middleware(request: NextRequest) { const authProvider = await fetchAuthProvider(); // Only handle OSS mode if (authProvider !== 'local') { return NextResponse.next(); } const token = request.cookies.get(OSS_TOKEN_COOKIE)?.value; const { pathname } = request.nextUrl; // Allow public paths without auth if (PUBLIC_PATHS.some((p) => pathname.startsWith(p))) { return NextResponse.next(); } // If no token, redirect to login if (!token) { const loginUrl = new URL('/auth/login', request.url); return NextResponse.redirect(loginUrl); } return NextResponse.next(); } // Configure which routes the middleware runs on export const config = { matcher: [ /* * Match all request paths except: * - api routes * - _next/static (static files) * - _next/image (image optimization files) * - favicon.ico (favicon file) * - public files (public folder) */ '/((?!api|_next/static|_next/image|favicon.ico|public).*)', ], };