node-server-engine 1.4.7 → 1.4.8
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/middleware/authTls/authTls.js +10 -0
- package/dist/middleware/authTls/authTls.js.map +1 -1
- package/dist/utils/createHttpServer/createHttpServer.js +1 -1
- package/dist/utils/createHttpServer/createHttpServer.js.map +1 -1
- package/package.json +1 -1
- package/src/middleware/authTls/authTls.ts +13 -0
- package/src/utils/createHttpServer/createHttpServer.ts +1 -1
|
@@ -49,6 +49,16 @@ loadEnv();
|
|
|
49
49
|
/** Middleware that handles mTLS based authentication */
|
|
50
50
|
function authTlsMiddleware(request, response, next, options = {}) {
|
|
51
51
|
const socket = request.socket;
|
|
52
|
+
(0, _report.reportDebug)({
|
|
53
|
+
namespace,
|
|
54
|
+
message: 'TLS socket auth state',
|
|
55
|
+
data: {
|
|
56
|
+
authorized: socket?.authorized,
|
|
57
|
+
authorizationError: socket?.authorizationError,
|
|
58
|
+
peerCert: socket?.getPeerCertificate?.()
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
|
|
52
62
|
// Check if the client's tls certificate is valid
|
|
53
63
|
if (!socket?.authorized) {
|
|
54
64
|
throw new _WebError.WebError({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authTls.js","names":["_WebError","require","_checkEnvironment","_envAssert","_report","namespace","authTls","options","assertEnvironment","TLS_SERVER_KEY","envAssert","isPath","TLS_SERVER_CERT","request","response","next","authTlsMiddleware","allowedClientHosts","loadEnv","process","env","ALLOWED_CLIENT_HOSTS","isHostList","split","map","value","trim","socket","
|
|
1
|
+
{"version":3,"file":"authTls.js","names":["_WebError","require","_checkEnvironment","_envAssert","_report","namespace","authTls","options","assertEnvironment","TLS_SERVER_KEY","envAssert","isPath","TLS_SERVER_CERT","request","response","next","authTlsMiddleware","allowedClientHosts","loadEnv","process","env","ALLOWED_CLIENT_HOSTS","isHostList","split","map","value","trim","socket","reportDebug","message","data","authorized","authorizationError","peerCert","getPeerCertificate","WebError","errorCode","statusCode","clientCertificate","subjects","subject","CN","push","subjectaltname","length","altNames","whitelist","certificate","allowed","includes","hosts"],"sources":["../../../src/middleware/authTls/authTls.ts"],"sourcesContent":["import { TLSSocket } from 'tls';\nimport { Request, Response, NextFunction } from 'express';\nimport { EndpointAuthParams, EndpointAuthType } from 'entities/Endpoint';\nimport { WebError } from 'entities/WebError';\nimport { assertEnvironment } from 'utils/checkEnvironment';\nimport { envAssert } from 'utils/envAssert';\nimport { reportDebug } from 'utils/report';\nimport {} from './authTls.types';\n\nconst namespace = 'engine:middleware:authTls';\n\n/**\n * Returns a middleware for TLS authentication\n * Both client and server must have a certificate signed by the same CA\n * Host name of the client is added to the express request object under 'request.user.host'\n * A limited number of hosts can be specified with the environment variable ALLOWED_CLIENT_HOSTS\n * @param {Object} options\n * @param {Array<String>} options.whitelist - List of certificate Common Name or Alt Name that are permitted to make requests to this endpoint\n * @return {Function}\n */\nexport function authTls(\n options: EndpointAuthParams<EndpointAuthType.TLS> = {}\n): (request: Request, response: Response, next: NextFunction) => void {\n assertEnvironment({\n TLS_SERVER_KEY: envAssert.isPath(),\n TLS_SERVER_CERT: envAssert.isPath()\n });\n\n return (request: Request, response: Response, next: NextFunction): void => {\n authTlsMiddleware(request, response, next, options);\n };\n}\n\nlet allowedClientHosts: Array<string> = [];\n\n/** Load TLS auth related environment variables */\nexport function loadEnv(): void {\n if (process.env.ALLOWED_CLIENT_HOSTS) {\n assertEnvironment({ ALLOWED_CLIENT_HOSTS: envAssert.isHostList() });\n allowedClientHosts = process.env.ALLOWED_CLIENT_HOSTS.split(',').map(\n (value) => value.trim()\n );\n } else {\n allowedClientHosts = [];\n }\n}\n\nloadEnv();\n\n/** Middleware that handles mTLS based authentication */\nexport function authTlsMiddleware(\n request: Request,\n response: Response,\n next: NextFunction,\n options: EndpointAuthParams<EndpointAuthType.TLS> = {}\n): void {\n const socket = request.socket as TLSSocket;\n\n reportDebug({\n namespace,\n message: 'TLS socket auth state',\n data: {\n authorized: socket?.authorized,\n authorizationError: (\n socket as TLSSocket & { authorizationError?: string }\n )?.authorizationError,\n peerCert: socket?.getPeerCertificate?.()\n }\n });\n\n // Check if the client's tls certificate is valid\n if (!socket?.authorized) {\n throw new WebError({\n errorCode: 'unauthorized',\n statusCode: 401,\n message: 'TLS certificate could not be validated'\n });\n }\n\n // Extract the subjects for the client certificate\n const clientCertificate = socket.getPeerCertificate();\n const subjects = [];\n if (clientCertificate.subject.CN) subjects.push(clientCertificate.subject.CN);\n if (clientCertificate.subjectaltname?.length) {\n const altNames = clientCertificate.subjectaltname\n .split(',')\n .map((subject) => subject.trim())\n .map((value) => value.split(':')[1]);\n subjects.push(...altNames);\n }\n\n const whitelist = options.whitelist ?? allowedClientHosts;\n reportDebug({\n namespace,\n message: 'Performing TLS authentication',\n data: { certificate: clientCertificate, whitelist, subjects }\n });\n // Check that the subject is authorized\n if (whitelist?.length) {\n let allowed = false;\n for (const subject of subjects) {\n if (whitelist.includes(subject)) {\n allowed = true;\n break;\n }\n }\n // Throw error if there is no subject in the whitelist\n if (!allowed)\n throw new WebError({\n errorCode: 'unauthorized',\n statusCode: 401,\n message: 'Client host is not in the whitelist',\n data: { subjects }\n });\n }\n // Pas subjects down\n request.hosts = subjects;\n next();\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -21,7 +21,7 @@ function createHttpServer(handler) {
|
|
|
21
21
|
cert: _fs.default.readFileSync(process.env.TLS_SERVER_CERT),
|
|
22
22
|
ca: process.env.TLS_CA ? _fs.default.readFileSync(process.env.TLS_CA) : undefined,
|
|
23
23
|
requestCert: true,
|
|
24
|
-
rejectUnauthorized:
|
|
24
|
+
rejectUnauthorized: true
|
|
25
25
|
}, handler);
|
|
26
26
|
} else {
|
|
27
27
|
return (0, _http.createServer)(handler);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createHttpServer.js","names":["_fs","_interopRequireDefault","require","_http","_https","_createHttpServer","createHttpServer","handler","validateHttpEnvironment","process","env","TLS_SERVER_KEY","TLS_SERVER_CERT","createSecureServer","key","fs","readFileSync","passphrase","TLS_SERVER_KEY_PASSPHRASE","cert","ca","TLS_CA","undefined","requestCert","rejectUnauthorized","createServer"],"sources":["../../../src/utils/createHttpServer/createHttpServer.ts"],"sourcesContent":["import fs from 'fs';\nimport { createServer, RequestListener, Server } from 'http';\nimport {\n createServer as createSecureServer,\n Server as SecureServer\n} from 'https';\nimport { Application } from 'express';\nimport { validateHttpEnvironment } from './createHttpServer.validate';\n\n/** Create and configure an http/https server */\nexport function createHttpServer(\n handler?: Application | RequestListener\n): Server | SecureServer {\n // Validate the environment variables\n validateHttpEnvironment();\n // Create a https server if env var are specified\n if (process.env.TLS_SERVER_KEY && process.env.TLS_SERVER_CERT) {\n return createSecureServer(\n {\n key: fs.readFileSync(process.env.TLS_SERVER_KEY),\n passphrase: process.env.TLS_SERVER_KEY_PASSPHRASE,\n cert: fs.readFileSync(process.env.TLS_SERVER_CERT),\n ca: process.env.TLS_CA\n ? fs.readFileSync(process.env.TLS_CA)\n : undefined,\n requestCert: true,\n rejectUnauthorized:
|
|
1
|
+
{"version":3,"file":"createHttpServer.js","names":["_fs","_interopRequireDefault","require","_http","_https","_createHttpServer","createHttpServer","handler","validateHttpEnvironment","process","env","TLS_SERVER_KEY","TLS_SERVER_CERT","createSecureServer","key","fs","readFileSync","passphrase","TLS_SERVER_KEY_PASSPHRASE","cert","ca","TLS_CA","undefined","requestCert","rejectUnauthorized","createServer"],"sources":["../../../src/utils/createHttpServer/createHttpServer.ts"],"sourcesContent":["import fs from 'fs';\nimport { createServer, RequestListener, Server } from 'http';\nimport {\n createServer as createSecureServer,\n Server as SecureServer\n} from 'https';\nimport { Application } from 'express';\nimport { validateHttpEnvironment } from './createHttpServer.validate';\n\n/** Create and configure an http/https server */\nexport function createHttpServer(\n handler?: Application | RequestListener\n): Server | SecureServer {\n // Validate the environment variables\n validateHttpEnvironment();\n // Create a https server if env var are specified\n if (process.env.TLS_SERVER_KEY && process.env.TLS_SERVER_CERT) {\n return createSecureServer(\n {\n key: fs.readFileSync(process.env.TLS_SERVER_KEY),\n passphrase: process.env.TLS_SERVER_KEY_PASSPHRASE,\n cert: fs.readFileSync(process.env.TLS_SERVER_CERT),\n ca: process.env.TLS_CA\n ? fs.readFileSync(process.env.TLS_CA)\n : undefined,\n requestCert: true,\n rejectUnauthorized: true\n },\n handler\n );\n } else {\n return createServer(handler);\n }\n}\n"],"mappings":";;;;;;;AAAA,IAAAA,GAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,KAAA,GAAAD,OAAA;AACA,IAAAE,MAAA,GAAAF,OAAA;AAKA,IAAAG,iBAAA,GAAAH,OAAA;AAEA;AACO,SAASI,gBAAgBA,CAC9BC,OAAuC,EAChB;EACvB;EACA,IAAAC,yCAAuB,EAAC,CAAC;EACzB;EACA,IAAIC,OAAO,CAACC,GAAG,CAACC,cAAc,IAAIF,OAAO,CAACC,GAAG,CAACE,eAAe,EAAE;IAC7D,OAAO,IAAAC,mBAAkB,EACvB;MACEC,GAAG,EAAEC,WAAE,CAACC,YAAY,CAACP,OAAO,CAACC,GAAG,CAACC,cAAc,CAAC;MAChDM,UAAU,EAAER,OAAO,CAACC,GAAG,CAACQ,yBAAyB;MACjDC,IAAI,EAAEJ,WAAE,CAACC,YAAY,CAACP,OAAO,CAACC,GAAG,CAACE,eAAe,CAAC;MAClDQ,EAAE,EAAEX,OAAO,CAACC,GAAG,CAACW,MAAM,GAClBN,WAAE,CAACC,YAAY,CAACP,OAAO,CAACC,GAAG,CAACW,MAAM,CAAC,GACnCC,SAAS;MACbC,WAAW,EAAE,IAAI;MACjBC,kBAAkB,EAAE;IACtB,CAAC,EACDjB,OACF,CAAC;EACH,CAAC,MAAM;IACL,OAAO,IAAAkB,kBAAY,EAAClB,OAAO,CAAC;EAC9B;AACF","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-server-engine",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.8",
|
|
4
4
|
"description": "Framework used to develop backend services. This package ships with a lot of features to standardize the creation of services, letting you focus on the business logic.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -55,6 +55,19 @@ export function authTlsMiddleware(
|
|
|
55
55
|
options: EndpointAuthParams<EndpointAuthType.TLS> = {}
|
|
56
56
|
): void {
|
|
57
57
|
const socket = request.socket as TLSSocket;
|
|
58
|
+
|
|
59
|
+
reportDebug({
|
|
60
|
+
namespace,
|
|
61
|
+
message: 'TLS socket auth state',
|
|
62
|
+
data: {
|
|
63
|
+
authorized: socket?.authorized,
|
|
64
|
+
authorizationError: (
|
|
65
|
+
socket as TLSSocket & { authorizationError?: string }
|
|
66
|
+
)?.authorizationError,
|
|
67
|
+
peerCert: socket?.getPeerCertificate?.()
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
|
|
58
71
|
// Check if the client's tls certificate is valid
|
|
59
72
|
if (!socket?.authorized) {
|
|
60
73
|
throw new WebError({
|