node-server-engine 1.4.2 → 1.4.4

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.
@@ -49,8 +49,8 @@ export declare class Server {
49
49
  private attachWebSocket;
50
50
  /** Call shutdown if signal gets sent to the process */
51
51
  private handleSignal;
52
- /** Load TLS Config */
53
- private loadTls;
52
+ /** Watch the TLS certificate change event */
53
+ private watchTlsCaFileChange;
54
54
  /** Executes a recurring job */
55
55
  private runCronJob;
56
56
  /** Run a shutdown/init callback */
@@ -8,6 +8,8 @@ exports.Server = void 0;
8
8
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
9
9
  var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
10
10
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
11
+ var _fs = _interopRequireDefault(require("fs"));
12
+ var _path = _interopRequireDefault(require("path"));
11
13
  var _promises = require("timers/promises");
12
14
  var _express = _interopRequireDefault(require("express"));
13
15
  var _cors = _interopRequireDefault(require("cors"));
@@ -94,29 +96,11 @@ let Server = exports.Server = /*#__PURE__*/function () {
94
96
 
95
97
  // Create the primary express core that serves the business logic
96
98
  this.app = (0, _express.default)();
97
-
98
- // small request logger + memory snapshot on response finish
99
- this.app.use((req, res, next) => {
100
- const start = Date.now();
101
- console.log(`[REQ START] ${req.method} ${req.originalUrl} ip=${req.ip} nodeEnv=${process.env.NODE_ENV}`);
102
- res.on('finish', () => {
103
- const time = Date.now() - start;
104
- const mem = process.memoryUsage();
105
- console.log(`[REQ END] ${req.method} ${req.originalUrl} status=${res.statusCode} timeMs=${time} rss=${mem.rss} heapUsed=${mem.heapUsed}`);
106
- });
107
- next();
108
- });
109
99
  this.app.use((0, _cors.default)({
110
100
  origin: process.env.CORS_ORIGIN ?? '*',
111
101
  methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
112
102
  allowedHeaders: ['Content-Type', 'Authorization']
113
103
  }));
114
- this.app.get('/test1', (req, res) => {
115
- console.log('Test endpoint hit');
116
- res.status(200).json({
117
- status: 'ok'
118
- });
119
- });
120
104
  this.registerMiddleware(this.app);
121
105
  this.httpServer = (0, _utils.createHttpServer)(this.app);
122
106
 
@@ -210,8 +194,8 @@ let Server = exports.Server = /*#__PURE__*/function () {
210
194
  });
211
195
  this.handleSignal();
212
196
 
213
- // Load TSL config files
214
- this.loadTls();
197
+ // Watch TSL config files changing
198
+ this.watchTlsCaFileChange();
215
199
  }
216
200
 
217
201
  /** Graceful shutdown */
@@ -352,18 +336,19 @@ let Server = exports.Server = /*#__PURE__*/function () {
352
336
  }));
353
337
  }
354
338
 
355
- /** Load TLS Config */
339
+ /** Watch the TLS certificate change event */
356
340
  }, {
357
- key: "loadTls",
358
- value: function loadTls() {
359
- try {
360
- (0, _report.reportInfo)('Loading TLS config');
361
- (0, _tlsConfig.loadTlsConfig)();
362
- this.httpServer.setSecureContext(_tlsConfig.tlsConfig);
363
- (0, _report.reportInfo)('TLS config loaded successfully');
364
- } catch (err) {
365
- (0, _report.reportError)(`TLS load failed: ${err}`);
366
- }
341
+ key: "watchTlsCaFileChange",
342
+ value: function watchTlsCaFileChange() {
343
+ ['TLS_REQUEST_KEY', 'TLS_REQUEST_KEY_PASSPHRASE', 'TLS_REQUEST_CERT', 'TLS_REQUEST_CA', 'TLS_SERVER_KEY', 'TLS_SERVER_KEY_PASSPHRASE', 'TLS_SERVER_CERT', 'TLS_CA'].forEach(key => {
344
+ const file = process.env[key];
345
+ if (file) _fs.default.watch(_path.default.resolve(file), event => {
346
+ if (event !== 'change') return;
347
+ (0, _report.reportInfo)(`Reloading TLS config [${file} changed]`);
348
+ (0, _tlsConfig.loadTlsConfig)();
349
+ this.httpServer.setSecureContext(_tlsConfig.tlsConfig);
350
+ });
351
+ });
367
352
  }
368
353
 
369
354
  /** Executes a recurring job */
@@ -1 +1 @@
1
- {"version":3,"file":"Server.js","names":["_promises","require","_express","_interopRequireDefault","_cors","_ws","_SocketClient","_Server2","_Endpoint","_EngineError","_LifecycleController","_PubSub","_utils","_jwt","_report","_tlsConfig","namespace","Server","exports","config","_classCallCheck2","default","_defineProperty2","AbortController","validate","reportDebug","message","endpoints","globalMiddleware","errorMiddleware","initCallbacks","shutdownCallbacks","syncCallbacks","cron","auth","noFetch","checkEnvironment","process","env","RUN_MIGRATION","UNDO_MIGRATION","SQL_HOST","envAssert","isHost","SQL_USER","isString","SQL_PASSWORD","SQL_DB","NODE_ENV","PORT","isPort","SECONDARY_PORT","app","express","use","req","res","next","start","Date","now","console","log","method","originalUrl","ip","on","time","mem","memoryUsage","statusCode","rss","heapUsed","cors","origin","CORS_ORIGIN","methods","allowedHeaders","get","status","json","registerMiddleware","httpServer","createHttpServer","secondaryApp","secondaryMiddleware","defaultErrorMiddleware","forEach","middleware","secondaryHttpServer","disable","server","headersTimeout","keepAliveTimeout","webSocket","attachWebSocket","_createClass2","key","value","setupGlobalErrorLogging","err","error","stack","reason","Error","code","init","initKeySets","callback","runCallback","Promise","all","map","PubSub","job","runCronJob","resolve","listen","reportInfo","data","port","secondaryPort","nodeEnv","handleSignal","loadTls","shutdown","listening","address","reportError","exit","close","wss","clients","socket","socketKillTimeout","WEBSOCKET_CLOSE_TIMEOUT","parseInt","setTimeout","readyState","CLOSING","OPEN","terminate","LifecycleController","shutdownRunningInstances","abortController","abort","shutdownKeySets","shutdownSignals","signal","removeAllListeners","getApp","getSecondaryApp","defaultMiddleware","path","endpoint","register","options","WebSocketServer","request","SocketClient","client","catch","loadTlsConfig","setSecureContext","tlsConfig","handler","name","interval","setTimeoutPromise","undefined","function","apply","parameters","some","Endpoint","EngineError","Object","values","validator","Array"],"sources":["../../../src/entities/Server/Server.ts"],"sourcesContent":["import http from 'http';\nimport https from 'https';\nimport { AddressInfo } from 'net';\nimport { setTimeout as setTimeoutPromise } from 'timers/promises';\nimport { ValidatorSpec } from 'envalid';\nimport express, { Application } from 'express';\nimport cors from 'cors';\nimport { Server as WebSocketServer } from 'ws';\nimport { SocketClient } from '../SocketClient';\nimport {\n defaultMiddleware,\n defaultErrorMiddleware,\n secondaryMiddleware,\n shutdownSignals\n} from './Server.const';\nimport {\n ServerOptions,\n ServerCronJon,\n ServerAuthConfig,\n ServerWebSocketConfig,\n ServerGlobalMiddleware,\n ServerErrorMiddleWare,\n ServerCallback\n} from './Server.types';\nimport { Endpoint } from 'entities/Endpoint';\nimport { EngineError } from 'entities/EngineError';\nimport { LifecycleController } from 'entities/LifecycleController';\nimport { PubSub } from 'entities/PubSub';\nimport { checkEnvironment, envAssert, createHttpServer } from 'utils';\nimport { initKeySets, shutdownKeySets } from 'utils/jwt';\nimport { reportInfo, reportError, reportDebug } from 'utils/report';\nimport { tlsConfig, loadTlsConfig, TlsConfig } from 'utils/tlsConfig';\n\nconst namespace = 'engine:Server';\n\n/** Main server class */\nexport class Server {\n /** The express application powering the main endpoints */\n private app: Application;\n /** The node HTTP(S) server, serving the main express application */\n private httpServer: http.Server | https.Server;\n /** The express application powering the support endpoints */\n private secondaryApp: Application;\n /** The node HTTP(S) server, serving the secondary express application */\n private secondaryHttpServer: http.Server | https.Server;\n /** List of endpoint instances that the server should handle */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private endpoints: Array<Endpoint<any>>;\n /** Mapping of env variable name with functions that should run to check their validity */\n private checkEnvironment: Record<string, ValidatorSpec<unknown>>;\n /** Middleware that should run on every request before the endpoint specific logic */\n private globalMiddleware: Array<ServerGlobalMiddleware>;\n /** Error middleware that should run on every request after the endpoint specific logic, but before the generic global middleware */\n private errorMiddleware: Array<\n ServerGlobalMiddleware | ServerErrorMiddleWare\n >;\n /** Functions that should be called on server startup */\n private initCallbacks: Array<ServerCallback>;\n /** Functions that should be called on server shutdown */\n private shutdownCallbacks: Array<ServerCallback>;\n /** When set to true, this indicates that init callbacks should run synchronously in the order they are declared. By default they all run in parallel */\n private syncCallbacks: boolean;\n /** Config to set regularly running jobs on the server */\n private cron?: Array<ServerCronJon>;\n /** Global auth related configuration */\n private auth: ServerAuthConfig;\n /** WebSocket server instance, if configured */\n private wss?: WebSocketServer;\n /** Abort controller that handles signals for the server */\n private abortController = new AbortController();\n\n /** Create a server */\n public constructor(config: ServerOptions) {\n this.validate(config);\n\n reportDebug({\n namespace,\n message: `Creating server`\n });\n\n this.endpoints = config.endpoints;\n this.globalMiddleware = config.globalMiddleware ?? [];\n this.errorMiddleware = config.errorMiddleware ?? [];\n this.initCallbacks = config.initCallbacks ?? [];\n this.shutdownCallbacks = config.shutdownCallbacks ?? [];\n this.syncCallbacks = config.syncCallbacks ?? false;\n this.cron = config.cron;\n this.auth = { noFetch: false, ...config.auth };\n\n // The minimal environment check is different between the migration modes of execution and the regular server execution mode\n // When running in migration mode, we only check that we have SQL related environment variables\n this.checkEnvironment =\n process.env.RUN_MIGRATION === 'true' ||\n process.env.UNDO_MIGRATION === 'true'\n ? {\n SQL_HOST: envAssert.isHost(),\n SQL_USER: envAssert.isString(),\n SQL_PASSWORD: envAssert.isString(),\n SQL_DB: envAssert.isString()\n }\n : {\n NODE_ENV: envAssert.isString(),\n PORT: envAssert.isPort(),\n SECONDARY_PORT: envAssert.isPort(),\n ...config.checkEnvironment\n };\n\n checkEnvironment(this.checkEnvironment);\n\n // Create the primary express core that serves the business logic\n this.app = express();\n\n // small request logger + memory snapshot on response finish\n this.app.use((req, res, next) => {\n const start = Date.now();\n console.log(\n `[REQ START] ${req.method} ${req.originalUrl} ip=${req.ip} nodeEnv=${process.env.NODE_ENV}`\n );\n res.on('finish', () => {\n const time = Date.now() - start;\n const mem = process.memoryUsage();\n console.log(\n `[REQ END] ${req.method} ${req.originalUrl} status=${res.statusCode} timeMs=${time} rss=${mem.rss} heapUsed=${mem.heapUsed}`\n );\n });\n next();\n });\n\n this.app.use(\n cors({\n origin: process.env.CORS_ORIGIN ?? '*',\n methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],\n allowedHeaders: ['Content-Type', 'Authorization']\n })\n );\n\n this.app.get('/test1', (req, res) => {\n console.log('Test endpoint hit');\n res.status(200).json({ status: 'ok' });\n });\n\n this.registerMiddleware(this.app);\n this.httpServer = createHttpServer(this.app);\n\n // Create a secondary express core that servers metrics and analytics\n // This will be served on a different port, allowing to specify different firewall rules for these routes\n this.secondaryApp = express();\n [...secondaryMiddleware, ...defaultErrorMiddleware].forEach(\n (middleware) => {\n if (middleware) this.secondaryApp.use(middleware);\n }\n );\n this.secondaryHttpServer = createHttpServer(this.secondaryApp);\n\n // Remove the express headers\n this.app.disable('x-powered-by');\n this.secondaryApp.disable('x-powered-by');\n\n // We remove all node timeout on connections and requests\n // This responsibility is delegated to the front-facing load balancer\n [this.httpServer, this.secondaryHttpServer].forEach((server) => {\n server.headersTimeout = 0;\n server.keepAliveTimeout = 0;\n });\n\n if (config.webSocket) {\n this.attachWebSocket(config.webSocket);\n }\n }\n\n private setupGlobalErrorLogging(): void {\n process.on('uncaughtException', (err) => {\n console.error(\n '💥 uncaughtException:',\n err && err.stack ? err.stack : err\n );\n });\n process.on('unhandledRejection', (reason: unknown) => {\n if (reason instanceof Error) {\n console.error('💥 unhandledRejection:', reason.stack || reason.message);\n } else {\n console.error('💥 unhandledRejection:', reason);\n }\n });\n process.on('beforeExit', (code) =>\n console.error('process.beforeExit', code)\n );\n process.on('exit', (code) => console.error('process.exit', code));\n process.on('SIGKILL', () => console.error('SIGKILL received')); // usually cannot catch SIGKILL\n process.on('SIGTERM', () => console.error('SIGTERM received'));\n }\n\n /** Start the server */\n public async init(): Promise<void> {\n this.setupGlobalErrorLogging();\n reportDebug({ namespace, message: `Starting Server` });\n // Fetch the keys for JWT authentication\n // Ignore in test environment as we do symmetrical token signing\n if (process.env.NODE_ENV !== 'test' && !this.auth.noFetch)\n await initKeySets();\n // Run all the init callbacks\n // We can either run them all 1/1 synchronously or run them all in parallel (default)\n // Callback can either be direct function or an object with function and parameters attributes\n\n if (this.syncCallbacks) {\n for (const callback of this.initCallbacks) {\n await this.runCallback(callback);\n }\n } else {\n await Promise.all(\n this.initCallbacks.map((callback) => this.runCallback(callback))\n );\n }\n\n // Initialize the Pub/Sub module\n await PubSub.init();\n // Run all the cronjob\n if (this.cron) {\n this.cron.forEach((job) => {\n this.runCronJob(job);\n });\n }\n\n // Start listening to requests\n await Promise.all([\n new Promise<void>((resolve) =>\n this.httpServer.listen(process.env.PORT, () => {\n resolve();\n })\n ),\n new Promise<void>((resolve) =>\n this.secondaryHttpServer.listen(process.env.SECONDARY_PORT, () => {\n resolve();\n })\n )\n ]);\n reportInfo({\n message: 'SERVER_RUNNING',\n data: {\n port: process.env.PORT,\n secondaryPort: process.env.SECONDARY_PORT,\n nodeEnv: process.env.NODE_ENV\n }\n });\n\n this.handleSignal();\n\n // Load TSL config files\n this.loadTls();\n }\n\n /** Graceful shutdown */\n public async shutdown(): Promise<void> {\n reportDebug({ namespace, message: `Shutting down Server` });\n\n // Stop listening to HTTP requests\n await Promise.all(\n [this.httpServer, this.secondaryHttpServer].map((server) => {\n // Ignore if the server was already stopped\n // We have observed cases where SIGTERM was thrown multiple times\n if (!server.listening) return;\n const { port } = server.address() as AddressInfo;\n server.on('close', (error: unknown) => {\n if (error) {\n reportError(error);\n process.exit(1);\n } else {\n reportInfo({\n message: `Stopped listening to requests on port ${port}`\n });\n }\n });\n server.close();\n })\n );\n\n // Close all socket connections\n if (this.wss) {\n // First ask then to close gracefully\n this.wss.clients.forEach((socket) => {\n socket.close();\n });\n // Hard terminate all connections still open after a defined time\n const socketKillTimeout = process.env.WEBSOCKET_CLOSE_TIMEOUT\n ? parseInt(process.env.WEBSOCKET_CLOSE_TIMEOUT)\n : 5000;\n await new Promise<void>((resolve) => {\n setTimeout(() => {\n (this.wss as WebSocketServer).clients.forEach((socket) => {\n if (\n socket.readyState === socket.CLOSING ||\n socket.readyState === socket.OPEN\n ) {\n socket.terminate();\n }\n });\n resolve();\n }, socketKillTimeout);\n });\n }\n\n // Run all the shutdown callback\n if (this.syncCallbacks) {\n for (const callback of this.shutdownCallbacks) {\n await this.runCallback(callback);\n }\n } else {\n await Promise.all(\n this.shutdownCallbacks.map((callback) => this.runCallback(callback))\n );\n }\n\n // Shutdown all the running entities\n await LifecycleController.shutdownRunningInstances();\n\n // Abort all the cronjob\n if (this.abortController) this.abortController.abort();\n\n // Stop the keyset timers\n shutdownKeySets();\n\n shutdownSignals.forEach((signal) => process.removeAllListeners(signal));\n }\n\n /** Get the express app instance of the server */\n public getApp(): Application {\n return this.app;\n }\n\n /** Get the express app instance of the server */\n public getSecondaryApp(): Application {\n return this.secondaryApp;\n }\n\n /** Registers all the middleware with the express app */\n private registerMiddleware(app: Application): void {\n // Global middleware can specify a path to which they apply\n [...defaultMiddleware, ...this.globalMiddleware].forEach((middleware) => {\n if (typeof middleware === 'function') {\n app.use(middleware);\n } else {\n app.use(middleware.path, middleware.middleware);\n }\n });\n // Call the register method of each endpoint\n this.endpoints.forEach((endpoint) => {\n endpoint.register(app);\n });\n // Add error middleware\n [...this.errorMiddleware, ...defaultErrorMiddleware].forEach(\n (middleware) => {\n if (typeof middleware === 'function') {\n app.use(middleware);\n } else {\n app.use(middleware.path, middleware.middleware);\n }\n }\n );\n }\n\n /** Add a handler for WebSocket connections */\n private attachWebSocket(options: ServerWebSocketConfig): void {\n this.wss = new WebSocketServer({\n ...options.server,\n server: this.httpServer\n })\n .on('connection', (webSocket, request) => {\n new SocketClient(webSocket, request, options.client);\n })\n .on('error', (error) => {\n reportError(error);\n });\n }\n\n /** Call shutdown if signal gets sent to the process */\n private handleSignal(): void {\n shutdownSignals.forEach((signal) =>\n process.on(signal, () => {\n (async (): Promise<void> => {\n reportInfo(`Received shutdown signal [${signal}]`);\n await this.shutdown();\n })().catch((error) => {\n reportError(error);\n });\n })\n );\n }\n\n /** Load TLS Config */\n private loadTls(): void {\n try {\n reportInfo('Loading TLS config');\n loadTlsConfig();\n (this.httpServer as https.Server).setSecureContext(\n tlsConfig as TlsConfig\n );\n reportInfo('TLS config loaded successfully');\n } catch (err) {\n reportError(`TLS load failed: ${err}`);\n }\n }\n\n /** Executes a recurring job */\n private runCronJob(job: ServerCronJon): void {\n (async (): Promise<void> => {\n reportInfo({ message: `Starting scheduled job \"${job.handler.name}\"` });\n try {\n await job.handler();\n reportInfo({\n message: `Job \"${job.handler.name}\" finished, starting again in ${job.interval} seconds`\n });\n await setTimeoutPromise(job.interval * 1000, undefined, {\n signal: this.abortController.signal\n });\n this.runCronJob(job);\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') {\n reportDebug({\n namespace,\n message: `Scheduled job \"${job.handler?.name}\" has been aborted`\n });\n } else {\n throw error;\n }\n }\n })().catch((error) => {\n reportError(error);\n });\n }\n\n /** Run a shutdown/init callback */\n private runCallback(callback: ServerCallback): unknown {\n return typeof callback === 'function'\n ? callback()\n : callback.function.apply(null, callback.parameters ?? []);\n }\n\n /**\n * Validate the Server constructor configuration\n */\n private validate(config: ServerOptions): void {\n if (\n !config.endpoints ||\n config.endpoints.some((endpoint) => !(endpoint instanceof Endpoint))\n )\n throw new EngineError(\n 'Server endpoints should be declared and all be Endpoint instances'\n );\n\n if (\n config.checkEnvironment &&\n Object.values(config.checkEnvironment).some(\n (validator) => typeof validator !== 'function'\n )\n )\n throw new EngineError(\n 'Some of the environment checks are not valid functions'\n );\n\n if (\n config.initCallbacks &&\n (!(config.initCallbacks instanceof Array) ||\n config.initCallbacks.some(\n (callback) =>\n !(\n typeof callback === 'function' ||\n typeof callback?.function === 'function'\n )\n ))\n )\n throw new EngineError('Init callbacks is not a list of functions');\n\n if (\n config.shutdownCallbacks &&\n (!(config.shutdownCallbacks instanceof Array) ||\n config.shutdownCallbacks.some(\n (callback) =>\n !(\n typeof callback === 'function' ||\n typeof callback?.function === 'function'\n )\n ))\n )\n throw new EngineError('Shutdown callbacks is not a list of functions');\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"Server.js","names":["_fs","_interopRequireDefault","require","_path","_promises","_express","_cors","_ws","_SocketClient","_Server2","_Endpoint","_EngineError","_LifecycleController","_PubSub","_utils","_jwt","_report","_tlsConfig","namespace","Server","exports","config","_classCallCheck2","default","_defineProperty2","AbortController","validate","reportDebug","message","endpoints","globalMiddleware","errorMiddleware","initCallbacks","shutdownCallbacks","syncCallbacks","cron","auth","noFetch","checkEnvironment","process","env","RUN_MIGRATION","UNDO_MIGRATION","SQL_HOST","envAssert","isHost","SQL_USER","isString","SQL_PASSWORD","SQL_DB","NODE_ENV","PORT","isPort","SECONDARY_PORT","app","express","use","cors","origin","CORS_ORIGIN","methods","allowedHeaders","registerMiddleware","httpServer","createHttpServer","secondaryApp","secondaryMiddleware","defaultErrorMiddleware","forEach","middleware","secondaryHttpServer","disable","server","headersTimeout","keepAliveTimeout","webSocket","attachWebSocket","_createClass2","key","value","setupGlobalErrorLogging","on","err","console","error","stack","reason","Error","code","init","initKeySets","callback","runCallback","Promise","all","map","PubSub","job","runCronJob","resolve","listen","reportInfo","data","port","secondaryPort","nodeEnv","handleSignal","watchTlsCaFileChange","shutdown","listening","address","reportError","exit","close","wss","clients","socket","socketKillTimeout","WEBSOCKET_CLOSE_TIMEOUT","parseInt","setTimeout","readyState","CLOSING","OPEN","terminate","LifecycleController","shutdownRunningInstances","abortController","abort","shutdownKeySets","shutdownSignals","signal","removeAllListeners","getApp","getSecondaryApp","defaultMiddleware","path","endpoint","register","options","WebSocketServer","request","SocketClient","client","catch","file","fs","watch","event","loadTlsConfig","setSecureContext","tlsConfig","handler","name","interval","setTimeoutPromise","undefined","function","apply","parameters","some","Endpoint","EngineError","Object","values","validator","Array"],"sources":["../../../src/entities/Server/Server.ts"],"sourcesContent":["import fs from 'fs';\nimport http from 'http';\nimport https from 'https';\nimport { AddressInfo } from 'net';\nimport path from 'path';\nimport { setTimeout as setTimeoutPromise } from 'timers/promises';\nimport { ValidatorSpec } from 'envalid';\nimport express, { Application } from 'express';\nimport cors from 'cors';\nimport { Server as WebSocketServer } from 'ws';\nimport { SocketClient } from '../SocketClient';\nimport {\n defaultMiddleware,\n defaultErrorMiddleware,\n secondaryMiddleware,\n shutdownSignals\n} from './Server.const';\nimport {\n ServerOptions,\n ServerCronJon,\n ServerAuthConfig,\n ServerWebSocketConfig,\n ServerGlobalMiddleware,\n ServerErrorMiddleWare,\n ServerCallback\n} from './Server.types';\nimport { Endpoint } from 'entities/Endpoint';\nimport { EngineError } from 'entities/EngineError';\nimport { LifecycleController } from 'entities/LifecycleController';\nimport { PubSub } from 'entities/PubSub';\nimport { checkEnvironment, envAssert, createHttpServer } from 'utils';\nimport { initKeySets, shutdownKeySets } from 'utils/jwt';\nimport { reportInfo, reportError, reportDebug } from 'utils/report';\nimport { tlsConfig, loadTlsConfig, TlsConfig } from 'utils/tlsConfig';\n\nconst namespace = 'engine:Server';\n\n/** Main server class */\nexport class Server {\n /** The express application powering the main endpoints */\n private app: Application;\n /** The node HTTP(S) server, serving the main express application */\n private httpServer: http.Server | https.Server;\n /** The express application powering the support endpoints */\n private secondaryApp: Application;\n /** The node HTTP(S) server, serving the secondary express application */\n private secondaryHttpServer: http.Server | https.Server;\n /** List of endpoint instances that the server should handle */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private endpoints: Array<Endpoint<any>>;\n /** Mapping of env variable name with functions that should run to check their validity */\n private checkEnvironment: Record<string, ValidatorSpec<unknown>>;\n /** Middleware that should run on every request before the endpoint specific logic */\n private globalMiddleware: Array<ServerGlobalMiddleware>;\n /** Error middleware that should run on every request after the endpoint specific logic, but before the generic global middleware */\n private errorMiddleware: Array<\n ServerGlobalMiddleware | ServerErrorMiddleWare\n >;\n /** Functions that should be called on server startup */\n private initCallbacks: Array<ServerCallback>;\n /** Functions that should be called on server shutdown */\n private shutdownCallbacks: Array<ServerCallback>;\n /** When set to true, this indicates that init callbacks should run synchronously in the order they are declared. By default they all run in parallel */\n private syncCallbacks: boolean;\n /** Config to set regularly running jobs on the server */\n private cron?: Array<ServerCronJon>;\n /** Global auth related configuration */\n private auth: ServerAuthConfig;\n /** WebSocket server instance, if configured */\n private wss?: WebSocketServer;\n /** Abort controller that handles signals for the server */\n private abortController = new AbortController();\n\n /** Create a server */\n public constructor(config: ServerOptions) {\n this.validate(config);\n\n reportDebug({\n namespace,\n message: `Creating server`\n });\n\n this.endpoints = config.endpoints;\n this.globalMiddleware = config.globalMiddleware ?? [];\n this.errorMiddleware = config.errorMiddleware ?? [];\n this.initCallbacks = config.initCallbacks ?? [];\n this.shutdownCallbacks = config.shutdownCallbacks ?? [];\n this.syncCallbacks = config.syncCallbacks ?? false;\n this.cron = config.cron;\n this.auth = { noFetch: false, ...config.auth };\n\n // The minimal environment check is different between the migration modes of execution and the regular server execution mode\n // When running in migration mode, we only check that we have SQL related environment variables\n this.checkEnvironment =\n process.env.RUN_MIGRATION === 'true' ||\n process.env.UNDO_MIGRATION === 'true'\n ? {\n SQL_HOST: envAssert.isHost(),\n SQL_USER: envAssert.isString(),\n SQL_PASSWORD: envAssert.isString(),\n SQL_DB: envAssert.isString()\n }\n : {\n NODE_ENV: envAssert.isString(),\n PORT: envAssert.isPort(),\n SECONDARY_PORT: envAssert.isPort(),\n ...config.checkEnvironment\n };\n\n checkEnvironment(this.checkEnvironment);\n\n // Create the primary express core that serves the business logic\n this.app = express();\n this.app.use(\n cors({\n origin: process.env.CORS_ORIGIN ?? '*',\n methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],\n allowedHeaders: ['Content-Type', 'Authorization']\n })\n );\n this.registerMiddleware(this.app);\n this.httpServer = createHttpServer(this.app);\n\n // Create a secondary express core that servers metrics and analytics\n // This will be served on a different port, allowing to specify different firewall rules for these routes\n this.secondaryApp = express();\n [...secondaryMiddleware, ...defaultErrorMiddleware].forEach(\n (middleware) => {\n if (middleware) this.secondaryApp.use(middleware);\n }\n );\n this.secondaryHttpServer = createHttpServer(this.secondaryApp);\n\n // Remove the express headers\n this.app.disable('x-powered-by');\n this.secondaryApp.disable('x-powered-by');\n\n // We remove all node timeout on connections and requests\n // This responsibility is delegated to the front-facing load balancer\n [this.httpServer, this.secondaryHttpServer].forEach((server) => {\n server.headersTimeout = 0;\n server.keepAliveTimeout = 0;\n });\n\n if (config.webSocket) {\n this.attachWebSocket(config.webSocket);\n }\n }\n\n private setupGlobalErrorLogging(): void {\n process.on('uncaughtException', (err) => {\n console.error(\n '💥 uncaughtException:',\n err && err.stack ? err.stack : err\n );\n });\n process.on('unhandledRejection', (reason: unknown) => {\n if (reason instanceof Error) {\n console.error('💥 unhandledRejection:', reason.stack || reason.message);\n } else {\n console.error('💥 unhandledRejection:', reason);\n }\n });\n process.on('beforeExit', (code) =>\n console.error('process.beforeExit', code)\n );\n process.on('exit', (code) => console.error('process.exit', code));\n process.on('SIGKILL', () => console.error('SIGKILL received')); // usually cannot catch SIGKILL\n process.on('SIGTERM', () => console.error('SIGTERM received'));\n }\n\n /** Start the server */\n public async init(): Promise<void> {\n this.setupGlobalErrorLogging();\n reportDebug({ namespace, message: `Starting Server` });\n // Fetch the keys for JWT authentication\n // Ignore in test environment as we do symmetrical token signing\n if (process.env.NODE_ENV !== 'test' && !this.auth.noFetch)\n await initKeySets();\n // Run all the init callbacks\n // We can either run them all 1/1 synchronously or run them all in parallel (default)\n // Callback can either be direct function or an object with function and parameters attributes\n\n if (this.syncCallbacks) {\n for (const callback of this.initCallbacks) {\n await this.runCallback(callback);\n }\n } else {\n await Promise.all(\n this.initCallbacks.map((callback) => this.runCallback(callback))\n );\n }\n\n // Initialize the Pub/Sub module\n await PubSub.init();\n // Run all the cronjob\n if (this.cron) {\n this.cron.forEach((job) => {\n this.runCronJob(job);\n });\n }\n\n // Start listening to requests\n await Promise.all([\n new Promise<void>((resolve) =>\n this.httpServer.listen(process.env.PORT, () => {\n resolve();\n })\n ),\n new Promise<void>((resolve) =>\n this.secondaryHttpServer.listen(process.env.SECONDARY_PORT, () => {\n resolve();\n })\n )\n ]);\n reportInfo({\n message: 'SERVER_RUNNING',\n data: {\n port: process.env.PORT,\n secondaryPort: process.env.SECONDARY_PORT,\n nodeEnv: process.env.NODE_ENV\n }\n });\n\n this.handleSignal();\n\n // Watch TSL config files changing\n this.watchTlsCaFileChange();\n }\n\n /** Graceful shutdown */\n public async shutdown(): Promise<void> {\n reportDebug({ namespace, message: `Shutting down Server` });\n\n // Stop listening to HTTP requests\n await Promise.all(\n [this.httpServer, this.secondaryHttpServer].map((server) => {\n // Ignore if the server was already stopped\n // We have observed cases where SIGTERM was thrown multiple times\n if (!server.listening) return;\n const { port } = server.address() as AddressInfo;\n server.on('close', (error: unknown) => {\n if (error) {\n reportError(error);\n process.exit(1);\n } else {\n reportInfo({\n message: `Stopped listening to requests on port ${port}`\n });\n }\n });\n server.close();\n })\n );\n\n // Close all socket connections\n if (this.wss) {\n // First ask then to close gracefully\n this.wss.clients.forEach((socket) => {\n socket.close();\n });\n // Hard terminate all connections still open after a defined time\n const socketKillTimeout = process.env.WEBSOCKET_CLOSE_TIMEOUT\n ? parseInt(process.env.WEBSOCKET_CLOSE_TIMEOUT)\n : 5000;\n await new Promise<void>((resolve) => {\n setTimeout(() => {\n (this.wss as WebSocketServer).clients.forEach((socket) => {\n if (\n socket.readyState === socket.CLOSING ||\n socket.readyState === socket.OPEN\n ) {\n socket.terminate();\n }\n });\n resolve();\n }, socketKillTimeout);\n });\n }\n\n // Run all the shutdown callback\n if (this.syncCallbacks) {\n for (const callback of this.shutdownCallbacks) {\n await this.runCallback(callback);\n }\n } else {\n await Promise.all(\n this.shutdownCallbacks.map((callback) => this.runCallback(callback))\n );\n }\n\n // Shutdown all the running entities\n await LifecycleController.shutdownRunningInstances();\n\n // Abort all the cronjob\n if (this.abortController) this.abortController.abort();\n\n // Stop the keyset timers\n shutdownKeySets();\n\n shutdownSignals.forEach((signal) => process.removeAllListeners(signal));\n }\n\n /** Get the express app instance of the server */\n public getApp(): Application {\n return this.app;\n }\n\n /** Get the express app instance of the server */\n public getSecondaryApp(): Application {\n return this.secondaryApp;\n }\n\n /** Registers all the middleware with the express app */\n private registerMiddleware(app: Application): void {\n // Global middleware can specify a path to which they apply\n [...defaultMiddleware, ...this.globalMiddleware].forEach((middleware) => {\n if (typeof middleware === 'function') {\n app.use(middleware);\n } else {\n app.use(middleware.path, middleware.middleware);\n }\n });\n // Call the register method of each endpoint\n this.endpoints.forEach((endpoint) => {\n endpoint.register(app);\n });\n // Add error middleware\n [...this.errorMiddleware, ...defaultErrorMiddleware].forEach(\n (middleware) => {\n if (typeof middleware === 'function') {\n app.use(middleware);\n } else {\n app.use(middleware.path, middleware.middleware);\n }\n }\n );\n }\n\n /** Add a handler for WebSocket connections */\n private attachWebSocket(options: ServerWebSocketConfig): void {\n this.wss = new WebSocketServer({\n ...options.server,\n server: this.httpServer\n })\n .on('connection', (webSocket, request) => {\n new SocketClient(webSocket, request, options.client);\n })\n .on('error', (error) => {\n reportError(error);\n });\n }\n\n /** Call shutdown if signal gets sent to the process */\n private handleSignal(): void {\n shutdownSignals.forEach((signal) =>\n process.on(signal, () => {\n (async (): Promise<void> => {\n reportInfo(`Received shutdown signal [${signal}]`);\n await this.shutdown();\n })().catch((error) => {\n reportError(error);\n });\n })\n );\n }\n\n /** Watch the TLS certificate change event */\n private watchTlsCaFileChange(): void {\n [\n 'TLS_REQUEST_KEY',\n 'TLS_REQUEST_KEY_PASSPHRASE',\n 'TLS_REQUEST_CERT',\n 'TLS_REQUEST_CA',\n 'TLS_SERVER_KEY',\n 'TLS_SERVER_KEY_PASSPHRASE',\n 'TLS_SERVER_CERT',\n 'TLS_CA'\n ].forEach((key) => {\n const file = process.env[key];\n if (file)\n fs.watch(path.resolve(file), (event) => {\n if (event !== 'change') return;\n reportInfo(`Reloading TLS config [${file} changed]`);\n loadTlsConfig();\n (this.httpServer as https.Server).setSecureContext(\n tlsConfig as TlsConfig\n );\n });\n });\n }\n\n /** Executes a recurring job */\n private runCronJob(job: ServerCronJon): void {\n (async (): Promise<void> => {\n reportInfo({ message: `Starting scheduled job \"${job.handler.name}\"` });\n try {\n await job.handler();\n reportInfo({\n message: `Job \"${job.handler.name}\" finished, starting again in ${job.interval} seconds`\n });\n await setTimeoutPromise(job.interval * 1000, undefined, {\n signal: this.abortController.signal\n });\n this.runCronJob(job);\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') {\n reportDebug({\n namespace,\n message: `Scheduled job \"${job.handler?.name}\" has been aborted`\n });\n } else {\n throw error;\n }\n }\n })().catch((error) => {\n reportError(error);\n });\n }\n\n /** Run a shutdown/init callback */\n private runCallback(callback: ServerCallback): unknown {\n return typeof callback === 'function'\n ? callback()\n : callback.function.apply(null, callback.parameters ?? []);\n }\n\n /**\n * Validate the Server constructor configuration\n */\n private validate(config: ServerOptions): void {\n if (\n !config.endpoints ||\n config.endpoints.some((endpoint) => !(endpoint instanceof Endpoint))\n )\n throw new EngineError(\n 'Server endpoints should be declared and all be Endpoint instances'\n );\n\n if (\n config.checkEnvironment &&\n Object.values(config.checkEnvironment).some(\n (validator) => typeof validator !== 'function'\n )\n )\n throw new EngineError(\n 'Some of the environment checks are not valid functions'\n );\n\n if (\n config.initCallbacks &&\n (!(config.initCallbacks instanceof Array) ||\n config.initCallbacks.some(\n (callback) =>\n !(\n typeof callback === 'function' ||\n typeof callback?.function === 'function'\n )\n ))\n )\n throw new EngineError('Init callbacks is not a list of functions');\n\n if (\n config.shutdownCallbacks &&\n (!(config.shutdownCallbacks instanceof Array) ||\n config.shutdownCallbacks.some(\n (callback) =>\n !(\n typeof callback === 'function' ||\n typeof callback?.function === 'function'\n )\n ))\n )\n throw new EngineError('Shutdown callbacks is not a list of functions');\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1,8 +1,5 @@
1
1
  import { RequestListener, Server } from 'http';
2
2
  import { Server as SecureServer } from 'https';
3
3
  import { Application } from 'express';
4
- /**
5
- * Create and configure an HTTP/HTTPS server.
6
- * Always uses HTTP in Cloud Run (TLS is terminated by the platform).
7
- */
8
- export declare const createHttpServer: (handler?: Application | RequestListener) => Server | SecureServer;
4
+ /** Create and configure an http/https server */
5
+ export declare function createHttpServer(handler?: Application | RequestListener): Server | SecureServer;
@@ -1,41 +1,30 @@
1
1
  "use strict";
2
2
 
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
3
4
  Object.defineProperty(exports, "__esModule", {
4
5
  value: true
5
6
  });
6
- exports.createHttpServer = void 0;
7
+ exports.createHttpServer = createHttpServer;
8
+ var _fs = _interopRequireDefault(require("fs"));
7
9
  var _http = require("http");
8
10
  var _https = require("https");
9
11
  var _createHttpServer = require("./createHttpServer.validate");
10
- var _ = require("./..");
11
- /**
12
- * Create and configure an HTTP/HTTPS server.
13
- * Always uses HTTP in Cloud Run (TLS is terminated by the platform).
14
- */
15
- const createHttpServer = handler => {
12
+ /** Create and configure an http/https server */
13
+ function createHttpServer(handler) {
14
+ // Validate the environment variables
16
15
  (0, _createHttpServer.validateHttpEnvironment)();
17
-
18
- // Cloud Run and similar managed environments handle TLS externally.
19
- // Detect Cloud Run by K_SERVICE or K_REVISION.
20
- const runningInCloudRun = !!process.env.K_SERVICE || !!process.env.K_REVISION;
21
- if (!runningInCloudRun && process.env.TLS_SERVER_KEY && process.env.TLS_SERVER_CERT) {
22
- const key = (0, _.getSecretOrFile)('TLS_SERVER_KEY');
23
- const cert = (0, _.getSecretOrFile)('TLS_SERVER_CERT');
24
- const ca = process.env.TLS_CA ? (0, _.getSecretOrFile)('TLS_CA') : undefined;
25
- const passphrase = process.env.TLS_SERVER_KEY_PASSPHRASE;
26
- console.log('[createHttpServer] Starting HTTPS server (local mode)');
16
+ // Create a https server if env var are specified
17
+ if (process.env.TLS_SERVER_KEY && process.env.TLS_SERVER_CERT) {
27
18
  return (0, _https.createServer)({
28
- key,
29
- cert,
30
- ca,
31
- passphrase,
19
+ key: _fs.default.readFileSync(process.env.TLS_SERVER_KEY),
20
+ passphrase: process.env.TLS_SERVER_KEY_PASSPHRASE,
21
+ cert: _fs.default.readFileSync(process.env.TLS_SERVER_CERT),
22
+ ca: process.env.TLS_CA ? _fs.default.readFileSync(process.env.TLS_CA) : undefined,
32
23
  requestCert: true,
33
24
  rejectUnauthorized: false
34
25
  }, handler);
35
26
  } else {
36
- console.log('[createHttpServer] Starting HTTP server (Cloud Run or no TLS)');
37
27
  return (0, _http.createServer)(handler);
38
28
  }
39
- };
40
- exports.createHttpServer = createHttpServer;
29
+ }
41
30
  //# sourceMappingURL=createHttpServer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"createHttpServer.js","names":["_http","require","_https","_createHttpServer","_","createHttpServer","handler","validateHttpEnvironment","runningInCloudRun","process","env","K_SERVICE","K_REVISION","TLS_SERVER_KEY","TLS_SERVER_CERT","key","getSecretOrFile","cert","ca","TLS_CA","undefined","passphrase","TLS_SERVER_KEY_PASSPHRASE","console","log","createSecureServer","requestCert","rejectUnauthorized","createServer","exports"],"sources":["../../../src/utils/createHttpServer/createHttpServer.ts"],"sourcesContent":["import { 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';\nimport { getSecretOrFile } from 'utils';\n\n/**\n * Create and configure an HTTP/HTTPS server.\n * Always uses HTTP in Cloud Run (TLS is terminated by the platform).\n */\nexport const createHttpServer = (\n handler?: Application | RequestListener\n): Server | SecureServer => {\n validateHttpEnvironment();\n\n // Cloud Run and similar managed environments handle TLS externally.\n // Detect Cloud Run by K_SERVICE or K_REVISION.\n const runningInCloudRun = !!process.env.K_SERVICE || !!process.env.K_REVISION;\n\n if (\n !runningInCloudRun &&\n process.env.TLS_SERVER_KEY &&\n process.env.TLS_SERVER_CERT\n ) {\n const key = getSecretOrFile('TLS_SERVER_KEY');\n const cert = getSecretOrFile('TLS_SERVER_CERT');\n const ca = process.env.TLS_CA ? getSecretOrFile('TLS_CA') : undefined;\n const passphrase = process.env.TLS_SERVER_KEY_PASSPHRASE;\n\n console.log('[createHttpServer] Starting HTTPS server (local mode)');\n return createSecureServer(\n {\n key,\n cert,\n ca,\n passphrase,\n requestCert: true,\n rejectUnauthorized: false\n },\n handler\n );\n } else {\n console.log(\n '[createHttpServer] Starting HTTP server (Cloud Run or no TLS)'\n );\n return createServer(handler);\n }\n};\n"],"mappings":";;;;;;AAAA,IAAAA,KAAA,GAAAC,OAAA;AACA,IAAAC,MAAA,GAAAD,OAAA;AAKA,IAAAE,iBAAA,GAAAF,OAAA;AACA,IAAAG,CAAA,GAAAH,OAAA;AAEA;AACA;AACA;AACA;AACO,MAAMI,gBAAgB,GAC3BC,OAAuC,IACb;EAC1B,IAAAC,yCAAuB,EAAC,CAAC;;EAEzB;EACA;EACA,MAAMC,iBAAiB,GAAG,CAAC,CAACC,OAAO,CAACC,GAAG,CAACC,SAAS,IAAI,CAAC,CAACF,OAAO,CAACC,GAAG,CAACE,UAAU;EAE7E,IACE,CAACJ,iBAAiB,IAClBC,OAAO,CAACC,GAAG,CAACG,cAAc,IAC1BJ,OAAO,CAACC,GAAG,CAACI,eAAe,EAC3B;IACA,MAAMC,GAAG,GAAG,IAAAC,iBAAe,EAAC,gBAAgB,CAAC;IAC7C,MAAMC,IAAI,GAAG,IAAAD,iBAAe,EAAC,iBAAiB,CAAC;IAC/C,MAAME,EAAE,GAAGT,OAAO,CAACC,GAAG,CAACS,MAAM,GAAG,IAAAH,iBAAe,EAAC,QAAQ,CAAC,GAAGI,SAAS;IACrE,MAAMC,UAAU,GAAGZ,OAAO,CAACC,GAAG,CAACY,yBAAyB;IAExDC,OAAO,CAACC,GAAG,CAAC,uDAAuD,CAAC;IACpE,OAAO,IAAAC,mBAAkB,EACvB;MACEV,GAAG;MACHE,IAAI;MACJC,EAAE;MACFG,UAAU;MACVK,WAAW,EAAE,IAAI;MACjBC,kBAAkB,EAAE;IACtB,CAAC,EACDrB,OACF,CAAC;EACH,CAAC,MAAM;IACLiB,OAAO,CAACC,GAAG,CACT,+DACF,CAAC;IACD,OAAO,IAAAI,kBAAY,EAACtB,OAAO,CAAC;EAC9B;AACF,CAAC;AAACuB,OAAA,CAAAxB,gBAAA,GAAAA,gBAAA","ignoreList":[]}
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: false\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":[]}
@@ -1,3 +1,2 @@
1
1
  export * from './tlsConfig';
2
2
  export * from './tlsConfig.types';
3
- export * from './httpsAgent';
@@ -25,15 +25,4 @@ Object.keys(_tlsConfig2).forEach(function (key) {
25
25
  }
26
26
  });
27
27
  });
28
- var _httpsAgent = require("./httpsAgent");
29
- Object.keys(_httpsAgent).forEach(function (key) {
30
- if (key === "default" || key === "__esModule") return;
31
- if (key in exports && exports[key] === _httpsAgent[key]) return;
32
- Object.defineProperty(exports, key, {
33
- enumerable: true,
34
- get: function () {
35
- return _httpsAgent[key];
36
- }
37
- });
38
- });
39
28
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["_tlsConfig","require","Object","keys","forEach","key","exports","defineProperty","enumerable","get","_tlsConfig2","_httpsAgent"],"sources":["../../../src/utils/tlsConfig/index.ts"],"sourcesContent":["export * from './tlsConfig';\nexport * from './tlsConfig.types';\nexport * from './httpsAgent';\n"],"mappings":";;;;;AAAA,IAAAA,UAAA,GAAAC,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAH,UAAA,EAAAI,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAL,UAAA,CAAAK,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAT,UAAA,CAAAK,GAAA;IAAA;EAAA;AAAA;AACA,IAAAK,WAAA,GAAAT,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAO,WAAA,EAAAN,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAK,WAAA,CAAAL,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAC,WAAA,CAAAL,GAAA;IAAA;EAAA;AAAA;AACA,IAAAM,WAAA,GAAAV,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAQ,WAAA,EAAAP,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAM,WAAA,CAAAN,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAE,WAAA,CAAAN,GAAA;IAAA;EAAA;AAAA","ignoreList":[]}
1
+ {"version":3,"file":"index.js","names":["_tlsConfig","require","Object","keys","forEach","key","exports","defineProperty","enumerable","get","_tlsConfig2"],"sources":["../../../src/utils/tlsConfig/index.ts"],"sourcesContent":["export * from './tlsConfig';\nexport * from './tlsConfig.types';\n"],"mappings":";;;;;AAAA,IAAAA,UAAA,GAAAC,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAH,UAAA,EAAAI,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAL,UAAA,CAAAK,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAT,UAAA,CAAAK,GAAA;IAAA;EAAA;AAAA;AACA,IAAAK,WAAA,GAAAT,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAO,WAAA,EAAAN,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAK,WAAA,CAAAL,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAC,WAAA,CAAAL,GAAA;IAAA;EAAA;AAAA","ignoreList":[]}
@@ -3,6 +3,6 @@ import { TlsConfig } from './tlsConfig.types';
3
3
  export declare let tlsConfig: undefined | TlsConfig;
4
4
  export declare let httpsAgent: undefined | Agent;
5
5
  /**
6
- * Load TLS config by its environment setting (local files or GCP secrets)
6
+ * Load TLS config by its Environment setting.
7
7
  */
8
8
  export declare function loadTlsConfig(): void;
@@ -7,37 +7,26 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.httpsAgent = void 0;
8
8
  exports.loadTlsConfig = loadTlsConfig;
9
9
  exports.tlsConfig = void 0;
10
+ var _fs = _interopRequireDefault(require("fs"));
10
11
  var _https = _interopRequireDefault(require("https"));
11
12
  var _tlsConfig = require("./tlsConfig.validate");
12
13
  var _EngineError = require("../../entities/EngineError");
13
- var _ = require("./..");
14
14
  let tlsConfig = exports.tlsConfig = void 0;
15
15
  let httpsAgent = exports.httpsAgent = void 0;
16
16
 
17
17
  /**
18
- * Load TLS config by its environment setting (local files or GCP secrets)
18
+ * Load TLS config by its Environment setting.
19
19
  */
20
20
  function loadTlsConfig() {
21
+ // Check that environment variables are correctly set
21
22
  (0, _tlsConfig.validateTlsConfig)();
22
23
  exports.tlsConfig = tlsConfig = undefined;
23
- const runningInCloudRun = !!process.env.K_SERVICE || !!process.env.K_REVISION;
24
- if (runningInCloudRun) {
25
- console.log('[loadTlsConfig] Skipping TLS config load (Cloud Run)');
26
- return;
27
- }
28
24
  if (process.env.TLS_REQUEST_KEY || process.env.TLS_SERVER_KEY) {
29
- // Fetch TLS secrets using unified utility
30
- const key = (0, _.getSecretOrFile)('TLS_SERVER_KEY');
31
- const cert = (0, _.getSecretOrFile)('TLS_SERVER_CERT');
32
- const ca = (0, _.getSecretOrFile)('TLS_CA');
33
-
34
- // Passphrase is read directly from env variables
35
- const passphrase = process.env.TLS_REQUEST_KEY_PASSPHRASE ?? process.env.TLS_SERVER_KEY_PASSPHRASE;
36
25
  exports.tlsConfig = tlsConfig = {
37
- key,
38
- cert,
39
- ca,
40
- passphrase
26
+ key: _fs.default.readFileSync(process.env.TLS_REQUEST_KEY ?? process.env.TLS_SERVER_KEY, 'utf-8'),
27
+ cert: _fs.default.readFileSync(process.env.TLS_REQUEST_CERT ?? process.env.TLS_SERVER_CERT, 'utf-8'),
28
+ ca: _fs.default.readFileSync(process.env.TLS_REQUEST_CA ?? process.env.TLS_CA, 'utf-8'),
29
+ passphrase: process.env.TLS_REQUEST_KEY_PASSPHRASE ?? process.env.TLS_SERVER_KEY_PASSPHRASE
41
30
  };
42
31
  exports.httpsAgent = httpsAgent = new _https.default.Agent({
43
32
  key: tlsConfig.key,
@@ -46,7 +35,7 @@ function loadTlsConfig() {
46
35
  passphrase: tlsConfig.passphrase
47
36
  });
48
37
  }
49
- if (!tlsConfig || !(tlsConfig.key && tlsConfig.cert && tlsConfig.ca)) {
38
+ if (!tlsConfig || !(tlsConfig.ca && tlsConfig.cert && tlsConfig.key)) {
50
39
  throw new _EngineError.EngineError({
51
40
  message: 'TLS environment variables are not set correctly'
52
41
  });
@@ -1 +1 @@
1
- {"version":3,"file":"tlsConfig.js","names":["_https","_interopRequireDefault","require","_tlsConfig","_EngineError","_","tlsConfig","exports","httpsAgent","loadTlsConfig","validateTlsConfig","undefined","runningInCloudRun","process","env","K_SERVICE","K_REVISION","console","log","TLS_REQUEST_KEY","TLS_SERVER_KEY","key","getSecretOrFile","cert","ca","passphrase","TLS_REQUEST_KEY_PASSPHRASE","TLS_SERVER_KEY_PASSPHRASE","https","Agent","EngineError","message"],"sources":["../../../src/utils/tlsConfig/tlsConfig.ts"],"sourcesContent":["import https, { Agent } from 'https';\nimport { TlsConfig } from './tlsConfig.types';\nimport { validateTlsConfig } from './tlsConfig.validate';\nimport { EngineError } from 'entities/EngineError';\nimport { getSecretOrFile } from 'utils';\n\nexport let tlsConfig: undefined | TlsConfig;\nexport let httpsAgent: undefined | Agent;\n\n/**\n * Load TLS config by its environment setting (local files or GCP secrets)\n */\nexport function loadTlsConfig(): void {\n validateTlsConfig();\n tlsConfig = undefined;\n\n const runningInCloudRun = !!process.env.K_SERVICE || !!process.env.K_REVISION;\n if (runningInCloudRun) {\n console.log('[loadTlsConfig] Skipping TLS config load (Cloud Run)');\n return;\n }\n\n if (process.env.TLS_REQUEST_KEY || process.env.TLS_SERVER_KEY) {\n // Fetch TLS secrets using unified utility\n const key = getSecretOrFile('TLS_SERVER_KEY');\n const cert = getSecretOrFile('TLS_SERVER_CERT');\n const ca = getSecretOrFile('TLS_CA');\n\n // Passphrase is read directly from env variables\n const passphrase =\n process.env.TLS_REQUEST_KEY_PASSPHRASE ??\n process.env.TLS_SERVER_KEY_PASSPHRASE;\n\n tlsConfig = { key, cert, ca, passphrase } as TlsConfig;\n\n httpsAgent = new https.Agent({\n key: tlsConfig.key,\n cert: tlsConfig.cert,\n ca: tlsConfig.ca,\n passphrase: tlsConfig.passphrase\n });\n }\n\n if (!tlsConfig || !(tlsConfig.key && tlsConfig.cert && tlsConfig.ca)) {\n throw new EngineError({\n message: 'TLS environment variables are not set correctly'\n });\n }\n}\n"],"mappings":";;;;;;;;;AAAA,IAAAA,MAAA,GAAAC,sBAAA,CAAAC,OAAA;AAEA,IAAAC,UAAA,GAAAD,OAAA;AACA,IAAAE,YAAA,GAAAF,OAAA;AACA,IAAAG,CAAA,GAAAH,OAAA;AAEO,IAAII,SAAgC,GAAAC,OAAA,CAAAD,SAAA;AACpC,IAAIE,UAA6B,GAAAD,OAAA,CAAAC,UAAA;;AAExC;AACA;AACA;AACO,SAASC,aAAaA,CAAA,EAAS;EACpC,IAAAC,4BAAiB,EAAC,CAAC;EACnBH,OAAA,CAAAD,SAAA,GAAAA,SAAS,GAAGK,SAAS;EAErB,MAAMC,iBAAiB,GAAG,CAAC,CAACC,OAAO,CAACC,GAAG,CAACC,SAAS,IAAI,CAAC,CAACF,OAAO,CAACC,GAAG,CAACE,UAAU;EAC7E,IAAIJ,iBAAiB,EAAE;IACrBK,OAAO,CAACC,GAAG,CAAC,sDAAsD,CAAC;IACnE;EACF;EAEA,IAAIL,OAAO,CAACC,GAAG,CAACK,eAAe,IAAIN,OAAO,CAACC,GAAG,CAACM,cAAc,EAAE;IAC7D;IACA,MAAMC,GAAG,GAAG,IAAAC,iBAAe,EAAC,gBAAgB,CAAC;IAC7C,MAAMC,IAAI,GAAG,IAAAD,iBAAe,EAAC,iBAAiB,CAAC;IAC/C,MAAME,EAAE,GAAG,IAAAF,iBAAe,EAAC,QAAQ,CAAC;;IAEpC;IACA,MAAMG,UAAU,GACdZ,OAAO,CAACC,GAAG,CAACY,0BAA0B,IACtCb,OAAO,CAACC,GAAG,CAACa,yBAAyB;IAEvCpB,OAAA,CAAAD,SAAA,GAAAA,SAAS,GAAG;MAAEe,GAAG;MAAEE,IAAI;MAAEC,EAAE;MAAEC;IAAW,CAAc;IAEtDlB,OAAA,CAAAC,UAAA,GAAAA,UAAU,GAAG,IAAIoB,cAAK,CAACC,KAAK,CAAC;MAC3BR,GAAG,EAAEf,SAAS,CAACe,GAAG;MAClBE,IAAI,EAAEjB,SAAS,CAACiB,IAAI;MACpBC,EAAE,EAAElB,SAAS,CAACkB,EAAE;MAChBC,UAAU,EAAEnB,SAAS,CAACmB;IACxB,CAAC,CAAC;EACJ;EAEA,IAAI,CAACnB,SAAS,IAAI,EAAEA,SAAS,CAACe,GAAG,IAAIf,SAAS,CAACiB,IAAI,IAAIjB,SAAS,CAACkB,EAAE,CAAC,EAAE;IACpE,MAAM,IAAIM,wBAAW,CAAC;MACpBC,OAAO,EAAE;IACX,CAAC,CAAC;EACJ;AACF","ignoreList":[]}
1
+ {"version":3,"file":"tlsConfig.js","names":["_fs","_interopRequireDefault","require","_https","_tlsConfig","_EngineError","tlsConfig","exports","httpsAgent","loadTlsConfig","validateTlsConfig","undefined","process","env","TLS_REQUEST_KEY","TLS_SERVER_KEY","key","fs","readFileSync","cert","TLS_REQUEST_CERT","TLS_SERVER_CERT","ca","TLS_REQUEST_CA","TLS_CA","passphrase","TLS_REQUEST_KEY_PASSPHRASE","TLS_SERVER_KEY_PASSPHRASE","https","Agent","EngineError","message"],"sources":["../../../src/utils/tlsConfig/tlsConfig.ts"],"sourcesContent":["import fs from 'fs';\nimport https, { Agent } from 'https';\nimport { TlsConfig } from './tlsConfig.types';\nimport { validateTlsConfig } from './tlsConfig.validate';\nimport { EngineError } from 'entities/EngineError';\n\nexport let tlsConfig: undefined | TlsConfig;\nexport let httpsAgent: undefined | Agent;\n\n/**\n * Load TLS config by its Environment setting.\n */\nexport function loadTlsConfig(): void {\n // Check that environment variables are correctly set\n validateTlsConfig();\n tlsConfig = undefined;\n\n if (process.env.TLS_REQUEST_KEY || process.env.TLS_SERVER_KEY) {\n tlsConfig = {\n key: fs.readFileSync(\n (process.env.TLS_REQUEST_KEY ?? process.env.TLS_SERVER_KEY) as string,\n 'utf-8'\n ),\n cert: fs.readFileSync(\n (process.env.TLS_REQUEST_CERT ?? process.env.TLS_SERVER_CERT) as string,\n 'utf-8'\n ),\n ca: fs.readFileSync(\n (process.env.TLS_REQUEST_CA ?? process.env.TLS_CA) as string,\n 'utf-8'\n ),\n passphrase: (process.env.TLS_REQUEST_KEY_PASSPHRASE ??\n process.env.TLS_SERVER_KEY_PASSPHRASE) as string\n } as TlsConfig;\n httpsAgent = new https.Agent({\n key: tlsConfig.key,\n cert: tlsConfig.cert,\n ca: tlsConfig.ca,\n passphrase: tlsConfig.passphrase\n });\n }\n if (!tlsConfig || !(tlsConfig.ca && tlsConfig.cert && tlsConfig.key)) {\n throw new EngineError({\n message: 'TLS environment variables are not set correctly'\n });\n }\n}\n"],"mappings":";;;;;;;;;AAAA,IAAAA,GAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,MAAA,GAAAF,sBAAA,CAAAC,OAAA;AAEA,IAAAE,UAAA,GAAAF,OAAA;AACA,IAAAG,YAAA,GAAAH,OAAA;AAEO,IAAII,SAAgC,GAAAC,OAAA,CAAAD,SAAA;AACpC,IAAIE,UAA6B,GAAAD,OAAA,CAAAC,UAAA;;AAExC;AACA;AACA;AACO,SAASC,aAAaA,CAAA,EAAS;EACpC;EACA,IAAAC,4BAAiB,EAAC,CAAC;EACnBH,OAAA,CAAAD,SAAA,GAAAA,SAAS,GAAGK,SAAS;EAErB,IAAIC,OAAO,CAACC,GAAG,CAACC,eAAe,IAAIF,OAAO,CAACC,GAAG,CAACE,cAAc,EAAE;IAC7DR,OAAA,CAAAD,SAAA,GAAAA,SAAS,GAAG;MACVU,GAAG,EAAEC,WAAE,CAACC,YAAY,CACjBN,OAAO,CAACC,GAAG,CAACC,eAAe,IAAIF,OAAO,CAACC,GAAG,CAACE,cAAc,EAC1D,OACF,CAAC;MACDI,IAAI,EAAEF,WAAE,CAACC,YAAY,CAClBN,OAAO,CAACC,GAAG,CAACO,gBAAgB,IAAIR,OAAO,CAACC,GAAG,CAACQ,eAAe,EAC5D,OACF,CAAC;MACDC,EAAE,EAAEL,WAAE,CAACC,YAAY,CAChBN,OAAO,CAACC,GAAG,CAACU,cAAc,IAAIX,OAAO,CAACC,GAAG,CAACW,MAAM,EACjD,OACF,CAAC;MACDC,UAAU,EAAGb,OAAO,CAACC,GAAG,CAACa,0BAA0B,IACjDd,OAAO,CAACC,GAAG,CAACc;IAChB,CAAc;IACdpB,OAAA,CAAAC,UAAA,GAAAA,UAAU,GAAG,IAAIoB,cAAK,CAACC,KAAK,CAAC;MAC3Bb,GAAG,EAAEV,SAAS,CAACU,GAAG;MAClBG,IAAI,EAAEb,SAAS,CAACa,IAAI;MACpBG,EAAE,EAAEhB,SAAS,CAACgB,EAAE;MAChBG,UAAU,EAAEnB,SAAS,CAACmB;IACxB,CAAC,CAAC;EACJ;EACA,IAAI,CAACnB,SAAS,IAAI,EAAEA,SAAS,CAACgB,EAAE,IAAIhB,SAAS,CAACa,IAAI,IAAIb,SAAS,CAACU,GAAG,CAAC,EAAE;IACpE,MAAM,IAAIc,wBAAW,CAAC;MACpBC,OAAO,EAAE;IACX,CAAC,CAAC;EACJ;AACF","ignoreList":[]}
@@ -1,3 +1,3 @@
1
1
  import { AxiosRequestConfig, AxiosResponse } from 'axios';
2
2
  /** Make a network request using TLS, this exposes the server client certificates to the destination */
3
- export declare const tlsRequest: <T = unknown>(options: AxiosRequestConfig) => Promise<AxiosResponse<T>>;
3
+ export declare function tlsRequest<T = unknown>(options: AxiosRequestConfig): Promise<AxiosResponse<T>>;
@@ -3,15 +3,16 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.tlsRequest = void 0;
6
+ exports.tlsRequest = tlsRequest;
7
7
  var _request = require("../request");
8
- var _httpsAgent = require("../tlsConfig/httpsAgent");
8
+ var _tlsConfig = require("../tlsConfig");
9
9
  /** Make a network request using TLS, this exposes the server client certificates to the destination */
10
- const tlsRequest = async options => {
10
+ async function tlsRequest(options) {
11
+ // if the config is not initial, will do that.
12
+ if (!_tlsConfig.httpsAgent) (0, _tlsConfig.loadTlsConfig)();
11
13
  return (0, _request.request)({
12
- httpsAgent: (0, _httpsAgent.getHttpsAgent)(),
14
+ httpsAgent: _tlsConfig.httpsAgent,
13
15
  ...options
14
16
  });
15
- };
16
- exports.tlsRequest = tlsRequest;
17
+ }
17
18
  //# sourceMappingURL=tlsRequest.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tlsRequest.js","names":["_request","require","_httpsAgent","tlsRequest","options","request","httpsAgent","getHttpsAgent","exports"],"sources":["../../../src/utils/tlsRequest/tlsRequest.ts"],"sourcesContent":["import { AxiosRequestConfig, AxiosResponse } from 'axios';\nimport { request } from 'utils/request';\nimport { getHttpsAgent } from 'utils/tlsConfig/httpsAgent';\n/** Make a network request using TLS, this exposes the server client certificates to the destination */\nexport const tlsRequest = async <T = unknown>(\n options: AxiosRequestConfig\n): Promise<AxiosResponse<T>> => {\n return request<T>({\n httpsAgent: getHttpsAgent(),\n ...options\n });\n};\n"],"mappings":";;;;;;AACA,IAAAA,QAAA,GAAAC,OAAA;AACA,IAAAC,WAAA,GAAAD,OAAA;AACA;AACO,MAAME,UAAU,GAAG,MACxBC,OAA2B,IACG;EAC9B,OAAO,IAAAC,gBAAO,EAAI;IAChBC,UAAU,EAAE,IAAAC,yBAAa,EAAC,CAAC;IAC3B,GAAGH;EACL,CAAC,CAAC;AACJ,CAAC;AAACI,OAAA,CAAAL,UAAA,GAAAA,UAAA","ignoreList":[]}
1
+ {"version":3,"file":"tlsRequest.js","names":["_request","require","_tlsConfig","tlsRequest","options","httpsAgent","loadTlsConfig","request"],"sources":["../../../src/utils/tlsRequest/tlsRequest.ts"],"sourcesContent":["import { AxiosRequestConfig, AxiosResponse } from 'axios';\nimport { request } from 'utils/request';\nimport { httpsAgent, loadTlsConfig } from 'utils/tlsConfig';\n\n/** Make a network request using TLS, this exposes the server client certificates to the destination */\nexport async function tlsRequest<T = unknown>(\n options: AxiosRequestConfig\n): Promise<AxiosResponse<T>> {\n // if the config is not initial, will do that.\n if (!httpsAgent) loadTlsConfig();\n return request<T>({ httpsAgent, ...options });\n}\n"],"mappings":";;;;;;AACA,IAAAA,QAAA,GAAAC,OAAA;AACA,IAAAC,UAAA,GAAAD,OAAA;AAEA;AACO,eAAeE,UAAUA,CAC9BC,OAA2B,EACA;EAC3B;EACA,IAAI,CAACC,qBAAU,EAAE,IAAAC,wBAAa,EAAC,CAAC;EAChC,OAAO,IAAAC,gBAAO,EAAI;IAAEF,UAAU,EAAVA,qBAAU;IAAE,GAAGD;EAAQ,CAAC,CAAC;AAC/C","ignoreList":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-server-engine",
3
- "version": "1.4.2",
3
+ "version": "1.4.4",
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": {
@@ -1,6 +1,8 @@
1
+ import fs from 'fs';
1
2
  import http from 'http';
2
3
  import https from 'https';
3
4
  import { AddressInfo } from 'net';
5
+ import path from 'path';
4
6
  import { setTimeout as setTimeoutPromise } from 'timers/promises';
5
7
  import { ValidatorSpec } from 'envalid';
6
8
  import express, { Application } from 'express';
@@ -109,23 +111,6 @@ export class Server {
109
111
 
110
112
  // Create the primary express core that serves the business logic
111
113
  this.app = express();
112
-
113
- // small request logger + memory snapshot on response finish
114
- this.app.use((req, res, next) => {
115
- const start = Date.now();
116
- console.log(
117
- `[REQ START] ${req.method} ${req.originalUrl} ip=${req.ip} nodeEnv=${process.env.NODE_ENV}`
118
- );
119
- res.on('finish', () => {
120
- const time = Date.now() - start;
121
- const mem = process.memoryUsage();
122
- console.log(
123
- `[REQ END] ${req.method} ${req.originalUrl} status=${res.statusCode} timeMs=${time} rss=${mem.rss} heapUsed=${mem.heapUsed}`
124
- );
125
- });
126
- next();
127
- });
128
-
129
114
  this.app.use(
130
115
  cors({
131
116
  origin: process.env.CORS_ORIGIN ?? '*',
@@ -133,12 +118,6 @@ export class Server {
133
118
  allowedHeaders: ['Content-Type', 'Authorization']
134
119
  })
135
120
  );
136
-
137
- this.app.get('/test1', (req, res) => {
138
- console.log('Test endpoint hit');
139
- res.status(200).json({ status: 'ok' });
140
- });
141
-
142
121
  this.registerMiddleware(this.app);
143
122
  this.httpServer = createHttpServer(this.app);
144
123
 
@@ -245,8 +224,8 @@ export class Server {
245
224
 
246
225
  this.handleSignal();
247
226
 
248
- // Load TSL config files
249
- this.loadTls();
227
+ // Watch TSL config files changing
228
+ this.watchTlsCaFileChange();
250
229
  }
251
230
 
252
231
  /** Graceful shutdown */
@@ -386,18 +365,29 @@ export class Server {
386
365
  );
387
366
  }
388
367
 
389
- /** Load TLS Config */
390
- private loadTls(): void {
391
- try {
392
- reportInfo('Loading TLS config');
393
- loadTlsConfig();
394
- (this.httpServer as https.Server).setSecureContext(
395
- tlsConfig as TlsConfig
396
- );
397
- reportInfo('TLS config loaded successfully');
398
- } catch (err) {
399
- reportError(`TLS load failed: ${err}`);
400
- }
368
+ /** Watch the TLS certificate change event */
369
+ private watchTlsCaFileChange(): void {
370
+ [
371
+ 'TLS_REQUEST_KEY',
372
+ 'TLS_REQUEST_KEY_PASSPHRASE',
373
+ 'TLS_REQUEST_CERT',
374
+ 'TLS_REQUEST_CA',
375
+ 'TLS_SERVER_KEY',
376
+ 'TLS_SERVER_KEY_PASSPHRASE',
377
+ 'TLS_SERVER_CERT',
378
+ 'TLS_CA'
379
+ ].forEach((key) => {
380
+ const file = process.env[key];
381
+ if (file)
382
+ fs.watch(path.resolve(file), (event) => {
383
+ if (event !== 'change') return;
384
+ reportInfo(`Reloading TLS config [${file} changed]`);
385
+ loadTlsConfig();
386
+ (this.httpServer as https.Server).setSecureContext(
387
+ tlsConfig as TlsConfig
388
+ );
389
+ });
390
+ });
401
391
  }
402
392
 
403
393
  /** Executes a recurring job */
@@ -1,3 +1,4 @@
1
+ import fs from 'fs';
1
2
  import { createServer, RequestListener, Server } from 'http';
2
3
  import {
3
4
  createServer as createSecureServer,
@@ -5,47 +6,29 @@ import {
5
6
  } from 'https';
6
7
  import { Application } from 'express';
7
8
  import { validateHttpEnvironment } from './createHttpServer.validate';
8
- import { getSecretOrFile } from 'utils';
9
9
 
10
- /**
11
- * Create and configure an HTTP/HTTPS server.
12
- * Always uses HTTP in Cloud Run (TLS is terminated by the platform).
13
- */
14
- export const createHttpServer = (
10
+ /** Create and configure an http/https server */
11
+ export function createHttpServer(
15
12
  handler?: Application | RequestListener
16
- ): Server | SecureServer => {
13
+ ): Server | SecureServer {
14
+ // Validate the environment variables
17
15
  validateHttpEnvironment();
18
-
19
- // Cloud Run and similar managed environments handle TLS externally.
20
- // Detect Cloud Run by K_SERVICE or K_REVISION.
21
- const runningInCloudRun = !!process.env.K_SERVICE || !!process.env.K_REVISION;
22
-
23
- if (
24
- !runningInCloudRun &&
25
- process.env.TLS_SERVER_KEY &&
26
- process.env.TLS_SERVER_CERT
27
- ) {
28
- const key = getSecretOrFile('TLS_SERVER_KEY');
29
- const cert = getSecretOrFile('TLS_SERVER_CERT');
30
- const ca = process.env.TLS_CA ? getSecretOrFile('TLS_CA') : undefined;
31
- const passphrase = process.env.TLS_SERVER_KEY_PASSPHRASE;
32
-
33
- console.log('[createHttpServer] Starting HTTPS server (local mode)');
16
+ // Create a https server if env var are specified
17
+ if (process.env.TLS_SERVER_KEY && process.env.TLS_SERVER_CERT) {
34
18
  return createSecureServer(
35
19
  {
36
- key,
37
- cert,
38
- ca,
39
- passphrase,
20
+ key: fs.readFileSync(process.env.TLS_SERVER_KEY),
21
+ passphrase: process.env.TLS_SERVER_KEY_PASSPHRASE,
22
+ cert: fs.readFileSync(process.env.TLS_SERVER_CERT),
23
+ ca: process.env.TLS_CA
24
+ ? fs.readFileSync(process.env.TLS_CA)
25
+ : undefined,
40
26
  requestCert: true,
41
27
  rejectUnauthorized: false
42
28
  },
43
29
  handler
44
30
  );
45
31
  } else {
46
- console.log(
47
- '[createHttpServer] Starting HTTP server (Cloud Run or no TLS)'
48
- );
49
32
  return createServer(handler);
50
33
  }
51
- };
34
+ }
@@ -1,3 +1,2 @@
1
1
  export * from './tlsConfig';
2
2
  export * from './tlsConfig.types';
3
- export * from './httpsAgent';
@@ -1,38 +1,37 @@
1
+ import fs from 'fs';
1
2
  import https, { Agent } from 'https';
2
3
  import { TlsConfig } from './tlsConfig.types';
3
4
  import { validateTlsConfig } from './tlsConfig.validate';
4
5
  import { EngineError } from 'entities/EngineError';
5
- import { getSecretOrFile } from 'utils';
6
6
 
7
7
  export let tlsConfig: undefined | TlsConfig;
8
8
  export let httpsAgent: undefined | Agent;
9
9
 
10
10
  /**
11
- * Load TLS config by its environment setting (local files or GCP secrets)
11
+ * Load TLS config by its Environment setting.
12
12
  */
13
13
  export function loadTlsConfig(): void {
14
+ // Check that environment variables are correctly set
14
15
  validateTlsConfig();
15
16
  tlsConfig = undefined;
16
17
 
17
- const runningInCloudRun = !!process.env.K_SERVICE || !!process.env.K_REVISION;
18
- if (runningInCloudRun) {
19
- console.log('[loadTlsConfig] Skipping TLS config load (Cloud Run)');
20
- return;
21
- }
22
-
23
18
  if (process.env.TLS_REQUEST_KEY || process.env.TLS_SERVER_KEY) {
24
- // Fetch TLS secrets using unified utility
25
- const key = getSecretOrFile('TLS_SERVER_KEY');
26
- const cert = getSecretOrFile('TLS_SERVER_CERT');
27
- const ca = getSecretOrFile('TLS_CA');
28
-
29
- // Passphrase is read directly from env variables
30
- const passphrase =
31
- process.env.TLS_REQUEST_KEY_PASSPHRASE ??
32
- process.env.TLS_SERVER_KEY_PASSPHRASE;
33
-
34
- tlsConfig = { key, cert, ca, passphrase } as TlsConfig;
35
-
19
+ tlsConfig = {
20
+ key: fs.readFileSync(
21
+ (process.env.TLS_REQUEST_KEY ?? process.env.TLS_SERVER_KEY) as string,
22
+ 'utf-8'
23
+ ),
24
+ cert: fs.readFileSync(
25
+ (process.env.TLS_REQUEST_CERT ?? process.env.TLS_SERVER_CERT) as string,
26
+ 'utf-8'
27
+ ),
28
+ ca: fs.readFileSync(
29
+ (process.env.TLS_REQUEST_CA ?? process.env.TLS_CA) as string,
30
+ 'utf-8'
31
+ ),
32
+ passphrase: (process.env.TLS_REQUEST_KEY_PASSPHRASE ??
33
+ process.env.TLS_SERVER_KEY_PASSPHRASE) as string
34
+ } as TlsConfig;
36
35
  httpsAgent = new https.Agent({
37
36
  key: tlsConfig.key,
38
37
  cert: tlsConfig.cert,
@@ -40,8 +39,7 @@ export function loadTlsConfig(): void {
40
39
  passphrase: tlsConfig.passphrase
41
40
  });
42
41
  }
43
-
44
- if (!tlsConfig || !(tlsConfig.key && tlsConfig.cert && tlsConfig.ca)) {
42
+ if (!tlsConfig || !(tlsConfig.ca && tlsConfig.cert && tlsConfig.key)) {
45
43
  throw new EngineError({
46
44
  message: 'TLS environment variables are not set correctly'
47
45
  });
@@ -1,12 +1,12 @@
1
1
  import { AxiosRequestConfig, AxiosResponse } from 'axios';
2
2
  import { request } from 'utils/request';
3
- import { getHttpsAgent } from 'utils/tlsConfig/httpsAgent';
3
+ import { httpsAgent, loadTlsConfig } from 'utils/tlsConfig';
4
+
4
5
  /** Make a network request using TLS, this exposes the server client certificates to the destination */
5
- export const tlsRequest = async <T = unknown>(
6
+ export async function tlsRequest<T = unknown>(
6
7
  options: AxiosRequestConfig
7
- ): Promise<AxiosResponse<T>> => {
8
- return request<T>({
9
- httpsAgent: getHttpsAgent(),
10
- ...options
11
- });
12
- };
8
+ ): Promise<AxiosResponse<T>> {
9
+ // if the config is not initial, will do that.
10
+ if (!httpsAgent) loadTlsConfig();
11
+ return request<T>({ httpsAgent, ...options });
12
+ }
package/test/env.ts CHANGED
@@ -48,5 +48,6 @@ process.env = {
48
48
  SQL_TYPE: 'mysql',
49
49
  DEFAULT_MESSAGE_AUDIENCE: audience,
50
50
  GOOGLE_AI_KEY: 'AIKEY',
51
+ ACCESS_TOKEN_EXPIRATION_TIME: '2000',
51
52
  ...process.env
52
53
  };
@@ -1,2 +0,0 @@
1
- import { Agent } from 'https';
2
- export declare function getHttpsAgent(): Agent;
@@ -1,37 +0,0 @@
1
- "use strict";
2
-
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
- Object.defineProperty(exports, "__esModule", {
5
- value: true
6
- });
7
- exports.getHttpsAgent = getHttpsAgent;
8
- var _https = _interopRequireDefault(require("https"));
9
- var _tlsConfig = require("./tlsConfig.validate");
10
- var _EngineError = require("../../entities/EngineError");
11
- var _ = require("./..");
12
- let httpsAgent;
13
- function getHttpsAgent() {
14
- if (httpsAgent) return httpsAgent;
15
- (0, _tlsConfig.validateTlsConfig)();
16
-
17
- // Always pass env var *names*, not their values
18
- const key = (0, _.getSecretOrFile)(process.env.TLS_REQUEST_KEY ? 'TLS_REQUEST_KEY' : 'TLS_SERVER_KEY');
19
- const cert = (0, _.getSecretOrFile)(process.env.TLS_REQUEST_CERT ? 'TLS_REQUEST_CERT' : 'TLS_SERVER_CERT');
20
-
21
- // CA is optional → only load if env var is set
22
- const ca = process.env.TLS_REQUEST_CA ? (0, _.getSecretOrFile)('TLS_REQUEST_CA') : process.env.TLS_CA ? (0, _.getSecretOrFile)('TLS_CA') : undefined;
23
- const passphrase = process.env.TLS_REQUEST_KEY_PASSPHRASE ?? process.env.TLS_SERVER_KEY_PASSPHRASE;
24
- if (!key || !cert || !ca || !passphrase) {
25
- throw new _EngineError.EngineError({
26
- message: 'TLS environment variables are not set correctly'
27
- });
28
- }
29
- httpsAgent = new _https.default.Agent({
30
- key,
31
- cert,
32
- ca,
33
- passphrase
34
- });
35
- return httpsAgent;
36
- }
37
- //# sourceMappingURL=httpsAgent.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"httpsAgent.js","names":["_https","_interopRequireDefault","require","_tlsConfig","_EngineError","_","httpsAgent","getHttpsAgent","validateTlsConfig","key","getSecretOrFile","process","env","TLS_REQUEST_KEY","cert","TLS_REQUEST_CERT","ca","TLS_REQUEST_CA","TLS_CA","undefined","passphrase","TLS_REQUEST_KEY_PASSPHRASE","TLS_SERVER_KEY_PASSPHRASE","EngineError","message","https","Agent"],"sources":["../../../src/utils/tlsConfig/httpsAgent.ts"],"sourcesContent":["import https, { Agent } from 'https';\nimport { validateTlsConfig } from './tlsConfig.validate';\nimport { EngineError } from 'entities/EngineError';\nimport { getSecretOrFile } from 'utils';\n\nlet httpsAgent: Agent | undefined;\nexport function getHttpsAgent(): Agent {\n if (httpsAgent) return httpsAgent;\n\n validateTlsConfig();\n\n // Always pass env var *names*, not their values\n const key = getSecretOrFile(\n process.env.TLS_REQUEST_KEY ? 'TLS_REQUEST_KEY' : 'TLS_SERVER_KEY'\n );\n\n const cert = getSecretOrFile(\n process.env.TLS_REQUEST_CERT ? 'TLS_REQUEST_CERT' : 'TLS_SERVER_CERT'\n );\n\n // CA is optional → only load if env var is set\n const ca = process.env.TLS_REQUEST_CA\n ? getSecretOrFile('TLS_REQUEST_CA')\n : process.env.TLS_CA\n ? getSecretOrFile('TLS_CA')\n : undefined;\n\n const passphrase =\n process.env.TLS_REQUEST_KEY_PASSPHRASE ??\n process.env.TLS_SERVER_KEY_PASSPHRASE;\n\n if (!key || !cert || !ca || !passphrase) {\n throw new EngineError({\n message: 'TLS environment variables are not set correctly'\n });\n }\n\n httpsAgent = new https.Agent({\n key,\n cert,\n ca,\n passphrase\n });\n\n return httpsAgent;\n}\n"],"mappings":";;;;;;;AAAA,IAAAA,MAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,UAAA,GAAAD,OAAA;AACA,IAAAE,YAAA,GAAAF,OAAA;AACA,IAAAG,CAAA,GAAAH,OAAA;AAEA,IAAII,UAA6B;AAC1B,SAASC,aAAaA,CAAA,EAAU;EACrC,IAAID,UAAU,EAAE,OAAOA,UAAU;EAEjC,IAAAE,4BAAiB,EAAC,CAAC;;EAEnB;EACA,MAAMC,GAAG,GAAG,IAAAC,iBAAe,EACzBC,OAAO,CAACC,GAAG,CAACC,eAAe,GAAG,iBAAiB,GAAG,gBACpD,CAAC;EAED,MAAMC,IAAI,GAAG,IAAAJ,iBAAe,EAC1BC,OAAO,CAACC,GAAG,CAACG,gBAAgB,GAAG,kBAAkB,GAAG,iBACtD,CAAC;;EAED;EACA,MAAMC,EAAE,GAAGL,OAAO,CAACC,GAAG,CAACK,cAAc,GACjC,IAAAP,iBAAe,EAAC,gBAAgB,CAAC,GACjCC,OAAO,CAACC,GAAG,CAACM,MAAM,GAChB,IAAAR,iBAAe,EAAC,QAAQ,CAAC,GACzBS,SAAS;EAEf,MAAMC,UAAU,GACdT,OAAO,CAACC,GAAG,CAACS,0BAA0B,IACtCV,OAAO,CAACC,GAAG,CAACU,yBAAyB;EAEvC,IAAI,CAACb,GAAG,IAAI,CAACK,IAAI,IAAI,CAACE,EAAE,IAAI,CAACI,UAAU,EAAE;IACvC,MAAM,IAAIG,wBAAW,CAAC;MACpBC,OAAO,EAAE;IACX,CAAC,CAAC;EACJ;EAEAlB,UAAU,GAAG,IAAImB,cAAK,CAACC,KAAK,CAAC;IAC3BjB,GAAG;IACHK,IAAI;IACJE,EAAE;IACFI;EACF,CAAC,CAAC;EAEF,OAAOd,UAAU;AACnB","ignoreList":[]}
@@ -1,46 +0,0 @@
1
- import https, { Agent } from 'https';
2
- import { validateTlsConfig } from './tlsConfig.validate';
3
- import { EngineError } from 'entities/EngineError';
4
- import { getSecretOrFile } from 'utils';
5
-
6
- let httpsAgent: Agent | undefined;
7
- export function getHttpsAgent(): Agent {
8
- if (httpsAgent) return httpsAgent;
9
-
10
- validateTlsConfig();
11
-
12
- // Always pass env var *names*, not their values
13
- const key = getSecretOrFile(
14
- process.env.TLS_REQUEST_KEY ? 'TLS_REQUEST_KEY' : 'TLS_SERVER_KEY'
15
- );
16
-
17
- const cert = getSecretOrFile(
18
- process.env.TLS_REQUEST_CERT ? 'TLS_REQUEST_CERT' : 'TLS_SERVER_CERT'
19
- );
20
-
21
- // CA is optional → only load if env var is set
22
- const ca = process.env.TLS_REQUEST_CA
23
- ? getSecretOrFile('TLS_REQUEST_CA')
24
- : process.env.TLS_CA
25
- ? getSecretOrFile('TLS_CA')
26
- : undefined;
27
-
28
- const passphrase =
29
- process.env.TLS_REQUEST_KEY_PASSPHRASE ??
30
- process.env.TLS_SERVER_KEY_PASSPHRASE;
31
-
32
- if (!key || !cert || !ca || !passphrase) {
33
- throw new EngineError({
34
- message: 'TLS environment variables are not set correctly'
35
- });
36
- }
37
-
38
- httpsAgent = new https.Agent({
39
- key,
40
- cert,
41
- ca,
42
- passphrase
43
- });
44
-
45
- return httpsAgent;
46
- }