import { NextResponse, type NextRequest } from "next/server"; import { canAccessPath, getDefaultPathForRole, parseSessionCookie, SESSION_COOKIE, type UserRole } from "@/lib/auth"; import { DEFAULT_LOCALE, isLocale, LOCALE_COOKIE } from "@/lib/i18n"; const publicPaths = ["/login", "/forgot-password", "/reset-password", "/unauthorized", "/invite", "/auth"]; function isPublicPath(pathname: string) { return publicPaths.some((path) => pathname === path || pathname.startsWith(`${path}/`)); } async function decodeSessionCookie(value: string) { return (await parseSessionCookie(value)) as null | { role: UserRole }; } export async function middleware(request: NextRequest) { const { pathname } = request.nextUrl; const response = NextResponse.next(); if (pathname.startsWith("/_next") || pathname.includes(".")) { return response; } const sessionCookie = request.cookies.get(SESSION_COOKIE)?.value; const session = sessionCookie ? await decodeSessionCookie(sessionCookie) : null; const localeCookie = request.cookies.get(LOCALE_COOKIE)?.value; const acceptLanguage = request.headers.get("accept-language")?.toLowerCase() || ""; if (!localeCookie) { const detected = acceptLanguage.includes("id") ? "id" : acceptLanguage.includes("en") ? "en" : DEFAULT_LOCALE; response.cookies.set(LOCALE_COOKIE, detected, { path: "/", maxAge: 365 * 24 * 60 * 60, secure: process.env.NODE_ENV === "production", sameSite: "lax" }); } else if (!isLocale(localeCookie)) { response.cookies.set(LOCALE_COOKIE, DEFAULT_LOCALE, { path: "/", maxAge: 365 * 24 * 60 * 60, secure: process.env.NODE_ENV === "production", sameSite: "lax" }); } if (!session && !isPublicPath(pathname) && pathname !== "/") { const loginUrl = new URL("/login", request.url); loginUrl.searchParams.set("next", pathname); return NextResponse.redirect(loginUrl); } if (session && (pathname === "/" || pathname === "/login")) { return NextResponse.redirect(new URL(getDefaultPathForRole(session.role), request.url)); } if (session && !isPublicPath(pathname) && !canAccessPath(session.role, pathname)) { return NextResponse.redirect(new URL("/unauthorized", request.url)); } return response; } export const config = { matcher: ["/((?!api).*)"] };