mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-27 10:52:53 +00:00
98 lines
2.5 KiB
TypeScript
98 lines
2.5 KiB
TypeScript
import { Injectable, Inject, Logger, Optional } from '@nestjs/common';
|
|
import { REQUEST } from '@nestjs/core';
|
|
import { PrismaService } from './prisma.service';
|
|
|
|
@Injectable()
|
|
export class AuditService {
|
|
private readonly logger = new Logger(AuditService.name);
|
|
constructor(
|
|
private prisma: PrismaService,
|
|
@Optional() @Inject(REQUEST) private request?: any,
|
|
) {}
|
|
|
|
async log(input: {
|
|
userId?: string;
|
|
action: 'CREATE' | 'UPDATE' | 'DELETE' | 'LOGIN' | 'LOGOUT' | 'VERIFY' | string;
|
|
entityType: string;
|
|
entityId?: string;
|
|
oldData?: any;
|
|
newData?: any;
|
|
}) {
|
|
try {
|
|
const ipAddress = this.getIpAddress();
|
|
const userAgent = this.getUserAgent();
|
|
|
|
await this.prisma.auditLog.create({
|
|
data: {
|
|
iamUserId: input.userId,
|
|
action: input.action,
|
|
entityType: input.entityType,
|
|
entityId: input.entityId,
|
|
oldData: input.oldData,
|
|
newData: input.newData,
|
|
ipAddress,
|
|
userAgent,
|
|
},
|
|
});
|
|
} catch (error) {
|
|
this.logger.error('Failed to log audit event:', error);
|
|
// Don't throw - audit logging should not break main operations
|
|
}
|
|
}
|
|
|
|
private getIpAddress(): string {
|
|
if (!this.request) return '';
|
|
|
|
return (
|
|
this.request.headers['x-forwarded-for']?.split(',')[0].trim() ||
|
|
this.request.headers['x-real-ip'] ||
|
|
this.request.connection?.remoteAddress ||
|
|
this.request.socket?.remoteAddress ||
|
|
this.request.ip ||
|
|
''
|
|
);
|
|
}
|
|
|
|
private getUserAgent(): string {
|
|
return this.request?.headers?.['user-agent'] || '';
|
|
}
|
|
|
|
async getLogs(filters: any = {}) {
|
|
const where: any = {};
|
|
|
|
if (filters.search) {
|
|
where.OR = [
|
|
{ entityId: { contains: filters.search, mode: 'insensitive' } },
|
|
{ iamUserId: { contains: filters.search, mode: 'insensitive' } },
|
|
];
|
|
}
|
|
|
|
if (filters.action) {
|
|
where.action = filters.action;
|
|
}
|
|
|
|
if (filters.entityType) {
|
|
where.entityType = filters.entityType;
|
|
}
|
|
|
|
const limit = Math.min(filters.limit ?? 50, 200);
|
|
const offset = filters.offset ?? 0;
|
|
|
|
const [data, total] = await Promise.all([
|
|
this.prisma.auditLog.findMany({
|
|
where,
|
|
orderBy: { createdAt: 'desc' },
|
|
take: limit,
|
|
skip: offset,
|
|
}),
|
|
this.prisma.auditLog.count({ where }),
|
|
]);
|
|
|
|
return { data, total, limit, offset };
|
|
}
|
|
|
|
async getLog(id: string) {
|
|
return this.prisma.auditLog.findUnique({ where: { id } });
|
|
}
|
|
}
|