add schemas to webauthn routes

This commit is contained in:
2025-02-17 18:57:23 +05:30
parent 453c3ef995
commit fc9abbbec4

View File

@@ -18,6 +18,7 @@ const rpName = "Quicker Permits";
const origin = `http://${rpID}:3000`; const origin = `http://${rpID}:3000`;
export async function webAuthnRoutes(fastify: FastifyInstance) { export async function webAuthnRoutes(fastify: FastifyInstance) {
// Registration request
fastify.post<{ Body: { email: string } }>( fastify.post<{ Body: { email: string } }>(
"/register/request", "/register/request",
{ {
@@ -79,59 +80,87 @@ export async function webAuthnRoutes(fastify: FastifyInstance) {
} }
); );
// Registration verification
fastify.post<{ fastify.post<{
Body: { Body: {
email: string; email: string;
code: string; code: string;
attestationResponse: RegistrationResponseJSON; attestationResponse: RegistrationResponseJSON;
}; };
}>("/register/verify", async (req, res: FastifyReply) => { }>(
const { email, code, attestationResponse } = req.body; "/register/verify",
{
schema: {
body: {
type: "object",
properties: {
email: { type: "string" },
code: { type: "string" },
attestationResponse: { type: "object" },
},
},
},
},
async (req, res: FastifyReply) => {
const { email, code, attestationResponse } = req.body;
const userInDB = await getUserByEmail(email); const userInDB = await getUserByEmail(email);
if (!userInDB) return res.code(400).send({ error: "not allowed" }); if (!userInDB) return res.code(400).send({ error: "not allowed" });
const challenge = userInDB.challenge; const challenge = userInDB.challenge;
const requiredOTP = userInDB.otp; const requiredOTP = userInDB.otp;
if (!challenge || !requiredOTP) if (!challenge || !requiredOTP)
return res.code(400).send({ error: "not allowed" }); return res.code(400).send({ error: "not allowed" });
if (new Date() > challenge.expiry || new Date() > requiredOTP.expiry) if (new Date() > challenge.expiry || new Date() > requiredOTP.expiry)
return res.code(400).send({ error: "challenge expired" }); return res.code(400).send({ error: "challenge expired" });
if (code != requiredOTP.value) if (code != requiredOTP.value)
return res.code(400).send({ error: "invalid code" }); return res.code(400).send({ error: "invalid code" });
try { try {
const verification = await verifyRegistrationResponse({ const verification = await verifyRegistrationResponse({
response: attestationResponse, response: attestationResponse,
expectedChallenge: challenge.value as string, expectedChallenge: challenge.value as string,
expectedRPID: rpID, expectedRPID: rpID,
expectedOrigin: origin, expectedOrigin: origin,
}); });
if (!verification.verified) { if (!verification.verified) {
return res.code(400).send({ error: "registration failed" }); return res.code(400).send({ error: "registration failed" });
}
userInDB.passKeys.push({
credentialID: verification.registrationInfo.credential.id,
credentialPublicKey:
verification.registrationInfo.credential.publicKey,
counter: verification.registrationInfo.credential.counter,
transports: attestationResponse.response.transports,
});
await userInDB.save();
return res.code(200).send({ success: "registration complete" });
} catch (error) {
return res.code(400).send({ error: error.message });
} }
userInDB.passKeys.push({
credentialID: verification.registrationInfo.credential.id,
credentialPublicKey: verification.registrationInfo.credential.publicKey,
counter: verification.registrationInfo.credential.counter,
transports: attestationResponse.response.transports,
});
await userInDB.save();
return res.code(200).send({ success: "registration complete" });
} catch (error) {
return res.code(400).send({ error: error.message });
} }
}); );
// Authentication request
fastify.post<{ Body: { email: string } }>( fastify.post<{ Body: { email: string } }>(
"/login/request", "/login/request",
{
schema: {
body: {
type: "string",
properties: {
email: { type: "string" },
},
},
},
},
async (req, res) => { async (req, res) => {
const { email } = req.body; const { email } = req.body;
@@ -161,9 +190,20 @@ export async function webAuthnRoutes(fastify: FastifyInstance) {
} }
); );
// Authentication Verification (Step 4) // Authentication Verification
fastify.post<{ Body: { email: string; assertionResponse: any } }>( fastify.post<{ Body: { email: string; assertionResponse: any } }>(
"/login/verify", "/login/verify",
{
schema: {
body: {
type: "object",
properties: {
email: { type: "string" },
assertionResponse: { type: "object" },
},
},
},
},
async (req, res) => { async (req, res) => {
const { email, assertionResponse } = req.body; const { email, assertionResponse } = req.body;