@node-c/api-http 1.0.0-beta0 → 1.0.0-beta1
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/dist/decorators/http.decorators.accessControl.d.ts +9 -0
- package/dist/decorators/http.decorators.accessControl.js +7 -0
- package/dist/decorators/http.decorators.accessControl.js.map +1 -0
- package/dist/decorators/index.d.ts +1 -0
- package/dist/decorators/index.js +18 -0
- package/dist/decorators/index.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/interceptors/http.interceptors.accessControl.d.ts +7 -6
- package/dist/interceptors/http.interceptors.accessControl.js +34 -20
- package/dist/interceptors/http.interceptors.accessControl.js.map +1 -1
- package/dist/interceptors/http.interceptors.error.d.ts +3 -0
- package/dist/interceptors/http.interceptors.error.js +9 -2
- package/dist/interceptors/http.interceptors.error.js.map +1 -1
- package/dist/middlewares/http.middlewares.authorization.d.ts +4 -3
- package/dist/middlewares/http.middlewares.authorization.js +15 -13
- package/dist/middlewares/http.middlewares.authorization.js.map +1 -1
- package/dist/middlewares/http.middlewares.requestLogging.d.ts +10 -0
- package/dist/middlewares/http.middlewares.requestLogging.js +35 -0
- package/dist/middlewares/http.middlewares.requestLogging.js.map +1 -0
- package/dist/middlewares/index.d.ts +1 -0
- package/dist/middlewares/index.js +1 -0
- package/dist/middlewares/index.js.map +1 -1
- package/dist/module/http.api.module.js +1 -4
- package/dist/module/http.api.module.js.map +1 -1
- package/package.json +4 -3
- package/src/decorators/http.decorators.accessControl.ts +8 -0
- package/src/decorators/index.ts +1 -0
- package/src/index.ts +1 -0
- package/src/interceptors/http.interceptors.accessControl.ts +43 -36
- package/src/interceptors/http.interceptors.error.ts +7 -2
- package/src/middlewares/http.middlewares.authorization.ts +11 -9
- package/src/middlewares/http.middlewares.requestLogging.ts +22 -0
- package/src/middlewares/index.ts +1 -0
- package/src/module/http.api.module.ts +2 -5
- package/dist/guards/http.guards.accessControl.d.ts +0 -2
- package/dist/guards/http.guards.accessControl.js +0 -18
- package/dist/guards/http.guards.accessControl.js.map +0 -1
- package/src/guards/http.guards.accessControl.ts +0 -13
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { GenericObject } from '@node-c/core';
|
|
2
|
+
export declare const AccessControlContext: import("@nestjs/core").ReflectableDecorator<string | {
|
|
3
|
+
context: string;
|
|
4
|
+
resourceMap: GenericObject<string>;
|
|
5
|
+
}, string | {
|
|
6
|
+
context: string;
|
|
7
|
+
resourceMap: GenericObject<string>;
|
|
8
|
+
}>;
|
|
9
|
+
export declare const AccessControlResource: import("@nestjs/core").ReflectableDecorator<string, string>;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AccessControlResource = exports.AccessControlContext = void 0;
|
|
4
|
+
const core_1 = require("@nestjs/core");
|
|
5
|
+
exports.AccessControlContext = core_1.Reflector.createDecorator();
|
|
6
|
+
exports.AccessControlResource = core_1.Reflector.createDecorator();
|
|
7
|
+
//# sourceMappingURL=http.decorators.accessControl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.decorators.accessControl.js","sourceRoot":"","sources":["../../src/decorators/http.decorators.accessControl.ts"],"names":[],"mappings":";;;AAAA,uCAAyC;AAG5B,QAAA,oBAAoB,GAAG,gBAAS,CAAC,eAAe,EAE1D,CAAC;AAES,QAAA,qBAAqB,GAAG,gBAAS,CAAC,eAAe,EAAU,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './http.decorators.accessControl';
|
|
@@ -0,0 +1,18 @@
|
|
|
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("./http.decorators.accessControl"), exports);
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/decorators/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,kEAAgD"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -16,6 +16,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./common/definitions"), exports);
|
|
18
18
|
__exportStar(require("./filters"), exports);
|
|
19
|
+
__exportStar(require("./decorators"), exports);
|
|
19
20
|
__exportStar(require("./interceptors"), exports);
|
|
20
21
|
__exportStar(require("./middlewares"), exports);
|
|
21
22
|
__exportStar(require("./module"), exports);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,uDAAqC;AACrC,4CAA0B;AAC1B,iDAA+B;AAC/B,gDAA8B;AAC9B,2CAAyB"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,uDAAqC;AACrC,4CAA0B;AAC1B,+CAA6B;AAC7B,iDAA+B;AAC/B,gDAA8B;AAC9B,2CAAyB"}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { CallHandler, ExecutionContext, NestInterceptor } from '@nestjs/common';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { ModuleRef, Reflector } from '@nestjs/core';
|
|
3
|
+
import { LoggerService } from '@node-c/core';
|
|
4
|
+
import { IAMUserManagerUserWithPermissionsData } from '@node-c/domain-iam';
|
|
4
5
|
import { Observable } from 'rxjs';
|
|
5
6
|
export declare class HTTPAccessControlInterceptor<User extends IAMUserManagerUserWithPermissionsData<unknown, unknown>> implements NestInterceptor {
|
|
6
|
-
protected
|
|
7
|
-
protected
|
|
8
|
-
protected
|
|
9
|
-
constructor(
|
|
7
|
+
protected logger: LoggerService;
|
|
8
|
+
protected moduleRef: ModuleRef;
|
|
9
|
+
protected reflector: Reflector;
|
|
10
|
+
constructor(logger: LoggerService, moduleRef: ModuleRef, reflector: Reflector);
|
|
10
11
|
intercept(context: ExecutionContext, next: CallHandler): Promise<Observable<unknown>>;
|
|
11
12
|
}
|
|
@@ -8,9 +8,6 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
8
8
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
9
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
10
|
};
|
|
11
|
-
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
-
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
-
};
|
|
14
11
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
15
12
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
16
13
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -23,18 +20,20 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
23
20
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
21
|
exports.HTTPAccessControlInterceptor = void 0;
|
|
25
22
|
const common_1 = require("@nestjs/common");
|
|
26
|
-
const core_1 = require("@
|
|
23
|
+
const core_1 = require("@nestjs/core");
|
|
24
|
+
const core_2 = require("@node-c/core");
|
|
27
25
|
const domain_iam_1 = require("@node-c/domain-iam");
|
|
28
26
|
const rxjs_1 = require("rxjs");
|
|
29
|
-
const
|
|
27
|
+
const decorators_1 = require("../decorators");
|
|
30
28
|
let HTTPAccessControlInterceptor = class HTTPAccessControlInterceptor {
|
|
31
|
-
constructor(
|
|
32
|
-
this.
|
|
33
|
-
this.
|
|
34
|
-
this.
|
|
29
|
+
constructor(logger, moduleRef, reflector) {
|
|
30
|
+
this.logger = logger;
|
|
31
|
+
this.moduleRef = moduleRef;
|
|
32
|
+
this.reflector = reflector;
|
|
35
33
|
}
|
|
36
34
|
intercept(context, next) {
|
|
37
35
|
return __awaiter(this, void 0, void 0, function* () {
|
|
36
|
+
var _a;
|
|
38
37
|
const [req] = context.getArgs();
|
|
39
38
|
const locals = req.locals;
|
|
40
39
|
if (!locals) {
|
|
@@ -43,17 +42,33 @@ let HTTPAccessControlInterceptor = class HTTPAccessControlInterceptor {
|
|
|
43
42
|
else if (locals.isAnonymous) {
|
|
44
43
|
return next.handle();
|
|
45
44
|
}
|
|
46
|
-
const {
|
|
47
|
-
const
|
|
48
|
-
const
|
|
45
|
+
const { logger, moduleRef, reflector } = this;
|
|
46
|
+
const contextClass = context.getClass();
|
|
47
|
+
const contextHandler = context.getHandler();
|
|
48
|
+
const moduleName = moduleRef.get(domain_iam_1.Constants.ACCESS_CONTROL_MODULE_NAME) ||
|
|
49
|
+
moduleRef.get(core_2.Constants.API_MODULE_NAME);
|
|
50
|
+
if (!moduleName) {
|
|
51
|
+
logger.error(`[HTTPAccessControlInterceptor]: No moduleName configured for ${contextClass.name}.${contextHandler.name}.`);
|
|
52
|
+
throw new common_1.HttpException('Internal Server Error', common_1.HttpStatus.INTERNAL_SERVER_ERROR);
|
|
53
|
+
}
|
|
54
|
+
const resourceContextData = reflector.get(decorators_1.AccessControlContext, contextClass);
|
|
55
|
+
const accessControlOptions = {
|
|
56
|
+
moduleName,
|
|
57
|
+
resource: reflector.get(decorators_1.AccessControlResource, contextHandler) ||
|
|
58
|
+
(typeof resourceContextData !== 'string' && ((_a = resourceContextData === null || resourceContextData === void 0 ? void 0 : resourceContextData.resourceMap) === null || _a === void 0 ? void 0 : _a[contextHandler.name])) ||
|
|
59
|
+
contextHandler.name,
|
|
60
|
+
resourceContext: (typeof resourceContextData === 'string' && resourceContextData) ||
|
|
61
|
+
(typeof resourceContextData !== 'string' && (resourceContextData === null || resourceContextData === void 0 ? void 0 : resourceContextData.context)) ||
|
|
62
|
+
contextClass.name
|
|
63
|
+
};
|
|
49
64
|
const user = locals.user;
|
|
50
|
-
const { authorizationPoints: usedAuthorizationPoints, errorCode, hasAccess, inputDataToBeMutated } = domain_iam_1.IAMAuthorizationService.checkAccess({ body: req.body, headers: req.headers, params: req.params, query: req.query }, user,
|
|
65
|
+
const { authorizationPoints: usedAuthorizationPoints, errorCode, hasAccess, inputDataToBeMutated } = domain_iam_1.IAMAuthorizationService.checkAccess({ body: req.body, headers: req.headers, params: req.params, query: req.query }, user, accessControlOptions);
|
|
51
66
|
if (!hasAccess) {
|
|
52
|
-
|
|
67
|
+
logger.error(`[${moduleName}][HTTPAccessControlInterceptor]: No user access to resource ${accessControlOptions.moduleName}.${accessControlOptions.resourceContext}.${accessControlOptions.resource} - ${errorCode}.`);
|
|
53
68
|
throw new common_1.HttpException('Forbidden', common_1.HttpStatus.FORBIDDEN);
|
|
54
69
|
}
|
|
55
70
|
for (const key in inputDataToBeMutated) {
|
|
56
|
-
(0,
|
|
71
|
+
(0, core_2.setNested)(req, key, inputDataToBeMutated[key], { removeNestedFieldEscapeSign: true });
|
|
57
72
|
}
|
|
58
73
|
return next.handle().pipe((0, rxjs_1.map)((data) => {
|
|
59
74
|
if (typeof data === 'undefined' || data === null || typeof data !== 'object' || data instanceof Date) {
|
|
@@ -62,7 +77,7 @@ let HTTPAccessControlInterceptor = class HTTPAccessControlInterceptor {
|
|
|
62
77
|
const actualData = data;
|
|
63
78
|
const { outputDataToBeMutated } = domain_iam_1.IAMAuthorizationService.processOutputData(usedAuthorizationPoints, actualData);
|
|
64
79
|
for (const key in outputDataToBeMutated) {
|
|
65
|
-
(0,
|
|
80
|
+
(0, core_2.setNested)(actualData, key, outputDataToBeMutated[key]);
|
|
66
81
|
}
|
|
67
82
|
return actualData;
|
|
68
83
|
}));
|
|
@@ -72,9 +87,8 @@ let HTTPAccessControlInterceptor = class HTTPAccessControlInterceptor {
|
|
|
72
87
|
exports.HTTPAccessControlInterceptor = HTTPAccessControlInterceptor;
|
|
73
88
|
exports.HTTPAccessControlInterceptor = HTTPAccessControlInterceptor = __decorate([
|
|
74
89
|
(0, common_1.Injectable)(),
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
core_1.ConfigProviderService, String])
|
|
90
|
+
__metadata("design:paramtypes", [core_2.LoggerService,
|
|
91
|
+
core_1.ModuleRef,
|
|
92
|
+
core_1.Reflector])
|
|
79
93
|
], HTTPAccessControlInterceptor);
|
|
80
94
|
//# sourceMappingURL=http.interceptors.accessControl.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.interceptors.accessControl.js","sourceRoot":"","sources":["../../src/interceptors/http.interceptors.accessControl.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"http.interceptors.accessControl.js","sourceRoot":"","sources":["../../src/interceptors/http.interceptors.accessControl.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA,2CAAuH;AACvH,uCAAoD;AAEpD,uCAAwG;AACxG,mDAI4B;AAE5B,+BAAuC;AAGvC,8CAA4E;AAMrE,IAAM,4BAA4B,GAAlC,MAAM,4BAA4B;IAGvC,YAEY,MAAqB,EAErB,SAAoB,EAEpB,SAAoB;QAJpB,WAAM,GAAN,MAAM,CAAe;QAErB,cAAS,GAAT,SAAS,CAAW;QAEpB,cAAS,GAAT,SAAS,CAAW;IAC7B,CAAC;IAEE,SAAS,CAAC,OAAyB,EAAE,IAAiB;;;YAC1D,MAAM,CAAC,GAAG,CAAC,GAAuC,OAAO,CAAC,OAAO,EAAE,CAAC;YACpE,MAAM,MAAM,GAAG,GAAG,CAAC,MAAO,CAAC;YAC3B,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,IAAI,sBAAa,CAAC,WAAW,EAAE,mBAAU,CAAC,SAAS,CAAC,CAAC;YAC7D,CAAC;iBAAM,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;gBAC9B,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;YACvB,CAAC;YACD,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC;YAC9C,MAAM,YAAY,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;YACxC,MAAM,cAAc,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;YAC5C,MAAM,UAAU,GACd,SAAS,CAAC,GAAG,CAAC,sBAAuB,CAAC,0BAA0B,CAAC;gBACjE,SAAS,CAAC,GAAG,CAAC,gBAAkB,CAAC,eAAe,CAAC,CAAC;YACpD,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,MAAM,CAAC,KAAK,CACV,gEAAgE,YAAY,CAAC,IAAI,IAAI,cAAc,CAAC,IAAI,GAAG,CAC5G,CAAC;gBACF,MAAM,IAAI,sBAAa,CAAC,uBAAuB,EAAE,mBAAU,CAAC,qBAAqB,CAAC,CAAC;YACrF,CAAC;YACD,MAAM,mBAAmB,GAAG,SAAS,CAAC,GAAG,CAAC,iCAAoB,EAAE,YAAY,CAAC,CAAC;YAC9E,MAAM,oBAAoB,GAAG;gBAC3B,UAAU;gBACV,QAAQ,EACN,SAAS,CAAC,GAAG,CAAC,kCAAqB,EAAE,cAAc,CAAC;oBACpD,CAAC,OAAO,mBAAmB,KAAK,QAAQ,KAAI,MAAA,mBAAmB,aAAnB,mBAAmB,uBAAnB,mBAAmB,CAAE,WAAW,0CAAG,cAAc,CAAC,IAAI,CAAC,CAAA,CAAC;oBACpG,cAAc,CAAC,IAAI;gBACrB,eAAe,EACb,CAAC,OAAO,mBAAmB,KAAK,QAAQ,IAAI,mBAAmB,CAAC;oBAChE,CAAC,OAAO,mBAAmB,KAAK,QAAQ,KAAI,mBAAmB,aAAnB,mBAAmB,uBAAnB,mBAAmB,CAAE,OAAO,CAAA,CAAC;oBACzE,YAAY,CAAC,IAAI;aACpB,CAAC;YACF,MAAM,IAAI,GAAG,MAAM,CAAC,IAAK,CAAC;YAC1B,MAAM,EACJ,mBAAmB,EAAE,uBAAuB,EAC5C,SAAS,EACT,SAAS,EACT,oBAAoB,EACrB,GAAG,oCAAuB,CAAC,WAAW,CACrC,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,EAC9E,IAAI,EACJ,oBAAoB,CACrB,CAAC;YACF,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,MAAM,CAAC,KAAK,CACV,IAAI,UAAU,+DAA+D,oBAAoB,CAAC,UAAU,IAAI,oBAAoB,CAAC,eAAe,IAAI,oBAAoB,CAAC,QAAQ,MAAM,SAAS,GAAG,CACxM,CAAC;gBACF,MAAM,IAAI,sBAAa,CAAC,WAAW,EAAE,mBAAU,CAAC,SAAS,CAAC,CAAC;YAC7D,CAAC;YACD,KAAK,MAAM,GAAG,IAAI,oBAAoB,EAAE,CAAC;gBACvC,IAAA,gBAAS,EAAC,GAAG,EAAE,GAAG,EAAE,oBAAoB,CAAC,GAAG,CAAC,EAAE,EAAE,2BAA2B,EAAE,IAAI,EAAE,CAAC,CAAC;YACxF,CAAC;YACD,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CACvB,IAAA,UAAG,EAAC,CAAC,IAAc,EAAE,EAAE;gBACrB,IAAI,OAAO,IAAI,KAAK,WAAW,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,YAAY,IAAI,EAAE,CAAC;oBACrG,OAAO,IAAI,CAAC;gBACd,CAAC;gBACD,MAAM,UAAU,GAAG,IAAqB,CAAC;gBACzC,MAAM,EAAE,qBAAqB,EAAE,GAAG,oCAAuB,CAAC,iBAAiB,CACzE,uBAAuB,EACvB,UAAU,CACX,CAAC;gBACF,KAAK,MAAM,GAAG,IAAI,qBAAqB,EAAE,CAAC;oBACxC,IAAA,gBAAS,EAAC,UAAU,EAAE,GAAG,EAAE,qBAAqB,CAAC,GAAG,CAAC,CAAC,CAAC;gBACzD,CAAC;gBACD,OAAO,UAAU,CAAC;YACpB,CAAC,CAAC,CACH,CAAC;QACJ,CAAC;KAAA;CACF,CAAA;AAjFY,oEAA4B;uCAA5B,4BAA4B;IADxC,IAAA,mBAAU,GAAE;qCAMS,oBAAa;QAEV,gBAAS;QAET,gBAAS;GATrB,4BAA4B,CAiFxC"}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { CallHandler, ExecutionContext, NestInterceptor } from '@nestjs/common';
|
|
2
|
+
import { LoggerService } from '@node-c/core';
|
|
2
3
|
import { Observable } from 'rxjs';
|
|
3
4
|
export declare class HTTPErrorInterceptor implements NestInterceptor {
|
|
5
|
+
protected logger: LoggerService;
|
|
6
|
+
constructor(logger: LoggerService);
|
|
4
7
|
intercept(context: ExecutionContext, next: CallHandler): Observable<unknown>;
|
|
5
8
|
}
|
|
@@ -5,6 +5,9 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
5
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
6
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
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
|
+
};
|
|
8
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
12
|
exports.HTTPErrorInterceptor = void 0;
|
|
10
13
|
const common_1 = require("@nestjs/common");
|
|
@@ -13,9 +16,12 @@ const rxjs_1 = require("rxjs");
|
|
|
13
16
|
const operators_1 = require("rxjs/operators");
|
|
14
17
|
const common_errors_1 = require("../common/definitions/common.errors");
|
|
15
18
|
let HTTPErrorInterceptor = class HTTPErrorInterceptor {
|
|
19
|
+
constructor(logger) {
|
|
20
|
+
this.logger = logger;
|
|
21
|
+
}
|
|
16
22
|
intercept(context, next) {
|
|
17
23
|
return next.handle().pipe((0, operators_1.catchError)(error => {
|
|
18
|
-
|
|
24
|
+
this.logger.error(error);
|
|
19
25
|
let message = 'An error has occurred.';
|
|
20
26
|
let status = 500;
|
|
21
27
|
if (error instanceof core_1.ApplicationError || error instanceof common_errors_1.ServerError) {
|
|
@@ -62,6 +68,7 @@ let HTTPErrorInterceptor = class HTTPErrorInterceptor {
|
|
|
62
68
|
};
|
|
63
69
|
exports.HTTPErrorInterceptor = HTTPErrorInterceptor;
|
|
64
70
|
exports.HTTPErrorInterceptor = HTTPErrorInterceptor = __decorate([
|
|
65
|
-
(0, common_1.Injectable)()
|
|
71
|
+
(0, common_1.Injectable)(),
|
|
72
|
+
__metadata("design:paramtypes", [core_1.LoggerService])
|
|
66
73
|
], HTTPErrorInterceptor);
|
|
67
74
|
//# sourceMappingURL=http.interceptors.error.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.interceptors.error.js","sourceRoot":"","sources":["../../src/interceptors/http.interceptors.error.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"http.interceptors.error.js","sourceRoot":"","sources":["../../src/interceptors/http.interceptors.error.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA4F;AAE5F,uCAA+D;AAE/D,+BAAkC;AAClC,8CAA4C;AAE5C,uEAAkE;AAG3D,IAAM,oBAAoB,GAA1B,MAAM,oBAAoB;IAC/B,YAEY,MAAqB;QAArB,WAAM,GAAN,MAAM,CAAe;IAC9B,CAAC;IAEJ,SAAS,CAAC,OAAyB,EAAE,IAAiB;QACpD,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CACvB,IAAA,sBAAU,EAAC,KAAK,CAAC,EAAE;YACjB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACzB,IAAI,OAAO,GAAsB,wBAAwB,CAAC;YAC1D,IAAI,MAAM,GAAG,GAAG,CAAC;YACjB,IAAI,KAAK,YAAY,uBAAgB,IAAI,KAAK,YAAY,2BAAW,EAAE,CAAC;gBACtE,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;oBAClB,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;gBAC1B,CAAC;gBACD,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;oBACf,IAAI,WAAW,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;wBAC9B,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,SAAmB,CAAC;oBAC1C,CAAC;yBAAM,IAAI,YAAY,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;wBACtC,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,UAAoB,CAAC;oBAC3C,CAAC;yBAAM,CAAC;wBACN,MAAM,GAAG,GAAG,CAAC;oBACf,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,MAAM,GAAG,GAAG,CAAC;gBACf,CAAC;YACH,CAAC;iBAAM,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;gBAC1B,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC;gBAC3B,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC;oBACxB,MAAM,GAAG,QAAQ,CAAC,UAAU,CAAC;gBAC/B,CAAC;gBACD,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;oBACrB,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;gBAC7B,CAAC;YACH,CAAC;iBAAM,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;gBAClC,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;oBAClB,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;gBAC1B,CAAC;YACH,CAAC;YACD,OAAO;iBACJ,YAAY,EAAE;iBACd,WAAW,EAAE;iBACb,MAAM,CAAC,MAAM,CAAC;iBACd,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,YAAY,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;YAC5E,OAAO,IAAI,iBAAU,EAAE,CAAC;QAC1B,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;CACF,CAAA;AAjDY,oDAAoB;+BAApB,oBAAoB;IADhC,IAAA,mBAAU,GAAE;qCAIS,oBAAa;GAHtB,oBAAoB,CAiDhC"}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { NestMiddleware } from '@nestjs/common';
|
|
2
|
-
import { ConfigProviderService } from '@node-c/core';
|
|
2
|
+
import { ConfigProviderService, LoggerService } from '@node-c/core';
|
|
3
3
|
import { AuthorizationPoint, IAMAuthorizationService, IAMTokenManagerService, IAMUserManagerService, IAMUserManagerUserTokenEnityFields } from '@node-c/domain-iam';
|
|
4
4
|
import { NextFunction, Response } from 'express';
|
|
5
5
|
import { RequestWithLocals } from '../common/definitions';
|
|
6
6
|
export declare class HTTPAuthorizationMiddleware<User extends object> implements NestMiddleware {
|
|
7
|
+
protected authorizationService: IAMAuthorizationService<AuthorizationPoint<unknown>>;
|
|
7
8
|
protected configProvider: ConfigProviderService;
|
|
9
|
+
protected logger: LoggerService;
|
|
8
10
|
protected moduleName: string;
|
|
9
|
-
protected authorizationService: IAMAuthorizationService<AuthorizationPoint<unknown>>;
|
|
10
11
|
protected tokenManager?: IAMTokenManagerService<IAMUserManagerUserTokenEnityFields> | undefined;
|
|
11
12
|
protected usersService?: IAMUserManagerService<User> | undefined;
|
|
12
|
-
constructor(configProvider: ConfigProviderService,
|
|
13
|
+
constructor(authorizationService: IAMAuthorizationService<AuthorizationPoint<unknown>>, configProvider: ConfigProviderService, logger: LoggerService, moduleName: string, tokenManager?: IAMTokenManagerService<IAMUserManagerUserTokenEnityFields> | undefined, usersService?: IAMUserManagerService<User> | undefined);
|
|
13
14
|
use(req: RequestWithLocals<unknown>, res: Response, next: NextFunction): void;
|
|
14
15
|
}
|
|
@@ -28,17 +28,19 @@ const domain_iam_1 = require("@node-c/domain-iam");
|
|
|
28
28
|
const definitions_1 = require("../common/definitions");
|
|
29
29
|
const utils_1 = require("../common/utils");
|
|
30
30
|
let HTTPAuthorizationMiddleware = class HTTPAuthorizationMiddleware {
|
|
31
|
-
constructor(configProvider,
|
|
31
|
+
constructor(authorizationService, configProvider, logger, moduleName, tokenManager, usersService) {
|
|
32
|
+
this.authorizationService = authorizationService;
|
|
32
33
|
this.configProvider = configProvider;
|
|
34
|
+
this.logger = logger;
|
|
33
35
|
this.moduleName = moduleName;
|
|
34
|
-
this.authorizationService = authorizationService;
|
|
35
36
|
this.tokenManager = tokenManager;
|
|
36
37
|
this.usersService = usersService;
|
|
37
38
|
}
|
|
38
39
|
use(req, res, next) {
|
|
40
|
+
const { configProvider, logger, moduleName, tokenManager, usersService } = this;
|
|
39
41
|
(() => __awaiter(this, void 0, void 0, function* () {
|
|
40
42
|
var _a, _b, _c, _d, _e;
|
|
41
|
-
const moduleConfig =
|
|
43
|
+
const moduleConfig = configProvider.config.api[moduleName];
|
|
42
44
|
const { anonymousAccessRoutes } = moduleConfig;
|
|
43
45
|
const requestMethod = req.method.toLowerCase();
|
|
44
46
|
if (!req.locals) {
|
|
@@ -60,7 +62,6 @@ let HTTPAuthorizationMiddleware = class HTTPAuthorizationMiddleware {
|
|
|
60
62
|
return;
|
|
61
63
|
}
|
|
62
64
|
}
|
|
63
|
-
const { tokenManager, usersService } = this;
|
|
64
65
|
const hasApiKey = !!((_a = req.headers.authorization) === null || _a === void 0 ? void 0 : _a.match(/^ApiKey\s/));
|
|
65
66
|
if (hasApiKey) {
|
|
66
67
|
const [apiKeyFromHeader, requestSignature] = ((_c = (_b = req.headers.authorization) === null || _b === void 0 ? void 0 : _b.replace(/^ApiKey\s/, '')) === null || _c === void 0 ? void 0 : _c.split(' ')) || [];
|
|
@@ -91,7 +92,7 @@ let HTTPAuthorizationMiddleware = class HTTPAuthorizationMiddleware {
|
|
|
91
92
|
return;
|
|
92
93
|
}
|
|
93
94
|
else if (!tokenManager) {
|
|
94
|
-
|
|
95
|
+
logger.error('Missing api key in the configuration and no tokenManager set up.');
|
|
95
96
|
throw new common_1.HttpException('Unauthorized', common_1.HttpStatus.UNAUTHORIZED);
|
|
96
97
|
}
|
|
97
98
|
let tokens = [];
|
|
@@ -116,7 +117,7 @@ let HTTPAuthorizationMiddleware = class HTTPAuthorizationMiddleware {
|
|
|
116
117
|
if (usersService) {
|
|
117
118
|
const userId = (_d = tokenContent === null || tokenContent === void 0 ? void 0 : tokenContent.data) === null || _d === void 0 ? void 0 : _d.userId;
|
|
118
119
|
if (!userId) {
|
|
119
|
-
|
|
120
|
+
logger.error('Missing userId in the tokenContent data.');
|
|
120
121
|
throw new common_1.HttpException('Unauthorized', common_1.HttpStatus.UNAUTHORIZED);
|
|
121
122
|
}
|
|
122
123
|
const user = (_e = tokenContent === null || tokenContent === void 0 ? void 0 : tokenContent.data) === null || _e === void 0 ? void 0 : _e.user;
|
|
@@ -135,7 +136,7 @@ let HTTPAuthorizationMiddleware = class HTTPAuthorizationMiddleware {
|
|
|
135
136
|
}
|
|
136
137
|
next();
|
|
137
138
|
}))().then(() => true, err => {
|
|
138
|
-
|
|
139
|
+
logger.error(err);
|
|
139
140
|
res.status((err && err.status) || common_1.HttpStatus.INTERNAL_SERVER_ERROR).end();
|
|
140
141
|
});
|
|
141
142
|
}
|
|
@@ -143,12 +144,13 @@ let HTTPAuthorizationMiddleware = class HTTPAuthorizationMiddleware {
|
|
|
143
144
|
exports.HTTPAuthorizationMiddleware = HTTPAuthorizationMiddleware;
|
|
144
145
|
exports.HTTPAuthorizationMiddleware = HTTPAuthorizationMiddleware = __decorate([
|
|
145
146
|
(0, common_1.Injectable)(),
|
|
146
|
-
__param(
|
|
147
|
-
__param(
|
|
148
|
-
__param(
|
|
149
|
-
__param(
|
|
150
|
-
__metadata("design:paramtypes", [
|
|
151
|
-
|
|
147
|
+
__param(0, (0, common_1.Inject)(definitions_1.Constants.API_MODULE_AUTHORIZATION_SERVICE)),
|
|
148
|
+
__param(3, (0, common_1.Inject)(definitions_1.Constants.API_MODULE_NAME)),
|
|
149
|
+
__param(4, (0, common_1.Inject)(definitions_1.Constants.AUTHORIZATION_MIDDLEWARE_TOKEN_MANAGER_SERVICE)),
|
|
150
|
+
__param(5, (0, common_1.Inject)(definitions_1.Constants.AUTHENTICATION_MIDDLEWARE_USERS_SERVICE)),
|
|
151
|
+
__metadata("design:paramtypes", [domain_iam_1.IAMAuthorizationService,
|
|
152
|
+
core_1.ConfigProviderService,
|
|
153
|
+
core_1.LoggerService, String, domain_iam_1.IAMTokenManagerService,
|
|
152
154
|
domain_iam_1.IAMUserManagerService])
|
|
153
155
|
], HTTPAuthorizationMiddleware);
|
|
154
156
|
//# sourceMappingURL=http.middlewares.authorization.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.middlewares.authorization.js","sourceRoot":"","sources":["../../src/middlewares/http.middlewares.authorization.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAA+F;AAE/F,
|
|
1
|
+
{"version":3,"file":"http.middlewares.authorization.js","sourceRoot":"","sources":["../../src/middlewares/http.middlewares.authorization.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { NestMiddleware } from '@nestjs/common';
|
|
2
|
+
import { LoggerService } from '@node-c/core';
|
|
3
|
+
import { NextFunction, Response } from 'express';
|
|
4
|
+
import { RequestWithLocals } from '../common/definitions';
|
|
5
|
+
export declare class HTTPRequestLoggingMiddleware implements NestMiddleware {
|
|
6
|
+
protected logger: LoggerService;
|
|
7
|
+
protected moduleName: string;
|
|
8
|
+
constructor(logger: LoggerService, moduleName: string);
|
|
9
|
+
use(req: RequestWithLocals<unknown>, _res: Response, next: NextFunction): void;
|
|
10
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
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.HTTPRequestLoggingMiddleware = void 0;
|
|
16
|
+
const common_1 = require("@nestjs/common");
|
|
17
|
+
const core_1 = require("@node-c/core");
|
|
18
|
+
const definitions_1 = require("../common/definitions");
|
|
19
|
+
let HTTPRequestLoggingMiddleware = class HTTPRequestLoggingMiddleware {
|
|
20
|
+
constructor(logger, moduleName) {
|
|
21
|
+
this.logger = logger;
|
|
22
|
+
this.moduleName = moduleName;
|
|
23
|
+
}
|
|
24
|
+
use(req, _res, next) {
|
|
25
|
+
this.logger.info(`[${this.moduleName}]: ${req.method} ${req.baseUrl}`);
|
|
26
|
+
next();
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
exports.HTTPRequestLoggingMiddleware = HTTPRequestLoggingMiddleware;
|
|
30
|
+
exports.HTTPRequestLoggingMiddleware = HTTPRequestLoggingMiddleware = __decorate([
|
|
31
|
+
(0, common_1.Injectable)(),
|
|
32
|
+
__param(1, (0, common_1.Inject)(definitions_1.Constants.API_MODULE_NAME)),
|
|
33
|
+
__metadata("design:paramtypes", [core_1.LoggerService, String])
|
|
34
|
+
], HTTPRequestLoggingMiddleware);
|
|
35
|
+
//# sourceMappingURL=http.middlewares.requestLogging.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.middlewares.requestLogging.js","sourceRoot":"","sources":["../../src/middlewares/http.middlewares.requestLogging.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAAoE;AAEpE,uCAA6C;AAG7C,uDAAqE;AAG9D,IAAM,4BAA4B,GAAlC,MAAM,4BAA4B;IACvC,YAEY,MAAqB,EAGrB,UAAkB;QAHlB,WAAM,GAAN,MAAM,CAAe;QAGrB,eAAU,GAAV,UAAU,CAAQ;IAC3B,CAAC;IAEJ,GAAG,CAAC,GAA+B,EAAE,IAAc,EAAE,IAAkB;QACrE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,MAAM,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACvE,IAAI,EAAE,CAAC;IACT,CAAC;CACF,CAAA;AAbY,oEAA4B;uCAA5B,4BAA4B;IADxC,IAAA,mBAAU,GAAE;IAKR,WAAA,IAAA,eAAM,EAAC,uBAAS,CAAC,eAAe,CAAC,CAAA;qCADhB,oBAAa;GAHtB,4BAA4B,CAaxC"}
|
|
@@ -16,4 +16,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./http.middlewares.authorization"), exports);
|
|
18
18
|
__exportStar(require("./http.middlewares.cors"), exports);
|
|
19
|
+
__exportStar(require("./http.middlewares.requestLogging"), exports);
|
|
19
20
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/middlewares/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,mEAAiD;AACjD,0DAAwC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/middlewares/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,mEAAiD;AACjD,0DAAwC;AACxC,oEAAkD"}
|
|
@@ -22,7 +22,6 @@ const core_1 = require("@nestjs/core");
|
|
|
22
22
|
const core_2 = require("@node-c/core");
|
|
23
23
|
const cookie_parser_1 = __importDefault(require("cookie-parser"));
|
|
24
24
|
const express_1 = __importDefault(require("express"));
|
|
25
|
-
const morgan_1 = __importDefault(require("morgan"));
|
|
26
25
|
const definitions_1 = require("../common/definitions");
|
|
27
26
|
const filters_1 = require("../filters");
|
|
28
27
|
const interceptors_1 = require("../interceptors");
|
|
@@ -36,9 +35,7 @@ let HTTPAPIModule = HTTPAPIModule_1 = class HTTPAPIModule {
|
|
|
36
35
|
consumer.apply(express_1.default.urlencoded({ verify: HTTPAPIModule_1.rawBodyBuffer, extended: true })).forRoutes('*');
|
|
37
36
|
consumer.apply(express_1.default.json({ verify: HTTPAPIModule_1.rawBodyBuffer })).forRoutes('*');
|
|
38
37
|
consumer.apply((0, cookie_parser_1.default)()).forRoutes('*');
|
|
39
|
-
consumer
|
|
40
|
-
.apply((0, morgan_1.default)(`[${this.moduleName}]: :method :url :status :res[content-length] - :response-time ms`))
|
|
41
|
-
.forRoutes('*');
|
|
38
|
+
consumer.apply(middlewares_1.HTTPRequestLoggingMiddleware).forRoutes('*');
|
|
42
39
|
consumer.apply(middlewares_1.HTTPCORSMiddleware).forRoutes('*');
|
|
43
40
|
consumer.apply(middlewares_1.HTTPAuthorizationMiddleware).forRoutes('*');
|
|
44
41
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.api.module.js","sourceRoot":"","sources":["../../src/module/http.api.module.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;AAAA,2CAA2G;AAC3G,uCAAwC;AAExC,uCAAyE;AAEzE,kEAAyC;AACzC,sDAA4C;
|
|
1
|
+
{"version":3,"file":"http.api.module.js","sourceRoot":"","sources":["../../src/module/http.api.module.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@node-c/api-http",
|
|
3
|
-
"version": "1.0.0-
|
|
3
|
+
"version": "1.0.0-beta1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
"check-types": "tsc -p tsconfig.build.json --noEmit",
|
|
10
10
|
"dev": "tsc -p tsconfig.build.json --watch",
|
|
11
11
|
"lint": "eslint src",
|
|
12
|
+
"lint:fix": "eslint src --fix",
|
|
12
13
|
"publish-package": "npm run build:clean && npm publish --access public",
|
|
13
14
|
"test": "vitest --config src/vitest.config.ts",
|
|
14
15
|
"test:coverage": "vitest --config src/vitest.config.ts --coverage"
|
|
@@ -27,7 +28,7 @@
|
|
|
27
28
|
"@types/lodash": "^4.17.19"
|
|
28
29
|
},
|
|
29
30
|
"peerDependencies": {
|
|
30
|
-
"@node-c/core": "^1.0.0-
|
|
31
|
-
"@node-c/domain-iam": "^1.0.0-
|
|
31
|
+
"@node-c/core": "^1.0.0-beta1",
|
|
32
|
+
"@node-c/domain-iam": "^1.0.0-beta1"
|
|
32
33
|
}
|
|
33
34
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Reflector } from '@nestjs/core';
|
|
2
|
+
import { GenericObject } from '@node-c/core';
|
|
3
|
+
|
|
4
|
+
export const AccessControlContext = Reflector.createDecorator<
|
|
5
|
+
string | { context: string; resourceMap: GenericObject<string> }
|
|
6
|
+
>();
|
|
7
|
+
|
|
8
|
+
export const AccessControlResource = Reflector.createDecorator<string>();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './http.decorators.accessControl';
|
package/src/index.ts
CHANGED
|
@@ -1,36 +1,32 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
ExecutionContext,
|
|
4
|
-
HttpException,
|
|
5
|
-
HttpStatus,
|
|
6
|
-
Inject,
|
|
7
|
-
Injectable,
|
|
8
|
-
NestInterceptor
|
|
9
|
-
} from '@nestjs/common';
|
|
1
|
+
import { CallHandler, ExecutionContext, HttpException, HttpStatus, Injectable, NestInterceptor } from '@nestjs/common';
|
|
2
|
+
import { ModuleRef, Reflector } from '@nestjs/core';
|
|
10
3
|
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
4
|
+
import { GenericObject, LoggerService, Constants as NodeCCoreConstants, setNested } from '@node-c/core';
|
|
5
|
+
import {
|
|
6
|
+
IAMAuthorizationService,
|
|
7
|
+
IAMUserManagerUserWithPermissionsData,
|
|
8
|
+
Constants as NodeCDomainIAMConstants
|
|
9
|
+
} from '@node-c/domain-iam';
|
|
13
10
|
|
|
14
11
|
import { Observable, map } from 'rxjs';
|
|
15
12
|
|
|
16
|
-
import {
|
|
13
|
+
import { RequestWithLocals } from '../common/definitions';
|
|
14
|
+
import { AccessControlContext, AccessControlResource } from '../decorators';
|
|
17
15
|
|
|
18
16
|
/*
|
|
19
17
|
* Authorization interceptor - used for role-based and fine-grained access control.
|
|
20
18
|
*/
|
|
21
19
|
@Injectable()
|
|
22
|
-
export class HTTPAccessControlInterceptor<
|
|
23
|
-
|
|
24
|
-
{
|
|
20
|
+
export class HTTPAccessControlInterceptor<
|
|
21
|
+
User extends IAMUserManagerUserWithPermissionsData<unknown, unknown>
|
|
22
|
+
> implements NestInterceptor {
|
|
25
23
|
constructor(
|
|
26
|
-
@Inject(Constants.API_MODULE_AUTHORIZATION_SERVICE)
|
|
27
24
|
// eslint-disable-next-line no-unused-vars
|
|
28
|
-
protected
|
|
25
|
+
protected logger: LoggerService,
|
|
29
26
|
// eslint-disable-next-line no-unused-vars
|
|
30
|
-
protected
|
|
31
|
-
@Inject(Constants.API_MODULE_NAME)
|
|
27
|
+
protected moduleRef: ModuleRef,
|
|
32
28
|
// eslint-disable-next-line no-unused-vars
|
|
33
|
-
protected
|
|
29
|
+
protected reflector: Reflector
|
|
34
30
|
) {}
|
|
35
31
|
|
|
36
32
|
async intercept(context: ExecutionContext, next: CallHandler): Promise<Observable<unknown>> {
|
|
@@ -41,9 +37,30 @@ export class HTTPAccessControlInterceptor<User extends IAMUserManagerUserWithPer
|
|
|
41
37
|
} else if (locals.isAnonymous) {
|
|
42
38
|
return next.handle();
|
|
43
39
|
}
|
|
44
|
-
const {
|
|
45
|
-
const
|
|
46
|
-
const
|
|
40
|
+
const { logger, moduleRef, reflector } = this;
|
|
41
|
+
const contextClass = context.getClass();
|
|
42
|
+
const contextHandler = context.getHandler();
|
|
43
|
+
const moduleName =
|
|
44
|
+
moduleRef.get(NodeCDomainIAMConstants.ACCESS_CONTROL_MODULE_NAME) ||
|
|
45
|
+
moduleRef.get(NodeCCoreConstants.API_MODULE_NAME);
|
|
46
|
+
if (!moduleName) {
|
|
47
|
+
logger.error(
|
|
48
|
+
`[HTTPAccessControlInterceptor]: No moduleName configured for ${contextClass.name}.${contextHandler.name}.`
|
|
49
|
+
);
|
|
50
|
+
throw new HttpException('Internal Server Error', HttpStatus.INTERNAL_SERVER_ERROR);
|
|
51
|
+
}
|
|
52
|
+
const resourceContextData = reflector.get(AccessControlContext, contextClass);
|
|
53
|
+
const accessControlOptions = {
|
|
54
|
+
moduleName,
|
|
55
|
+
resource:
|
|
56
|
+
reflector.get(AccessControlResource, contextHandler) ||
|
|
57
|
+
(typeof resourceContextData !== 'string' && resourceContextData?.resourceMap?.[contextHandler.name]) ||
|
|
58
|
+
contextHandler.name,
|
|
59
|
+
resourceContext:
|
|
60
|
+
(typeof resourceContextData === 'string' && resourceContextData) ||
|
|
61
|
+
(typeof resourceContextData !== 'string' && resourceContextData?.context) ||
|
|
62
|
+
contextClass.name
|
|
63
|
+
};
|
|
47
64
|
const user = locals.user!; // we'll always have this, otherwise the system has not been configured properly
|
|
48
65
|
const {
|
|
49
66
|
authorizationPoints: usedAuthorizationPoints,
|
|
@@ -53,21 +70,11 @@ export class HTTPAccessControlInterceptor<User extends IAMUserManagerUserWithPer
|
|
|
53
70
|
} = IAMAuthorizationService.checkAccess(
|
|
54
71
|
{ body: req.body, headers: req.headers, params: req.params, query: req.query },
|
|
55
72
|
user,
|
|
56
|
-
|
|
73
|
+
accessControlOptions
|
|
57
74
|
);
|
|
58
75
|
if (!hasAccess) {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
// if (noMatchForResource && ) {
|
|
62
|
-
// }
|
|
63
|
-
// if (!endpointSecurityMode || endpointSecurityMode === EndpointSecurityMode.Strict) {
|
|
64
|
-
// console.info(
|
|
65
|
-
// `[${moduleName}][HTTPAccessControlInterceptor]: No authorization point data for handler ${controllerName}.${handlerName}.`
|
|
66
|
-
// );
|
|
67
|
-
// throw new HttpException('Forbidden', HttpStatus.FORBIDDEN);
|
|
68
|
-
// }
|
|
69
|
-
console.error(
|
|
70
|
-
`[${moduleName}][HTTPAccessControlInterceptor]: No user access to handler ${controllerName}.${handlerName} - ${errorCode}.`
|
|
76
|
+
logger.error(
|
|
77
|
+
`[${moduleName}][HTTPAccessControlInterceptor]: No user access to resource ${accessControlOptions.moduleName}.${accessControlOptions.resourceContext}.${accessControlOptions.resource} - ${errorCode}.`
|
|
71
78
|
);
|
|
72
79
|
throw new HttpException('Forbidden', HttpStatus.FORBIDDEN);
|
|
73
80
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common';
|
|
2
2
|
|
|
3
|
-
import { ApplicationError } from '@node-c/core';
|
|
3
|
+
import { ApplicationError, LoggerService } from '@node-c/core';
|
|
4
4
|
|
|
5
5
|
import { Observable } from 'rxjs';
|
|
6
6
|
import { catchError } from 'rxjs/operators';
|
|
@@ -9,10 +9,15 @@ import { ServerError } from '../common/definitions/common.errors';
|
|
|
9
9
|
|
|
10
10
|
@Injectable()
|
|
11
11
|
export class HTTPErrorInterceptor implements NestInterceptor {
|
|
12
|
+
constructor(
|
|
13
|
+
// eslint-disable-next-line no-unused-vars
|
|
14
|
+
protected logger: LoggerService
|
|
15
|
+
) {}
|
|
16
|
+
|
|
12
17
|
intercept(context: ExecutionContext, next: CallHandler): Observable<unknown> {
|
|
13
18
|
return next.handle().pipe(
|
|
14
19
|
catchError(error => {
|
|
15
|
-
|
|
20
|
+
this.logger.error(error);
|
|
16
21
|
let message: string | string[] = 'An error has occurred.';
|
|
17
22
|
let status = 500;
|
|
18
23
|
if (error instanceof ApplicationError || error instanceof ServerError) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { HttpException, HttpStatus, Inject, Injectable, NestMiddleware } from '@nestjs/common';
|
|
2
2
|
|
|
3
|
-
import { AppConfigAPIHTTP, ConfigProviderService } from '@node-c/core';
|
|
3
|
+
import { AppConfigAPIHTTP, ConfigProviderService, LoggerService } from '@node-c/core';
|
|
4
4
|
import {
|
|
5
5
|
AuthorizationPoint,
|
|
6
6
|
IAMAuthorizationService,
|
|
@@ -20,14 +20,16 @@ import { checkRoutes } from '../common/utils';
|
|
|
20
20
|
@Injectable()
|
|
21
21
|
export class HTTPAuthorizationMiddleware<User extends object> implements NestMiddleware {
|
|
22
22
|
constructor(
|
|
23
|
+
@Inject(Constants.API_MODULE_AUTHORIZATION_SERVICE)
|
|
24
|
+
// eslint-disable-next-line no-unused-vars
|
|
25
|
+
protected authorizationService: IAMAuthorizationService<AuthorizationPoint<unknown>>,
|
|
23
26
|
// eslint-disable-next-line no-unused-vars
|
|
24
27
|
protected configProvider: ConfigProviderService,
|
|
28
|
+
// eslint-disable-next-line no-unused-vars
|
|
29
|
+
protected logger: LoggerService,
|
|
25
30
|
@Inject(Constants.API_MODULE_NAME)
|
|
26
31
|
// eslint-disable-next-line no-unused-vars
|
|
27
32
|
protected moduleName: string,
|
|
28
|
-
@Inject(Constants.API_MODULE_AUTHORIZATION_SERVICE)
|
|
29
|
-
// eslint-disable-next-line no-unused-vars
|
|
30
|
-
protected authorizationService: IAMAuthorizationService<AuthorizationPoint<unknown>>,
|
|
31
33
|
@Inject(Constants.AUTHORIZATION_MIDDLEWARE_TOKEN_MANAGER_SERVICE)
|
|
32
34
|
// eslint-disable-next-line no-unused-vars
|
|
33
35
|
protected tokenManager?: IAMTokenManagerService<IAMUserManagerUserTokenEnityFields>,
|
|
@@ -37,8 +39,9 @@ export class HTTPAuthorizationMiddleware<User extends object> implements NestMid
|
|
|
37
39
|
) {}
|
|
38
40
|
|
|
39
41
|
use(req: RequestWithLocals<unknown>, res: Response, next: NextFunction): void {
|
|
42
|
+
const { configProvider, logger, moduleName, tokenManager, usersService } = this;
|
|
40
43
|
(async () => {
|
|
41
|
-
const moduleConfig =
|
|
44
|
+
const moduleConfig = configProvider.config.api![moduleName] as AppConfigAPIHTTP;
|
|
42
45
|
const { anonymousAccessRoutes } = moduleConfig;
|
|
43
46
|
const requestMethod = req.method.toLowerCase();
|
|
44
47
|
if (!req.locals) {
|
|
@@ -62,7 +65,6 @@ export class HTTPAuthorizationMiddleware<User extends object> implements NestMid
|
|
|
62
65
|
return;
|
|
63
66
|
}
|
|
64
67
|
}
|
|
65
|
-
const { tokenManager, usersService } = this;
|
|
66
68
|
const hasApiKey = !!req.headers.authorization?.match(/^ApiKey\s/);
|
|
67
69
|
if (hasApiKey) {
|
|
68
70
|
const [apiKeyFromHeader, requestSignature] =
|
|
@@ -96,7 +98,7 @@ export class HTTPAuthorizationMiddleware<User extends object> implements NestMid
|
|
|
96
98
|
next();
|
|
97
99
|
return;
|
|
98
100
|
} else if (!tokenManager) {
|
|
99
|
-
|
|
101
|
+
logger.error('Missing api key in the configuration and no tokenManager set up.');
|
|
100
102
|
throw new HttpException('Unauthorized', HttpStatus.UNAUTHORIZED);
|
|
101
103
|
}
|
|
102
104
|
let tokens: string[] = [];
|
|
@@ -124,7 +126,7 @@ export class HTTPAuthorizationMiddleware<User extends object> implements NestMid
|
|
|
124
126
|
if (usersService) {
|
|
125
127
|
const userId = tokenContent?.data?.userId;
|
|
126
128
|
if (!userId) {
|
|
127
|
-
|
|
129
|
+
logger.error('Missing userId in the tokenContent data.');
|
|
128
130
|
throw new HttpException('Unauthorized', HttpStatus.UNAUTHORIZED);
|
|
129
131
|
}
|
|
130
132
|
// use the bearer auth token decoded payload for the user data, if configured this way
|
|
@@ -145,7 +147,7 @@ export class HTTPAuthorizationMiddleware<User extends object> implements NestMid
|
|
|
145
147
|
})().then(
|
|
146
148
|
() => true,
|
|
147
149
|
err => {
|
|
148
|
-
|
|
150
|
+
logger.error(err);
|
|
149
151
|
res.status((err && err.status) || HttpStatus.INTERNAL_SERVER_ERROR).end();
|
|
150
152
|
}
|
|
151
153
|
);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Inject, Injectable, NestMiddleware } from '@nestjs/common';
|
|
2
|
+
|
|
3
|
+
import { LoggerService } from '@node-c/core';
|
|
4
|
+
import { NextFunction, Response } from 'express';
|
|
5
|
+
|
|
6
|
+
import { Constants, RequestWithLocals } from '../common/definitions';
|
|
7
|
+
|
|
8
|
+
@Injectable()
|
|
9
|
+
export class HTTPRequestLoggingMiddleware implements NestMiddleware {
|
|
10
|
+
constructor(
|
|
11
|
+
// eslint-disable-next-line no-unused-vars
|
|
12
|
+
protected logger: LoggerService,
|
|
13
|
+
@Inject(Constants.API_MODULE_NAME)
|
|
14
|
+
// eslint-disable-next-line no-unused-vars
|
|
15
|
+
protected moduleName: string
|
|
16
|
+
) {}
|
|
17
|
+
|
|
18
|
+
use(req: RequestWithLocals<unknown>, _res: Response, next: NextFunction): void {
|
|
19
|
+
this.logger.info(`[${this.moduleName}]: ${req.method} ${req.baseUrl}`);
|
|
20
|
+
next();
|
|
21
|
+
}
|
|
22
|
+
}
|
package/src/middlewares/index.ts
CHANGED
|
@@ -5,14 +5,13 @@ import { ConfigProviderService, loadDynamicModules } from '@node-c/core';
|
|
|
5
5
|
|
|
6
6
|
import cookieParser from 'cookie-parser';
|
|
7
7
|
import express, { Response } from 'express';
|
|
8
|
-
import morgan from 'morgan';
|
|
9
8
|
|
|
10
9
|
import { HTTPAPIModuleOptions } from './http.api.module.definitions';
|
|
11
10
|
|
|
12
11
|
import { Constants, RequestWithLocals } from '../common/definitions';
|
|
13
12
|
import { HttpExceptionFilter } from '../filters';
|
|
14
13
|
import { HTTPAccessControlInterceptor, HTTPErrorInterceptor } from '../interceptors';
|
|
15
|
-
import { HTTPAuthorizationMiddleware, HTTPCORSMiddleware } from '../middlewares';
|
|
14
|
+
import { HTTPAuthorizationMiddleware, HTTPCORSMiddleware, HTTPRequestLoggingMiddleware } from '../middlewares';
|
|
16
15
|
|
|
17
16
|
export class HTTPAPIModule {
|
|
18
17
|
constructor(
|
|
@@ -28,9 +27,7 @@ export class HTTPAPIModule {
|
|
|
28
27
|
consumer.apply(express.json({ verify: HTTPAPIModule.rawBodyBuffer })).forRoutes('*');
|
|
29
28
|
consumer.apply(cookieParser()).forRoutes('*');
|
|
30
29
|
// configure logging
|
|
31
|
-
consumer
|
|
32
|
-
.apply(morgan(`[${this.moduleName}]: :method :url :status :res[content-length] - :response-time ms`))
|
|
33
|
-
.forRoutes('*');
|
|
30
|
+
consumer.apply(HTTPRequestLoggingMiddleware).forRoutes('*');
|
|
34
31
|
consumer.apply(HTTPCORSMiddleware).forRoutes('*');
|
|
35
32
|
consumer.apply(HTTPAuthorizationMiddleware).forRoutes('*');
|
|
36
33
|
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AccessControlResource = exports.AccessControlContext = void 0;
|
|
4
|
-
const AccessControlContext = (moduleName, resourceContext) => {
|
|
5
|
-
console.log(moduleName, resourceContext);
|
|
6
|
-
return (target, propertyKey) => {
|
|
7
|
-
console.log(target, propertyKey);
|
|
8
|
-
};
|
|
9
|
-
};
|
|
10
|
-
exports.AccessControlContext = AccessControlContext;
|
|
11
|
-
const AccessControlResource = (resource) => {
|
|
12
|
-
console.log(resource);
|
|
13
|
-
return (target, propertyKey) => {
|
|
14
|
-
console.log(target, propertyKey);
|
|
15
|
-
};
|
|
16
|
-
};
|
|
17
|
-
exports.AccessControlResource = AccessControlResource;
|
|
18
|
-
//# sourceMappingURL=http.guards.accessControl.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"http.guards.accessControl.js","sourceRoot":"","sources":["../../src/guards/http.guards.accessControl.ts"],"names":[],"mappings":";;;AAAO,MAAM,oBAAoB,GAAG,CAAC,UAAkB,EAAE,eAAuB,EAAE,EAAE;IAClF,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;IACzC,OAAO,CAAC,MAAc,EAAE,WAAmB,EAAQ,EAAE;QACnD,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACnC,CAAC,CAAC;AACJ,CAAC,CAAC;AALW,QAAA,oBAAoB,wBAK/B;AAEK,MAAM,qBAAqB,GAAG,CAAC,QAAgB,EAAE,EAAE;IACxD,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACtB,OAAO,CAAC,MAAc,EAAE,WAAmB,EAAQ,EAAE;QACnD,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACnC,CAAC,CAAC;AACJ,CAAC,CAAC;AALW,QAAA,qBAAqB,yBAKhC"}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
export const AccessControlContext = (moduleName: string, resourceContext: string) => {
|
|
2
|
-
console.log(moduleName, resourceContext);
|
|
3
|
-
return (target: object, propertyKey: string): void => {
|
|
4
|
-
console.log(target, propertyKey);
|
|
5
|
-
};
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
export const AccessControlResource = (resource: string) => {
|
|
9
|
-
console.log(resource);
|
|
10
|
-
return (target: object, propertyKey: string): void => {
|
|
11
|
-
console.log(target, propertyKey);
|
|
12
|
-
};
|
|
13
|
-
};
|