61 lines
1.8 KiB
TypeScript
61 lines
1.8 KiB
TypeScript
import { Injectable } from '@nestjs/common';
|
|
import { EntityManager } from 'typeorm';
|
|
import { AuditEventsRepository } from '../core-data/repositories/audit-events.repository';
|
|
import { AuditEvent, AuditSource } from '../database/entities';
|
|
import { sanitizeAuditData } from './audit-sanitizer';
|
|
|
|
export interface RecordAuditInput {
|
|
actorUserId?: string | null;
|
|
actorUsername?: string | null;
|
|
action: string;
|
|
entityType?: string | null;
|
|
entityId?: string | null;
|
|
requestId?: string | null;
|
|
source?: AuditSource;
|
|
ip?: string | null;
|
|
userAgent?: string | null;
|
|
beforeData?: Record<string, unknown> | null;
|
|
afterData?: Record<string, unknown> | null;
|
|
metadata?: Record<string, unknown> | null;
|
|
}
|
|
|
|
@Injectable()
|
|
export class AuditService {
|
|
constructor(private readonly events: AuditEventsRepository) {}
|
|
|
|
async record(
|
|
input: RecordAuditInput,
|
|
manager?: EntityManager,
|
|
): Promise<void> {
|
|
const eventInput = {
|
|
actorUserId: input.actorUserId ?? null,
|
|
actorUsername: input.actorUsername ?? null,
|
|
action: input.action,
|
|
entityType: input.entityType ?? null,
|
|
entityId: input.entityId ?? null,
|
|
requestId: input.requestId ?? null,
|
|
source: input.source ?? AuditSource.WEB,
|
|
ip: input.ip ?? null,
|
|
userAgent: input.userAgent ?? null,
|
|
beforeData: sanitizeAuditData(input.beforeData ?? null) as Record<
|
|
string,
|
|
unknown
|
|
> | null,
|
|
afterData: sanitizeAuditData(input.afterData ?? null) as Record<
|
|
string,
|
|
unknown
|
|
> | null,
|
|
metadata: sanitizeAuditData(input.metadata ?? null) as Record<
|
|
string,
|
|
unknown
|
|
> | null,
|
|
};
|
|
|
|
if (manager) {
|
|
await manager.getRepository(AuditEvent).save(eventInput);
|
|
return;
|
|
}
|
|
await this.events.save(this.events.create(eventInput));
|
|
}
|
|
}
|