kanban-dev-webapp/src/middleware.ts
Dave 65b0cf4f01 feat(middleware): carve out /intake/:path* from auth redirect
Phase 8a Task 6. The matcher's exclusion is unchanged; this is the
explicit short-circuit so a future matcher edit cannot accidentally
lock the public route out.
2026-09-21 01:59:56 +02:00

37 lines
No EOL
1.3 KiB
TypeScript

import { NextResponse, type NextRequest } from "next/server";
// From @/lib/auth/cookie, NOT @/lib/pb/server. Middleware runs on the Edge
// runtime, where `server-only` and `next/headers` do not exist.
import { AUTH_COOKIE } from "@/lib/auth/cookie";
/**
* A coarse redirect for signed-out visitors, nothing more.
*
* It checks only that a cookie is present — it does not validate the token and
* must never be relied on for authorization. Every route handler and page
* re-checks the session itself. Middleware runs before the request reaches
* them and is the wrong place to make security decisions.
*/
export function middleware(request: NextRequest) {
const hasAuth = request.cookies.has(AUTH_COOKIE);
// Public intake links have no session. The token IS the authentication,
// and the route's own checks enforce it. A redirect here would lock every
// visitor out of the wizard, so /intake/:path* is the one path the
// cookie check is allowed to ignore.
if (request.nextUrl.pathname.startsWith("/intake/")) {
return NextResponse.next();
}
if (!hasAuth) {
const url = request.nextUrl.clone();
url.pathname = "/login";
return NextResponse.redirect(url);
}
return NextResponse.next();
}
export const config = {
matcher: ["/", "/p/:path*", "/plan", "/admin/:path*"],
};