29 lines
1.2 KiB
TypeScript
29 lines
1.2 KiB
TypeScript
import { NextResponse, type NextRequest } from "next/server"
|
|
|
|
// Route guard for the dashboard. (Next 16 renamed the `middleware` convention to `proxy`;
|
|
// this file is the same guard under the current name.)
|
|
//
|
|
// This is a PRESENCE CHECK ONLY, and deliberately so: `erp_at` is httpOnly and holds an
|
|
// RS256 JWT that only ERPCore can validate (docs/10 A.4), so the edge cannot tell whether
|
|
// it is real, expired, or forged. It exists purely so a logged-out user lands on /login
|
|
// instead of a dashboard full of 401s.
|
|
//
|
|
// The API remains the sole authority (docs/20-FRONTEND.md §3): every screen's data comes
|
|
// from calls that enforce auth server-side, and the client redirects to /login on a 401.
|
|
const ACCESS_COOKIE = "erp_at"
|
|
|
|
export default function proxy(request: NextRequest) {
|
|
const hasSession = request.cookies.has(ACCESS_COOKIE)
|
|
if (hasSession) return NextResponse.next()
|
|
|
|
const loginUrl = new URL("/login", request.url)
|
|
// Preserve where they were headed so login can send them back.
|
|
const { pathname, search } = request.nextUrl
|
|
if (pathname !== "/dashboard") loginUrl.searchParams.set("next", `${pathname}${search}`)
|
|
return NextResponse.redirect(loginUrl)
|
|
}
|
|
|
|
export const config = {
|
|
matcher: ["/dashboard/:path*"],
|
|
}
|