2026-05-29 17:22:33 +08:00
|
|
|
import type { NextRequest } from "next/server";
|
|
|
|
|
import { NextResponse } from "next/server";
|
|
|
|
|
import {
|
|
|
|
|
applyAuthResponseCookies,
|
|
|
|
|
type BackendHeaderBuildResult,
|
|
|
|
|
} from "@/lib/backend-auth";
|
2026-06-14 22:44:02 +08:00
|
|
|
import { isLocalOpsAccessHost } from "@/lib/ops-local-access";
|
2026-05-29 17:22:33 +08:00
|
|
|
|
|
|
|
|
function hasBearerAuth(request: NextRequest) {
|
|
|
|
|
const raw = request.headers.get("authorization");
|
|
|
|
|
if (!raw) return false;
|
|
|
|
|
const parts = raw.trim().split(/\s+/);
|
|
|
|
|
return parts.length === 2 && parts[0].toLowerCase() === "bearer" && Boolean(parts[1]);
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-14 22:44:02 +08:00
|
|
|
function isLocalOpsAccessRequest(request: NextRequest) {
|
|
|
|
|
const requestHost =
|
|
|
|
|
request.headers.get("x-forwarded-host") ||
|
|
|
|
|
request.headers.get("host") ||
|
|
|
|
|
request.nextUrl.host;
|
|
|
|
|
return (
|
|
|
|
|
isLocalOpsAccessHost(requestHost) ||
|
|
|
|
|
isLocalOpsAccessHost(request.nextUrl.hostname)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-29 17:22:33 +08:00
|
|
|
export function requireOpsProxyAuth(
|
|
|
|
|
request: NextRequest,
|
|
|
|
|
auth: BackendHeaderBuildResult,
|
|
|
|
|
): NextResponse | null {
|
2026-06-14 22:44:02 +08:00
|
|
|
if (isLocalOpsAccessRequest(request)) return null;
|
2026-05-29 17:22:33 +08:00
|
|
|
if (auth.authUserId || hasBearerAuth(request)) return null;
|
|
|
|
|
return applyAuthResponseCookies(
|
|
|
|
|
NextResponse.json(
|
|
|
|
|
{ error: "Unauthorized", detail: "Supabase session required" },
|
|
|
|
|
{ status: 401 },
|
|
|
|
|
),
|
|
|
|
|
auth.response,
|
|
|
|
|
);
|
|
|
|
|
}
|