update webauthn flow

This commit is contained in:
2025-02-27 16:34:20 +05:30
parent 0b9f941cb3
commit 63bcc4bafd
5 changed files with 45 additions and 45 deletions

View File

@@ -8,10 +8,8 @@ import {
verifyRegistrationResponse,
} from "@simplewebauthn/server";
import { isoUint8Array } from "@simplewebauthn/server/helpers";
import { getUserByEmail } from "../user/user.service";
import { getUserByEmail, getUserByToken } from "../user/user.service";
import { createSession } from "../auth/auth.service";
import { generateOTP } from "../utils/id";
import { sendMail } from "../utils/mail";
const rpID = process.env.SERVER_DOMAIN;
const rpName = "Quicker Permits";
@@ -19,36 +17,36 @@ const origin = `https://${rpID}`;
export async function webAuthnRoutes(fastify: FastifyInstance) {
// Registration request
fastify.post<{ Body: { email: string } }>(
fastify.post<{ Body: { token: string } }>(
"/register/request",
{
schema: {
body: {
type: "object",
properties: {
email: { type: "string" },
token: { type: "string" },
},
},
},
},
async (req, res: FastifyReply) => {
const { email } = req.body;
const { token } = req.body;
if (!email) {
return res.code(400).send({ error: "Email is required" });
if (!token) {
return res.code(400).send({ error: "bad request" });
}
const userInDB = await getUserByEmail(email);
if (!userInDB) return res.code(400).send({ error: "not allowed" });
const otp = generateOTP();
const userInDB = await getUserByToken(token);
if (!userInDB) return res.code(400).send({ error: "bad request" });
if (new Date() > userInDB.token.expiry)
return res.code(400).send({ error: "link expired" });
const userId = userInDB.id;
const options = await generateRegistrationOptions({
rpName,
rpID,
userID: isoUint8Array.fromUTF8String(userId),
userName: email,
userName: userInDB.email,
attestationType: "none",
excludeCredentials: userInDB.passKeys.map((cred) => ({
// @ts-ignore
@@ -61,23 +59,11 @@ export async function webAuthnRoutes(fastify: FastifyInstance) {
userInDB.challenge = {
value: options.challenge,
expiry: new Date(Date.now() + 60 * 5 * 1000),
};
userInDB.otp = {
value: otp,
expiry: new Date(Date.now() + 60 * 5 * 1000),
expiry: new Date(Date.now() + 60 * 10 * 1000),
};
await userInDB.save();
const sent = await sendMail(
email,
"Code for Quicker Permits Authentication",
`Your code is ${otp}`
);
if (!sent) return res.code(500).send({ error: "server error" });
return res.send(options);
}
);
@@ -85,8 +71,7 @@ export async function webAuthnRoutes(fastify: FastifyInstance) {
// Registration verification
fastify.post<{
Body: {
email: string;
code: string;
token: string;
attestationResponse: RegistrationResponseJSON;
};
}>(
@@ -96,31 +81,25 @@ export async function webAuthnRoutes(fastify: FastifyInstance) {
body: {
type: "object",
properties: {
email: { type: "string" },
code: { type: "string" },
token: { type: "string" },
attestationResponse: { type: "object", additionalProperties: true },
},
},
},
},
async (req, res: FastifyReply) => {
const { email, code, attestationResponse } = req.body;
const { token, attestationResponse } = req.body;
const userInDB = await getUserByEmail(email);
if (!userInDB) return res.code(400).send({ error: "not allowed" });
const userInDB = await getUserByToken(token);
if (!userInDB) return res.code(400).send({ error: "bad request" });
const challenge = userInDB.challenge;
const requiredOTP = userInDB.otp;
const tokenInDb = userInDB.token;
if (!challenge) 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)
if (new Date() > challenge.expiry || new Date() > tokenInDb.expiry)
return res.code(400).send({ error: "challenge expired" });
if (code != requiredOTP.value)
return res.code(400).send({ error: "invalid code" });
try {
const verification = await verifyRegistrationResponse({
response: attestationResponse,