46 lines
1.7 KiB
TypeScript
46 lines
1.7 KiB
TypeScript
import { authenticateRelayNode } from "@/db/relay-control-plane";
|
|
import { claimDevice, DomainError } from "@/db/repository";
|
|
import { apiError, readJsonMutation } from "../../../respond";
|
|
|
|
export async function POST(request: Request) {
|
|
try {
|
|
await authenticateRelayNode(request);
|
|
const payload = await readJsonMutation<{
|
|
bootstrap_token?: string;
|
|
source_hash?: string;
|
|
os?: string;
|
|
ed25519_public?: string;
|
|
x25519_public?: string;
|
|
identity_fingerprint?: string;
|
|
transport_mode?: string;
|
|
registration_proof?: string;
|
|
daemon_version?: string;
|
|
registration_retry_key?: string;
|
|
}>(request);
|
|
const sourceHash = payload.source_hash?.trim().toLowerCase() ?? "";
|
|
if (!/^[0-9a-f]{64}$/u.test(sourceHash)) {
|
|
throw new DomainError("registration_rate_limited", "注册来源摘要无效", 429, true, 60);
|
|
}
|
|
const result = await claimDevice({
|
|
bootstrapToken: payload.bootstrap_token ?? "",
|
|
trustedSourceHash: sourceHash,
|
|
os: payload.os ?? "",
|
|
ed25519Public: payload.ed25519_public ?? "",
|
|
x25519Public: payload.x25519_public ?? "",
|
|
identityFingerprint: payload.identity_fingerprint ?? "",
|
|
transportMode: payload.transport_mode ?? "",
|
|
registrationProof: payload.registration_proof ?? "",
|
|
daemonVersion: payload.daemon_version ?? "",
|
|
registrationRetryKey: payload.registration_retry_key ?? "",
|
|
});
|
|
return Response.json(result, {
|
|
status: 200,
|
|
headers: { "cache-control": "no-store" },
|
|
});
|
|
} catch (error) {
|
|
const response = apiError(error);
|
|
response.headers.set("cache-control", "no-store");
|
|
return response;
|
|
}
|
|
}
|