@thisisagile/easy-express 8.4.7 → 8.5.2
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 +3 -1
- package/dist/express/ErrorHandler.js +1 -1
- package/dist/express/ErrorHandler.js.map +1 -1
- package/dist/express/ExpressProvider.js +2 -0
- package/dist/express/ExpressProvider.js.map +1 -1
- package/dist/express/SecurityHandler.d.ts +1 -0
- package/dist/express/SecurityHandler.js +5 -1
- package/dist/express/SecurityHandler.js.map +1 -1
- package/package.json +3 -3
- package/src/express/ErrorHandler.ts +8 -8
- package/src/express/ExpressProvider.ts +7 -6
- package/src/express/SecurityHandler.ts +8 -1
package/README.md
CHANGED
|
@@ -241,7 +241,7 @@ During the execution of a request, lots of things can go wrong. Here as some com
|
|
|
241
241
|
|
|
242
242
|
* For starters, you might not reach the endpoint, because you've typed in the wrong URL. If this happens, and you still reach your microservice, **easy** handles this in the `NotFoundHandler`, which is plugged-in by default.
|
|
243
243
|
* If you are not allowed to execute an endpoint, for instance because it is secured with one of the security decorators in **easy**, such as `@requires.useCase()`, `@requires.Scope()` or `@requires.token`, the endpoint will not execute, and you will receive a 403. In this case the middleware from the `SecurityHandler` already breaks the loop, and the code in you microservices is not executed at all.
|
|
244
|
-
* All other failures are handled by the `ErrorHandler`,
|
|
244
|
+
* All other failures are handled by the `ErrorHandler`, and can result in any custom HTTP status code, most likely a 400, or a 500. In case the caller makes a mistake, the code should come from the 400 range, in cases the microservice makes the mistake, the code comes from the 500 range.
|
|
245
245
|
|
|
246
246
|
## Utilities
|
|
247
247
|
Additionally, this library contains utility classes for standardizing e.g. uri's, and ids, constructors, lists, queries, and errors. Quite often these are constructed as monads, which renders robust code.
|
|
@@ -276,5 +276,7 @@ Access to endpoints is configured using the `@requires` decorator group. If mult
|
|
|
276
276
|
add = (req: Req): Promise<Product> => this.manage.add(req.body as Json);
|
|
277
277
|
}
|
|
278
278
|
|
|
279
|
+
The `@requires` decorator group also contains `@requires.labCoat()` this decorator can be added to endpoints you only want to be available on your development environment, for example a `delete`.
|
|
280
|
+
|
|
279
281
|
To use these decorators, the generic `security` middleware must be loaded first. In most cases, it should be added to the `pre` list of handlers of a service.
|
|
280
282
|
The security middleware takes an optional configuration object, which is documented [in code](packages/easy-express/src/express/SecurityHandler.ts).
|
|
@@ -21,7 +21,7 @@ const toBody = ({ origin, options }) => {
|
|
|
21
21
|
const error = (e, req, res, _next) => {
|
|
22
22
|
(0, easy_1.tryTo)(() => (0, easy_1.toOriginatedError)(e))
|
|
23
23
|
.map(oe => toBody(oe))
|
|
24
|
-
.accept(r => easy_1.ctx.request.lastError = r.status.isServerError ? r.body.error?.errors[0]?.message : undefined)
|
|
24
|
+
.accept(r => (easy_1.ctx.request.lastError = r.status.isServerError ? r.body.error?.errors[0]?.message : undefined))
|
|
25
25
|
.accept(r => res.status(r.status.status).json(r.body));
|
|
26
26
|
};
|
|
27
27
|
exports.error = error;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ErrorHandler.js","sourceRoot":"","sources":["../../src/express/ErrorHandler.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"ErrorHandler.js","sourceRoot":"","sources":["../../src/express/ErrorHandler.ts"],"names":[],"mappings":"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"}
|
|
@@ -36,6 +36,8 @@ class ExpressProvider {
|
|
|
36
36
|
}
|
|
37
37
|
addSecurityMiddleware(requires) {
|
|
38
38
|
const middleware = [];
|
|
39
|
+
if (requires.labCoat)
|
|
40
|
+
middleware.push((0, SecurityHandler_1.checkLabCoat)());
|
|
39
41
|
if (requires.token)
|
|
40
42
|
middleware.push((0, SecurityHandler_1.checkToken)());
|
|
41
43
|
if (requires.scope)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpressProvider.js","sourceRoot":"","sources":["../../src/express/ExpressProvider.ts"],"names":[],"mappings":";;;;;;AAAA,sDAA4F;AAC5F,
|
|
1
|
+
{"version":3,"file":"ExpressProvider.js","sourceRoot":"","sources":["../../src/express/ExpressProvider.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,6 +11,7 @@ export interface SecurityOptions {
|
|
|
11
11
|
algorithms?: string[];
|
|
12
12
|
};
|
|
13
13
|
}
|
|
14
|
+
export declare const checkLabCoat: () => RequestHandler;
|
|
14
15
|
export declare const checkToken: () => RequestHandler;
|
|
15
16
|
export declare const checkScope: (scope: Scope) => RequestHandler;
|
|
16
17
|
export declare const checkUseCase: (uc: UseCase) => RequestHandler;
|
|
@@ -3,11 +3,15 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.security = exports.checkUseCase = exports.checkScope = exports.checkToken = void 0;
|
|
6
|
+
exports.security = exports.checkUseCase = exports.checkScope = exports.checkToken = exports.checkLabCoat = void 0;
|
|
7
7
|
const passport_1 = __importDefault(require("passport"));
|
|
8
8
|
const passport_jwt_1 = require("passport-jwt");
|
|
9
9
|
const AuthError_1 = require("./AuthError");
|
|
10
10
|
const easy_1 = require("@thisisagile/easy");
|
|
11
|
+
const checkLabCoat = () => (req, res, next) => next((0, easy_1.choose)(easy_1.ctx.env.name)
|
|
12
|
+
.case(e => easy_1.Environment.Dev.equals(e), undefined)
|
|
13
|
+
.else((0, AuthError_1.authError)(easy_1.HttpStatus.Forbidden)));
|
|
14
|
+
exports.checkLabCoat = checkLabCoat;
|
|
11
15
|
const checkToken = () => passport_1.default.authenticate('jwt', { session: false, failWithError: true });
|
|
12
16
|
exports.checkToken = checkToken;
|
|
13
17
|
const checkScope = (scope) => (req, res, next) => next((0, easy_1.choose)(scope.id)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SecurityHandler.js","sourceRoot":"","sources":["../../src/express/SecurityHandler.ts"],"names":[],"mappings":";;;;;;AACA,wDAAgC;AAChC,+CAAiG;AACjG,2CAAwC;AACxC,
|
|
1
|
+
{"version":3,"file":"SecurityHandler.js","sourceRoot":"","sources":["../../src/express/SecurityHandler.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thisisagile/easy-express",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.5.2",
|
|
4
4
|
"description": "Straightforward library for building domain-driven microservice architectures",
|
|
5
5
|
"author": "Sander Hoogendoorn",
|
|
6
6
|
"license": "MIT",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"access": "public"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"@thisisagile/easy-test": "8.
|
|
34
|
+
"@thisisagile/easy-test": "8.5.2",
|
|
35
35
|
"@types/cls-hooked": "^4.3.3",
|
|
36
36
|
"@types/form-urlencoded": "^4.4.0",
|
|
37
37
|
"@types/jsonwebtoken": "^8.5.6",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"@types/validator": "^13.7.0"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@thisisagile/easy": "8.
|
|
44
|
+
"@thisisagile/easy": "8.5.2",
|
|
45
45
|
"@types/express": "^4.17.13",
|
|
46
46
|
"cls-hooked": "^4.2.2",
|
|
47
47
|
"express": "^4.17.1",
|
|
@@ -31,35 +31,35 @@ const toBody = ({ origin, options }: OriginatedError): Response => {
|
|
|
31
31
|
return choose<Response, any>(origin)
|
|
32
32
|
.case(
|
|
33
33
|
o => isAuthError(o),
|
|
34
|
-
o => toResponse(toHttpStatus(o.status), [toResult(o.message)])
|
|
34
|
+
o => toResponse(toHttpStatus(o.status), [toResult(o.message)])
|
|
35
35
|
)
|
|
36
36
|
.case(
|
|
37
37
|
o => Exception.DoesNotExist.equals(o),
|
|
38
|
-
(o: Exception) => toResponse(options?.onNotFound ?? HttpStatus.NotFound, [toResult(o.reason ?? o.message)])
|
|
38
|
+
(o: Exception) => toResponse(options?.onNotFound ?? HttpStatus.NotFound, [toResult(o.reason ?? o.message)])
|
|
39
39
|
)
|
|
40
40
|
.case(
|
|
41
41
|
// This service breaks with an error
|
|
42
42
|
o => isError(o),
|
|
43
|
-
(o: Error) => toResponse(HttpStatus.InternalServerError, [toResult(o.message)])
|
|
43
|
+
(o: Error) => toResponse(HttpStatus.InternalServerError, [toResult(o.message)])
|
|
44
44
|
)
|
|
45
45
|
.case(
|
|
46
46
|
// This service fails
|
|
47
47
|
o => isResults(o),
|
|
48
|
-
(o: Results) => toResponse(options?.onError ?? HttpStatus.BadRequest, o.results)
|
|
48
|
+
(o: Results) => toResponse(options?.onError ?? HttpStatus.BadRequest, o.results)
|
|
49
49
|
)
|
|
50
50
|
.case(
|
|
51
51
|
// Underlying service fails
|
|
52
52
|
o => isResponse(o),
|
|
53
|
-
(o: Response) => toResponse(HttpStatus.InternalServerError, o.body.error?.errors)
|
|
53
|
+
(o: Response) => toResponse(HttpStatus.InternalServerError, o.body.error?.errors)
|
|
54
54
|
)
|
|
55
55
|
.case(
|
|
56
56
|
o => isException(o),
|
|
57
|
-
(o: Exception) => toResponse(options?.onError ?? HttpStatus.BadRequest, [toResult(o.reason ?? o.message)])
|
|
57
|
+
(o: Exception) => toResponse(options?.onError ?? HttpStatus.BadRequest, [toResult(o.reason ?? o.message)])
|
|
58
58
|
)
|
|
59
59
|
.case(
|
|
60
60
|
// This service fails with a string
|
|
61
61
|
o => isText(o),
|
|
62
|
-
(o: Response) => toResponse(options?.onError ?? HttpStatus.BadRequest, [toResult(asString(o))])
|
|
62
|
+
(o: Response) => toResponse(options?.onError ?? HttpStatus.BadRequest, [toResult(asString(o))])
|
|
63
63
|
)
|
|
64
64
|
.else(() => toResponse(HttpStatus.InternalServerError, [toResult('Unknown error')]));
|
|
65
65
|
};
|
|
@@ -67,6 +67,6 @@ const toBody = ({ origin, options }: OriginatedError): Response => {
|
|
|
67
67
|
export const error = (e: Error, req: express.Request, res: express.Response, _next: express.NextFunction): void => {
|
|
68
68
|
tryTo(() => toOriginatedError(e))
|
|
69
69
|
.map(oe => toBody(oe))
|
|
70
|
-
.accept(r => ctx.request.lastError = r.status.isServerError ? r.body.error?.errors[0]?.message : undefined)
|
|
70
|
+
.accept(r => (ctx.request.lastError = r.status.isServerError ? r.body.error?.errors[0]?.message : undefined))
|
|
71
71
|
.accept(r => res.status(r.status.status).json(r.body));
|
|
72
72
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import express, { Express, NextFunction, Request, RequestHandler, Response } from 'express';
|
|
2
|
-
import { checkScope, checkToken, checkUseCase } from './SecurityHandler';
|
|
2
|
+
import { checkLabCoat, checkScope, checkToken, checkUseCase } from './SecurityHandler';
|
|
3
3
|
import {
|
|
4
4
|
AppProvider,
|
|
5
5
|
Endpoint,
|
|
@@ -41,7 +41,7 @@ export class ExpressProvider implements AppProvider {
|
|
|
41
41
|
route.route(service.name),
|
|
42
42
|
...this.addSecurityMiddleware(requires),
|
|
43
43
|
...middleware,
|
|
44
|
-
this.handle(endpoint, verb.options)
|
|
44
|
+
this.handle(endpoint, verb.options)
|
|
45
45
|
);
|
|
46
46
|
});
|
|
47
47
|
|
|
@@ -56,6 +56,7 @@ export class ExpressProvider implements AppProvider {
|
|
|
56
56
|
|
|
57
57
|
protected addSecurityMiddleware(requires: RouteRequires): RequestHandler[] {
|
|
58
58
|
const middleware: RequestHandler[] = [];
|
|
59
|
+
if (requires.labCoat) middleware.push(checkLabCoat());
|
|
59
60
|
if (requires.token) middleware.push(checkToken());
|
|
60
61
|
if (requires.scope) middleware.push(checkScope(requires.scope));
|
|
61
62
|
if (requires.uc) middleware.push(checkUseCase(requires.uc));
|
|
@@ -64,10 +65,10 @@ export class ExpressProvider implements AppProvider {
|
|
|
64
65
|
|
|
65
66
|
protected handle =
|
|
66
67
|
(endpoint: Endpoint, options?: VerbOptions): RequestHandler =>
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
(req: Request, res: Response, next: NextFunction) =>
|
|
69
|
+
endpoint(toReq(req))
|
|
70
|
+
.then((r: any) => this.toResponse(res, r, toVerbOptions(options)))
|
|
71
|
+
.catch(error => next(toOriginatedError(error, options)));
|
|
71
72
|
|
|
72
73
|
protected toResponse(res: Response, result: unknown, options: Required<VerbOptions>): void {
|
|
73
74
|
res.status(options.onOk.status);
|
|
@@ -2,7 +2,7 @@ import express, { Request, RequestHandler } from 'express';
|
|
|
2
2
|
import passport from 'passport';
|
|
3
3
|
import passportJwt, { ExtractJwt, Strategy as JwtStrategy, StrategyOptions } from 'passport-jwt';
|
|
4
4
|
import { authError } from './AuthError';
|
|
5
|
-
import { choose, ctx, HttpStatus, Scope, UseCase } from '@thisisagile/easy';
|
|
5
|
+
import { choose, ctx, Environment, HttpStatus, Scope, UseCase } from '@thisisagile/easy';
|
|
6
6
|
|
|
7
7
|
type SecretOrKeyProvider = (request: Request, rawJwtToken: any) => Promise<string | Buffer>;
|
|
8
8
|
|
|
@@ -28,6 +28,13 @@ export interface SecurityOptions {
|
|
|
28
28
|
};
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
export const checkLabCoat = (): RequestHandler => (req, res, next) =>
|
|
32
|
+
next(
|
|
33
|
+
choose(ctx.env.name)
|
|
34
|
+
.case(e => Environment.Dev.equals(e), undefined)
|
|
35
|
+
.else(authError(HttpStatus.Forbidden))
|
|
36
|
+
);
|
|
37
|
+
|
|
31
38
|
export const checkToken = (): RequestHandler => passport.authenticate('jwt', { session: false, failWithError: true });
|
|
32
39
|
|
|
33
40
|
export const checkScope =
|