import type { APIRoute } from "astro"; import { generateRegistrationOptions } from "@simplewebauthn/server"; import { db } from "../../../../../db"; import { passkeys, passkeyChallenges } from "../../../../../db/schema"; import { eq, lte } from "drizzle-orm"; import { getOrigin } from "../../../../../lib/auth"; export const GET: APIRoute = async ({ request, locals }) => { const user = locals.user; if (!user) { return new Response(JSON.stringify({ error: "Unauthorized" }), { status: 401, }); } await db .delete(passkeyChallenges) .where(lte(passkeyChallenges.expiresAt, new Date())); const userPasskeys = await db.query.passkeys.findMany({ where: eq(passkeys.userId, user.id), }); const { hostname } = getOrigin(); const options = await generateRegistrationOptions({ rpName: "Chronus", rpID: hostname, userName: user.email, attestationType: "none", excludeCredentials: userPasskeys.map((passkey) => ({ id: passkey.id, transports: passkey.transports ? JSON.parse(passkey.transports) : undefined, })), authenticatorSelection: { residentKey: "preferred", userVerification: "preferred", }, }); await db.insert(passkeyChallenges).values({ challenge: options.challenge, userId: user.id, expiresAt: new Date(Date.now() + 5 * 60 * 1000), }); return new Response(JSON.stringify(options)); };