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.
37 lines
1.2 KiB
TypeScript
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 };
|
|
}
|