import bcrypt from "bcrypt"; import jwt from "jsonwebtoken"; import userModel from "../user/user.model"; import auditLogModel from "../auditLogs/auditLog.model"; import { IChangePassword } from "./changePassword.interface"; import { RolePermissionService } from '../role-permissions/rolePermission.service'; const service = new RolePermissionService(); export class AuthService { async login ( userName:string, password:string ){ const user = await userModel.findOne({ userName }).populate("roleId"); //Validador de usuario existente if (!user) { throw new Error("Usuario no encontrado"); } //Validar si el usuario está activo if(!user.active){ throw new Error("Usuario inactivo") } //Validar contraseña const validPassword =await bcrypt.compare( password, user.passwordHash ); if (!validPassword){ throw new Error("Contraseña incorrecta"); } user.lastLogin = new Date(); await user.save(); //Registrar login en auditoría await auditLogModel.create({ userId: user._id, module:"Authentication", action:"LOGIN", description:"El usuario inició sesión.", status:"EXITOSO" }); const role = user.roleId as any; const rolePermissions = await service.getByRole( role._id.toString() ); const permissions = rolePermissions ? (rolePermissions.permissions as any []).map( permission => ({ name:permission.name, module:permission.module, action:permission.action }) ) :[] const token = jwt.sign( { id:user._id, roleId: role._id, roleName: role.roleName, permissions }, process.env.JWT_SECRET as string, { expiresIn:"8h" } ); return { token, user:{ id: user._id, employeeId:user.employeeId, userName:user.userName, roleId: role._id, roleName: role.roleName, permissions, active: user.active } }; } async logout ( userId:string ){ if(!userId){ throw new Error("Usuario no autenticado."); } await auditLogModel.create({ userId, module:"Authentication", action:"LOGOUT", description:"El usuario cerró sesión.", status:"EXITOSO" }); return{ message:"Sesión cerrada exitosamente" }; } async changePassword( userId: string, data: IChangePassword ) { // Buscar usuario const user = await userModel.findById(userId); if (!user) { throw new Error("Usuario no encontrado."); } // Validar contraseña actual const validPassword = await bcrypt.compare( data.currentPassword, user.passwordHash ); if (!validPassword) { throw new Error("La contraseña actual es incorrecta."); } // Validar que la nueva contraseña sea diferente if (data.currentPassword === data.newPassword) { throw new Error( "La nueva contraseña debe ser diferente a la actual." ); } // Validar longitud mínima if (data.newPassword.length < 8) { throw new Error( "La nueva contraseña debe tener al menos 8 caracteres." ); } // Encriptar nueva contraseña user.passwordHash = await bcrypt.hash( data.newPassword, 10 ); await user.save(); // Registrar en auditoría await auditLogModel.create({ userId: user._id, module: "Authentication", action: "CHANGE_PASSWORD", description: "El usuario cambió su contraseña.", status: "EXITOSO" }); return { message: "Contraseña actualizada correctamente." }; } }