Actualización módulo de authentication

This commit is contained in:
2026-07-02 19:44:30 +00:00
parent 7aaf12a6d0
commit 62a3beca15
7 changed files with 385 additions and 19 deletions

View File

@ -0,0 +1,205 @@
import { Request, Response } from "express";
import { AuditLogService } from './auditLog.service';
const service = new AuditLogService();
export class AuditLogController{
async create(
req:Request,
res:Response
){
try{
const auditLog = await service.create(
req.body
)
res.status(201).json(auditLog);
}catch(error){
res.status(500).json({
message:"Error al crear el registro de auditoría",
error
});
}
}
async getAll(
req:Request,
res:Response
){
try{
const auditLog = await service.getAll()
res.status(200).json(auditLog);
}catch(error){
res.status(500).json({
message:"Error al obtener registros",
error
});
}
}
async getById(
req:Request,
res:Response
){
try{
const auditLog = await service.getById(
req.params.id as string
);
if(!auditLog){
return res.status(404).json({
message:"Registro no encontrado"
});
}
res.status(200).json(auditLog);
}catch(error){
res.status(500).json({
message:"Error al obtener registros",
error
});
}
}
async getByUser(
req:Request,
res:Response
){
try{
const auditLog = await service.getByUser(
req.params.userId as string
);
res.status(200).json(auditLog);
} catch(error){
res.status(500).json({
message:"Error al obtener registros",
error
});
}
}
async getByModule(
req:Request,
res:Response
){
try{
const auditLog = await service.getByModule(
req.params.module as any
);
res.status(200).json(auditLog);
}catch(error){
res.status(500).json({
message:"Error al obtener registros",
error
});
}
}
async getByAction(
req:Request,
res:Response
){
try{
const auditLog = await service.getByAction(
req.params.action as any
);
res.status(200).json(auditLog);
}catch(error){
res.status(500).json({
message:"Error al obtener registros",
error
});
}
}
async getByStatus(
req:Request,
res:Response
){
try{
const auditLog = await service.getByStatus(
req.params.status as any
);
res.status(200).json(auditLog);
}catch(error){
res.status(500).json({
message:"Error al obtener registros",
error
});
}
}
async getByDateRange(
req:Request,
res:Response
){
try{
const {startDate, endDate} = req.query;
const auditLog = await service.getByDateRange(
new Date(startDate as string),
new Date(endDate as string)
);
res.status(200).json(auditLog)
}catch(error){
res.status(500).json({
message:"Error al obtener registros",
error
});
}
}
async delete(
req:Request,
res:Response
){
try{
const auditLog = await service.delete(
req.params.id as string
);
if(!auditLog){
return res.status(404).json({
message:"Registro no encontrado"
})
}
res.status(200).json(auditLog);
}catch(error){
res.status(500).json({
message:"Error al eliminar registros",
error
});
}
}
}

View File

@ -7,7 +7,6 @@ const auditLogSchema = new mongoose.Schema(
userId: { userId: {
type: mongoose.Schema.Types.ObjectId, type: mongoose.Schema.Types.ObjectId,
ref: "User" ref: "User"
}, },
@ -15,9 +14,7 @@ const auditLogSchema = new mongoose.Schema(
module: { module: {
type: String, type: String,
required: true, required: true,
enum: [ enum: [
"User", "User",
@ -49,7 +46,6 @@ const auditLogSchema = new mongoose.Schema(
"Report", "Report",
"Authentication" "Authentication"
] ]
}, },
@ -57,9 +53,7 @@ const auditLogSchema = new mongoose.Schema(
action: { action: {
type: String, type: String,
required: true, required: true,
enum: [ enum: [
"CREATE", "CREATE",
@ -110,13 +104,13 @@ const auditLogSchema = new mongoose.Schema(
enum: [ enum: [
"SUCCESS", "EXITOSO",
"FAILED" "FALLIDO"
], ],
default: "SUCCESS" default: "EXITOSO"
} }
@ -132,4 +126,4 @@ const auditLogSchema = new mongoose.Schema(
); );
export default mongoose.model("AuditLog", auditLogSchema); export default mongoose.model("AuditLog",auditLogSchema);

View File

@ -0,0 +1,26 @@
import { Router } from "express";
import { AuditLogController } from "./auditLog.controller";
import { authMiddleware } from "../auth/auth.middleware";
const auditRouter = Router();
const controller = new AuditLogController();
auditRouter.get("/", authMiddleware, controller.getAll);
auditRouter.get("/:id", authMiddleware, controller.getById);
auditRouter.post("/", authMiddleware, controller.create);
auditRouter.get("/user/:userId", authMiddleware, controller.getByUser);
auditRouter.get("/module/:module", authMiddleware, controller.getByModule);
auditRouter.get("/action/:action", authMiddleware, controller.getByAction);
auditRouter.get("/status/:status", authMiddleware, controller.getByStatus);
auditRouter.get("/date-range", authMiddleware, controller.getByDateRange);
auditRouter.delete("/:id", authMiddleware, controller.delete);
export default auditRouter;

View File

@ -0,0 +1,110 @@
import auditLogModel from "./auditLog.model";
import { IAuditLog } from "./auditLog.interface";
export class AuditLogService {
//Registrar una acción
async create(
data:IAuditLog
){
const auditLog = new auditLogModel(data);
return await auditLog.save();
}
//Obtener todos los registros
async getAll(){
return await auditLogModel
.find()
.populate("userId")
.sort({
createdAt: -1
});
}
async getById(
id:string
){
return await auditLogModel
.findById(id)
.populate("userId");
}
async getByUser(
userId:string
){
return await auditLogModel
.find({
userId
})
.sort({
createdAt: -1
})
}
async getByModule(
module:IAuditLog["module"]
){
return await auditLogModel
.find({
module
})
.populate("userId")
.sort({
createdAt: -1
});
}
async getByAction(
action:IAuditLog["action"]
){
return await auditLogModel
.find({
action
})
.populate("userId")
.sort({
createdAt: -1
})
}
async getByStatus(
status:IAuditLog["status"]
){
return await auditLogModel
.find({
status
})
.populate("userId")
.sort({
createdAt: -1
})
}
async getByDateRange(
startDate:Date,
endDate:Date
){
return await auditLogModel
.find({
createdAt:{
$gte:startDate,
$lte:endDate
}
})
.populate("userId")
.sort({
createdAt: -1
})
}
async delete(
id:string
){
return await auditLogModel.findById(id);
}
}

View File

@ -17,8 +17,15 @@ export class AuthController {
password password
} = req.body; } = req.body;
const result =
await authService.login( //Validar datos de entrada
if(!userName || !password){
return res.status(400).json({
message:"Usuario y contraseña son requeridos"
});
}
const result = await authService.login(
userName, userName,
password password
); );
@ -33,4 +40,22 @@ export class AuthController {
} }
} }
async logout(
req:Request,
res:Response
){
try{
const user = (req as any).user;
const result = await authService.logout(user.id);
res.json(result);
}catch(error) {
res.status(500).json({
message:"Error al cerrar sesión",
error
});
}
}
} }

View File

@ -15,12 +15,19 @@ export const authMiddleware = (
}); });
} }
//Verificar formato Bearer
if(!authHeader.startsWith("Bearer ")) {
return res.status(401).json({
message:"Formato de token inválido"
});
}
const token = authHeader.split(" ")[1]; const token = authHeader.split(" ")[1];
if (!token) if (!token)
{ {
return res.status(401).json({ return res.status(401).json({
message:"Token invalido" message:"Token inválido"
}); });
} }
@ -37,7 +44,7 @@ export const authMiddleware = (
next(); next();
} catch{ } catch{
return res.status(401).json({ return res.status(401).json({
message:"Token invalido" message:"Token inválido"
}); });
} }
}; };

View File

@ -1,14 +1,13 @@
import { Router } from "express"; import { Router } from "express";
import { AuthController } from "./auth.controller"; import { AuthController } from "./auth.controller";
import { authMiddleware } from "./auth.middleware";
const authRouter = Router(); const authRouter = Router();
const controller = new AuthController(); const controller = new AuthController();
authRouter.post( authRouter.post("/login", controller.login);
"/login",
controller.login authRouter.post("/logout", authMiddleware, controller.logout);
);
export default authRouter; export default authRouter;