@boarteam/boar-pack-users-backend 5.2.1 → 5.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@boarteam/boar-pack-users-backend",
3
- "version": "5.2.1",
3
+ "version": "5.3.1",
4
4
  "description": "NestJS Users module including permissions system, authentication strategies etc",
5
5
  "main": "src/index",
6
6
  "files": [
@@ -60,5 +60,5 @@
60
60
  "yalc:push": "yalc push",
61
61
  "gen-types": "SWAGGER=true JWT_SECRET=swagger nest start"
62
62
  },
63
- "gitHead": "5375680e9ca5595408afe3c2e902620717182f85"
63
+ "gitHead": "00a92888f2e0604ff6806655523913426657e72f"
64
64
  }
@@ -57,17 +57,13 @@ export class EventLogInterceptor implements NestInterceptor {
57
57
  logEntry.duration = Date.now() - now;
58
58
  logEntry.statusCode = response.statusCode;
59
59
  logEntry.logLevel = response.statusCode >= 500 ? LogLevel.ERROR : (response.statusCode >= 400 ? LogLevel.WARNING : LogLevel.INFO);
60
- this.eventLogService.audit(logEntry, request).catch((error) => {
61
- this.logger.error(`Failed to log event: ${error.message}`);
62
- });
60
+ this.eventLogService.audit(logEntry, request);
63
61
  }),
64
62
  catchError((error: HttpException) => {
65
63
  logEntry.duration = Date.now() - now;
66
64
  logEntry.statusCode = error?.getStatus?.() || 500;
67
65
  logEntry.logLevel = logEntry.statusCode >= 500 ? LogLevel.ERROR : LogLevel.WARNING;
68
- this.eventLogService.audit(logEntry, request).catch((error) => {
69
- this.logger.error(`Failed to log event: ${error.message}`);
70
- });
66
+ this.eventLogService.audit(logEntry, request);
71
67
  return throwError(() => error);
72
68
  }),
73
69
  );
@@ -50,9 +50,7 @@ export class EventLogMiddleware implements NestMiddleware {
50
50
  ? LogLevel.WARNING
51
51
  : LogLevel.INFO;
52
52
 
53
- this.eventLogService.audit(logEntry, req).catch((error) => {
54
- this.logger.error(`Failed to log event: ${error.message}`);
55
- });
53
+ this.eventLogService.audit(logEntry, req);
56
54
  });
57
55
 
58
56
  next();
@@ -12,6 +12,7 @@ import { CONFIGURE_EVENTS_MIDDLEWARE, SERVICE_CONFIG_TOKEN } from "./event-logs.
12
12
  import { TEventLogServiceConfig } from "./event-logs.types";
13
13
  import { EventLogsLogger } from "./event-logs.logger";
14
14
  import { EventLogMiddleware } from "./event-logs.middleware";
15
+ import { ScheduleModule } from "@nestjs/schedule";
15
16
 
16
17
  @Module({})
17
18
  export class EventLogsModule implements NestModule {
@@ -49,6 +50,7 @@ export class EventLogsModule implements NestModule {
49
50
  module: EventLogsModule,
50
51
  imports: [
51
52
  CaslModule.forFeature(),
53
+ ScheduleModule.forRoot(),
52
54
  TypeOrmModule.forFeature([EventLog], config.dataSourceName),
53
55
  ],
54
56
  providers: [
@@ -5,6 +5,7 @@ import { DataSource, Repository } from 'typeorm';
5
5
  import { Request } from 'express';
6
6
  import { Roles } from "../users";
7
7
  import { EventLogTimelineDto } from "./dto/event-log-timeline.dto";
8
+ import { Cron, CronExpression } from "@nestjs/schedule";
8
9
  import moment from "moment";
9
10
  import 'moment-timezone';
10
11
 
@@ -13,6 +14,7 @@ type TInterval = 'second' | 'minute' | 'hour' | 'day' | 'week';
13
14
  @Injectable()
14
15
  export class EventLogsService extends TypeOrmCrudService<EventLog> {
15
16
  private static requestHandled = Symbol('requestHandled');
17
+ private logsStore: Partial<EventLog>[] = [];
16
18
 
17
19
  private readonly logger = new Logger(EventLogsService.name);
18
20
 
@@ -28,7 +30,37 @@ export class EventLogsService extends TypeOrmCrudService<EventLog> {
28
30
  super(repo);
29
31
  }
30
32
 
31
- async audit(eventLog: Partial<EventLog>, request?: Request): Promise<void> {
33
+ @Cron(CronExpression.EVERY_10_SECONDS)
34
+ private async saveAccumulatedLogs(): Promise<void> {
35
+ if (this.logsStore.length > 0) {
36
+ const logs = [...this.logsStore];
37
+ this.logger.verbose('Reset event logs store variable');
38
+ this.logsStore = [];
39
+
40
+ await this.repo.save(logs).catch(e => {
41
+ // DO NOT USE LOGGER HERE - it will cause infinite loop
42
+ console.error('Error while saving logs');
43
+ console.error(e);
44
+ });
45
+ }
46
+ }
47
+
48
+ @Cron(CronExpression.EVERY_WEEK)
49
+ private async deleteOldEventLogs() {
50
+ const threeMonthsAgo = new Date();
51
+ threeMonthsAgo.setMonth(threeMonthsAgo.getMonth() - 2);
52
+
53
+ const result = await this.repo
54
+ .createQueryBuilder()
55
+ .delete()
56
+ .from(EventLog)
57
+ .where('created_at <= :threeMonthsAgo', { threeMonthsAgo })
58
+ .execute();
59
+
60
+ this.logger.debug(`Removed ${result.affected} expired records from event_logs table.`);
61
+ }
62
+
63
+ audit(eventLog: Partial<EventLog>, request?: Request): void {
32
64
  // @ts-ignore
33
65
  if (request?.[EventLogsService.requestHandled]) {
34
66
  this.logger.debug('Request already handled');
@@ -54,7 +86,7 @@ export class EventLogsService extends TypeOrmCrudService<EventLog> {
54
86
  request[EventLogsService.requestHandled] = true;
55
87
  }
56
88
 
57
- await this.repo.save({
89
+ this.logsStore.push({
58
90
  ...logPartial,
59
91
  ...eventLog,
60
92
  logType: LogType.AUDIT,
@@ -66,8 +98,9 @@ export class EventLogsService extends TypeOrmCrudService<EventLog> {
66
98
  return request?.[EventLogsService.requestHandled];
67
99
  }
68
100
 
101
+ // TODO: Remove async in the next major version (breaking change)
69
102
  async operationalLog(eventLog: Partial<EventLog>): Promise<void> {
70
- await this.repo.save({
103
+ this.logsStore.push({
71
104
  logLevel: LogLevel.INFO,
72
105
  userRole: UserRole.SYSTEM,
73
106
  ...eventLog,
@@ -76,15 +109,11 @@ export class EventLogsService extends TypeOrmCrudService<EventLog> {
76
109
  }
77
110
 
78
111
  public applicationLog(eventLog: Partial<EventLog>): void {
79
- this.repo.save({
112
+ this.logsStore.push({
80
113
  logLevel: LogLevel.INFO,
81
114
  userRole: UserRole.SYSTEM,
82
115
  ...eventLog,
83
116
  logType: LogType.APPLICATION,
84
- }).catch(e => {
85
- // DO NOT USE LOGGER HERE - it will cause infinite loop
86
- console.error('Error while saving application log');
87
- console.error(e);
88
117
  });
89
118
  }
90
119