File: /var/www/api-parametros/src/middleware/auditor.middleware.ts
import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';
import { AuditService } from '../app/auditor/services/auditor.service';
import { JwtService } from '@nestjs/jwt';
import { TokenExpiredError } from 'jsonwebtoken';
import { Audit } from '../app/auditor/schemas/audit.schema';
import messages from '../shared/messages/messages';
@Injectable()
export class AuditMiddleware implements NestMiddleware {
constructor(
private readonly auditorService: AuditService,
private readonly jwtService: JwtService,
) {}
async use(req: Request, res: Response, next: NextFunction) {
const { method, originalUrl, headers, body } = req;
const originalSend = res.send;
res.send = function (data, ...restArgs) {
res.locals.data = data;
return originalSend.apply(res, [data, ...restArgs]);
};
let tokenExpiredAt: Date | null = null;
let userId: string | null = null;
if (headers.authorization) {
const token = headers.authorization.split(' ')[1];
try {
const decoded = this.jwtService.verify(token, { secret: 'puma1984' });
userId = decoded.sub;
} catch (e) {
if (e instanceof TokenExpiredError) {
tokenExpiredAt = e.expiredAt;
return res.status(401).json({
status: 401,
message: messages.error.token.message,
error: messages.error.token.summary,
});
} else {
return res.status(401).json({
status: 401,
message: messages.error.token.message,
error: messages.error.token.summary,
});
}
}
}
res.on('finish', async () => {
const response = res.locals.data || {};
if (userId) {
await this.auditorService.log({
userId,
method,
url: originalUrl,
headers,
body,
response:
typeof response === 'string' ? JSON.parse(response) : response,
tokenExpiredAt,
} as unknown as Partial<Audit>);
}
});
next();
}
}