@flusys/nestjs-shared 1.1.0-beta → 1.2.0-rc.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/README.md +146 -1330
- package/cjs/classes/api-controller.class.js +325 -49
- package/cjs/classes/api-service.class.js +271 -149
- package/cjs/classes/handle-custome-db.js +37 -0
- package/cjs/classes/index.js +2 -2
- package/cjs/classes/winston.logger.class.js +103 -70
- package/cjs/constants/index.js +15 -4
- package/cjs/constants/message-keys.js +68 -0
- package/cjs/constants/permissions.js +287 -0
- package/cjs/decorators/api-response.decorator.js +2 -3
- package/cjs/decorators/index.js +1 -0
- package/cjs/decorators/log-action.decorator.js +149 -0
- package/cjs/decorators/require-permission.decorator.js +5 -5
- package/cjs/dtos/delete.dto.js +10 -0
- package/cjs/dtos/filter-and-pagination.dto.js +24 -34
- package/cjs/dtos/get-by-ids.dto.js +65 -0
- package/cjs/dtos/identity-response.dto.js +4 -8
- package/cjs/dtos/index.js +1 -0
- package/cjs/dtos/pagination.dto.js +4 -8
- package/cjs/dtos/response-payload.dto.js +68 -112
- package/cjs/entities/identity.js +12 -6
- package/cjs/entities/index.js +1 -0
- package/cjs/entities/raw-type.js +4 -0
- package/cjs/entities/user-root.js +15 -15
- package/cjs/enums/index.js +20 -0
- package/cjs/enums/notification-type.enum.js +17 -0
- package/cjs/enums/participant-status.enum.js +17 -0
- package/cjs/enums/recurrence-type.enum.js +18 -0
- package/cjs/exceptions/base-app.exception.js +151 -0
- package/cjs/exceptions/index.js +1 -0
- package/cjs/exceptions/permission.exception.js +13 -9
- package/cjs/filters/global-exception.filter.js +279 -0
- package/cjs/filters/index.js +18 -0
- package/cjs/guards/jwt-auth.guard.js +4 -1
- package/cjs/guards/permission.guard.js +88 -148
- package/cjs/index.js +2 -0
- package/cjs/interceptors/idempotency.interceptor.js +1 -1
- package/cjs/interceptors/index.js +1 -4
- package/cjs/interceptors/set-user-field-on-body.interceptor.js +60 -0
- package/cjs/interceptors/slug.interceptor.js +30 -9
- package/cjs/interfaces/datasource.interface.js +4 -0
- package/cjs/interfaces/event-manager-adapter.interface.js +11 -0
- package/cjs/interfaces/index.js +4 -2
- package/cjs/interfaces/module-config.interface.js +4 -0
- package/cjs/interfaces/notification-adapter.interface.js +11 -0
- package/cjs/interfaces/permission.interface.js +1 -1
- package/cjs/middlewares/logger.middleware.js +133 -115
- package/cjs/modules/cache/cache.module.js +3 -3
- package/cjs/modules/datasource/index.js +0 -1
- package/cjs/modules/datasource/multi-tenant-datasource.service.js +60 -183
- package/cjs/modules/utils/utils.service.js +27 -206
- package/cjs/utils/date-time.util.js +94 -0
- package/cjs/utils/html-sanitizer.util.js +64 -0
- package/cjs/utils/index.js +5 -1
- package/cjs/utils/query-helpers.util.js +60 -0
- package/cjs/utils/request.util.js +96 -0
- package/cjs/utils/string.util.js +63 -0
- package/classes/api-controller.class.d.ts +16 -8
- package/classes/api-service.class.d.ts +30 -25
- package/classes/handle-custome-db.d.ts +3 -0
- package/classes/index.d.ts +2 -2
- package/classes/winston.logger.class.d.ts +1 -0
- package/constants/index.d.ts +2 -1
- package/constants/message-keys.d.ts +45 -0
- package/constants/permissions.d.ts +306 -0
- package/decorators/api-response.decorator.d.ts +1 -1
- package/decorators/current-user.decorator.d.ts +1 -1
- package/decorators/index.d.ts +1 -0
- package/decorators/log-action.decorator.d.ts +8 -0
- package/decorators/require-permission.decorator.d.ts +2 -2
- package/dtos/delete.dto.d.ts +1 -0
- package/dtos/filter-and-pagination.dto.d.ts +0 -2
- package/dtos/get-by-ids.dto.d.ts +4 -0
- package/dtos/index.d.ts +1 -0
- package/dtos/response-payload.dto.d.ts +8 -20
- package/entities/index.d.ts +1 -0
- package/entities/raw-type.d.ts +1 -0
- package/enums/index.d.ts +3 -0
- package/enums/notification-type.enum.d.ts +6 -0
- package/enums/participant-status.enum.d.ts +6 -0
- package/enums/recurrence-type.enum.d.ts +7 -0
- package/exceptions/base-app.exception.d.ts +41 -0
- package/exceptions/index.d.ts +1 -0
- package/exceptions/permission.exception.d.ts +2 -2
- package/fesm/classes/api-controller.class.js +326 -50
- package/fesm/classes/api-service.class.js +274 -152
- package/fesm/classes/handle-custome-db.js +19 -0
- package/fesm/classes/index.js +3 -2
- package/fesm/classes/winston.logger.class.js +100 -68
- package/fesm/constants/index.js +4 -1
- package/fesm/constants/message-keys.js +49 -0
- package/fesm/constants/permissions.js +200 -0
- package/fesm/decorators/api-response.decorator.js +3 -21
- package/fesm/decorators/index.js +1 -0
- package/fesm/decorators/log-action.decorator.js +139 -0
- package/fesm/decorators/require-permission.decorator.js +17 -65
- package/fesm/dtos/delete.dto.js +12 -2
- package/fesm/dtos/filter-and-pagination.dto.js +26 -47
- package/fesm/dtos/get-by-ids.dto.js +55 -0
- package/fesm/dtos/identity-response.dto.js +4 -8
- package/fesm/dtos/index.js +1 -0
- package/fesm/dtos/pagination.dto.js +4 -8
- package/fesm/dtos/response-payload.dto.js +68 -103
- package/fesm/entities/identity.js +12 -6
- package/fesm/entities/index.js +1 -0
- package/fesm/entities/raw-type.js +1 -0
- package/fesm/entities/user-root.js +15 -15
- package/fesm/enums/index.js +3 -0
- package/fesm/enums/notification-type.enum.js +7 -0
- package/fesm/enums/participant-status.enum.js +7 -0
- package/fesm/enums/recurrence-type.enum.js +8 -0
- package/fesm/exceptions/base-app.exception.js +115 -0
- package/fesm/exceptions/index.js +1 -0
- package/fesm/exceptions/permission.exception.js +16 -18
- package/fesm/filters/global-exception.filter.js +269 -0
- package/fesm/filters/index.js +1 -0
- package/fesm/guards/jwt-auth.guard.js +5 -2
- package/fesm/guards/permission.guard.js +90 -150
- package/fesm/index.js +2 -0
- package/fesm/interceptors/idempotency.interceptor.js +2 -2
- package/fesm/interceptors/index.js +1 -4
- package/fesm/interceptors/set-user-field-on-body.interceptor.js +39 -0
- package/fesm/interceptors/slug.interceptor.js +31 -10
- package/fesm/interfaces/datasource.interface.js +1 -0
- package/fesm/interfaces/event-manager-adapter.interface.js +1 -0
- package/fesm/interfaces/index.js +4 -2
- package/fesm/interfaces/module-config.interface.js +5 -0
- package/fesm/interfaces/notification-adapter.interface.js +1 -0
- package/fesm/interfaces/permission.interface.js +1 -3
- package/fesm/middlewares/logger.middleware.js +133 -109
- package/fesm/modules/cache/cache.module.js +2 -2
- package/fesm/modules/datasource/index.js +0 -1
- package/fesm/modules/datasource/multi-tenant-datasource.service.js +61 -184
- package/fesm/modules/utils/utils.service.js +27 -206
- package/fesm/utils/date-time.util.js +70 -0
- package/fesm/utils/html-sanitizer.util.js +69 -0
- package/fesm/utils/index.js +5 -1
- package/fesm/utils/query-helpers.util.js +85 -0
- package/fesm/utils/request.util.js +81 -0
- package/fesm/utils/string.util.js +71 -0
- package/filters/global-exception.filter.d.ts +9 -0
- package/filters/index.d.ts +1 -0
- package/guards/permission.guard.d.ts +4 -6
- package/index.d.ts +2 -0
- package/interceptors/idempotency.interceptor.d.ts +1 -1
- package/interceptors/index.d.ts +1 -4
- package/interceptors/set-user-field-on-body.interceptor.d.ts +5 -0
- package/interceptors/slug.interceptor.d.ts +2 -1
- package/interfaces/api.interface.d.ts +4 -2
- package/interfaces/datasource.interface.d.ts +5 -0
- package/interfaces/event-manager-adapter.interface.d.ts +43 -0
- package/interfaces/identity.interface.d.ts +4 -4
- package/interfaces/index.d.ts +4 -2
- package/interfaces/logged-user-info.interface.d.ts +0 -2
- package/interfaces/module-config.interface.d.ts +6 -0
- package/interfaces/notification-adapter.interface.d.ts +21 -0
- package/interfaces/permission.interface.d.ts +13 -9
- package/middlewares/logger.middleware.d.ts +2 -2
- package/modules/datasource/index.d.ts +0 -1
- package/modules/datasource/multi-tenant-datasource.service.d.ts +5 -16
- package/modules/utils/utils.service.d.ts +3 -14
- package/package.json +21 -14
- package/utils/date-time.util.d.ts +8 -0
- package/utils/html-sanitizer.util.d.ts +2 -0
- package/utils/index.d.ts +5 -1
- package/utils/query-helpers.util.d.ts +16 -0
- package/utils/request.util.d.ts +6 -0
- package/utils/string.util.d.ts +2 -0
- package/cjs/classes/request-scoped-api.service.js +0 -61
- package/cjs/classes/winston-logger-adapter.class.js +0 -121
- package/cjs/interceptors/query-performance.interceptor.js +0 -66
- package/cjs/interceptors/set-create-by-on-body.interceptor.js +0 -40
- package/cjs/interceptors/set-delete-by-on-body.interceptor.js +0 -40
- package/cjs/interceptors/set-update-by-on-body.interceptor.js +0 -40
- package/cjs/interfaces/base-query.interface.js +0 -6
- package/cjs/interfaces/logger.interface.js +0 -7
- package/cjs/modules/datasource/datasource.module.js +0 -120
- package/cjs/utils/error-handler.util.js +0 -67
- package/classes/request-scoped-api.service.d.ts +0 -13
- package/classes/winston-logger-adapter.class.d.ts +0 -20
- package/fesm/classes/request-scoped-api.service.js +0 -51
- package/fesm/classes/winston-logger-adapter.class.js +0 -124
- package/fesm/interceptors/query-performance.interceptor.js +0 -56
- package/fesm/interceptors/set-create-by-on-body.interceptor.js +0 -30
- package/fesm/interceptors/set-delete-by-on-body.interceptor.js +0 -30
- package/fesm/interceptors/set-update-by-on-body.interceptor.js +0 -30
- package/fesm/interfaces/base-query.interface.js +0 -3
- package/fesm/interfaces/logger.interface.js +0 -4
- package/fesm/modules/datasource/datasource.module.js +0 -110
- package/fesm/utils/error-handler.util.js +0 -59
- package/interceptors/query-performance.interceptor.d.ts +0 -8
- package/interceptors/set-create-by-on-body.interceptor.d.ts +0 -5
- package/interceptors/set-delete-by-on-body.interceptor.d.ts +0 -5
- package/interceptors/set-update-by-on-body.interceptor.d.ts +0 -5
- package/interfaces/base-query.interface.d.ts +0 -7
- package/interfaces/logger.interface.d.ts +0 -7
- package/modules/datasource/datasource.module.d.ts +0 -18
- package/utils/error-handler.util.d.ts +0 -24
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "GlobalExceptionFilter", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return GlobalExceptionFilter;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _common = require("@nestjs/common");
|
|
12
|
+
const _typeorm = require("typeorm");
|
|
13
|
+
const _messagekeys = require("../constants/message-keys");
|
|
14
|
+
const _baseappexception = require("../exceptions/base-app.exception");
|
|
15
|
+
const _loggermiddleware = require("../middlewares/logger.middleware");
|
|
16
|
+
function _define_property(obj, key, value) {
|
|
17
|
+
if (key in obj) {
|
|
18
|
+
Object.defineProperty(obj, key, {
|
|
19
|
+
value: value,
|
|
20
|
+
enumerable: true,
|
|
21
|
+
configurable: true,
|
|
22
|
+
writable: true
|
|
23
|
+
});
|
|
24
|
+
} else {
|
|
25
|
+
obj[key] = value;
|
|
26
|
+
}
|
|
27
|
+
return obj;
|
|
28
|
+
}
|
|
29
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
30
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
31
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
32
|
+
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;
|
|
33
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
34
|
+
}
|
|
35
|
+
let GlobalExceptionFilter = class GlobalExceptionFilter {
|
|
36
|
+
catch(exception, host) {
|
|
37
|
+
const ctx = host.switchToHttp();
|
|
38
|
+
const request = ctx.getRequest();
|
|
39
|
+
const response = ctx.getResponse();
|
|
40
|
+
const responseTime = Date.now() - (request._startTime || Date.now());
|
|
41
|
+
const requestId = (0, _loggermiddleware.getRequestId)() || request.headers['x-request-id'] || 'no-request-id';
|
|
42
|
+
const { statusCode, errorResponse } = this.resolveException(exception, requestId, responseTime);
|
|
43
|
+
const logContext = {
|
|
44
|
+
requestId,
|
|
45
|
+
userId: (0, _loggermiddleware.getUserId)(),
|
|
46
|
+
tenantId: (0, _loggermiddleware.getTenantId)(),
|
|
47
|
+
companyId: (0, _loggermiddleware.getCompanyId)(),
|
|
48
|
+
method: request.method,
|
|
49
|
+
url: request.originalUrl,
|
|
50
|
+
path: request.path,
|
|
51
|
+
statusCode,
|
|
52
|
+
duration: `${responseTime}ms`,
|
|
53
|
+
messageKey: errorResponse.messageKey
|
|
54
|
+
};
|
|
55
|
+
const logMessage = `Exception caught "HTTP/1.1" "${request.method}" "${request.originalUrl}" - ${statusCode} "${errorResponse.messageKey}" ${responseTime}ms | ${errorResponse.message}`;
|
|
56
|
+
if (statusCode >= 500) {
|
|
57
|
+
this.logger.error(logMessage, exception instanceof Error ? exception.stack : undefined, logContext);
|
|
58
|
+
} else if (statusCode >= 400) {
|
|
59
|
+
this.logger.warn(logMessage, logContext);
|
|
60
|
+
}
|
|
61
|
+
response.status(statusCode).json(errorResponse);
|
|
62
|
+
}
|
|
63
|
+
resolveException(exception, requestId, responseTime) {
|
|
64
|
+
const meta = {
|
|
65
|
+
requestId,
|
|
66
|
+
timestamp: new Date().toISOString(),
|
|
67
|
+
responseTime
|
|
68
|
+
};
|
|
69
|
+
if (exception instanceof _baseappexception.BaseAppException) {
|
|
70
|
+
return {
|
|
71
|
+
statusCode: exception.getStatus(),
|
|
72
|
+
errorResponse: {
|
|
73
|
+
success: false,
|
|
74
|
+
message: exception.message,
|
|
75
|
+
messageKey: exception.messageKey,
|
|
76
|
+
messageVariables: exception.messageVariables,
|
|
77
|
+
errors: exception.errors,
|
|
78
|
+
_meta: meta
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
if (exception instanceof _common.HttpException) {
|
|
83
|
+
const resolved = this.resolveHttpException(exception);
|
|
84
|
+
return {
|
|
85
|
+
statusCode: resolved.statusCode,
|
|
86
|
+
errorResponse: {
|
|
87
|
+
success: false,
|
|
88
|
+
message: resolved.message,
|
|
89
|
+
messageKey: resolved.messageKey,
|
|
90
|
+
messageVariables: resolved.messageVariables,
|
|
91
|
+
errors: resolved.errors,
|
|
92
|
+
_meta: meta
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
if (exception instanceof _typeorm.QueryFailedError) {
|
|
97
|
+
const resolved = this.resolveQueryFailedError(exception);
|
|
98
|
+
if (resolved) {
|
|
99
|
+
return {
|
|
100
|
+
statusCode: resolved.getStatus(),
|
|
101
|
+
errorResponse: {
|
|
102
|
+
success: false,
|
|
103
|
+
message: resolved.message,
|
|
104
|
+
messageKey: resolved.messageKey,
|
|
105
|
+
messageVariables: resolved.messageVariables,
|
|
106
|
+
_meta: meta
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return {
|
|
112
|
+
statusCode: _common.HttpStatus.INTERNAL_SERVER_ERROR,
|
|
113
|
+
errorResponse: {
|
|
114
|
+
success: false,
|
|
115
|
+
message: 'Internal server error',
|
|
116
|
+
messageKey: _messagekeys.ERROR_MESSAGES.INTERNAL,
|
|
117
|
+
_meta: meta
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
resolveHttpException(exception) {
|
|
122
|
+
const statusCode = exception.getStatus();
|
|
123
|
+
const response = exception.getResponse();
|
|
124
|
+
if (typeof response === 'string') {
|
|
125
|
+
return {
|
|
126
|
+
statusCode,
|
|
127
|
+
message: response,
|
|
128
|
+
messageKey: _messagekeys.ERROR_MESSAGES.HTTP
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
if (typeof response === 'object' && response !== null) {
|
|
132
|
+
const obj = response;
|
|
133
|
+
if (Array.isArray(obj.message)) {
|
|
134
|
+
const errors = obj.message.map((msg)=>{
|
|
135
|
+
const [field, ...rest] = msg.split(' ');
|
|
136
|
+
return {
|
|
137
|
+
field: field || 'unknown',
|
|
138
|
+
message: rest.join(' ') || msg
|
|
139
|
+
};
|
|
140
|
+
});
|
|
141
|
+
return {
|
|
142
|
+
statusCode,
|
|
143
|
+
message: 'Validation failed',
|
|
144
|
+
messageKey: _messagekeys.ERROR_MESSAGES.VALIDATION,
|
|
145
|
+
errors
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
return {
|
|
149
|
+
statusCode,
|
|
150
|
+
message: String(obj.message || 'Unknown error'),
|
|
151
|
+
messageKey: String(obj.messageKey || _messagekeys.ERROR_MESSAGES.HTTP),
|
|
152
|
+
messageVariables: obj.messageVariables,
|
|
153
|
+
errors: obj.errors
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
return {
|
|
157
|
+
statusCode,
|
|
158
|
+
message: 'Unknown error',
|
|
159
|
+
messageKey: _messagekeys.ERROR_MESSAGES.UNKNOWN
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
resolveQueryFailedError(exception) {
|
|
163
|
+
const dbError = exception;
|
|
164
|
+
const code = dbError.driverError?.code ?? dbError.code;
|
|
165
|
+
const number = dbError.driverError?.number ?? dbError.number;
|
|
166
|
+
const errno = dbError.driverError?.errno ?? dbError.errno;
|
|
167
|
+
const sqlMessage = dbError.driverError?.sqlMessage ?? '';
|
|
168
|
+
const detail = dbError.driverError?.detail ?? dbError.detail ?? '';
|
|
169
|
+
const table = dbError.driverError?.table ?? dbError.table ?? '';
|
|
170
|
+
const column = dbError.driverError?.column ?? dbError.column;
|
|
171
|
+
const pgField = detail.match(/Key \(([^)]+)\)/)?.[1] ?? column;
|
|
172
|
+
// DUPLICATE / UNIQUE VIOLATION
|
|
173
|
+
// PG: 23505 | MSSQL: 2627 (constraint), 2601 (index) | MySQL: ER_DUP_ENTRY / errno 1062
|
|
174
|
+
if (code === '23505' || number === 2627 || number === 2601 || code === 'ER_DUP_ENTRY' || errno === 1062) {
|
|
175
|
+
const mysqlTable = sqlMessage.match(/for key '([^'.]+)\./)?.[1];
|
|
176
|
+
const mysqlIndex = sqlMessage.match(/for key '(?:[^.]+\.)?([^']+)'/)?.[1];
|
|
177
|
+
const resolvedTable = table || mysqlTable || 'record';
|
|
178
|
+
const resolvedField = pgField ? this.toHumanReadable(pgField) : mysqlIndex ? this.toHumanReadable(mysqlIndex) : undefined;
|
|
179
|
+
return new _baseappexception.ConflictException(this.toHumanReadable(resolvedTable), resolvedField);
|
|
180
|
+
}
|
|
181
|
+
// FOREIGN KEY VIOLATION
|
|
182
|
+
// PG: 23503 | MSSQL: 547 | MySQL: ER_NO_REFERENCED_ROW_2/1452 (insert), ER_ROW_IS_REFERENCED_2/1451 (delete)
|
|
183
|
+
if (code === '23503' || number === 547 || code === 'ER_NO_REFERENCED_ROW_2' || code === 'ER_ROW_IS_REFERENCED_2' || errno === 1452 || errno === 1451) {
|
|
184
|
+
const mysqlColumn = sqlMessage.match(/FOREIGN KEY \(`([^`]+)`\)/)?.[1];
|
|
185
|
+
const raw = pgField ?? mysqlColumn;
|
|
186
|
+
const humanField = raw ? this.toHumanReadable(raw) : undefined;
|
|
187
|
+
return new _baseappexception.BaseAppException({
|
|
188
|
+
message: humanField ? `Invalid reference for '${humanField}'` : 'Invalid reference',
|
|
189
|
+
messageKey: _messagekeys.ERROR_MESSAGES.DB_FOREIGN_KEY,
|
|
190
|
+
messageVariables: humanField ? {
|
|
191
|
+
field: humanField
|
|
192
|
+
} : undefined,
|
|
193
|
+
status: _common.HttpStatus.BAD_REQUEST
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
// NOT NULL VIOLATION
|
|
197
|
+
// PG: 23502 | MSSQL: 515 | MySQL: ER_BAD_NULL_ERROR / errno 1048
|
|
198
|
+
if (code === '23502' || number === 515 || code === 'ER_BAD_NULL_ERROR' || errno === 1048) {
|
|
199
|
+
const mysqlColumn = sqlMessage.match(/Column '([^']+)' cannot be null/)?.[1];
|
|
200
|
+
const humanField = this.toHumanReadable(column ?? mysqlColumn ?? 'field');
|
|
201
|
+
return new _baseappexception.BaseAppException({
|
|
202
|
+
message: `Required field '${humanField}' cannot be null`,
|
|
203
|
+
messageKey: _messagekeys.ERROR_MESSAGES.DB_NOT_NULL,
|
|
204
|
+
messageVariables: {
|
|
205
|
+
field: humanField
|
|
206
|
+
},
|
|
207
|
+
status: _common.HttpStatus.BAD_REQUEST
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
// INVALID INPUT SYNTAX — PostgreSQL only (MySQL silently coerces types)
|
|
211
|
+
if (code === '22P02') {
|
|
212
|
+
const typeMatch = exception.message.match(/invalid input syntax for(?:\s+type)?\s+(\w+)/i);
|
|
213
|
+
const type = typeMatch?.[1] ?? 'value';
|
|
214
|
+
const humanField = column ? this.toHumanReadable(column) : undefined;
|
|
215
|
+
return new _baseappexception.BaseAppException({
|
|
216
|
+
message: humanField ? `Invalid ${type} value for '${humanField}'` : `Invalid ${type} value`,
|
|
217
|
+
messageKey: _messagekeys.ERROR_MESSAGES.DB_INVALID_INPUT,
|
|
218
|
+
messageVariables: {
|
|
219
|
+
type,
|
|
220
|
+
...humanField !== undefined && {
|
|
221
|
+
field: humanField
|
|
222
|
+
}
|
|
223
|
+
},
|
|
224
|
+
status: _common.HttpStatus.BAD_REQUEST
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
// VALUE TOO LONG
|
|
228
|
+
// PG: 22001 | MySQL: ER_DATA_TOO_LONG / errno 1406
|
|
229
|
+
if (code === '22001' || code === 'ER_DATA_TOO_LONG' || errno === 1406) {
|
|
230
|
+
const mysqlColumn = sqlMessage.match(/Data too long for column '([^']+)'/)?.[1];
|
|
231
|
+
const resolvedColumn = column ?? mysqlColumn;
|
|
232
|
+
const humanField = resolvedColumn ? this.toHumanReadable(resolvedColumn) : undefined;
|
|
233
|
+
return new _baseappexception.BaseAppException({
|
|
234
|
+
message: humanField ? `Value too long for '${humanField}'` : 'Value exceeds maximum length',
|
|
235
|
+
messageKey: _messagekeys.ERROR_MESSAGES.DB_VALUE_TOO_LONG,
|
|
236
|
+
messageVariables: humanField !== undefined ? {
|
|
237
|
+
field: humanField
|
|
238
|
+
} : undefined,
|
|
239
|
+
status: _common.HttpStatus.BAD_REQUEST
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
// CHECK CONSTRAINT VIOLATION
|
|
243
|
+
// PG: 23514 | MySQL 8.0+: ER_CHECK_CONSTRAINT_VIOLATED / errno 3819
|
|
244
|
+
if (code === '23514' || code === 'ER_CHECK_CONSTRAINT_VIOLATED' || errno === 3819) {
|
|
245
|
+
const constraint = dbError.driverError?.constraint ?? dbError.constraint;
|
|
246
|
+
const humanTable = this.toHumanReadable(table || 'record');
|
|
247
|
+
return new _baseappexception.BaseAppException({
|
|
248
|
+
message: `${humanTable} violates a validation rule`,
|
|
249
|
+
messageKey: _messagekeys.ERROR_MESSAGES.DB_CHECK_CONSTRAINT,
|
|
250
|
+
messageVariables: {
|
|
251
|
+
entity: humanTable,
|
|
252
|
+
...constraint !== undefined && {
|
|
253
|
+
constraint
|
|
254
|
+
}
|
|
255
|
+
},
|
|
256
|
+
status: _common.HttpStatus.BAD_REQUEST
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
// DEADLOCK
|
|
260
|
+
// PG: 40P01 | MSSQL: 1205 | MySQL: ER_LOCK_DEADLOCK / errno 1213
|
|
261
|
+
if (code === '40P01' || number === 1205 || code === 'ER_LOCK_DEADLOCK' || errno === 1213) {
|
|
262
|
+
return new _baseappexception.BaseAppException({
|
|
263
|
+
message: 'The request could not be completed due to a conflict, please try again',
|
|
264
|
+
messageKey: _messagekeys.ERROR_MESSAGES.DB_DEADLOCK,
|
|
265
|
+
status: _common.HttpStatus.SERVICE_UNAVAILABLE
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
return null;
|
|
269
|
+
}
|
|
270
|
+
toHumanReadable(dbName) {
|
|
271
|
+
return dbName.split(', ').map((part)=>part.split('_').map((word)=>word.toLowerCase() === 'id' ? 'ID' : word.charAt(0).toUpperCase() + word.slice(1)).join(' ')).join(', ');
|
|
272
|
+
}
|
|
273
|
+
constructor(){
|
|
274
|
+
_define_property(this, "logger", new _common.Logger('ExceptionFilter'));
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
GlobalExceptionFilter = _ts_decorate([
|
|
278
|
+
(0, _common.Catch)()
|
|
279
|
+
], GlobalExceptionFilter);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
_export_star(require("./global-exception.filter"), exports);
|
|
6
|
+
function _export_star(from, to) {
|
|
7
|
+
Object.keys(from).forEach(function(k) {
|
|
8
|
+
if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
|
|
9
|
+
Object.defineProperty(to, k, {
|
|
10
|
+
enumerable: true,
|
|
11
|
+
get: function() {
|
|
12
|
+
return from[k];
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
return from;
|
|
18
|
+
}
|
|
@@ -53,7 +53,10 @@ let JwtAuthGuard = class JwtAuthGuard extends (0, _passport.AuthGuard)('jwt') {
|
|
|
53
53
|
}
|
|
54
54
|
handleRequest(err, user) {
|
|
55
55
|
if (err || !user) {
|
|
56
|
-
throw err || new _common.UnauthorizedException(
|
|
56
|
+
throw err || new _common.UnauthorizedException({
|
|
57
|
+
message: 'Invalid or expired token',
|
|
58
|
+
messageKey: _constants.AUTH_MESSAGES.TOKEN_INVALID
|
|
59
|
+
});
|
|
57
60
|
}
|
|
58
61
|
return user;
|
|
59
62
|
}
|
|
@@ -11,10 +11,8 @@ Object.defineProperty(exports, "PermissionGuard", {
|
|
|
11
11
|
const _common = require("@nestjs/common");
|
|
12
12
|
const _core = require("@nestjs/core");
|
|
13
13
|
const _hybridcacheclass = require("../classes/hybrid-cache.class");
|
|
14
|
-
const _winstonloggeradapterclass = require("../classes/winston-logger-adapter.class");
|
|
15
14
|
const _constants = require("../constants");
|
|
16
15
|
const _permissionexception = require("../exceptions/permission.exception");
|
|
17
|
-
const _loggerinterface = require("../interfaces/logger.interface");
|
|
18
16
|
const _permissioninterface = require("../interfaces/permission.interface");
|
|
19
17
|
function _define_property(obj, key, value) {
|
|
20
18
|
if (key in obj) {
|
|
@@ -45,206 +43,151 @@ function _ts_param(paramIndex, decorator) {
|
|
|
45
43
|
}
|
|
46
44
|
let PermissionGuard = class PermissionGuard {
|
|
47
45
|
async canActivate(context) {
|
|
48
|
-
// Check if route is marked as public
|
|
49
46
|
const isPublic = this.reflector.getAllAndOverride(_constants.IS_PUBLIC_KEY, [
|
|
50
47
|
context.getHandler(),
|
|
51
48
|
context.getClass()
|
|
52
49
|
]);
|
|
53
50
|
if (isPublic) return true;
|
|
54
|
-
// Get required permissions from decorator
|
|
55
51
|
const permissionConfig = this.reflector.getAllAndOverride(_constants.PERMISSIONS_KEY, [
|
|
56
52
|
context.getHandler(),
|
|
57
53
|
context.getClass()
|
|
58
54
|
]);
|
|
59
|
-
|
|
60
|
-
if (!permissionConfig) {
|
|
61
|
-
return true;
|
|
62
|
-
}
|
|
63
|
-
// Normalize permission config (support old format: string[])
|
|
64
|
-
const { permissions: requiredPermissions, operator } = this.normalizePermissionConfig(permissionConfig);
|
|
65
|
-
// If no permissions required, allow access
|
|
66
|
-
if (!requiredPermissions || requiredPermissions.length === 0) {
|
|
67
|
-
return true;
|
|
68
|
-
}
|
|
55
|
+
if (!permissionConfig) return true;
|
|
69
56
|
const request = context.switchToHttp().getRequest();
|
|
70
57
|
const user = request.user;
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
75
|
-
// Cache is required for permission checks - fail securely if unavailable
|
|
58
|
+
if (!user) throw new _common.UnauthorizedException({
|
|
59
|
+
message: 'Authentication required',
|
|
60
|
+
messageKey: _constants.AUTH_MESSAGES.TOKEN_REQUIRED
|
|
61
|
+
});
|
|
76
62
|
if (!this.cache) {
|
|
77
|
-
// Log error (in production, this should be monitored)
|
|
78
|
-
this.logger.error(`Cache not available - permission system unavailable (userId: ${user.id})`, undefined, 'PermissionGuard');
|
|
79
|
-
// Fail securely - deny access rather than allowing without permission check
|
|
80
63
|
throw new _permissionexception.PermissionSystemUnavailableException();
|
|
81
64
|
}
|
|
82
|
-
// Get user's permissions from cache
|
|
83
65
|
const userPermissions = await this.getUserPermissions(user);
|
|
84
|
-
// If no permissions found in cache, deny access
|
|
85
66
|
if (!userPermissions || userPermissions.length === 0) {
|
|
86
|
-
this.logger.warn(`No permissions found for user (userId: ${user.id})`, 'PermissionGuard');
|
|
87
67
|
throw new _permissionexception.NoPermissionsFoundException();
|
|
88
68
|
}
|
|
89
|
-
|
|
90
|
-
if (
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
this.logger.warn(`Permission check failed (userId: ${user.id}, missing: ${result.missingPermissions.join(', ')})`, 'PermissionGuard');
|
|
95
|
-
throw new _permissionexception.InsufficientPermissionsException(result.missingPermissions, result.operator);
|
|
96
|
-
}
|
|
97
|
-
} else {
|
|
98
|
-
// Simple permission check (backward compatible)
|
|
99
|
-
let hasRequiredPermissions;
|
|
100
|
-
if (operator === 'or') {
|
|
101
|
-
// OR: User must have at least ONE permission
|
|
102
|
-
hasRequiredPermissions = requiredPermissions.some((permission)=>this.hasPermission(userPermissions, permission));
|
|
103
|
-
if (!hasRequiredPermissions) {
|
|
104
|
-
throw new _permissionexception.InsufficientPermissionsException(requiredPermissions, 'or');
|
|
105
|
-
}
|
|
106
|
-
} else {
|
|
107
|
-
// AND (default): User must have ALL permissions
|
|
108
|
-
hasRequiredPermissions = requiredPermissions.every((permission)=>this.hasPermission(userPermissions, permission));
|
|
109
|
-
if (!hasRequiredPermissions) {
|
|
110
|
-
const missing = requiredPermissions.filter((permission)=>!this.hasPermission(userPermissions, permission));
|
|
111
|
-
throw new _permissionexception.InsufficientPermissionsException(missing, 'and');
|
|
112
|
-
}
|
|
113
|
-
}
|
|
69
|
+
const logicNode = this.normalizeToLogicNode(permissionConfig);
|
|
70
|
+
if (!logicNode) return true;
|
|
71
|
+
const result = this.evaluateLogicNode(logicNode, userPermissions);
|
|
72
|
+
if (!result.passed) {
|
|
73
|
+
throw new _permissionexception.InsufficientPermissionsException(result.missingPermissions, result.operator);
|
|
114
74
|
}
|
|
115
75
|
return true;
|
|
116
76
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
77
|
+
normalizeToLogicNode(config) {
|
|
78
|
+
// string - single permission
|
|
79
|
+
if (typeof config === 'string') {
|
|
80
|
+
return config ? {
|
|
81
|
+
type: 'action',
|
|
82
|
+
actionId: config
|
|
83
|
+
} : null;
|
|
84
|
+
}
|
|
85
|
+
// string[] - treat as AND of multiple permissions
|
|
121
86
|
if (Array.isArray(config)) {
|
|
87
|
+
if (config.length === 0) return null;
|
|
88
|
+
if (config.length === 1) return {
|
|
89
|
+
type: 'action',
|
|
90
|
+
actionId: config[0]
|
|
91
|
+
};
|
|
122
92
|
return {
|
|
123
|
-
|
|
124
|
-
operator: '
|
|
93
|
+
type: 'group',
|
|
94
|
+
operator: 'AND',
|
|
95
|
+
children: config.map((p)=>({
|
|
96
|
+
type: 'action',
|
|
97
|
+
actionId: p
|
|
98
|
+
}))
|
|
125
99
|
};
|
|
126
100
|
}
|
|
127
|
-
//
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
101
|
+
// SimplePermissionConfig - { permissions: string[], operator: 'AND'|'OR' }
|
|
102
|
+
if ('permissions' in config && Array.isArray(config.permissions)) {
|
|
103
|
+
const simple = config;
|
|
104
|
+
if (simple.permissions.length === 0) return null;
|
|
105
|
+
if (simple.permissions.length === 1) return {
|
|
106
|
+
type: 'action',
|
|
107
|
+
actionId: simple.permissions[0]
|
|
108
|
+
};
|
|
109
|
+
return {
|
|
110
|
+
type: 'group',
|
|
111
|
+
operator: simple.operator || 'AND',
|
|
112
|
+
children: simple.permissions.map((p)=>({
|
|
113
|
+
type: 'action',
|
|
114
|
+
actionId: p
|
|
115
|
+
}))
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
// ILogicNode
|
|
119
|
+
return config;
|
|
138
120
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
121
|
+
evaluateLogicNode(node, userPermissions) {
|
|
122
|
+
if (node.type === 'action') {
|
|
123
|
+
const passed = this.hasPermission(userPermissions, node.actionId);
|
|
124
|
+
return {
|
|
125
|
+
passed,
|
|
126
|
+
missingPermissions: passed ? [] : [
|
|
127
|
+
node.actionId
|
|
128
|
+
],
|
|
129
|
+
operator: 'AND'
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
// Group node
|
|
133
|
+
const { operator, children } = node;
|
|
134
|
+
// SECURITY: Fail-closed - deny access when no children configured
|
|
135
|
+
if (!children || children.length === 0) {
|
|
136
|
+
return {
|
|
137
|
+
passed: false,
|
|
138
|
+
missingPermissions: [],
|
|
139
|
+
operator
|
|
140
|
+
};
|
|
141
|
+
}
|
|
144
142
|
const results = [];
|
|
145
|
-
const failureDetails = [];
|
|
146
143
|
const missingPermissions = [];
|
|
147
|
-
// Check permissions at this level
|
|
148
|
-
if (permissions.length > 0) {
|
|
149
|
-
if (operator === 'or') {
|
|
150
|
-
const hasAny = permissions.some((p)=>this.hasPermission(userPermissions, p));
|
|
151
|
-
results.push(hasAny);
|
|
152
|
-
if (!hasAny) {
|
|
153
|
-
failureDetails.push(`needs one of: [${permissions.join(', ')}]`);
|
|
154
|
-
missingPermissions.push(...permissions);
|
|
155
|
-
}
|
|
156
|
-
} else {
|
|
157
|
-
const hasAll = permissions.every((p)=>this.hasPermission(userPermissions, p));
|
|
158
|
-
results.push(hasAll);
|
|
159
|
-
if (!hasAll) {
|
|
160
|
-
const missing = permissions.filter((p)=>!this.hasPermission(userPermissions, p));
|
|
161
|
-
failureDetails.push(`missing: [${missing.join(', ')}]`);
|
|
162
|
-
missingPermissions.push(...missing);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
// Evaluate children recursively
|
|
167
144
|
for (const child of children){
|
|
168
|
-
const childResult = this.
|
|
145
|
+
const childResult = this.evaluateLogicNode(child, userPermissions);
|
|
169
146
|
results.push(childResult.passed);
|
|
170
147
|
if (!childResult.passed) {
|
|
171
|
-
failureDetails.push(`(${childResult.message})`);
|
|
172
148
|
missingPermissions.push(...childResult.missingPermissions);
|
|
173
149
|
}
|
|
174
150
|
}
|
|
175
|
-
|
|
176
|
-
let passed;
|
|
177
|
-
if (operator === 'or') {
|
|
178
|
-
passed = results.length === 0 || results.some((r)=>r);
|
|
179
|
-
} else {
|
|
180
|
-
passed = results.length === 0 || results.every((r)=>r);
|
|
181
|
-
}
|
|
182
|
-
const message = passed ? 'Permission granted' : `Permission denied: ${failureDetails.join(` ${operator.toUpperCase()} `)}`;
|
|
151
|
+
const passed = operator === 'OR' ? results.some((r)=>r) : results.every((r)=>r);
|
|
183
152
|
return {
|
|
184
153
|
passed,
|
|
185
|
-
|
|
186
|
-
missingPermissions,
|
|
154
|
+
missingPermissions: passed ? [] : missingPermissions,
|
|
187
155
|
operator
|
|
188
156
|
};
|
|
189
157
|
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
let cacheKey;
|
|
158
|
+
async getUserPermissions(user) {
|
|
159
|
+
if (!this.cache) throw new _permissionexception.PermissionSystemUnavailableException();
|
|
160
|
+
const cacheKey = this.buildPermissionCacheKey(user);
|
|
161
|
+
return await this.cache.get(cacheKey) || [];
|
|
162
|
+
}
|
|
163
|
+
buildPermissionCacheKey(user) {
|
|
197
164
|
if (this.config.enableCompanyFeature && user.companyId) {
|
|
198
|
-
|
|
199
|
-
const format = this.config.companyPermissionKeyFormat || `${_constants.PERMISSIONS_CACHE_PREFIX}:company:{companyId}:branch:{branchId}:user:{userId}`;
|
|
200
|
-
cacheKey = format.replace('{userId}', user.id).replace('{companyId}', user.companyId).replace('{branchId}', user.branchId || 'null');
|
|
201
|
-
} else {
|
|
202
|
-
// User-based permissions
|
|
203
|
-
const format = this.config.userPermissionKeyFormat || `${_constants.PERMISSIONS_CACHE_PREFIX}:user:{userId}`;
|
|
204
|
-
cacheKey = format.replace('{userId}', user.id);
|
|
165
|
+
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');
|
|
205
166
|
}
|
|
206
|
-
|
|
207
|
-
return permissions || [];
|
|
167
|
+
return (this.config.userPermissionKeyFormat || `${_constants.PERMISSIONS_CACHE_PREFIX}:user:{userId}`).replace('{userId}', user.id);
|
|
208
168
|
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
* Supports wildcard matching (e.g., 'admin.*' matches 'admin.users.read')
|
|
212
|
-
*/ hasPermission(userPermissions, requiredPermission) {
|
|
213
|
-
// Direct match
|
|
214
|
-
if (userPermissions.includes(requiredPermission)) {
|
|
215
|
-
return true;
|
|
216
|
-
}
|
|
217
|
-
// Wildcard match (e.g., '*' or 'admin.*')
|
|
169
|
+
hasPermission(userPermissions, requiredPermission) {
|
|
170
|
+
if (userPermissions.includes(requiredPermission)) return true;
|
|
218
171
|
for (const permission of userPermissions){
|
|
219
|
-
if (permission === '*')
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
if (permission.endsWith('.*')) {
|
|
223
|
-
const prefix = permission.slice(0, -1); // Remove '*'
|
|
224
|
-
if (requiredPermission.startsWith(prefix)) {
|
|
225
|
-
return true;
|
|
226
|
-
}
|
|
172
|
+
if (permission === '*') return true;
|
|
173
|
+
if (permission.endsWith('.*') && requiredPermission.startsWith(permission.slice(0, -1))) {
|
|
174
|
+
return true;
|
|
227
175
|
}
|
|
228
176
|
}
|
|
229
177
|
return false;
|
|
230
178
|
}
|
|
231
|
-
|
|
232
|
-
constructor(reflector, cache, config, logger){
|
|
179
|
+
constructor(reflector, cache, config){
|
|
233
180
|
_define_property(this, "reflector", void 0);
|
|
234
181
|
_define_property(this, "cache", void 0);
|
|
235
182
|
_define_property(this, "config", void 0);
|
|
236
|
-
_define_property(this, "logger", void 0);
|
|
237
183
|
this.reflector = reflector;
|
|
238
184
|
this.cache = cache;
|
|
239
185
|
this.config = {
|
|
240
186
|
enableCompanyFeature: false,
|
|
241
|
-
cacheKeyPrefix: _constants.PERMISSIONS_CACHE_PREFIX,
|
|
242
187
|
userPermissionKeyFormat: `${_constants.PERMISSIONS_CACHE_PREFIX}:user:{userId}`,
|
|
243
188
|
companyPermissionKeyFormat: `${_constants.PERMISSIONS_CACHE_PREFIX}:company:{companyId}:branch:{branchId}:user:{userId}`,
|
|
244
189
|
...config
|
|
245
190
|
};
|
|
246
|
-
// Use provided logger or fallback to NestJS Logger wrapped in adapter
|
|
247
|
-
this.logger = logger || new _winstonloggeradapterclass.NestLoggerAdapter(new _common.Logger(PermissionGuard.name));
|
|
248
191
|
}
|
|
249
192
|
};
|
|
250
193
|
PermissionGuard = _ts_decorate([
|
|
@@ -254,13 +197,10 @@ PermissionGuard = _ts_decorate([
|
|
|
254
197
|
_ts_param(1, (0, _common.Inject)(_constants.CACHE_INSTANCE)),
|
|
255
198
|
_ts_param(2, (0, _common.Optional)()),
|
|
256
199
|
_ts_param(2, (0, _common.Inject)(_constants.PERMISSION_GUARD_CONFIG)),
|
|
257
|
-
_ts_param(3, (0, _common.Optional)()),
|
|
258
|
-
_ts_param(3, (0, _common.Inject)(_constants.LOGGER_INSTANCE)),
|
|
259
200
|
_ts_metadata("design:type", Function),
|
|
260
201
|
_ts_metadata("design:paramtypes", [
|
|
261
202
|
typeof _core.Reflector === "undefined" ? Object : _core.Reflector,
|
|
262
203
|
typeof _hybridcacheclass.HybridCache === "undefined" ? Object : _hybridcacheclass.HybridCache,
|
|
263
|
-
typeof _permissioninterface.PermissionGuardConfig === "undefined" ? Object : _permissioninterface.PermissionGuardConfig
|
|
264
|
-
typeof _loggerinterface.ILogger === "undefined" ? Object : _loggerinterface.ILogger
|
|
204
|
+
typeof _permissioninterface.PermissionGuardConfig === "undefined" ? Object : _permissioninterface.PermissionGuardConfig
|
|
265
205
|
])
|
|
266
206
|
], PermissionGuard);
|
package/cjs/index.js
CHANGED
|
@@ -7,7 +7,9 @@ _export_star(require("./constants"), exports);
|
|
|
7
7
|
_export_star(require("./decorators"), exports);
|
|
8
8
|
_export_star(require("./dtos"), exports);
|
|
9
9
|
_export_star(require("./entities"), exports);
|
|
10
|
+
_export_star(require("./enums"), exports);
|
|
10
11
|
_export_star(require("./exceptions"), exports);
|
|
12
|
+
_export_star(require("./filters"), exports);
|
|
11
13
|
_export_star(require("./guards"), exports);
|
|
12
14
|
_export_star(require("./interceptors"), exports);
|
|
13
15
|
_export_star(require("./interfaces"), exports);
|
|
@@ -61,7 +61,7 @@ let IdempotencyInterceptor = class IdempotencyInterceptor {
|
|
|
61
61
|
throw new _common.ConflictException({
|
|
62
62
|
success: false,
|
|
63
63
|
message: 'Request is already being processed',
|
|
64
|
-
|
|
64
|
+
messageKey: _constants.SYSTEM_MESSAGES.DUPLICATE_REQUEST
|
|
65
65
|
});
|
|
66
66
|
}
|
|
67
67
|
// Return cached response
|