makearmy-app/middleware.ts

60 lines
1.8 KiB
TypeScript
Raw Normal View History

2025-09-26 15:19:19 -04:00
// middleware.ts
2025-09-27 14:30:16 -04:00
import { NextResponse, NextRequest } from "next/server";
2025-09-27 14:30:16 -04:00
const PUBLIC_PATHS = new Set<string>([
"/auth/sign-in",
"/auth/sign-up",
2025-09-27 14:41:56 -04:00
// add oauth/callback endpoints here if you use them, e.g.: "/auth/callback"
2025-09-27 14:30:16 -04:00
]);
2025-09-27 14:30:16 -04:00
export function middleware(req: NextRequest) {
2025-09-27 14:41:56 -04:00
const { pathname } = req.nextUrl;
2025-09-27 14:30:16 -04:00
const isAuthRoute = pathname.startsWith("/auth/");
const token = req.cookies.get("ma_at")?.value ?? "";
2025-09-27 14:41:56 -04:00
// If already authed and hitting an auth route, always go to the portal
2025-09-27 14:30:16 -04:00
if (token && isAuthRoute) {
const url = req.nextUrl.clone();
url.pathname = "/portal";
url.search = "";
return NextResponse.redirect(url);
2025-09-26 15:34:24 -04:00
}
2025-09-27 14:41:56 -04:00
// If not authed and path is protected → send to sign-in (no ?next=)
if (!token && !isPublicPath(pathname)) {
2025-09-27 14:30:16 -04:00
const url = req.nextUrl.clone();
url.pathname = "/auth/sign-in";
2025-09-27 14:41:56 -04:00
url.search = ""; // IMPORTANT: drop next so login always goes to /portal
2025-09-27 14:30:16 -04:00
return NextResponse.redirect(url);
2025-09-26 15:34:24 -04:00
}
return NextResponse.next();
}
2025-09-27 14:30:16 -04:00
// Helpers
function isPublicPath(pathname: string): boolean {
if (PUBLIC_PATHS.has(pathname)) return true;
2025-09-27 14:41:56 -04:00
// Static assets / internals
2025-09-27 14:30:16 -04:00
if (
pathname.startsWith("/_next/") ||
pathname.startsWith("/static/") ||
pathname.startsWith("/images/") ||
pathname === "/favicon.ico" ||
pathname === "/robots.txt" ||
pathname === "/sitemap.xml"
) return true;
2025-09-27 14:41:56 -04:00
// API routes aren't gated here; each route should enforce auth as needed
2025-09-27 14:30:16 -04:00
if (pathname.startsWith("/api/")) return true;
// Everything else is protected
return false;
}
2025-09-26 15:34:24 -04:00
export const config = {
2025-09-27 14:30:16 -04:00
matcher: [
"/((?!_next/static|_next/image|favicon.ico|robots.txt|sitemap.xml|images|static).*)",
],
2025-09-26 15:34:24 -04:00
};