node-server-engine 1.4.9 → 1.5.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/.commitlintrc.js +27 -0
- package/.releaserc.js +56 -0
- package/README.md +154 -2
- package/dist/const/tokenIssuer.js +1 -0
- package/dist/const/tokenIssuer.js.map +1 -1
- package/dist/db/models/SequelizeMeta.js +3 -1
- package/dist/db/models/SequelizeMeta.js.map +1 -1
- package/dist/entities/ElasticSearch/ElasticSearch.js +1 -2
- package/dist/entities/ElasticSearch/ElasticSearch.js.map +1 -1
- package/dist/entities/SocketClient/SocketClient.js +1 -0
- package/dist/entities/SocketClient/SocketClient.js.map +1 -1
- package/dist/index.js +1 -2
- package/dist/index.js.map +1 -1
- package/dist/middleware/checkPermission/checkPermission.d.ts +1 -1
- package/dist/middleware/checkPermission/checkPermission.js +4 -2
- package/dist/middleware/checkPermission/checkPermission.js.map +1 -1
- package/dist/utils/jwt/jwt.js +1 -1
- package/dist/utils/jwt/jwt.js.map +1 -1
- package/dist/utils/semverCompare/semverCompare.js +1 -5
- package/dist/utils/semverCompare/semverCompare.js.map +1 -1
- package/package.json +30 -19
- package/.env.example +0 -186
- package/.github/workflows/publish.yml +0 -41
- package/.prettierrc +0 -7
- package/Dockerfile +0 -31
- package/babel.config.json +0 -34
- package/eslint.config.mjs +0 -11
- package/src/const/DebeziumEvent.ts +0 -6
- package/src/const/LogSeverity.ts +0 -7
- package/src/const/index.ts +0 -5
- package/src/const/metrics.ts +0 -6
- package/src/const/mime.ts +0 -37
- package/src/const/tokenIssuer.ts +0 -7
- package/src/db/migrations/20241030121500-create-sequelize-meta-table.ts +0 -29
- package/src/db/models/SequelizeMeta.ts +0 -16
- package/src/db/models/index.ts +0 -2
- package/src/entities/ElasticSearch/ElasticSearch.ts +0 -103
- package/src/entities/ElasticSearch/ElasticSearch.types.ts +0 -7
- package/src/entities/ElasticSearch/index.ts +0 -2
- package/src/entities/Endpoint/Endpoint.test.ts +0 -248
- package/src/entities/Endpoint/Endpoint.ts +0 -221
- package/src/entities/Endpoint/Endpoint.types.ts +0 -181
- package/src/entities/Endpoint/index.ts +0 -2
- package/src/entities/EngineError/EngineError.ts +0 -28
- package/src/entities/EngineError/EngineError.types.ts +0 -15
- package/src/entities/EngineError/index.ts +0 -2
- package/src/entities/KeySet/KeySet.test.ts +0 -126
- package/src/entities/KeySet/KeySet.ts +0 -172
- package/src/entities/KeySet/KeySet.types.ts +0 -28
- package/src/entities/KeySet/index.ts +0 -2
- package/src/entities/LifecycleController/LifecycleController.test.ts +0 -48
- package/src/entities/LifecycleController/LifecycleController.ts +0 -24
- package/src/entities/LifecycleController/LifecycleController.types.ts +0 -5
- package/src/entities/LifecycleController/index.ts +0 -2
- package/src/entities/Localizator/Localizator.ts +0 -139
- package/src/entities/Localizator/Localizator.types.ts +0 -52
- package/src/entities/Localizator/guessNamingConvention/guessNamingConvention.test.ts +0 -165
- package/src/entities/Localizator/guessNamingConvention/guessNamingConvention.ts +0 -58
- package/src/entities/Localizator/guessNamingConvention/index.ts +0 -1
- package/src/entities/Localizator/index.ts +0 -2
- package/src/entities/MessageHandler/MessageHandler.test.ts +0 -130
- package/src/entities/MessageHandler/MessageHandler.ts +0 -72
- package/src/entities/MessageHandler/MessageHandler.types.ts +0 -15
- package/src/entities/MessageHandler/index.ts +0 -2
- package/src/entities/PubSub/PubSub.test.ts +0 -297
- package/src/entities/PubSub/PubSub.ts +0 -202
- package/src/entities/PubSub/PubSub.types.ts +0 -76
- package/src/entities/PubSub/handleMessage/handleMessage.test.ts +0 -102
- package/src/entities/PubSub/handleMessage/handleMessage.ts +0 -65
- package/src/entities/PubSub/handleMessage/index.ts +0 -1
- package/src/entities/PubSub/index.ts +0 -2
- package/src/entities/PushNotification/PushNotification.test.ts +0 -35
- package/src/entities/PushNotification/PushNotification.ts +0 -44
- package/src/entities/PushNotification/PushNotification.types.ts +0 -25
- package/src/entities/PushNotification/index.ts +0 -2
- package/src/entities/Redis/Redis.ts +0 -71
- package/src/entities/Redis/Redis.types.ts +0 -19
- package/src/entities/Redis/Redis.validate.ts +0 -17
- package/src/entities/Redis/index.ts +0 -2
- package/src/entities/Sequelize/Sequelize.config.ts +0 -59
- package/src/entities/Sequelize/Sequelize.test.ts +0 -21
- package/src/entities/Sequelize/Sequelize.ts +0 -75
- package/src/entities/Sequelize/Sequelize.types.ts +0 -10
- package/src/entities/Sequelize/Sequelize.validate.ts +0 -15
- package/src/entities/Sequelize/index.ts +0 -2
- package/src/entities/Server/Server.const.ts +0 -56
- package/src/entities/Server/Server.test.ts +0 -272
- package/src/entities/Server/Server.ts +0 -471
- package/src/entities/Server/Server.types.ts +0 -88
- package/src/entities/Server/index.ts +0 -2
- package/src/entities/SocketClient/SocketClient.test.ts +0 -392
- package/src/entities/SocketClient/SocketClient.ts +0 -401
- package/src/entities/SocketClient/SocketClient.types.ts +0 -62
- package/src/entities/SocketClient/index.ts +0 -2
- package/src/entities/SocketClient/parseMessage/index.ts +0 -1
- package/src/entities/SocketClient/parseMessage/parseMessage.test.ts +0 -20
- package/src/entities/SocketClient/parseMessage/parseMessage.ts +0 -26
- package/src/entities/Storage/Storage.test.ts +0 -58
- package/src/entities/Storage/Storage.ts +0 -219
- package/src/entities/Storage/Storage.types.ts +0 -57
- package/src/entities/Storage/index.ts +0 -2
- package/src/entities/ValidationError/ValidationError.ts +0 -34
- package/src/entities/ValidationError/index.ts +0 -1
- package/src/entities/WebError/WebError.test.ts +0 -18
- package/src/entities/WebError/WebError.ts +0 -23
- package/src/entities/WebError/WebError.types.ts +0 -9
- package/src/entities/WebError/index.ts +0 -2
- package/src/entities/index.ts +0 -16
- package/src/index.ts +0 -6
- package/src/metrics/debug.ts +0 -10
- package/src/metrics/index.ts +0 -2
- package/src/metrics/request.ts +0 -17
- package/src/middleware/authHmac/authHmac.test.ts +0 -86
- package/src/middleware/authHmac/authHmac.ts +0 -56
- package/src/middleware/authHmac/authHmac.types.ts +0 -7
- package/src/middleware/authHmac/index.ts +0 -2
- package/src/middleware/authJwt/authJwt.test.ts +0 -54
- package/src/middleware/authJwt/authJwt.ts +0 -55
- package/src/middleware/authJwt/authJwt.types.ts +0 -14
- package/src/middleware/authJwt/index.ts +0 -2
- package/src/middleware/authStatic/authStatic.test.ts +0 -36
- package/src/middleware/authStatic/authStatic.ts +0 -45
- package/src/middleware/authStatic/index.ts +0 -1
- package/src/middleware/authTls/authTls.test.ts +0 -138
- package/src/middleware/authTls/authTls.ts +0 -119
- package/src/middleware/authTls/authTls.types.ts +0 -13
- package/src/middleware/authTls/index.ts +0 -2
- package/src/middleware/checkPermission/checkPermission.ts +0 -33
- package/src/middleware/checkPermission/index.ts +0 -1
- package/src/middleware/error/error.test.ts +0 -60
- package/src/middleware/error/error.ts +0 -25
- package/src/middleware/error/index.ts +0 -1
- package/src/middleware/fileUploader/fileUploader.ts +0 -154
- package/src/middleware/fileUploader/fileUploader.types.ts +0 -35
- package/src/middleware/fileUploader/index.ts +0 -2
- package/src/middleware/fileUploader/isMultiPart/index.ts +0 -1
- package/src/middleware/fileUploader/isMultiPart/isMultipart.ts +0 -9
- package/src/middleware/fileUploader/validate/index.ts +0 -1
- package/src/middleware/fileUploader/validate/validate.ts +0 -27
- package/src/middleware/fourOhFour/fourOhFour.test.ts +0 -14
- package/src/middleware/fourOhFour/fourOhFour.ts +0 -13
- package/src/middleware/fourOhFour/index.ts +0 -1
- package/src/middleware/geminiFileUploader/geminiFileUploader.ts +0 -68
- package/src/middleware/geminiFileUploader/index.ts +0 -1
- package/src/middleware/healthCheck/healthCheck.test.ts +0 -12
- package/src/middleware/healthCheck/healthCheck.ts +0 -14
- package/src/middleware/healthCheck/index.ts +0 -1
- package/src/middleware/index.ts +0 -17
- package/src/middleware/metrics/index.ts +0 -1
- package/src/middleware/metrics/metrics.test.ts +0 -46
- package/src/middleware/metrics/metrics.ts +0 -24
- package/src/middleware/multiPartFileUploader/index.ts +0 -2
- package/src/middleware/multiPartFileUploader/multiPartFileUploader.ts +0 -249
- package/src/middleware/multiPartFileUploader/multiPartFileUploader.types.ts +0 -23
- package/src/middleware/multiPartFileUploader/validate/index.ts +0 -1
- package/src/middleware/multiPartFileUploader/validate/validate.ts +0 -27
- package/src/middleware/requestMetrics/index.ts +0 -1
- package/src/middleware/requestMetrics/requestMetrics.test.ts +0 -77
- package/src/middleware/requestMetrics/requestMetrics.ts +0 -20
- package/src/middleware/swaggerDocs/index.ts +0 -2
- package/src/middleware/swaggerDocs/swaggerDocs.ts +0 -114
- package/src/middleware/swaggerDocs/swaggerDocs.types.ts +0 -41
- package/src/middleware/userResolver/index.ts +0 -1
- package/src/middleware/userResolver/userResolver.ts +0 -53
- package/src/middleware/validate/index.ts +0 -1
- package/src/middleware/validate/validate.test.ts +0 -43
- package/src/middleware/validate/validate.ts +0 -25
- package/src/middleware/version/index.ts +0 -1
- package/src/middleware/version/version.test.ts +0 -23
- package/src/middleware/version/version.ts +0 -12
- package/src/utils/checkEnvironment/index.ts +0 -49
- package/src/utils/createHttpServer/createHttpServer.test.ts +0 -24
- package/src/utils/createHttpServer/createHttpServer.ts +0 -34
- package/src/utils/createHttpServer/createHttpServer.validate.ts +0 -17
- package/src/utils/createHttpServer/index.ts +0 -1
- package/src/utils/createSortedObject/createSortedObject.ts +0 -20
- package/src/utils/createSortedObject/createSortedObjet.test.ts +0 -47
- package/src/utils/createSortedObject/index.ts +0 -1
- package/src/utils/dbMigration/dbMigration.test.ts +0 -209
- package/src/utils/dbMigration/dbMigration.ts +0 -199
- package/src/utils/dbMigration/dbMigration.types.ts +0 -11
- package/src/utils/dbMigration/index.ts +0 -2
- package/src/utils/dbMigration/migrateMetadataTable/index.ts +0 -1
- package/src/utils/dbMigration/migrateMetadataTable/migrateMetadataTable.test.ts +0 -59
- package/src/utils/dbMigration/migrateMetadataTable/migrateMetadataTable.ts +0 -102
- package/src/utils/envAssert/envAssert.ts +0 -31
- package/src/utils/envAssert/index.ts +0 -1
- package/src/utils/envAssert/validators/hostList.ts +0 -17
- package/src/utils/envAssert/validators/index.ts +0 -5
- package/src/utils/envAssert/validators/ipList.ts +0 -13
- package/src/utils/envAssert/validators/path.ts +0 -13
- package/src/utils/envAssert/validators/string.ts +0 -9
- package/src/utils/envAssert/validators/stringList.ts +0 -13
- package/src/utils/filter/filter.ts +0 -17
- package/src/utils/filter/index.ts +0 -1
- package/src/utils/geminiFileUpload/geminiFileUpload.ts +0 -93
- package/src/utils/geminiFileUpload/index.ts +0 -1
- package/src/utils/hmac/checkEnv/checkEnv.test.ts +0 -18
- package/src/utils/hmac/checkEnv/checkEnv.ts +0 -9
- package/src/utils/hmac/checkEnv/index.ts +0 -1
- package/src/utils/hmac/createHmac/createHmac.ts +0 -33
- package/src/utils/hmac/createHmac/index.ts +0 -1
- package/src/utils/hmac/index.ts +0 -4
- package/src/utils/hmac/index.types.ts +0 -13
- package/src/utils/hmac/signPayload/index.ts +0 -1
- package/src/utils/hmac/signPayload/signPayload.ts +0 -16
- package/src/utils/hmac/verifySignature/index.ts +0 -1
- package/src/utils/hmac/verifySignature/verifySignature.ts +0 -24
- package/src/utils/index.ts +0 -29
- package/src/utils/jwt/index.ts +0 -2
- package/src/utils/jwt/jwt.test.ts +0 -28
- package/src/utils/jwt/jwt.ts +0 -182
- package/src/utils/jwt/jwt.types.ts +0 -21
- package/src/utils/report/index.ts +0 -3
- package/src/utils/report/output.ts +0 -45
- package/src/utils/report/output.types.ts +0 -70
- package/src/utils/report/report.test.ts +0 -133
- package/src/utils/report/report.ts +0 -133
- package/src/utils/report/report.types.ts +0 -13
- package/src/utils/request/index.ts +0 -1
- package/src/utils/request/request.test.ts +0 -26
- package/src/utils/request/request.ts +0 -48
- package/src/utils/secretManager/index.ts +0 -2
- package/src/utils/secretManager/secretLoader.ts +0 -62
- package/src/utils/secretManager/secretResolver.ts +0 -35
- package/src/utils/semverCompare/index.ts +0 -1
- package/src/utils/semverCompare/semverCompare.test.ts +0 -49
- package/src/utils/semverCompare/semverCompare.ts +0 -60
- package/src/utils/sendEmail/index.ts +0 -2
- package/src/utils/sendEmail/sendEmail.ts +0 -61
- package/src/utils/sendEmail/sendEmail.types.ts +0 -61
- package/src/utils/sendPush/index.ts +0 -2
- package/src/utils/sendPush/sendPush.ts +0 -20
- package/src/utils/sendPush/sendPush.types.ts +0 -25
- package/src/utils/tlsConfig/index.ts +0 -2
- package/src/utils/tlsConfig/tlsConfig.test.ts +0 -32
- package/src/utils/tlsConfig/tlsConfig.ts +0 -47
- package/src/utils/tlsConfig/tlsConfig.types.ts +0 -11
- package/src/utils/tlsConfig/tlsConfig.validate.ts +0 -25
- package/src/utils/tlsRequest/index.ts +0 -1
- package/src/utils/tlsRequest/tlsRequest.test.ts +0 -63
- package/src/utils/tlsRequest/tlsRequest.ts +0 -12
- package/src/utils/trimPathSlash/index.ts +0 -1
- package/src/utils/trimPathSlash/trimPathSlash.test.ts +0 -26
- package/src/utils/trimPathSlash/trimPathSlash.ts +0 -8
- package/test/env.ts +0 -53
- package/test/factory/index.ts +0 -8
- package/test/factory/sequelizeMeta.ts +0 -12
- package/test/hooks.ts +0 -35
- package/test/index.ts +0 -3
- package/test/stub/index.ts +0 -3
- package/test/stub/stubLocales.ts +0 -68
- package/test/stub/stubPubSub.ts +0 -7
- package/test/stub/stubStorage.ts +0 -77
- package/test/stub/stubStorage.types.ts +0 -11
- package/test/utils/app.ts +0 -31
- package/test/utils/index.ts +0 -1
- package/tsconfig.build.json +0 -5
- package/tsconfig.json +0 -32
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
-
import {
|
|
3
|
-
ErrorRequestHandler,
|
|
4
|
-
Request,
|
|
5
|
-
Response,
|
|
6
|
-
NextFunction,
|
|
7
|
-
RequestHandler
|
|
8
|
-
} from 'express';
|
|
9
|
-
import { ParamsDictionary } from 'express-serve-static-core';
|
|
10
|
-
import { Schema } from 'express-validator';
|
|
11
|
-
import { ParsedQs } from 'qs';
|
|
12
|
-
|
|
13
|
-
import {
|
|
14
|
-
authJwt,
|
|
15
|
-
authHmac,
|
|
16
|
-
authTls,
|
|
17
|
-
authStatic,
|
|
18
|
-
FileUploaderConfig
|
|
19
|
-
} from 'middleware';
|
|
20
|
-
import { MultiPartFileUploaderConfig } from 'middleware/multiPartFileUploader/multiPartFileUploader.types';
|
|
21
|
-
|
|
22
|
-
export enum EndpointMethod {
|
|
23
|
-
GET = 'get',
|
|
24
|
-
POST = 'post',
|
|
25
|
-
PUT = 'put',
|
|
26
|
-
PATCH = 'patch',
|
|
27
|
-
DELETE = 'delete',
|
|
28
|
-
HEAD = 'head',
|
|
29
|
-
ALL = 'all'
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export const EndpointMethods = Object.values(EndpointMethod);
|
|
33
|
-
|
|
34
|
-
export enum EndpointAuthType {
|
|
35
|
-
NONE = 'none',
|
|
36
|
-
JWT = 'jwt',
|
|
37
|
-
TLS = 'tls',
|
|
38
|
-
HMAC = 'hmac',
|
|
39
|
-
STATIC = 'static'
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export const EndpointAuthTypes = Object.values(EndpointAuthType);
|
|
43
|
-
|
|
44
|
-
export type Middleware<T extends EndpointAuthType> = (
|
|
45
|
-
request: EndpointRequestType[T],
|
|
46
|
-
response: Response,
|
|
47
|
-
next: NextFunction
|
|
48
|
-
) => unknown | Promise<unknown>;
|
|
49
|
-
|
|
50
|
-
export type MiddlewareChainElement<T extends EndpointAuthType> =
|
|
51
|
-
| Array<Middleware<T>>
|
|
52
|
-
| Middleware<T>
|
|
53
|
-
| any;
|
|
54
|
-
|
|
55
|
-
/** Auth related parameters used with HMAC authentication */
|
|
56
|
-
interface EndpointAuthHmacParams {
|
|
57
|
-
/** [HMAC] Secret used for signature */
|
|
58
|
-
secret?: string;
|
|
59
|
-
/** [HMAC] For Github webhook, the standard differs slightly, so this option must be selected */
|
|
60
|
-
isGithub?: boolean;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/** Auth related parameters used with mTLS authentication */
|
|
64
|
-
interface EndpointAuthTlsParams {
|
|
65
|
-
/** [TLS] List oh hosts that are allowed to use the endpoint, this is compared to the claims in the certificate */
|
|
66
|
-
whitelist?: Array<string>;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/** Mapping used to get auth specific parameters depending on the auth type used */
|
|
70
|
-
interface EndpointAuthSpecificParams {
|
|
71
|
-
/** Auth parameters for no authentication */
|
|
72
|
-
[EndpointAuthType.NONE]: any;
|
|
73
|
-
/** Auth parameters for JWT authentication */
|
|
74
|
-
[EndpointAuthType.JWT]: any;
|
|
75
|
-
/** Auth parameters for mTLS authentication */
|
|
76
|
-
[EndpointAuthType.TLS]: EndpointAuthTlsParams;
|
|
77
|
-
/** Auth parameters for HMAC authentication */
|
|
78
|
-
[EndpointAuthType.HMAC]: EndpointAuthHmacParams;
|
|
79
|
-
/** Auth parameters for static authentication */
|
|
80
|
-
[EndpointAuthType.STATIC]: any;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
export type EndpointAuthParams<T extends EndpointAuthType> =
|
|
84
|
-
EndpointAuthSpecificParams[T] & {
|
|
85
|
-
/** This will allow the business logic to run event if the authentication fails */
|
|
86
|
-
acceptInvalid?: boolean;
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
export type EndpointAuthHandler<T extends EndpointAuthType> = (
|
|
90
|
-
options?: EndpointAuthParams<T>
|
|
91
|
-
) => (
|
|
92
|
-
request: Request,
|
|
93
|
-
response: Response,
|
|
94
|
-
next: NextFunction
|
|
95
|
-
) => void | Promise<void>;
|
|
96
|
-
|
|
97
|
-
export const EndpointAuthHandlers = {
|
|
98
|
-
/** Auth handler for no authentication */
|
|
99
|
-
[EndpointAuthType.NONE]: undefined,
|
|
100
|
-
/** Auth handler for JWT authentication */
|
|
101
|
-
[EndpointAuthType.JWT]: authJwt,
|
|
102
|
-
/** Auth handler for mTLS authentication */
|
|
103
|
-
[EndpointAuthType.TLS]: authTls,
|
|
104
|
-
/** Auth handler for HMAC authentication */
|
|
105
|
-
[EndpointAuthType.HMAC]: authHmac,
|
|
106
|
-
/** Auth handler for static authentication */
|
|
107
|
-
[EndpointAuthType.STATIC]: authStatic
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
export type EndpointHandler<T extends EndpointAuthType> = (
|
|
111
|
-
request: EndpointRequestType[T],
|
|
112
|
-
response: Response
|
|
113
|
-
) => void | Promise<void>;
|
|
114
|
-
|
|
115
|
-
/** Endpoint initialization options */
|
|
116
|
-
export interface EndpointOptions<T extends EndpointAuthType> {
|
|
117
|
-
/** Path at which the endpoint is reachable */
|
|
118
|
-
path: string;
|
|
119
|
-
/** HTTP method of the endpoint */
|
|
120
|
-
method: EndpointMethod;
|
|
121
|
-
/** Function handling the endpoint's business logic */
|
|
122
|
-
handler: EndpointHandler<T>;
|
|
123
|
-
/** Validation schema that the request must pass before reaching the handler */
|
|
124
|
-
validator: Schema;
|
|
125
|
-
/** Authentication system required by this endpoint */
|
|
126
|
-
authType: T;
|
|
127
|
-
/** Authentication related options for this endpoint */
|
|
128
|
-
authParams?: EndpointAuthParams<T>;
|
|
129
|
-
/** @deprecated Setting to upload a file through this endpoint */
|
|
130
|
-
file?: FileUploaderConfig;
|
|
131
|
-
/** Settings to upload files through this endpoint (this will automatically switch the expected request to be a multipart) */
|
|
132
|
-
files?: Array<FileUploaderConfig>;
|
|
133
|
-
/** Settings to upload file parts (Chunks) through this endpoint (this will automatically switch the expected request to be a multipart) */
|
|
134
|
-
multiPartFile?: MultiPartFileUploaderConfig;
|
|
135
|
-
/** Express request handlers that should run on this endpoint before the business logic, they will run after the global middleware */
|
|
136
|
-
middleware?: MiddlewareChainElement<T>;
|
|
137
|
-
/** Express error handlers that should be registered for this endpoint. they will run before the global error handler */
|
|
138
|
-
errorMiddleware?: ErrorRequestHandler | Array<ErrorRequestHandler>;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
/** Request type when using JWT authentication */
|
|
142
|
-
export interface JwtRequest<
|
|
143
|
-
P = ParamsDictionary,
|
|
144
|
-
ResBody = any,
|
|
145
|
-
ReqBody = any,
|
|
146
|
-
ReqQuery = ParsedQs,
|
|
147
|
-
Locals extends Record<string, any> = Record<string, any>
|
|
148
|
-
> extends Request<P, ResBody, ReqBody, ReqQuery, Locals> {
|
|
149
|
-
/** User that identified using a JWT */
|
|
150
|
-
user: Record<string, any> | any;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/** Request type when using mTLS authentication */
|
|
154
|
-
export interface TlsRequest<
|
|
155
|
-
P = ParamsDictionary,
|
|
156
|
-
ResBody = any,
|
|
157
|
-
ReqBody = any,
|
|
158
|
-
ReqQuery = ParsedQs,
|
|
159
|
-
Locals extends Record<string, any> = Record<string, any>
|
|
160
|
-
> extends Request<P, ResBody, ReqBody, ReqQuery, Locals> {
|
|
161
|
-
/** Host names provided by the mTLS authenticated client */
|
|
162
|
-
hosts: Array<string>;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/** Mapping of request types in endpoints based on auth type used */
|
|
166
|
-
export interface EndpointRequestType {
|
|
167
|
-
/** Request type for no authentication */
|
|
168
|
-
[EndpointAuthType.NONE]: Request;
|
|
169
|
-
/** Request type when using JWT authentication */
|
|
170
|
-
[EndpointAuthType.JWT]: JwtRequest;
|
|
171
|
-
/** Request type when using mTLS authentication */
|
|
172
|
-
[EndpointAuthType.TLS]: TlsRequest;
|
|
173
|
-
/** Request type when using HMAC authentication */
|
|
174
|
-
[EndpointAuthType.HMAC]: Request;
|
|
175
|
-
/** Auth handler for static authentication */
|
|
176
|
-
[EndpointAuthType.STATIC]: Request;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
export type SafeMiddleWareChain = Array<
|
|
180
|
-
RequestHandler | ErrorRequestHandler | SafeMiddleWareChain
|
|
181
|
-
>;
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { EngineErrorOptions } from './EngineError.types';
|
|
2
|
-
import { LogSeverity } from 'const';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Base error type for engine related errors
|
|
6
|
-
*/
|
|
7
|
-
export class EngineError extends Error {
|
|
8
|
-
/** Severity of the log entry */
|
|
9
|
-
public severity: LogSeverity;
|
|
10
|
-
/** If this error is wrapping another one, this will contain the original error */
|
|
11
|
-
public error?: Error;
|
|
12
|
-
/** Additional contextual data for debugging */
|
|
13
|
-
public data?: unknown;
|
|
14
|
-
/** Human readable error message sent to the client */
|
|
15
|
-
public hint?: unknown;
|
|
16
|
-
|
|
17
|
-
/** Create an EngineError, these errors represent errors in the engine itself */
|
|
18
|
-
public constructor(config: EngineErrorOptions | string) {
|
|
19
|
-
const options: EngineErrorOptions =
|
|
20
|
-
typeof config === 'string' ? { message: config } : config;
|
|
21
|
-
super(options.message);
|
|
22
|
-
|
|
23
|
-
this.severity = options.severity ?? LogSeverity.CRITICAL;
|
|
24
|
-
this.data = options.data;
|
|
25
|
-
this.error = options.error;
|
|
26
|
-
this.hint = options.hint;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { LogSeverity } from 'const';
|
|
2
|
-
|
|
3
|
-
/** EngineError initialization options */
|
|
4
|
-
export interface EngineErrorOptions {
|
|
5
|
-
/** Main logged message */
|
|
6
|
-
message: string;
|
|
7
|
-
/** Severity of the log entry */
|
|
8
|
-
severity?: LogSeverity;
|
|
9
|
-
/** If this error is wrapping another one, this will contain the original error */
|
|
10
|
-
error?: Error;
|
|
11
|
-
/** Additional contextual data for debugging */
|
|
12
|
-
data?: unknown;
|
|
13
|
-
/** Human readable error message sent to the client */
|
|
14
|
-
hint?: unknown;
|
|
15
|
-
}
|
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
import { randomUUID, createPublicKey } from 'crypto';
|
|
2
|
-
import { readFileSync } from 'fs';
|
|
3
|
-
import { readFile } from 'fs/promises';
|
|
4
|
-
import { AxiosResponse } from 'axios';
|
|
5
|
-
import { expect } from 'chai';
|
|
6
|
-
import { faker } from '@faker-js/faker';
|
|
7
|
-
import { stub, SinonStub } from 'sinon';
|
|
8
|
-
import { KeySet } from './KeySet';
|
|
9
|
-
import { JWKS } from './KeySet.types';
|
|
10
|
-
import * as request from 'utils/request/request';
|
|
11
|
-
import * as tlsRequest from 'utils/tlsRequest/tlsRequest';
|
|
12
|
-
|
|
13
|
-
// We test with both an RSA key and an EC key
|
|
14
|
-
const TEST_JWKS = {
|
|
15
|
-
data: {
|
|
16
|
-
keys: [
|
|
17
|
-
{
|
|
18
|
-
alg: 'RS256',
|
|
19
|
-
kty: 'RSA',
|
|
20
|
-
use: 'sig',
|
|
21
|
-
n:
|
|
22
|
-
'u18mjw63ELk8xA4C2Qbi1WTtqcx853iRv9Gfd-zKKmlU2wStnOGnIfnHkrNbl5y8vTMNBKNuqLh3Y_el' +
|
|
23
|
-
'PVSUIWGcy3KByw7VRnBTAze2bsmI0Dvz-89Ar1C2g0Ui6DOYyEa0iiXer4gSQgJ5ddsbIAMJMBT5j96G' +
|
|
24
|
-
'1mhbjM2mqekORRyjCZHGeNbofnTvKcJRTStsBPXQ2WEkAf6J1eNZ2-QnNYMVVO44-KXfhQsfaqRoporj' +
|
|
25
|
-
'4LvTkNX0kkxyfC3V1R8Qrk-_pHhzPtKtQxiRj2axTVXFoj5I1Po7WgQz2_vBZnWZ-0AIzHXN6F_fmMhy' +
|
|
26
|
-
'PBPk3pbuN7cHBe2cKh_nHQ',
|
|
27
|
-
e: 'AQAB',
|
|
28
|
-
kid: 'Q0ZCQzEwRTFCOUE3QjI0MUZEREQ0N0I4MTI3OTVFRDkyNTIxQjQ3MA'
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
crv: 'P-256',
|
|
32
|
-
kty: 'EC',
|
|
33
|
-
x: 'ruky13qVa2GM9jnWsBYP_OTsk6fyV_HWC2AjvUkyCv8',
|
|
34
|
-
y: 'kIAW58dw6pjO1dy4czpNdsaL8DUc3RKo6Hmses5O_Bc',
|
|
35
|
-
kid: '3d-GYUhTwkAfCi9JdvMieQ',
|
|
36
|
-
alg: 'EC256',
|
|
37
|
-
use: 'sig'
|
|
38
|
-
}
|
|
39
|
-
]
|
|
40
|
-
}
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
const TEST_PEMS = TEST_JWKS.data.keys.map((key) =>
|
|
44
|
-
createPublicKey({ key, format: 'jwk' }).export({
|
|
45
|
-
format: 'pem',
|
|
46
|
-
type: 'spki'
|
|
47
|
-
})
|
|
48
|
-
);
|
|
49
|
-
|
|
50
|
-
describe('Entity - KeySet', function () {
|
|
51
|
-
let url: string;
|
|
52
|
-
let requestStub: SinonStub;
|
|
53
|
-
let tlsRequestStub: SinonStub;
|
|
54
|
-
|
|
55
|
-
beforeEach(() => {
|
|
56
|
-
url = faker.internet.url();
|
|
57
|
-
|
|
58
|
-
requestStub = stub(request, 'request').resolves(
|
|
59
|
-
TEST_JWKS as unknown as AxiosResponse<JWKS>
|
|
60
|
-
);
|
|
61
|
-
tlsRequestStub = stub(tlsRequest, 'tlsRequest').resolves(
|
|
62
|
-
TEST_JWKS as unknown as AxiosResponse<JWKS>
|
|
63
|
-
);
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
it('should create a key set when fetching', async () => {
|
|
67
|
-
const keySet = new KeySet(url);
|
|
68
|
-
await keySet.init();
|
|
69
|
-
|
|
70
|
-
const keys = keySet.getKeys();
|
|
71
|
-
expect(Object.values(keys)).to.have.length(2);
|
|
72
|
-
Object.values(keys).forEach((key) => {
|
|
73
|
-
expect(TEST_PEMS).to.include(key);
|
|
74
|
-
});
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
it('should make a regular request by default', async () => {
|
|
78
|
-
const keySet = new KeySet(url);
|
|
79
|
-
|
|
80
|
-
await keySet.init();
|
|
81
|
-
|
|
82
|
-
expect(requestStub).to.have.been.calledOnceWithExactly({
|
|
83
|
-
url,
|
|
84
|
-
method: 'get'
|
|
85
|
-
});
|
|
86
|
-
expect(tlsRequestStub).to.not.have.been.called;
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
it('should make a TLS request for internal keysets', async () => {
|
|
90
|
-
const keySet = new KeySet(url, { internal: true });
|
|
91
|
-
|
|
92
|
-
await keySet.init();
|
|
93
|
-
|
|
94
|
-
expect(tlsRequestStub).to.have.been.calledOnceWithExactly({
|
|
95
|
-
url,
|
|
96
|
-
method: 'get'
|
|
97
|
-
});
|
|
98
|
-
expect(requestStub).to.not.have.been.called;
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
it('should read a key from a PEM string', async () => {
|
|
102
|
-
const pem = await readFile(
|
|
103
|
-
process.env.ECDSA_PUBLIC_KEY as string,
|
|
104
|
-
'utf-8'
|
|
105
|
-
);
|
|
106
|
-
|
|
107
|
-
const keySet = new KeySet(pem, { pem: true });
|
|
108
|
-
|
|
109
|
-
await keySet.init();
|
|
110
|
-
|
|
111
|
-
expect(tlsRequestStub).to.not.have.been.called;
|
|
112
|
-
expect(requestStub).to.not.have.been.called;
|
|
113
|
-
expect(Object.keys(keySet.getKeys())).to.have.length(1);
|
|
114
|
-
for (const key of Object.values(keySet.getKeys())) {
|
|
115
|
-
expect(key).to.equal(pem);
|
|
116
|
-
}
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
it('should not fail if the init did not complete and a key is asked', () => {
|
|
120
|
-
const keySet = new KeySet(faker.internet.url());
|
|
121
|
-
|
|
122
|
-
const result = keySet.getKey(randomUUID());
|
|
123
|
-
|
|
124
|
-
expect(result).to.be.undefined;
|
|
125
|
-
});
|
|
126
|
-
});
|
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
import { createPublicKey, createHash } from 'crypto';
|
|
2
|
-
import { readFileSync } from 'fs';
|
|
3
|
-
import { Method } from 'axios';
|
|
4
|
-
import { KeySetOptions, KeySetValues, JWKS } from './KeySet.types';
|
|
5
|
-
import { LogSeverity } from 'const';
|
|
6
|
-
import { EngineError } from 'entities/EngineError';
|
|
7
|
-
import { reportDebug, reportError } from 'utils/report';
|
|
8
|
-
import { request } from 'utils/request';
|
|
9
|
-
import { tlsRequest } from 'utils/tlsRequest';
|
|
10
|
-
|
|
11
|
-
const namespace = 'engine:keySet';
|
|
12
|
-
|
|
13
|
-
// Number of seconds between each key refresh
|
|
14
|
-
const KEY_REFRESH_INTERVAL = 300;
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Fetch Json Web Key Sets and cache them
|
|
18
|
-
* Keys can then be used for Json Web Token authentication
|
|
19
|
-
*/
|
|
20
|
-
export class KeySet {
|
|
21
|
-
/** Latest known value for the keys in the set, indexed by the key id */
|
|
22
|
-
private keySet: KeySetValues = {};
|
|
23
|
-
/** URL at which the key set can be fetched */
|
|
24
|
-
private url: string;
|
|
25
|
-
/** This resource is located on a service inside of our private cluster */
|
|
26
|
-
private internal: boolean;
|
|
27
|
-
/** This URL is actually a path to a local key file encoded in PEM */
|
|
28
|
-
private file: boolean;
|
|
29
|
-
/** This input is actually a full PEM string representation of a key */
|
|
30
|
-
private pem: boolean;
|
|
31
|
-
/** Timer for the key fetching interval */
|
|
32
|
-
private interval?: NodeJS.Timeout | string | number | undefined;
|
|
33
|
-
|
|
34
|
-
/** Create a new Key Set */
|
|
35
|
-
public constructor(url: string, options: KeySetOptions = {}) {
|
|
36
|
-
this.url = url;
|
|
37
|
-
this.internal = options.internal ?? false;
|
|
38
|
-
this.file = options.file ?? false;
|
|
39
|
-
this.pem = options.pem ?? false;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/** Calculate key ID from PEM string */
|
|
43
|
-
private static calculateKeyId(pem: string): string {
|
|
44
|
-
// We use the md5 hash of the PEM file to defined the key ID
|
|
45
|
-
const hash = createHash('md5');
|
|
46
|
-
hash.update(pem.trim());
|
|
47
|
-
const kid = hash.digest('base64url');
|
|
48
|
-
reportDebug({
|
|
49
|
-
namespace,
|
|
50
|
-
message: `Calculated Key ID: "${kid}"`,
|
|
51
|
-
data: { key: pem }
|
|
52
|
-
});
|
|
53
|
-
return kid;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/** Initialize a KeySet, should be run on server startup to avoid any misconfiguration */
|
|
57
|
-
public async init(): Promise<void> {
|
|
58
|
-
await this.fetch();
|
|
59
|
-
this.interval = setInterval(() => {
|
|
60
|
-
(async (): Promise<void> => {
|
|
61
|
-
try {
|
|
62
|
-
await this.fetch();
|
|
63
|
-
} catch (error) {
|
|
64
|
-
reportError(error);
|
|
65
|
-
}
|
|
66
|
-
})().catch((error) => {
|
|
67
|
-
reportError(error);
|
|
68
|
-
});
|
|
69
|
-
}, KEY_REFRESH_INTERVAL * 1000);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/** Clear any pending timers to avoid pending process */
|
|
73
|
-
public shutdown(): void {
|
|
74
|
-
if (this.interval) clearInterval(this.interval);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/** Get the PEM encoded version of a key by its id */
|
|
78
|
-
public getKey(keyId: string): string | undefined {
|
|
79
|
-
return this.keySet[keyId];
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/** Get all the keys in the set mapped by their ID */
|
|
83
|
-
public getKeys(): KeySetValues {
|
|
84
|
-
return this.keySet;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/** Fetch the latest version of the key set */
|
|
88
|
-
private async fetch(): Promise<void> {
|
|
89
|
-
reportDebug({
|
|
90
|
-
namespace,
|
|
91
|
-
message: `Fetching JWKS`,
|
|
92
|
-
data: { url: this.url }
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
if (this.pem) {
|
|
96
|
-
// Read the key from the parameter directly
|
|
97
|
-
reportDebug({
|
|
98
|
-
namespace,
|
|
99
|
-
message: 'Processing key from given PEM string'
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
const kid = KeySet.calculateKeyId(this.url);
|
|
103
|
-
|
|
104
|
-
this.keySet = { [kid]: this.url };
|
|
105
|
-
} else if (this.file) {
|
|
106
|
-
// Read the key from a file
|
|
107
|
-
reportDebug({
|
|
108
|
-
namespace,
|
|
109
|
-
message: `Reading key on disk at path "${this.url}"`
|
|
110
|
-
});
|
|
111
|
-
const set = JSON.parse(readFileSync(this.url, 'utf-8'));
|
|
112
|
-
|
|
113
|
-
// Check that the returned data has the shape of a JWKS
|
|
114
|
-
if (!(set.keys && set.keys instanceof Array))
|
|
115
|
-
throw new EngineError({
|
|
116
|
-
severity: LogSeverity.ERROR,
|
|
117
|
-
message: 'Fetched key set is not in an appropriate format',
|
|
118
|
-
data: { url: this.url, set }
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
// Create a node.crypto public key object for each key in the set
|
|
122
|
-
this.keySet = set.keys.reduce(
|
|
123
|
-
(set: { [x: string]: string; }, key: { kid: string | number; }) => {
|
|
124
|
-
set[key.kid] = createPublicKey({ key, format: 'jwk' }).export({
|
|
125
|
-
format: 'pem',
|
|
126
|
-
type: 'spki'
|
|
127
|
-
}) as string;
|
|
128
|
-
return set;
|
|
129
|
-
},
|
|
130
|
-
{} as Record<string, string>
|
|
131
|
-
);
|
|
132
|
-
} else {
|
|
133
|
-
// Fetch key by making a network request
|
|
134
|
-
reportDebug({
|
|
135
|
-
namespace,
|
|
136
|
-
message: `Making network request to "${this.url}"`
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
const requestOptions = { url: this.url, method: 'get' as Method };
|
|
140
|
-
// For services inside of our cluster we use the TLS authenticated request method
|
|
141
|
-
const { data: set } = await (this.internal
|
|
142
|
-
? tlsRequest<JWKS>(requestOptions)
|
|
143
|
-
: request<JWKS>(requestOptions));
|
|
144
|
-
|
|
145
|
-
// Check that the returned data has the shape of a JWKS
|
|
146
|
-
if (!(set.keys && set.keys instanceof Array))
|
|
147
|
-
throw new EngineError({
|
|
148
|
-
severity: LogSeverity.ERROR,
|
|
149
|
-
message: 'Fetched key set is not in an appropriate format',
|
|
150
|
-
data: { url: this.url, set }
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
// Create a node.crypto public key object for each key in the set
|
|
154
|
-
this.keySet = set.keys.reduce(
|
|
155
|
-
(set, key) => {
|
|
156
|
-
set[key.kid] = createPublicKey({ key, format: 'jwk' }).export({
|
|
157
|
-
format: 'pem',
|
|
158
|
-
type: 'spki'
|
|
159
|
-
}) as string;
|
|
160
|
-
return set;
|
|
161
|
-
},
|
|
162
|
-
{} as Record<string, string>
|
|
163
|
-
);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
reportDebug({
|
|
167
|
-
namespace,
|
|
168
|
-
message: `Stored ${Object.keys(this.keySet).length} keys`,
|
|
169
|
-
data: { keyIds: Object.keys(this.keySet) }
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { JsonWebKey } from 'crypto';
|
|
2
|
-
|
|
3
|
-
/** KeySet initialization options */
|
|
4
|
-
export interface KeySetOptions {
|
|
5
|
-
/** This resource is located on a service inside of our private cluster */
|
|
6
|
-
internal?: boolean;
|
|
7
|
-
/** This URL is actually a path to a local key file encoded in PEM */
|
|
8
|
-
file?: boolean;
|
|
9
|
-
/** This input is actually a full PEM string representation of a key */
|
|
10
|
-
pem?: boolean;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
/** Keep a mapping ok keyId => PEM */
|
|
14
|
-
export interface KeySetValues {
|
|
15
|
-
[id: string]: string;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/** Object holding JWK keys */
|
|
19
|
-
export interface JWKS {
|
|
20
|
-
/** Key set is JWKS format */
|
|
21
|
-
keys: Array<JWK>;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/** JWK key with custom claims */
|
|
25
|
-
interface JWK extends JsonWebKey {
|
|
26
|
-
/** ID of the key */
|
|
27
|
-
kid: string;
|
|
28
|
-
}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { expect } from 'chai';
|
|
2
|
-
import { Request, Response } from 'express';
|
|
3
|
-
import { stub, SinonStub } from 'sinon';
|
|
4
|
-
import { Endpoint, EndpointMethod, EndpointAuthType } from '../Endpoint';
|
|
5
|
-
import { runningInstances } from './LifecycleController';
|
|
6
|
-
import { Localizator } from 'entities/Localizator';
|
|
7
|
-
import { redisClient } from 'entities/Redis/Redis';
|
|
8
|
-
import { Server } from 'entities/Server';
|
|
9
|
-
import { stubPubSub } from 'test';
|
|
10
|
-
|
|
11
|
-
describe('Entity - LifecycleController', function () {
|
|
12
|
-
let localizatorShutdownStub: SinonStub;
|
|
13
|
-
|
|
14
|
-
beforeEach(() => {
|
|
15
|
-
stubPubSub();
|
|
16
|
-
stub(Localizator, 'synchronize').resolves();
|
|
17
|
-
localizatorShutdownStub = stub(Localizator, 'shutdown').resolves();
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
it('Shutdown the running entities', async () => {
|
|
21
|
-
const server = new Server({
|
|
22
|
-
endpoints: [
|
|
23
|
-
new Endpoint({
|
|
24
|
-
method: EndpointMethod.GET,
|
|
25
|
-
authType: EndpointAuthType.NONE,
|
|
26
|
-
validator: {},
|
|
27
|
-
path: '/',
|
|
28
|
-
handler: (req: Request, res: Response): void => {
|
|
29
|
-
res.json({ message: 'success' });
|
|
30
|
-
}
|
|
31
|
-
})
|
|
32
|
-
],
|
|
33
|
-
initCallbacks: [
|
|
34
|
-
Localizator.init.bind(Localizator)
|
|
35
|
-
]
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
await server.init();
|
|
39
|
-
|
|
40
|
-
// Redis will always have been init
|
|
41
|
-
expect([...runningInstances]).to.include(Localizator);
|
|
42
|
-
|
|
43
|
-
await server.shutdown();
|
|
44
|
-
|
|
45
|
-
expect(localizatorShutdownStub).to.have.been.calledOnce;
|
|
46
|
-
expect(redisClient).to.be.undefined;
|
|
47
|
-
});
|
|
48
|
-
});
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { LifecycleControlledInstance } from './LifecycleController.types';
|
|
2
|
-
|
|
3
|
-
/** List of initialized entities */
|
|
4
|
-
export const runningInstances: Set<LifecycleControlledInstance> = new Set();
|
|
5
|
-
|
|
6
|
-
/** LifecycleController is used to shutdown all the entities on server shutdown */
|
|
7
|
-
export const LifecycleController = {
|
|
8
|
-
/** Add the initialized instances into the runningInstance property */
|
|
9
|
-
register(instance: LifecycleControlledInstance): void {
|
|
10
|
-
runningInstances.add(instance);
|
|
11
|
-
},
|
|
12
|
-
|
|
13
|
-
/** Shutdown all the running instances */
|
|
14
|
-
async shutdownRunningInstances(): Promise<void> {
|
|
15
|
-
const promises = [];
|
|
16
|
-
for (const instance of runningInstances) {
|
|
17
|
-
if (instance) {
|
|
18
|
-
promises.push(instance.shutdown.bind(instance)());
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
await Promise.all(promises);
|
|
22
|
-
runningInstances.clear();
|
|
23
|
-
}
|
|
24
|
-
};
|