import { NextRequest, NextResponse } from "next/server" import { verifySession } from "@/lib/auth" // Rutas públicas EXACTAS (coincidencia por segmento, no por prefijo). const publicExact = new Set([ "/login", "/api/auth/login", "/api/auth/logout", "/api/health", "/api/proxy/health", "/setup", ]) // Prefijos públicos: /api/cover (imágenes de portada para el sitio público), // assets de Next y fuentes. Coinciden a nivel de segmento: "/api/cover" NO // destapa "/api/cover/evil" ni otras rutas. const publicPrefixes = [ "/api/cover/", "/_next/", "/fonts/", ] // Páginas públicas del sitio (server-side, sin login). // "/" es MATCH EXACTO (startsWith("/") matchearía TODO). // "/gallery/" incluye el lector: cualquiera puede LEER (GET); las acciones // del panel (eliminar, etc.) quedan protegidas por el middleware vía método. const publicPages = ["/p/", "/tag/", "/gallery/", "/buscar"] // GET de lectura del proxy hacia el pipeline: solo las rutas que el LECTOR // público necesita (páginas, summary, artifacts, cover). /status y /queue // exponen info operativa interna -> requieren sesión. function isPublicProxyRead(pathname: string, method: string): boolean { if (method !== "GET" && method !== "HEAD") return false return pathname.startsWith("/api/proxy/galleries/") } function isPublicPath(pathname: string, method: string): boolean { if (pathname === "/") return true if (publicExact.has(pathname)) return true if (publicPrefixes.some((p) => pathname.startsWith(p))) return true if (publicPages.some((p) => pathname.startsWith(p))) return true if (isPublicProxyRead(pathname, method)) return true // /api/posts: GET de listado público; mutaciones requieren sesión. if (pathname === "/api/posts" && method === "GET") return true // /api/setup: GET (chequeo de config) público; POST (cambiar secrets) NO. if (pathname === "/api/setup" && method === "GET") return true return false } export async function middleware(req: NextRequest) { const { pathname } = req.nextUrl const method = req.method if (isPublicPath(pathname, method)) return NextResponse.next() const webPassword = process.env.WEB_PASSWORD if (!webPassword) return NextResponse.next() const session = req.cookies.get("session")?.value if (!session) { return NextResponse.redirect(new URL("/login", req.url)) } const payload = await verifySession(session) if (!payload || !payload.authenticated) { return NextResponse.redirect(new URL("/login", req.url)) } return NextResponse.next() } export const config = { matcher: ["/((?!_next/static|_next/image|favicon.ico).*)"], }