Files
at-mintel/packages/gatekeeper/src/app/api/verify/route.ts
Marc Mintel e662415137
All checks were successful
Monorepo Pipeline / 🧪 Quality Assurance (push) Successful in 14m32s
Monorepo Pipeline / 🐳 Build Directus (Base) (push) Successful in 17s
Monorepo Pipeline / 🐳 Build Gatekeeper (Product) (push) Successful in 3m17s
Monorepo Pipeline / 🐳 Build Build-Base (push) Successful in 2m38s
Monorepo Pipeline / 🐳 Build Production Runtime (push) Successful in 21s
Monorepo Pipeline / 🚀 Release (push) Successful in 14m53s
feat: add gk_bypass
2026-02-07 16:02:52 +01:00

88 lines
2.6 KiB
TypeScript

import { NextRequest, NextResponse } from "next/server";
import { cookies } from "next/headers";
export async function GET(req: NextRequest) {
const cookieStore = await cookies();
const authCookieName =
process.env.AUTH_COOKIE_NAME || "mintel_gatekeeper_session";
const password = process.env.GATEKEEPER_PASSWORD || "mintel";
const session = cookieStore.get(authCookieName);
// 1. URL Parameter Bypass (for automated tests/staging)
const originalUrl = req.headers.get("x-forwarded-uri") || "/";
const host =
req.headers.get("x-forwarded-host") || req.headers.get("host") || "";
const proto = req.headers.get("x-forwarded-proto") || "https";
try {
const url = new URL(originalUrl, `${proto}://${host}`);
if (url.searchParams.get("gk_bypass") === password) {
// Remove the bypass parameter from the redirect URL
url.searchParams.delete("gk_bypass");
const cleanUrl = url.pathname + url.search;
const absoluteCleanUrl = `${proto}://${host}${cleanUrl}`;
const response = NextResponse.redirect(absoluteCleanUrl);
// Set the session cookie so the bypass is persistent
const isDev = process.env.NODE_ENV === "development";
const cookieDomain = process.env.COOKIE_DOMAIN;
const sessionValue = JSON.stringify({
identity: "Bypass",
timestamp: Date.now(),
});
response.cookies.set(authCookieName, sessionValue, {
httpOnly: true,
secure: !isDev,
path: "/",
maxAge: 30 * 24 * 60 * 60, // 30 days
sameSite: "lax",
...(cookieDomain ? { domain: cookieDomain } : {}),
});
return response;
}
} catch (e) {
// URL parsing failed, proceed with normal logic
}
let isAuthenticated = false;
let identity = "Guest";
if (session?.value) {
if (session.value === password) {
isAuthenticated = true;
} else {
try {
const payload = JSON.parse(session.value);
if (payload.identity) {
isAuthenticated = true;
identity = payload.identity;
}
} catch (e) {
// Fallback or old format
}
}
}
if (isAuthenticated) {
return new NextResponse("OK", {
status: 200,
headers: {
"X-Auth-User": identity,
},
});
}
// Traefik ForwardAuth headers
const gatekeeperUrl =
process.env.NEXT_PUBLIC_BASE_URL || `${proto}://gatekeeper.${host}`;
const absoluteOriginalUrl = `${proto}://${host}${originalUrl}`;
const loginUrl = `${gatekeeperUrl}/login?redirect=${encodeURIComponent(absoluteOriginalUrl)}`;
return NextResponse.redirect(loginUrl);
}