Files
sistema_combustible/backend/src/modules/auth/auth.service.ts

196 lines
4.4 KiB
TypeScript

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."
};
}
}