Address PR comments

This commit is contained in:
Carlos Monastyrski
2025-09-20 00:01:44 -03:00
parent 082e11d603
commit e57cd54ead
3 changed files with 49 additions and 67 deletions

View File

@@ -1,5 +1,7 @@
import { FastifyReply, FastifyRequest } from "fastify";
import { z } from "zod";
import { TUsers } from "@app/db/schemas";
import { getConfig } from "@app/lib/config/env";
import { crypto } from "@app/lib/crypto";
import { BadRequestError, NotFoundError } from "@app/lib/errors";
@@ -7,6 +9,49 @@ import { mfaRateLimit } from "@app/server/config/rateLimiter";
import { addAuthOriginDomainCookie } from "@app/server/lib/cookie";
import { AuthModeMfaJwtTokenPayload, AuthTokenType, MfaMethod } from "@app/services/auth/auth-type";
const handleMfaVerification = async (
req: FastifyRequest & { mfa: { userId: string; orgId?: string; user: TUsers } },
res: FastifyReply,
server: FastifyZodProvider,
mfaToken: string,
mfaMethod: MfaMethod,
isRecoveryCode?: boolean
) => {
const userAgent = req.headers["user-agent"];
const mfaJwtToken = req.headers.authorization?.replace("Bearer ", "");
if (!userAgent) throw new Error("user agent header is required");
if (!mfaJwtToken) throw new Error("authorization header is required");
const appCfg = getConfig();
const { user, token } = await server.services.login.verifyMfaToken({
userAgent,
mfaJwtToken,
ip: req.realIp,
userId: req.mfa.userId,
orgId: req.mfa.orgId,
mfaToken,
mfaMethod,
isRecoveryCode
});
void res.setCookie("jid", token.refresh, {
httpOnly: true,
path: "/",
sameSite: "strict",
secure: appCfg.HTTPS_ENABLED
});
addAuthOriginDomainCookie(res);
return {
...user,
token: token.access,
protectedKey: user.protectedKey || null,
protectedKeyIV: user.protectedKeyIV || null,
protectedKeyTag: user.protectedKeyTag || null
};
};
export const registerMfaRouter = async (server: FastifyZodProvider) => {
const cfg = getConfig();
@@ -109,38 +154,7 @@ export const registerMfaRouter = async (server: FastifyZodProvider) => {
}
},
handler: async (req, res) => {
const userAgent = req.headers["user-agent"];
const mfaJwtToken = req.headers.authorization?.replace("Bearer ", "");
if (!userAgent) throw new Error("user agent header is required");
if (!mfaJwtToken) throw new Error("authorization header is required");
const appCfg = getConfig();
const { user, token } = await server.services.login.verifyMfaToken({
userAgent,
mfaJwtToken,
ip: req.realIp,
userId: req.mfa.userId,
orgId: req.mfa.orgId,
mfaToken: req.body.mfaToken,
mfaMethod: req.body.mfaMethod
});
void res.setCookie("jid", token.refresh, {
httpOnly: true,
path: "/",
sameSite: "strict",
secure: appCfg.HTTPS_ENABLED
});
addAuthOriginDomainCookie(res);
return {
...user,
token: token.access,
protectedKey: user.protectedKey || null,
protectedKeyIV: user.protectedKeyIV || null,
protectedKeyTag: user.protectedKeyTag || null
};
return handleMfaVerification(req, res, server, req.body.mfaToken, req.body.mfaMethod);
}
});
@@ -169,39 +183,7 @@ export const registerMfaRouter = async (server: FastifyZodProvider) => {
}
},
handler: async (req, res) => {
const userAgent = req.headers["user-agent"];
const mfaJwtToken = req.headers.authorization?.replace("Bearer ", "");
if (!userAgent) throw new Error("user agent header is required");
if (!mfaJwtToken) throw new Error("authorization header is required");
const appCfg = getConfig();
const { user, token } = await server.services.login.verifyMfaToken({
userAgent,
mfaJwtToken,
ip: req.realIp,
userId: req.mfa.userId,
orgId: req.mfa.orgId,
mfaToken: req.body.recoveryCode,
mfaMethod: MfaMethod.TOTP,
isRecoveryCode: true
});
void res.setCookie("jid", token.refresh, {
httpOnly: true,
path: "/",
sameSite: "strict",
secure: appCfg.HTTPS_ENABLED
});
addAuthOriginDomainCookie(res);
return {
...user,
token: token.access,
protectedKey: user.protectedKey || null,
protectedKeyIV: user.protectedKeyIV || null,
protectedKeyTag: user.protectedKeyTag || null
};
return handleMfaVerification(req, res, server, req.body.recoveryCode, MfaMethod.TOTP, true);
}
});
};

View File

@@ -707,7 +707,7 @@ export const authLoginServiceFactory = ({
} else {
if (mfaToken.length !== 6) {
throw new BadRequestError({
message: "Invalid TOTP code. Please use a valid recovery code."
message: "Please use a valid TOTP code."
});
}
await totpService.verifyUserTotp({

View File

@@ -35,7 +35,7 @@ const TotpRegistration = ({ onComplete, shouldCenterQr }: Props) => {
type: "success"
});
if (result.recoveryCodes) {
if (result.recoveryCodes && result.recoveryCodes.length > 0) {
setRecoveryCodes(result.recoveryCodes);
setShowRecoveryModal(true);
} else if (onComplete) {