1
0
Fork 0
polaris-task-force/src/lib/arma-bridge/server.ts
Z8MB1E 9b909e85e6 refactor(arma-bridge): extract shared server guard and json coercion
requireArmaServer (src/lib/arma-bridge/server.ts) wraps the shared
bridge auth + game-servers lookup that every v1 route repeated;
asJson (json.ts) narrows untrusted request values to what Payload's
json field validation accepts (strings normalize to the fallback
instead of failing the write). All four v1 routes now use both.

Also document the ARMA_BRIDGE_API_KEY env var missed when the bridge
routes landed.
2026-08-25 12:30:50 -04:00

37 lines
1.2 KiB
TypeScript

import config from "@payload-config";
import { getPayload } from "payload";
import { NextRequest, NextResponse } from "next/server";
import type { GameServer } from "@/payload-types";
import { authenticateArmaBridge } from "./auth";
/**
* Shared guard for bridge routes that operate on behalf of a known game
* server: verifies the bridge API key + server id headers, then resolves the
* matching `game-servers` doc.
*
* Returns the Payload instance and server doc on success, or a NextResponse
* (503/401/400/409) the route should return verbatim.
*/
export async function requireArmaServer(
req: NextRequest,
): Promise<
| { payload: Awaited<ReturnType<typeof getPayload>>; server: GameServer }
| NextResponse
> {
const serverId = authenticateArmaBridge(req);
if (serverId instanceof NextResponse) return serverId;
const payload = await getPayload({ config });
const servers = await payload.find({
collection: "game-servers",
where: { serverId: { equals: serverId } },
limit: 1,
overrideAccess: true,
});
const server = servers.docs[0];
if (!server) {
return NextResponse.json({ error: "Heartbeat is required first." }, { status: 409 });
}
return { payload, server };
}