This commit is contained in:
45
src/pages/api/auth/passkey/register/start.ts
Normal file
45
src/pages/api/auth/passkey/register/start.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import type { APIRoute } from "astro";
|
||||
import { generateRegistrationOptions } from "@simplewebauthn/server";
|
||||
import { db } from "../../../../../db";
|
||||
import { passkeys, passkeyChallenges } from "../../../../../db/schema";
|
||||
import { eq } from "drizzle-orm";
|
||||
|
||||
export const GET: APIRoute = async ({ request, locals }) => {
|
||||
const user = locals.user;
|
||||
|
||||
if (!user) {
|
||||
return new Response(JSON.stringify({ error: "Unauthorized" }), {
|
||||
status: 401,
|
||||
});
|
||||
}
|
||||
|
||||
// Get user's existing passkeys to prevent registering the same authenticator twice
|
||||
const userPasskeys = await db.query.passkeys.findMany({
|
||||
where: eq(passkeys.userId, user.id),
|
||||
});
|
||||
|
||||
const options = await generateRegistrationOptions({
|
||||
rpName: "Chronus",
|
||||
rpID: new URL(request.url).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));
|
||||
};
|
||||
Reference in New Issue
Block a user