Files
immich/server/src/infra/subscribers/audit.subscriber.ts
Fynn Petersen-Frey cf9e04c8ec feat(server): asset entity audit (#3824)
* feat(server): audit log

* feedback

* Insert to database

* migration

* test

* controller/repository/service

* test

* module

* feat(server): implement audit endpoint

* directly return changed assets

* add daily cleanup of audit table

* fix tests

* review feedback

* ci

* refactor(server): audit implementation

* chore: open api

---------

Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
Co-authored-by: Fynn Petersen-Frey <zoodyy@users.noreply.github.com>
Co-authored-by: Jason Rasmussen <jrasm91@gmail.com>
2023-08-24 15:28:50 -04:00

39 lines
1.3 KiB
TypeScript

import { EntitySubscriberInterface, EventSubscriber, RemoveEvent } from 'typeorm';
import { AlbumEntity, AssetEntity, AuditEntity, DatabaseAction, EntityType } from '../entities';
@EventSubscriber()
export class AuditSubscriber implements EntitySubscriberInterface<AssetEntity | AlbumEntity> {
async afterRemove(event: RemoveEvent<AssetEntity>): Promise<void> {
await this.onEvent(DatabaseAction.DELETE, event);
}
private async onEvent<T>(action: DatabaseAction, event: RemoveEvent<T>): Promise<any> {
const audit = this.getAudit(event.metadata.name, { ...event.entity, id: event.entityId });
if (audit && audit.entityId && audit.ownerId) {
await event.manager.getRepository(AuditEntity).save({ ...audit, action });
}
}
private getAudit(entityName: string, entity: any): Partial<AuditEntity> | null {
switch (entityName) {
case AssetEntity.name:
const asset = entity as AssetEntity;
return {
entityType: EntityType.ASSET,
entityId: asset.id,
ownerId: asset.ownerId,
};
case AlbumEntity.name:
const album = entity as AlbumEntity;
return {
entityType: EntityType.ALBUM,
entityId: album.id,
ownerId: album.ownerId,
};
}
return null;
}
}