node-server-engine 2.0.1 → 2.1.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 +10 -10
- package/.nycrc +1 -3
- package/.releaserc.js +2 -1
- package/README.md +206 -146
- package/dist/const/metrics.js.map +1 -1
- package/dist/db/models/index.js.map +1 -1
- package/dist/entities/AWSS3/AWSS3.js +12 -12
- package/dist/entities/AWSS3/AWSS3.js.map +1 -1
- package/dist/entities/ElasticSearch/ElasticSearch.js.map +1 -1
- package/dist/entities/Endpoint/Endpoint.types.js.map +1 -1
- package/dist/entities/GoogleCloudStorage/GoogleCloudStorage.js +11 -11
- package/dist/entities/GoogleCloudStorage/GoogleCloudStorage.js.map +1 -1
- package/dist/entities/KeySet/KeySet.js.map +1 -1
- package/dist/entities/PubSub/PubSub.js.map +1 -1
- package/dist/entities/PushNotification/PushNotification.js.map +1 -1
- package/dist/entities/Redis/Redis.js +3 -3
- package/dist/entities/Redis/Redis.js.map +1 -1
- package/dist/entities/SecretManager/SecretManager.js +3 -3
- package/dist/entities/SecretManager/SecretManager.js.map +1 -1
- package/dist/entities/Sequelize/Sequelize.config.js +11 -7
- package/dist/entities/Sequelize/Sequelize.config.js.map +1 -1
- package/dist/entities/Sequelize/Sequelize.js.map +1 -1
- package/dist/entities/Server/Server.js.map +1 -1
- package/dist/entities/Server/Server.types.js.map +1 -1
- package/dist/entities/SocketClient/SocketClient.d.ts +12 -0
- package/dist/entities/SocketClient/SocketClient.js +34 -3
- package/dist/entities/SocketClient/SocketClient.js.map +1 -1
- package/dist/entities/SocketClient/SocketClient.types.d.ts +6 -0
- package/dist/entities/SocketClient/SocketClient.types.js.map +1 -1
- package/dist/entities/index.js.map +1 -1
- package/dist/middleware/checkPermission/checkPermission.js.map +1 -1
- package/dist/middleware/checkPermission/index.js.map +1 -1
- package/dist/middleware/index.js.map +1 -1
- package/dist/middleware/multiPartFileUploader/multiPartFileUploader.js.map +1 -1
- package/dist/middleware/requestMetrics/requestMetrics.js.map +1 -1
- package/dist/middleware/swaggerDocs/swaggerDocs.js.map +1 -1
- package/dist/middleware/verificationToken/verificationToken.js.map +1 -1
- package/dist/utils/createSortedObject/createSortedObject.js.map +1 -1
- package/dist/utils/dbMigration/dbMigration.js.map +1 -1
- package/dist/utils/dbMigration/migrateMetadataTable/migrateMetadataTable.js.map +1 -1
- package/dist/utils/jwt/jwt.js.map +1 -1
- package/dist/utils/jwt/jwt.types.js.map +1 -1
- package/dist/utils/report/output.js.map +1 -1
- package/dist/utils/report/report.js.map +1 -1
- package/dist/utils/semverCompare/semverCompare.js.map +1 -1
- package/dist/utils/verificationToken/verificationToken.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Server.js","names":["_fs","_interopRequireDefault","require","_path","_promises","_express","_cors","_ws","_SocketClient","_Server2","_Endpoint","_EngineError","_LifecycleController","_PubSub","_SecretManager","_utils","_jwt","_report","_tlsConfig","namespace","DEFAULT_WS_MAX_PAYLOAD","parseCorsOrigin","value","origins","split","map","origin","trim","filter","Boolean","length","Server","exports","config","_classCallCheck2","default","_defineProperty2","AbortController","validate","reportDebug","message","endpoints","globalMiddleware","errorMiddleware","initCallbacks","shutdownCallbacks","syncCallbacks","cron","auth","noFetch","secretManagerConfig","secretManager","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","CORS_ORIGIN","methods","allowedHeaders","exposedHeaders","registerMiddleware","httpServer","createHttpServer","secondaryApp","secondaryMiddleware","defaultErrorMiddleware","forEach","middleware","secondaryHttpServer","disable","server","headersTimeout","keepAliveTimeout","webSocket","attachWebSocket","_createClass2","key","setupGlobalErrorLogging","on","err","reportError","reportInfo","setTimeout","exit","reason","Error","String","init","SecretManager","initKeySets","callback","runCallback","Promise","all","PubSub","job","runCronJob","resolve","listen","data","port","secondaryPort","nodeEnv","handleSignal","watchTlsCaFileChange","shutdown","reject","listening","address","close","error","wss","clients","socket","socketKillTimeout","WEBSOCKET_CLOSE_TIMEOUT","parseInt","setTimeoutPromise","readyState","CLOSING","OPEN","terminate","LifecycleController","shutdownRunningInstances","abortController","abort","fileWatchers","watcher","shutdownKeySets","shutdownSignals","signal","removeAllListeners","getApp","getSecondaryApp","defaultMiddleware","path","endpoint","register","options","WebSocketServer","maxPayload","Number","WS_MAX_PAYLOAD","request","SocketClient","client","isShuttingDown","then","catch","file","fs","watch","event","loadTlsConfig","setSecureContext","tlsConfig","push","handler","name","interval","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 { SecretManager } from 'entities/SecretManager';\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/** Default maximum size (in bytes) of an incoming WebSocket message */\nconst DEFAULT_WS_MAX_PAYLOAD = 1024 * 1024;\n\n/** Parse the CORS_ORIGIN variable, which can hold a single origin or a comma separated list */\nexport function parseCorsOrigin(value?: string): string | Array<string> {\n if (!value) return '*';\n const origins = value\n .split(',')\n .map((origin) => origin.trim())\n .filter(Boolean);\n if (origins.length === 0) return '*';\n return origins.length === 1 ? origins[0] : origins;\n}\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 /** Secret Manager configuration */\n private secretManagerConfig?: ServerOptions['secretManager'];\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 /** File system watchers for TLS certificate changes */\n private fileWatchers: Array<fs.FSWatcher> = [];\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 this.secretManagerConfig = config.secretManager;\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: parseCorsOrigin(process.env.CORS_ORIGIN),\n methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'],\n allowedHeaders: [\n 'Content-Type',\n 'Authorization',\n 'x-verification-token',\n 'x-verification-otp',\n 'Access-Control-Allow-Origin'\n ],\n exposedHeaders: ['Access-Control-Allow-Origin']\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 /**\n * Setup global error handlers for uncaught exceptions and unhandled rejections\n */\n private setupGlobalErrorLogging(): void {\n process.on('uncaughtException', (err) => {\n reportError(err);\n reportInfo('💥 Uncaught exception - process will exit');\n // Give time for logs to flush before exiting\n setTimeout(() => process.exit(1), 1000);\n });\n \n process.on('unhandledRejection', (reason: unknown) => {\n reportError(reason instanceof Error ? reason : new Error(String(reason)));\n reportInfo('💥 Unhandled rejection - process will exit');\n // Give time for logs to flush before exiting\n setTimeout(() => process.exit(1), 1000);\n });\n }\n\n /** Start the server */\n public async init(): Promise<void> {\n this.setupGlobalErrorLogging();\n reportDebug({ namespace, message: `Starting Server` });\n \n // Load secrets from Secret Manager FIRST (before anything else that might need them)\n if (this.secretManagerConfig) {\n await SecretManager.init(this.secretManagerConfig);\n }\n \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(\n (server) =>\n new Promise<void>((resolve, reject) => {\n // Ignore if the server was already stopped\n // We have observed cases where SIGTERM was thrown multiple times\n if (!server.listening) {\n resolve();\n return;\n }\n \n const { port } = server.address() as AddressInfo;\n \n server.close((error) => {\n if (error) {\n reportError(error);\n reject(error);\n } else {\n reportInfo({\n message: `Stopped listening to requests on port ${port}`\n });\n resolve();\n }\n });\n })\n )\n );\n\n // Close all socket connections\n if (this.wss) {\n // First ask them to close gracefully\n this.wss.clients.forEach((socket) => {\n socket.close();\n });\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, 10)\n : 5000;\n \n await setTimeoutPromise(socketKillTimeout);\n \n this.wss.clients.forEach((socket) => {\n if (\n socket.readyState === socket.CLOSING ||\n socket.readyState === socket.OPEN\n ) {\n socket.terminate();\n }\n });\n \n // Close the WebSocket server itself\n await new Promise<void>((resolve, reject) => {\n this.wss?.close((error) => {\n if (error) {\n reportError(error);\n reject(error);\n } else {\n reportInfo({ message: 'WebSocket server closed' });\n resolve();\n }\n });\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 // Close all file watchers\n this.fileWatchers.forEach((watcher) => watcher.close());\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 // Limit the size of incoming messages (ws defaults to 100MiB)\n maxPayload: Number(process.env.WS_MAX_PAYLOAD) || DEFAULT_WS_MAX_PAYLOAD,\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 let isShuttingDown = false;\n \n shutdownSignals.forEach((signal) =>\n process.on(signal, () => {\n // Prevent multiple shutdown attempts\n if (isShuttingDown) {\n reportInfo(`Already shutting down, ignoring ${signal}`);\n return;\n }\n \n isShuttingDown = true;\n reportInfo(`Received shutdown signal [${signal}]`);\n \n this.shutdown()\n .then(() => {\n reportInfo('Graceful shutdown completed successfully');\n process.exit(0);\n })\n .catch((error) => {\n reportError(error);\n process.exit(1);\n });\n })\n );\n }\n\n /** Watch the TLS certificate change event */\n private watchTlsCaFileChange(): void {\n [\n 'TLS_REQUEST_KEY',\n 'TLS_REQUEST_CERT',\n 'TLS_REQUEST_CA',\n 'TLS_SERVER_KEY',\n 'TLS_SERVER_CERT',\n 'TLS_CA'\n ].forEach((key) => {\n const file = process.env[key];\n if (file) {\n const watcher = 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 this.fileWatchers.push(watcher);\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":";;;;;;;;;;;AAAA,IAAAA,GAAA,GAAAC,sBAAA,CAAAC,OAAA;AAIA,IAAAC,KAAA,GAAAF,sBAAA,CAAAC,OAAA;AACA,IAAAE,SAAA,GAAAF,OAAA;AAEA,IAAAG,QAAA,GAAAJ,sBAAA,CAAAC,OAAA;AACA,IAAAI,KAAA,GAAAL,sBAAA,CAAAC,OAAA;AACA,IAAAK,GAAA,GAAAL,OAAA;AACA,IAAAM,aAAA,GAAAN,OAAA;AACA,IAAAO,QAAA,GAAAP,OAAA;AAeA,IAAAQ,SAAA,GAAAR,OAAA;AACA,IAAAS,YAAA,GAAAT,OAAA;AACA,IAAAU,oBAAA,GAAAV,OAAA;AACA,IAAAW,OAAA,GAAAX,OAAA;AACA,IAAAY,cAAA,GAAAZ,OAAA;AACA,IAAAa,MAAA,GAAAb,OAAA;AACA,IAAAc,IAAA,GAAAd,OAAA;AACA,IAAAe,OAAA,GAAAf,OAAA;AACA,IAAAgB,UAAA,GAAAhB,OAAA;AAEA,MAAMiB,SAAS,GAAG,eAAe;;AAEjC;AACA,MAAMC,sBAAsB,GAAG,IAAI,GAAG,IAAI;;AAE1C;AACO,SAASC,eAAeA,CAACC,KAAc,EAA0B;EACtE,IAAI,CAACA,KAAK,EAAE,OAAO,GAAG;EACtB,MAAMC,OAAO,GAAGD,KAAK,CAClBE,KAAK,CAAC,GAAG,CAAC,CACVC,GAAG,CAAEC,MAAM,IAAKA,MAAM,CAACC,IAAI,CAAC,CAAC,CAAC,CAC9BC,MAAM,CAACC,OAAO,CAAC;EAClB,IAAIN,OAAO,CAACO,MAAM,KAAK,CAAC,EAAE,OAAO,GAAG;EACpC,OAAOP,OAAO,CAACO,MAAM,KAAK,CAAC,GAAGP,OAAO,CAAC,CAAC,CAAC,GAAGA,OAAO;AACpD;;AAEA;AAAA,IACaQ,MAAM,GAAAC,OAAA,CAAAD,MAAA;EAuCjB;EACA,SAAAA,OAAmBE,MAAqB,EAAE;IAAA,IAAAC,gBAAA,CAAAC,OAAA,QAAAJ,MAAA;IAvC1C;IAAA,IAAAK,gBAAA,CAAAD,OAAA;IAEA;IAAA,IAAAC,gBAAA,CAAAD,OAAA;IAEA;IAAA,IAAAC,gBAAA,CAAAD,OAAA;IAEA;IAAA,IAAAC,gBAAA,CAAAD,OAAA;IAEA;IACA;IAAA,IAAAC,gBAAA,CAAAD,OAAA;IAEA;IAAA,IAAAC,gBAAA,CAAAD,OAAA;IAEA;IAAA,IAAAC,gBAAA,CAAAD,OAAA;IAEA;IAAA,IAAAC,gBAAA,CAAAD,OAAA;IAIA;IAAA,IAAAC,gBAAA,CAAAD,OAAA;IAEA;IAAA,IAAAC,gBAAA,CAAAD,OAAA;IAEA;IAAA,IAAAC,gBAAA,CAAAD,OAAA;IAEA;IAAA,IAAAC,gBAAA,CAAAD,OAAA;IAEA;IAAA,IAAAC,gBAAA,CAAAD,OAAA;IAEA;IAAA,IAAAC,gBAAA,CAAAD,OAAA;IAEA;IAAA,IAAAC,gBAAA,CAAAD,OAAA;IAEA;IAAA,IAAAC,gBAAA,CAAAD,OAAA,2BAC0B,IAAIE,eAAe,CAAC,CAAC;IAC/C;IAAA,IAAAD,gBAAA,CAAAD,OAAA,wBAC4C,EAAE;IAI5C,IAAI,CAACG,QAAQ,CAACL,MAAM,CAAC;IAErB,IAAAM,mBAAW,EAAC;MACVpB,SAAS;MACTqB,OAAO,EAAE;IACX,CAAC,CAAC;IAEF,IAAI,CAACC,SAAS,GAAGR,MAAM,CAACQ,SAAS;IACjC,IAAI,CAACC,gBAAgB,GAAGT,MAAM,CAACS,gBAAgB,IAAI,EAAE;IACrD,IAAI,CAACC,eAAe,GAAGV,MAAM,CAACU,eAAe,IAAI,EAAE;IACnD,IAAI,CAACC,aAAa,GAAGX,MAAM,CAACW,aAAa,IAAI,EAAE;IAC/C,IAAI,CAACC,iBAAiB,GAAGZ,MAAM,CAACY,iBAAiB,IAAI,EAAE;IACvD,IAAI,CAACC,aAAa,GAAGb,MAAM,CAACa,aAAa,IAAI,KAAK;IAClD,IAAI,CAACC,IAAI,GAAGd,MAAM,CAACc,IAAI;IACvB,IAAI,CAACC,IAAI,GAAG;MAAEC,OAAO,EAAE,KAAK;MAAE,GAAGhB,MAAM,CAACe;IAAK,CAAC;IAC9C,IAAI,CAACE,mBAAmB,GAAGjB,MAAM,CAACkB,aAAa;;IAE/C;IACA;IACA,IAAI,CAACC,gBAAgB,GACnBC,OAAO,CAACC,GAAG,CAACC,aAAa,KAAK,MAAM,IACpCF,OAAO,CAACC,GAAG,CAACE,cAAc,KAAK,MAAM,GACjC;MACEC,QAAQ,EAAEC,gBAAS,CAACC,MAAM,CAAC,CAAC;MAC5BC,QAAQ,EAAEF,gBAAS,CAACG,QAAQ,CAAC,CAAC;MAC9BC,YAAY,EAAEJ,gBAAS,CAACG,QAAQ,CAAC,CAAC;MAClCE,MAAM,EAAEL,gBAAS,CAACG,QAAQ,CAAC;IAC7B,CAAC,GACD;MACEG,QAAQ,EAAEN,gBAAS,CAACG,QAAQ,CAAC,CAAC;MAC9BI,IAAI,EAAEP,gBAAS,CAACQ,MAAM,CAAC,CAAC;MACxBC,cAAc,EAAET,gBAAS,CAACQ,MAAM,CAAC,CAAC;MAClC,GAAGjC,MAAM,CAACmB;IACZ,CAAC;IAEP,IAAAA,uBAAgB,EAAC,IAAI,CAACA,gBAAgB,CAAC;;IAEvC;IACA,IAAI,CAACgB,GAAG,GAAG,IAAAC,gBAAO,EAAC,CAAC;IACpB,IAAI,CAACD,GAAG,CAACE,GAAG,CACV,IAAAC,aAAI,EAAC;MACH7C,MAAM,EAAEL,eAAe,CAACgC,OAAO,CAACC,GAAG,CAACkB,WAAW,CAAC;MAChDC,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,CAAC;MAC7DC,cAAc,EAAE,CACd,cAAc,EACd,eAAe,EACf,sBAAsB,EACtB,oBAAoB,EACpB,6BAA6B,CAC9B;MACDC,cAAc,EAAE,CAAC,6BAA6B;IAChD,CAAC,CACH,CAAC;IACD,IAAI,CAACC,kBAAkB,CAAC,IAAI,CAACR,GAAG,CAAC;IACjC,IAAI,CAACS,UAAU,GAAG,IAAAC,uBAAgB,EAAC,IAAI,CAACV,GAAG,CAAC;;IAE5C;IACA;IACA,IAAI,CAACW,YAAY,GAAG,IAAAV,gBAAO,EAAC,CAAC;IAC7B,CAAC,GAAGW,4BAAmB,EAAE,GAAGC,+BAAsB,CAAC,CAACC,OAAO,CACxDC,UAAU,IAAK;MACd,IAAIA,UAAU,EAAE,IAAI,CAACJ,YAAY,CAACT,GAAG,CAACa,UAAU,CAAC;IACnD,CACF,CAAC;IACD,IAAI,CAACC,mBAAmB,GAAG,IAAAN,uBAAgB,EAAC,IAAI,CAACC,YAAY,CAAC;;IAE9D;IACA,IAAI,CAACX,GAAG,CAACiB,OAAO,CAAC,cAAc,CAAC;IAChC,IAAI,CAACN,YAAY,CAACM,OAAO,CAAC,cAAc,CAAC;;IAEzC;IACA;IACA,CAAC,IAAI,CAACR,UAAU,EAAE,IAAI,CAACO,mBAAmB,CAAC,CAACF,OAAO,CAAEI,MAAM,IAAK;MAC9DA,MAAM,CAACC,cAAc,GAAG,CAAC;MACzBD,MAAM,CAACE,gBAAgB,GAAG,CAAC;IAC7B,CAAC,CAAC;IAEF,IAAIvD,MAAM,CAACwD,SAAS,EAAE;MACpB,IAAI,CAACC,eAAe,CAACzD,MAAM,CAACwD,SAAS,CAAC;IACxC;EACF;;EAEA;AACF;AACA;EAFE,WAAAE,aAAA,CAAAxD,OAAA,EAAAJ,MAAA;IAAA6D,GAAA;IAAAtE,KAAA,EAGA,SAAQuE,uBAAuBA,CAAA,EAAS;MACtCxC,OAAO,CAACyC,EAAE,CAAC,mBAAmB,EAAGC,GAAG,IAAK;QACvC,IAAAC,mBAAW,EAACD,GAAG,CAAC;QAChB,IAAAE,kBAAU,EAAC,2CAA2C,CAAC;QACvD;QACAC,UAAU,CAAC,MAAM7C,OAAO,CAAC8C,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;MACzC,CAAC,CAAC;MAEF9C,OAAO,CAACyC,EAAE,CAAC,oBAAoB,EAAGM,MAAe,IAAK;QACpD,IAAAJ,mBAAW,EAACI,MAAM,YAAYC,KAAK,GAAGD,MAAM,GAAG,IAAIC,KAAK,CAACC,MAAM,CAACF,MAAM,CAAC,CAAC,CAAC;QACzE,IAAAH,kBAAU,EAAC,4CAA4C,CAAC;QACxD;QACAC,UAAU,CAAC,MAAM7C,OAAO,CAAC8C,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;MACzC,CAAC,CAAC;IACJ;;IAEA;EAAA;IAAAP,GAAA;IAAAtE,KAAA,EACA,eAAaiF,IAAIA,CAAA,EAAkB;MACjC,IAAI,CAACV,uBAAuB,CAAC,CAAC;MAC9B,IAAAtD,mBAAW,EAAC;QAAEpB,SAAS;QAAEqB,OAAO,EAAE;MAAkB,CAAC,CAAC;;MAEtD;MACA,IAAI,IAAI,CAACU,mBAAmB,EAAE;QAC5B,MAAMsD,4BAAa,CAACD,IAAI,CAAC,IAAI,CAACrD,mBAAmB,CAAC;MACpD;;MAEA;MACA;MACA,IAAIG,OAAO,CAACC,GAAG,CAACU,QAAQ,KAAK,MAAM,IAAI,CAAC,IAAI,CAAChB,IAAI,CAACC,OAAO,EACvD,MAAM,IAAAwD,gBAAW,EAAC,CAAC;MACrB;MACA;MACA;;MAEA,IAAI,IAAI,CAAC3D,aAAa,EAAE;QACtB,KAAK,MAAM4D,QAAQ,IAAI,IAAI,CAAC9D,aAAa,EAAE;UACzC,MAAM,IAAI,CAAC+D,WAAW,CAACD,QAAQ,CAAC;QAClC;MACF,CAAC,MAAM;QACL,MAAME,OAAO,CAACC,GAAG,CACf,IAAI,CAACjE,aAAa,CAACnB,GAAG,CAAEiF,QAAQ,IAAK,IAAI,CAACC,WAAW,CAACD,QAAQ,CAAC,CACjE,CAAC;MACH;;MAEA;MACA,MAAMI,cAAM,CAACP,IAAI,CAAC,CAAC;MACnB;MACA,IAAI,IAAI,CAACxD,IAAI,EAAE;QACb,IAAI,CAACA,IAAI,CAACmC,OAAO,CAAE6B,GAAG,IAAK;UACzB,IAAI,CAACC,UAAU,CAACD,GAAG,CAAC;QACtB,CAAC,CAAC;MACJ;;MAEA;MACA,MAAMH,OAAO,CAACC,GAAG,CAAC,CAChB,IAAID,OAAO,CAAQK,OAAO,IACxB,IAAI,CAACpC,UAAU,CAACqC,MAAM,CAAC7D,OAAO,CAACC,GAAG,CAACW,IAAI,EAAE,MAAM;QAC7CgD,OAAO,CAAC,CAAC;MACX,CAAC,CACH,CAAC,EACD,IAAIL,OAAO,CAAQK,OAAO,IACxB,IAAI,CAAC7B,mBAAmB,CAAC8B,MAAM,CAAC7D,OAAO,CAACC,GAAG,CAACa,cAAc,EAAE,MAAM;QAChE8C,OAAO,CAAC,CAAC;MACX,CAAC,CACH,CAAC,CACF,CAAC;MACF,IAAAhB,kBAAU,EAAC;QACTzD,OAAO,EAAE,gBAAgB;QACzB2E,IAAI,EAAE;UACJC,IAAI,EAAE/D,OAAO,CAACC,GAAG,CAACW,IAAI;UACtBoD,aAAa,EAAEhE,OAAO,CAACC,GAAG,CAACa,cAAc;UACzCmD,OAAO,EAAEjE,OAAO,CAACC,GAAG,CAACU;QACvB;MACF,CAAC,CAAC;MAEF,IAAI,CAACuD,YAAY,CAAC,CAAC;;MAEnB;MACA,IAAI,CAACC,oBAAoB,CAAC,CAAC;IAC7B;;IAEA;EAAA;IAAA5B,GAAA;IAAAtE,KAAA,EACA,eAAamG,QAAQA,CAAA,EAAkB;MACrC,IAAAlF,mBAAW,EAAC;QAAEpB,SAAS;QAAEqB,OAAO,EAAE;MAAuB,CAAC,CAAC;;MAE3D;MACA,MAAMoE,OAAO,CAACC,GAAG,CACf,CAAC,IAAI,CAAChC,UAAU,EAAE,IAAI,CAACO,mBAAmB,CAAC,CAAC3D,GAAG,CAC5C6D,MAAM,IACL,IAAIsB,OAAO,CAAO,CAACK,OAAO,EAAES,MAAM,KAAK;QACrC;QACA;QACA,IAAI,CAACpC,MAAM,CAACqC,SAAS,EAAE;UACrBV,OAAO,CAAC,CAAC;UACT;QACF;QAEA,MAAM;UAAEG;QAAK,CAAC,GAAG9B,MAAM,CAACsC,OAAO,CAAC,CAAgB;QAEhDtC,MAAM,CAACuC,KAAK,CAAEC,KAAK,IAAK;UACtB,IAAIA,KAAK,EAAE;YACT,IAAA9B,mBAAW,EAAC8B,KAAK,CAAC;YAClBJ,MAAM,CAACI,KAAK,CAAC;UACf,CAAC,MAAM;YACL,IAAA7B,kBAAU,EAAC;cACTzD,OAAO,EAAE,yCAAyC4E,IAAI;YACxD,CAAC,CAAC;YACFH,OAAO,CAAC,CAAC;UACX;QACF,CAAC,CAAC;MACJ,CAAC,CACL,CACF,CAAC;;MAED;MACA,IAAI,IAAI,CAACc,GAAG,EAAE;QACZ;QACA,IAAI,CAACA,GAAG,CAACC,OAAO,CAAC9C,OAAO,CAAE+C,MAAM,IAAK;UACnCA,MAAM,CAACJ,KAAK,CAAC,CAAC;QAChB,CAAC,CAAC;;QAEF;QACA,MAAMK,iBAAiB,GAAG7E,OAAO,CAACC,GAAG,CAAC6E,uBAAuB,GACzDC,QAAQ,CAAC/E,OAAO,CAACC,GAAG,CAAC6E,uBAAuB,EAAE,EAAE,CAAC,GACjD,IAAI;QAER,MAAM,IAAAE,oBAAiB,EAACH,iBAAiB,CAAC;QAE1C,IAAI,CAACH,GAAG,CAACC,OAAO,CAAC9C,OAAO,CAAE+C,MAAM,IAAK;UACnC,IACEA,MAAM,CAACK,UAAU,KAAKL,MAAM,CAACM,OAAO,IACpCN,MAAM,CAACK,UAAU,KAAKL,MAAM,CAACO,IAAI,EACjC;YACAP,MAAM,CAACQ,SAAS,CAAC,CAAC;UACpB;QACF,CAAC,CAAC;;QAEF;QACA,MAAM,IAAI7B,OAAO,CAAO,CAACK,OAAO,EAAES,MAAM,KAAK;UAC3C,IAAI,CAACK,GAAG,EAAEF,KAAK,CAAEC,KAAK,IAAK;YACzB,IAAIA,KAAK,EAAE;cACT,IAAA9B,mBAAW,EAAC8B,KAAK,CAAC;cAClBJ,MAAM,CAACI,KAAK,CAAC;YACf,CAAC,MAAM;cACL,IAAA7B,kBAAU,EAAC;gBAAEzD,OAAO,EAAE;cAA0B,CAAC,CAAC;cAClDyE,OAAO,CAAC,CAAC;YACX;UACF,CAAC,CAAC;QACJ,CAAC,CAAC;MACJ;;MAEA;MACA,IAAI,IAAI,CAACnE,aAAa,EAAE;QACtB,KAAK,MAAM4D,QAAQ,IAAI,IAAI,CAAC7D,iBAAiB,EAAE;UAC7C,MAAM,IAAI,CAAC8D,WAAW,CAACD,QAAQ,CAAC;QAClC;MACF,CAAC,MAAM;QACL,MAAME,OAAO,CAACC,GAAG,CACf,IAAI,CAAChE,iBAAiB,CAACpB,GAAG,CAAEiF,QAAQ,IAAK,IAAI,CAACC,WAAW,CAACD,QAAQ,CAAC,CACrE,CAAC;MACH;;MAEA;MACA,MAAMgC,wCAAmB,CAACC,wBAAwB,CAAC,CAAC;;MAEpD;MACA,IAAI,IAAI,CAACC,eAAe,EAAE,IAAI,CAACA,eAAe,CAACC,KAAK,CAAC,CAAC;;MAEtD;MACA,IAAI,CAACC,YAAY,CAAC5D,OAAO,CAAE6D,OAAO,IAAKA,OAAO,CAAClB,KAAK,CAAC,CAAC,CAAC;;MAEvD;MACA,IAAAmB,oBAAe,EAAC,CAAC;MAEjBC,wBAAe,CAAC/D,OAAO,CAAEgE,MAAM,IAAK7F,OAAO,CAAC8F,kBAAkB,CAACD,MAAM,CAAC,CAAC;IACzE;;IAEA;EAAA;IAAAtD,GAAA;IAAAtE,KAAA,EACA,SAAO8H,MAAMA,CAAA,EAAgB;MAC3B,OAAO,IAAI,CAAChF,GAAG;IACjB;;IAEA;EAAA;IAAAwB,GAAA;IAAAtE,KAAA,EACA,SAAO+H,eAAeA,CAAA,EAAgB;MACpC,OAAO,IAAI,CAACtE,YAAY;IAC1B;;IAEA;EAAA;IAAAa,GAAA;IAAAtE,KAAA,EACA,SAAQsD,kBAAkBA,CAACR,GAAgB,EAAQ;MACjD;MACA,CAAC,GAAGkF,0BAAiB,EAAE,GAAG,IAAI,CAAC5G,gBAAgB,CAAC,CAACwC,OAAO,CAAEC,UAAU,IAAK;QACvE,IAAI,OAAOA,UAAU,KAAK,UAAU,EAAE;UACpCf,GAAG,CAACE,GAAG,CAACa,UAAU,CAAC;QACrB,CAAC,MAAM;UACLf,GAAG,CAACE,GAAG,CAACa,UAAU,CAACoE,IAAI,EAAEpE,UAAU,CAACA,UAAU,CAAC;QACjD;MACF,CAAC,CAAC;MACF;MACA,IAAI,CAAC1C,SAAS,CAACyC,OAAO,CAAEsE,QAAQ,IAAK;QACnCA,QAAQ,CAACC,QAAQ,CAACrF,GAAG,CAAC;MACxB,CAAC,CAAC;MACF;MACA,CAAC,GAAG,IAAI,CAACzB,eAAe,EAAE,GAAGsC,+BAAsB,CAAC,CAACC,OAAO,CACzDC,UAAU,IAAK;QACd,IAAI,OAAOA,UAAU,KAAK,UAAU,EAAE;UACpCf,GAAG,CAACE,GAAG,CAACa,UAAU,CAAC;QACrB,CAAC,MAAM;UACLf,GAAG,CAACE,GAAG,CAACa,UAAU,CAACoE,IAAI,EAAEpE,UAAU,CAACA,UAAU,CAAC;QACjD;MACF,CACF,CAAC;IACH;;IAEA;EAAA;IAAAS,GAAA;IAAAtE,KAAA,EACA,SAAQoE,eAAeA,CAACgE,OAA8B,EAAQ;MAC5D,IAAI,CAAC3B,GAAG,GAAG,IAAI4B,UAAe,CAAC;QAC7B;QACAC,UAAU,EAAEC,MAAM,CAACxG,OAAO,CAACC,GAAG,CAACwG,cAAc,CAAC,IAAI1I,sBAAsB;QACxE,GAAGsI,OAAO,CAACpE,MAAM;QACjBA,MAAM,EAAE,IAAI,CAACT;MACf,CAAC,CAAC,CACCiB,EAAE,CAAC,YAAY,EAAE,CAACL,SAAS,EAAEsE,OAAO,KAAK;QACxC,IAAIC,0BAAY,CAACvE,SAAS,EAAEsE,OAAO,EAAEL,OAAO,CAACO,MAAM,CAAC;MACtD,CAAC,CAAC,CACDnE,EAAE,CAAC,OAAO,EAAGgC,KAAK,IAAK;QACtB,IAAA9B,mBAAW,EAAC8B,KAAK,CAAC;MACpB,CAAC,CAAC;IACN;;IAEA;EAAA;IAAAlC,GAAA;IAAAtE,KAAA,EACA,SAAQiG,YAAYA,CAAA,EAAS;MAC3B,IAAI2C,cAAc,GAAG,KAAK;MAE1BjB,wBAAe,CAAC/D,OAAO,CAAEgE,MAAM,IAC7B7F,OAAO,CAACyC,EAAE,CAACoD,MAAM,EAAE,MAAM;QACvB;QACA,IAAIgB,cAAc,EAAE;UAClB,IAAAjE,kBAAU,EAAC,mCAAmCiD,MAAM,EAAE,CAAC;UACvD;QACF;QAEAgB,cAAc,GAAG,IAAI;QACrB,IAAAjE,kBAAU,EAAC,6BAA6BiD,MAAM,GAAG,CAAC;QAElD,IAAI,CAACzB,QAAQ,CAAC,CAAC,CACZ0C,IAAI,CAAC,MAAM;UACV,IAAAlE,kBAAU,EAAC,0CAA0C,CAAC;UACtD5C,OAAO,CAAC8C,IAAI,CAAC,CAAC,CAAC;QACjB,CAAC,CAAC,CACDiE,KAAK,CAAEtC,KAAK,IAAK;UAChB,IAAA9B,mBAAW,EAAC8B,KAAK,CAAC;UAClBzE,OAAO,CAAC8C,IAAI,CAAC,CAAC,CAAC;QACjB,CAAC,CAAC;MACN,CAAC,CACH,CAAC;IACH;;IAEA;EAAA;IAAAP,GAAA;IAAAtE,KAAA,EACA,SAAQkG,oBAAoBA,CAAA,EAAS;MACnC,CACE,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,QAAQ,CACT,CAACtC,OAAO,CAAEU,GAAG,IAAK;QACjB,MAAMyE,IAAI,GAAGhH,OAAO,CAACC,GAAG,CAACsC,GAAG,CAAC;QAC7B,IAAIyE,IAAI,EAAE;UACR,MAAMtB,OAAO,GAAGuB,WAAE,CAACC,KAAK,CAAChB,aAAI,CAACtC,OAAO,CAACoD,IAAI,CAAC,EAAGG,KAAK,IAAK;YACtD,IAAIA,KAAK,KAAK,QAAQ,EAAE;YACxB,IAAAvE,kBAAU,EAAC,yBAAyBoE,IAAI,WAAW,CAAC;YACpD,IAAAI,wBAAa,EAAC,CAAC;YACd,IAAI,CAAC5F,UAAU,CAAkB6F,gBAAgB,CAChDC,oBACF,CAAC;UACH,CAAC,CAAC;UACF,IAAI,CAAC7B,YAAY,CAAC8B,IAAI,CAAC7B,OAAO,CAAC;QACjC;MACF,CAAC,CAAC;IACJ;;IAEA;EAAA;IAAAnD,GAAA;IAAAtE,KAAA,EACA,SAAQ0F,UAAUA,CAACD,GAAkB,EAAQ;MAC3C,CAAC,YAA2B;QAC1B,IAAAd,kBAAU,EAAC;UAAEzD,OAAO,EAAE,2BAA2BuE,GAAG,CAAC8D,OAAO,CAACC,IAAI;QAAI,CAAC,CAAC;QACvE,IAAI;UACF,MAAM/D,GAAG,CAAC8D,OAAO,CAAC,CAAC;UACnB,IAAA5E,kBAAU,EAAC;YACTzD,OAAO,EAAE,QAAQuE,GAAG,CAAC8D,OAAO,CAACC,IAAI,iCAAiC/D,GAAG,CAACgE,QAAQ;UAChF,CAAC,CAAC;UACF,MAAM,IAAA1C,oBAAiB,EAACtB,GAAG,CAACgE,QAAQ,GAAG,IAAI,EAAEC,SAAS,EAAE;YACtD9B,MAAM,EAAE,IAAI,CAACN,eAAe,CAACM;UAC/B,CAAC,CAAC;UACF,IAAI,CAAClC,UAAU,CAACD,GAAG,CAAC;QACtB,CAAC,CAAC,OAAOe,KAAK,EAAE;UACd,IAAIA,KAAK,YAAYzB,KAAK,IAAIyB,KAAK,CAACgD,IAAI,KAAK,YAAY,EAAE;YACzD,IAAAvI,mBAAW,EAAC;cACVpB,SAAS;cACTqB,OAAO,EAAE,kBAAkBuE,GAAG,CAAC8D,OAAO,EAAEC,IAAI;YAC9C,CAAC,CAAC;UACJ,CAAC,MAAM;YACL,MAAMhD,KAAK;UACb;QACF;MACF,CAAC,EAAE,CAAC,CAACsC,KAAK,CAAEtC,KAAK,IAAK;QACpB,IAAA9B,mBAAW,EAAC8B,KAAK,CAAC;MACpB,CAAC,CAAC;IACJ;;IAEA;EAAA;IAAAlC,GAAA;IAAAtE,KAAA,EACA,SAAQqF,WAAWA,CAACD,QAAwB,EAAW;MACrD,OAAO,OAAOA,QAAQ,KAAK,UAAU,GACjCA,QAAQ,CAAC,CAAC,GACVA,QAAQ,CAACuE,QAAQ,CAACC,KAAK,CAAC,IAAI,EAAExE,QAAQ,CAACyE,UAAU,IAAI,EAAE,CAAC;IAC9D;;IAEA;AACF;AACA;EAFE;IAAAvF,GAAA;IAAAtE,KAAA,EAGA,SAAQgB,QAAQA,CAACL,MAAqB,EAAQ;MAC5C,IACE,CAACA,MAAM,CAACQ,SAAS,IACjBR,MAAM,CAACQ,SAAS,CAAC2I,IAAI,CAAE5B,QAAQ,IAAK,EAAEA,QAAQ,YAAY6B,kBAAQ,CAAC,CAAC,EAEpE,MAAM,IAAIC,wBAAW,CACnB,mEACF,CAAC;MAEH,IACErJ,MAAM,CAACmB,gBAAgB,IACvBmI,MAAM,CAACC,MAAM,CAACvJ,MAAM,CAACmB,gBAAgB,CAAC,CAACgI,IAAI,CACxCK,SAAS,IAAK,OAAOA,SAAS,KAAK,UACtC,CAAC,EAED,MAAM,IAAIH,wBAAW,CACnB,wDACF,CAAC;MAEH,IACErJ,MAAM,CAACW,aAAa,KACnB,EAAEX,MAAM,CAACW,aAAa,YAAY8I,KAAK,CAAC,IACvCzJ,MAAM,CAACW,aAAa,CAACwI,IAAI,CACtB1E,QAAQ,IACP,EACE,OAAOA,QAAQ,KAAK,UAAU,IAC9B,OAAOA,QAAQ,EAAEuE,QAAQ,KAAK,UAAU,CAE9C,CAAC,CAAC,EAEJ,MAAM,IAAIK,wBAAW,CAAC,2CAA2C,CAAC;MAEpE,IACErJ,MAAM,CAACY,iBAAiB,KACvB,EAAEZ,MAAM,CAACY,iBAAiB,YAAY6I,KAAK,CAAC,IAC3CzJ,MAAM,CAACY,iBAAiB,CAACuI,IAAI,CAC1B1E,QAAQ,IACP,EACE,OAAOA,QAAQ,KAAK,UAAU,IAC9B,OAAOA,QAAQ,EAAEuE,QAAQ,KAAK,UAAU,CAE9C,CAAC,CAAC,EAEJ,MAAM,IAAIK,wBAAW,CAAC,+CAA+C,CAAC;IAC1E;EAAC;AAAA","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"Server.js","names":["_fs","_interopRequireDefault","require","_path","_promises","_express","_cors","_ws","_SocketClient","_Server2","_Endpoint","_EngineError","_LifecycleController","_PubSub","_SecretManager","_utils","_jwt","_report","_tlsConfig","namespace","DEFAULT_WS_MAX_PAYLOAD","parseCorsOrigin","value","origins","split","map","origin","trim","filter","Boolean","length","Server","exports","config","_classCallCheck2","default","_defineProperty2","AbortController","validate","reportDebug","message","endpoints","globalMiddleware","errorMiddleware","initCallbacks","shutdownCallbacks","syncCallbacks","cron","auth","noFetch","secretManagerConfig","secretManager","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","CORS_ORIGIN","methods","allowedHeaders","exposedHeaders","registerMiddleware","httpServer","createHttpServer","secondaryApp","secondaryMiddleware","defaultErrorMiddleware","forEach","middleware","secondaryHttpServer","disable","server","headersTimeout","keepAliveTimeout","webSocket","attachWebSocket","_createClass2","key","setupGlobalErrorLogging","on","err","reportError","reportInfo","setTimeout","exit","reason","Error","String","init","SecretManager","initKeySets","callback","runCallback","Promise","all","PubSub","job","runCronJob","resolve","listen","data","port","secondaryPort","nodeEnv","handleSignal","watchTlsCaFileChange","shutdown","reject","listening","address","close","error","wss","clients","socket","socketKillTimeout","WEBSOCKET_CLOSE_TIMEOUT","parseInt","setTimeoutPromise","readyState","CLOSING","OPEN","terminate","LifecycleController","shutdownRunningInstances","abortController","abort","fileWatchers","watcher","shutdownKeySets","shutdownSignals","signal","removeAllListeners","getApp","getSecondaryApp","defaultMiddleware","path","endpoint","register","options","WebSocketServer","maxPayload","Number","WS_MAX_PAYLOAD","request","SocketClient","client","isShuttingDown","then","catch","file","fs","watch","event","loadTlsConfig","setSecureContext","tlsConfig","push","handler","name","interval","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 { SecretManager } from 'entities/SecretManager';\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/** Default maximum size (in bytes) of an incoming WebSocket message */\nconst DEFAULT_WS_MAX_PAYLOAD = 1024 * 1024;\n\n/** Parse the CORS_ORIGIN variable, which can hold a single origin or a comma separated list */\nexport function parseCorsOrigin(value?: string): string | Array<string> {\n if (!value) return '*';\n const origins = value\n .split(',')\n .map((origin) => origin.trim())\n .filter(Boolean);\n if (origins.length === 0) return '*';\n return origins.length === 1 ? origins[0] : origins;\n}\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 /** Secret Manager configuration */\n private secretManagerConfig?: ServerOptions['secretManager'];\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 /** File system watchers for TLS certificate changes */\n private fileWatchers: Array<fs.FSWatcher> = [];\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 this.secretManagerConfig = config.secretManager;\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: parseCorsOrigin(process.env.CORS_ORIGIN),\n methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'],\n allowedHeaders: [\n 'Content-Type',\n 'Authorization',\n 'x-verification-token',\n 'x-verification-otp',\n 'Access-Control-Allow-Origin'\n ],\n exposedHeaders: ['Access-Control-Allow-Origin']\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 /**\n * Setup global error handlers for uncaught exceptions and unhandled rejections\n */\n private setupGlobalErrorLogging(): void {\n process.on('uncaughtException', (err) => {\n reportError(err);\n reportInfo('💥 Uncaught exception - process will exit');\n // Give time for logs to flush before exiting\n setTimeout(() => process.exit(1), 1000);\n });\n\n process.on('unhandledRejection', (reason: unknown) => {\n reportError(reason instanceof Error ? reason : new Error(String(reason)));\n reportInfo('💥 Unhandled rejection - process will exit');\n // Give time for logs to flush before exiting\n setTimeout(() => process.exit(1), 1000);\n });\n }\n\n /** Start the server */\n public async init(): Promise<void> {\n this.setupGlobalErrorLogging();\n reportDebug({ namespace, message: `Starting Server` });\n\n // Load secrets from Secret Manager FIRST (before anything else that might need them)\n if (this.secretManagerConfig) {\n await SecretManager.init(this.secretManagerConfig);\n }\n\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(\n (server) =>\n new Promise<void>((resolve, reject) => {\n // Ignore if the server was already stopped\n // We have observed cases where SIGTERM was thrown multiple times\n if (!server.listening) {\n resolve();\n return;\n }\n\n const { port } = server.address() as AddressInfo;\n\n server.close((error) => {\n if (error) {\n reportError(error);\n reject(error);\n } else {\n reportInfo({\n message: `Stopped listening to requests on port ${port}`\n });\n resolve();\n }\n });\n })\n )\n );\n\n // Close all socket connections\n if (this.wss) {\n // First ask them to close gracefully\n this.wss.clients.forEach((socket) => {\n socket.close();\n });\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, 10)\n : 5000;\n\n await setTimeoutPromise(socketKillTimeout);\n\n this.wss.clients.forEach((socket) => {\n if (\n socket.readyState === socket.CLOSING ||\n socket.readyState === socket.OPEN\n ) {\n socket.terminate();\n }\n });\n\n // Close the WebSocket server itself\n await new Promise<void>((resolve, reject) => {\n this.wss?.close((error) => {\n if (error) {\n reportError(error);\n reject(error);\n } else {\n reportInfo({ message: 'WebSocket server closed' });\n resolve();\n }\n });\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 // Close all file watchers\n this.fileWatchers.forEach((watcher) => watcher.close());\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 // Limit the size of incoming messages (ws defaults to 100MiB)\n maxPayload: Number(process.env.WS_MAX_PAYLOAD) || DEFAULT_WS_MAX_PAYLOAD,\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 let isShuttingDown = false;\n\n shutdownSignals.forEach((signal) =>\n process.on(signal, () => {\n // Prevent multiple shutdown attempts\n if (isShuttingDown) {\n reportInfo(`Already shutting down, ignoring ${signal}`);\n return;\n }\n\n isShuttingDown = true;\n reportInfo(`Received shutdown signal [${signal}]`);\n\n this.shutdown()\n .then(() => {\n reportInfo('Graceful shutdown completed successfully');\n process.exit(0);\n })\n .catch((error) => {\n reportError(error);\n process.exit(1);\n });\n })\n );\n }\n\n /** Watch the TLS certificate change event */\n private watchTlsCaFileChange(): void {\n [\n 'TLS_REQUEST_KEY',\n 'TLS_REQUEST_CERT',\n 'TLS_REQUEST_CA',\n 'TLS_SERVER_KEY',\n 'TLS_SERVER_CERT',\n 'TLS_CA'\n ].forEach((key) => {\n const file = process.env[key];\n if (file) {\n const watcher = 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 this.fileWatchers.push(watcher);\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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Server.types.js","names":[],"sources":["../../../src/entities/Server/Server.types.ts"],"sourcesContent":["import { ValidatorSpec } from 'envalid';\nimport { ErrorRequestHandler, RequestHandler } from 'express';\nimport { ServerOptions as WebSocketServerOptions } from 'ws';\nimport { Endpoint } from 'entities/Endpoint';\nimport { SocketClientOptions } from 'entities/SocketClient';\nimport { SecretManagerOptions } from 'entities/SecretManager';\n\n/** Options to create a server */\nexport interface ServerOptions {\n /** List of endpoint instances that the server should handle */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n endpoints: Array<Endpoint<any>>;\n /** Mapping of env variable name with functions that should run to check their validity */\n checkEnvironment?: Record<string, ValidatorSpec<unknown>>;\n /** Middleware that should run on every request before the endpoint specific logic */\n globalMiddleware?: Array<ServerGlobalMiddleware>;\n /** Error middleware that should run on every request after the endpoint specific logic, but before the generic global middleware */\n errorMiddleware?: Array<ServerGlobalMiddleware | ServerErrorMiddleWare>;\n /** Functions that should be called on server startup */\n initCallbacks?: Array<ServerCallback>;\n /** Functions that should be called on server shutdown */\n 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 syncCallbacks?: boolean;\n /** Config to set regularly running jobs on the server */\n cron?: Array<ServerCronJon>;\n /** Global auth related configuration */\n auth?: ServerAuthConfig;\n /** Configuration to enable webSocket connections to the server */\n webSocket?: ServerWebSocketConfig;\n /** Configuration for GCP Secret Manager to load secrets at startup */\n secretManager?: SecretManagerOptions;\n}\n\n/** Options for a CRON task on the server */\nexport interface ServerCronJon {\n /** Function that is called when the job needs to run */\n handler: () => unknown;\n /** Interval (in seconds) between each job execution. The interval starts after the previous execution finished */\n interval: number;\n /** When this is set, the job is only run on the instance that is that has been elected leader of the service */\n leaderOnly?: boolean;\n}\n\n/** Common server authentication related config */\nexport interface ServerAuthConfig {\n /** Do not fetch JWT authentication parameters, this should be used on servers that do not receive public requests and therefore do not need access to the authentication service */\n noFetch?: boolean;\n}\n\n/** Configuration for WebSocket on this server */\nexport interface ServerWebSocketConfig {\n /** Options to pass to create the webSocket server */\n server: WebSocketServerOptions;\n /** Options to pass when creating socket client instances */\n client: SocketClientOptions;\n}\n\n/** Middleware function definition with path */\nexport interface ServerObjectGlobalMiddleware {\n /** Path on which the middleware is used */\n path: string;\n /** Middleware function */\n middleware: RequestHandler;\n}\nexport type ServerGlobalMiddleware =\n
|
|
1
|
+
{"version":3,"file":"Server.types.js","names":[],"sources":["../../../src/entities/Server/Server.types.ts"],"sourcesContent":["import { ValidatorSpec } from 'envalid';\nimport { ErrorRequestHandler, RequestHandler } from 'express';\nimport { ServerOptions as WebSocketServerOptions } from 'ws';\nimport { Endpoint } from 'entities/Endpoint';\nimport { SocketClientOptions } from 'entities/SocketClient';\nimport { SecretManagerOptions } from 'entities/SecretManager';\n\n/** Options to create a server */\nexport interface ServerOptions {\n /** List of endpoint instances that the server should handle */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n endpoints: Array<Endpoint<any>>;\n /** Mapping of env variable name with functions that should run to check their validity */\n checkEnvironment?: Record<string, ValidatorSpec<unknown>>;\n /** Middleware that should run on every request before the endpoint specific logic */\n globalMiddleware?: Array<ServerGlobalMiddleware>;\n /** Error middleware that should run on every request after the endpoint specific logic, but before the generic global middleware */\n errorMiddleware?: Array<ServerGlobalMiddleware | ServerErrorMiddleWare>;\n /** Functions that should be called on server startup */\n initCallbacks?: Array<ServerCallback>;\n /** Functions that should be called on server shutdown */\n 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 syncCallbacks?: boolean;\n /** Config to set regularly running jobs on the server */\n cron?: Array<ServerCronJon>;\n /** Global auth related configuration */\n auth?: ServerAuthConfig;\n /** Configuration to enable webSocket connections to the server */\n webSocket?: ServerWebSocketConfig;\n /** Configuration for GCP Secret Manager to load secrets at startup */\n secretManager?: SecretManagerOptions;\n}\n\n/** Options for a CRON task on the server */\nexport interface ServerCronJon {\n /** Function that is called when the job needs to run */\n handler: () => unknown;\n /** Interval (in seconds) between each job execution. The interval starts after the previous execution finished */\n interval: number;\n /** When this is set, the job is only run on the instance that is that has been elected leader of the service */\n leaderOnly?: boolean;\n}\n\n/** Common server authentication related config */\nexport interface ServerAuthConfig {\n /** Do not fetch JWT authentication parameters, this should be used on servers that do not receive public requests and therefore do not need access to the authentication service */\n noFetch?: boolean;\n}\n\n/** Configuration for WebSocket on this server */\nexport interface ServerWebSocketConfig {\n /** Options to pass to create the webSocket server */\n server: WebSocketServerOptions;\n /** Options to pass when creating socket client instances */\n client: SocketClientOptions;\n}\n\n/** Middleware function definition with path */\nexport interface ServerObjectGlobalMiddleware {\n /** Path on which the middleware is used */\n path: string;\n /** Middleware function */\n middleware: RequestHandler;\n}\nexport type ServerGlobalMiddleware =\n RequestHandler | ServerObjectGlobalMiddleware;\n\n/** Error middleware function definition with path */\nexport interface ServerObjectErrorMiddleware {\n /** Path on which the middleware is used */\n path: string;\n /** Middleware function */\n middleware: ErrorRequestHandler;\n}\nexport type ServerErrorMiddleWare =\n ErrorRequestHandler | ServerObjectErrorMiddleware;\n\ntype ServerFunctionCallback = (...args: Array<unknown>) => unknown;\n\n/** Callback definition with parameters */\ninterface ServerObjectCallback {\n /** Callback function */\n function: ServerFunctionCallback;\n /** Parameters to pass to the callback function */\n parameters?: Parameters<ServerFunctionCallback>;\n}\n\nexport type ServerCallback = ServerFunctionCallback | ServerObjectCallback;\n"],"mappings":"","ignoreList":[]}
|
|
@@ -37,6 +37,12 @@ export declare class SocketClient {
|
|
|
37
37
|
private audience;
|
|
38
38
|
/** Status tracking variable used to check the liveness of connections */
|
|
39
39
|
private isAlive;
|
|
40
|
+
/** The `user` claim of the token the client authenticated with */
|
|
41
|
+
private tokenUser;
|
|
42
|
+
/** Timestamp (ms) at which the current authentication expires */
|
|
43
|
+
private authExpiresAt;
|
|
44
|
+
/** Closes the connection if the client does not authenticate in time */
|
|
45
|
+
private authTimeout;
|
|
40
46
|
/** Timer used to track interval between client pinging */
|
|
41
47
|
private pingInterval;
|
|
42
48
|
/**
|
|
@@ -54,6 +60,12 @@ export declare class SocketClient {
|
|
|
54
60
|
* Send a message to the client
|
|
55
61
|
*/
|
|
56
62
|
sendMessage(type: string, payload?: unknown, options?: SocketClientSendMessageOptions): void;
|
|
63
|
+
/**
|
|
64
|
+
* Close the connection
|
|
65
|
+
* @param code - WebSocket close code (4000-4999 are free for applications, e.g. 4401 / 4403)
|
|
66
|
+
* @param reason - Human readable reason, sent to the client
|
|
67
|
+
*/
|
|
68
|
+
close(code?: number, reason?: string): void;
|
|
57
69
|
/** Get the client authentication status */
|
|
58
70
|
isAuthenticated(): boolean;
|
|
59
71
|
/** Fetch data on the user if he is authenticated */
|
|
@@ -61,6 +61,12 @@ let SocketClient = exports.SocketClient = /*#__PURE__*/function () {
|
|
|
61
61
|
(0, _defineProperty2.default)(this, "audience", void 0);
|
|
62
62
|
/** Status tracking variable used to check the liveness of connections */
|
|
63
63
|
(0, _defineProperty2.default)(this, "isAlive", true);
|
|
64
|
+
/** The `user` claim of the token the client authenticated with */
|
|
65
|
+
(0, _defineProperty2.default)(this, "tokenUser", void 0);
|
|
66
|
+
/** Timestamp (ms) at which the current authentication expires */
|
|
67
|
+
(0, _defineProperty2.default)(this, "authExpiresAt", void 0);
|
|
68
|
+
/** Closes the connection if the client does not authenticate in time */
|
|
69
|
+
(0, _defineProperty2.default)(this, "authTimeout", void 0);
|
|
64
70
|
/** Timer used to track interval between client pinging */
|
|
65
71
|
(0, _defineProperty2.default)(this, "pingInterval", void 0);
|
|
66
72
|
this.id = (0, _crypto.randomUUID)();
|
|
@@ -91,9 +97,15 @@ let SocketClient = exports.SocketClient = /*#__PURE__*/function () {
|
|
|
91
97
|
(0, _report.reportInfo)({
|
|
92
98
|
message: `Client connected [${this.id}]`
|
|
93
99
|
});
|
|
100
|
+
// Optionally close connections that do not authenticate in time
|
|
101
|
+
if (options.authTimeoutMs && options.authTimeoutMs > 0) {
|
|
102
|
+
this.authTimeout = setTimeout(() => {
|
|
103
|
+
if (!this.authenticated) this.close(4401, 'Authentication required');
|
|
104
|
+
}, options.authTimeoutMs);
|
|
105
|
+
}
|
|
94
106
|
// On socket close, deregister from clients list
|
|
95
|
-
this.ws.on('close', () => {
|
|
96
|
-
this.handleClose.bind(this)().catch(error => {
|
|
107
|
+
this.ws.on('close', (code, reason) => {
|
|
108
|
+
this.handleClose.bind(this)(code, reason?.toString()).catch(error => {
|
|
97
109
|
(0, _report.reportError)(error);
|
|
98
110
|
});
|
|
99
111
|
});
|
|
@@ -184,6 +196,19 @@ let SocketClient = exports.SocketClient = /*#__PURE__*/function () {
|
|
|
184
196
|
}
|
|
185
197
|
}
|
|
186
198
|
|
|
199
|
+
/**
|
|
200
|
+
* Close the connection
|
|
201
|
+
* @param code - WebSocket close code (4000-4999 are free for applications, e.g. 4401 / 4403)
|
|
202
|
+
* @param reason - Human readable reason, sent to the client
|
|
203
|
+
*/
|
|
204
|
+
}, {
|
|
205
|
+
key: "close",
|
|
206
|
+
value: function close(code = 1000, reason) {
|
|
207
|
+
this.clearTimeouts();
|
|
208
|
+
if (this.authTimeout) clearTimeout(this.authTimeout);
|
|
209
|
+
this.ws.close(code, reason);
|
|
210
|
+
}
|
|
211
|
+
|
|
187
212
|
/** Get the client authentication status */
|
|
188
213
|
}, {
|
|
189
214
|
key: "isAuthenticated",
|
|
@@ -199,7 +224,9 @@ let SocketClient = exports.SocketClient = /*#__PURE__*/function () {
|
|
|
199
224
|
userId: this.userId,
|
|
200
225
|
deviceId: this.deviceId,
|
|
201
226
|
tokenId: this.tokenId,
|
|
202
|
-
audience: this.audience
|
|
227
|
+
audience: this.audience,
|
|
228
|
+
user: this.tokenUser,
|
|
229
|
+
expiresAt: this.authExpiresAt
|
|
203
230
|
};
|
|
204
231
|
return undefined;
|
|
205
232
|
}
|
|
@@ -258,6 +285,9 @@ let SocketClient = exports.SocketClient = /*#__PURE__*/function () {
|
|
|
258
285
|
const payload = await (0, _jwt.jwtVerify)(token);
|
|
259
286
|
this.setUserData(payload);
|
|
260
287
|
this.authenticated = true;
|
|
288
|
+
this.tokenUser = payload.user;
|
|
289
|
+
this.authExpiresAt = payload.exp * 1000;
|
|
290
|
+
if (this.authTimeout) clearTimeout(this.authTimeout);
|
|
261
291
|
// Time remaining before token expiration
|
|
262
292
|
const authExpiration = payload.exp * 1000 - Date.now();
|
|
263
293
|
// Clear previously created timers
|
|
@@ -365,6 +395,7 @@ let SocketClient = exports.SocketClient = /*#__PURE__*/function () {
|
|
|
365
395
|
value: async function handleClose(code, reason) {
|
|
366
396
|
delete SocketClient.socketClients[this.id];
|
|
367
397
|
this.clearTimeouts();
|
|
398
|
+
if (this.authTimeout) clearTimeout(this.authTimeout);
|
|
368
399
|
// Stop ping process
|
|
369
400
|
if (this.pingInterval) clearInterval(this.pingInterval);
|
|
370
401
|
// Run all the shutdown callbacks
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SocketClient.js","names":["_crypto","require","_parseMessage","_const","_EngineError","_MessageHandler","_ValidationError","_WebError","_jwt","_report","namespace","SocketClient","exports","webSocket","_request","options","_classCallCheck2","default","_defineProperty2","id","randomUUID","ws","establishedAt","Date","reportDebug","message","initCallbacks","Array","authCallbacks","shutdownCallbacks","handlers","handler","MessageHandler","EngineError","socketClients","reportInfo","on","handleClose","bind","catch","error","reportError","severity","LogSeverity","WARNING","data","handleMessage","callbackResults","Promise","allSettled","map","callback","forEach","result","status","reason","pingInterval","setInterval","isAlive","terminate","ping","process","env","WS_PING_INTERVAL","parseInt","_createClass2","key","value","sendMessage","type","payload","send","noAuth","authenticated","audience","includes","DEFAULT_MESSAGE_AUDIENCE","JSON","stringify","isAuthenticated","getUser","userId","deviceId","tokenId","undefined","parseMessage","toString","authenticate","handle","handleError","token","WebError","errorCode","jwtVerify","setUserData","authExpiration","exp","now","clearTimeouts","authRenewTimer","setTimeout","authExpireTimer","clearTimeout","sub","dev","jti","aud","hint","ValidationError","code","clearInterval","getSocketClients","getSocketClient"],"sources":["../../../src/entities/SocketClient/SocketClient.ts"],"sourcesContent":["import { randomUUID } from 'crypto';\nimport { IncomingMessage } from 'http';\nimport WS, { RawData } from 'ws';\nimport { parseMessage } from './parseMessage';\nimport {\n SocketClientOptions,\n SocketClientSendMessageOptions,\n SocketAuthenticationMessage,\n SocketClientCallback,\n SocketClientList,\n SocketUser\n} from './SocketClient.types';\nimport { LogSeverity } from 'const';\nimport { EngineError } from 'entities/EngineError';\nimport { MessageHandler } from 'entities/MessageHandler';\nimport { ValidationError } from 'entities/ValidationError';\nimport { WebError } from 'entities/WebError';\nimport { jwtVerify, UserTokenPayload } from 'utils/jwt';\nimport { reportInfo, reportError, reportDebug } from 'utils/report';\n\nconst namespace = 'SocketClient';\n\n/**\n * Class where each instance represents a client connected through web-sockets\n */\nexport class SocketClient {\n /** Mapping of all the connected socket clients */\n private static socketClients: SocketClientList = {};\n /** Unique identifier of the client */\n public readonly id: string;\n /** Date at which the client connection was established */\n public readonly establishedAt: Date;\n /** WS instance of the client connection */\n private ws: WS;\n /** List of message handlers that are registered with the client */\n private handlers: Array<MessageHandler>;\n /** Callback function that are called when the client is created */\n private initCallbacks: Array<SocketClientCallback> = [];\n /** Callback function that are called when the client successfully authenticates */\n private authCallbacks: Array<SocketClientCallback> = [];\n /** Callback function that are called when the client connection is terminated */\n private shutdownCallbacks: Array<SocketClientCallback> = [];\n /** Authentication status of the client */\n private authenticated = false;\n /** Timer used to track when to send authentication renewal reminder to the client */\n private authRenewTimer: NodeJS.Timeout | string | number | undefined;\n /** Timers used to track the time at which a user losses authentication */\n private authExpireTimer: NodeJS.Timeout | string | number | undefined;\n /** ID of the user that is authenticated */\n private userId: undefined | string;\n /** ID of the device with which the client authenticated */\n private deviceId: undefined | string;\n /** Id of the token with which the client authenticated */\n private tokenId: undefined | string;\n /** Audience claims that were in the latest authentication token used by the client */\n private audience: undefined | Array<string>;\n /** Status tracking variable used to check the liveness of connections */\n private isAlive = true;\n /** Timer used to track interval between client pinging */\n private pingInterval: NodeJS.Timeout | string | number | undefined;\n\n /**\n * Create a WS client\n * @param webSocket - The WebSocket instance\n * @param _request - The incoming HTTP request (reserved for future use)\n * @param options - Socket client configuration options\n */\n public constructor(\n webSocket: WS,\n _request: IncomingMessage,\n options: SocketClientOptions\n ) {\n this.id = randomUUID();\n this.ws = webSocket;\n this.establishedAt = new Date();\n\n reportDebug({ namespace, message: `Creating socket client [${this.id}]` });\n\n // Make sure that callbacks are made as lists of functions\n // Init\n if (typeof options.initCallbacks === 'function')\n this.initCallbacks = [options.initCallbacks];\n else if (options.initCallbacks instanceof Array)\n this.initCallbacks = options.initCallbacks;\n // Auth\n if (typeof options.authCallbacks === 'function')\n this.authCallbacks = [options.authCallbacks];\n else if (options.authCallbacks instanceof Array)\n this.authCallbacks = options.authCallbacks;\n // Shutdown\n if (typeof options.shutdownCallbacks === 'function')\n this.shutdownCallbacks = [options.shutdownCallbacks];\n else if (options.shutdownCallbacks instanceof Array)\n this.shutdownCallbacks = options.shutdownCallbacks;\n\n // Check that all handlers are valid\n this.handlers = options.handlers;\n for (const handler of this.handlers) {\n if (!(handler instanceof MessageHandler))\n throw new EngineError({\n message: 'Handler is not an instance of MessageHandler'\n });\n }\n // Register in clients list\n SocketClient.socketClients[this.id] = this;\n\n reportInfo({ message: `Client connected [${this.id}]` });\n // On socket close, deregister from clients list\n this.ws.on('close', () => {\n this.handleClose\n .bind(this)()\n .catch((error) => {\n reportError(error);\n });\n });\n // On socket error, log the error\n this.ws.on('error', (error) => {\n reportError(\n new EngineError({\n severity: LogSeverity.WARNING,\n message: `Error [${this.id}]`\n })\n );\n reportError(error);\n });\n // When receiving a message, call message handler\n this.ws.on('message', (data) => {\n this.handleMessage\n .bind(this)(data)\n .catch((error) => {\n reportError(error);\n });\n });\n\n // Run all the init callbacks\n // For proper error handling of potential asynchronous callbacks, we wrap the execution in an auto-executing async function\n (async (): Promise<void> => {\n const callbackResults = await Promise.allSettled(\n this.initCallbacks.map((callback) => callback(this))\n );\n callbackResults.forEach((result) => {\n if (result.status === 'rejected') reportError(result.reason);\n });\n })().catch((error) => {\n reportError(error);\n });\n\n // Server -> client ping mechanism using WS standard ping control frames\n // We terminate the connection if we did not get a reply in the previous interval\n this.pingInterval = setInterval(\n () => {\n if (!this.isAlive) {\n reportError(\n new EngineError({\n severity: LogSeverity.WARNING,\n message: `Terminating socket connection, ping timeout [${this.id}]`\n })\n );\n this.ws.terminate();\n return;\n }\n this.isAlive = false;\n this.ws.ping();\n reportDebug({ namespace, message: `Ping sent to client [${this.id}]` });\n },\n process.env.WS_PING_INTERVAL\n ? parseInt(process.env.WS_PING_INTERVAL) * 1000\n : 30000\n );\n\n // Track the connection as alive as we get a pong back\n this.ws.on('pong', () => {\n reportDebug({\n namespace,\n message: `Client responded to ping [${this.id}]`\n });\n this.isAlive = true;\n });\n }\n\n /** Get the list of all connected clients indexed by ID */\n public static getSocketClients(): SocketClientList {\n return this.socketClients;\n }\n\n /** Get a client by his ID */\n public static getSocketClient(id: string): SocketClient | undefined {\n return this.socketClients[id];\n }\n\n /**\n * Send a message to the client\n */\n public sendMessage(\n type: string,\n payload: unknown = {},\n options: SocketClientSendMessageOptions = {}\n ): void {\n reportDebug({\n namespace,\n message: `Received request to send message to client of type \"${type}\" [${this.id}]`,\n data: { options }\n });\n let send = false;\n // If the message is sent to unauthenticated user skip auth check\n if (options.noAuth) send = true;\n // If the message is authenticated and with the correct audience, it gets sent\n else if (\n this.authenticated &&\n (this.audience as Array<string>).includes(\n options.audience ?? (process.env.DEFAULT_MESSAGE_AUDIENCE as string)\n )\n )\n send = true;\n\n if (send) {\n reportDebug({\n namespace,\n message: `Sending message to client of type \"${type ?? 'unknown'}\" [${this.id}]`\n });\n this.ws.send(JSON.stringify({ type, payload }));\n }\n }\n\n /** Get the client authentication status */\n public isAuthenticated(): boolean {\n return this.authenticated;\n }\n\n /** Fetch data on the user if he is authenticated */\n public getUser(): SocketUser | undefined {\n if (this.authenticated)\n return {\n userId: this.userId as string,\n deviceId: this.deviceId as string,\n tokenId: this.tokenId as string,\n audience: this.audience as Array<string>\n };\n return undefined;\n }\n\n /** Process an incoming message */\n private async handleMessage(data: RawData): Promise<void> {\n try {\n const message = parseMessage(data.toString('utf-8'));\n reportInfo({\n message: `Received message of type \"${message?.type ?? 'unknown'}\" [${this.id}]`\n });\n switch (message.type) {\n case 'authenticate':\n await this.authenticate(message as SocketAuthenticationMessage);\n break;\n // As not all client libraries allow sending pings through WS control frames,\n // we add a higher level ping mechanism\n case 'ping':\n reportDebug({\n namespace,\n message: `Received ping from client [${this.id}]`\n });\n this.sendMessage('pong', {}, { noAuth: true });\n break;\n default:\n for (const handler of this.handlers) {\n await handler.handle(message, this);\n }\n }\n } catch (error) {\n this.handleError(error);\n }\n }\n\n /**\n * Process an authentication request\n * @param {String} message - Authentication message\n */\n private async authenticate(\n message: SocketAuthenticationMessage\n ): Promise<void> {\n const token = message.payload?.token;\n if (!token) {\n throw new WebError({\n errorCode: 'no-token',\n message: 'No token was given',\n data: { message }\n });\n }\n const payload = await jwtVerify(token);\n this.setUserData(payload);\n\n this.authenticated = true;\n // Time remaining before token expiration\n const authExpiration = payload.exp * 1000 - Date.now();\n // Clear previously created timers\n this.clearTimeouts();\n // Send a refresh request to the client 1 minute before expiration\n this.authRenewTimer = setTimeout(\n () => {\n this.sendMessage('renewAuthentication');\n },\n authExpiration - 60 * 1000\n );\n // Expire client authentication\n this.authExpireTimer = setTimeout(() => {\n this.authenticated = false;\n }, authExpiration);\n\n // Run all the post-authentication callbacks\n const callbackResults = await Promise.allSettled(\n this.authCallbacks.map((callback) => callback(this))\n );\n callbackResults.forEach((result) => {\n if (result.status === 'rejected') reportError(result.reason);\n });\n }\n\n // Clear all the pending timers\n /** */\n private clearTimeouts(): void {\n if (this.authRenewTimer) clearTimeout(this.authRenewTimer);\n if (this.authExpireTimer) clearTimeout(this.authExpireTimer);\n }\n\n /**\n * Fetch the user's data and attach it to the connection for new connections. For existing connections, it checks that the authentication is done on the same user.\n */\n private setUserData({ sub, dev, jti, aud }: UserTokenPayload): void {\n // Check if the user is already authenticated\n if (this.userId) {\n // Check that the token is for the same connection as before\n if (this.userId && this.userId !== sub)\n throw new WebError({\n errorCode: 'wrong-user-token',\n message:\n 'A user tried to authenticate with a token that is not for him [userId]'\n });\n } else {\n // Set the user's ID\n this.userId = sub;\n // Set the user's Device Id\n this.deviceId = dev;\n // Set the token ID\n this.tokenId = jti;\n // Set the aud\n this.audience = aud instanceof Array ? aud : [aud];\n\n reportDebug({\n namespace,\n message: `Successfully authenticated client [${this.id}]`,\n data: {\n userId: this.userId,\n deviceId: this.deviceId,\n tokenId: this.tokenId,\n audience: this.audience\n }\n });\n }\n }\n\n /**\n * Properly return errors to clients\n */\n private handleError(error: unknown): void {\n reportError(error);\n if (error instanceof WebError) {\n this.sendMessage(\n 'error',\n { errorCode: error.errorCode, hint: error.hint },\n { noAuth: true }\n );\n } else if (error instanceof ValidationError) {\n this.sendMessage(\n 'error',\n { errorCode: 'validation-error', hint: error.data },\n { noAuth: true }\n );\n } else {\n this.sendMessage(\n 'error',\n { errorCode: 'server-error' },\n { noAuth: true }\n );\n }\n }\n\n /**\n * Process a socket close event\n */\n private async handleClose(code?: string, reason?: string): Promise<void> {\n delete SocketClient.socketClients[this.id];\n this.clearTimeouts();\n // Stop ping process\n if (this.pingInterval) clearInterval(this.pingInterval);\n // Run all the shutdown callbacks\n const callbackResults = await Promise.allSettled(\n this.shutdownCallbacks.map((callback) => callback(this))\n );\n callbackResults.forEach((result) => {\n if (result.status === 'rejected') reportError(result.reason);\n });\n reportInfo({\n message: `Client disconnected [${this.id}]`,\n data: { code, reason }\n });\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"SocketClient.js","names":["_crypto","require","_parseMessage","_const","_EngineError","_MessageHandler","_ValidationError","_WebError","_jwt","_report","namespace","SocketClient","exports","webSocket","_request","options","_classCallCheck2","default","_defineProperty2","id","randomUUID","ws","establishedAt","Date","reportDebug","message","initCallbacks","Array","authCallbacks","shutdownCallbacks","handlers","handler","MessageHandler","EngineError","socketClients","reportInfo","authTimeoutMs","authTimeout","setTimeout","authenticated","close","on","code","reason","handleClose","bind","toString","catch","error","reportError","severity","LogSeverity","WARNING","data","handleMessage","callbackResults","Promise","allSettled","map","callback","forEach","result","status","pingInterval","setInterval","isAlive","terminate","ping","process","env","WS_PING_INTERVAL","parseInt","_createClass2","key","value","sendMessage","type","payload","send","noAuth","audience","includes","DEFAULT_MESSAGE_AUDIENCE","JSON","stringify","clearTimeouts","clearTimeout","isAuthenticated","getUser","userId","deviceId","tokenId","user","tokenUser","expiresAt","authExpiresAt","undefined","parseMessage","authenticate","handle","handleError","token","WebError","errorCode","jwtVerify","setUserData","exp","authExpiration","now","authRenewTimer","authExpireTimer","sub","dev","jti","aud","hint","ValidationError","clearInterval","getSocketClients","getSocketClient"],"sources":["../../../src/entities/SocketClient/SocketClient.ts"],"sourcesContent":["import { randomUUID } from 'crypto';\nimport { IncomingMessage } from 'http';\nimport WS, { RawData } from 'ws';\nimport { parseMessage } from './parseMessage';\nimport {\n SocketClientOptions,\n SocketClientSendMessageOptions,\n SocketAuthenticationMessage,\n SocketClientCallback,\n SocketClientList,\n SocketUser\n} from './SocketClient.types';\nimport { LogSeverity } from 'const';\nimport { EngineError } from 'entities/EngineError';\nimport { MessageHandler } from 'entities/MessageHandler';\nimport { ValidationError } from 'entities/ValidationError';\nimport { WebError } from 'entities/WebError';\nimport { jwtVerify, UserTokenPayload } from 'utils/jwt';\nimport { reportInfo, reportError, reportDebug } from 'utils/report';\n\nconst namespace = 'SocketClient';\n\n/**\n * Class where each instance represents a client connected through web-sockets\n */\nexport class SocketClient {\n /** Mapping of all the connected socket clients */\n private static socketClients: SocketClientList = {};\n /** Unique identifier of the client */\n public readonly id: string;\n /** Date at which the client connection was established */\n public readonly establishedAt: Date;\n /** WS instance of the client connection */\n private ws: WS;\n /** List of message handlers that are registered with the client */\n private handlers: Array<MessageHandler>;\n /** Callback function that are called when the client is created */\n private initCallbacks: Array<SocketClientCallback> = [];\n /** Callback function that are called when the client successfully authenticates */\n private authCallbacks: Array<SocketClientCallback> = [];\n /** Callback function that are called when the client connection is terminated */\n private shutdownCallbacks: Array<SocketClientCallback> = [];\n /** Authentication status of the client */\n private authenticated = false;\n /** Timer used to track when to send authentication renewal reminder to the client */\n private authRenewTimer: NodeJS.Timeout | string | number | undefined;\n /** Timers used to track the time at which a user losses authentication */\n private authExpireTimer: NodeJS.Timeout | string | number | undefined;\n /** ID of the user that is authenticated */\n private userId: undefined | string;\n /** ID of the device with which the client authenticated */\n private deviceId: undefined | string;\n /** Id of the token with which the client authenticated */\n private tokenId: undefined | string;\n /** Audience claims that were in the latest authentication token used by the client */\n private audience: undefined | Array<string>;\n /** Status tracking variable used to check the liveness of connections */\n private isAlive = true;\n /** The `user` claim of the token the client authenticated with */\n private tokenUser: undefined | Record<string, unknown>;\n /** Timestamp (ms) at which the current authentication expires */\n private authExpiresAt: undefined | number;\n /** Closes the connection if the client does not authenticate in time */\n private authTimeout: NodeJS.Timeout | undefined;\n /** Timer used to track interval between client pinging */\n private pingInterval: NodeJS.Timeout | string | number | undefined;\n\n /**\n * Create a WS client\n * @param webSocket - The WebSocket instance\n * @param _request - The incoming HTTP request (reserved for future use)\n * @param options - Socket client configuration options\n */\n public constructor(\n webSocket: WS,\n _request: IncomingMessage,\n options: SocketClientOptions\n ) {\n this.id = randomUUID();\n this.ws = webSocket;\n this.establishedAt = new Date();\n\n reportDebug({ namespace, message: `Creating socket client [${this.id}]` });\n\n // Make sure that callbacks are made as lists of functions\n // Init\n if (typeof options.initCallbacks === 'function')\n this.initCallbacks = [options.initCallbacks];\n else if (options.initCallbacks instanceof Array)\n this.initCallbacks = options.initCallbacks;\n // Auth\n if (typeof options.authCallbacks === 'function')\n this.authCallbacks = [options.authCallbacks];\n else if (options.authCallbacks instanceof Array)\n this.authCallbacks = options.authCallbacks;\n // Shutdown\n if (typeof options.shutdownCallbacks === 'function')\n this.shutdownCallbacks = [options.shutdownCallbacks];\n else if (options.shutdownCallbacks instanceof Array)\n this.shutdownCallbacks = options.shutdownCallbacks;\n\n // Check that all handlers are valid\n this.handlers = options.handlers;\n for (const handler of this.handlers) {\n if (!(handler instanceof MessageHandler))\n throw new EngineError({\n message: 'Handler is not an instance of MessageHandler'\n });\n }\n // Register in clients list\n SocketClient.socketClients[this.id] = this;\n\n reportInfo({ message: `Client connected [${this.id}]` });\n // Optionally close connections that do not authenticate in time\n if (options.authTimeoutMs && options.authTimeoutMs > 0) {\n this.authTimeout = setTimeout(() => {\n if (!this.authenticated) this.close(4401, 'Authentication required');\n }, options.authTimeoutMs);\n }\n // On socket close, deregister from clients list\n this.ws.on('close', (code: number, reason: Buffer) => {\n this.handleClose\n .bind(this)(code, reason?.toString())\n .catch((error) => {\n reportError(error);\n });\n });\n // On socket error, log the error\n this.ws.on('error', (error) => {\n reportError(\n new EngineError({\n severity: LogSeverity.WARNING,\n message: `Error [${this.id}]`\n })\n );\n reportError(error);\n });\n // When receiving a message, call message handler\n this.ws.on('message', (data) => {\n this.handleMessage\n .bind(this)(data)\n .catch((error) => {\n reportError(error);\n });\n });\n\n // Run all the init callbacks\n // For proper error handling of potential asynchronous callbacks, we wrap the execution in an auto-executing async function\n (async (): Promise<void> => {\n const callbackResults = await Promise.allSettled(\n this.initCallbacks.map((callback) => callback(this))\n );\n callbackResults.forEach((result) => {\n if (result.status === 'rejected') reportError(result.reason);\n });\n })().catch((error) => {\n reportError(error);\n });\n\n // Server -> client ping mechanism using WS standard ping control frames\n // We terminate the connection if we did not get a reply in the previous interval\n this.pingInterval = setInterval(\n () => {\n if (!this.isAlive) {\n reportError(\n new EngineError({\n severity: LogSeverity.WARNING,\n message: `Terminating socket connection, ping timeout [${this.id}]`\n })\n );\n this.ws.terminate();\n return;\n }\n this.isAlive = false;\n this.ws.ping();\n reportDebug({ namespace, message: `Ping sent to client [${this.id}]` });\n },\n process.env.WS_PING_INTERVAL\n ? parseInt(process.env.WS_PING_INTERVAL) * 1000\n : 30000\n );\n\n // Track the connection as alive as we get a pong back\n this.ws.on('pong', () => {\n reportDebug({\n namespace,\n message: `Client responded to ping [${this.id}]`\n });\n this.isAlive = true;\n });\n }\n\n /** Get the list of all connected clients indexed by ID */\n public static getSocketClients(): SocketClientList {\n return this.socketClients;\n }\n\n /** Get a client by his ID */\n public static getSocketClient(id: string): SocketClient | undefined {\n return this.socketClients[id];\n }\n\n /**\n * Send a message to the client\n */\n public sendMessage(\n type: string,\n payload: unknown = {},\n options: SocketClientSendMessageOptions = {}\n ): void {\n reportDebug({\n namespace,\n message: `Received request to send message to client of type \"${type}\" [${this.id}]`,\n data: { options }\n });\n let send = false;\n // If the message is sent to unauthenticated user skip auth check\n if (options.noAuth) send = true;\n // If the message is authenticated and with the correct audience, it gets sent\n else if (\n this.authenticated &&\n (this.audience as Array<string>).includes(\n options.audience ?? (process.env.DEFAULT_MESSAGE_AUDIENCE as string)\n )\n )\n send = true;\n\n if (send) {\n reportDebug({\n namespace,\n message: `Sending message to client of type \"${type ?? 'unknown'}\" [${this.id}]`\n });\n this.ws.send(JSON.stringify({ type, payload }));\n }\n }\n\n /**\n * Close the connection\n * @param code - WebSocket close code (4000-4999 are free for applications, e.g. 4401 / 4403)\n * @param reason - Human readable reason, sent to the client\n */\n public close(code = 1000, reason?: string): void {\n this.clearTimeouts();\n if (this.authTimeout) clearTimeout(this.authTimeout);\n this.ws.close(code, reason);\n }\n\n /** Get the client authentication status */\n public isAuthenticated(): boolean {\n return this.authenticated;\n }\n\n /** Fetch data on the user if he is authenticated */\n public getUser(): SocketUser | undefined {\n if (this.authenticated)\n return {\n userId: this.userId as string,\n deviceId: this.deviceId as string,\n tokenId: this.tokenId as string,\n audience: this.audience as Array<string>,\n user: this.tokenUser,\n expiresAt: this.authExpiresAt\n };\n return undefined;\n }\n\n /** Process an incoming message */\n private async handleMessage(data: RawData): Promise<void> {\n try {\n const message = parseMessage(data.toString('utf-8'));\n reportInfo({\n message: `Received message of type \"${message?.type ?? 'unknown'}\" [${this.id}]`\n });\n switch (message.type) {\n case 'authenticate':\n await this.authenticate(message as SocketAuthenticationMessage);\n break;\n // As not all client libraries allow sending pings through WS control frames,\n // we add a higher level ping mechanism\n case 'ping':\n reportDebug({\n namespace,\n message: `Received ping from client [${this.id}]`\n });\n this.sendMessage('pong', {}, { noAuth: true });\n break;\n default:\n for (const handler of this.handlers) {\n await handler.handle(message, this);\n }\n }\n } catch (error) {\n this.handleError(error);\n }\n }\n\n /**\n * Process an authentication request\n * @param {String} message - Authentication message\n */\n private async authenticate(\n message: SocketAuthenticationMessage\n ): Promise<void> {\n const token = message.payload?.token;\n if (!token) {\n throw new WebError({\n errorCode: 'no-token',\n message: 'No token was given',\n data: { message }\n });\n }\n const payload = await jwtVerify(token);\n this.setUserData(payload);\n\n this.authenticated = true;\n this.tokenUser = payload.user;\n this.authExpiresAt = payload.exp * 1000;\n if (this.authTimeout) clearTimeout(this.authTimeout);\n // Time remaining before token expiration\n const authExpiration = payload.exp * 1000 - Date.now();\n // Clear previously created timers\n this.clearTimeouts();\n // Send a refresh request to the client 1 minute before expiration\n this.authRenewTimer = setTimeout(\n () => {\n this.sendMessage('renewAuthentication');\n },\n authExpiration - 60 * 1000\n );\n // Expire client authentication\n this.authExpireTimer = setTimeout(() => {\n this.authenticated = false;\n }, authExpiration);\n\n // Run all the post-authentication callbacks\n const callbackResults = await Promise.allSettled(\n this.authCallbacks.map((callback) => callback(this))\n );\n callbackResults.forEach((result) => {\n if (result.status === 'rejected') reportError(result.reason);\n });\n }\n\n // Clear all the pending timers\n /** */\n private clearTimeouts(): void {\n if (this.authRenewTimer) clearTimeout(this.authRenewTimer);\n if (this.authExpireTimer) clearTimeout(this.authExpireTimer);\n }\n\n /**\n * Fetch the user's data and attach it to the connection for new connections. For existing connections, it checks that the authentication is done on the same user.\n */\n private setUserData({ sub, dev, jti, aud }: UserTokenPayload): void {\n // Check if the user is already authenticated\n if (this.userId) {\n // Check that the token is for the same connection as before\n if (this.userId && this.userId !== sub)\n throw new WebError({\n errorCode: 'wrong-user-token',\n message:\n 'A user tried to authenticate with a token that is not for him [userId]'\n });\n } else {\n // Set the user's ID\n this.userId = sub;\n // Set the user's Device Id\n this.deviceId = dev;\n // Set the token ID\n this.tokenId = jti;\n // Set the aud\n this.audience = aud instanceof Array ? aud : [aud];\n\n reportDebug({\n namespace,\n message: `Successfully authenticated client [${this.id}]`,\n data: {\n userId: this.userId,\n deviceId: this.deviceId,\n tokenId: this.tokenId,\n audience: this.audience\n }\n });\n }\n }\n\n /**\n * Properly return errors to clients\n */\n private handleError(error: unknown): void {\n reportError(error);\n if (error instanceof WebError) {\n this.sendMessage(\n 'error',\n { errorCode: error.errorCode, hint: error.hint },\n { noAuth: true }\n );\n } else if (error instanceof ValidationError) {\n this.sendMessage(\n 'error',\n { errorCode: 'validation-error', hint: error.data },\n { noAuth: true }\n );\n } else {\n this.sendMessage(\n 'error',\n { errorCode: 'server-error' },\n { noAuth: true }\n );\n }\n }\n\n /**\n * Process a socket close event\n */\n private async handleClose(code?: number, reason?: string): Promise<void> {\n delete SocketClient.socketClients[this.id];\n this.clearTimeouts();\n if (this.authTimeout) clearTimeout(this.authTimeout);\n // Stop ping process\n if (this.pingInterval) clearInterval(this.pingInterval);\n // Run all the shutdown callbacks\n const callbackResults = await Promise.allSettled(\n this.shutdownCallbacks.map((callback) => callback(this))\n );\n callbackResults.forEach((result) => {\n if (result.status === 'rejected') reportError(result.reason);\n });\n reportInfo({\n message: `Client disconnected [${this.id}]`,\n data: { code, reason }\n });\n }\n}\n"],"mappings":";;;;;;;;;;AAAA,IAAAA,OAAA,GAAAC,OAAA;AAGA,IAAAC,aAAA,GAAAD,OAAA;AASA,IAAAE,MAAA,GAAAF,OAAA;AACA,IAAAG,YAAA,GAAAH,OAAA;AACA,IAAAI,eAAA,GAAAJ,OAAA;AACA,IAAAK,gBAAA,GAAAL,OAAA;AACA,IAAAM,SAAA,GAAAN,OAAA;AACA,IAAAO,IAAA,GAAAP,OAAA;AACA,IAAAQ,OAAA,GAAAR,OAAA;AAEA,MAAMS,SAAS,GAAG,cAAc;;AAEhC;AACA;AACA;AAFA,IAGaC,YAAY,GAAAC,OAAA,CAAAD,YAAA;EA0CvB;AACF;AACA;AACA;AACA;AACA;EACE,SAAAA,aACEE,SAAa,EACbC,QAAyB,EACzBC,OAA4B,EAC5B;IAAA,IAAAC,gBAAA,CAAAC,OAAA,QAAAN,YAAA;IAjDF;IAAA,IAAAO,gBAAA,CAAAD,OAAA;IAEA;IAAA,IAAAC,gBAAA,CAAAD,OAAA;IAEA;IAAA,IAAAC,gBAAA,CAAAD,OAAA;IAEA;IAAA,IAAAC,gBAAA,CAAAD,OAAA;IAEA;IAAA,IAAAC,gBAAA,CAAAD,OAAA,yBACqD,EAAE;IACvD;IAAA,IAAAC,gBAAA,CAAAD,OAAA,yBACqD,EAAE;IACvD;IAAA,IAAAC,gBAAA,CAAAD,OAAA,6BACyD,EAAE;IAC3D;IAAA,IAAAC,gBAAA,CAAAD,OAAA,yBACwB,KAAK;IAC7B;IAAA,IAAAC,gBAAA,CAAAD,OAAA;IAEA;IAAA,IAAAC,gBAAA,CAAAD,OAAA;IAEA;IAAA,IAAAC,gBAAA,CAAAD,OAAA;IAEA;IAAA,IAAAC,gBAAA,CAAAD,OAAA;IAEA;IAAA,IAAAC,gBAAA,CAAAD,OAAA;IAEA;IAAA,IAAAC,gBAAA,CAAAD,OAAA;IAEA;IAAA,IAAAC,gBAAA,CAAAD,OAAA,mBACkB,IAAI;IACtB;IAAA,IAAAC,gBAAA,CAAAD,OAAA;IAEA;IAAA,IAAAC,gBAAA,CAAAD,OAAA;IAEA;IAAA,IAAAC,gBAAA,CAAAD,OAAA;IAEA;IAAA,IAAAC,gBAAA,CAAAD,OAAA;IAcE,IAAI,CAACE,EAAE,GAAG,IAAAC,kBAAU,EAAC,CAAC;IACtB,IAAI,CAACC,EAAE,GAAGR,SAAS;IACnB,IAAI,CAACS,aAAa,GAAG,IAAIC,IAAI,CAAC,CAAC;IAE/B,IAAAC,mBAAW,EAAC;MAAEd,SAAS;MAAEe,OAAO,EAAE,2BAA2B,IAAI,CAACN,EAAE;IAAI,CAAC,CAAC;;IAE1E;IACA;IACA,IAAI,OAAOJ,OAAO,CAACW,aAAa,KAAK,UAAU,EAC7C,IAAI,CAACA,aAAa,GAAG,CAACX,OAAO,CAACW,aAAa,CAAC,CAAC,KAC1C,IAAIX,OAAO,CAACW,aAAa,YAAYC,KAAK,EAC7C,IAAI,CAACD,aAAa,GAAGX,OAAO,CAACW,aAAa;IAC5C;IACA,IAAI,OAAOX,OAAO,CAACa,aAAa,KAAK,UAAU,EAC7C,IAAI,CAACA,aAAa,GAAG,CAACb,OAAO,CAACa,aAAa,CAAC,CAAC,KAC1C,IAAIb,OAAO,CAACa,aAAa,YAAYD,KAAK,EAC7C,IAAI,CAACC,aAAa,GAAGb,OAAO,CAACa,aAAa;IAC5C;IACA,IAAI,OAAOb,OAAO,CAACc,iBAAiB,KAAK,UAAU,EACjD,IAAI,CAACA,iBAAiB,GAAG,CAACd,OAAO,CAACc,iBAAiB,CAAC,CAAC,KAClD,IAAId,OAAO,CAACc,iBAAiB,YAAYF,KAAK,EACjD,IAAI,CAACE,iBAAiB,GAAGd,OAAO,CAACc,iBAAiB;;IAEpD;IACA,IAAI,CAACC,QAAQ,GAAGf,OAAO,CAACe,QAAQ;IAChC,KAAK,MAAMC,OAAO,IAAI,IAAI,CAACD,QAAQ,EAAE;MACnC,IAAI,EAAEC,OAAO,YAAYC,8BAAc,CAAC,EACtC,MAAM,IAAIC,wBAAW,CAAC;QACpBR,OAAO,EAAE;MACX,CAAC,CAAC;IACN;IACA;IACAd,YAAY,CAACuB,aAAa,CAAC,IAAI,CAACf,EAAE,CAAC,GAAG,IAAI;IAE1C,IAAAgB,kBAAU,EAAC;MAAEV,OAAO,EAAE,qBAAqB,IAAI,CAACN,EAAE;IAAI,CAAC,CAAC;IACxD;IACA,IAAIJ,OAAO,CAACqB,aAAa,IAAIrB,OAAO,CAACqB,aAAa,GAAG,CAAC,EAAE;MACtD,IAAI,CAACC,WAAW,GAAGC,UAAU,CAAC,MAAM;QAClC,IAAI,CAAC,IAAI,CAACC,aAAa,EAAE,IAAI,CAACC,KAAK,CAAC,IAAI,EAAE,yBAAyB,CAAC;MACtE,CAAC,EAAEzB,OAAO,CAACqB,aAAa,CAAC;IAC3B;IACA;IACA,IAAI,CAACf,EAAE,CAACoB,EAAE,CAAC,OAAO,EAAE,CAACC,IAAY,EAAEC,MAAc,KAAK;MACpD,IAAI,CAACC,WAAW,CACbC,IAAI,CAAC,IAAI,CAAC,CAACH,IAAI,EAAEC,MAAM,EAAEG,QAAQ,CAAC,CAAC,CAAC,CACpCC,KAAK,CAAEC,KAAK,IAAK;QAChB,IAAAC,mBAAW,EAACD,KAAK,CAAC;MACpB,CAAC,CAAC;IACN,CAAC,CAAC;IACF;IACA,IAAI,CAAC3B,EAAE,CAACoB,EAAE,CAAC,OAAO,EAAGO,KAAK,IAAK;MAC7B,IAAAC,mBAAW,EACT,IAAIhB,wBAAW,CAAC;QACdiB,QAAQ,EAAEC,kBAAW,CAACC,OAAO;QAC7B3B,OAAO,EAAE,UAAU,IAAI,CAACN,EAAE;MAC5B,CAAC,CACH,CAAC;MACD,IAAA8B,mBAAW,EAACD,KAAK,CAAC;IACpB,CAAC,CAAC;IACF;IACA,IAAI,CAAC3B,EAAE,CAACoB,EAAE,CAAC,SAAS,EAAGY,IAAI,IAAK;MAC9B,IAAI,CAACC,aAAa,CACfT,IAAI,CAAC,IAAI,CAAC,CAACQ,IAAI,CAAC,CAChBN,KAAK,CAAEC,KAAK,IAAK;QAChB,IAAAC,mBAAW,EAACD,KAAK,CAAC;MACpB,CAAC,CAAC;IACN,CAAC,CAAC;;IAEF;IACA;IACA,CAAC,YAA2B;MAC1B,MAAMO,eAAe,GAAG,MAAMC,OAAO,CAACC,UAAU,CAC9C,IAAI,CAAC/B,aAAa,CAACgC,GAAG,CAAEC,QAAQ,IAAKA,QAAQ,CAAC,IAAI,CAAC,CACrD,CAAC;MACDJ,eAAe,CAACK,OAAO,CAAEC,MAAM,IAAK;QAClC,IAAIA,MAAM,CAACC,MAAM,KAAK,UAAU,EAAE,IAAAb,mBAAW,EAACY,MAAM,CAAClB,MAAM,CAAC;MAC9D,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,CAACI,KAAK,CAAEC,KAAK,IAAK;MACpB,IAAAC,mBAAW,EAACD,KAAK,CAAC;IACpB,CAAC,CAAC;;IAEF;IACA;IACA,IAAI,CAACe,YAAY,GAAGC,WAAW,CAC7B,MAAM;MACJ,IAAI,CAAC,IAAI,CAACC,OAAO,EAAE;QACjB,IAAAhB,mBAAW,EACT,IAAIhB,wBAAW,CAAC;UACdiB,QAAQ,EAAEC,kBAAW,CAACC,OAAO;UAC7B3B,OAAO,EAAE,gDAAgD,IAAI,CAACN,EAAE;QAClE,CAAC,CACH,CAAC;QACD,IAAI,CAACE,EAAE,CAAC6C,SAAS,CAAC,CAAC;QACnB;MACF;MACA,IAAI,CAACD,OAAO,GAAG,KAAK;MACpB,IAAI,CAAC5C,EAAE,CAAC8C,IAAI,CAAC,CAAC;MACd,IAAA3C,mBAAW,EAAC;QAAEd,SAAS;QAAEe,OAAO,EAAE,wBAAwB,IAAI,CAACN,EAAE;MAAI,CAAC,CAAC;IACzE,CAAC,EACDiD,OAAO,CAACC,GAAG,CAACC,gBAAgB,GACxBC,QAAQ,CAACH,OAAO,CAACC,GAAG,CAACC,gBAAgB,CAAC,GAAG,IAAI,GAC7C,KACN,CAAC;;IAED;IACA,IAAI,CAACjD,EAAE,CAACoB,EAAE,CAAC,MAAM,EAAE,MAAM;MACvB,IAAAjB,mBAAW,EAAC;QACVd,SAAS;QACTe,OAAO,EAAE,6BAA6B,IAAI,CAACN,EAAE;MAC/C,CAAC,CAAC;MACF,IAAI,CAAC8C,OAAO,GAAG,IAAI;IACrB,CAAC,CAAC;EACJ;;EAEA;EAAA,WAAAO,aAAA,CAAAvD,OAAA,EAAAN,YAAA;IAAA8D,GAAA;IAAAC,KAAA;IAUA;AACF;AACA;IACE,SAAOC,WAAWA,CAChBC,IAAY,EACZC,OAAgB,GAAG,CAAC,CAAC,EACrB9D,OAAuC,GAAG,CAAC,CAAC,EACtC;MACN,IAAAS,mBAAW,EAAC;QACVd,SAAS;QACTe,OAAO,EAAE,uDAAuDmD,IAAI,MAAM,IAAI,CAACzD,EAAE,GAAG;QACpFkC,IAAI,EAAE;UAAEtC;QAAQ;MAClB,CAAC,CAAC;MACF,IAAI+D,IAAI,GAAG,KAAK;MAChB;MACA,IAAI/D,OAAO,CAACgE,MAAM,EAAED,IAAI,GAAG,IAAI;MAC/B;MAAA,KACK,IACH,IAAI,CAACvC,aAAa,IACjB,IAAI,CAACyC,QAAQ,CAAmBC,QAAQ,CACvClE,OAAO,CAACiE,QAAQ,IAAKZ,OAAO,CAACC,GAAG,CAACa,wBACnC,CAAC,EAEDJ,IAAI,GAAG,IAAI;MAEb,IAAIA,IAAI,EAAE;QACR,IAAAtD,mBAAW,EAAC;UACVd,SAAS;UACTe,OAAO,EAAE,sCAAsCmD,IAAI,IAAI,SAAS,MAAM,IAAI,CAACzD,EAAE;QAC/E,CAAC,CAAC;QACF,IAAI,CAACE,EAAE,CAACyD,IAAI,CAACK,IAAI,CAACC,SAAS,CAAC;UAAER,IAAI;UAAEC;QAAQ,CAAC,CAAC,CAAC;MACjD;IACF;;IAEA;AACF;AACA;AACA;AACA;EAJE;IAAAJ,GAAA;IAAAC,KAAA,EAKA,SAAOlC,KAAKA,CAACE,IAAI,GAAG,IAAI,EAAEC,MAAe,EAAQ;MAC/C,IAAI,CAAC0C,aAAa,CAAC,CAAC;MACpB,IAAI,IAAI,CAAChD,WAAW,EAAEiD,YAAY,CAAC,IAAI,CAACjD,WAAW,CAAC;MACpD,IAAI,CAAChB,EAAE,CAACmB,KAAK,CAACE,IAAI,EAAEC,MAAM,CAAC;IAC7B;;IAEA;EAAA;IAAA8B,GAAA;IAAAC,KAAA,EACA,SAAOa,eAAeA,CAAA,EAAY;MAChC,OAAO,IAAI,CAAChD,aAAa;IAC3B;;IAEA;EAAA;IAAAkC,GAAA;IAAAC,KAAA,EACA,SAAOc,OAAOA,CAAA,EAA2B;MACvC,IAAI,IAAI,CAACjD,aAAa,EACpB,OAAO;QACLkD,MAAM,EAAE,IAAI,CAACA,MAAgB;QAC7BC,QAAQ,EAAE,IAAI,CAACA,QAAkB;QACjCC,OAAO,EAAE,IAAI,CAACA,OAAiB;QAC/BX,QAAQ,EAAE,IAAI,CAACA,QAAyB;QACxCY,IAAI,EAAE,IAAI,CAACC,SAAS;QACpBC,SAAS,EAAE,IAAI,CAACC;MAClB,CAAC;MACH,OAAOC,SAAS;IAClB;;IAEA;EAAA;IAAAvB,GAAA;IAAAC,KAAA,EACA,eAAcpB,aAAaA,CAACD,IAAa,EAAiB;MACxD,IAAI;QACF,MAAM5B,OAAO,GAAG,IAAAwE,0BAAY,EAAC5C,IAAI,CAACP,QAAQ,CAAC,OAAO,CAAC,CAAC;QACpD,IAAAX,kBAAU,EAAC;UACTV,OAAO,EAAE,6BAA6BA,OAAO,EAAEmD,IAAI,IAAI,SAAS,MAAM,IAAI,CAACzD,EAAE;QAC/E,CAAC,CAAC;QACF,QAAQM,OAAO,CAACmD,IAAI;UAClB,KAAK,cAAc;YACjB,MAAM,IAAI,CAACsB,YAAY,CAACzE,OAAsC,CAAC;YAC/D;UACF;UACA;UACA,KAAK,MAAM;YACT,IAAAD,mBAAW,EAAC;cACVd,SAAS;cACTe,OAAO,EAAE,8BAA8B,IAAI,CAACN,EAAE;YAChD,CAAC,CAAC;YACF,IAAI,CAACwD,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE;cAAEI,MAAM,EAAE;YAAK,CAAC,CAAC;YAC9C;UACF;YACE,KAAK,MAAMhD,OAAO,IAAI,IAAI,CAACD,QAAQ,EAAE;cACnC,MAAMC,OAAO,CAACoE,MAAM,CAAC1E,OAAO,EAAE,IAAI,CAAC;YACrC;QACJ;MACF,CAAC,CAAC,OAAOuB,KAAK,EAAE;QACd,IAAI,CAACoD,WAAW,CAACpD,KAAK,CAAC;MACzB;IACF;;IAEA;AACF;AACA;AACA;EAHE;IAAAyB,GAAA;IAAAC,KAAA,EAIA,eAAcwB,YAAYA,CACxBzE,OAAoC,EACrB;MACf,MAAM4E,KAAK,GAAG5E,OAAO,CAACoD,OAAO,EAAEwB,KAAK;MACpC,IAAI,CAACA,KAAK,EAAE;QACV,MAAM,IAAIC,kBAAQ,CAAC;UACjBC,SAAS,EAAE,UAAU;UACrB9E,OAAO,EAAE,oBAAoB;UAC7B4B,IAAI,EAAE;YAAE5B;UAAQ;QAClB,CAAC,CAAC;MACJ;MACA,MAAMoD,OAAO,GAAG,MAAM,IAAA2B,cAAS,EAACH,KAAK,CAAC;MACtC,IAAI,CAACI,WAAW,CAAC5B,OAAO,CAAC;MAEzB,IAAI,CAACtC,aAAa,GAAG,IAAI;MACzB,IAAI,CAACsD,SAAS,GAAGhB,OAAO,CAACe,IAAI;MAC7B,IAAI,CAACG,aAAa,GAAGlB,OAAO,CAAC6B,GAAG,GAAG,IAAI;MACvC,IAAI,IAAI,CAACrE,WAAW,EAAEiD,YAAY,CAAC,IAAI,CAACjD,WAAW,CAAC;MACpD;MACA,MAAMsE,cAAc,GAAG9B,OAAO,CAAC6B,GAAG,GAAG,IAAI,GAAGnF,IAAI,CAACqF,GAAG,CAAC,CAAC;MACtD;MACA,IAAI,CAACvB,aAAa,CAAC,CAAC;MACpB;MACA,IAAI,CAACwB,cAAc,GAAGvE,UAAU,CAC9B,MAAM;QACJ,IAAI,CAACqC,WAAW,CAAC,qBAAqB,CAAC;MACzC,CAAC,EACDgC,cAAc,GAAG,EAAE,GAAG,IACxB,CAAC;MACD;MACA,IAAI,CAACG,eAAe,GAAGxE,UAAU,CAAC,MAAM;QACtC,IAAI,CAACC,aAAa,GAAG,KAAK;MAC5B,CAAC,EAAEoE,cAAc,CAAC;;MAElB;MACA,MAAMpD,eAAe,GAAG,MAAMC,OAAO,CAACC,UAAU,CAC9C,IAAI,CAAC7B,aAAa,CAAC8B,GAAG,CAAEC,QAAQ,IAAKA,QAAQ,CAAC,IAAI,CAAC,CACrD,CAAC;MACDJ,eAAe,CAACK,OAAO,CAAEC,MAAM,IAAK;QAClC,IAAIA,MAAM,CAACC,MAAM,KAAK,UAAU,EAAE,IAAAb,mBAAW,EAACY,MAAM,CAAClB,MAAM,CAAC;MAC9D,CAAC,CAAC;IACJ;;IAEA;IACA;EAAA;IAAA8B,GAAA;IAAAC,KAAA,EACA,SAAQW,aAAaA,CAAA,EAAS;MAC5B,IAAI,IAAI,CAACwB,cAAc,EAAEvB,YAAY,CAAC,IAAI,CAACuB,cAAc,CAAC;MAC1D,IAAI,IAAI,CAACC,eAAe,EAAExB,YAAY,CAAC,IAAI,CAACwB,eAAe,CAAC;IAC9D;;IAEA;AACF;AACA;EAFE;IAAArC,GAAA;IAAAC,KAAA,EAGA,SAAQ+B,WAAWA,CAAC;MAAEM,GAAG;MAAEC,GAAG;MAAEC,GAAG;MAAEC;IAAsB,CAAC,EAAQ;MAClE;MACA,IAAI,IAAI,CAACzB,MAAM,EAAE;QACf;QACA,IAAI,IAAI,CAACA,MAAM,IAAI,IAAI,CAACA,MAAM,KAAKsB,GAAG,EACpC,MAAM,IAAIT,kBAAQ,CAAC;UACjBC,SAAS,EAAE,kBAAkB;UAC7B9E,OAAO,EACL;QACJ,CAAC,CAAC;MACN,CAAC,MAAM;QACL;QACA,IAAI,CAACgE,MAAM,GAAGsB,GAAG;QACjB;QACA,IAAI,CAACrB,QAAQ,GAAGsB,GAAG;QACnB;QACA,IAAI,CAACrB,OAAO,GAAGsB,GAAG;QAClB;QACA,IAAI,CAACjC,QAAQ,GAAGkC,GAAG,YAAYvF,KAAK,GAAGuF,GAAG,GAAG,CAACA,GAAG,CAAC;QAElD,IAAA1F,mBAAW,EAAC;UACVd,SAAS;UACTe,OAAO,EAAE,sCAAsC,IAAI,CAACN,EAAE,GAAG;UACzDkC,IAAI,EAAE;YACJoC,MAAM,EAAE,IAAI,CAACA,MAAM;YACnBC,QAAQ,EAAE,IAAI,CAACA,QAAQ;YACvBC,OAAO,EAAE,IAAI,CAACA,OAAO;YACrBX,QAAQ,EAAE,IAAI,CAACA;UACjB;QACF,CAAC,CAAC;MACJ;IACF;;IAEA;AACF;AACA;EAFE;IAAAP,GAAA;IAAAC,KAAA,EAGA,SAAQ0B,WAAWA,CAACpD,KAAc,EAAQ;MACxC,IAAAC,mBAAW,EAACD,KAAK,CAAC;MAClB,IAAIA,KAAK,YAAYsD,kBAAQ,EAAE;QAC7B,IAAI,CAAC3B,WAAW,CACd,OAAO,EACP;UAAE4B,SAAS,EAAEvD,KAAK,CAACuD,SAAS;UAAEY,IAAI,EAAEnE,KAAK,CAACmE;QAAK,CAAC,EAChD;UAAEpC,MAAM,EAAE;QAAK,CACjB,CAAC;MACH,CAAC,MAAM,IAAI/B,KAAK,YAAYoE,gCAAe,EAAE;QAC3C,IAAI,CAACzC,WAAW,CACd,OAAO,EACP;UAAE4B,SAAS,EAAE,kBAAkB;UAAEY,IAAI,EAAEnE,KAAK,CAACK;QAAK,CAAC,EACnD;UAAE0B,MAAM,EAAE;QAAK,CACjB,CAAC;MACH,CAAC,MAAM;QACL,IAAI,CAACJ,WAAW,CACd,OAAO,EACP;UAAE4B,SAAS,EAAE;QAAe,CAAC,EAC7B;UAAExB,MAAM,EAAE;QAAK,CACjB,CAAC;MACH;IACF;;IAEA;AACF;AACA;EAFE;IAAAN,GAAA;IAAAC,KAAA,EAGA,eAAc9B,WAAWA,CAACF,IAAa,EAAEC,MAAe,EAAiB;MACvE,OAAOhC,YAAY,CAACuB,aAAa,CAAC,IAAI,CAACf,EAAE,CAAC;MAC1C,IAAI,CAACkE,aAAa,CAAC,CAAC;MACpB,IAAI,IAAI,CAAChD,WAAW,EAAEiD,YAAY,CAAC,IAAI,CAACjD,WAAW,CAAC;MACpD;MACA,IAAI,IAAI,CAAC0B,YAAY,EAAEsD,aAAa,CAAC,IAAI,CAACtD,YAAY,CAAC;MACvD;MACA,MAAMR,eAAe,GAAG,MAAMC,OAAO,CAACC,UAAU,CAC9C,IAAI,CAAC5B,iBAAiB,CAAC6B,GAAG,CAAEC,QAAQ,IAAKA,QAAQ,CAAC,IAAI,CAAC,CACzD,CAAC;MACDJ,eAAe,CAACK,OAAO,CAAEC,MAAM,IAAK;QAClC,IAAIA,MAAM,CAACC,MAAM,KAAK,UAAU,EAAE,IAAAb,mBAAW,EAACY,MAAM,CAAClB,MAAM,CAAC;MAC9D,CAAC,CAAC;MACF,IAAAR,kBAAU,EAAC;QACTV,OAAO,EAAE,wBAAwB,IAAI,CAACN,EAAE,GAAG;QAC3CkC,IAAI,EAAE;UAAEX,IAAI;UAAEC;QAAO;MACvB,CAAC,CAAC;IACJ;EAAC;IAAA8B,GAAA;IAAAC,KAAA,EA/OD,SAAc4C,gBAAgBA,CAAA,EAAqB;MACjD,OAAO,IAAI,CAACpF,aAAa;IAC3B;;IAEA;EAAA;IAAAuC,GAAA;IAAAC,KAAA,EACA,SAAc6C,eAAeA,CAACpG,EAAU,EAA4B;MAClE,OAAO,IAAI,CAACe,aAAa,CAACf,EAAE,CAAC;IAC/B;EAAC;AAAA;AA9KD;AAAA,IAAAD,gBAAA,CAAAD,OAAA,EADWN,YAAY,mBAE0B,CAAC,CAAC","ignoreList":[]}
|
|
@@ -11,6 +11,8 @@ export interface SocketClientOptions {
|
|
|
11
11
|
authCallbacks?: SocketClientCallback | Array<SocketClientCallback>;
|
|
12
12
|
/** Callback function that are called when the client connection is terminated */
|
|
13
13
|
shutdownCallbacks?: SocketClientCallback | Array<SocketClientCallback>;
|
|
14
|
+
/** Close the connection with code 4401 if the client has not authenticated after this many ms (default: never) */
|
|
15
|
+
authTimeoutMs?: number;
|
|
14
16
|
}
|
|
15
17
|
/** Socket Message abstract typing */
|
|
16
18
|
export interface SocketMessage<T = unknown> {
|
|
@@ -50,4 +52,8 @@ export interface SocketUser {
|
|
|
50
52
|
tokenId: string;
|
|
51
53
|
/** Audience included in the token */
|
|
52
54
|
audience: Array<string>;
|
|
55
|
+
/** The `user` claim of the authentication token (application data such as role or organisation) */
|
|
56
|
+
user?: Record<string, unknown>;
|
|
57
|
+
/** Timestamp (ms) at which the authentication expires */
|
|
58
|
+
expiresAt?: number;
|
|
53
59
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SocketClient.types.js","names":[],"sources":["../../../src/entities/SocketClient/SocketClient.types.ts"],"sourcesContent":["import { SocketClient } from './SocketClient';\nimport { MessageHandler } from 'entities/MessageHandler';\n\nexport type SocketClientCallback = (\n client: SocketClient\n) => void | Promise<void>;\n\n/** SocketClient creation option */\nexport interface SocketClientOptions {\n /** List of message handlers that are registered with the client */\n handlers: Array<MessageHandler>;\n /** Callback function that are called when the client is created */\n initCallbacks?: SocketClientCallback | Array<SocketClientCallback>;\n /** Callback function that are called when the client successfully authenticates */\n authCallbacks?: SocketClientCallback | Array<SocketClientCallback>;\n /** Callback function that are called when the client connection is terminated */\n shutdownCallbacks?: SocketClientCallback | Array<SocketClientCallback>;\n}\n\n/** Socket Message abstract typing */\nexport interface SocketMessage<T = unknown> {\n /** A string that identifies the message type */\n type: string;\n /** Free-form data payload of the message */\n payload: T;\n}\n\n/** SocketMessage used by client for authentication */\nexport interface SocketAuthenticationMessage extends SocketMessage {\n /** Sting that identifies the message type */\n type: 'authenticate';\n /** Data payload of the message */\n payload: {\n /** Authentication token */\n token: string;\n };\n}\n\n/** Options for sending a message with the client */\nexport interface SocketClientSendMessageOptions {\n /** Send message event if the user is not authenticated */\n noAuth?: boolean;\n /** Audience that the authenticated user must have on his token to continue */\n audience?: string;\n}\n\n/** Map of socket clients connected to the server */\nexport interface SocketClientList {\n [id: string]: SocketClient;\n}\n\n/** User that authenticated though his socket */\nexport interface SocketUser {\n /** ID od the user */\n userId: string;\n /** ID of the device */\n deviceId: string;\n /** ID of the token used */\n tokenId: string;\n /** Audience included in the token */\n audience: Array<string>;\n}\n"],"mappings":"","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"SocketClient.types.js","names":[],"sources":["../../../src/entities/SocketClient/SocketClient.types.ts"],"sourcesContent":["import { SocketClient } from './SocketClient';\nimport { MessageHandler } from 'entities/MessageHandler';\n\nexport type SocketClientCallback = (\n client: SocketClient\n) => void | Promise<void>;\n\n/** SocketClient creation option */\nexport interface SocketClientOptions {\n /** List of message handlers that are registered with the client */\n handlers: Array<MessageHandler>;\n /** Callback function that are called when the client is created */\n initCallbacks?: SocketClientCallback | Array<SocketClientCallback>;\n /** Callback function that are called when the client successfully authenticates */\n authCallbacks?: SocketClientCallback | Array<SocketClientCallback>;\n /** Callback function that are called when the client connection is terminated */\n shutdownCallbacks?: SocketClientCallback | Array<SocketClientCallback>;\n /** Close the connection with code 4401 if the client has not authenticated after this many ms (default: never) */\n authTimeoutMs?: number;\n}\n\n/** Socket Message abstract typing */\nexport interface SocketMessage<T = unknown> {\n /** A string that identifies the message type */\n type: string;\n /** Free-form data payload of the message */\n payload: T;\n}\n\n/** SocketMessage used by client for authentication */\nexport interface SocketAuthenticationMessage extends SocketMessage {\n /** Sting that identifies the message type */\n type: 'authenticate';\n /** Data payload of the message */\n payload: {\n /** Authentication token */\n token: string;\n };\n}\n\n/** Options for sending a message with the client */\nexport interface SocketClientSendMessageOptions {\n /** Send message event if the user is not authenticated */\n noAuth?: boolean;\n /** Audience that the authenticated user must have on his token to continue */\n audience?: string;\n}\n\n/** Map of socket clients connected to the server */\nexport interface SocketClientList {\n [id: string]: SocketClient;\n}\n\n/** User that authenticated though his socket */\nexport interface SocketUser {\n /** ID od the user */\n userId: string;\n /** ID of the device */\n deviceId: string;\n /** ID of the token used */\n tokenId: string;\n /** Audience included in the token */\n audience: Array<string>;\n /** The `user` claim of the authentication token (application data such as role or organisation) */\n user?: Record<string, unknown>;\n /** Timestamp (ms) at which the authentication expires */\n expiresAt?: number;\n}\n"],"mappings":"","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["_EngineError","require","Object","keys","forEach","key","exports","defineProperty","enumerable","get","_WebError","_ValidationError","_KeySet","_Endpoint","_MessageHandler","_SocketClient","_Server","_Redis","_Localizator","_GoogleCloudStorage","_AWSS","_Sequelize","_ElasticSearch","_LifecycleController","_PubSub","_PushNotification","_SecretManager"],"sources":["../../src/entities/index.ts"],"sourcesContent":["export * from './EngineError';\nexport * from './WebError';\nexport * from './ValidationError';\nexport * from './KeySet';\nexport * from './Endpoint';\nexport * from './MessageHandler';\nexport * from './SocketClient';\nexport * from './Server';\nexport * from './Redis';\nexport * from './Localizator';\nexport * from './GoogleCloudStorage';\nexport * from './AWSS3';\nexport * from './Sequelize';\nexport * from './ElasticSearch';\nexport * from './LifecycleController';\nexport * from './PubSub';\nexport * from './PushNotification';\nexport * from './SecretManager'
|
|
1
|
+
{"version":3,"file":"index.js","names":["_EngineError","require","Object","keys","forEach","key","exports","defineProperty","enumerable","get","_WebError","_ValidationError","_KeySet","_Endpoint","_MessageHandler","_SocketClient","_Server","_Redis","_Localizator","_GoogleCloudStorage","_AWSS","_Sequelize","_ElasticSearch","_LifecycleController","_PubSub","_PushNotification","_SecretManager"],"sources":["../../src/entities/index.ts"],"sourcesContent":["export * from './EngineError';\nexport * from './WebError';\nexport * from './ValidationError';\nexport * from './KeySet';\nexport * from './Endpoint';\nexport * from './MessageHandler';\nexport * from './SocketClient';\nexport * from './Server';\nexport * from './Redis';\nexport * from './Localizator';\nexport * from './GoogleCloudStorage';\nexport * from './AWSS3';\nexport * from './Sequelize';\nexport * from './ElasticSearch';\nexport * from './LifecycleController';\nexport * from './PubSub';\nexport * from './PushNotification';\nexport * from './SecretManager';\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkPermission.js","names":["checkPermission","requiredActions","req","res","next","user","permissions","status","json","message","requiredActionsArray","Array","isArray","requiredActionsLower","map","action","toLowerCase","hasPermission","some","permission","includes"],"sources":["../../../src/middleware/checkPermission/checkPermission.ts"],"sourcesContent":["import { Request, Response, NextFunction } from 'express';\n\n/** Middleware to check if the user has at least one of the required permissions (case-insensitive). */\nfunction checkPermission(requiredActions: string | string[]) {\n return function (req: Request, res: Response, next: NextFunction) {\n const user = req.user;\n\n if (!user || !user.permissions) {\n res.status(403).json({ message: 'User does not have permissions' });\n return;\n }\n\n // Normalize input to an array of strings\n const requiredActionsArray = Array.isArray(requiredActions)\n ? requiredActions\n : [requiredActions];\n\n // Normalize required actions to lowercase\n const requiredActionsLower = requiredActionsArray.map(action
|
|
1
|
+
{"version":3,"file":"checkPermission.js","names":["checkPermission","requiredActions","req","res","next","user","permissions","status","json","message","requiredActionsArray","Array","isArray","requiredActionsLower","map","action","toLowerCase","hasPermission","some","permission","includes"],"sources":["../../../src/middleware/checkPermission/checkPermission.ts"],"sourcesContent":["import { Request, Response, NextFunction } from 'express';\n\n/** Middleware to check if the user has at least one of the required permissions (case-insensitive). */\nfunction checkPermission(requiredActions: string | string[]) {\n return function (req: Request, res: Response, next: NextFunction) {\n const user = req.user;\n\n if (!user || !user.permissions) {\n res.status(403).json({ message: 'User does not have permissions' });\n return;\n }\n\n // Normalize input to an array of strings\n const requiredActionsArray = Array.isArray(requiredActions)\n ? requiredActions\n : [requiredActions];\n\n // Normalize required actions to lowercase\n const requiredActionsLower = requiredActionsArray.map((action) =>\n action.toLowerCase()\n );\n\n // Check if the user has any of the required permissions (case-insensitive)\n const hasPermission = user.permissions.some((permission: string) =>\n requiredActionsLower.includes(permission.toLowerCase())\n );\n\n if (!hasPermission) {\n res.status(403).json({ message: 'Permission denied' });\n return;\n }\n\n next();\n };\n}\n\nexport { checkPermission };\n"],"mappings":";;;;;;AAEA;AACA,SAASA,eAAeA,CAACC,eAAkC,EAAE;EAC3D,OAAO,UAAUC,GAAY,EAAEC,GAAa,EAAEC,IAAkB,EAAE;IAChE,MAAMC,IAAI,GAAGH,GAAG,CAACG,IAAI;IAErB,IAAI,CAACA,IAAI,IAAI,CAACA,IAAI,CAACC,WAAW,EAAE;MAC9BH,GAAG,CAACI,MAAM,CAAC,GAAG,CAAC,CAACC,IAAI,CAAC;QAAEC,OAAO,EAAE;MAAiC,CAAC,CAAC;MACnE;IACF;;IAEA;IACA,MAAMC,oBAAoB,GAAGC,KAAK,CAACC,OAAO,CAACX,eAAe,CAAC,GACvDA,eAAe,GACf,CAACA,eAAe,CAAC;;IAErB;IACA,MAAMY,oBAAoB,GAAGH,oBAAoB,CAACI,GAAG,CAAEC,MAAM,IAC3DA,MAAM,CAACC,WAAW,CAAC,CACrB,CAAC;;IAED;IACA,MAAMC,aAAa,GAAGZ,IAAI,CAACC,WAAW,CAACY,IAAI,CAAEC,UAAkB,IAC7DN,oBAAoB,CAACO,QAAQ,CAACD,UAAU,CAACH,WAAW,CAAC,CAAC,CACxD,CAAC;IAED,IAAI,CAACC,aAAa,EAAE;MAClBd,GAAG,CAACI,MAAM,CAAC,GAAG,CAAC,CAACC,IAAI,CAAC;QAAEC,OAAO,EAAE;MAAoB,CAAC,CAAC;MACtD;IACF;IAEAL,IAAI,CAAC,CAAC;EACR,CAAC;AACH","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["_checkPermission","require","Object","keys","forEach","key","exports","defineProperty","enumerable","get"],"sources":["../../../src/middleware/checkPermission/index.ts"],"sourcesContent":["export * from './checkPermission'
|
|
1
|
+
{"version":3,"file":"index.js","names":["_checkPermission","require","Object","keys","forEach","key","exports","defineProperty","enumerable","get"],"sources":["../../../src/middleware/checkPermission/index.ts"],"sourcesContent":["export * from './checkPermission';\n"],"mappings":";;;;;AAAA,IAAAA,gBAAA,GAAAC,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAH,gBAAA,EAAAI,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAL,gBAAA,CAAAK,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAT,gBAAA,CAAAK,GAAA;IAAA;EAAA;AAAA","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["_error","require","Object","keys","forEach","key","exports","defineProperty","enumerable","get","_healthCheck","_validate","_fourOhFour","_authJwt","_authHmac","_authStatic","_swaggerDocs","_authTls","_userResolver","_fileUploader","_metrics","_requestMetrics","_requestLogger","_version","_geminiFileUploader","_checkPermission","_multiPartFileUploader","_verificationToken"],"sources":["../../src/middleware/index.ts"],"sourcesContent":["export * from './error';\nexport * from './healthCheck';\nexport * from './validate';\nexport * from './fourOhFour';\nexport * from './authJwt';\nexport * from './authHmac';\nexport * from './authStatic';\nexport * from './swaggerDocs';\nexport * from './authTls';\nexport * from './userResolver';\nexport * from './fileUploader';\nexport * from './metrics';\nexport * from './requestMetrics';\nexport * from './requestLogger';\nexport * from './version';\nexport * from './geminiFileUploader';\nexport * from './checkPermission';\nexport * from './multiPartFileUploader';\nexport * from './verificationToken'
|
|
1
|
+
{"version":3,"file":"index.js","names":["_error","require","Object","keys","forEach","key","exports","defineProperty","enumerable","get","_healthCheck","_validate","_fourOhFour","_authJwt","_authHmac","_authStatic","_swaggerDocs","_authTls","_userResolver","_fileUploader","_metrics","_requestMetrics","_requestLogger","_version","_geminiFileUploader","_checkPermission","_multiPartFileUploader","_verificationToken"],"sources":["../../src/middleware/index.ts"],"sourcesContent":["export * from './error';\nexport * from './healthCheck';\nexport * from './validate';\nexport * from './fourOhFour';\nexport * from './authJwt';\nexport * from './authHmac';\nexport * from './authStatic';\nexport * from './swaggerDocs';\nexport * from './authTls';\nexport * from './userResolver';\nexport * from './fileUploader';\nexport * from './metrics';\nexport * from './requestMetrics';\nexport * from './requestLogger';\nexport * from './version';\nexport * from './geminiFileUploader';\nexport * from './checkPermission';\nexport * from './multiPartFileUploader';\nexport * from './verificationToken';\n"],"mappings":"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","ignoreList":[]}
|