@nest-omni/core 3.1.2-8 → 4.1.2-9
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/audit/audit.module.d.ts +10 -0
- package/audit/audit.module.js +231 -0
- package/audit/controllers/audit.controller.d.ts +20 -0
- package/audit/controllers/audit.controller.js +142 -0
- package/audit/controllers/index.d.ts +1 -0
- package/audit/controllers/index.js +17 -0
- package/audit/decorators/audit-controller.decorator.d.ts +5 -0
- package/audit/decorators/audit-controller.decorator.js +17 -0
- package/audit/decorators/audit-operation.decorator.d.ts +5 -0
- package/audit/decorators/audit-operation.decorator.js +23 -0
- package/audit/decorators/entity-audit.decorator.d.ts +5 -0
- package/audit/decorators/entity-audit.decorator.js +19 -0
- package/audit/decorators/index.d.ts +2 -0
- package/audit/decorators/index.js +18 -0
- package/audit/dto/audit-log-query.dto.d.ts +14 -0
- package/audit/dto/audit-log-query.dto.js +95 -0
- package/audit/dto/begin-transaction.dto.d.ts +3 -0
- package/audit/dto/begin-transaction.dto.js +22 -0
- package/audit/dto/compare-entities.dto.d.ts +6 -0
- package/audit/dto/compare-entities.dto.js +44 -0
- package/audit/dto/index.d.ts +5 -0
- package/audit/dto/index.js +21 -0
- package/audit/dto/pre-check-restore.dto.d.ts +5 -0
- package/audit/dto/pre-check-restore.dto.js +32 -0
- package/audit/dto/restore-entity.dto.d.ts +9 -0
- package/audit/dto/restore-entity.dto.js +53 -0
- package/audit/entities/entity-audit-log.entity.d.ts +18 -0
- package/audit/entities/entity-audit-log.entity.js +81 -0
- package/audit/entities/entity-transaction.entity.d.ts +14 -0
- package/audit/entities/entity-transaction.entity.js +51 -0
- package/audit/entities/index.d.ts +2 -0
- package/audit/entities/index.js +18 -0
- package/audit/entities/manual-operation-log.entity.d.ts +15 -0
- package/audit/entities/manual-operation-log.entity.js +82 -0
- package/audit/entities/operation-template.entity.d.ts +11 -0
- package/audit/entities/operation-template.entity.js +65 -0
- package/audit/enums/audit.enums.d.ts +27 -0
- package/audit/enums/audit.enums.js +35 -0
- package/audit/enums/index.d.ts +1 -0
- package/audit/enums/index.js +17 -0
- package/audit/index.d.ts +10 -0
- package/audit/index.js +26 -0
- package/audit/interceptors/audit.interceptor.d.ts +12 -0
- package/audit/interceptors/audit.interceptor.js +95 -0
- package/audit/interceptors/index.d.ts +1 -0
- package/audit/interceptors/index.js +17 -0
- package/audit/interfaces/audit.interfaces.d.ts +119 -0
- package/audit/interfaces/audit.interfaces.js +2 -0
- package/audit/interfaces/index.d.ts +1 -0
- package/audit/interfaces/index.js +17 -0
- package/audit/services/audit-context.service.d.ts +10 -0
- package/audit/services/audit-context.service.js +55 -0
- package/audit/services/audit-strategy.service.d.ts +19 -0
- package/audit/services/audit-strategy.service.js +89 -0
- package/audit/services/entity-audit.service.d.ts +37 -0
- package/audit/services/entity-audit.service.js +484 -0
- package/audit/services/index.d.ts +5 -0
- package/audit/services/index.js +21 -0
- package/audit/services/manual-audit-log.service.d.ts +29 -0
- package/audit/services/manual-audit-log.service.js +184 -0
- package/audit/services/multi-database.service.d.ts +10 -0
- package/audit/services/multi-database.service.js +59 -0
- package/audit/services/operation-description.service.d.ts +21 -0
- package/audit/services/operation-description.service.js +213 -0
- package/audit/services/transaction-audit.service.d.ts +22 -0
- package/audit/services/transaction-audit.service.js +201 -0
- package/audit/subscribers/entity-audit.subscriber.d.ts +14 -0
- package/audit/subscribers/entity-audit.subscriber.js +136 -0
- package/audit/subscribers/index.d.ts +1 -0
- package/audit/subscribers/index.js +17 -0
- package/common/abstract.entity.js +1 -1
- package/http-client/examples/advanced-usage.example.js +14 -1
- package/http-client/examples/auth-with-waiting-lock.example.d.ts +17 -0
- package/http-client/examples/auth-with-waiting-lock.example.js +336 -0
- package/http-client/examples/basic-usage.example.d.ts +1 -9
- package/http-client/examples/basic-usage.example.js +4 -14
- package/http-client/examples/multi-api-configuration.example.js +4 -4
- package/http-client/http-client.module.js +7 -4
- package/http-client/services/api-client-registry.service.d.ts +2 -1
- package/http-client/services/api-client-registry.service.js +2 -1
- package/http-client/services/http-client.service.d.ts +18 -1
- package/http-client/services/http-client.service.js +123 -3
- package/http-client/services/http-log-query.service.d.ts +20 -0
- package/http-client/services/http-log-query.service.js +176 -0
- package/http-client/services/http-replay.service.d.ts +58 -0
- package/http-client/services/http-replay.service.js +266 -0
- package/http-client/services/log-cleanup.service.js +2 -2
- package/http-client/services/logging.service.js +1 -1
- package/http-client/utils/request-id.util.d.ts +4 -0
- package/http-client/utils/request-id.util.js +34 -0
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/package.json +1 -1
- package/setup/bootstrap.setup.js +5 -1
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./audit.enums"), exports);
|
package/audit/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from './entities';
|
|
2
|
+
export * from './enums';
|
|
3
|
+
export * from './interfaces';
|
|
4
|
+
export * from './dto';
|
|
5
|
+
export * from './decorators';
|
|
6
|
+
export * from './services';
|
|
7
|
+
export * from './subscribers';
|
|
8
|
+
export * from './interceptors';
|
|
9
|
+
export * from './controllers';
|
|
10
|
+
export * from './audit.module';
|
package/audit/index.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./entities"), exports);
|
|
18
|
+
__exportStar(require("./enums"), exports);
|
|
19
|
+
__exportStar(require("./interfaces"), exports);
|
|
20
|
+
__exportStar(require("./dto"), exports);
|
|
21
|
+
__exportStar(require("./decorators"), exports);
|
|
22
|
+
__exportStar(require("./services"), exports);
|
|
23
|
+
__exportStar(require("./subscribers"), exports);
|
|
24
|
+
__exportStar(require("./interceptors"), exports);
|
|
25
|
+
__exportStar(require("./controllers"), exports);
|
|
26
|
+
__exportStar(require("./audit.module"), exports);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
import { AuditContextService } from '../services/audit-context.service';
|
|
4
|
+
export declare class AuditInterceptor implements NestInterceptor {
|
|
5
|
+
private readonly contextService;
|
|
6
|
+
constructor(contextService: AuditContextService);
|
|
7
|
+
intercept(context: ExecutionContext, next: CallHandler): Observable<any>;
|
|
8
|
+
private setRequestContext;
|
|
9
|
+
private handleError;
|
|
10
|
+
private isAuditEnabled;
|
|
11
|
+
private generateRequestId;
|
|
12
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
12
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
13
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
14
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
15
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
16
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
17
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
exports.AuditInterceptor = void 0;
|
|
22
|
+
const common_1 = require("@nestjs/common");
|
|
23
|
+
const operators_1 = require("rxjs/operators");
|
|
24
|
+
const crypto_1 = require("crypto");
|
|
25
|
+
const audit_context_service_1 = require("../services/audit-context.service");
|
|
26
|
+
const decorators_1 = require("../decorators");
|
|
27
|
+
let AuditInterceptor = class AuditInterceptor {
|
|
28
|
+
constructor(contextService) {
|
|
29
|
+
this.contextService = contextService;
|
|
30
|
+
}
|
|
31
|
+
intercept(context, next) {
|
|
32
|
+
const request = context.switchToHttp().getRequest();
|
|
33
|
+
const handler = context.getHandler();
|
|
34
|
+
const controller = context.getClass();
|
|
35
|
+
if (!this.isAuditEnabled(controller, handler)) {
|
|
36
|
+
return next.handle();
|
|
37
|
+
}
|
|
38
|
+
this.setRequestContext(request);
|
|
39
|
+
return next.handle().pipe((0, operators_1.tap)(() => {
|
|
40
|
+
}), (0, operators_1.catchError)((error) => __awaiter(this, void 0, void 0, function* () {
|
|
41
|
+
yield this.handleError(error, request);
|
|
42
|
+
throw error;
|
|
43
|
+
})));
|
|
44
|
+
}
|
|
45
|
+
setRequestContext(request) {
|
|
46
|
+
var _a, _b, _c;
|
|
47
|
+
const user = request.user || {};
|
|
48
|
+
const auditContext = {
|
|
49
|
+
userId: user.uid || 'anonymous',
|
|
50
|
+
username: user.username || 'anonymous',
|
|
51
|
+
requestId: request.id || ((_a = request.headers) === null || _a === void 0 ? void 0 : _a['x-request-id']) || this.generateRequestId(),
|
|
52
|
+
requestIp: request.ip || ((_b = request.connection) === null || _b === void 0 ? void 0 : _b.remoteAddress),
|
|
53
|
+
userAgent: (_c = request.headers) === null || _c === void 0 ? void 0 : _c['user-agent'],
|
|
54
|
+
timestamp: new Date(),
|
|
55
|
+
};
|
|
56
|
+
this.contextService.setContext(auditContext);
|
|
57
|
+
}
|
|
58
|
+
handleError(error, request) {
|
|
59
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
60
|
+
this.contextService.setContext({
|
|
61
|
+
metadata: {
|
|
62
|
+
error: {
|
|
63
|
+
message: error.message,
|
|
64
|
+
stack: error.stack,
|
|
65
|
+
status: error.status,
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
isAuditEnabled(controller, handler) {
|
|
72
|
+
try {
|
|
73
|
+
const controllerMetadata = Reflect.getMetadata(decorators_1.CONTROLLER_AUDIT_OPTIONS, controller);
|
|
74
|
+
if (controllerMetadata && controllerMetadata.enabled === false) {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
const handlerMetadata = Reflect.getMetadata(decorators_1.METHOD_AUDIT_OPTIONS, handler);
|
|
78
|
+
if (handlerMetadata && handlerMetadata.enabled === false) {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
generateRequestId() {
|
|
88
|
+
return (0, crypto_1.randomBytes)(16).toString('hex');
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
exports.AuditInterceptor = AuditInterceptor;
|
|
92
|
+
exports.AuditInterceptor = AuditInterceptor = __decorate([
|
|
93
|
+
(0, common_1.Injectable)(),
|
|
94
|
+
__metadata("design:paramtypes", [audit_context_service_1.AuditContextService])
|
|
95
|
+
], AuditInterceptor);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './audit.interceptor';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./audit.interceptor"), exports);
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { AuditOperation, MaskingStrategy, RecordStrategy } from '../enums/audit.enums';
|
|
2
|
+
export interface AuditContext {
|
|
3
|
+
userId?: string;
|
|
4
|
+
username?: string;
|
|
5
|
+
requestId?: string;
|
|
6
|
+
requestIp?: string;
|
|
7
|
+
userAgent?: string;
|
|
8
|
+
timestamp?: Date;
|
|
9
|
+
transactionId?: string;
|
|
10
|
+
metadata?: Record<string, any>;
|
|
11
|
+
}
|
|
12
|
+
export interface IAuditStrategy {
|
|
13
|
+
shouldRecord(entityType: string, operation: AuditOperation): boolean;
|
|
14
|
+
getRecordStrategy(entityType: string, operation: AuditOperation): RecordStrategy;
|
|
15
|
+
getFieldFilter(entityType: string): IFieldFilter;
|
|
16
|
+
}
|
|
17
|
+
export interface IFieldFilter {
|
|
18
|
+
shouldIncludeField(fieldName: string, path: string[]): boolean;
|
|
19
|
+
shouldMaskField(fieldName: string, path: string[]): boolean;
|
|
20
|
+
getMaskingStrategy(fieldName: string, path: string[]): MaskingStrategy;
|
|
21
|
+
}
|
|
22
|
+
export interface EntityDifference {
|
|
23
|
+
changes: Array<{
|
|
24
|
+
path: string[];
|
|
25
|
+
type: 'ADD' | 'REMOVE' | 'CHANGE';
|
|
26
|
+
oldValue: any;
|
|
27
|
+
newValue: any;
|
|
28
|
+
}>;
|
|
29
|
+
summary: {
|
|
30
|
+
added: number;
|
|
31
|
+
removed: number;
|
|
32
|
+
changed: number;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
export interface RestoreOptions {
|
|
36
|
+
force?: boolean;
|
|
37
|
+
dryRun?: boolean;
|
|
38
|
+
excludeFields?: string[];
|
|
39
|
+
includeFields?: string[];
|
|
40
|
+
skipDependencies?: boolean;
|
|
41
|
+
connectionName?: string;
|
|
42
|
+
}
|
|
43
|
+
export interface RestoreResult {
|
|
44
|
+
success: boolean;
|
|
45
|
+
message?: string;
|
|
46
|
+
conflicts?: Array<{
|
|
47
|
+
field: string;
|
|
48
|
+
reason: string;
|
|
49
|
+
currentValue: any;
|
|
50
|
+
targetValue: any;
|
|
51
|
+
}>;
|
|
52
|
+
restoredEntities?: Array<{
|
|
53
|
+
entityType: string;
|
|
54
|
+
entityId: string;
|
|
55
|
+
}>;
|
|
56
|
+
}
|
|
57
|
+
export interface PreCheckResult {
|
|
58
|
+
canRestore: boolean;
|
|
59
|
+
conflicts: Array<{
|
|
60
|
+
field: string;
|
|
61
|
+
reason: string;
|
|
62
|
+
currentValue: any;
|
|
63
|
+
targetValue: any;
|
|
64
|
+
}>;
|
|
65
|
+
warnings: string[];
|
|
66
|
+
}
|
|
67
|
+
export interface BatchOperationResult {
|
|
68
|
+
total: number;
|
|
69
|
+
success: number;
|
|
70
|
+
failed: number;
|
|
71
|
+
errors: Array<{
|
|
72
|
+
index: number;
|
|
73
|
+
error: string;
|
|
74
|
+
}>;
|
|
75
|
+
results: any[];
|
|
76
|
+
}
|
|
77
|
+
export interface AuditConfig {
|
|
78
|
+
enabled?: boolean;
|
|
79
|
+
defaultStrategy?: RecordStrategy;
|
|
80
|
+
maxDiffDepth?: number;
|
|
81
|
+
maxDiffFields?: number;
|
|
82
|
+
connections?: {
|
|
83
|
+
audit?: string;
|
|
84
|
+
monitored?: string[];
|
|
85
|
+
};
|
|
86
|
+
entities?: Record<string, EntityAuditConfig>;
|
|
87
|
+
operations?: Record<string, OperationAuditConfig>;
|
|
88
|
+
security?: {
|
|
89
|
+
hashChainEnabled?: boolean;
|
|
90
|
+
hashAlgorithm?: string;
|
|
91
|
+
masking?: {
|
|
92
|
+
defaultStrategy?: MaskingStrategy;
|
|
93
|
+
strategies?: Record<string, MaskingStrategy>;
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
export interface EntityAuditConfig {
|
|
98
|
+
enabled?: boolean;
|
|
99
|
+
strategy?: RecordStrategy;
|
|
100
|
+
includeFields?: string[];
|
|
101
|
+
excludeFields?: string[];
|
|
102
|
+
maskFields?: string[];
|
|
103
|
+
}
|
|
104
|
+
export interface OperationAuditConfig {
|
|
105
|
+
enabled?: boolean;
|
|
106
|
+
strategy?: RecordStrategy;
|
|
107
|
+
}
|
|
108
|
+
export interface FieldDisplayOptions {
|
|
109
|
+
displayName?: string;
|
|
110
|
+
sensitive?: boolean;
|
|
111
|
+
formatter?: (value: any) => string;
|
|
112
|
+
}
|
|
113
|
+
export interface ControllerAuditOptions {
|
|
114
|
+
enabled?: boolean;
|
|
115
|
+
operations?: AuditOperation[];
|
|
116
|
+
}
|
|
117
|
+
export interface MethodAuditOptions {
|
|
118
|
+
enabled?: boolean;
|
|
119
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './audit.interfaces';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./audit.interfaces"), exports);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ClsService } from 'nestjs-cls';
|
|
2
|
+
import { AuditContext } from '../interfaces';
|
|
3
|
+
export declare class AuditContextService {
|
|
4
|
+
private readonly cls;
|
|
5
|
+
constructor(cls: ClsService);
|
|
6
|
+
getCurrentContext(): Promise<AuditContext>;
|
|
7
|
+
setContext(context: Partial<AuditContext>): void;
|
|
8
|
+
clearContext(): void;
|
|
9
|
+
private getDefaultContext;
|
|
10
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
12
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
13
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
14
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
15
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
16
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
17
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
exports.AuditContextService = void 0;
|
|
22
|
+
const common_1 = require("@nestjs/common");
|
|
23
|
+
const nestjs_cls_1 = require("nestjs-cls");
|
|
24
|
+
let AuditContextService = class AuditContextService {
|
|
25
|
+
constructor(cls) {
|
|
26
|
+
this.cls = cls;
|
|
27
|
+
}
|
|
28
|
+
getCurrentContext() {
|
|
29
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
30
|
+
return this.cls.get('auditContext') || this.getDefaultContext();
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
setContext(context) {
|
|
34
|
+
const currentContext = this.cls.get('auditContext') || this.getDefaultContext();
|
|
35
|
+
this.cls.set('auditContext', Object.assign(Object.assign({}, currentContext), context));
|
|
36
|
+
}
|
|
37
|
+
clearContext() {
|
|
38
|
+
this.cls.set('auditContext', undefined);
|
|
39
|
+
}
|
|
40
|
+
getDefaultContext() {
|
|
41
|
+
return {
|
|
42
|
+
userId: 'system',
|
|
43
|
+
username: 'system',
|
|
44
|
+
requestId: '',
|
|
45
|
+
requestIp: '',
|
|
46
|
+
userAgent: '',
|
|
47
|
+
timestamp: new Date(),
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
exports.AuditContextService = AuditContextService;
|
|
52
|
+
exports.AuditContextService = AuditContextService = __decorate([
|
|
53
|
+
(0, common_1.Injectable)(),
|
|
54
|
+
__metadata("design:paramtypes", [nestjs_cls_1.ClsService])
|
|
55
|
+
], AuditContextService);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { IAuditStrategy, IFieldFilter, AuditConfig } from '../interfaces';
|
|
2
|
+
import { AuditOperation, RecordStrategy, MaskingStrategy } from '../enums';
|
|
3
|
+
export declare class DefaultFieldFilter implements IFieldFilter {
|
|
4
|
+
private readonly includeFields?;
|
|
5
|
+
private readonly excludeFields?;
|
|
6
|
+
private readonly maskFields?;
|
|
7
|
+
constructor(includeFields?: string[], excludeFields?: string[], maskFields?: string[]);
|
|
8
|
+
shouldIncludeField(fieldName: string, path: string[]): boolean;
|
|
9
|
+
shouldMaskField(fieldName: string, path: string[]): boolean;
|
|
10
|
+
getMaskingStrategy(fieldName: string, path: string[]): MaskingStrategy;
|
|
11
|
+
private matchPattern;
|
|
12
|
+
}
|
|
13
|
+
export declare class DefaultAuditStrategy implements IAuditStrategy {
|
|
14
|
+
private readonly config?;
|
|
15
|
+
constructor(config?: AuditConfig);
|
|
16
|
+
shouldRecord(entityType: string, operation: AuditOperation): boolean;
|
|
17
|
+
getRecordStrategy(entityType: string, operation: AuditOperation): RecordStrategy;
|
|
18
|
+
getFieldFilter(entityType: string): IFieldFilter;
|
|
19
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.DefaultAuditStrategy = exports.DefaultFieldFilter = void 0;
|
|
16
|
+
const common_1 = require("@nestjs/common");
|
|
17
|
+
const enums_1 = require("../enums");
|
|
18
|
+
class DefaultFieldFilter {
|
|
19
|
+
constructor(includeFields, excludeFields, maskFields) {
|
|
20
|
+
this.includeFields = includeFields;
|
|
21
|
+
this.excludeFields = excludeFields;
|
|
22
|
+
this.maskFields = maskFields;
|
|
23
|
+
}
|
|
24
|
+
shouldIncludeField(fieldName, path) {
|
|
25
|
+
const fullPath = [...path, fieldName].join('.');
|
|
26
|
+
if (this.includeFields && this.includeFields.length > 0) {
|
|
27
|
+
return this.includeFields.some((pattern) => this.matchPattern(fullPath, pattern));
|
|
28
|
+
}
|
|
29
|
+
if (this.excludeFields && this.excludeFields.length > 0) {
|
|
30
|
+
return !this.excludeFields.some((pattern) => this.matchPattern(fullPath, pattern));
|
|
31
|
+
}
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
shouldMaskField(fieldName, path) {
|
|
35
|
+
var _a;
|
|
36
|
+
const fullPath = [...path, fieldName].join('.');
|
|
37
|
+
return ((_a = this.maskFields) === null || _a === void 0 ? void 0 : _a.some((pattern) => this.matchPattern(fullPath, pattern))) || false;
|
|
38
|
+
}
|
|
39
|
+
getMaskingStrategy(fieldName, path) {
|
|
40
|
+
return enums_1.MaskingStrategy.MASK;
|
|
41
|
+
}
|
|
42
|
+
matchPattern(path, pattern) {
|
|
43
|
+
if (pattern.endsWith('*')) {
|
|
44
|
+
return path.startsWith(pattern.slice(0, -1));
|
|
45
|
+
}
|
|
46
|
+
return path === pattern;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
exports.DefaultFieldFilter = DefaultFieldFilter;
|
|
50
|
+
let DefaultAuditStrategy = class DefaultAuditStrategy {
|
|
51
|
+
constructor(config) {
|
|
52
|
+
this.config = config;
|
|
53
|
+
}
|
|
54
|
+
shouldRecord(entityType, operation) {
|
|
55
|
+
var _a, _b, _c, _d, _e;
|
|
56
|
+
const globalEnabled = ((_a = this.config) === null || _a === void 0 ? void 0 : _a.enabled) !== false;
|
|
57
|
+
if (!globalEnabled)
|
|
58
|
+
return false;
|
|
59
|
+
const entityConfig = (_c = (_b = this.config) === null || _b === void 0 ? void 0 : _b.entities) === null || _c === void 0 ? void 0 : _c[entityType];
|
|
60
|
+
if (entityConfig && entityConfig.enabled === false)
|
|
61
|
+
return false;
|
|
62
|
+
const operationConfig = (_e = (_d = this.config) === null || _d === void 0 ? void 0 : _d.operations) === null || _e === void 0 ? void 0 : _e[operation];
|
|
63
|
+
if (operationConfig && operationConfig.enabled === false)
|
|
64
|
+
return false;
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
getRecordStrategy(entityType, operation) {
|
|
68
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
69
|
+
const entityStrategy = (_c = (_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.entities) === null || _b === void 0 ? void 0 : _b[entityType]) === null || _c === void 0 ? void 0 : _c.strategy;
|
|
70
|
+
if (entityStrategy)
|
|
71
|
+
return entityStrategy;
|
|
72
|
+
const operationStrategy = (_f = (_e = (_d = this.config) === null || _d === void 0 ? void 0 : _d.operations) === null || _e === void 0 ? void 0 : _e[operation]) === null || _f === void 0 ? void 0 : _f.strategy;
|
|
73
|
+
if (operationStrategy)
|
|
74
|
+
return operationStrategy;
|
|
75
|
+
return ((_g = this.config) === null || _g === void 0 ? void 0 : _g.defaultStrategy) || enums_1.RecordStrategy.FULL;
|
|
76
|
+
}
|
|
77
|
+
getFieldFilter(entityType) {
|
|
78
|
+
var _a, _b;
|
|
79
|
+
const entityConfig = (_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.entities) === null || _b === void 0 ? void 0 : _b[entityType];
|
|
80
|
+
return new DefaultFieldFilter(entityConfig === null || entityConfig === void 0 ? void 0 : entityConfig.includeFields, entityConfig === null || entityConfig === void 0 ? void 0 : entityConfig.excludeFields, entityConfig === null || entityConfig === void 0 ? void 0 : entityConfig.maskFields);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
exports.DefaultAuditStrategy = DefaultAuditStrategy;
|
|
84
|
+
exports.DefaultAuditStrategy = DefaultAuditStrategy = __decorate([
|
|
85
|
+
(0, common_1.Injectable)(),
|
|
86
|
+
__param(0, (0, common_1.Optional)()),
|
|
87
|
+
__param(0, (0, common_1.Inject)('AUDIT_CONFIG')),
|
|
88
|
+
__metadata("design:paramtypes", [Object])
|
|
89
|
+
], DefaultAuditStrategy);
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Repository, EntityManager } from 'typeorm';
|
|
2
|
+
import { EntityAuditLogEntity, EntityTransactionEntity } from '../entities';
|
|
3
|
+
import { AuditOperation } from '../enums';
|
|
4
|
+
import { AuditConfig, IAuditStrategy, EntityDifference, RestoreOptions, RestoreResult, PreCheckResult } from '../interfaces';
|
|
5
|
+
import { AuditContextService } from './audit-context.service';
|
|
6
|
+
import { MultiDatabaseService } from './multi-database.service';
|
|
7
|
+
import { PageDto } from '../../common/dto';
|
|
8
|
+
import { AuditLogQueryDto } from '../dto';
|
|
9
|
+
export declare class EntityAuditService {
|
|
10
|
+
private readonly auditLogRepository;
|
|
11
|
+
private readonly transactionRepository;
|
|
12
|
+
private readonly entityManager;
|
|
13
|
+
private readonly contextService;
|
|
14
|
+
private readonly multiDbService;
|
|
15
|
+
private readonly auditStrategy;
|
|
16
|
+
private readonly config?;
|
|
17
|
+
private readonly auditConnectionName;
|
|
18
|
+
constructor(auditLogRepository: Repository<EntityAuditLogEntity>, transactionRepository: Repository<EntityTransactionEntity>, entityManager: EntityManager, contextService: AuditContextService, multiDbService: MultiDatabaseService, auditStrategy?: IAuditStrategy, config?: AuditConfig, auditConnectionName?: string);
|
|
19
|
+
logEntityChange(entityType: string, entityId: string, operation: AuditOperation, oldValue: Record<string, any>, newValue: Record<string, any>, metadata?: Record<string, any>): Promise<EntityAuditLogEntity | null>;
|
|
20
|
+
getAuditLogs(query: AuditLogQueryDto): Promise<PageDto<EntityAuditLogEntity>>;
|
|
21
|
+
compareEntities(entityType: string, entityId: string, fromLogId?: string, toLogId?: string): Promise<EntityDifference>;
|
|
22
|
+
preCheckRestore(entityType: string, entityId: string, auditLogId: string): Promise<PreCheckResult>;
|
|
23
|
+
restoreEntity(entityType: string, entityId: string, auditLogId: string, options?: RestoreOptions): Promise<RestoreResult>;
|
|
24
|
+
private calculateChangedFields;
|
|
25
|
+
private calculateChangedFieldPaths;
|
|
26
|
+
private deepEqual;
|
|
27
|
+
private deepDiff;
|
|
28
|
+
private compareSnapshotData;
|
|
29
|
+
private filterAndMaskFields;
|
|
30
|
+
private applyMasking;
|
|
31
|
+
private hashValue;
|
|
32
|
+
private maskValue;
|
|
33
|
+
private partialMaskValue;
|
|
34
|
+
private generateHashChain;
|
|
35
|
+
private generateDescription;
|
|
36
|
+
private detectConflicts;
|
|
37
|
+
}
|