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`;
export async function webAuthnRoutes(fastify: FastifyInstance) {
// Registration request
fastify.post<{ Body: { email: string } }>(
"/register/request",
{
@@ -79,59 +80,87 @@ export async function webAuthnRoutes(fastify: FastifyInstance) {
}
);
// Registration verification
fastify.post<{
Body: {
email: string;
code: string;
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);
if (!userInDB) return res.code(400).send({ error: "not allowed" });
const userInDB = await getUserByEmail(email);
if (!userInDB) return res.code(400).send({ error: "not allowed" });
const challenge = userInDB.challenge;
const requiredOTP = userInDB.otp;
const challenge = userInDB.challenge;
const requiredOTP = userInDB.otp;
if (!challenge || !requiredOTP)
return res.code(400).send({ error: "not allowed" });
if (!challenge || !requiredOTP)
return res.code(400).send({ error: "not allowed" });
if (new Date() > challenge.expiry || new Date() > requiredOTP.expiry)
return res.code(400).send({ error: "challenge expired" });
if (new Date() > challenge.expiry || new Date() > requiredOTP.expiry)
return res.code(400).send({ error: "challenge expired" });
if (code != requiredOTP.value)
return res.code(400).send({ error: "invalid code" });
if (code != requiredOTP.value)
return res.code(400).send({ error: "invalid code" });
try {
const verification = await verifyRegistrationResponse({
response: attestationResponse,
expectedChallenge: challenge.value as string,
expectedRPID: rpID,
expectedOrigin: origin,
});
try {
const verification = await verifyRegistrationResponse({
response: attestationResponse,
expectedChallenge: challenge.value as string,
expectedRPID: rpID,
expectedOrigin: origin,
});
if (!verification.verified) {
return res.code(400).send({ error: "registration failed" });
if (!verification.verified) {
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 } }>(
"/login/request",
{
schema: {
body: {
type: "string",
properties: {
email: { type: "string" },
},
},
},
},
async (req, res) => {
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 } }>(
"/login/verify",
{
schema: {
body: {
type: "object",
properties: {
email: { type: "string" },
assertionResponse: { type: "object" },
},
},
},
},
async (req, res) => {
const { email, assertionResponse } = req.body;