Files
Epicure/apps/web/proxy.ts
T
Arnaud 292c7d6722 fix: favicon and PWA assets blocked by auth middleware
proxy.ts's matcher excluded favicon.ico but not icon.svg, the PWA
manifest, or the service worker — logged-out requests for any of them
got 307-redirected to /login instead of the actual asset, so browsers
silently gave up on the tab icon (and PWA install/offline support was
broken the same way). Exclude the same static-asset set favicon.ico
already had.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-09 03:22:35 +02:00

40 lines
1.3 KiB
TypeScript

import { NextRequest, NextResponse } from "next/server";
import { getSessionCookie } from "better-auth/cookies";
const PUBLIC_PATHS = ["/login", "/signup", "/verify-email", "/forgot-password", "/reset-password", "/api/auth", "/r/", "/u/", "/docs", "/api/v1/openapi.json", "/api/webhooks", "/api/v1/invites/"];
const ADMIN_PATHS = ["/admin"];
export async function proxy(request: NextRequest) {
const { pathname } = request.nextUrl;
const isPublic = PUBLIC_PATHS.some((p) => pathname.startsWith(p));
const isAdmin = ADMIN_PATHS.some((p) => pathname.startsWith(p));
const isApi = pathname.startsWith("/api/v1");
if (isPublic) return NextResponse.next();
const sessionCookie = getSessionCookie(request);
if (!sessionCookie) {
if (isApi) {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}
return NextResponse.redirect(new URL("/login", request.url));
}
if (isAdmin) {
// Role check happens inside admin pages — middleware only checks auth
// Full role verification requires DB lookup, done server-side in admin layout
}
return NextResponse.next();
}
export default proxy;
export const config = {
matcher: [
"/((?!_next/static|_next/image|favicon.ico|icon.svg|icon-192.svg|icon-512.svg|manifest.webmanifest|sw.js|public/).*)",
],
};