feat: implement two-factor authentication (2FA) functionality

- Added two-factor authentication support to the login process, enhancing security for user accounts.
- Introduced new routes and services for managing 2FA setup, verification, and backup codes.
- Updated user model to include fields for 2FA status and backup codes.
- Enhanced login and profile pages to accommodate 2FA input and management.
- Added translations for 2FA-related messages in multiple languages.
- Integrated QR code generation for 2FA setup, improving user experience during authentication.
This commit is contained in:
Daniel Luiz Alves
2025-07-08 00:23:50 -03:00
parent 4d101fbdeb
commit 7f76d48314
45 changed files with 5619 additions and 2447 deletions

View File

@@ -1,7 +1,12 @@
import { FastifyReply, FastifyRequest } from "fastify";
import { env } from "../../env";
import { createResetPasswordSchema, LoginSchema, RequestPasswordResetSchema } from "./dto";
import {
CompleteTwoFactorLoginSchema,
createResetPasswordSchema,
LoginSchema,
RequestPasswordResetSchema,
} from "./dto";
import { AuthService } from "./service";
export class AuthController {
@@ -10,7 +15,36 @@ export class AuthController {
async login(request: FastifyRequest, reply: FastifyReply) {
try {
const input = LoginSchema.parse(request.body);
const user = await this.authService.login(input);
const result = await this.authService.login(input);
if ("requiresTwoFactor" in result) {
return reply.send(result);
}
const user = result;
const token = await request.jwtSign({
userId: user.id,
isAdmin: user.isAdmin,
});
reply.setCookie("token", token, {
httpOnly: true,
path: "/",
secure: env.SECURE_SITE === "true" ? true : false,
sameSite: env.SECURE_SITE === "true" ? "lax" : "strict",
});
return reply.send({ user });
} catch (error: any) {
return reply.status(400).send({ error: error.message });
}
}
async completeTwoFactorLogin(request: FastifyRequest, reply: FastifyReply) {
try {
const input = CompleteTwoFactorLoginSchema.parse(request.body);
const user = await this.authService.completeTwoFactorLogin(input.userId, input.token);
const token = await request.jwtSign({
userId: user.id,
isAdmin: user.isAdmin,