import "server-only"; import { query, queryOne } from "@/lib/db"; const CHALLENGE_TTL_MS = 5 * 60 * 1000; export type ChallengeType = "registration" | "authentication"; export async function storeChallenge( challenge: string, type: ChallengeType, userId: string | null ): Promise { // Kein Cron nötig: abgelaufene Zeilen bei jeder neuen Challenge // gleich mit aufräumen. await query("delete from webauthn_challenges where expires_at < now()"); await query( "insert into webauthn_challenges (user_id, challenge, type, expires_at) values ($1, $2, $3, $4)", [userId, challenge, type, new Date(Date.now() + CHALLENGE_TTL_MS)] ); } /** Einmalig verwendbar: die Zeile wird beim Abruf sofort gelöscht. */ export async function consumeChallenge( challenge: string, type: ChallengeType ): Promise<{ userId: string | null } | null> { const row = await queryOne<{ user_id: string | null }>( `delete from webauthn_challenges where challenge = $1 and type = $2 and expires_at > now() returning user_id`, [challenge, type] ); return row ? { userId: row.user_id } : null; }