Files
ProxLedger/src/app/api/agent/v1/enroll/route.ts
T
florian.wildeandClaude Opus 5 bef51eb863 feat(api): Agent-API mit Enrollment, Report und Ping (#004)
Gehashte Tokens mit Praefix, Rate-Limit je IP und Token, zod-Validierung mit
durchgaengig optionalen Feldern, idempotente Reports ueber reportId, Key- und
Server-ID-Historie sowie automatischer Laufzeit-Vorschlag. 32 Tests.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 20:39:33 +02:00

46 lines
1.3 KiB
TypeScript

import {
AGENT_VERSION,
bearerToken,
enrollRateLimit,
fehlerAntwort,
fehlerBehandeln,
jsonEingabe,
rateLimitPruefen,
} from "@/server/agent/http";
import { enrollSchema } from "@/server/agent/schema";
import { registriereAgent } from "@/server/agent/service";
export const dynamic = "force-dynamic";
/** Registrierung eines Agents mit einem Enrollment-Token. */
export async function POST(request: Request) {
const token = bearerToken(request);
const gebremst = rateLimitPruefen(enrollRateLimit, request.headers, token);
if (gebremst) return gebremst;
if (!token) {
return fehlerAntwort(401, "token_fehlt", "Enrollment-Token fehlt (Authorization: Bearer …).");
}
const eingabe = await jsonEingabe(request, enrollSchema);
if ("antwort" in eingabe) return eingabe.antwort;
try {
const ergebnis = await registriereAgent(eingabe.daten, token);
return Response.json(
{
ok: true,
hostId: ergebnis.hostId,
token: ergebnis.token,
bestehenderHost: ergebnis.bestehenderHost,
serverIdBereitsBekannt: ergebnis.serverIdBereitsBekannt,
agentVersion: AGENT_VERSION,
serverZeit: new Date().toISOString(),
},
{ status: ergebnis.bestehenderHost ? 200 : 201 },
);
} catch (fehler) {
return fehlerBehandeln(fehler);
}
}