@boarteam/boar-pack-users-backend 6.4.0 → 6.6.0
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": "6.
|
|
3
|
+
"version": "6.6.0",
|
|
4
4
|
"description": "NestJS Users module including permissions system, authentication strategies etc",
|
|
5
5
|
"main": "src/index",
|
|
6
6
|
"files": [
|
|
@@ -64,5 +64,5 @@
|
|
|
64
64
|
"yalc:push": "yalc push",
|
|
65
65
|
"gen-types": "SWAGGER=true JWT_SECRET=swagger nest start"
|
|
66
66
|
},
|
|
67
|
-
"gitHead": "
|
|
67
|
+
"gitHead": "0c74a3f6b2b7e986124cac71a55467b9b8c25b63"
|
|
68
68
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CreateManyDto, CrudRequest, } from '@dataui/crud';
|
|
2
|
-
import { DeepPartial, ObjectLiteral, Repository, } from 'typeorm';
|
|
2
|
+
import { DeepPartial, EntityManager, ObjectLiteral, Repository, } from 'typeorm';
|
|
3
3
|
import { TypeOrmCrudService } from "@dataui/crud-typeorm";
|
|
4
4
|
import { Injectable } from "@nestjs/common";
|
|
5
5
|
import { AuditAction, AuditLog } from "./entities/audit-log.entity";
|
|
@@ -162,8 +162,8 @@ export class AuditLogBaseService<T extends ObjectLiteral> extends TypeOrmCrudSer
|
|
|
162
162
|
return toReturn;
|
|
163
163
|
}
|
|
164
164
|
|
|
165
|
-
public createAuditLog(log: Partial<AuditLog> | Partial<AuditLog>[]): Promise<AuditLog | AuditLog[]> {
|
|
166
|
-
return this.repo.manager.getRepository(AuditLog).save(log as Partial<AuditLog>);
|
|
165
|
+
public createAuditLog(log: Partial<AuditLog> | Partial<AuditLog>[], manager?: EntityManager): Promise<AuditLog | AuditLog[]> {
|
|
166
|
+
return (manager || this.repo.manager).getRepository(AuditLog).save(log as Partial<AuditLog>);
|
|
167
167
|
}
|
|
168
168
|
}
|
|
169
169
|
|
|
@@ -6,6 +6,7 @@ import { AuthService } from '../auth.service';
|
|
|
6
6
|
import { SkipJWTGuard } from '../../jwt-auth/jwt-auth.guard';
|
|
7
7
|
import { SkipPoliciesGuard } from '../../casl/policies.guard';
|
|
8
8
|
import { LocalAuthLoginDto, LocalAuthTokenDto } from "./local-auth.dto";
|
|
9
|
+
import { SkipEventsLog } from "../../event-logs";
|
|
9
10
|
|
|
10
11
|
@SkipPoliciesGuard()
|
|
11
12
|
@ApiTags('Authentication')
|
|
@@ -18,6 +19,9 @@ export default class LocalAuthController {
|
|
|
18
19
|
@SkipJWTGuard()
|
|
19
20
|
@UseGuards(LocalAuthGuard)
|
|
20
21
|
@Post('login')
|
|
22
|
+
@SkipEventsLog({
|
|
23
|
+
body: ['password'],
|
|
24
|
+
})
|
|
21
25
|
async login(
|
|
22
26
|
@Req() req: Request,
|
|
23
27
|
@Res({ passthrough: true }) res: Response,
|
|
@@ -84,7 +84,7 @@ export class CaslAbilityFactory {
|
|
|
84
84
|
user.permissions.forEach((permission) => {
|
|
85
85
|
const actionAndSubject = CaslAbilityFactory.permissionsToActionsMap[permission];
|
|
86
86
|
if (!actionAndSubject) {
|
|
87
|
-
this.logger.
|
|
87
|
+
this.logger.warn(`Unknown permission: ${permission}`);
|
|
88
88
|
return;
|
|
89
89
|
}
|
|
90
90
|
|
|
@@ -17,8 +17,12 @@ import { SERVICE_CONFIG_TOKEN } from "./event-logs.constants";
|
|
|
17
17
|
import type { TEventLogServiceConfig } from "./event-logs.types";
|
|
18
18
|
import { Reflector } from "@nestjs/core";
|
|
19
19
|
|
|
20
|
+
export type TSkipEventsLogOptions = true | {
|
|
21
|
+
body?: string[];
|
|
22
|
+
}
|
|
23
|
+
|
|
20
24
|
export const SKIP_EVENTS_LOG = 'SKIP_EVENTS_LOG';
|
|
21
|
-
export const SkipEventsLog = () => SetMetadata(SKIP_EVENTS_LOG,
|
|
25
|
+
export const SkipEventsLog = (skipOptions: TSkipEventsLogOptions = true) => SetMetadata(SKIP_EVENTS_LOG, skipOptions);
|
|
22
26
|
|
|
23
27
|
@Injectable()
|
|
24
28
|
export class EventLogInterceptor implements NestInterceptor {
|
|
@@ -36,8 +40,8 @@ export class EventLogInterceptor implements NestInterceptor {
|
|
|
36
40
|
const handler = context.getHandler();
|
|
37
41
|
const controller = context.getClass();
|
|
38
42
|
|
|
39
|
-
const
|
|
40
|
-
if (
|
|
43
|
+
const skipOptions = this.reflector.getAllAndOverride<TSkipEventsLogOptions | undefined>(SKIP_EVENTS_LOG, [handler, controller]);
|
|
44
|
+
if (skipOptions === true) {
|
|
41
45
|
return next.handle();
|
|
42
46
|
}
|
|
43
47
|
|
|
@@ -57,13 +61,13 @@ export class EventLogInterceptor implements NestInterceptor {
|
|
|
57
61
|
logEntry.duration = Date.now() - now;
|
|
58
62
|
logEntry.statusCode = response.statusCode;
|
|
59
63
|
logEntry.logLevel = response.statusCode >= 500 ? LogLevel.ERROR : (response.statusCode >= 400 ? LogLevel.WARNING : LogLevel.INFO);
|
|
60
|
-
this.eventLogService.audit(logEntry, request);
|
|
64
|
+
this.eventLogService.audit(logEntry, request, skipOptions);
|
|
61
65
|
}),
|
|
62
66
|
catchError((error: HttpException) => {
|
|
63
67
|
logEntry.duration = Date.now() - now;
|
|
64
68
|
logEntry.statusCode = error?.getStatus?.() || 500;
|
|
65
69
|
logEntry.logLevel = logEntry.statusCode >= 500 ? LogLevel.ERROR : LogLevel.WARNING;
|
|
66
|
-
this.eventLogService.audit(logEntry, request);
|
|
70
|
+
this.eventLogService.audit(logEntry, request, skipOptions);
|
|
67
71
|
return throwError(() => error);
|
|
68
72
|
}),
|
|
69
73
|
);
|
|
@@ -8,6 +8,7 @@ import { EventLogTimelineDto } from "./dto/event-log-timeline.dto";
|
|
|
8
8
|
import { Cron, CronExpression } from "@nestjs/schedule";
|
|
9
9
|
import moment from "moment";
|
|
10
10
|
import 'moment-timezone';
|
|
11
|
+
import { TSkipEventsLogOptions } from "./event-logs.interceptor";
|
|
11
12
|
|
|
12
13
|
type TInterval = 'second' | 'minute' | 'hour' | 'day' | 'week';
|
|
13
14
|
|
|
@@ -60,7 +61,7 @@ export class EventLogsService extends TypeOrmCrudService<EventLog> {
|
|
|
60
61
|
this.logger.debug(`Removed ${result.affected} expired records from event_logs table.`);
|
|
61
62
|
}
|
|
62
63
|
|
|
63
|
-
audit(eventLog: Partial<EventLog>, request?: Request): void {
|
|
64
|
+
audit(eventLog: Partial<EventLog>, request?: Request, skipOptions?: TSkipEventsLogOptions): void {
|
|
64
65
|
// @ts-ignore
|
|
65
66
|
if (request?.[EventLogsService.requestHandled]) {
|
|
66
67
|
this.logger.debug('Request already handled');
|
|
@@ -72,10 +73,20 @@ export class EventLogsService extends TypeOrmCrudService<EventLog> {
|
|
|
72
73
|
const { user } = request;
|
|
73
74
|
const userRole = user?.role ? EventLogsService.rolesMap[user.role] : UserRole.GUEST;
|
|
74
75
|
|
|
76
|
+
const payload = request.body ? { ...request.body } : null;
|
|
77
|
+
if (skipOptions && typeof skipOptions === 'object' && Array.isArray(skipOptions.body) && payload) {
|
|
78
|
+
for (const field of skipOptions.body) {
|
|
79
|
+
if (field in payload) {
|
|
80
|
+
// @ts-ignore
|
|
81
|
+
payload[field] = '*****';
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
75
86
|
logPartial.userId = user?.id || null;
|
|
76
87
|
logPartial.userName = user?.name || null;
|
|
77
88
|
logPartial.userRole = userRole || UserRole.GUEST;
|
|
78
|
-
logPartial.payload =
|
|
89
|
+
logPartial.payload = payload;
|
|
79
90
|
logPartial.method = request.method || null;
|
|
80
91
|
logPartial.url = request.url || null;
|
|
81
92
|
logPartial.entityId = request.params.id || null;
|