@flusys/nestjs-shared 1.0.0-rc → 1.0.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/README.md +493 -658
- package/cjs/classes/api-service.class.js +59 -92
- package/cjs/classes/winston-logger-adapter.class.js +23 -40
- package/cjs/constants/permissions.js +11 -1
- package/cjs/dtos/delete.dto.js +10 -0
- package/cjs/dtos/response-payload.dto.js +0 -75
- package/cjs/guards/permission.guard.js +19 -18
- package/cjs/interceptors/index.js +0 -3
- package/cjs/interceptors/set-user-field-on-body.interceptor.js +20 -3
- package/cjs/middlewares/logger.middleware.js +50 -89
- package/cjs/modules/datasource/datasource.module.js +11 -14
- package/cjs/modules/datasource/multi-tenant-datasource.service.js +0 -4
- package/cjs/modules/utils/utils.service.js +22 -103
- package/cjs/utils/error-handler.util.js +12 -67
- package/cjs/utils/html-sanitizer.util.js +1 -11
- package/cjs/utils/index.js +2 -0
- package/cjs/utils/request.util.js +70 -0
- package/cjs/utils/string.util.js +63 -0
- package/classes/api-service.class.d.ts +2 -0
- package/classes/winston-logger-adapter.class.d.ts +2 -0
- package/constants/permissions.d.ts +12 -0
- package/dtos/delete.dto.d.ts +1 -0
- package/dtos/response-payload.dto.d.ts +0 -13
- package/fesm/classes/api-service.class.js +59 -92
- package/fesm/classes/winston-logger-adapter.class.js +23 -40
- package/fesm/constants/permissions.js +8 -1
- package/fesm/dtos/delete.dto.js +12 -2
- package/fesm/dtos/response-payload.dto.js +0 -69
- package/fesm/guards/permission.guard.js +19 -18
- package/fesm/interceptors/index.js +0 -3
- package/fesm/interceptors/set-user-field-on-body.interceptor.js +3 -0
- package/fesm/middlewares/logger.middleware.js +50 -83
- package/fesm/modules/datasource/datasource.module.js +11 -14
- package/fesm/modules/datasource/multi-tenant-datasource.service.js +0 -4
- package/fesm/modules/utils/utils.service.js +19 -89
- package/fesm/utils/error-handler.util.js +12 -68
- package/fesm/utils/html-sanitizer.util.js +1 -14
- package/fesm/utils/index.js +2 -0
- package/fesm/utils/request.util.js +58 -0
- package/fesm/utils/string.util.js +71 -0
- package/guards/permission.guard.d.ts +2 -0
- package/interceptors/index.d.ts +0 -3
- package/interceptors/set-user-field-on-body.interceptor.d.ts +3 -0
- package/interfaces/logged-user-info.interface.d.ts +0 -2
- package/middlewares/logger.middleware.d.ts +2 -2
- package/modules/datasource/datasource.module.d.ts +1 -0
- package/modules/datasource/multi-tenant-datasource.service.d.ts +0 -1
- package/modules/utils/utils.service.d.ts +2 -18
- package/package.json +2 -2
- package/utils/error-handler.util.d.ts +3 -18
- package/utils/html-sanitizer.util.d.ts +0 -1
- package/utils/index.d.ts +2 -0
- package/utils/request.util.d.ts +4 -0
- package/utils/string.util.d.ts +2 -0
- package/cjs/interceptors/set-create-by-on-body.interceptor.js +0 -12
- package/cjs/interceptors/set-delete-by-on-body.interceptor.js +0 -12
- package/cjs/interceptors/set-update-by-on-body.interceptor.js +0 -12
- package/fesm/interceptors/set-create-by-on-body.interceptor.js +0 -4
- package/fesm/interceptors/set-delete-by-on-body.interceptor.js +0 -4
- package/fesm/interceptors/set-update-by-on-body.interceptor.js +0 -4
- package/interceptors/set-create-by-on-body.interceptor.d.ts +0 -1
- package/interceptors/set-delete-by-on-body.interceptor.d.ts +0 -1
- package/interceptors/set-update-by-on-body.interceptor.d.ts +0 -1
|
@@ -26,116 +26,52 @@ function _define_property(obj, key, value) {
|
|
|
26
26
|
}
|
|
27
27
|
let ApiService = class ApiService {
|
|
28
28
|
async insert(dto, user) {
|
|
29
|
-
|
|
30
|
-
const qr = this.repository.manager.connection.createQueryRunner();
|
|
31
|
-
await qr.connect();
|
|
32
|
-
await qr.startTransaction();
|
|
33
|
-
try {
|
|
29
|
+
return this.executeInTransaction('insert', async (qr)=>{
|
|
34
30
|
await this.beforeInsertOperation(dto, user, qr);
|
|
35
31
|
const entities = await this.convertRequestDtoToEntity(dto, user);
|
|
36
32
|
const saved = await qr.manager.save(this.repository.target, entities);
|
|
37
|
-
await this.afterInsertOperation(saved, user, qr);
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
])
|
|
44
|
-
]);
|
|
45
|
-
const first = Array.isArray(saved) ? saved[0] : saved;
|
|
46
|
-
return this.convertEntityToResponseDto(first, false);
|
|
47
|
-
} catch (error) {
|
|
48
|
-
await qr.rollbackTransaction();
|
|
49
|
-
this.handleError(error, 'insert');
|
|
50
|
-
} finally{
|
|
51
|
-
await qr.release();
|
|
52
|
-
}
|
|
33
|
+
await this.afterInsertOperation(this.ensureArray(saved), user, qr);
|
|
34
|
+
return {
|
|
35
|
+
saved,
|
|
36
|
+
returnFirst: true
|
|
37
|
+
};
|
|
38
|
+
});
|
|
53
39
|
}
|
|
54
40
|
async insertMany(dtos, user) {
|
|
55
|
-
|
|
56
|
-
const qr = this.repository.manager.connection.createQueryRunner();
|
|
57
|
-
await qr.connect();
|
|
58
|
-
await qr.startTransaction();
|
|
59
|
-
try {
|
|
41
|
+
return this.executeInTransaction('insertMany', async (qr)=>{
|
|
60
42
|
await this.beforeInsertOperation(dtos, user, qr);
|
|
61
43
|
const entities = await this.convertRequestDtoToEntity(dtos, user);
|
|
62
44
|
const saved = await qr.manager.save(this.repository.target, entities);
|
|
63
|
-
await this.afterInsertOperation(
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
this.clearCacheForId(Array.isArray(saved) ? saved : [
|
|
70
|
-
saved
|
|
71
|
-
])
|
|
72
|
-
]);
|
|
73
|
-
const list = (Array.isArray(saved) ? saved : [
|
|
74
|
-
saved
|
|
75
|
-
]).map((e)=>this.convertEntityToResponseDto(e, false));
|
|
76
|
-
return list;
|
|
77
|
-
} catch (error) {
|
|
78
|
-
await qr.rollbackTransaction();
|
|
79
|
-
this.handleError(error, 'insertMany');
|
|
80
|
-
} finally{
|
|
81
|
-
await qr.release();
|
|
82
|
-
}
|
|
45
|
+
await this.afterInsertOperation(this.ensureArray(saved), user, qr);
|
|
46
|
+
return {
|
|
47
|
+
saved,
|
|
48
|
+
returnFirst: false
|
|
49
|
+
};
|
|
50
|
+
});
|
|
83
51
|
}
|
|
84
52
|
async update(dto, user) {
|
|
85
|
-
|
|
86
|
-
const qr = this.repository.manager.connection.createQueryRunner();
|
|
87
|
-
await qr.connect();
|
|
88
|
-
await qr.startTransaction();
|
|
89
|
-
try {
|
|
53
|
+
return this.executeInTransaction('update', async (qr)=>{
|
|
90
54
|
await this.beforeUpdateOperation(dto, user, qr);
|
|
91
55
|
const entities = await this.convertRequestDtoToEntity(dto, user);
|
|
92
56
|
const saved = await qr.manager.save(this.repository.target, entities);
|
|
93
|
-
await this.afterUpdateOperation(saved, user, qr);
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
])
|
|
100
|
-
]);
|
|
101
|
-
const first = Array.isArray(saved) ? saved[0] : saved;
|
|
102
|
-
return this.convertEntityToResponseDto(first, false);
|
|
103
|
-
} catch (error) {
|
|
104
|
-
await qr.rollbackTransaction();
|
|
105
|
-
this.handleError(error, 'update');
|
|
106
|
-
} finally{
|
|
107
|
-
await qr.release();
|
|
108
|
-
}
|
|
57
|
+
await this.afterUpdateOperation(this.ensureArray(saved), user, qr);
|
|
58
|
+
return {
|
|
59
|
+
saved,
|
|
60
|
+
returnFirst: true
|
|
61
|
+
};
|
|
62
|
+
});
|
|
109
63
|
}
|
|
110
64
|
async updateMany(dtos, user) {
|
|
111
|
-
|
|
112
|
-
const qr = this.repository.manager.connection.createQueryRunner();
|
|
113
|
-
await qr.connect();
|
|
114
|
-
await qr.startTransaction();
|
|
115
|
-
try {
|
|
65
|
+
return this.executeInTransaction('updateMany', async (qr)=>{
|
|
116
66
|
await this.beforeUpdateOperation(dtos, user, qr);
|
|
117
67
|
const entities = await this.convertRequestDtoToEntity(dtos, user);
|
|
118
68
|
const saved = await qr.manager.save(this.repository.target, entities);
|
|
119
|
-
await this.afterUpdateOperation(
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
this.clearCacheForId(Array.isArray(saved) ? saved : [
|
|
126
|
-
saved
|
|
127
|
-
])
|
|
128
|
-
]);
|
|
129
|
-
const list = (Array.isArray(saved) ? saved : [
|
|
130
|
-
saved
|
|
131
|
-
]).map((e)=>this.convertEntityToResponseDto(e, false));
|
|
132
|
-
return list;
|
|
133
|
-
} catch (error) {
|
|
134
|
-
await qr.rollbackTransaction();
|
|
135
|
-
this.handleError(error, 'updateMany');
|
|
136
|
-
} finally{
|
|
137
|
-
await qr.release();
|
|
138
|
-
}
|
|
69
|
+
await this.afterUpdateOperation(this.ensureArray(saved), user, qr);
|
|
70
|
+
return {
|
|
71
|
+
saved,
|
|
72
|
+
returnFirst: false
|
|
73
|
+
};
|
|
74
|
+
});
|
|
139
75
|
}
|
|
140
76
|
async findByIds(ids, user) {
|
|
141
77
|
await this.ensureRepositoryInitialized();
|
|
@@ -354,6 +290,37 @@ let ApiService = class ApiService {
|
|
|
354
290
|
});
|
|
355
291
|
_errorhandlerutil.ErrorHandler.rethrowError(error);
|
|
356
292
|
}
|
|
293
|
+
/** Ensures value is always an array */ ensureArray(value) {
|
|
294
|
+
return Array.isArray(value) ? value : [
|
|
295
|
+
value
|
|
296
|
+
];
|
|
297
|
+
}
|
|
298
|
+
/** Executes operation in transaction with automatic cache clearing */ async executeInTransaction(operation, fn) {
|
|
299
|
+
await this.ensureRepositoryInitialized();
|
|
300
|
+
const qr = this.repository.manager.connection.createQueryRunner();
|
|
301
|
+
await qr.connect();
|
|
302
|
+
await qr.startTransaction();
|
|
303
|
+
try {
|
|
304
|
+
const { saved, returnFirst } = await fn(qr);
|
|
305
|
+
await qr.commitTransaction();
|
|
306
|
+
const savedArray = this.ensureArray(saved);
|
|
307
|
+
if (this.isCacheable) {
|
|
308
|
+
await Promise.all([
|
|
309
|
+
this.clearCacheForAll(),
|
|
310
|
+
this.clearCacheForId(savedArray)
|
|
311
|
+
]);
|
|
312
|
+
}
|
|
313
|
+
if (returnFirst) {
|
|
314
|
+
return this.convertEntityToResponseDto(savedArray[0], false);
|
|
315
|
+
}
|
|
316
|
+
return savedArray.map((e)=>this.convertEntityToResponseDto(e, false));
|
|
317
|
+
} catch (error) {
|
|
318
|
+
await qr.rollbackTransaction();
|
|
319
|
+
this.handleError(error, operation);
|
|
320
|
+
} finally{
|
|
321
|
+
await qr.release();
|
|
322
|
+
}
|
|
323
|
+
}
|
|
357
324
|
// Hooks (override in child classes)
|
|
358
325
|
async ensureRepositoryInitialized() {}
|
|
359
326
|
async beforeInsertOperation(_dto, _user, _queryRunner) {}
|
|
@@ -47,46 +47,31 @@ function _define_property(obj, key, value) {
|
|
|
47
47
|
return meta;
|
|
48
48
|
}
|
|
49
49
|
let WinstonLoggerAdapter = class WinstonLoggerAdapter {
|
|
50
|
-
|
|
51
|
-
const meta = args
|
|
52
|
-
|
|
50
|
+
buildLogMeta(context, args, extra) {
|
|
51
|
+
const meta = args?.length && typeof args[0] === 'object' ? args[0] : {};
|
|
52
|
+
return {
|
|
53
53
|
context: context || this.context,
|
|
54
54
|
...getCorrelationMeta(),
|
|
55
|
-
...meta
|
|
56
|
-
|
|
55
|
+
...meta,
|
|
56
|
+
...extra
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
log(message, context, ...args) {
|
|
60
|
+
_winstonloggerclass.instance.info(message, this.buildLogMeta(context, args));
|
|
57
61
|
}
|
|
58
62
|
error(message, trace, context, ...args) {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
stack: trace,
|
|
63
|
-
...getCorrelationMeta(),
|
|
64
|
-
...meta
|
|
65
|
-
});
|
|
63
|
+
_winstonloggerclass.instance.error(message, this.buildLogMeta(context, args, {
|
|
64
|
+
stack: trace
|
|
65
|
+
}));
|
|
66
66
|
}
|
|
67
67
|
warn(message, context, ...args) {
|
|
68
|
-
|
|
69
|
-
_winstonloggerclass.instance.warn(message, {
|
|
70
|
-
context: context || this.context,
|
|
71
|
-
...getCorrelationMeta(),
|
|
72
|
-
...meta
|
|
73
|
-
});
|
|
68
|
+
_winstonloggerclass.instance.warn(message, this.buildLogMeta(context, args));
|
|
74
69
|
}
|
|
75
70
|
debug(message, context, ...args) {
|
|
76
|
-
|
|
77
|
-
_winstonloggerclass.instance.debug(message, {
|
|
78
|
-
context: context || this.context,
|
|
79
|
-
...getCorrelationMeta(),
|
|
80
|
-
...meta
|
|
81
|
-
});
|
|
71
|
+
_winstonloggerclass.instance.debug(message, this.buildLogMeta(context, args));
|
|
82
72
|
}
|
|
83
73
|
verbose(message, context, ...args) {
|
|
84
|
-
|
|
85
|
-
_winstonloggerclass.instance.verbose(message, {
|
|
86
|
-
context: context || this.context,
|
|
87
|
-
...getCorrelationMeta(),
|
|
88
|
-
...meta
|
|
89
|
-
});
|
|
74
|
+
_winstonloggerclass.instance.verbose(message, this.buildLogMeta(context, args));
|
|
90
75
|
}
|
|
91
76
|
constructor(context){
|
|
92
77
|
_define_property(this, "context", void 0);
|
|
@@ -94,25 +79,23 @@ let WinstonLoggerAdapter = class WinstonLoggerAdapter {
|
|
|
94
79
|
}
|
|
95
80
|
};
|
|
96
81
|
let NestLoggerAdapter = class NestLoggerAdapter {
|
|
82
|
+
formatMessage(message, args) {
|
|
83
|
+
return args?.length ? `${message} ${JSON.stringify(args)}` : message;
|
|
84
|
+
}
|
|
97
85
|
log(message, context, ...args) {
|
|
98
|
-
|
|
99
|
-
this.logger.log(logMessage, context);
|
|
86
|
+
this.logger.log(this.formatMessage(message, args), context);
|
|
100
87
|
}
|
|
101
88
|
error(message, trace, context, ...args) {
|
|
102
|
-
|
|
103
|
-
this.logger.error(logMessage, trace, context);
|
|
89
|
+
this.logger.error(this.formatMessage(message, args), trace, context);
|
|
104
90
|
}
|
|
105
91
|
warn(message, context, ...args) {
|
|
106
|
-
|
|
107
|
-
this.logger.warn(logMessage, context);
|
|
92
|
+
this.logger.warn(this.formatMessage(message, args), context);
|
|
108
93
|
}
|
|
109
94
|
debug(message, context, ...args) {
|
|
110
|
-
|
|
111
|
-
this.logger.debug(logMessage, context);
|
|
95
|
+
this.logger.debug(this.formatMessage(message, args), context);
|
|
112
96
|
}
|
|
113
97
|
verbose(message, context, ...args) {
|
|
114
|
-
|
|
115
|
-
this.logger.verbose(logMessage, context);
|
|
98
|
+
this.logger.verbose(this.formatMessage(message, args), context);
|
|
116
99
|
}
|
|
117
100
|
constructor(logger){
|
|
118
101
|
_define_property(this, "logger", void 0);
|
|
@@ -46,6 +46,9 @@ _export(exports, {
|
|
|
46
46
|
get FORM_PERMISSIONS () {
|
|
47
47
|
return FORM_PERMISSIONS;
|
|
48
48
|
},
|
|
49
|
+
get FORM_RESULT_PERMISSIONS () {
|
|
50
|
+
return FORM_RESULT_PERMISSIONS;
|
|
51
|
+
},
|
|
49
52
|
get PERMISSIONS () {
|
|
50
53
|
return PERMISSIONS;
|
|
51
54
|
},
|
|
@@ -150,6 +153,12 @@ const FORM_PERMISSIONS = {
|
|
|
150
153
|
UPDATE: 'form.update',
|
|
151
154
|
DELETE: 'form.delete'
|
|
152
155
|
};
|
|
156
|
+
const FORM_RESULT_PERMISSIONS = {
|
|
157
|
+
CREATE: 'form-result.create',
|
|
158
|
+
READ: 'form-result.read',
|
|
159
|
+
UPDATE: 'form-result.update',
|
|
160
|
+
DELETE: 'form-result.delete'
|
|
161
|
+
};
|
|
153
162
|
const PERMISSIONS = {
|
|
154
163
|
// Auth
|
|
155
164
|
USER: USER_PERMISSIONS,
|
|
@@ -170,5 +179,6 @@ const PERMISSIONS = {
|
|
|
170
179
|
EMAIL_CONFIG: EMAIL_CONFIG_PERMISSIONS,
|
|
171
180
|
EMAIL_TEMPLATE: EMAIL_TEMPLATE_PERMISSIONS,
|
|
172
181
|
// Form Builder
|
|
173
|
-
FORM: FORM_PERMISSIONS
|
|
182
|
+
FORM: FORM_PERMISSIONS,
|
|
183
|
+
FORM_RESULT: FORM_RESULT_PERMISSIONS
|
|
174
184
|
};
|
package/cjs/dtos/delete.dto.js
CHANGED
|
@@ -36,6 +36,7 @@ let DeleteDto = class DeleteDto {
|
|
|
36
36
|
constructor(){
|
|
37
37
|
_define_property(this, "id", void 0);
|
|
38
38
|
_define_property(this, "type", void 0);
|
|
39
|
+
_define_property(this, "deletedById", void 0);
|
|
39
40
|
}
|
|
40
41
|
};
|
|
41
42
|
_ts_decorate([
|
|
@@ -80,3 +81,12 @@ _ts_decorate([
|
|
|
80
81
|
]),
|
|
81
82
|
_ts_metadata("design:type", String)
|
|
82
83
|
], DeleteDto.prototype, "type", void 0);
|
|
84
|
+
_ts_decorate([
|
|
85
|
+
(0, _swagger.ApiPropertyOptional)({
|
|
86
|
+
description: 'User ID who initiated the deletion (auto-set by interceptor)',
|
|
87
|
+
example: 'f2e9c8d0-7a2a-11eb-9439-0242ac130002'
|
|
88
|
+
}),
|
|
89
|
+
(0, _classvalidator.IsOptional)(),
|
|
90
|
+
(0, _classvalidator.IsUUID)(),
|
|
91
|
+
_ts_metadata("design:type", String)
|
|
92
|
+
], DeleteDto.prototype, "deletedById", void 0);
|
|
@@ -15,9 +15,6 @@ _export(exports, {
|
|
|
15
15
|
get BulkResponseDto () {
|
|
16
16
|
return BulkResponseDto;
|
|
17
17
|
},
|
|
18
|
-
get ErrorResponseDto () {
|
|
19
|
-
return ErrorResponseDto;
|
|
20
|
-
},
|
|
21
18
|
get ListResponseDto () {
|
|
22
19
|
return ListResponseDto;
|
|
23
20
|
},
|
|
@@ -32,9 +29,6 @@ _export(exports, {
|
|
|
32
29
|
},
|
|
33
30
|
get SingleResponseDto () {
|
|
34
31
|
return SingleResponseDto;
|
|
35
|
-
},
|
|
36
|
-
get ValidationErrorDto () {
|
|
37
|
-
return ValidationErrorDto;
|
|
38
32
|
}
|
|
39
33
|
});
|
|
40
34
|
const _swagger = require("@nestjs/swagger");
|
|
@@ -301,72 +295,3 @@ _ts_decorate([
|
|
|
301
295
|
MessageResponseDto = _ts_decorate([
|
|
302
296
|
(0, _swagger.ApiExtraModels)()
|
|
303
297
|
], MessageResponseDto);
|
|
304
|
-
let ValidationErrorDto = class ValidationErrorDto {
|
|
305
|
-
constructor(){
|
|
306
|
-
_define_property(this, "field", void 0);
|
|
307
|
-
_define_property(this, "message", void 0);
|
|
308
|
-
_define_property(this, "constraint", void 0);
|
|
309
|
-
}
|
|
310
|
-
};
|
|
311
|
-
_ts_decorate([
|
|
312
|
-
(0, _swagger.ApiProperty)({
|
|
313
|
-
example: 'email'
|
|
314
|
-
}),
|
|
315
|
-
_ts_metadata("design:type", String)
|
|
316
|
-
], ValidationErrorDto.prototype, "field", void 0);
|
|
317
|
-
_ts_decorate([
|
|
318
|
-
(0, _swagger.ApiProperty)({
|
|
319
|
-
example: 'Invalid email format'
|
|
320
|
-
}),
|
|
321
|
-
_ts_metadata("design:type", String)
|
|
322
|
-
], ValidationErrorDto.prototype, "message", void 0);
|
|
323
|
-
_ts_decorate([
|
|
324
|
-
(0, _swagger.ApiPropertyOptional)({
|
|
325
|
-
example: 'isEmail'
|
|
326
|
-
}),
|
|
327
|
-
_ts_metadata("design:type", String)
|
|
328
|
-
], ValidationErrorDto.prototype, "constraint", void 0);
|
|
329
|
-
let ErrorResponseDto = class ErrorResponseDto {
|
|
330
|
-
constructor(){
|
|
331
|
-
_define_property(this, "success", void 0);
|
|
332
|
-
_define_property(this, "message", void 0);
|
|
333
|
-
_define_property(this, "code", void 0);
|
|
334
|
-
_define_property(this, "errors", void 0);
|
|
335
|
-
_define_property(this, "_meta", void 0);
|
|
336
|
-
}
|
|
337
|
-
};
|
|
338
|
-
_ts_decorate([
|
|
339
|
-
(0, _swagger.ApiProperty)({
|
|
340
|
-
example: false
|
|
341
|
-
}),
|
|
342
|
-
_ts_metadata("design:type", Boolean)
|
|
343
|
-
], ErrorResponseDto.prototype, "success", void 0);
|
|
344
|
-
_ts_decorate([
|
|
345
|
-
(0, _swagger.ApiProperty)({
|
|
346
|
-
example: 'Validation failed'
|
|
347
|
-
}),
|
|
348
|
-
_ts_metadata("design:type", String)
|
|
349
|
-
], ErrorResponseDto.prototype, "message", void 0);
|
|
350
|
-
_ts_decorate([
|
|
351
|
-
(0, _swagger.ApiPropertyOptional)({
|
|
352
|
-
example: 'VALIDATION_ERROR'
|
|
353
|
-
}),
|
|
354
|
-
_ts_metadata("design:type", String)
|
|
355
|
-
], ErrorResponseDto.prototype, "code", void 0);
|
|
356
|
-
_ts_decorate([
|
|
357
|
-
(0, _swagger.ApiPropertyOptional)({
|
|
358
|
-
type: [
|
|
359
|
-
ValidationErrorDto
|
|
360
|
-
]
|
|
361
|
-
}),
|
|
362
|
-
_ts_metadata("design:type", Array)
|
|
363
|
-
], ErrorResponseDto.prototype, "errors", void 0);
|
|
364
|
-
_ts_decorate([
|
|
365
|
-
(0, _swagger.ApiPropertyOptional)({
|
|
366
|
-
type: RequestMetaDto
|
|
367
|
-
}),
|
|
368
|
-
_ts_metadata("design:type", typeof RequestMetaDto === "undefined" ? Object : RequestMetaDto)
|
|
369
|
-
], ErrorResponseDto.prototype, "_meta", void 0);
|
|
370
|
-
ErrorResponseDto = _ts_decorate([
|
|
371
|
-
(0, _swagger.ApiExtraModels)()
|
|
372
|
-
], ErrorResponseDto);
|
|
@@ -76,17 +76,7 @@ let PermissionGuard = class PermissionGuard {
|
|
|
76
76
|
throw new _permissionexception.InsufficientPermissionsException(result.missingPermissions, result.operator);
|
|
77
77
|
}
|
|
78
78
|
} else {
|
|
79
|
-
|
|
80
|
-
if (operator === 'or') {
|
|
81
|
-
hasRequired = requiredPermissions.some((p)=>this.hasPermission(userPermissions, p));
|
|
82
|
-
if (!hasRequired) throw new _permissionexception.InsufficientPermissionsException(requiredPermissions, 'or');
|
|
83
|
-
} else {
|
|
84
|
-
hasRequired = requiredPermissions.every((p)=>this.hasPermission(userPermissions, p));
|
|
85
|
-
if (!hasRequired) {
|
|
86
|
-
const missing = requiredPermissions.filter((p)=>!this.hasPermission(userPermissions, p));
|
|
87
|
-
throw new _permissionexception.InsufficientPermissionsException(missing, 'and');
|
|
88
|
-
}
|
|
89
|
-
}
|
|
79
|
+
this.validateSimplePermissions(requiredPermissions, userPermissions, operator);
|
|
90
80
|
}
|
|
91
81
|
return true;
|
|
92
82
|
}
|
|
@@ -100,6 +90,18 @@ let PermissionGuard = class PermissionGuard {
|
|
|
100
90
|
operator: config.operator || 'and'
|
|
101
91
|
};
|
|
102
92
|
}
|
|
93
|
+
validateSimplePermissions(requiredPermissions, userPermissions, operator) {
|
|
94
|
+
if (operator === 'or') {
|
|
95
|
+
const hasAny = requiredPermissions.some((p)=>this.hasPermission(userPermissions, p));
|
|
96
|
+
if (!hasAny) throw new _permissionexception.InsufficientPermissionsException(requiredPermissions, 'or');
|
|
97
|
+
} else {
|
|
98
|
+
const hasAll = requiredPermissions.every((p)=>this.hasPermission(userPermissions, p));
|
|
99
|
+
if (!hasAll) {
|
|
100
|
+
const missing = requiredPermissions.filter((p)=>!this.hasPermission(userPermissions, p));
|
|
101
|
+
throw new _permissionexception.InsufficientPermissionsException(missing, 'and');
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
103
105
|
isNestedCondition(config) {
|
|
104
106
|
if (Array.isArray(config)) return false;
|
|
105
107
|
return 'children' in config && Array.isArray(config.children) && config.children.length > 0;
|
|
@@ -156,15 +158,14 @@ let PermissionGuard = class PermissionGuard {
|
|
|
156
158
|
}
|
|
157
159
|
async getUserPermissions(user) {
|
|
158
160
|
if (!this.cache) throw new _permissionexception.PermissionSystemUnavailableException();
|
|
159
|
-
|
|
161
|
+
const cacheKey = this.buildPermissionCacheKey(user);
|
|
162
|
+
return await this.cache.get(cacheKey) || [];
|
|
163
|
+
}
|
|
164
|
+
buildPermissionCacheKey(user) {
|
|
160
165
|
if (this.config.enableCompanyFeature && user.companyId) {
|
|
161
|
-
|
|
162
|
-
cacheKey = format.replace('{userId}', user.id).replace('{companyId}', user.companyId).replace('{branchId}', user.branchId || 'null');
|
|
163
|
-
} else {
|
|
164
|
-
const format = this.config.userPermissionKeyFormat || `${_constants.PERMISSIONS_CACHE_PREFIX}:user:{userId}`;
|
|
165
|
-
cacheKey = format.replace('{userId}', user.id);
|
|
166
|
+
return (this.config.companyPermissionKeyFormat || `${_constants.PERMISSIONS_CACHE_PREFIX}:company:{companyId}:branch:{branchId}:user:{userId}`).replace('{userId}', user.id).replace('{companyId}', user.companyId).replace('{branchId}', user.branchId || 'null');
|
|
166
167
|
}
|
|
167
|
-
return
|
|
168
|
+
return (this.config.userPermissionKeyFormat || `${_constants.PERMISSIONS_CACHE_PREFIX}:user:{userId}`).replace('{userId}', user.id);
|
|
168
169
|
}
|
|
169
170
|
hasPermission(userPermissions, requiredPermission) {
|
|
170
171
|
if (userPermissions.includes(requiredPermission)) return true;
|
|
@@ -7,9 +7,6 @@ _export_star(require("./idempotency.interceptor"), exports);
|
|
|
7
7
|
_export_star(require("./query-performance.interceptor"), exports);
|
|
8
8
|
_export_star(require("./response-meta.interceptor"), exports);
|
|
9
9
|
_export_star(require("./set-user-field-on-body.interceptor"), exports);
|
|
10
|
-
_export_star(require("./set-create-by-on-body.interceptor"), exports);
|
|
11
|
-
_export_star(require("./set-delete-by-on-body.interceptor"), exports);
|
|
12
|
-
_export_star(require("./set-update-by-on-body.interceptor"), exports);
|
|
13
10
|
_export_star(require("./slug.interceptor"), exports);
|
|
14
11
|
function _export_star(from, to) {
|
|
15
12
|
Object.keys(from).forEach(function(k) {
|
|
@@ -2,9 +2,23 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", {
|
|
3
3
|
value: true
|
|
4
4
|
});
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
get SetCreatedByOnBody () {
|
|
13
|
+
return SetCreatedByOnBody;
|
|
14
|
+
},
|
|
15
|
+
get SetDeletedByOnBody () {
|
|
16
|
+
return SetDeletedByOnBody;
|
|
17
|
+
},
|
|
18
|
+
get SetUpdateByOnBody () {
|
|
19
|
+
return SetUpdateByOnBody;
|
|
20
|
+
},
|
|
21
|
+
get createSetUserFieldInterceptor () {
|
|
8
22
|
return createSetUserFieldInterceptor;
|
|
9
23
|
}
|
|
10
24
|
});
|
|
@@ -41,3 +55,6 @@ function createSetUserFieldInterceptor(fieldName) {
|
|
|
41
55
|
], SetUserFieldOnBody);
|
|
42
56
|
return SetUserFieldOnBody;
|
|
43
57
|
}
|
|
58
|
+
const SetCreatedByOnBody = createSetUserFieldInterceptor('createdById');
|
|
59
|
+
const SetUpdateByOnBody = createSetUserFieldInterceptor('updatedById');
|
|
60
|
+
const SetDeletedByOnBody = createSetUserFieldInterceptor('deletedById');
|