api-machine 1.4.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/authentication/authenticated-request.d.ts +5 -0
- package/authentication/authentication-scheme.d.ts +3 -1
- package/authentication/authentication-scheme.js +32 -3
- package/authentication/authentication-scheme.js.map +1 -1
- package/authentication/index.d.ts +1 -1
- package/authentication/index.js.map +1 -1
- package/authentication/schemes/bearer-authentication-scheme.d.ts +5 -4
- package/authentication/schemes/bearer-authentication-scheme.js +3 -1
- package/authentication/schemes/bearer-authentication-scheme.js.map +1 -1
- package/authorization/authorization.d.ts +16 -0
- package/authorization/authorization.js +3 -0
- package/authorization/authorization.js.map +1 -0
- package/authorization/index.d.ts +1 -0
- package/authorization/index.js +5 -0
- package/authorization/index.js.map +1 -0
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/index.js.map +1 -1
- package/package.json +2 -1
- package/router/base.d.ts +10 -0
- package/router/base.js +32 -3
- package/router/base.js.map +1 -1
- package/router/endpoint.d.ts +3 -2
- package/router/endpoint.js +33 -0
- package/router/endpoint.js.map +1 -1
- package/router/endpoints/health-check-endpoint.js +2 -0
- package/router/endpoints/health-check-endpoint.js.map +1 -1
- package/router/index.d.ts +1 -0
- package/router/index.js +5 -1
- package/router/index.js.map +1 -1
- package/server/server-options.d.ts +7 -0
- package/server/server-options.js.map +1 -1
- package/server/server.d.ts +4 -0
- package/server/server.js +24 -0
- package/server/server.js.map +1 -1
- package/session/session.d.ts +2 -0
|
@@ -2,6 +2,7 @@ import { RequestHandler } from 'express';
|
|
|
2
2
|
import { SecuritySchemeObject, SecurityRequirementObject } from 'auto-oas/oas/v3.1';
|
|
3
3
|
import { ApiRequest, BaseApiRouter } from '../router';
|
|
4
4
|
import { SessionDriver } from '../session/session-driver';
|
|
5
|
+
import { AuthenticatedPrincipal, AuthenticatedRequest } from './authenticated-request';
|
|
5
6
|
import { AuthFlow } from './auth-flow';
|
|
6
7
|
import { ApiRoute } from '../router/base';
|
|
7
8
|
export interface AuthenticationSchemeOptions {
|
|
@@ -50,7 +51,7 @@ export declare abstract class InlineAuthenticationScheme extends AuthenticationS
|
|
|
50
51
|
abstract authenticate(options: {
|
|
51
52
|
credentials: unknown;
|
|
52
53
|
request: ApiRequest;
|
|
53
|
-
}): Promise<void>;
|
|
54
|
+
}): Promise<void | AuthenticatedPrincipal>;
|
|
54
55
|
/**
|
|
55
56
|
* Generate the Express middleware that enforces this authentication
|
|
56
57
|
* The middleware should validate the authentication and throw appropriate
|
|
@@ -87,4 +88,5 @@ export declare abstract class SessionAuthenticationScheme extends Authentication
|
|
|
87
88
|
*/
|
|
88
89
|
getAuthRouter(basePath?: string): BaseApiRouter;
|
|
89
90
|
getMiddleware(): RequestHandler;
|
|
91
|
+
protected getSessionId(request: AuthenticatedRequest): string | undefined;
|
|
90
92
|
}
|
|
@@ -44,8 +44,11 @@ class InlineAuthenticationScheme extends AuthenticationScheme {
|
|
|
44
44
|
getMiddleware() {
|
|
45
45
|
return async (request, response, next) => {
|
|
46
46
|
const credentials = this.getCredentials(request);
|
|
47
|
-
await this.authenticate({ credentials, request });
|
|
47
|
+
const principal = await this.authenticate({ credentials, request });
|
|
48
48
|
request.authenticated = true;
|
|
49
|
+
if (principal) {
|
|
50
|
+
request.principal = principal;
|
|
51
|
+
}
|
|
49
52
|
return next();
|
|
50
53
|
};
|
|
51
54
|
}
|
|
@@ -84,14 +87,40 @@ class SessionAuthenticationScheme extends AuthenticationScheme {
|
|
|
84
87
|
}
|
|
85
88
|
getMiddleware() {
|
|
86
89
|
return async (request, response, next) => {
|
|
90
|
+
const sessionId = this.getSessionId(request);
|
|
87
91
|
await this.sessionDriver.checkSession({
|
|
88
|
-
|
|
89
|
-
sessionId: request.sessionId,
|
|
92
|
+
sessionId,
|
|
90
93
|
});
|
|
94
|
+
const session = await this.sessionDriver.getSession({ sessionId });
|
|
91
95
|
request.authenticated = true;
|
|
96
|
+
if (session.principal) {
|
|
97
|
+
request.principal = session.principal;
|
|
98
|
+
}
|
|
92
99
|
return next();
|
|
93
100
|
};
|
|
94
101
|
}
|
|
102
|
+
getSessionId(request) {
|
|
103
|
+
if (request.sessionId) {
|
|
104
|
+
return request.sessionId;
|
|
105
|
+
}
|
|
106
|
+
const cookieHeader = request.headers?.cookie;
|
|
107
|
+
if (!cookieHeader) {
|
|
108
|
+
return undefined;
|
|
109
|
+
}
|
|
110
|
+
const sessionCookie = cookieHeader
|
|
111
|
+
.split(';')
|
|
112
|
+
.map((cookie) => cookie.trim())
|
|
113
|
+
.find((cookie) => cookie.startsWith('sessionId='));
|
|
114
|
+
if (!sessionCookie) {
|
|
115
|
+
return undefined;
|
|
116
|
+
}
|
|
117
|
+
try {
|
|
118
|
+
return decodeURIComponent(sessionCookie.slice('sessionId='.length));
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
return undefined;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
95
124
|
}
|
|
96
125
|
exports.SessionAuthenticationScheme = SessionAuthenticationScheme;
|
|
97
126
|
//# sourceMappingURL=authentication-scheme.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authentication-scheme.js","sourceRoot":"","sources":["../../../src/authentication/authentication-scheme.ts"],"names":[],"mappings":";;;AAKA,sCAKmB;AAEnB,oCAAgD;
|
|
1
|
+
{"version":3,"file":"authentication-scheme.js","sourceRoot":"","sources":["../../../src/authentication/authentication-scheme.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { AuthenticatedRequest } from './authenticated-request';
|
|
1
|
+
export { AuthenticatedPrincipal, AuthenticatedRequest, } from './authenticated-request';
|
|
2
2
|
export { AuthenticationScheme, InlineAuthenticationScheme, SessionAuthenticationScheme, throwIfAuthenticationBlocked, AuthenticationProtectionResult, } from './authentication-scheme';
|
|
3
3
|
export { AuthFlow } from './auth-flow';
|
|
4
4
|
export * from './schemes';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/authentication/index.ts"],"names":[],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/authentication/index.ts"],"names":[],"mappings":";;;;AAIA,iEAMiC;AALhC,6HAAA,oBAAoB,OAAA;AACpB,mIAAA,0BAA0B,OAAA;AAC1B,oIAAA,2BAA2B,OAAA;AAC3B,qIAAA,4BAA4B,OAAA;AAI7B,oDAA0B"}
|
|
@@ -2,7 +2,8 @@ import { AuthenticationSchemeOptions, InlineAuthenticationScheme } from '../auth
|
|
|
2
2
|
import { SecuritySchemeObject } from 'auto-oas/oas/v3.1';
|
|
3
3
|
import { LogInterface } from '../../log';
|
|
4
4
|
import { ApiRequest } from '../../router';
|
|
5
|
-
|
|
5
|
+
import { AuthenticatedPrincipal } from '../authenticated-request';
|
|
6
|
+
export type CheckTokenFunction = (token: string) => Promise<boolean | AuthenticatedPrincipal>;
|
|
6
7
|
export interface BearerAuthenticationSchemeOptions extends AuthenticationSchemeOptions {
|
|
7
8
|
/**
|
|
8
9
|
* The name of the security scheme in OpenAPI
|
|
@@ -21,8 +22,8 @@ export interface BearerAuthenticationSchemeOptions extends AuthenticationSchemeO
|
|
|
21
22
|
*/
|
|
22
23
|
description?: string;
|
|
23
24
|
/**
|
|
24
|
-
*
|
|
25
|
-
*
|
|
25
|
+
* Validate a bearer token and optionally return the authenticated
|
|
26
|
+
* principal.
|
|
26
27
|
*/
|
|
27
28
|
checkToken: CheckTokenFunction;
|
|
28
29
|
/**
|
|
@@ -47,5 +48,5 @@ export declare class BearerAuthenticationScheme extends InlineAuthenticationSche
|
|
|
47
48
|
authenticate(options: {
|
|
48
49
|
credentials: string;
|
|
49
50
|
request: ApiRequest;
|
|
50
|
-
}): Promise<void>;
|
|
51
|
+
}): Promise<void | AuthenticatedPrincipal>;
|
|
51
52
|
}
|
|
@@ -67,7 +67,8 @@ class BearerAuthenticationScheme extends authentication_scheme_1.InlineAuthentic
|
|
|
67
67
|
details: validationResult.errors,
|
|
68
68
|
});
|
|
69
69
|
}
|
|
70
|
-
|
|
70
|
+
const tokenResult = await this.checkToken(validationResult.data);
|
|
71
|
+
if (!tokenResult) {
|
|
71
72
|
// eslint-disable-next-line max-len
|
|
72
73
|
const msg = 'Unauthorized access attempt from ' +
|
|
73
74
|
request.ip +
|
|
@@ -77,6 +78,7 @@ class BearerAuthenticationScheme extends authentication_scheme_1.InlineAuthentic
|
|
|
77
78
|
scheme: 'Bearer',
|
|
78
79
|
});
|
|
79
80
|
}
|
|
81
|
+
return typeof tokenResult === 'object' ? tokenResult : undefined;
|
|
80
82
|
}
|
|
81
83
|
}
|
|
82
84
|
exports.BearerAuthenticationScheme = BearerAuthenticationScheme;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bearer-authentication-scheme.js","sourceRoot":"","sources":["../../../../src/authentication/schemes/bearer-authentication-scheme.ts"],"names":[],"mappings":";;;AAAA,oEAGkC;AAElC,uCAAgD;AAChD,kDAAsD;
|
|
1
|
+
{"version":3,"file":"bearer-authentication-scheme.js","sourceRoot":"","sources":["../../../../src/authentication/schemes/bearer-authentication-scheme.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { AuthenticatedPrincipal } from '../authentication/authenticated-request';
|
|
2
|
+
export interface AuthorizationRequirement {
|
|
3
|
+
action: string;
|
|
4
|
+
resource?: string | Record<string, unknown>;
|
|
5
|
+
metadata?: Record<string, unknown>;
|
|
6
|
+
}
|
|
7
|
+
export interface AuthorizationContext extends AuthorizationRequirement {
|
|
8
|
+
principal: AuthenticatedPrincipal;
|
|
9
|
+
}
|
|
10
|
+
export interface AuthorizationResult {
|
|
11
|
+
allowed: boolean;
|
|
12
|
+
reason?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface ApiAuthorizationService {
|
|
15
|
+
evaluate(context: AuthorizationContext): Promise<AuthorizationResult>;
|
|
16
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authorization.js","sourceRoot":"","sources":["../../../src/authorization/authorization.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './authorization';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/authorization/index.ts"],"names":[],"mappings":";;;AAAA,0DAAgC"}
|
package/index.d.ts
CHANGED
package/index.js
CHANGED
|
@@ -5,5 +5,6 @@ tslib_1.__exportStar(require("./router"), exports);
|
|
|
5
5
|
tslib_1.__exportStar(require("./server"), exports);
|
|
6
6
|
tslib_1.__exportStar(require("./error"), exports);
|
|
7
7
|
tslib_1.__exportStar(require("./authentication"), exports);
|
|
8
|
+
tslib_1.__exportStar(require("./authorization"), exports);
|
|
8
9
|
tslib_1.__exportStar(require("./session"), exports);
|
|
9
10
|
//# sourceMappingURL=index.js.map
|
package/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA,mDAAyB;AACzB,mDAAyB;AACzB,kDAAwB;AACxB,2DAAiC;AACjC,oDAA0B"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA,mDAAyB;AACzB,mDAAyB;AACzB,kDAAwB;AACxB,2DAAiC;AACjC,0DAAgC;AAChC,oDAA0B"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "api-machine",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "api-machine",
|
|
5
5
|
"typescript-template": {
|
|
6
6
|
"base": "1.0.1",
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
},
|
|
10
10
|
"scripts": {},
|
|
11
11
|
"dependencies": {
|
|
12
|
+
"@types/express": "^5.0.5",
|
|
12
13
|
"auto-oas": "^1.3.0",
|
|
13
14
|
"cors": "^2.8.5",
|
|
14
15
|
"express": "^5.1.0",
|
package/router/base.d.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { Router as ExpressRouter, RequestHandler } from 'express';
|
|
2
2
|
import { AuthenticationScheme } from '../authentication/authentication-scheme';
|
|
3
3
|
import { DependencyContainer } from 'hidi';
|
|
4
|
+
import { AuthenticatedRequest } from '../authentication/authenticated-request';
|
|
5
|
+
import { ApiAuthorizationService, AuthorizationRequirement } from '../authorization';
|
|
6
|
+
export declare const AUTHENTICATION_KEY = "api-machine.authn";
|
|
7
|
+
export declare const AUTHORIZATION_KEY = "api-machine.authz";
|
|
8
|
+
export declare const AUTHORIZATION_REQUIREMENT_KEY = "api-machine.authorization-requirement";
|
|
4
9
|
export declare abstract class BaseApiRoute {
|
|
5
10
|
path: string;
|
|
6
11
|
fullPath: string;
|
|
@@ -21,6 +26,8 @@ export declare abstract class BaseApiRoute {
|
|
|
21
26
|
* If undefined, inherits from parent router or server
|
|
22
27
|
*/
|
|
23
28
|
authentication?: AuthenticationScheme | null;
|
|
29
|
+
authorizer?: ApiAuthorizationService | null;
|
|
30
|
+
authorization?: AuthorizationRequirement | null;
|
|
24
31
|
/**
|
|
25
32
|
* Parent route in the hierarchy (used for authentication cascading)
|
|
26
33
|
* @internal
|
|
@@ -36,5 +43,8 @@ export declare abstract class BaseApiRoute {
|
|
|
36
43
|
* @returns The authentication scheme to use, or undefined if public
|
|
37
44
|
*/
|
|
38
45
|
getEffectiveAuthentication(): AuthenticationScheme | undefined | null;
|
|
46
|
+
getEffectiveAuthorizationService(): ApiAuthorizationService | undefined | null;
|
|
47
|
+
getEffectiveAuthorizationRequirement(): AuthorizationRequirement | undefined | null;
|
|
48
|
+
logAuthorization(level: 'info' | 'warn' | 'error', event: string, request: AuthenticatedRequest, context?: Record<string, unknown>): void;
|
|
39
49
|
}
|
|
40
50
|
export type ApiRoute = new (...params: ConstructorParameters<typeof BaseApiRoute>) => BaseApiRoute;
|
package/router/base.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.BaseApiRoute = void 0;
|
|
3
|
+
exports.BaseApiRoute = exports.AUTHORIZATION_REQUIREMENT_KEY = exports.AUTHORIZATION_KEY = exports.AUTHENTICATION_KEY = void 0;
|
|
4
4
|
const hidi_1 = require("hidi");
|
|
5
|
+
exports.AUTHENTICATION_KEY = 'api-machine.authn';
|
|
6
|
+
exports.AUTHORIZATION_KEY = 'api-machine.authz';
|
|
7
|
+
exports.AUTHORIZATION_REQUIREMENT_KEY = 'api-machine.authorization-requirement';
|
|
5
8
|
class BaseApiRoute {
|
|
6
9
|
path;
|
|
7
10
|
fullPath;
|
|
@@ -22,6 +25,8 @@ class BaseApiRoute {
|
|
|
22
25
|
* If undefined, inherits from parent router or server
|
|
23
26
|
*/
|
|
24
27
|
authentication;
|
|
28
|
+
authorizer;
|
|
29
|
+
authorization;
|
|
25
30
|
/**
|
|
26
31
|
* Parent route in the hierarchy (used for authentication cascading)
|
|
27
32
|
* @internal
|
|
@@ -30,7 +35,13 @@ class BaseApiRoute {
|
|
|
30
35
|
parentRoute;
|
|
31
36
|
async register(_parentRouter, _parentPath) {
|
|
32
37
|
if (this.authentication !== undefined) {
|
|
33
|
-
this.container.register(
|
|
38
|
+
this.container.register(exports.AUTHENTICATION_KEY, this.authentication);
|
|
39
|
+
}
|
|
40
|
+
if (this.authorizer !== undefined) {
|
|
41
|
+
this.container.register(exports.AUTHORIZATION_KEY, this.authorizer);
|
|
42
|
+
}
|
|
43
|
+
if (this.authorization !== undefined) {
|
|
44
|
+
this.container.register(exports.AUTHORIZATION_REQUIREMENT_KEY, this.authorization);
|
|
34
45
|
}
|
|
35
46
|
this.inject();
|
|
36
47
|
}
|
|
@@ -58,7 +69,25 @@ class BaseApiRoute {
|
|
|
58
69
|
* @returns The authentication scheme to use, or undefined if public
|
|
59
70
|
*/
|
|
60
71
|
getEffectiveAuthentication() {
|
|
61
|
-
return this.container.get(
|
|
72
|
+
return this.container.get(exports.AUTHENTICATION_KEY);
|
|
73
|
+
}
|
|
74
|
+
getEffectiveAuthorizationService() {
|
|
75
|
+
return this.container.get(exports.AUTHORIZATION_KEY);
|
|
76
|
+
}
|
|
77
|
+
getEffectiveAuthorizationRequirement() {
|
|
78
|
+
return this.container.get(exports.AUTHORIZATION_REQUIREMENT_KEY);
|
|
79
|
+
}
|
|
80
|
+
logAuthorization(level, event, request, context = {}) {
|
|
81
|
+
const logger = this.container.get('log');
|
|
82
|
+
if (logger) {
|
|
83
|
+
logger[level](event, {
|
|
84
|
+
...context,
|
|
85
|
+
principalId: request.principal?.id,
|
|
86
|
+
method: request.method,
|
|
87
|
+
path: request.originalUrl,
|
|
88
|
+
requestId: request.headers?.['x-request-id'],
|
|
89
|
+
});
|
|
90
|
+
}
|
|
62
91
|
}
|
|
63
92
|
}
|
|
64
93
|
exports.BaseApiRoute = BaseApiRoute;
|
package/router/base.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../../src/router/base.ts"],"names":[],"mappings":";;;AAEA,+BAA2C;
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../../src/router/base.ts"],"names":[],"mappings":"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"}
|
package/router/endpoint.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { Router as ExpressRouter,
|
|
1
|
+
import { Router as ExpressRouter, Response as ExpressResponse, NextFunction as ExpressNextFunction } from 'express';
|
|
2
2
|
import { ObjectSanitizer } from 'valsan/object-sanitizer';
|
|
3
3
|
import { BaseApiRoute } from './base';
|
|
4
4
|
import { HTTPError } from '../error';
|
|
5
5
|
import { ArrayValSan, ObjectValSan } from 'valsan';
|
|
6
|
-
|
|
6
|
+
import { AuthenticatedRequest } from '../authentication/authenticated-request';
|
|
7
|
+
export type ApiRequest = AuthenticatedRequest;
|
|
7
8
|
export type ApiResponse = ExpressResponse;
|
|
8
9
|
export type ApiNextFunction = ExpressNextFunction;
|
|
9
10
|
export type ApiResponseData = {
|
package/router/endpoint.js
CHANGED
|
@@ -57,6 +57,39 @@ class BaseApiEndpoint extends base_1.BaseApiRoute {
|
|
|
57
57
|
if (effectiveAuth) {
|
|
58
58
|
endpointMiddleware.push(effectiveAuth.getMiddleware());
|
|
59
59
|
}
|
|
60
|
+
const authorization = this.getEffectiveAuthorizationRequirement();
|
|
61
|
+
if (authorization) {
|
|
62
|
+
const authorizer = this.getEffectiveAuthorizationService();
|
|
63
|
+
if (!authorizer) {
|
|
64
|
+
throw new Error('Authorization is configured but no authorizer is available');
|
|
65
|
+
}
|
|
66
|
+
endpointMiddleware.push(async (request, _response, next) => {
|
|
67
|
+
const principal = request.principal;
|
|
68
|
+
if (!principal) {
|
|
69
|
+
this.logAuthorization('warn', 'authorization.missing-principal', request);
|
|
70
|
+
throw new error_1.UnauthorizedError('An authenticated principal is required');
|
|
71
|
+
}
|
|
72
|
+
let result;
|
|
73
|
+
try {
|
|
74
|
+
result = await authorizer.evaluate({
|
|
75
|
+
...authorization,
|
|
76
|
+
principal,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
this.logAuthorization('error', 'authorization.error', request, { ...authorization, error });
|
|
81
|
+
throw error;
|
|
82
|
+
}
|
|
83
|
+
if (!result.allowed) {
|
|
84
|
+
this.logAuthorization('warn', 'authorization.denied', request, { ...authorization, reason: result.reason });
|
|
85
|
+
throw new error_1.ForbiddenError(result.reason || 'Authorization denied');
|
|
86
|
+
}
|
|
87
|
+
this.logAuthorization('info', 'authorization.allowed', request, {
|
|
88
|
+
...authorization,
|
|
89
|
+
});
|
|
90
|
+
return next();
|
|
91
|
+
});
|
|
92
|
+
}
|
|
60
93
|
// Register with middleware (if any) before the handler
|
|
61
94
|
if (endpointMiddleware.length > 0) {
|
|
62
95
|
parentRouter[this.method](this.path, ...endpointMiddleware, this.handleWrapper.bind(this));
|
package/router/endpoint.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"endpoint.js","sourceRoot":"","sources":["../../../src/router/endpoint.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"endpoint.js","sourceRoot":"","sources":["../../../src/router/endpoint.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,8 @@ const valsan_1 = require("valsan");
|
|
|
5
5
|
const get_endpoint_1 = require("./get-endpoint");
|
|
6
6
|
class HealthCheckEndpoint extends get_endpoint_1.GetEndpoint {
|
|
7
7
|
path = '/health';
|
|
8
|
+
// override authentication = null;
|
|
9
|
+
// override authorization = null;
|
|
8
10
|
responseExample = {
|
|
9
11
|
status: 'ok',
|
|
10
12
|
timestamp: new Date().toISOString(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"health-check-endpoint.js","sourceRoot":"","sources":["../../../../src/router/endpoints/health-check-endpoint.ts"],"names":[],"mappings":";;;AAAA,mCAKgB;AAChB,iDAA6C;AAE7C,MAAa,mBAAoB,SAAQ,0BAAW;IAC1C,IAAI,GAAG,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"health-check-endpoint.js","sourceRoot":"","sources":["../../../../src/router/endpoints/health-check-endpoint.ts"],"names":[],"mappings":";;;AAAA,mCAKgB;AAChB,iDAA6C;AAE7C,MAAa,mBAAoB,SAAQ,0BAAW;IAC1C,IAAI,GAAG,SAAS,CAAC;IAC1B,kCAAkC;IAClC,iCAAiC;IAExB,eAAe,GAAG;QAC1B,MAAM,EAAE,IAAI;QACZ,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,MAAM,EAAE,KAAK;QACb,WAAW,EAAE,aAAa;KAC1B,CAAC;IAEO,QAAQ,GAAG,IAAI,qBAAY,CAAC;QACpC,MAAM,EAAE;YACP,MAAM,EAAE,IAAI,2BAAkB,EAAE;YAChC,SAAS,EAAE,IAAI,+BAAsB,EAAE;YACvC,MAAM,EAAE,IAAI,6BAAoB,EAAE;YAClC,WAAW,EAAE,IAAI,2BAAkB,EAAE;SACrC;KACD,CAAC,CAAC;IAEH,KAAK,CAAC,MAAM;QACX,OAAO;YACN,MAAM,EAAE,MAAM,IAAI,CAAC,SAAS,EAAE;YAC9B,SAAS,EAAE,MAAM,IAAI,CAAC,YAAY,EAAE;YACpC,MAAM,EAAE,MAAM,IAAI,CAAC,SAAS,EAAE;YAC9B,WAAW,EAAE,MAAM,IAAI,CAAC,cAAc,EAAE;SACxC,CAAC;IACH,CAAC;IAEM,KAAK,CAAC,SAAS;QACrB,OAAO,IAAI,CAAC;IACb,CAAC;IAEM,KAAK,CAAC,YAAY;QACxB,OAAO,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACjC,CAAC;IAEM,KAAK,CAAC,SAAS;QACrB,OAAO,OAAO,CAAC,MAAM,EAAE,CAAC;IACzB,CAAC;IAEM,KAAK,CAAC,cAAc;QAC1B,OAAO,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,aAAa,CAAC;IACjD,CAAC;CACD;AA7CD,kDA6CC"}
|
package/router/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export { ApiEndpoint, ApiRequest, ApiResponse, ApiNextFunction, BaseApiEndpoint, } from './endpoint';
|
|
2
2
|
export { ApiRouter, BaseApiRouter } from './router';
|
|
3
|
+
export { AUTHENTICATION_KEY, AUTHORIZATION_KEY, AUTHORIZATION_REQUIREMENT_KEY, } from './base';
|
|
3
4
|
export { GetEndpoint, PostEndpoint, PutEndpoint, DeleteEndpoint, PatchEndpoint, HealthCheckEndpoint, } from './endpoints';
|
package/router/index.js
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.HealthCheckEndpoint = exports.PatchEndpoint = exports.DeleteEndpoint = exports.PutEndpoint = exports.PostEndpoint = exports.GetEndpoint = exports.BaseApiRouter = exports.BaseApiEndpoint = void 0;
|
|
3
|
+
exports.HealthCheckEndpoint = exports.PatchEndpoint = exports.DeleteEndpoint = exports.PutEndpoint = exports.PostEndpoint = exports.GetEndpoint = exports.AUTHORIZATION_REQUIREMENT_KEY = exports.AUTHORIZATION_KEY = exports.AUTHENTICATION_KEY = exports.BaseApiRouter = exports.BaseApiEndpoint = void 0;
|
|
4
4
|
var endpoint_1 = require("./endpoint");
|
|
5
5
|
Object.defineProperty(exports, "BaseApiEndpoint", { enumerable: true, get: function () { return endpoint_1.BaseApiEndpoint; } });
|
|
6
6
|
var router_1 = require("./router");
|
|
7
7
|
Object.defineProperty(exports, "BaseApiRouter", { enumerable: true, get: function () { return router_1.BaseApiRouter; } });
|
|
8
|
+
var base_1 = require("./base");
|
|
9
|
+
Object.defineProperty(exports, "AUTHENTICATION_KEY", { enumerable: true, get: function () { return base_1.AUTHENTICATION_KEY; } });
|
|
10
|
+
Object.defineProperty(exports, "AUTHORIZATION_KEY", { enumerable: true, get: function () { return base_1.AUTHORIZATION_KEY; } });
|
|
11
|
+
Object.defineProperty(exports, "AUTHORIZATION_REQUIREMENT_KEY", { enumerable: true, get: function () { return base_1.AUTHORIZATION_REQUIREMENT_KEY; } });
|
|
8
12
|
var endpoints_1 = require("./endpoints");
|
|
9
13
|
Object.defineProperty(exports, "GetEndpoint", { enumerable: true, get: function () { return endpoints_1.GetEndpoint; } });
|
|
10
14
|
Object.defineProperty(exports, "PostEndpoint", { enumerable: true, get: function () { return endpoints_1.PostEndpoint; } });
|
package/router/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/router/index.ts"],"names":[],"mappings":";;;AAAA,uCAMoB;AADnB,2GAAA,eAAe,OAAA;AAGhB,mCAAoD;AAAhC,uGAAA,aAAa,OAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/router/index.ts"],"names":[],"mappings":";;;AAAA,uCAMoB;AADnB,2GAAA,eAAe,OAAA;AAGhB,mCAAoD;AAAhC,uGAAA,aAAa,OAAA;AACjC,+BAIgB;AAHf,0GAAA,kBAAkB,OAAA;AAClB,yGAAA,iBAAiB,OAAA;AACjB,qHAAA,6BAA6B,OAAA;AAG9B,yCAOqB;AANpB,wGAAA,WAAW,OAAA;AACX,yGAAA,YAAY,OAAA;AACZ,wGAAA,WAAW,OAAA;AACX,2GAAA,cAAc,OAAA;AACd,0GAAA,aAAa,OAAA;AACb,gHAAA,mBAAmB,OAAA"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { LogInterface } from '../log';
|
|
2
2
|
import { AuthenticationScheme } from '../authentication/authentication-scheme';
|
|
3
|
+
import { ApiAuthorizationService } from '../authorization';
|
|
3
4
|
export interface SecurityHeadersOptions {
|
|
4
5
|
/**
|
|
5
6
|
* Disable the X-Powered-By header to prevent server fingerprinting
|
|
@@ -41,6 +42,12 @@ export interface RestServerOptions {
|
|
|
41
42
|
* This will be applied to all routers and endpoints unless overridden
|
|
42
43
|
*/
|
|
43
44
|
authentication?: AuthenticationScheme;
|
|
45
|
+
authorizer?: ApiAuthorizationService;
|
|
46
|
+
/**
|
|
47
|
+
* Fail startup if any endpoint has no effective authentication scheme.
|
|
48
|
+
* Explicitly public endpoints (`authentication = null`) are allowed.
|
|
49
|
+
*/
|
|
50
|
+
requireAuthentication?: boolean;
|
|
44
51
|
}
|
|
45
52
|
export declare const defaultSecurityHeadersOptions: SecurityHeadersOptions;
|
|
46
53
|
export declare const defaultRestServerOptions: RestServerOptions;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-options.js","sourceRoot":"","sources":["../../../src/server/server-options.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"server-options.js","sourceRoot":"","sources":["../../../src/server/server-options.ts"],"names":[],"mappings":";;;AA2Da,QAAA,6BAA6B,GAA2B;IACpE,iBAAiB,EAAE,IAAI;IACvB,OAAO,EAAE,IAAI;IACb,YAAY,EAAE,MAAM;IACpB,aAAa,EAAE,IAAI;IACnB,IAAI,EAAE,KAAK,EAAE,+CAA+C;CAC5D,CAAC;AAEW,QAAA,wBAAwB,GAAsB;IAC1D,IAAI,EAAE,IAAI;IACV,gBAAgB,EAAE,EAAE;IACpB,mBAAmB,EAAE,CAAC;IACtB,GAAG,EAAE;QACJ,GAAG,OAAO;QACV,sCAAsC;QACtC,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,sCAAsC;QACtC,IAAI,EAAE,OAAO,CAAC,GAAG;KACjB;IACD,eAAe,EAAE,qCAA6B;CAC9C,CAAC"}
|
package/server/server.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import http from 'http';
|
|
|
4
4
|
import { DependencyContainer } from 'hidi';
|
|
5
5
|
import { RestServerOptions } from './server-options';
|
|
6
6
|
import { ApiRouter, BaseApiRouter } from '../router';
|
|
7
|
+
import { BaseApiRoute } from '../router/base';
|
|
7
8
|
import { AuthenticationScheme } from '../authentication/authentication-scheme';
|
|
8
9
|
import { LogInterface } from '../log';
|
|
9
10
|
export declare abstract class RestServer {
|
|
@@ -22,6 +23,8 @@ export declare abstract class RestServer {
|
|
|
22
23
|
readonly securityHeaders: RestServerOptions['securityHeaders'];
|
|
23
24
|
swaggerEnabled: boolean;
|
|
24
25
|
authentication?: AuthenticationScheme;
|
|
26
|
+
authorizer?: RestServerOptions['authorizer'];
|
|
27
|
+
requireAuthentication: boolean;
|
|
25
28
|
protected app: express.Express;
|
|
26
29
|
protected listener: http.Server;
|
|
27
30
|
protected log: LogInterface;
|
|
@@ -32,6 +35,7 @@ export declare abstract class RestServer {
|
|
|
32
35
|
protected createRouter(): Promise<void>;
|
|
33
36
|
protected registerAuthentication(): Promise<void>;
|
|
34
37
|
protected registerRoutes(): Promise<void>;
|
|
38
|
+
protected validateAuthenticationCoverage(route: BaseApiRoute): void;
|
|
35
39
|
protected registerSwagger(): Promise<void>;
|
|
36
40
|
protected setupExpress(): Promise<void>;
|
|
37
41
|
protected setupSecurityHeaders(): Promise<void>;
|
package/server/server.js
CHANGED
|
@@ -6,6 +6,8 @@ const express_1 = tslib_1.__importDefault(require("express"));
|
|
|
6
6
|
const cors_1 = tslib_1.__importDefault(require("cors"));
|
|
7
7
|
const hidi_1 = require("hidi");
|
|
8
8
|
const server_options_1 = require("./server-options");
|
|
9
|
+
const router_1 = require("../router");
|
|
10
|
+
const base_1 = require("../router/base");
|
|
9
11
|
const error_1 = require("../error");
|
|
10
12
|
const routes_1 = require("../oas/routes");
|
|
11
13
|
class RestServer {
|
|
@@ -24,6 +26,8 @@ class RestServer {
|
|
|
24
26
|
securityHeaders;
|
|
25
27
|
swaggerEnabled = false;
|
|
26
28
|
authentication;
|
|
29
|
+
authorizer;
|
|
30
|
+
requireAuthentication;
|
|
27
31
|
app;
|
|
28
32
|
listener;
|
|
29
33
|
log;
|
|
@@ -33,15 +37,21 @@ class RestServer {
|
|
|
33
37
|
this.maxPayloadSizeMB = options.maxPayloadSizeMB;
|
|
34
38
|
this.maxUrlEncodedSizeMB = options.maxUrlEncodedSizeMB;
|
|
35
39
|
this.log = options.log;
|
|
40
|
+
this.container.register('log', this.log);
|
|
36
41
|
this.securityHeaders = {
|
|
37
42
|
...server_options_1.defaultRestServerOptions.securityHeaders,
|
|
38
43
|
...options.securityHeaders,
|
|
39
44
|
};
|
|
40
45
|
this.swaggerEnabled = options.swaggerEnabled ?? false;
|
|
41
46
|
this.authentication = options.authentication;
|
|
47
|
+
this.authorizer = options.authorizer;
|
|
48
|
+
this.requireAuthentication = options.requireAuthentication ?? false;
|
|
42
49
|
}
|
|
43
50
|
async start() {
|
|
44
51
|
await this.inject();
|
|
52
|
+
if (this.authorizer !== undefined) {
|
|
53
|
+
this.container.register(base_1.AUTHORIZATION_KEY, this.authorizer);
|
|
54
|
+
}
|
|
45
55
|
await this.setupExpress();
|
|
46
56
|
await this.createRouter();
|
|
47
57
|
await this.registerAuthentication();
|
|
@@ -72,6 +82,20 @@ class RestServer {
|
|
|
72
82
|
}
|
|
73
83
|
async registerRoutes() {
|
|
74
84
|
await this.routerInstance.register(this.app, '');
|
|
85
|
+
if (this.requireAuthentication) {
|
|
86
|
+
this.validateAuthenticationCoverage(this.routerInstance);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
validateAuthenticationCoverage(route) {
|
|
90
|
+
if (route.routeType === 'endpoint' &&
|
|
91
|
+
route.getEffectiveAuthentication() === undefined) {
|
|
92
|
+
throw new Error(`Authentication is required but missing for ${route.fullPath}`);
|
|
93
|
+
}
|
|
94
|
+
if (route instanceof router_1.BaseApiRouter) {
|
|
95
|
+
for (const child of route.registeredRoutes) {
|
|
96
|
+
this.validateAuthenticationCoverage(child);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
75
99
|
}
|
|
76
100
|
async registerSwagger() {
|
|
77
101
|
if (this.swaggerEnabled) {
|
package/server/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/server/server.ts"],"names":[],"mappings":";;;;AAAA,8DAA8B;AAC9B,wDAAwB;AAExB,+BAA2C;AAE3C,qDAA+E;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/server/server.ts"],"names":[],"mappings":"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"}
|