Files
flatrender/src/app/api/admin/_adminProxy.ts
T

52 lines
1.4 KiB
TypeScript
Raw Normal View History

/**
* Shared helper for admin action proxy routes.
* Validates the caller is an admin (checks is_admin in the JWT), then
* proxies the action to the V2 gateway.
*/
import { type NextRequest, NextResponse } from "next/server";
import { gatewayUrl } from "@/lib/api/gateway";
import { getAccessToken } from "@/lib/auth/session";
import { decodeJwt } from "@/lib/auth/jwt";
export async function adminProxy(
_req: NextRequest,
gatewayPath: string,
method: string = "POST"
): Promise<NextResponse> {
const token = await getAccessToken();
if (!token) {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}
// Quick admin check on the server side before forwarding
const claims = decodeJwt(token);
const isAdmin =
String(claims?.is_admin) === "true" ||
claims?.is_admin === true ||
String(claims?.is_tenant_admin) === "true";
if (!isAdmin) {
return NextResponse.json({ error: "Forbidden" }, { status: 403 });
}
const res = await fetch(gatewayUrl(gatewayPath), {
method,
cache: "no-store",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
});
if (!res.ok) {
const err = await res.json().catch(() => null) as { message?: string } | null;
return NextResponse.json(
{ error: err?.message ?? "Gateway error" },
{ status: res.status }
);
}
return NextResponse.json({ ok: true });
}