File size: 2,014 Bytes
bc4a7e8 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | import { markCommandCodeAuthSessionReceived } from "@/lib/db/commandCodeAuth";
import {
callbackCorsHeaders,
commandCodeCallbackSchema,
MAX_CALLBACK_BODY_BYTES,
noStoreJson,
readJsonBodyWithLimit,
rejectDisallowedCallbackOrigin,
stateHashFromState,
} from "../shared";
export async function OPTIONS(request: Request) {
return new Response(null, { status: 204, headers: callbackCorsHeaders(request) });
}
export async function POST(request: Request) {
const originError = rejectDisallowedCallbackOrigin(request);
if (originError) return originError;
let body: unknown;
try {
body = await readJsonBodyWithLimit(request, MAX_CALLBACK_BODY_BYTES);
} catch (error) {
const isTooLarge = error instanceof Error && error.message === "BODY_TOO_LARGE";
return noStoreJson(
{ success: false, error: isTooLarge ? "Request body too large" : "Invalid JSON body" },
{ status: isTooLarge ? 413 : 400, headers: callbackCorsHeaders(request) }
);
}
const parsed = commandCodeCallbackSchema.safeParse(body);
if (!parsed.success) {
return noStoreJson(
{ success: false, error: "Invalid callback payload" },
{ status: 400, headers: callbackCorsHeaders(request) }
);
}
const session = markCommandCodeAuthSessionReceived({
stateHash: stateHashFromState(parsed.data.state),
apiKey: parsed.data.apiKey,
metadata: {
userId: parsed.data.userId,
userName: parsed.data.userName,
keyName: parsed.data.keyName,
},
});
if (!session || session.status !== "received") {
return noStoreJson(
{ success: false, error: "Invalid or expired state" },
{ status: 400, headers: callbackCorsHeaders(request) }
);
}
return noStoreJson(
{
success: true,
ok: true,
status: session.status,
expiresAt: session.expiresAt,
metadata: session.metadata,
},
{ headers: callbackCorsHeaders(request) }
);
}
|