@interopio/gateway-server 0.20.0 → 0.21.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/changelog.md +15 -0
- package/dist/index.cjs +3 -3
- package/dist/index.cjs.map +4 -4
- package/dist/index.js +3 -3
- package/dist/index.js.map +4 -4
- package/dist/web/test.js +2 -2
- package/dist/web/test.js.map +3 -3
- package/gateway-server +285 -155
- package/gateway-server.d.ts +10 -0
- package/package.json +1 -1
- package/readme.md +5 -0
- package/types/web/test.d.ts +5 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/index.ts", "../src/server.ts", "../src/server/address.ts", "../src/logger.ts", "../src/gateway/ws/core.ts", "../src/gateway/gateway-manager.ts", "../src/common/compose.ts", "../src/http/exchange.ts", "../src/http/status.ts", "../src/server/exchange.ts", "../src/server/monitoring.ts", "../src/server/server-header.ts", "../src/server/ws-client-verify.ts", "../src/server/util/matchers.ts", "../src/app/route.ts", "../src/server/cors.ts", "../src/app/cors.ts", "../src/server/security/types.ts", "../src/server/security/http-headers.ts", "../src/server/security/entry-point-failure-handler.ts", "../src/server/security/http-basic-entry-point.ts", "../src/server/security/http-basic-converter.ts", "../src/server/security/security-context.ts", "../src/server/security/authentication-filter.ts", "../src/server/security/http-status-entry-point.ts", "../src/server/security/delegating-entry-point.ts", "../src/server/security/delegating-success-handler.ts", "../src/server/security/http-basic.ts", "../src/server/security/oauth2/token-error.ts", "../src/server/security/oauth2/token-converter.ts", "../src/server/security/oauth2/token-entry-point.ts", "../src/server/security/oauth2/jwt-auth-manager.ts", "../src/server/security/oauth2-resource-server.ts", "../src/server/security/config.ts", "../src/server/security/error-filter.ts", "../src/server/security/delegating-authorization-manager.ts", "../src/server/security/authorization-filter.ts", "../src/server/security/exchange-filter.ts", "../src/server/security/x509-converter.ts", "../src/server/security/preauth/x509.ts", "../src/server/security/crypto/password.ts", "../src/server/security/crypto/argon2.ts", "../src/server/security/crypto/index.ts", "../src/server/security/users/types.ts", "../src/server/security/users.ts", "../src/server/security/x509.ts", "../src/server/security/users/memory.ts", "../src/app/auth.ts", "../src/server/handler.ts", "../src/server/ws.ts", "../src/server/socket.ts", "../src/server/ws-pings.ts", "../src/server/ssl/config.ts"],
|
|
4
|
-
"sourcesContent": ["import * as GatewayServer from './server.ts';\n\nexport { GatewayServer };\nexport default GatewayServer.Factory;\n", "import http from 'node:http';\nimport https from 'node:https';\nimport type { AddressInfo, Socket } from 'node:net';\nimport { AsyncLocalStorage } from 'node:async_hooks';\nimport wsGateway from './gateway/ws/core.ts';\nimport { GatewayManager } from './gateway/gateway-manager.ts';\nimport { compose } from './common/compose.ts';\nimport {\n ExtendedHttpIncomingMessage,\n ExtendedHttpServerResponse,\n HttpServerRequest,\n HttpServerResponse\n} from './server/exchange.ts';\nimport getLogger from './logger.ts';\nimport { addressAndPort, localIp, portRange } from './server/address.ts';\nimport * as monitoring from './server/monitoring.ts';\nimport { GatewayServer } from '@interopio/gateway-server';\nimport serverHeader from './server/server-header.ts';\nimport { configure, type RouteConfig } from './app/route.ts';\nimport { httpSecurity } from './app/auth.ts';\nimport type { ServerConfigurer, ServerHttpResponse, ServerWebExchange } from '../types/web/server';\nimport { HttpHeadResponseDecorator, WebHttpHandlerBuilder } from './server/handler.ts';\nimport { initRoute } from './server/ws.ts';\nimport { type SocketRoute, webSockets } from './server/socket.ts';\nimport { HttpStatus } from './http/status.ts';\nimport { secureContextOptions } from './server/ssl/config.ts';\n\nconst logger = getLogger('app');\n\n\ntype RequestListener<\n Request extends typeof ExtendedHttpIncomingMessage = typeof ExtendedHttpIncomingMessage,\n Response extends typeof ExtendedHttpServerResponse<InstanceType<Request>> = typeof ExtendedHttpServerResponse,\n> = (req: InstanceType<Request>, resOrUpgradeHead: (InstanceType<Response> & { req: InstanceType<Request> }) | Buffer<ArrayBufferLike>) => void;\n\ntype ServerOptions = http.ServerOptions<typeof ExtendedHttpIncomingMessage, typeof ExtendedHttpServerResponse>;\n\nasync function createListener(builder: WebHttpHandlerBuilder,\n onSocketError: (err: Error) => void): Promise<RequestListener> {\n\n const httpHandler = builder.build();\n return async (req: ExtendedHttpIncomingMessage, resOrUpgradeHead: ExtendedHttpServerResponse | Buffer<ArrayBufferLike>) => {\n req.socket.addListener('error', onSocketError);\n let res: ExtendedHttpServerResponse;\n if (resOrUpgradeHead instanceof ExtendedHttpServerResponse) {\n res = resOrUpgradeHead;\n }\n else {\n req.upgradeHead = resOrUpgradeHead;\n res = new ExtendedHttpServerResponse(req);\n res.assignSocket(req.socket);\n }\n const request = new HttpServerRequest(req);\n const response = new HttpServerResponse(res);\n const decoratedResponse: ServerHttpResponse = request.method === 'HEAD' ? new HttpHeadResponseDecorator(response) : response;\n\n await httpHandler(request, decoratedResponse)\n\n };\n}\n\nfunction promisify<T>(fn: (callback?: (err?: Error) => void) => T): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n const r = fn((err?: Error) => {\n if (err) {\n reject(err);\n } else {\n resolve(r);\n }\n });\n });\n}\n\nfunction memoryMonitor(config?: GatewayServer.ServerConfig['memory']) {\n if (config) {\n return monitoring.start({\n memoryLimit: config.memory_limit,\n dumpLocation: config.dump_location,\n dumpPrefix: config.dump_prefix,\n reportInterval: config.report_interval,\n maxBackups: config.max_backups\n });\n }\n}\n\nimport info from '@interopio/gateway-server/package.json' with { type: 'json' };\nexport const VERSION = `${info.name} - v${info.version}`;\n\nasync function initBuilder(context: RouteConfig) {\n const storage = context.storage;\n const security = await httpSecurity(context);\n // websocket upgrade handler\n const sockets = webSockets(context);\n const handler = compose<ServerWebExchange>(\n serverHeader(VERSION, context.serverHeader),\n ...security,\n ...sockets,\n ...context.middleware,\n // health check\n async ({request, response}, next) => {\n if (request.method === 'GET' && request.path === '/health') {\n response.setStatusCode(HttpStatus.OK);\n const buffer = Buffer.from('UP', 'utf-8');\n response.headers.set('Content-Type', 'text/plain; charset=utf-8');\n await response.body(buffer);\n } else {\n await next();\n }\n },\n // home page\n async ({request, response}, next) => {\n if (request.method === 'GET' && request.path === '/') {\n response.setStatusCode(HttpStatus.OK);\n const buffer = Buffer.from('io.Gateway Server', 'utf-8');\n response.headers.set('Content-Type', 'text/plain; charset=utf-8');\n await response.body(buffer);\n } else {\n await next();\n }\n },\n // not found\n async ({response}, _next) => {\n response.setStatusCode(HttpStatus.NOT_FOUND);\n await response.end();\n }\n );\n\n return new WebHttpHandlerBuilder(handler).storage(storage);\n}\n\nexport const Factory = async (options: GatewayServer.ServerConfig): Promise<GatewayServer.Server> => {\n const ssl = options.ssl;\n const host = options.host;\n\n // Build serverCertificate config if auth.x509.key is provided\n const serverCertificate = options.auth?.x509?.key ? {\n host: host ?? 'localhost',\n key: options.auth.x509.key,\n passphrase: options.auth.x509.passphrase\n } : undefined;\n\n const createServer = ssl\n ? (options: ServerOptions, handler: RequestListener) => https.createServer({...options, ...secureContextOptions(ssl, serverCertificate)}, handler)\n : (options: ServerOptions, handler: RequestListener) => http.createServer(options, handler);\n const monitor = memoryMonitor(options.memory);\n const context: RouteConfig = {\n middleware: [],\n corsConfig: options.cors,\n cors: [],\n authConfig: options.auth,\n authorize: [],\n storage: new AsyncLocalStorage<{ exchange: ServerWebExchange }>(),\n sockets: new Map<string, SocketRoute>()\n };\n\n // Create gateway manager to handle default and per-principal gateway instances\n const gatewayManager = new GatewayManager({\n baseConfig: {...options.gateway},\n scope: options.gateway?.scope ?? 'principal'\n });\n\n if (options.gateway) {\n const config = options.gateway;\n\n await configure(async (configurer: ServerConfigurer) => {\n configurer.socket({path: config.route, factory: wsGateway.bind(gatewayManager), options: config})\n }, options, context);\n\n }\n if (options.app) {\n await configure(options.app, options, context)\n }\n\n const ports = portRange(options.port ?? 0);\n const onSocketError = (err: Error) => logger.error(`socket error: ${err}`, err);\n const builder = await initBuilder(context);\n\n const listener = await createListener(builder, onSocketError);\n\n const serverP = new Promise<http.Server<typeof ExtendedHttpIncomingMessage, typeof ExtendedHttpServerResponse>>((resolve, reject) => {\n\n const server = createServer({\n IncomingMessage: ExtendedHttpIncomingMessage,\n ServerResponse: ExtendedHttpServerResponse,\n ...options.http\n }, listener);\n\n server.on('error', (e: Error) => {\n if (e['code'] === 'EADDRINUSE') {\n logger.debug(`port ${e['port']} already in use on address ${e['address']}`);\n const {value: port} = ports.next();\n if (port) {\n logger.info(`retry starting server on port ${port} and host ${host ?? '<unspecified>'}`);\n server.close();\n server.listen(port, host);\n } else {\n logger.warn(`all configured port(s) ${options.port} are in use. closing...`);\n server.close();\n reject(e);\n }\n } else {\n logger.error(`server error: ${e.message}`, e);\n reject(e);\n }\n });\n server\n .on('listening', async () => {\n const info = server.address() as AddressInfo;\n\n for (const [path, route] of context.sockets) {\n const endpoint = `${ssl ? 'wss' : 'ws'}://${localIp}:${info.port}${path}`;\n await initRoute(path, route, endpoint, context.storage, onSocketError);\n }\n logger.info(`http server listening on ${ ssl ? 'https' : 'http' }://${addressAndPort(info)}`);\n resolve(server);\n });\n server\n .on('upgrade', (req: ExtendedHttpIncomingMessage, _socket: Socket, head: Buffer<ArrayBufferLike>) => {\n try {\n listener(req, head);\n } catch (err) {\n logger.error(`upgrade error: ${err}`, err);\n }\n })\n .on('close', async () => {\n logger.info(`http server closed.`);\n });\n try {\n const {value: port} = ports.next();\n server.listen(port, host);\n } catch (e) {\n logger.error(`error starting web socket server`, e);\n reject(e instanceof Error ? e : new Error(`listen failed: ${e}`));\n }\n });\n const server = await serverP;\n return new class implements GatewayServer.Server {\n // Expose the gateway manager which implements ScopedGateway\n readonly gateway = gatewayManager;\n\n get address(): AddressInfo | null {\n const address = server.address();\n return typeof address === 'object' ? address : null;\n }\n\n async close(): Promise<void> {\n for (const [path, route] of context.sockets) {\n try {\n if (route.close !== undefined) {\n await route.close();\n }\n } catch (e) {\n logger.warn(`error closing route ${path}`, e);\n }\n }\n await promisify(cb => {\n server.closeAllConnections();\n server.close(cb);\n });\n if (monitor) {\n await monitoring.stop(monitor);\n }\n // Stop all gateways (default + per-principal)\n await gatewayManager.stop();\n }\n }\n}\n", "import type { AddressInfo } from 'node:net';\nimport { type NetworkInterfaceInfo, networkInterfaces } from 'node:os';\n\nconst PORT_RANGE_MATCHER = /^(\\d+|(0x[\\da-f]+))(-(\\d+|(0x[\\da-f]+)))?$/i;\nfunction validPort(port: number) {\n if (port > 0xFFFF) throw new Error(`bad port ${port}`);\n return port;\n}\n\n/**\n * parse port range. port can be number or string representing comma separated\n * list of port ranges for e.g. \"3434,8380-8385\"\n * @param port\n */\nexport function* portRange(port: number | string): Generator<number> {\n if (typeof port === 'string') {\n for (const portRange of port.split(',')) {\n const trimmed = portRange.trim();\n const matchResult = PORT_RANGE_MATCHER.exec(trimmed);\n if (matchResult) {\n const start = parseInt(matchResult[1]);\n const end = parseInt(matchResult[4] ?? matchResult[1]);\n for (let i = validPort(start); i < validPort(end) + 1; i++) {\n yield i;\n }\n }\n else {\n throw new Error(`'${portRange}' is not a valid port or range.`);\n }\n }\n } else {\n yield validPort(port);\n }\n}\n\nexport const localIp = (() => {\n function first<T>(a: T[]): T | undefined {\n return a.length > 0 ? a[0] : undefined;\n }\n const addresses = Object.values(networkInterfaces())\n .flatMap((details?: NetworkInterfaceInfo[]) => {\n return (details ?? []).filter((info) => info.family === 'IPv4');\n }).reduce((acc, info) => {\n acc[info.internal ? 'internal' : 'external'].push(info);\n return acc;\n }, {internal: [] as NetworkInterfaceInfo[], external: [] as NetworkInterfaceInfo[]});\n return (first(addresses.internal) ?? first(addresses.external))?.address;\n})();\n\nexport function addressAndPort(address?: AddressInfo) {\n if (address) {\n if (address.family === 'IPv6') {\n return `[${address.address}]:${address.port}`;\n }\n return `${address.address}:${address.port}`;\n }\n}\n", "import * as GatewayLogging from '@interopio/gateway/logging/core';\n\nexport type Logger = GatewayLogging.Logger;\n\nexport default function getLogger(name: string): Logger {\n return GatewayLogging.getLogger(`gateway.server.${name}`);\n}\n\n// This function is used to ensure that RegExp objects are displayed correctly when logging.\nexport function regexAwareReplacer<T>(_key: string, value: T): string | T {\n return value instanceof RegExp ? value.toString() : value;\n}\n", "import { addressAndPort } from '../../server/address.ts';\nimport type { WebSocket } from 'ws';\nimport getLogger from '../../logger.ts';\nimport type { Authentication } from '../../server/security/types.ts';\nimport { IOGateway } from '@interopio/gateway';\nimport { GatewayManager } from '../gateway-manager.ts';\n\nimport type {ServerWebSocketHandler} from '../../../types/web/server';\nimport type {AddressInfo} from 'node:net';\nimport {AsyncLocalStorage} from 'node:async_hooks';\n\nconst log = getLogger('ws');\nconst codec = IOGateway.Encoding.json<IOGateway.Message>();\n\nfunction principalName(authentication: Authentication): string | undefined {\n let name: string | undefined;\n if (authentication.authenticated) {\n name = authentication.name;\n if (name === undefined) {\n if (authentication['principal'] !== undefined) {\n const principal = authentication['principal'];\n if (typeof principal === 'object' && principal !== null && ('username' in principal || 'name' in principal)) {\n name = (principal as { username?: string }).username ?? (principal as { name?: string }).name;\n }\n if (name === undefined) {\n if (principal === undefined || principal === null) {\n name = '';\n }\n else {\n name = String(principal);\n }\n }\n }\n }\n }\n return name;\n}\n\nfunction initClient(gateway: IOGateway.Gateway,\n socket: WebSocket,\n authenticationPromise: () => Promise<Authentication | undefined>,\n remoteAddress?: AddressInfo\n): IOGateway.GatewayClient<string> | undefined {\n const key = addressAndPort(remoteAddress);\n const host = remoteAddress?.address ?? '<unknown>';\n const opts = {\n key,\n host,\n codec,\n onAuthenticate: async (): Promise<IOGateway.Auth.AuthenticationSuccess> => {\n const authentication = (await authenticationPromise());\n if (authentication?.authenticated) {\n return {type: 'success', user: principalName(authentication)};\n }\n throw new Error(`no valid client authentication ${key}`);\n },\n onPing: () => {\n socket.ping((err?: Error) => {\n if (err) {\n log.warn(`failed to ping ${key}`, err);\n }\n else {\n log.info(`ping sent to ${key}`);\n }\n });\n },\n onDisconnect: (reason: 'inactive' | 'shutdown') => {\n switch (reason) {\n case 'inactive': {\n log.warn(`no heartbeat (ping) received from ${key}, closing socket`);\n socket.close(4001, 'ping expected');\n break;\n }\n case 'shutdown': {\n socket.close(1001, 'shutdown');\n break;\n }\n }\n }\n };\n try {\n return gateway.client((data) => socket.send(data), opts as IOGateway.GatewayClientOptions<string>);\n } catch (err) {\n log.warn(`${key} failed to create client`, err);\n }\n}\n\nasync function create(this: GatewayManager, environment: {\n endpoint: string,\n storage?: AsyncLocalStorage<{ }>\n}): Promise<ServerWebSocketHandler> {\n log.info(`starting gateway on ${environment.endpoint}`);\n await this.start(environment);\n\n\n return async ({socket, handshake}) => {\n const {logPrefix, remoteAddress, principal: principalPromise} = handshake;\n const user = (await principalPromise())?.name;\n log.info(`${logPrefix}connected on gw as ${user ?? '<anonymous>'}`);\n \n const gw = await this.getGateway(user);\n const client = initClient(gw, socket, principalPromise, remoteAddress);\n if (!client) {\n log.error(`${logPrefix}gw client init failed`);\n socket.terminate();\n return;\n }\n socket.on('error', (err: Error) => {\n log.error(`${logPrefix}websocket error: ${err}`, err);\n });\n\n const contextFn = environment.storage !== undefined ? AsyncLocalStorage.snapshot() : undefined;\n socket.on('message', (data, _isBinary) => {\n if (Array.isArray(data)) {\n data = Buffer.concat(data);\n }\n // JSON.parse will invoke abstract operation ToString (coerce it) prior parsing (https://262.ecma-international.org/5.1/#sec-15.12.2)\n if (contextFn !== undefined) {\n contextFn(() => client.send(data as unknown as string))\n }\n else {\n client.send(data as unknown as string);\n }\n\n });\n socket.on('close', (code) => {\n log.info(`${logPrefix}disconnected from gw. code: ${code}`);\n client.close();\n });\n }\n}\n\nexport default create;\n", "import { IOGateway } from '@interopio/gateway';\nimport getLogger from '../logger.ts';\nimport type { GatewayServer } from '../../gateway-server.ts';\n\nconst log = getLogger('gateway-manager');\n\nfunction generateRandomGatewayId(): string {\n return globalThis.crypto.randomUUID().replaceAll('-', '');\n}\n\nexport interface GatewayManagerConfig {\n /**\n * Base gateway configuration to use for all gateway instances.\n */\n baseConfig: IOGateway.GatewayConfig;\n\n /**\n * Gateway scope - determines how gateway instances are managed:\n * - 'principal': Each authenticated principal gets their own gateway instance.\n * A default (shared) gateway instance handles all unauthenticated connections.\n * - 'singleton': All connections share the same gateway instance\n *\n * Default: 'principal'\n */\n scope?: 'singleton' | 'principal';\n}\n\n/**\n * Manages multiple Gateway instances - one default and optionally one per authenticated principal.\n * Each gateway instance gets a unique node ID to ensure proper isolation.\n */\nexport class GatewayManager implements GatewayServer.ScopedGateway {\n readonly #defaultGatewayId: string;\n readonly #defaultGateway: IOGateway.Gateway;\n readonly #managedGateways = new Map<string, IOGateway.Gateway>();\n readonly #principalToGatewayId = new Map<string, string>();\n readonly #config: GatewayManagerConfig;\n #started = false;\n #environment?: { endpoint?: string };\n\n constructor(config: GatewayManagerConfig) {\n this.#config = {\n baseConfig: config.baseConfig,\n scope: config.scope ?? 'principal'\n }\n\n // Use configured gateway ID or generate a random one for the default gateway\n this.#defaultGatewayId = config.baseConfig.node ?? generateRandomGatewayId();\n\n if (log.enabledFor('debug')) {\n log.debug(`creating default gateway with gateway id: ${this.#defaultGatewayId}`);\n }\n\n this.#defaultGateway = IOGateway.Factory({...config.baseConfig, node: this.#defaultGatewayId});\n }\n\n /**\n * Starts the default gateway.\n */\n async start(environment?: { endpoint?: string }): Promise<this> {\n if (this.#started) {\n return this;\n }\n\n // Store environment for use with per-principal gateways\n this.#environment = environment;\n\n log.debug('starting default gateway');\n await this.#defaultGateway.start(environment);\n this.#started = true;\n return this;\n }\n\n /**\n * Gets a gateway instance for the given principal.\n * If scope is 'singleton' or no principal is provided, returns the default gateway.\n * Otherwise, creates a new gateway instance for the principal if it doesn't exist.\n */\n async getGateway(principal?: string): Promise<IOGateway.Gateway> {\n // If scope is singleton or no principal, use default\n if (this.#config.scope === 'singleton' || !principal) {\n return this.#defaultGateway;\n }\n\n // Check if we already have a gateway for this principal\n const gatewayId = this.#principalToGatewayId.get(principal);\n let gateway = gatewayId ? this.#managedGateways.get(gatewayId) : undefined;\n\n if (!gateway) {\n if (log.enabledFor('debug')) {\n log.debug(`no existing gateway for principal '${principal}', creating new one`);\n }\n gateway = await this.createPrincipalGateway(principal);\n } else {\n if (log.enabledFor('debug')) {\n log.debug(`reusing existing gateway for principal '${principal}'`);\n }\n }\n\n return gateway;\n }\n\n /**\n * Creates a new gateway instance for a specific principal with a unique gateway ID.\n */\n private async createPrincipalGateway(principal: string): Promise<IOGateway.Gateway> {\n const gatewayId = generateRandomGatewayId();\n const config = {\n ...this.#config.baseConfig,\n node: gatewayId\n };\n\n if (log.enabledFor('debug')) {\n log.debug(`creating gateway for principal '${principal}' with gateway id: ${config.node}`);\n }\n const gateway = IOGateway.Factory(config);\n\n // Track the principal-to-gateway ID mapping\n this.#principalToGatewayId.set(principal, gatewayId);\n this.#managedGateways.set(gatewayId, gateway);\n\n // Start the gateway with the same environment as the default gateway\n await gateway.start(this.#environment);\n\n return gateway;\n }\n\n // ScopedGateway interface methods\n\n /**\n * Get all gateway instances including the default.\n */\n getGateways(): Map<string, IOGateway.Gateway> {\n const allGateways = new Map<string, IOGateway.Gateway>(this.#managedGateways);\n allGateways.set(this.#defaultGatewayId, this.#defaultGateway);\n return allGateways;\n }\n\n /**\n * Gets information about specific or all active gateways.\n * - If no gatewayId is provided: returns aggregated info for all gateways (default + managed).\n * - If default gateway ID is provided: returns info only for the default gateway.\n * - If a non-default gateway ID is provided: returns info only for that specific gateway. If not found, throws an error.\n */\n info(gatewayId?: string): Record<string, unknown> {\n // Case 1: Specific non-default gateway ID provided\n if (gatewayId && this.#defaultGatewayId !== gatewayId) {\n const gateway = this.#managedGateways.get(gatewayId);\n if (gateway) {\n return gateway.info();\n } else {\n throw new Error(`no gateway found with ID: ${gatewayId}`);\n }\n }\n\n // Case 2: Default gateway ID explicitly provided - return only default info\n if (gatewayId === this.#defaultGatewayId) {\n return this.#defaultGateway.info();\n }\n\n // Case 3: No gateway ID provided - return aggregated info\n return {\n ...this.#defaultGateway.info(),\n managedGateways: this.#managedGateways.size,\n scope: this.#config.scope\n };\n }\n\n /**\n * Stops specific or all gateway instances.\n * - If no gatewayId is provided: stops all gateways (default + managed), returning the stopped default.\n * - If default gateway ID is provided: stops only the default gateway, leaving managed gateways running.\n * - If a non-default gateway ID is provided: stops only that specific gateway. If not found, throws an error.\n * @param gatewayId - ID of the gateway to stop.\n * @returns stopped gateway instance.\n */\n async stop(gatewayId?: string): Promise<IOGateway.Gateway> {\n // Case 1: Specific non-default gateway ID provided\n if (gatewayId && this.#defaultGatewayId !== gatewayId) {\n const gateway = this.#managedGateways.get(gatewayId);\n if (gateway) {\n log.info(`stopping gateway with ID: ${gatewayId}`);\n await gateway.stop();\n this.#managedGateways.delete(gatewayId);\n\n // Remove principal mapping for this gateway\n for (const [principal, gId] of this.#principalToGatewayId.entries()) {\n if (gId === gatewayId) {\n this.#principalToGatewayId.delete(principal);\n break;\n }\n }\n\n return gateway;\n } else {\n throw new Error(`no gateway found with ID: ${gatewayId}`);\n }\n }\n\n // Case 2: Default gateway ID explicitly provided - stop only default\n if (gatewayId === this.#defaultGatewayId) {\n log.debug('stopping default gateway (managed gateways will continue running)');\n await this.#defaultGateway.stop();\n this.#started = false;\n return this.#defaultGateway;\n }\n\n // Case 3: No gateway ID provided - stop all gateways\n log.info(`stopping all gateways (1 default + ${this.#managedGateways.size} managed)`);\n\n // Stop all managed gateways\n for (const [id, gateway] of this.#managedGateways.entries()) {\n if (log.enabledFor('debug')) {\n log.debug(`stopping gateway with ID: ${id}`);\n }\n await gateway.stop();\n }\n this.#managedGateways.clear();\n this.#principalToGatewayId.clear();\n\n log.debug('stopping default gateway');\n await this.#defaultGateway.stop();\n this.#started = false;\n return this.#defaultGateway;\n }\n\n\n /**\n * Get the gateway ID for a specific principal.\n */\n getPrincipalGatewayId(principal: string): string | undefined {\n return this.#principalToGatewayId.get(principal);\n }\n\n /**\n * Get all principal-to-gateway ID mappings.\n */\n getPrincipalGatewayIds(): Map<string, string> {\n return new Map(this.#principalToGatewayId);\n }\n\n\n // Gateway interface delegation to defaultGateway\n\n /**\n * Get the default gateway instance.\n */\n getDefaultGateway(): IOGateway.Gateway {\n return this.#defaultGateway;\n }\n\n /**\n * Create a gateway client with the specified handler.\n * Delegates to the default gateway.\n */\n client<T = IOGateway.Message>(\n handler: (this: IOGateway.GatewayClient<T>, msg: T) => void,\n opts?: IOGateway.GatewayClientOptions<T>\n ): IOGateway.GatewayClient<T> {\n return this.#defaultGateway.client(handler, opts);\n }\n\n /**\n * Connect to the gateway with the specified handler.\n * Delegates to the default gateway.\n */\n async connect(\n handler: (client: IOGateway.GatewayClient, msg: IOGateway.Message) => void\n ): Promise<IOGateway.GatewayClient> {\n return this.#defaultGateway.connect(handler);\n }\n\n /**\n * Gets the number of active principal gateways.\n */\n getPrincipalCount(): number {\n return this.#managedGateways.size;\n }\n}\n", "type MiddlewareFunction<T> = ((ctx: T, next: (ctx?: T) => Promise<void>) => Promise<void>) | ((ctx: T) => Promise<void>);\n\n// https://github.com/koajs/compose/blob/master/index.js\n/**\n * @typeParam T - Type of context passed through the middleware\n * @param middleware middleware stack\n * @return {MiddlewareFunction}\n */\nexport function compose<T>(...middleware: MiddlewareFunction<T>[]): (ctx: T) => Promise<void> {\n if (!Array.isArray(middleware)) {\n throw new Error('middleware must be array!');\n }\n const fns = middleware.flat();\n for (const fn of fns) {\n if (typeof fn !== 'function') {\n throw new Error('middleware must be compose of functions!');\n }\n }\n return async function (ctx: T, next?: (ctx?: T) => Promise<void>) {\n const dispatch = async (i: number, dispatchedCtx: T): Promise<void> => {\n const fn = i === fns.length ? next : fns[i];\n if (fn === undefined) {\n return;\n }\n let nextCalled = false;\n let nextResolved = false;\n const nextFn = async (nextCtx?: T) => {\n if (nextCalled) {\n throw new Error('next() called multiple times');\n }\n nextCalled = true;\n try {\n return await dispatch(i + 1, nextCtx ?? dispatchedCtx);\n }\n finally {\n nextResolved = true;\n }\n };\n const result = await fn(dispatchedCtx, nextFn);\n if (nextCalled && !nextResolved) {\n throw new Error('middleware resolved before downstream.\\n\\t You are probably missing an await or return statement in your middleware function.');\n }\n return result;\n }\n\n return dispatch(0, ctx);\n }\n}\n", "import type {\n HeaderValues,\n HttpCookie,\n HttpHeaders,\n MutableHttpHeaders,\n ReadonlyHeaderValues,\n ResponseCookie\n} from '../../types/web/http';\nimport { type AddressInfo, isIP } from 'node:net';\nimport { Cookie } from 'tough-cookie';\n\nfunction parseHost(headers: HttpHeaders, defaultHost?: string): string | undefined {\n let host = headers.get('x-forwarded-host');\n if (Array.isArray(host)) {\n host = host[0];\n }\n if (host) {\n const port = headers.one('x-forwarded-port');\n if (port) {\n host = `${host}:${port}`;\n }\n }\n host ??= headers.one('host');\n if (Array.isArray(host)) {\n host = host[0];\n }\n if (host) {\n return (host as string).split(',', 1)[0].trim();\n }\n\n return defaultHost;\n}\n\nfunction isForwardedSsl(headers: HttpHeaders): boolean {\n const v = headers.one('x-forwarded-ssl');\n return (typeof v === 'string') && (v.toLowerCase() === 'on');\n}\n\nfunction parseProtocol(headers: HttpHeaders, defaultProtocol: string): string {\n let proto = headers.get('x-forwarded-proto');\n\n if (Array.isArray(proto)) {\n proto = proto[0];\n }\n if (proto !== undefined) {\n return (proto as string).split(',', 1)[0].trim();\n }\n else if (isForwardedSsl(headers)) {\n return 'https';\n }\n return defaultProtocol;\n}\n\nfunction parseRemoteAddress(url: URL, headers: HttpHeaders, remoteAddress?: AddressInfo) : AddressInfo | undefined {\n const port = remoteAddress ? remoteAddress.port : 'https:' === url.protocol ? 443 : 80;\n\n let host = headers.one('x-forwarded-for');\n if (Array.isArray(host)) {\n host = host[0];\n }\n if (host !== undefined) {\n host = (host as string).split(',', 1)[0].trim();\n return { address: host, port: Number(port), family: isIP(host) === 6 ? 'IPv6' : 'IPv4' };\n }\n}\n\nexport abstract class AbstractHttpMessage<Headers extends HttpHeaders = HttpHeaders> {\n readonly #headers: Headers;\n protected constructor(headers: Headers) {\n this.#headers = headers;\n }\n get headers(): Headers {\n return this.#headers;\n }\n}\n\nexport abstract class AbstractHttpRequest<Headers extends HttpHeaders = HttpHeaders> extends AbstractHttpMessage<Headers> {\n private static logIdCounter = 0;\n #id?: string\n\n get id(): string {\n if (this.#id === undefined) {\n this.#id = `${this.initId()}-${++AbstractHttpRequest.logIdCounter}`;\n\n }\n return this.#id;\n }\n\n protected initId(): string {\n return 'request';\n }\n\n get cookies(): HttpCookie[] {\n return parseCookies(this.headers);\n }\n\n protected parseHost(defaultHost?: string): string | undefined {\n return parseHost(this.headers, defaultHost);\n }\n\n protected parseProtocol(defaultProtocol: string): string {\n return parseProtocol(this.headers, defaultProtocol);\n }\n\n abstract get URL(): URL;\n\n protected parseRemoteAddress(remoteAddress?: AddressInfo) {\n return parseRemoteAddress(this.URL, this.headers, remoteAddress);\n }\n}\n\nexport abstract class AbstractHttpResponse<Headers extends HttpHeaders = HttpHeaders> extends AbstractHttpMessage<Headers> {\n get cookies(): ResponseCookie[] {\n return parseResponseCookies(this.headers);\n }\n\n protected setCookieValue(responseCookie: ResponseCookie): string {\n const cookie = new Cookie({\n key: responseCookie.name,\n value: responseCookie.value,\n maxAge: responseCookie.maxAge,\n domain: responseCookie.domain,\n path: responseCookie.path,\n secure: responseCookie.secure,\n httpOnly: responseCookie.httpOnly,\n sameSite: responseCookie.sameSite\n });\n return cookie.toString();\n }\n\n}\n\nfunction parseHeader(value: string): string[] {\n const list: string[] = [];\n {\n let start = 0;\n let end = 0;\n\n for (let i = 0; i < value.length; i++) {\n switch (value.charCodeAt(i)) {\n case 0x20: // space\n if (start === end) {\n start = end = i + 1;\n }\n break;\n case 0x2c: // comma\n list.push(value.slice(start, end));\n start = end = i + 1;\n break;\n default:\n end = end + 1;\n break;\n }\n }\n list.push(value.slice(start, end));\n }\n\n return list;\n}\n\nfunction toList(values: number | string | (readonly string[]) | undefined): string[] {\n if (typeof values === 'string') {\n values = [values];\n }\n if (typeof values === 'number') {\n values = [String(values)];\n }\n const list: string[] = [];\n if (values) {\n for (const value of values) {\n if (value) {\n list.push(...parseHeader(value));\n }\n }\n }\n return list;\n}\n\nfunction parseCookies(headers: HttpHeaders): HttpCookie[] {\n return headers.list('cookie')\n .map(s => s.split(';').map((cs) => Cookie.parse(cs)))\n .flat(1)\n .filter((tc) => tc !== undefined)\n .map((tc) => {\n const result: HttpCookie = Object.freeze({name: tc.key, value: tc.value});\n return result;\n });\n}\n\ntype Mutable<T> = {-readonly [K in keyof T]: T[K]};\n\nfunction parseResponseCookies(headers: HttpHeaders): ResponseCookie[] {\n return headers.list('set-cookie').map((cookie) => {\n const parsed = Cookie.parse(cookie);\n if (parsed) {\n const result: Mutable<ResponseCookie> = {name: parsed.key, value: parsed.value, maxAge: Number(parsed.maxAge ?? -1)};\n if (parsed.httpOnly) result.httpOnly = true;\n if (parsed.domain) result.domain = parsed.domain;\n if (parsed.path) result.path = parsed.path;\n if (parsed.secure) result.secure = true;\n if (parsed.httpOnly) result.httpOnly = true;\n if (parsed.sameSite) result.sameSite = parsed.sameSite as 'strict' | 'lax' | 'none';\n return Object.freeze(result);\n }\n }).filter((cookie): cookie is ResponseCookie => cookie !== undefined);\n}\n\n\nexport abstract class AbstractHttpHeaders<Values extends HeaderValues | ReadonlyHeaderValues> {\n protected constructor() {}\n abstract get(name: string): Values\n\n toList(name: string): string[] {\n const values = this.get(name);\n return toList(values);\n }\n}\n\nexport class MapHttpHeaders extends Map<string, (readonly string[])> implements MutableHttpHeaders {\n\n get(name: string) {\n return super.get(name.toLowerCase());\n }\n\n one(name: string): string | undefined {\n return this.get(name)?.[0];\n }\n\n list(name: string) {\n const values = super.get(name.toLowerCase());\n return toList(values);\n }\n\n set(name: string, value: number | string | (readonly string[]) | undefined): this {\n if (typeof value === 'number') {\n value = String(value);\n }\n if (typeof value === 'string') {\n value = [value];\n }\n if (value) {\n return super.set(name.toLowerCase(), value);\n }\n else {\n super.delete(name.toLowerCase());\n return this;\n }\n }\n\n add(name: string, value: string | (readonly string[])) {\n const prev = super.get(name.toLowerCase());\n if (typeof value === 'string') {\n value = [value];\n }\n if (prev) {\n value = prev.concat(value);\n }\n this.set(name, value);\n return this;\n }\n}\n", "import type {HttpStatusCode} from '../../types/web/http';\n\nclass DefaultHttpStatusCode implements HttpStatusCode {\n readonly #value: number;\n constructor(value: number) {\n this.#value = value;\n }\n get value(): number {\n return this.#value;\n }\n\n toString(): string {\n return this.#value.toString();\n }\n}\n\nexport class HttpStatus implements HttpStatusCode {\n static readonly CONTINUE = new HttpStatus(100, 'Continue');\n static readonly SWITCHING_PROTOCOLS = new HttpStatus(101, 'Switching Protocols');\n\n // 2xx Success\n\n static readonly OK = new HttpStatus(200, 'OK');\n static readonly CREATED = new HttpStatus(201, 'Created');\n static readonly ACCEPTED = new HttpStatus(202, 'Accepted');\n static readonly NON_AUTHORITATIVE_INFORMATION = new HttpStatus(203, 'Non-Authoritative Information');\n static readonly NO_CONTENT = new HttpStatus(204, 'No Content');\n static readonly RESET_CONTENT = new HttpStatus(205, 'Reset Content');\n static readonly PARTIAL_CONTENT = new HttpStatus(206, 'Partial Content');\n static readonly MULTI_STATUS = new HttpStatus(207, 'Multi-Status');\n\n static readonly IM_USED = new HttpStatus(226, 'IM Used');\n\n\n // 3xx Redirection\n static readonly MULTIPLE_CHOICES = new HttpStatus(300, 'Multiple Choices');\n static readonly MOVED_PERMANENTLY = new HttpStatus(301, 'Moved Permanently');\n\n // 4xx Client Error\n\n static readonly BAD_REQUEST = new HttpStatus(400, 'Bad Request');\n static readonly UNAUTHORIZED = new HttpStatus(401, 'Unauthorized');\n static readonly FORBIDDEN = new HttpStatus(403, 'Forbidden');\n static readonly NOT_FOUND = new HttpStatus(404, 'Not Found');\n static readonly METHOD_NOT_ALLOWED = new HttpStatus(405, 'Method Not Allowed');\n static readonly NOT_ACCEPTABLE = new HttpStatus(406, 'Not Acceptable');\n static readonly PROXY_AUTHENTICATION_REQUIRED = new HttpStatus(407, 'Proxy Authentication Required');\n static readonly REQUEST_TIMEOUT = new HttpStatus(408, 'Request Timeout');\n static readonly CONFLICT = new HttpStatus(409, 'Conflict');\n static readonly GONE = new HttpStatus(410, 'Gone');\n static readonly LENGTH_REQUIRED = new HttpStatus(411, 'Length Required');\n static readonly PRECONDITION_FAILED = new HttpStatus(412, 'Precondition Failed');\n static readonly PAYLOAD_TOO_LARGE = new HttpStatus(413, 'Payload Too Large');\n static readonly URI_TOO_LONG = new HttpStatus(414, 'URI Too Long');\n static readonly UNSUPPORTED_MEDIA_TYPE = new HttpStatus(415, 'Unsupported Media Type');\n\n static readonly EXPECTATION_FAILED = new HttpStatus(417, 'Expectation Failed');\n static readonly IM_A_TEAPOT = new HttpStatus(418, 'I\\'m a teapot');\n\n static readonly TOO_EARLY = new HttpStatus(425, 'Too Early');\n static readonly UPGRADE_REQUIRED = new HttpStatus(426, 'Upgrade Required');\n static readonly PRECONDITION_REQUIRED = new HttpStatus(428, 'Precondition Required');\n static readonly TOO_MANY_REQUESTS = new HttpStatus(429, 'Too Many Requests');\n static readonly REQUEST_HEADER_FIELDS_TOO_LARGE = new HttpStatus(431, 'Request Header Fields Too Large');\n static readonly UNAVAILABLE_FOR_LEGAL_REASONS = new HttpStatus(451, 'Unavailable For Legal Reasons');\n\n // 5xx Server Error\n static readonly INTERNAL_SERVER_ERROR = new HttpStatus(500, 'Internal Server Error');\n static readonly NOT_IMPLEMENTED = new HttpStatus(501, 'Not Implemented');\n static readonly BAD_GATEWAY = new HttpStatus(502, 'Bad Gateway');\n static readonly SERVICE_UNAVAILABLE = new HttpStatus(503, 'Service Unavailable');\n static readonly GATEWAY_TIMEOUT = new HttpStatus(504, 'Gateway Timeout');\n static readonly HTTP_VERSION_NOT_SUPPORTED = new HttpStatus(505, 'HTTP Version Not Supported');\n static readonly VARIANT_ALSO_NEGOTIATES = new HttpStatus(506, 'Variant Also Negotiates');\n static readonly INSUFFICIENT_STORAGE = new HttpStatus(507, 'Insufficient Storage');\n static readonly LOOP_DETECTED = new HttpStatus(508, 'Loop Detected');\n static readonly NOT_EXTENDED = new HttpStatus(510, 'Not Extended');\n static readonly NETWORK_AUTHENTICATION_REQUIRED = new HttpStatus(511, 'Network Authentication Required');\n\n static readonly #VALUES: HttpStatus[] = [];\n static {\n Object.keys(HttpStatus)\n .filter(key => key !== 'VALUES' && key !== 'resolve')\n .forEach(key => {\n const value = HttpStatus[key];\n if (value instanceof HttpStatus) {\n Object.defineProperty(value, 'name', {enumerable: true, value: key, writable: false});\n HttpStatus.#VALUES.push(value);\n }\n })\n\n }\n\n static resolve(code: number): HttpStatus | undefined {\n for (const status of HttpStatus.#VALUES) {\n if (status.value === code) {\n return status;\n }\n }\n }\n\n readonly #value: number;\n readonly #phrase: string;\n\n private constructor(value: number, phrase: string) {\n this.#value = value;\n this.#phrase = phrase;\n }\n\n get value(): number {\n return this.#value;\n }\n get phrase(): string {\n return this.#phrase;\n }\n\n toString() {\n return `${this.#value} ${this['name']}`;\n }\n}\n\n\nexport function httpStatusCode(value: number | HttpStatusCode): HttpStatusCode {\n if (typeof value === 'number') {\n if (value < 100 || value > 999) {\n throw new Error(`status code ${value} should be in range 100-999`);\n }\n const status = HttpStatus.resolve(value);\n if (status !== undefined) {\n return status;\n }\n return new DefaultHttpStatusCode(value);\n }\n return value;\n}\n", "import type { Principal } from '../../types/auth';\nimport type {\n BodyChunk,\n HeaderValue,\n HeaderValues,\n HttpCookie,\n HttpMethod,\n HttpStatusCode,\n MutableHttpHeaders,\n ReadonlyHeaderValues,\n ReadonlyHttpHeaders,\n ResponseCookie\n} from '../../types/web/http'\n\nimport type {\n ServerHttpRequest,\n ServerHttpResponse,\n ServerWebExchange,\n SslInfo\n} from '../../types/web/server';\nimport { AbstractHttpHeaders, AbstractHttpRequest, AbstractHttpResponse } from '../http/exchange.ts';\nimport { httpStatusCode } from '../http/status.ts';\nimport type { X509Certificate} from 'node:crypto';\nimport http from 'node:http';\nimport http2 from 'node:http2';\nimport net from 'node:net';\nimport type { TLSSocket } from 'node:tls';\n\nexport class ExtendedHttpIncomingMessage extends http.IncomingMessage {\n // circular reference to the exchange\n exchange?: ServerWebExchange;\n\n upgradeHead?: Buffer<ArrayBufferLike>\n\n\n get urlBang(): string {\n return this.url!;\n }\n\n get socketEncrypted(): boolean {\n // see tls.TLSSocket#encrypted\n return this.socket['encrypted'] === true;\n }\n}\n\nexport class ExtendedHttpServerResponse<Request extends ExtendedHttpIncomingMessage = ExtendedHttpIncomingMessage> extends http.ServerResponse<Request> {\n\n markHeadersSent(): void {\n this['_header'] = true; // prevent response from being sent\n }\n\n getRawHeaderNames(): string[] {\n return super['getRawHeaderNames']();\n }\n}\n\nabstract class AbstractServerHttpRequest extends AbstractHttpRequest<ReadonlyHttpHeaders> {\n #sslInfo?: SslInfo\n\n abstract getNativeRequest<T>(): T;\n\n protected abstract initSslInfo(): SslInfo | undefined;\n\n get sslInfo(): SslInfo | undefined {\n if (this.#sslInfo === undefined) {\n this.#sslInfo = this.initSslInfo();\n }\n return this.#sslInfo;\n }\n}\n\nexport abstract class AbstractServerHttpResponse extends AbstractHttpResponse<MutableHttpHeaders> {\n #cookies: ResponseCookie[] = [];\n #statusCode?: HttpStatusCode;\n #state: 'new' | 'committing' | 'commit-action-failed' | 'committed' = 'new';\n #commitActions: (() => Promise<void>)[] = [];\n\n setStatusCode(statusCode?: HttpStatusCode): boolean {\n if (this.#state === 'committed') {\n return false;\n }\n else {\n this.#statusCode = statusCode;\n return true;\n }\n }\n\n setRawStatusCode(statusCode?: number): boolean {\n return this.setStatusCode(statusCode === undefined ? undefined : httpStatusCode(statusCode));\n };\n\n get statusCode(): HttpStatusCode | undefined {\n return this.#statusCode;\n }\n\n addCookie(cookie: ResponseCookie): this {\n if (this.#state === 'committed') {\n throw new Error(`Cannot add cookie ${JSON.stringify(cookie)} because HTTP response has already been committed`);\n }\n this.#cookies.push(cookie);\n return this;\n }\n\n abstract getNativeResponse<T>(): T;\n\n beforeCommit(action: () => Promise<void>): void {\n this.#commitActions.push(action);\n }\n\n get commited(): boolean {\n const state = this.#state;\n return state !== 'new' && state !== 'commit-action-failed';\n }\n\n async body(body: ReadableStream<BodyChunk> | Promise<BodyChunk | void> | BodyChunk): Promise<boolean> {\n if (body instanceof ReadableStream) {\n throw new Error('ReadableStream body not supported yet');\n }\n const buffer = await body;\n try {\n // touch buffers if needed\n\n return await this.doCommit(async () => {\n\n return await this.bodyInternal(Promise.resolve(buffer));\n\n }).catch(error => {\n // release buffers\n throw error;\n });\n }\n catch (error) {\n // clear content headers\n throw error;\n }\n }\n\n abstract bodyInternal(body: Promise<BodyChunk | void>): Promise<boolean>;\n\n async end(): Promise<boolean> {\n if (!this.commited) {\n return this.doCommit(async () => {\n return await this.bodyInternal(Promise.resolve());\n });\n }\n else {\n return Promise.resolve(false);\n }\n }\n\n protected doCommit(writeAction?: () => Promise<boolean>): Promise<boolean> {\n const state = this.#state;\n let allActions = Promise.resolve();\n if (state === 'new') {\n this.#state = 'committing';\n if (this.#commitActions.length > 0) {\n allActions = this.#commitActions\n .reduce(\n (acc, cur) => acc.then(() => cur()),\n Promise.resolve())\n .catch((_error) => {\n const state = this.#state;\n if (state === 'committing') {\n this.#state = 'commit-action-failed';\n // clear content headers\n }\n });\n }\n }\n else if (state === 'commit-action-failed') {\n this.#state = 'committing';\n // skip commit actions\n } else {\n return Promise.resolve(false);\n }\n\n allActions = allActions.then(() => {\n this.applyStatusCode();\n this.applyHeaders();\n this.applyCookies();\n this.#state = 'committed';\n });\n\n\n return allActions.then(async () => {\n return writeAction !== undefined ? await writeAction() : true;\n });\n }\n\n protected applyStatusCode(): void {}\n protected applyHeaders(): void {}\n protected applyCookies(): void {}\n}\nexport class HttpServerRequest extends AbstractServerHttpRequest implements ServerHttpRequest {\n\n #url?: URL;\n #cookies?: HttpCookie[];\n readonly #req: ExtendedHttpIncomingMessage;\n\n constructor(req: ExtendedHttpIncomingMessage) {\n super(new IncomingMessageHeaders(req));\n this.#req = req;\n }\n\n getNativeRequest<T>(): T {\n return this.#req as T;\n }\n\n get upgrade() {\n return this.#req['upgrade'];\n }\n\n get http2(): boolean {\n return this.#req.httpVersionMajor >= 2;\n }\n\n get path() {\n return this.URL?.pathname;\n }\n\n get URL() {\n this.#url ??= new URL(this.#req.urlBang, `${this.protocol}://${this.host}`);\n return this.#url;\n }\n\n get query() {\n return this.URL?.search;\n }\n\n get method() {\n return this.#req.method as HttpMethod;\n }\n\n get host() {\n let dh: string | undefined = undefined;\n if (this.#req.httpVersionMajor >= 2) {\n dh = (this.#req.headers as http2.IncomingHttpHeaders)[':authority'];\n }\n dh ??= this.#req.socket.remoteAddress;\n return super.parseHost(dh);\n }\n\n get protocol() {\n let dp: string | undefined = undefined;\n if (this.#req.httpVersionMajor > 2) {\n dp = (this.#req.headers as http2.IncomingHttpHeaders)[':scheme'];\n }\n dp ??= this.#req.socketEncrypted ? 'https' : 'http';\n return super.parseProtocol(dp);\n }\n\n get socket() {\n return this.#req.socket;\n }\n\n get remoteAddress(): net.AddressInfo | undefined {\n const family = this.#req.socket.remoteFamily;\n const address = this.#req.socket.remoteAddress;\n const port = this.#req.socket.remotePort;\n const remoteAddress = (!family || !address || !port) ? undefined : { family, address, port };\n return super.parseRemoteAddress(remoteAddress) ?? remoteAddress;\n }\n\n protected initSslInfo(): SslInfo | undefined {\n if (this.#req.socketEncrypted) {\n return new DefaultSslInfo(this.#req.socket as TLSSocket);\n }\n }\n\n get cookies(): HttpCookie[] {\n this.#cookies ??= super.cookies\n return this.#cookies;\n }\n\n get body(): ReadableStream<BodyChunk> {\n return http.IncomingMessage.toWeb(this.#req) as ReadableStream<BodyChunk>;\n }\n\n async blob() {\n const chunks: BodyChunk[] = [];\n if (this.body !== undefined) {\n for await (const chunk of this.body) {\n chunks.push(chunk);\n }\n }\n return new Blob(chunks, {type: this.headers.one('content-type') as string || 'application/octet-stream'});\n }\n\n\n async text() {\n const blob = await this.blob();\n return await blob.text();\n }\n\n async formData() {\n const blob = await this.blob();\n const text = await blob.text();\n return new URLSearchParams(text);\n }\n\n async json() {\n const blob = await this.blob();\n if (blob.size === 0) {\n return undefined;\n }\n const text = await blob.text();\n return JSON.parse(text);\n }\n\n\n protected initId(): string {\n const remoteIp = this.#req.socket.remoteAddress;\n if (!remoteIp) {\n throw new Error('Socket has no remote address');\n }\n return `${remoteIp}:${this.#req.socket.remotePort}`;\n }\n}\n\nclass DefaultSslInfo implements SslInfo {\n readonly peerCertificate?: X509Certificate;\n constructor(socket: TLSSocket) {\n this.peerCertificate = socket.getPeerX509Certificate();\n }\n}\n\nclass IncomingMessageHeaders extends AbstractHttpHeaders<ReadonlyHeaderValues> implements ReadonlyHttpHeaders {\n readonly #msg: ExtendedHttpIncomingMessage;\n\n constructor(msg: ExtendedHttpIncomingMessage) {\n super();\n this.#msg = msg;\n }\n\n has(name: string): boolean {\n return this.#msg.headers[name] !== undefined;\n }\n\n get(name: string): string | (readonly string[]) | undefined {\n return this.#msg.headers[name];\n }\n\n list(name: string): string[] {\n return super.toList(name);\n }\n\n one(name: string): string | undefined {\n const value = this.#msg.headers[name];\n if (Array.isArray(value)) {\n return value[0];\n }\n return value;\n }\n\n keys() {\n return Object.keys(this.#msg.headers).values();\n }\n}\n\nclass OutgoingMessageHeaders extends AbstractHttpHeaders<HeaderValues> implements MutableHttpHeaders {\n readonly #msg: ExtendedHttpServerResponse;\n\n constructor(msg: ExtendedHttpServerResponse) {\n super();\n this.#msg = msg;\n }\n\n has(name: string): boolean {\n return this.#msg.hasHeader(name);\n }\n\n keys() {\n return this.#msg.getHeaderNames().values();\n }\n\n get(name: string): HeaderValues {\n return this.#msg.getHeader(name);\n }\n\n one(name: string): HeaderValue {\n const value = this.#msg.getHeader(name);\n if (Array.isArray(value)) {\n return value[0];\n }\n return value;\n }\n\n set(name: string, value: HeaderValues): this {\n if (!this.#msg.headersSent) {\n if (Array.isArray(value)) {\n value = value.map(v => typeof v === 'number' ? String(v) : v);\n } else if (typeof value === 'number') {\n value = String(value);\n }\n\n if (value) {\n this.#msg.setHeader(name, value);\n }\n else {\n this.#msg.removeHeader(name);\n }\n }\n return this;\n }\n\n add(name: string, value: string | (readonly string[])): this {\n if (!this.#msg.headersSent) {\n this.#msg.appendHeader(name, value);\n }\n return this;\n }\n\n list(name: string): string[] {\n return super.toList(name);\n }\n}\n\nexport class HttpServerResponse extends AbstractServerHttpResponse implements ServerHttpResponse {\n readonly #res: ExtendedHttpServerResponse;\n\n constructor(res: ExtendedHttpServerResponse) {\n super(new OutgoingMessageHeaders(res));\n this.#res = res;\n }\n\n getNativeResponse<T>(): T {\n return this.#res as T;\n }\n\n get statusCode(): HttpStatusCode {\n const status = super.statusCode;\n return status ?? {value: this.#res.statusCode};\n }\n\n applyStatusCode() {\n const status = super.statusCode;\n if (status !== undefined) {\n this.#res.statusCode = status.value;\n }\n }\n\n addCookie(cookie: ResponseCookie): this {\n this.headers.add('Set-Cookie', super.setCookieValue(cookie));\n return this;\n }\n\n async bodyInternal(body: Promise<BodyChunk | void>): Promise<boolean> {\n if (!this.#res.headersSent) {\n if (body instanceof ReadableStream) {\n // http.IncomingMessage.fromWeb(body)\n throw new Error('ReadableStream body not supported in response');\n }\n else {\n const chunk = await body;\n return await new Promise<boolean>((resolve, reject) => {\n try {\n if (chunk === undefined) {\n this.#res.end(() => {\n resolve(true);\n });\n } else {\n if (!this.headers.has('content-length')) {\n // set content-length if not already set\n if (typeof chunk === 'string') {\n this.headers.set('content-length', Buffer.byteLength(chunk));\n }\n else if (chunk instanceof Blob) {\n this.headers.set('content-length', chunk.size);\n }\n else {\n this.headers.set('content-length', chunk.byteLength);\n }\n }\n this.#res.end(chunk, () => {\n resolve(true);\n });\n }\n } catch (e) {\n reject(e instanceof Error ? e : new Error(`end failed: ${e}`));\n }\n });\n }\n }\n else {\n return false; // already ended\n }\n }\n}\n\nexport class ServerHttpRequestDecorator implements ServerHttpRequest {\n readonly #delegate: ServerHttpRequest;\n\n constructor(request: ServerHttpRequest) {\n this.#delegate = request;\n }\n\n get delegate(): ServerHttpRequest {\n return this.#delegate;\n }\n\n get id(): string {\n return this.#delegate.id;\n }\n\n get method(): HttpMethod {\n return this.#delegate.method;\n }\n\n get path(): string {\n return this.#delegate.path;\n }\n\n get protocol() {\n return this.#delegate.protocol;\n }\n\n get host(): string | undefined {\n return this.#delegate.host;\n }\n\n get URL(): URL {\n return this.#delegate.URL;\n }\n\n get headers(): ReadonlyHttpHeaders {\n return this.#delegate.headers;\n }\n\n get cookies(): HttpCookie[] {\n return this.#delegate.cookies;\n }\n\n get remoteAddress() {\n return this.#delegate.remoteAddress;\n }\n\n get upgrade() {\n return this.#delegate.upgrade;\n }\n\n get sslInfo() {\n return this.#delegate.sslInfo;\n }\n\n get body(): ReadableStream<BodyChunk> | undefined {\n return this.#delegate.body;\n }\n async blob(): Promise<Blob> {\n return await this.#delegate.blob();\n }\n async text(): Promise<string> {\n return await this.#delegate.text();\n }\n async formData(): Promise<URLSearchParams> {\n return await this.#delegate.formData();\n }\n async json(): Promise<unknown> {\n return await this.#delegate.json();\n }\n\n toString(): string {\n return `${ServerHttpRequestDecorator.name} [delegate: ${this.delegate.toString()}]`;\n }\n\n public static getNativeRequest<T>(request: ServerHttpRequest): T {\n if (request instanceof AbstractServerHttpRequest) {\n return request.getNativeRequest<T>();\n }\n else if (request instanceof ServerHttpRequestDecorator) {\n return ServerHttpRequestDecorator.getNativeRequest<T>(request.delegate);\n }\n else {\n throw new Error(`Cannot get native request from ${request.constructor.name}`);\n }\n }\n}\nexport class ServerHttpResponseDecorator implements ServerHttpResponse {\n readonly #delegate: ServerHttpResponse;\n\n constructor(response: ServerHttpResponse) {\n this.#delegate = response;\n }\n\n get delegate(): ServerHttpResponse {\n return this.#delegate;\n }\n\n setStatusCode(statusCode: HttpStatusCode): boolean {\n return this.delegate.setStatusCode(statusCode);\n }\n\n setRawStatusCode(statusCode?: number): boolean {\n return this.delegate.setRawStatusCode(statusCode);\n }\n\n get statusCode(): HttpStatusCode {\n return this.delegate.statusCode;\n }\n\n get cookies(): ResponseCookie[] {\n return this.delegate.cookies;\n }\n\n addCookie(cookie: ResponseCookie): this {\n this.delegate.addCookie(cookie);\n return this;\n }\n\n async end(): Promise<boolean> {\n return await this.delegate.end();\n }\n\n async body(body: ReadableStream<BodyChunk> | Promise<BodyChunk | void> | BodyChunk): Promise<boolean> {\n return await this.#delegate.body(body);\n }\n\n get headers(): MutableHttpHeaders {\n return this.#delegate.headers;\n }\n\n toString(): string {\n return `${ServerHttpResponseDecorator.name} [delegate: ${this.delegate.toString()}]`;\n }\n\n public static getNativeResponse<T>(response: ServerHttpResponse): T {\n if (response instanceof AbstractServerHttpResponse) {\n return response.getNativeResponse<T>();\n }\n else if (response instanceof ServerHttpResponseDecorator) {\n return ServerHttpResponseDecorator.getNativeResponse<T>(response.delegate);\n }\n else {\n throw new Error(`Cannot get native response from ${response.constructor.name}`);\n }\n }\n}\n\nexport class ServerWebExchangeDecorator implements ServerWebExchange {\n readonly #delegate: ServerWebExchange;\n\n protected constructor(exchange: ServerWebExchange) {\n this.#delegate = exchange;\n }\n\n get delegate(): ServerWebExchange {\n return this.#delegate;\n }\n\n get request(): ServerHttpRequest {\n return this.#delegate.request;\n }\n\n get response(): ServerHttpResponse {\n return this.#delegate.response;\n }\n\n attribute<T>(name: string): T | undefined {\n return this.#delegate.attribute(name);\n }\n\n principal<P extends Principal>(): Promise<P | undefined> {\n return this.#delegate.principal();\n }\n\n get logPrefix(): string {\n return this.#delegate.logPrefix;\n }\n\n toString() {\n return `${ServerWebExchangeDecorator.name} [delegate: ${this.delegate}]`;\n }\n}\n\nexport class DefaultWebExchange<Request extends ServerHttpRequest, Response extends ServerHttpResponse> {\n readonly request: Request;\n readonly response: Response;\n readonly #attributes: Record<string, unknown> = {};\n #logId?: unknown;\n #logPrefix: string = '';\n\n constructor(request: Request, response: Response) {\n this.#attributes[LOG_ID_ATTRIBUTE] = request.id;\n this.request = request;\n this.response = response;\n }\n\n get method(): HttpMethod {\n return this.request.method;\n }\n\n get path(): string | null | undefined {\n return this.request.path;\n }\n\n get attributes(): Record<string, unknown> {\n return this.#attributes;\n }\n\n attribute<T>(name: string): T | undefined {\n return this.attributes[name] as T;\n }\n\n principal<P extends Principal>(): Promise<P | undefined> {\n return Promise.resolve(undefined);\n }\n\n get logPrefix(): string {\n const value = this.attribute(LOG_ID_ATTRIBUTE);\n if (this.#logId !== value) {\n this.#logId = value;\n this.#logPrefix = value !== undefined ? `[${value}] ` : '';\n }\n return this.#logPrefix;\n }\n}\n\nexport const LOG_ID_ATTRIBUTE = 'io.interop.gateway.server.log_id';\n\n", "import getLogger from '../logger.ts';\nimport { getHeapStatistics, writeHeapSnapshot, type HeapInfo } from 'node:v8';\nimport type { PathLike } from 'node:fs';\nimport { access, mkdir, rename, unlink } from 'node:fs/promises';\n\nconst log = getLogger('monitoring');\n\nexport type Options = typeof DEFAULT_OPTIONS;\n\nexport type Command = 'run' | 'dump' | 'stop';\nexport type Channel = (command?: Command) => Promise<boolean>;\n\nconst DEFAULT_OPTIONS = {\n memoryLimit: 1024 * 1024 * 1024, // 1GB\n reportInterval: 10 * 60 * 1000, // 10 min\n dumpLocation: '.', // current folder\n maxBackups: 10,\n dumpPrefix: 'Heap'\n}\n\nfunction fetchStats(): HeapInfo {\n return getHeapStatistics();\n}\n\nasync function dumpHeap(opts: Options) {\n const prefix = opts.dumpPrefix ?? 'Heap';\n const target = `${opts.dumpLocation}/${prefix}.heapsnapshot`;\n if (log.enabledFor('debug')) {\n log.debug(`starting heap dump in ${target}`);\n }\n\n await fileExists(opts.dumpLocation)\n .catch(async (_) => {\n if (log.enabledFor('debug')) {\n log.debug(`dump location ${opts.dumpLocation} does not exists. Will try to create it`);\n }\n try {\n await mkdir(opts.dumpLocation, {recursive: true});\n log.info(`dump location dir ${opts.dumpLocation} successfully created`);\n } catch (e) {\n log.error(`failed to create dump location ${opts.dumpLocation}`);\n }\n });\n const dumpFileName = writeHeapSnapshot(target);\n log.info(`heap dumped`);\n try {\n log.debug(`rolling snapshot backups`);\n const lastFileName = `${opts.dumpLocation}/${prefix}.${opts.maxBackups}.heapsnapshot`;\n await fileExists(lastFileName)\n .then(async () => {\n if (log.enabledFor('debug')) {\n log.debug(`deleting ${lastFileName}`);\n }\n try {\n await unlink(lastFileName);\n } catch (e) {\n log.warn(`failed to delete ${lastFileName}`, e);\n }\n })\n .catch(() => {\n /* do nothing*/\n });\n for (let i = opts.maxBackups - 1; i > 0; i--) {\n const currentFileName = `${opts.dumpLocation}/${prefix}.${i}.heapsnapshot`;\n const nextFileName = `${opts.dumpLocation}/${prefix}.${i + 1}.heapsnapshot`;\n await fileExists(currentFileName)\n .then(async () => {\n try {\n await rename(currentFileName, nextFileName);\n } catch (e) {\n log.warn(`failed to rename ${currentFileName} to ${nextFileName}`, e);\n }\n })\n .catch(() => {\n /* do nothing*/\n });\n }\n const firstFileName = `${opts.dumpLocation}/${prefix}.${1}.heapsnapshot`;\n try {\n await rename(dumpFileName, firstFileName);\n } catch (e) {\n log.warn(`failed to rename ${dumpFileName} to ${firstFileName}`, e);\n }\n log.debug('snapshots rolled');\n } catch (e) {\n log.error('error rolling backups', e);\n throw e;\n }\n}\n\nasync function fileExists(path: PathLike): Promise<void> {\n if (log.enabledFor('trace')) {\n log.debug(`checking file ${path}`);\n }\n await access(path);\n}\n\nasync function processStats(stats: HeapInfo, state: {\n memoryLimitExceeded: boolean,\n snapshot?: boolean\n}, opts: Options) {\n if (log.enabledFor('debug')) {\n log.debug(`processing heap stats ${JSON.stringify(stats)}`);\n }\n const limit = Math.min(opts.memoryLimit, (0.95 * stats.heap_size_limit));\n const used = stats.used_heap_size;\n log.info(`heap stats ${JSON.stringify(stats)}`);\n if (used >= limit) {\n log.warn(`used heap ${used} bytes exceeds memory limit ${limit} bytes`);\n if (state.memoryLimitExceeded) {\n delete state.snapshot;\n } else {\n state.memoryLimitExceeded = true;\n state.snapshot = true;\n }\n await dumpHeap(opts);\n } else {\n state.memoryLimitExceeded = false;\n delete state.snapshot;\n }\n}\n\nexport function start(opts?: Partial<Options>): Options & { channel: Channel } {\n const merged: Options = {...DEFAULT_OPTIONS, ...opts};\n\n let stopped = false;\n const state = {memoryLimitExceeded: false};\n const report = async () => {\n const stats = fetchStats();\n await processStats(stats, state, merged);\n }\n const interval = setInterval(report, merged.reportInterval);\n const channel = async (command?: Command) => {\n if (!stopped) {\n command ??= 'run';\n switch (command) {\n case 'run': {\n await report();\n break;\n }\n case 'dump': {\n await dumpHeap(merged);\n break;\n }\n case 'stop': {\n stopped = true;\n clearInterval(interval);\n log.info('exit memory diagnostic');\n break;\n }\n }\n\n }\n return stopped;\n }\n\n return {...merged, channel};\n}\n\nasync function run({channel}: { channel: Channel }, command?: Command) {\n if (!await channel(command)) {\n log.warn(`cannot execute command \"${command}\" already closed`)\n }\n}\n\n\nexport async function stop(m: { channel: Channel }) {\n return await run(m, 'stop');\n}\n", "import type {ServerWebExchange} from '../../types/web/server';\n\nconst serverHeader = (version: string, server?: string | false) => {\n server ??= version;\n return async ({response}: ServerWebExchange, next: () => Promise<void>) => {\n if (server !== false && !response.headers.has('server')) {\n response.headers.set('Server', server);\n }\n await next();\n }\n};\n\nexport default (version: string, server?: string | false) => serverHeader(version, server);\n", "import { IOGateway } from '@interopio/gateway';\nimport type { OriginFilters } from '../../types/web/server';\nimport getLogger from '../logger.ts';\n\nconst log = getLogger('gateway.ws.client-verify');\n\nexport type ProcessedOriginFilters\n = Required<Omit<OriginFilters, 'blacklist' | 'whitelist'>>\n //| Required<Omit<GatewayServer.OriginFilters, 'block' | 'allow'>>\n ;\n\nfunction acceptsMissing(originFilters: ProcessedOriginFilters): boolean {\n switch (originFilters.missing) {\n case 'allow': // fall-through\n case 'whitelist':\n return true;\n case 'block': // fall-through\n case 'blacklist':\n return false;\n default:\n return false;\n }\n}\n\nfunction tryMatch(originFilters: ProcessedOriginFilters, origin: string): boolean | undefined {\n const block = originFilters.block ?? originFilters['blacklist'];\n const allow = originFilters.allow ?? originFilters['whitelist'];\n if (block.length > 0 && IOGateway.Filtering.valuesMatch(block, origin)) {\n log.warn(`origin ${origin} matches block filter`);\n return false;\n } else if (allow.length > 0 && IOGateway.Filtering.valuesMatch(allow, origin)) {\n if (log.enabledFor('debug')) {\n log.debug(`origin ${origin} matches allow filter`);\n }\n return true;\n }\n}\n\nfunction acceptsNonMatched(originFilters: ProcessedOriginFilters): boolean {\n switch (originFilters.non_matched) {\n case 'allow': // fall-through\n case 'whitelist':\n return true;\n case 'block': // fall-through\n case 'blacklist':\n return false;\n default:\n return false;\n }\n}\n\nexport function acceptsOrigin(origin?: string, originFilters?: ProcessedOriginFilters): boolean {\n if (!originFilters) {\n return true;\n }\n if (!origin) {\n return acceptsMissing(originFilters);\n } else {\n const matchResult: boolean | undefined = tryMatch(originFilters, origin);\n if (matchResult) {\n return matchResult;\n } else {\n return acceptsNonMatched(originFilters);\n }\n }\n}\n\nexport function regexifyOriginFilters(originFilters?: OriginFilters): ProcessedOriginFilters | undefined {\n if (originFilters) {\n const block = (originFilters.block ?? originFilters.blacklist ?? []).map(IOGateway.Filtering.regexify);\n const allow = (originFilters.allow ?? originFilters.whitelist ?? []).map(IOGateway.Filtering.regexify);\n return {\n non_matched: originFilters.non_matched ?? 'allow',\n missing: originFilters.missing ?? 'allow',\n allow,\n block,\n }\n }\n}\n", "import type {ServerWebExchange} from '../../../types/web/server';\n\nexport type MatchResult = Readonly<{ match: boolean, variables: Readonly<Record<string, string>> }>;\n\nexport interface ServerWebExchangeMatcher {\n /**\n * Matches the given exchange against the matcher.\n * @param exchange The web exchange to match.\n * @returns A promise that resolves to true if the exchange matches, false otherwise.\n */\n (exchange: ServerWebExchange): Promise<MatchResult>;\n\n /**\n * Returns a string representation of the matcher.\n * @returns A string representation of the matcher.\n */\n toString(): string;\n}\n\nexport type ServerWebExchangeMatcherEntry<T> = Readonly<[ServerWebExchangeMatcher, T]>\n\nexport const or: (matchers: ServerWebExchangeMatcher[]) => ServerWebExchangeMatcher = (matchers: ServerWebExchangeMatcher[]): ServerWebExchangeMatcher => {\n return async (exchange: ServerWebExchange): Promise<MatchResult> => {\n for (const matcher of matchers) {\n const result = await matcher(exchange);\n if (result.match) {\n return match();\n }\n }\n return NO_MATCH;\n };\n}\n\nexport const and: (matchers: ServerWebExchangeMatcher[]) => ServerWebExchangeMatcher = (matchers: ServerWebExchangeMatcher[]) => {\n const matcher = async (exchange: ServerWebExchange): Promise<MatchResult> => {\n for (const matcher of matchers) {\n const result = await matcher(exchange);\n if (!result.match) {\n return NO_MATCH;\n }\n }\n return match();\n };\n matcher.toString = () => `and(${matchers.map(m => m.toString()).join(', ')})`;\n return matcher;\n}\n\n\nexport const not: (matcher: ServerWebExchangeMatcher) => ServerWebExchangeMatcher = (matcher: ServerWebExchangeMatcher): ServerWebExchangeMatcher => {\n return async (exchange: ServerWebExchange): Promise<MatchResult> => {\n const result = await matcher(exchange);\n return result.match ? NO_MATCH : match();\n };\n}\n\nexport const anyExchange: ServerWebExchangeMatcher = async (_exchange: ServerWebExchange): Promise<MatchResult> => {\n return match();\n}\nanyExchange.toString = () => 'any-exchange';\n\nconst EMPTY_OBJECT = Object.freeze({});\nexport const NO_MATCH: MatchResult = Object.freeze({match: false, variables: EMPTY_OBJECT});\nexport const match = (variables: Record<string, string> = EMPTY_OBJECT): MatchResult => {\n return {match: true, variables};\n}\n\nexport const pattern: ((pattern: string | RegExp, opts?: {method?: string}) => ServerWebExchangeMatcher) = (pattern, opts) => {\n const method = opts?.method;\n const matcher = async (exchange: ServerWebExchange): Promise<MatchResult> => {\n const request = exchange.request;\n const path = request.path;\n if (method !== undefined && request.method !== method) {\n return NO_MATCH;\n }\n if (typeof pattern === 'string') {\n if (path === pattern) {\n return match();\n }\n return NO_MATCH;\n }\n else {\n const match = pattern.exec(path);\n if (match === null) {\n return NO_MATCH;\n }\n return {match: true, variables: {...match.groups}};\n }\n };\n matcher.toString = () => {\n return `pattern(${pattern.toString()}, method=${method ?? '<any>'})`;\n }\n return matcher\n\n}\nexport const mediaType : ((opts: {mediaTypes: string[], ignoredMediaTypes?: string[], useEquality?: boolean}) => ServerWebExchangeMatcher) = (opts): ServerWebExchangeMatcher => {\n\n const shouldIgnore = (requestedMediaType: string): boolean => {\n if (opts.ignoredMediaTypes !== undefined) {\n for (const ignoredMediaType of opts.ignoredMediaTypes) {\n if (requestedMediaType === ignoredMediaType || ignoredMediaType === '*/*') {\n return true;\n }\n }\n }\n return false;\n }\n\n return async (exchange: ServerWebExchange): Promise<MatchResult> => {\n const request = exchange.request;\n let requestMediaTypes: string[];\n try {\n requestMediaTypes = request.headers.list('accept');\n }\n catch (e) {\n return NO_MATCH;\n }\n for (const requestedMediaType of requestMediaTypes) {\n if (shouldIgnore(requestedMediaType)) {\n continue;\n }\n for (const mediaType of opts.mediaTypes) {\n if (requestedMediaType.startsWith(mediaType)) {\n return match();\n }\n }\n }\n\n return NO_MATCH;\n };\n}\n\nexport const upgradeMatcher: ServerWebExchangeMatcher = async ({request}: ServerWebExchange): Promise<MatchResult> => {\n const upgrade = request.upgrade && request.headers.one('upgrade')?.toLowerCase() === 'websocket';\n return upgrade ? match() : NO_MATCH;\n};\nupgradeMatcher.toString = () => 'websocket upgrade';\n", "import { regexifyOriginFilters } from '../server/ws-client-verify.ts';\nimport type { SecurityContext } from '../server/security/security-context.ts';\nimport { pattern, type ServerWebExchangeMatcher } from '../server/util/matchers.ts';\nimport type { CorsConfig } from '../server/cors.ts';\nimport type { Middleware } from '../server/types.ts';\nimport type { AsyncLocalStorage } from 'node:async_hooks';\nimport type { SocketRoute } from '../server/socket.ts';\nimport { GatewayServer } from '@interopio/gateway-server';\nimport type {\n ServerConfigurer,\n ServerConfigurerHandlerSpec,\n ServerConfigurerSocketSpec,\n ServerExchangeOptions,\n ServerWebExchange\n} from '../../types/web/server';\nimport type { AuthorizationRule } from '../../types/auth';\nimport { IOGateway } from '@interopio/gateway';\n\nexport type PathPattern = string | RegExp;\nexport type RouteConfig = Readonly<{\n readonly storage: AsyncLocalStorage<{\n exchange: ServerWebExchange,\n securityContext?: Promise<SecurityContext>\n }>,\n readonly serverHeader?: string | false\n readonly corsConfig?: GatewayServer.ServerConfig['cors'],\n readonly authConfig?: GatewayServer.ServerConfig['auth'],\n readonly middleware: Middleware,\n readonly cors: Array<[PathPattern, CorsConfig | undefined]>,\n readonly authorize: Array<[ServerWebExchangeMatcher, AuthorizationRule]>\n readonly sockets: Map<string, SocketRoute>\n}>\n\nexport async function configure(app: GatewayServer.ServerCustomizer, config: GatewayServer.ServerConfig, routes: RouteConfig): Promise<void> {\n const applyCors = (request: ServerConfigurerHandlerSpec['request'], options?: ServerExchangeOptions) => {\n // // disable CORS for this route\n // if (options?.cors === false) {\n // const path = request.path as (PathPattern);\n // routes.cors.push([request.path, undefined]);\n // }\n if (options?.cors) {\n const cors: CorsConfig = options.cors === true ? {\n allowOrigins: options.origins?.allow?.map(IOGateway.Filtering.regexify),\n allowMethods: request.method === undefined ? ['*'] : [request.method],\n allowCredentials: options.authorize?.access !== 'permitted' ? true : undefined,\n } : options.cors;\n const path = request.path as (PathPattern);\n routes.cors.push([path, cors]);\n }\n }\n\n const configurer = new class implements ServerConfigurer {\n\n handle(...handlers: Array<ServerConfigurerHandlerSpec>) {\n handlers.forEach(({request, options, handler}) => {\n const matcher = pattern(IOGateway.Filtering.regexify(request.path) as string | RegExp, {method: request.method});\n if (options?.authorize) {\n routes.authorize.push([matcher, options.authorize]);\n }\n\n applyCors(request, options);\n const middleware = async (exchange: ServerWebExchange, next: () => Promise<void>): Promise<void> => {\n const {match, variables} = await matcher(exchange);\n if (match) {\n await handler(exchange, variables);\n } else {\n await next();\n }\n };\n routes.middleware.push(middleware);\n });\n }\n\n socket(...sockets: Array<ServerConfigurerSocketSpec>) {\n for (const {path, factory, options} of sockets) {\n const route = path ?? '/';\n\n // cors and authorize are currently handled for ws\n routes.sockets.set(route, {\n default: path === undefined,\n ping: options?.ping,\n factory: factory,\n maxConnections: options?.maxConnections,\n authorize: options?.authorize,\n originFilters: regexifyOriginFilters(options?.origins)\n });\n }\n }\n };\n await app(configurer, config);\n}\n", "import type { ServerWebExchangeMatcher } from './util/matchers.ts';\nimport { HttpStatus } from '../http/status.ts';\nimport getLogger from '../logger.ts';\nimport type { HttpRequest, ReadonlyHttpHeaders } from '../../types/web/http';\nimport type { ServerHttpResponse, ServerWebExchange } from '../../types/web/server';\nimport { IOGateway } from '@interopio/gateway';\n\nfunction isSameOrigin(request: HttpRequest<ReadonlyHttpHeaders>) {\n const origin = request.headers.one('origin');\n if (origin === undefined) {\n return true;\n }\n const url = request.URL;\n const actualProtocol = url.protocol;\n const actualHost = url.host;\n\n const originUrl = URL.parse(origin); // URL.parse requires Node.js 20.18 || 22.1\n\n const originHost = originUrl?.host;\n const originProtocol = originUrl?.protocol;\n return actualProtocol === originProtocol\n && actualHost === originHost;\n}\n\n/**\n * Returns `true` if the request is a valid CORS one by checking `Origin` header presence and ensuring origins differ.\n */\nexport function isCorsRequest(request: HttpRequest<ReadonlyHttpHeaders>): boolean {\n return request.headers.has('origin') && !isSameOrigin(request);\n\n}\n\nexport function isPreFlightRequest(request: HttpRequest): boolean {\n return request.method === 'OPTIONS'\n && request.headers.has('origin')\n && request.headers.has('access-control-request-method');\n}\n\nconst VARY_HEADERS: readonly string[] = ['Origin', 'Access-Control-Request-Method', 'Access-Control-Request-Headers'];\n\n/**\n * Processes a request given a {@link CorsConfig}.\n *\n * @param exchange the current exchange\n * @param config the CORS configuration to use, possibly `undefined` in which case pre-flight requests are rejected, but all others allowed\n * @returns `false` if the request is rejected, `true` otherwise\n */\nexport const processRequest: CorsProcessor = (exchange: ServerWebExchange, config?: CorsConfig): boolean => {\n const {request, response} = exchange;\n const responseHeaders = response.headers;\n\n if (!responseHeaders.has('Vary')) {\n responseHeaders.set('Vary', VARY_HEADERS.join(', '));\n }\n else {\n const varyHeaders = responseHeaders.list('Vary');\n for (const header of VARY_HEADERS) {\n if (!varyHeaders.find(h => h === header)) {\n varyHeaders.push(header);\n }\n }\n responseHeaders.set('Vary', varyHeaders.join(', '));\n }\n\n try {\n if (!isCorsRequest(request)) {\n return true;\n }\n }\n catch (e) {\n if(logger.enabledFor('debug')) {\n logger.debug(`reject: origin is malformed`);\n }\n rejectRequest(response);\n return false;\n }\n\n if (responseHeaders.has('access-control-allow-origin')) {\n if (logger.enabledFor('trace')) {\n logger.debug(`skip: already contains \"Access-Control-Allow-Origin\"`);\n }\n return true;\n }\n\n const preFlightRequest = isPreFlightRequest(request);\n\n if (config) {\n return handleInternal(exchange, config, preFlightRequest);\n }\n if (preFlightRequest) {\n rejectRequest(response);\n return false;\n }\n return true;\n}\n\nexport type CorsConfig = Readonly<{\n allowOrigins?: '*' | IOGateway.Filtering.Matcher[]\n allowMethods?:'*' | string[]\n allowHeaders?: '*' | string[]\n exposeHeaders?: string[]\n allowCredentials?: boolean\n allowPrivateNetwork?: boolean\n maxAge?: number\n}>;\n\nconst DEFAULT_PERMIT_ALL = ['*'];\nconst DEFAULT_PERMIT_METHODS = ['GET', 'HEAD', 'POST'];\nexport const PERMIT_DEFAULT_CONFIG: CorsConfig = {\n allowOrigins: DEFAULT_PERMIT_ALL,\n allowMethods: DEFAULT_PERMIT_METHODS,\n allowHeaders: DEFAULT_PERMIT_ALL,\n maxAge: 1800 // 30 minutes\n}\nexport /*testing*/ function validateCorsConfig(config?: CorsConfig): CorsConfig | undefined {\n if (config) {\n const allowHeaders = config.allowHeaders;\n if (allowHeaders && allowHeaders !== ALL) {\n config = {\n ...config,\n allowHeaders: allowHeaders.map(header => header.toLowerCase())\n };\n }\n const allowOrigins = config.allowOrigins;\n if (allowOrigins) {\n if (allowOrigins === '*') {\n validateAllowCredentials(config);\n validateAllowPrivateNetwork(config);\n }\n else {\n config = {\n ...config,\n allowOrigins: allowOrigins.map(origin => {\n if (typeof origin === 'string' && origin !== ALL) {\n origin = IOGateway.Filtering.regexify(origin);\n if (typeof origin === 'string') {\n // exact match\n return trimTrailingSlash(origin).toLowerCase();\n }\n }\n return origin;\n })\n };\n }\n }\n return config;\n }\n}\n\nfunction combine<T = (string | IOGateway.Filtering.Matcher)>(source?: '*' | T[], other?: '*' | T[]): T[] | undefined {\n if (other === undefined) {\n return source !== undefined ? (source === ALL ? [ALL as T] : source) : [];\n }\n if (source === undefined) {\n return other === ALL ? [ALL as T] : other;\n }\n if (source == DEFAULT_PERMIT_ALL || source === DEFAULT_PERMIT_METHODS) {\n return other === ALL ? [ALL as T] : other;\n }\n if (other == DEFAULT_PERMIT_ALL || other === DEFAULT_PERMIT_METHODS) {\n return source === ALL ? [ALL as T] : source;\n }\n if (source === ALL || source.includes(ALL as T) || other === ALL || other.includes(ALL as T)) {\n return [ALL as T];\n }\n const combined = new Set<T>();\n source.forEach((v) => combined.add(v));\n other.forEach((v) => combined.add(v));\n return Array.from(combined);\n}\nexport const combineCorsConfig = (source: CorsConfig, other?: CorsConfig): CorsConfig => {\n if (other === undefined) {\n return source;\n }\n const config: CorsConfig = {\n allowOrigins: combine(source.allowOrigins, other?.allowOrigins),\n allowMethods: combine(source.allowMethods, other?.allowMethods),\n allowHeaders: combine(source.allowHeaders, other?.allowHeaders),\n exposeHeaders: combine(source.exposeHeaders, other?.exposeHeaders),\n allowCredentials: other?.allowCredentials ?? source.allowCredentials,\n allowPrivateNetwork: other?.allowPrivateNetwork ?? source.allowPrivateNetwork,\n maxAge: other?.maxAge ?? source.maxAge\n }\n return config;\n\n}\n\nexport type CorsConfigSource = (exchange: ServerWebExchange) => Promise<CorsConfig | undefined>;\nexport type CorsProcessor = (exchange: ServerWebExchange, config?: CorsConfig) => boolean;\n\nconst corsFilter = (opts: {corsConfigSource: CorsConfigSource, corsProcessor?: CorsProcessor}) => {\n const source = opts.corsConfigSource;\n const processor = opts.corsProcessor ?? processRequest;\n if (source === undefined) {\n throw new Error('corsConfigSource is required');\n }\n if (processor === undefined) {\n throw new Error('corsProcessor is required');\n }\n return async (ctx: ServerWebExchange, next: () => Promise<void>) => {\n const config = await source(ctx);\n const isValid = processor(ctx, config);\n if (!isValid || isPreFlightRequest(ctx.request)) {\n return;\n } else {\n await next();\n }\n };\n}\n\nexport default corsFilter;\n\n\nconst logger = getLogger('cors');\n\nfunction rejectRequest(response: ServerHttpResponse) {\n response.setStatusCode(HttpStatus.FORBIDDEN);\n}\n\nfunction handleInternal(exchange: ServerWebExchange,\n config: CorsConfig, preFlightRequest: boolean): boolean {\n const {request, response} = exchange;\n const responseHeaders = response.headers;\n\n const requestOrigin = request.headers.one('origin');\n const allowOrigin = checkOrigin(config, requestOrigin);\n\n if (allowOrigin === undefined) {\n if (logger.enabledFor('debug')) {\n logger.debug(`reject: '${requestOrigin}' origin is not allowed`);\n }\n rejectRequest(response);\n return false;\n }\n\n const requestMethod = getMethodToUse(request, preFlightRequest);\n const allowMethods = checkMethods(config, requestMethod);\n if (allowMethods === undefined) {\n if (logger.enabledFor('debug')) {\n logger.debug(`reject: HTTP '${requestMethod}' is not allowed`);\n }\n rejectRequest(response);\n return false;\n }\n\n const requestHeaders = getHeadersToUse(request, preFlightRequest);\n const allowHeaders = checkHeaders(config, requestHeaders);\n if (preFlightRequest && allowHeaders === undefined) {\n if (logger.enabledFor('debug')) {\n logger.debug(`reject: headers '${requestHeaders}' are not allowed`);\n }\n rejectRequest(response);\n return false;\n }\n\n responseHeaders.set('Access-Control-Allow-Origin', allowOrigin);\n\n if (preFlightRequest) {\n responseHeaders.set('Access-Control-Allow-Methods', allowMethods.join(','));\n\n }\n if (preFlightRequest && allowHeaders !== undefined && allowHeaders.length > 0) {\n responseHeaders.set('Access-Control-Allow-Headers', allowHeaders.join(', '));\n }\n const exposeHeaders = config.exposeHeaders;\n if (exposeHeaders && exposeHeaders.length > 0) {\n responseHeaders.set('Access-Control-Expose-Headers', exposeHeaders.join(', '));\n }\n if (config.allowCredentials) {\n responseHeaders.set('Access-Control-Allow-Credentials', 'true');\n }\n if (config.allowPrivateNetwork && request.headers.one('access-control-request-private-network') === 'true') {\n responseHeaders.set('Access-Control-Allow-Private-Network', 'true');\n }\n\n if (preFlightRequest && config.maxAge !== undefined) {\n responseHeaders.set('Access-Control-Max-Age', config.maxAge.toString());\n }\n return true;\n}\n\nconst ALL = '*';\nconst DEFAULT_METHODS = ['GET', 'HEAD'];\n\nfunction validateAllowCredentials(config: CorsConfig) {\n if (config.allowCredentials === true && config.allowOrigins === ALL) {\n throw new Error(`when allowCredentials is true allowOrigins cannot be \"*\"`);\n }\n}\n\nfunction validateAllowPrivateNetwork(config: CorsConfig) {\n if (config.allowPrivateNetwork === true && config.allowOrigins === ALL) {\n throw new Error(`when allowPrivateNetwork is true allowOrigins cannot be \"*\"`);\n }\n}\n\nfunction checkOrigin(config: CorsConfig, origin? :string): string | undefined {\n if (origin) {\n const allowedOrigins = config.allowOrigins;\n if (allowedOrigins) {\n if (allowedOrigins === ALL) {\n validateAllowCredentials(config);\n validateAllowPrivateNetwork(config);\n return ALL;\n }\n const originToCheck = trimTrailingSlash(origin.toLowerCase());\n\n for (const allowedOrigin of allowedOrigins) {\n if ((allowedOrigin === ALL) || IOGateway.Filtering.valueMatches(allowedOrigin, originToCheck)) {\n return origin;\n }\n }\n }\n }\n}\n\nfunction checkMethods(config: CorsConfig, requestMethod?: string): string[] | undefined {\n if (requestMethod) {\n const allowedMethods = config.allowMethods ?? DEFAULT_METHODS;\n if (allowedMethods === ALL) {\n return [requestMethod];\n }\n if (IOGateway.Filtering.valuesMatch(allowedMethods, requestMethod)) {\n return allowedMethods;\n }\n }\n}\n\nfunction checkHeaders(config: CorsConfig, requestHeaders?: string[]): string[] | undefined {\n if (requestHeaders === undefined) {\n return;\n }\n if (requestHeaders.length == 0) {\n return [];\n }\n const allowedHeaders = config.allowHeaders;\n if (allowedHeaders === undefined) {\n return;\n }\n const allowAnyHeader = allowedHeaders === ALL || allowedHeaders.includes(ALL);\n const result: string[] = [];\n for (const requestHeader of requestHeaders) {\n const value = requestHeader?.trim();\n if (value) {\n if (allowAnyHeader) {\n result.push(value);\n }\n else {\n for (const allowedHeader of allowedHeaders) {\n if (value.toLowerCase() === allowedHeader) {\n result.push(value);\n break;\n }\n }\n }\n }\n }\n if (result.length > 0) {\n return result;\n }\n}\n\nfunction trimTrailingSlash(origin: string): string {\n return origin.endsWith('/') ? origin.slice(0, -1) : origin;\n}\n\nfunction getMethodToUse(request: HttpRequest<ReadonlyHttpHeaders>, isPreFlight: boolean): string | undefined {\n return (isPreFlight ? request.headers.one('access-control-request-method') : request.method);\n}\n\nfunction getHeadersToUse(request: HttpRequest, isPreFlight: boolean): string[] {\n const headers = request.headers;\n return (isPreFlight ? headers.list('access-control-request-headers') : Array.from(headers.keys()));\n}\n\nexport const matchingCorsConfigSource = (opts: {mappings: Array<[ServerWebExchangeMatcher, CorsConfig | undefined]>}): CorsConfigSource => {\n return async (exchange: ServerWebExchange) => {\n for (const [matcher, config] of opts.mappings) {\n if ((await matcher(exchange)).match) {\n logger.debug(`resolved cors config on '${exchange.request.path}' using ${matcher}: ${JSON.stringify(config)}`);\n return config;\n }\n }\n }\n}\n", "import type { RouteConfig, PathPattern } from './route.ts';\nimport {\n combineCorsConfig,\n type CorsConfig,\n type CorsConfigSource,\n matchingCorsConfigSource,\n PERMIT_DEFAULT_CONFIG,\n validateCorsConfig\n} from '../server/cors.ts';\nimport { and, pattern, type ServerWebExchangeMatcher, upgradeMatcher } from '../server/util/matchers.ts';\nimport { IOGateway } from '@interopio/gateway';\n\nexport function createCorsConfigSource(context: Pick<RouteConfig, 'sockets' | 'cors' | 'corsConfig'>): CorsConfigSource {\n const {sockets: routes, cors} = context;\n\n // create a default CORS config that allows all origins and methods and then combine it with the provided corsConfig\n const defaultCorsConfig: CorsConfig | undefined = context.corsConfig === false ? undefined : combineCorsConfig(PERMIT_DEFAULT_CONFIG, context.corsConfig);\n\n const validatedConfigs: Array<[ServerWebExchangeMatcher, CorsConfig | undefined]> = [];\n\n // for each socket route, combine the default CORS config, then any app CORS config that match, and finally the route CORS config\n for (const [path, route] of routes) {\n let routeCorsConfig: CorsConfig | undefined = defaultCorsConfig;\n for (const [matcher, config] of cors) {\n if (IOGateway.Filtering.valueMatches(matcher, path)) {\n if (config === undefined) {\n routeCorsConfig = undefined;\n }\n else {\n routeCorsConfig = routeCorsConfig === undefined ? config : combineCorsConfig(routeCorsConfig, config);\n }\n }\n }\n const config = context.corsConfig === false ? undefined : {\n allowOrigins: route.originFilters?.allow,\n allowMethods: ['GET', 'CONNECT', 'OPTIONS'],\n allowHeaders: [\n 'Upgrade',\n 'Connection',\n 'Origin',\n 'Sec-Websocket-Key',\n 'Sec-Websocket-Version',\n 'Sec-Websocket-Protocol',\n 'Sec-Websocket-Extensions'\n ],\n exposeHeaders: ['Sec-Websocket-Accept', 'Sec-Websocket-Protocol', 'Sec-Websocket-Extensions'],\n allowCredentials: route.authorize?.access !== 'permitted' ? true : undefined,\n };\n routeCorsConfig = routeCorsConfig === undefined ? config : combineCorsConfig(routeCorsConfig, config);\n\n validatedConfigs.push([\n and([upgradeMatcher, pattern(path)]),\n validateCorsConfig(routeCorsConfig)]);\n }\n\n const appConfigs: Array<[PathPattern, CorsConfig | undefined]> = [];\n // add app CORS configs\n for (const [matcher, config] of cors) {\n let [, routeCorsConfig] = appConfigs.find(([m]) => String(m) === String(matcher)) ?? [matcher, defaultCorsConfig];\n\n routeCorsConfig = routeCorsConfig === undefined ? config : combineCorsConfig(routeCorsConfig, config);\n let added = false;\n for (const entry of appConfigs) {\n if (String(entry[0]) === String(matcher)) {\n entry[1] = routeCorsConfig;\n added = true;\n break;\n }\n }\n if (!added) {\n appConfigs.push([matcher, routeCorsConfig]);\n }\n }\n for (const [matcher, config] of appConfigs) {\n validatedConfigs.push([pattern(matcher), validateCorsConfig(config)]);\n }\n\n validatedConfigs.push([pattern(/\\/api\\/.*/), validateCorsConfig(defaultCorsConfig)]);\n\n\n return matchingCorsConfigSource({mappings: validatedConfigs});\n}\n", "import type { Principal } from '../../../types/auth';\nimport type { ServerWebExchange } from '../../../types/web/server';\n\n// A principal that has been authenticated and has a name.\nexport type AuthenticatedPrincipal = Principal & { readonly name: string };\n\nexport type Authentication = Principal & {\n type: string;\n readonly authorities?: ReadonlyArray<GrantedAuthority>;\n readonly credentials?: unknown;\n readonly details?: unknown;\n readonly principal?: unknown;\n authenticated: boolean;\n}\n\nexport type GrantedAuthority = {\n readonly authority?: string;\n}\n\n// An interface for holding credentials that can be erased. Not CredentialsContainer to avoid confusion with web Credential Management API .\nexport interface CredentialsHolder {\n eraseCredentials?(): void;\n}\n\nexport type AbstractAuthenticationToken = Authentication & CredentialsHolder & {\n readonly name: string;\n details?: unknown;\n}\n\nexport function isAuthentication(principal?: Principal): principal is Authentication {\n return principal !== undefined && typeof principal['type'] === 'string' && typeof principal['authenticated'] === 'boolean';\n}\n\nexport type AuthenticationConverter = (exchange: ServerWebExchange) => Promise<Authentication | undefined>;\n\nexport class AuthenticationError extends Error {\n private _authentication?: Authentication;\n\n get authentication(): Authentication | undefined {\n return this._authentication;\n }\n\n set authentication(value: Authentication) {\n if (value === undefined) {\n throw new TypeError(\"Authentication cannot be undefined\");\n }\n this._authentication = value;\n }\n}\n\nexport class InsufficientAuthenticationError extends AuthenticationError {}\n\nexport class BadCredentialsError extends AuthenticationError {}\n\nabstract class AccountStatusError extends AuthenticationError {\n protected constructor(message: string) {\n super(message);\n }\n}\n\nexport class LockedError extends AccountStatusError {\n constructor(message: string) {\n super(message);\n }\n}\n\nexport class DisabledError extends AccountStatusError {\n constructor(message: string) {\n super(message);\n }\n}\n\nexport class AccountExpiredError extends AccountStatusError {\n constructor(message: string) {\n super(message);\n }\n}\n\nexport class CredentialsExpiredError extends AccountStatusError {\n constructor(message: string) {\n super(message);\n }\n}\n\n\nexport class AuthenticationCredentialsNotFoundError extends AuthenticationError {}\n\nexport class AccessDeniedError extends Error {}\n\nexport type AuthenticationManager = (authentication: Authentication) => Promise<Authentication | undefined>;\n\nexport type AuthorizationManager<T> = {\n\n /**\n * Determines if access should be granted to the given object for the provided authentication.\n * @param authentication\n * @param object\n */\n verify(authentication: Promise<Authentication | undefined>, object: T): Promise<void>,\n /**\n * Checks if the authentication is authorized to access the given object.\n * @param authentication\n * @param object\n */\n authorize: (authentication: Promise<Authentication | undefined>, object: T) => Promise<AuthorizationResult | undefined>;\n}\nexport interface AuthorizationResult {readonly granted: boolean;}\nexport class AuthorizationDecision implements AuthorizationResult {\n constructor(granted: boolean) {\n this.granted = granted;\n }\n\n readonly granted: boolean;\n}\nexport class DefaultAuthorizationManager<T> implements AuthorizationManager<T> {\n readonly #check: (authentication: Promise<Authentication | undefined>, object: T) => Promise<AuthorizationDecision | undefined>;\n\n constructor(check: (authentication: Promise<Authentication | undefined>, object: T) => Promise<AuthorizationDecision>) {\n this.#check = check;\n }\n\n async verify(authentication: Promise<Authentication | undefined>, object: T): Promise<void> {\n const decision = await this.#check(authentication, object);\n if (!decision?.granted) {\n throw new AccessDeniedError(\"Access denied\");\n }\n }\n\n async authorize(authentication: Promise<Authentication | undefined>, object: T) {\n return await this.#check(authentication, object);\n }\n}\n\nexport class AuthenticationServiceError extends AuthenticationError {}\nexport type ServerAuthenticationSuccessHandler = (filterExchange: {exchange: ServerWebExchange, next: () => Promise<void>}, authentication: Authentication) => Promise<void>;\nexport type ServerAuthenticationFailureHandler = (filterExchange: {exchange: ServerWebExchange, next: () => Promise<void>}, error: AuthenticationError) => Promise<void>;\nexport type ServerAuthenticationEntryPoint = (exchange: ServerWebExchange, error: AuthenticationError) => Promise<void>;\nexport type ServerAccessDeniedHandler = (exchange: ServerWebExchange, error: AccessDeniedError) => Promise<void>;\n", "import { MapHttpHeaders } from '../../http/exchange.ts';\nimport type { ServerWebExchange } from '../../../types/web/server';\n\ntype ServerHttpHeadersWriter = (exchange: ServerWebExchange) => Promise<void>;\n\nconst staticServerHttpHeadersWriter = (headers: MapHttpHeaders): ServerHttpHeadersWriter => {\n return async (exchange: ServerWebExchange) => {\n let containsNoHeaders = true;\n const {response} = exchange;\n for (const name of headers.keys()) {\n if (response.headers.has(name)) {\n containsNoHeaders = false;\n }\n }\n if (containsNoHeaders) {\n for (const [name, value] of headers) {\n response.headers.set(name, value);\n }\n }\n }\n}\n\nconst cacheControlServerHttpHeadersWriter = () => staticServerHttpHeadersWriter(\n new MapHttpHeaders()\n .add('cache-control', 'no-cache, no-store, max-age=0, must-revalidate')\n .add('pragma', 'no-cache')\n .add('expires', '0'));\n\nconst contentTypeServerHttpHeadersWriter = () => staticServerHttpHeadersWriter(\n new MapHttpHeaders()\n .add('x-content-type-options', 'nosniff'));\n\nconst strictTransportSecurityServerHttpHeadersWriter = (maxAgeInSeconds: number, includeSubDomains: boolean, preload: boolean) => {\n let headerValue = `max-age=${maxAgeInSeconds}`;\n if (includeSubDomains) {\n headerValue += ' ; includeSubDomains';\n }\n if (preload) {\n headerValue += ' ; preload';\n }\n const delegate = staticServerHttpHeadersWriter(\n new MapHttpHeaders()\n .add('strict-transport-security', headerValue))\n\n const isSecure = (exchange: ServerWebExchange) => {\n const protocol = exchange.request.URL.protocol;\n return protocol === 'https:';\n }\n\n return async (exchange: ServerWebExchange) => {\n if (isSecure(exchange)) {\n await delegate(exchange);\n }\n }\n};\n\ntype FrameOptionsMode = 'DENY' | 'SAMEORIGIN';\nconst frameOptionsServerHttpHeadersWriter = (mode: FrameOptionsMode) => {\n return staticServerHttpHeadersWriter(\n new MapHttpHeaders()\n .add('x-frame-options', mode))\n};\n\ntype XssProtectionHeaderValue = '0' | '1' | '1; mode=block';\nconst xssProtectionServerHttpHeadersWriter = (headerValue: XssProtectionHeaderValue) => staticServerHttpHeadersWriter(\n new MapHttpHeaders()\n .add('x-xss-protection', headerValue));\n\n\nconst permissionsPolicyServerHttpHeadersWriter = (policyDirectives?: string) => {\n\n const delegate = policyDirectives === undefined ? undefined : staticServerHttpHeadersWriter(\n new MapHttpHeaders()\n .add('permissions-policy', policyDirectives));\n return async (exchange: ServerWebExchange) => {\n if (delegate !== undefined) {\n await delegate(exchange);\n }\n }\n}\nconst contentSecurityPolicyServerHttpHeadersWriter = (policyDirectives?: string, reportOnly?: boolean) => {\n const headerName = reportOnly ? 'content-security-policy-report-only' : 'content-security-policy';\n const delegate = policyDirectives === undefined ? undefined : staticServerHttpHeadersWriter(\n new MapHttpHeaders()\n .add(headerName, policyDirectives));\n return async (exchange: ServerWebExchange) => {\n if (delegate !== undefined) {\n await delegate(exchange);\n }\n }\n};\n\ntype ReferrerPolicy =\n 'no-referrer'\n | 'no-referrer-when-downgrade'\n | 'origin'\n | 'origin-when-cross-origin'\n | 'same-origin'\n | 'strict-origin'\n | 'strict-origin-when-cross-origin'\n | 'unsafe-url';\nconst refererPolicyServerHttpHeadersWriter = (policy: ReferrerPolicy = 'no-referrer') => {\n return staticServerHttpHeadersWriter(\n new MapHttpHeaders()\n .add('referer-policy', policy));\n}\n\ntype CrossOriginOpenerPolicy = 'unsafe-none' | 'same-origin' | 'same-origin-allow-popups';\nconst crossOriginOpenerPolicyServerHttpHeadersWriter = (policy?: CrossOriginOpenerPolicy) => {\n const delegate = policy === undefined ? undefined : staticServerHttpHeadersWriter(\n new MapHttpHeaders()\n .add('cross-origin-opener-policy', policy));\n return async (exchange: ServerWebExchange) => {\n if (delegate !== undefined) {\n await delegate(exchange);\n }\n }\n}\n\ntype CrossOriginEmbedderPolicy = 'unsafe-none' | 'require-corp';\nconst crossOriginEmbedderPolicyServerHttpHeadersWriter = (policy?: CrossOriginEmbedderPolicy) => {\n const delegate = policy === undefined ? undefined : staticServerHttpHeadersWriter(\n new MapHttpHeaders()\n .add('cross-origin-embedder-policy', policy));\n return async (exchange: ServerWebExchange) => {\n if (delegate !== undefined) {\n await delegate(exchange);\n }\n }\n}\n\ntype CrossOriginResourcePolicy = 'same-origin' | 'same-site' | 'cross-origin';\nconst crossOriginResourcePolicyServerHttpHeadersWriter = (policy?: CrossOriginResourcePolicy) => {\n const delegate = policy === undefined ? undefined : staticServerHttpHeadersWriter(\n new MapHttpHeaders()\n .add('cross-origin-resource-policy', policy));\n return async (exchange: ServerWebExchange) => {\n if (delegate !== undefined) {\n await delegate(exchange);\n }\n }\n}\n\nconst compositeServerHttpHeadersWriter = (\n ...writers: ServerHttpHeadersWriter[]\n): ServerHttpHeadersWriter => {\n return async (exchange: ServerWebExchange) => {\n for (const writer of writers) {\n await writer(exchange);\n }\n }\n}\n\nexport default function headers(opts?: {\n cache?: { disabled?: boolean }\n contentType?: { disabled?: boolean },\n frameOptions?: { disabled?: boolean, mode?: FrameOptionsMode },\n hsts?: { disabled?: boolean, maxAge?: number, includeSubDomains?: boolean, preload?: boolean },\n xss?: { disabled?: boolean, headerValue?: XssProtectionHeaderValue },\n permissionsPolicy?: { disabled?: boolean, policyDirectives?: string },\n contentSecurityPolicy?: { disabled?: boolean, policyDirectives?: string, reportOnly?: boolean },\n refererPolicy?: { disabled?: boolean, policy?: ReferrerPolicy },\n crossOriginOpenerPolicy?: { disabled?: boolean, policy?: CrossOriginOpenerPolicy },\n crossOriginEmbedderPolicy?: { disabled?: boolean, policy?: CrossOriginEmbedderPolicy },\n crossOriginResourcePolicy?: { disabled?: boolean, policy?: CrossOriginResourcePolicy }\n writers?: ServerHttpHeadersWriter[]\n}) {\n const writers: ServerHttpHeadersWriter[] = [];\n if (!opts?.cache?.disabled) {\n writers.push(cacheControlServerHttpHeadersWriter());\n }\n if (!opts?.contentType?.disabled) {\n writers.push(contentTypeServerHttpHeadersWriter());\n }\n if (!opts?.hsts?.disabled) {\n writers.push(strictTransportSecurityServerHttpHeadersWriter(opts?.hsts?.maxAge ?? 365 * 24 * 60 * 60, opts?.hsts?.includeSubDomains ?? true, opts?.hsts?.preload ?? false));\n }\n if (!opts?.frameOptions?.disabled) {\n writers.push(frameOptionsServerHttpHeadersWriter(opts?.frameOptions?.mode ?? 'DENY'));\n }\n if (!opts?.xss?.disabled) {\n writers.push(xssProtectionServerHttpHeadersWriter(opts?.xss?.headerValue ?? '0'));\n }\n if (!opts?.permissionsPolicy?.disabled) {\n writers.push(permissionsPolicyServerHttpHeadersWriter(opts?.permissionsPolicy?.policyDirectives));\n }\n if (!opts?.contentSecurityPolicy?.disabled) {\n writers.push(contentSecurityPolicyServerHttpHeadersWriter(opts?.contentSecurityPolicy?.policyDirectives ?? \"default-src 'self'\", opts?.contentSecurityPolicy?.reportOnly));\n }\n if (!opts?.refererPolicy?.disabled) {\n writers.push(refererPolicyServerHttpHeadersWriter(opts?.refererPolicy?.policy ?? 'no-referrer'));\n }\n if (!opts?.crossOriginOpenerPolicy?.disabled) {\n writers.push(crossOriginOpenerPolicyServerHttpHeadersWriter(opts?.crossOriginOpenerPolicy?.policy));\n }\n if (!opts?.crossOriginEmbedderPolicy?.disabled) {\n writers.push(crossOriginEmbedderPolicyServerHttpHeadersWriter(opts?.crossOriginEmbedderPolicy?.policy));\n }\n if (!opts?.crossOriginResourcePolicy?.disabled) {\n writers.push(crossOriginResourcePolicyServerHttpHeadersWriter(opts?.crossOriginResourcePolicy?.policy));\n }\n if (opts?.writers) {\n writers.push(...opts.writers);\n }\n const writer = compositeServerHttpHeadersWriter(...writers);\n\n return async (exchange: ServerWebExchange, next: () => Promise<void>) => {\n await writer(exchange);\n await next();\n }\n}\n", "import {\n AuthenticationServiceError,\n type ServerAuthenticationEntryPoint,\n type ServerAuthenticationFailureHandler\n} from './types.ts';\n\nexport const serverAuthenticationEntryPointFailureHandler = (opts: {\n entryPoint: ServerAuthenticationEntryPoint,\n rethrowAuthenticationServiceError?: boolean\n}): ServerAuthenticationFailureHandler => {\n const entryPoint = opts.entryPoint;\n const rethrowAuthenticationServiceError = opts?.rethrowAuthenticationServiceError ?? true;\n return async ({exchange}, error) => {\n if (!rethrowAuthenticationServiceError) {\n return entryPoint(exchange, error);\n }\n if (!(error instanceof AuthenticationServiceError)) {\n return entryPoint(exchange, error);\n }\n throw error;\n\n };\n\n\n}\n", "import type { ServerAuthenticationEntryPoint } from './types.ts';\nimport { HttpStatus } from '../../http/status.ts';\n\nconst DEFAULT_REALM = 'Realm';\nconst createHeaderValue = (realm: string): string => {\n return `Basic realm=\"${realm}\"`;\n}\n\nexport const httpBasicEntryPoint = (opts?: { realm?: string }): ServerAuthenticationEntryPoint => {\n const headerValue = createHeaderValue(opts?.realm ?? DEFAULT_REALM);\n return async (exchange, _error) => {\n const {response} = exchange;\n response.setStatusCode(HttpStatus.UNAUTHORIZED);\n response.headers.set('WWW-Authenticate', headerValue);\n };\n}\n", "import type { AbstractAuthenticationToken, AuthenticationConverter } from './types.ts';\n\nconst BASIC = 'Basic ';\n\nexport const httpBasicAuthenticationConverter = (opts?: {credentialsEncoding?: BufferEncoding}): AuthenticationConverter => {\n const credentialsEncoding = opts?.credentialsEncoding ?? 'utf-8';\n\n return async (exchange): Promise<AbstractAuthenticationToken | undefined> => {\n const { request } = exchange;\n const authorization = request.headers.one(\"authorization\");\n if (!authorization || !(/basic/i).test(authorization.substring(0,))) {\n return;\n }\n const credentials = authorization.length <= BASIC.length ? '' : authorization.substring(BASIC.length);\n const decoded = Buffer.from(credentials, 'base64').toString(credentialsEncoding);\n const parts = decoded.split(\":\", 2);\n if (parts.length !== 2) {\n return undefined;\n }\n const principal = parts[0];\n let erasableCredentials: string | null = parts[1];\n return {\n type: 'UsernamePassword',\n authenticated: false,\n principal,\n credentials: erasableCredentials,\n name: principal,\n eraseCredentials: () => {\n erasableCredentials = null;\n },\n };\n }\n\n}\n", "import type { Authentication } from './types';\nimport { AsyncLocalStorage } from 'node:async_hooks';\n\nexport interface SecurityContext {\n authentication?: Authentication;\n}\n\nexport class AsyncStorageSecurityContextHolder {\n private static hasSecurityContext(storage: AsyncLocalStorage<{\n securityContext?: Promise<SecurityContext>\n }>): boolean {\n return storage.getStore()?.securityContext !== undefined;\n }\n\n private static async getSecurityContext(storage: AsyncLocalStorage<{\n securityContext?: Promise<SecurityContext>\n }>): Promise<SecurityContext | undefined> {\n return await storage.getStore()?.securityContext;\n }\n\n public static clearSecurityContext(storage: AsyncLocalStorage<{ securityContext?: Promise<SecurityContext> }>) {\n delete storage.getStore()?.securityContext;\n }\n\n public static withSecurityContext(securityContext: Promise<SecurityContext>) {\n return (storage: AsyncLocalStorage<{ securityContext?: Promise<SecurityContext> }> = new AsyncLocalStorage<{\n securityContext?: Promise<SecurityContext>\n }>()) => {\n storage.getStore()!.securityContext = securityContext;\n return storage;\n };\n }\n\n public static withAuthentication(authentication: Authentication) {\n return AsyncStorageSecurityContextHolder.withSecurityContext(Promise.resolve({authentication}));\n }\n\n public static async getContext(storage: AsyncLocalStorage<{ securityContext?: Promise<SecurityContext> }>): Promise<SecurityContext | undefined> {\n if (AsyncStorageSecurityContextHolder.hasSecurityContext(storage)) {\n return AsyncStorageSecurityContextHolder.getSecurityContext(storage);\n }\n }\n}\n\n", "import { type Authentication } from './types.ts';\nimport {\n type AuthenticationConverter,\n AuthenticationError,\n type AuthenticationManager,\n type ServerAuthenticationFailureHandler,\n type ServerAuthenticationSuccessHandler\n} from './types.ts';\nimport { serverAuthenticationEntryPointFailureHandler } from './entry-point-failure-handler.ts';\nimport { httpBasicEntryPoint } from './http-basic-entry-point.ts';\nimport { httpBasicAuthenticationConverter } from './http-basic-converter.ts';\nimport { anyExchange, type ServerWebExchangeMatcher } from '../util/matchers.ts';\nimport { AsyncStorageSecurityContextHolder, type SecurityContext } from './security-context.ts';\nimport { AsyncLocalStorage } from 'node:async_hooks';\nimport type { ServerWebExchange } from '../../../types/web/server'\n\nasync function authenticate(exchange: ServerWebExchange,\n next: () => Promise<void>,\n token: Authentication,\n managerResolver: (exchange: ServerWebExchange) => Promise<AuthenticationManager | undefined>,\n successHandler: ServerAuthenticationSuccessHandler,\n storage: AsyncLocalStorage<{ securityContext?: Promise<SecurityContext> }>): Promise<void> {\n const authManager = await managerResolver(exchange);\n const authentication = await authManager?.(token);\n if (authentication === undefined) {\n throw new Error(\"No authentication manager found for the exchange\");\n }\n try {\n await onAuthenticationSuccess(authentication, {exchange, next}, successHandler, storage);\n } catch (e) {\n if (e instanceof AuthenticationError) {\n // todo debug log\n }\n throw e;\n }\n}\n\nasync function onAuthenticationSuccess(authentication: Authentication,\n filterExchange: {exchange: ServerWebExchange, next: () => Promise<void>},\n successHandler: ServerAuthenticationSuccessHandler,\n storage: AsyncLocalStorage<{ securityContext?: Promise<SecurityContext> }>): Promise<void> {\n AsyncStorageSecurityContextHolder.withAuthentication(authentication)(storage);\n await successHandler(filterExchange, authentication);\n\n}\n\nexport type AuthenticationFilterOptions = {\n storage: AsyncLocalStorage<{securityContext?: Promise<SecurityContext>}>\n managerResolver?: (exchange: ServerWebExchange) => Promise<AuthenticationManager | undefined>,\n manager?: AuthenticationManager,\n successHandler?: ServerAuthenticationSuccessHandler,\n // converter is a function that converts the exchange to an authentication object\n converter?: AuthenticationConverter,\n failureHandler?: ServerAuthenticationFailureHandler\n // matcher is a function that checks if the exchange must be authenticated\n matcher?: ServerWebExchangeMatcher,\n};\n\nexport default function authenticationFilter(opts: AuthenticationFilterOptions) {\n const auth = {\n matcher: anyExchange,\n successHandler: async({next}) => {\n await next();\n },\n converter: httpBasicAuthenticationConverter({}),\n failureHandler: serverAuthenticationEntryPointFailureHandler({ entryPoint: httpBasicEntryPoint({}) }),\n ...opts\n };\n let managerResolver = auth.managerResolver;\n if (managerResolver === undefined && auth.manager !== undefined) {\n const manager: AuthenticationManager = auth.manager;\n managerResolver = async (_exchange: ServerWebExchange) => {\n return manager;\n };\n }\n if (managerResolver === undefined) {\n throw new Error(\"Authentication filter requires a managerResolver or a manager\");\n }\n return async (exchange: ServerWebExchange, next: () => Promise<void>): Promise<void> => {\n const matchResult = await auth.matcher(exchange);\n const token = matchResult.match ? await auth.converter(exchange) : undefined;\n if (token === undefined) {\n await next();\n return;\n }\n\n try {\n await authenticate(exchange, next, token, managerResolver, auth.successHandler, auth.storage);\n\n } catch (error) {\n if (error instanceof AuthenticationError) {\n await auth.failureHandler({exchange, next}, error);\n return;\n }\n throw error; // Re-throw the error to be handled by the next middleware or error handler\n }\n };\n}\n", "import type { AuthenticationError, ServerAuthenticationEntryPoint } from './types.ts';\nimport { HttpStatus } from \"../../http/status.ts\";\n\nexport const httpStatusEntryPoint = (opts: {\n httpStatus: HttpStatus\n}): ServerAuthenticationEntryPoint => {\n return async (exchange, _error: AuthenticationError) => {\n const response = exchange.response;\n response.setStatusCode(opts.httpStatus);\n };\n}\n", "import {AuthenticationError, type ServerAuthenticationEntryPoint} from './types.ts';\nimport {type ServerWebExchangeMatcher} from '../util/matchers.ts';\nimport {HttpStatus} from '../../http/status.ts';\nimport getLogger from '../../logger.ts';\nimport type {ServerWebExchange} from '../../../types/web/server';\n\nconst logger = getLogger('auth.entry-point');\n\nexport const delegatingEntryPoint = (opts: {\n entryPoints: Array<[ServerWebExchangeMatcher, ServerAuthenticationEntryPoint]>;\n defaultEntryPoint: ServerAuthenticationEntryPoint;\n}): ServerAuthenticationEntryPoint => {\n const defaultEntryPoint = opts.defaultEntryPoint ?? (async ({response}, _error) => {\n response.setStatusCode(HttpStatus.UNAUTHORIZED);\n await response.end();\n });\n return async (exchange: ServerWebExchange, error: AuthenticationError) => {\n for (const [matcher, entryPoint] of opts.entryPoints) {\n if (logger.enabledFor('debug')) {\n logger.debug(`trying to match using: ${matcher}`);\n }\n const match = await matcher(exchange);\n if (match.match) {\n if (logger.enabledFor('debug')) {\n logger.debug(`match found. using default entry point ${entryPoint}`);\n }\n return entryPoint(exchange, error);\n }\n }\n if (logger.enabledFor('debug')) {\n logger.debug(`no match found. using default entry point ${defaultEntryPoint}`);\n }\n return defaultEntryPoint(exchange, error);\n };\n}\n", "import type {Authentication, ServerAuthenticationSuccessHandler} from './types.ts';\n\nexport const delegatingSuccessHandler = (handlers: Array<ServerAuthenticationSuccessHandler>) => {\n\n return async ({exchange, next}, authentication: Authentication) => {\n for (const handler of handlers) {\n await handler({exchange, next}, authentication);\n }\n };\n}\n", "import authenticationFilter from './authentication-filter.ts';\nimport { serverAuthenticationEntryPointFailureHandler } from './entry-point-failure-handler.ts';\nimport type {\n AuthenticationManager,\n ServerAuthenticationEntryPoint,\n ServerAuthenticationFailureHandler,\n ServerAuthenticationSuccessHandler\n} from './types.ts';\nimport { httpStatusEntryPoint } from './http-status-entry-point.ts';\nimport { httpBasicEntryPoint } from './http-basic-entry-point.ts';\nimport { delegatingEntryPoint } from './delegating-entry-point.ts';\nimport { httpBasicAuthenticationConverter } from './http-basic-converter.ts';\nimport { delegatingSuccessHandler } from './delegating-success-handler.ts';\nimport type { SecurityContext } from './security-context.ts';\nimport type { MatchResult, ServerWebExchangeMatcher } from '../util/matchers.ts';\nimport * as matchers from '../util/matchers.ts';\nimport { HttpStatus } from '../../http/status.ts';\nimport { AsyncLocalStorage } from 'node:async_hooks';\nimport type { ServerWebExchange } from '../../../types/web/server';\n\nexport default function httpBasic(opts: {\n readonly storage: AsyncLocalStorage<{securityContext?: Promise<SecurityContext>}>\n readonly manager: AuthenticationManager;\n readonly entryPoint?: ServerAuthenticationEntryPoint;\n readonly failureHandler?: ServerAuthenticationFailureHandler;\n readonly successHandlers?: ServerAuthenticationSuccessHandler[];\n defaultEntryPoints: Array<[ServerWebExchangeMatcher, ServerAuthenticationEntryPoint]>;\n defaultSuccessHandlers: ServerAuthenticationSuccessHandler[];\n}) {\n\n const xhrMatcher: ServerWebExchangeMatcher = async (exchange: ServerWebExchange): Promise<MatchResult> => {\n const headers = exchange.request.headers;\n const h = headers.list('X-Requested-With');\n if (h.includes('XMLHttpRequest')) {\n return matchers.match();\n }\n return matchers.NO_MATCH;\n }\n\n const defaultEntryPoint = delegatingEntryPoint({\n entryPoints: [[xhrMatcher, httpStatusEntryPoint({httpStatus: HttpStatus.UNAUTHORIZED})]],\n defaultEntryPoint: httpBasicEntryPoint({})\n });\n\n const entryPoint = opts.entryPoint ?? defaultEntryPoint;\n\n const manager = opts.manager;\n\n const restMatcher = matchers.mediaType({\n mediaTypes: [\n 'application/atom+xml',\n 'application/x-www-form-urlencoded',\n 'application/json',\n 'application/octet-stream',\n 'application/xml',\n 'multipart/form-data',\n 'text/xml'\n ],\n ignoredMediaTypes: ['*/*']\n });\n\n const notHtmlMatcher = matchers.not(matchers.mediaType({mediaTypes: ['text/html']}));\n const restNoHtmlMatcher = matchers.and([notHtmlMatcher, restMatcher]);\n const preferredMatcher = matchers.or([xhrMatcher, restNoHtmlMatcher]);\n opts.defaultEntryPoints.push([preferredMatcher, entryPoint]);\n const failureHandler = opts.failureHandler ?? serverAuthenticationEntryPointFailureHandler({entryPoint});\n const successHandler = delegatingSuccessHandler(opts.successHandlers ?? opts.defaultSuccessHandlers);\n const converter = httpBasicAuthenticationConverter({});\n return authenticationFilter({\n storage: opts.storage,\n manager,\n failureHandler,\n successHandler,\n converter\n });\n}\n\n", "import { HttpStatus } from '../../../http/status.ts';\n\nexport type OAuth2Error = {\n readonly errorCode: string\n readonly description?: string\n readonly uri?: string\n}\n\nexport type BearerTokenError = OAuth2Error & {\n readonly httpStatus: HttpStatus\n readonly scope?: string\n}\n\nexport const BearerTokenErrorCodes = {\n invalid_request: 'invalid_request',\n invalid_token: 'invalid_token',\n insufficient_scope: 'insufficient_scope',\n}\n\nconst DEFAULT_URI = \"https://tools.ietf.org/html/rfc6750#section-3.1\";\n\nexport function invalidToken(message: string): BearerTokenError {\n return {\n errorCode: BearerTokenErrorCodes.invalid_token,\n httpStatus: HttpStatus.UNAUTHORIZED,\n description: message,\n uri: DEFAULT_URI\n };\n}\n\nexport function invalidRequest(message: string): BearerTokenError {\n return {\n errorCode: BearerTokenErrorCodes.invalid_request,\n httpStatus: HttpStatus.BAD_REQUEST,\n description: message,\n uri: DEFAULT_URI\n };\n}\n\nexport function insufficientScope(message: string, scope?: string): BearerTokenError {\n return {\n errorCode: BearerTokenErrorCodes.insufficient_scope,\n httpStatus: HttpStatus.FORBIDDEN,\n description: message,\n uri: DEFAULT_URI,\n scope\n };\n}\n", "import { type Authentication, type AuthenticationConverter, AuthenticationError } from '../types.ts';\nimport { invalidRequest, invalidToken, type OAuth2Error } from './token-error.ts';\nimport type { ReadonlyHttpHeaders } from '../../../../types/web/http';\nimport type { ServerHttpRequest, ServerWebExchange } from '../../../../types/web/server';\n\nconst ACCESS_TOKEN_PARAMETER_NAME = 'access_token';\nconst authorizationPattern = /^Bearer\\s+(?<token>[a-zA-Z0-9-._~+/]+=*)$/i;\n\nexport class Oauth2AuthenticationError extends AuthenticationError {\n readonly error: OAuth2Error;\n\n constructor(error: string | OAuth2Error, message?: string, options?: ErrorOptions) {\n super(message ?? (typeof error === 'string' ? undefined : error.description), options);\n this.error = typeof error === 'string' ? {errorCode: error} : error;\n }\n}\n\nexport type BearerTokenAuthenticationToken = Authentication & {\n type: 'BearerToken';\n token: string;\n}\n\nexport const isBearerTokenAuthenticationToken = (authentication: Authentication): authentication is BearerTokenAuthenticationToken => {\n return authentication.type === 'BearerToken';\n}\n\nconst serverBearerTokenAuthenticationConverter = (opts?: {headerName?: string, uriQueryParameter?: boolean, formEncodedBodyParameter?: boolean }): AuthenticationConverter => {\n return async (exchange: ServerWebExchange) => {\n const {request} = exchange;\n return Promise.all<string[] | undefined>([\n resolveFromAuthorizationHeader(request.headers, opts?.headerName).then((token?: string) => token !== undefined ? [token] : undefined),\n resolveFromQueryString(request, opts?.uriQueryParameter),\n resolveFromBody(exchange, opts?.formEncodedBodyParameter)\n ])\n .then(rs => rs.filter(r => r !== undefined).flat(1))\n .then(resolveToken)\n .then(token => {\n if (token) return {authenticated: false, type: 'BearerToken', token};\n });\n }\n}\n\nasync function resolveToken(accessTokens: string[]) {\n if (accessTokens.length === 0) {\n return;\n }\n if (accessTokens.length > 1) {\n const error = invalidRequest('Found multiple access tokens in the request');\n throw new Oauth2AuthenticationError(error);\n }\n\n const accessToken = accessTokens[0];\n if (!accessToken || accessToken.length === 0) {\n const error = invalidRequest('The requested access token parameter is an empty string');\n throw new Oauth2AuthenticationError(error);\n }\n return accessToken;\n}\n\nasync function resolveFromAuthorizationHeader(headers: ReadonlyHttpHeaders, headerName: string = 'authorization'): Promise<string | undefined> {\n const authorization = headers.one(headerName);\n if (!authorization || !(/bearer/i).test(authorization.substring(0,))) {\n return;\n }\n const match = authorizationPattern.exec(authorization);\n if (match === null) {\n const error = invalidToken('Bearer token is malformed');\n throw new Oauth2AuthenticationError(error);\n }\n return match.groups?.token;\n}\n\nasync function resolveTokens(parameters: URLSearchParams): Promise<string[] | undefined> {\n const accessTokens = parameters.getAll(ACCESS_TOKEN_PARAMETER_NAME);\n if (accessTokens.length === 0) {\n return;\n }\n return accessTokens;\n}\n\nasync function resolveFromQueryString(request: ServerHttpRequest, allow = false): Promise<string[] | undefined> {\n if (!allow || request.method !== 'GET') {\n return;\n }\n return resolveTokens(request.URL.searchParams);\n}\n\nasync function resolveFromBody(exchange: ServerWebExchange, allow = false): Promise<string[] | undefined> {\n const {request} = exchange;\n if (!allow\n || ('application/x-www-form-urlencoded' !== request.headers.one('content-type'))\n || request.method !== 'POST') {\n return;\n }\n const parameters = await exchange.request.formData();\n if (parameters) {\n return resolveTokens(parameters);\n }\n}\n\nexport default serverBearerTokenAuthenticationConverter;\n", "import { AuthenticationError, type ServerAuthenticationEntryPoint } from '../types.ts';\nimport { Oauth2AuthenticationError } from './token-converter.ts';\nimport type { BearerTokenError, OAuth2Error } from './token-error.ts';\nimport { HttpStatus } from '../../../http/status.ts';\n\nfunction computeWWWAuthenticate(parameters: Map<string, string>) {\n let wwwAuthenticate = 'Bearer';\n if (parameters.size !== 0) {\n wwwAuthenticate += ' ';\n let i = 0;\n for (const [key, value] of parameters) {\n wwwAuthenticate += `${key}=\"${value}\"`;\n if (i !== parameters.size - 1) {\n wwwAuthenticate += ', ';\n }\n i++;\n }\n }\n return wwwAuthenticate;\n}\n\nconst isBearerTokenError = (error: OAuth2Error): error is BearerTokenError => {\n return (error as BearerTokenError).httpStatus !== undefined;\n}\n\nfunction getStatus(authError: AuthenticationError): HttpStatus {\n if (authError instanceof Oauth2AuthenticationError) {\n const {error} = authError;\n if (isBearerTokenError(error)) {\n return error.httpStatus;\n }\n }\n return HttpStatus.UNAUTHORIZED;\n}\n\nfunction createParameters(authError: AuthenticationError, realm?: string) {\n const parameters = new Map<string, string>();\n if (realm) {\n parameters.set('realm', realm);\n }\n if (authError instanceof Oauth2AuthenticationError) {\n const {error} = authError;\n parameters.set('error', error.errorCode);\n if (error.description) {\n parameters.set('error_description', error.description);\n }\n if (error.uri) {\n parameters.set('error_uri', error.uri);\n }\n if (isBearerTokenError(error) && error.scope) {\n parameters.set('scope', error.scope);\n }\n }\n return parameters;\n}\n\nconst bearerTokenServerAuthenticationEntryPoint = (opts?: { realmName?: string }): ServerAuthenticationEntryPoint => {\n return async (exchange, error) => {\n const status = getStatus(error);\n const parameters = createParameters(error, opts?.realmName)\n const wwwAuthenticate = computeWWWAuthenticate(parameters);\n const {response} = exchange;\n response.headers.set('WWW-Authenticate', wwwAuthenticate);\n response.setStatusCode(status);\n await response.end();\n };\n}\n\nexport default bearerTokenServerAuthenticationEntryPoint;\n", "import {\n type AbstractAuthenticationToken,\n type Authentication,\n type AuthenticationManager,\n AuthenticationServiceError\n} from '../types.ts';\nimport { invalidToken } from './token-error.ts';\nimport { isBearerTokenAuthenticationToken, Oauth2AuthenticationError } from './token-converter.ts';\n\nexport interface Jwt extends OAuth2Token {\n readonly subject?: string\n\n getClaimAsString(claim: string): string | undefined\n}\n\nexport type OAuth2Token = {\n readonly tokenValue: string;\n readonly issuedAt?: Date;\n readonly expiresAt?: Date;\n}\n\ntype AbstractOAuth2TokenAuthenticationToken<T extends OAuth2Token> = AbstractAuthenticationToken & {\n // token: T;\n}\n\n\nconst jwtAuthConverter = (opts?: { principalClaimName?: string}): (jwt: Jwt) => AbstractAuthenticationToken => {\n const principalClaimName = opts?.principalClaimName ?? 'sub';\n\n return (jwt: Jwt) => {\n const name = jwt.getClaimAsString(principalClaimName)!;\n const authentication: (AbstractOAuth2TokenAuthenticationToken<any> & { type: 'JwtToken' }) = { type: 'JwtToken', authenticated: true, name };\n return authentication;\n };\n}\n\nconst asyncJwtConverter = (converter: (jwt: Jwt) => Authentication): (jwt: Jwt) => Promise<Authentication> => {\n return async (jwt: Jwt) => {\n return converter(jwt);\n };\n};\n\nexport class JwtError extends Error {}\nexport class BadJwtError extends JwtError {}\n\n\nfunction onError(error: JwtError) {\n if (error instanceof BadJwtError) {\n return new Oauth2AuthenticationError(invalidToken(error.message), error.message, {cause: error});\n }\n throw new AuthenticationServiceError(error.message, {cause: error});\n\n}\n\nexport default function jwtAuthManager(opts: {\n decoder: (token: string) => Promise<Jwt>\n authConverter?: (jwt: Jwt) => Promise<Authentication>\n}): AuthenticationManager {\n const decoder = opts.decoder;\n const authConverter = opts.authConverter ?? asyncJwtConverter(jwtAuthConverter({}));\n return async (authentication) => {\n if (isBearerTokenAuthenticationToken(authentication)) {\n const token = authentication.token;\n try {\n const jwt = await decoder(token);\n return await authConverter(jwt);\n } catch (e) {\n if (e instanceof JwtError) {\n throw onError(e);\n }\n throw e;\n }\n }\n }\n}\n", "import authenticationFilter from './authentication-filter.ts';\nimport type {\n Authentication,\n AuthenticationConverter,\n AuthenticationManager,\n ServerAuthenticationEntryPoint,\n ServerAuthenticationFailureHandler\n} from './types.ts';\nimport serverBearerTokenAuthenticationConverter from './oauth2/token-converter.ts';\nimport { serverAuthenticationEntryPointFailureHandler } from './entry-point-failure-handler.ts';\nimport bearerTokenServerAuthenticationEntryPoint from './oauth2/token-entry-point.ts';\nimport jwtAuthManager, { type Jwt } from './oauth2/jwt-auth-manager.ts';\nimport type { SecurityContext } from './security-context.ts';\nimport { AsyncLocalStorage } from 'node:async_hooks';\nimport type { ServerWebExchange } from '../../../types/web/server';\n\nexport default function resourceServer(opts: {\n readonly storage: AsyncLocalStorage<{securityContext?: Promise<SecurityContext>}>,\n converter?: AuthenticationConverter,\n failureHandler?: ServerAuthenticationFailureHandler,\n entryPoint?: ServerAuthenticationEntryPoint,\n managerResolver?: (exchange: ServerWebExchange) => Promise<AuthenticationManager | undefined>,\n jwt?: {\n manager?: AuthenticationManager,\n decoder: (token: string) => Promise<Jwt>,\n authConverter?: (jwt: Jwt) => Promise<Authentication>\n }\n}): (exchange: ServerWebExchange, next: () => Promise<void>) => Promise<void> {\n const entryPoint = opts.entryPoint ?? bearerTokenServerAuthenticationEntryPoint({});\n const converter = opts?.converter ?? serverBearerTokenAuthenticationConverter({});\n const failureHandler = opts.failureHandler ?? serverAuthenticationEntryPointFailureHandler({entryPoint})\n if (opts.managerResolver!== undefined) {\n return authenticationFilter({\n storage: opts.storage,\n converter,\n failureHandler,\n managerResolver: opts.managerResolver,\n });\n }\n if (opts.jwt !== undefined) {\n\n const manager = opts.jwt.manager ?? jwtAuthManager(opts.jwt);\n return authenticationFilter({\n storage: opts.storage,\n converter,\n failureHandler,\n managerResolver: async (_exchange: ServerWebExchange) => {\n return manager;\n },\n });\n }\n throw new Error(\"Invalid resource server configuration: either managerResolver or jwt must be provided\");\n}\n", "import {\n type Authentication,\n type AuthenticationManager,\n AuthorizationDecision,\n DefaultAuthorizationManager,\n type ServerAuthenticationEntryPoint,\n type ServerAuthenticationSuccessHandler\n} from './types.ts';\nimport headers from './http-headers.ts';\nimport httpBasic from './http-basic.ts';\nimport resourceServer from './oauth2-resource-server.ts';\nimport serverBearerTokenAuthenticationConverter from './oauth2/token-converter.ts';\nimport bearerTokenServerAuthenticationEntryPoint from './oauth2/token-entry-point.ts';\nimport { BadJwtError, type Jwt, JwtError } from './oauth2/jwt-auth-manager.ts';\nimport { jwtVerifier, JwtVerifyError } from '@interopio/gateway/jose/jwt';\nimport {\n anyExchange,\n match,\n NO_MATCH,\n type ServerWebExchangeMatcher,\n type ServerWebExchangeMatcherEntry\n} from '../util/matchers.ts';\nimport { errorFilter } from './error-filter.ts';\nimport { delegatingEntryPoint } from './delegating-entry-point.ts';\nimport delegatingAuthorizationManager from './delegating-authorization-manager.ts';\nimport authorizationFilter from './authorization-filter.ts';\nimport { exchangeFilter } from './exchange-filter.ts';\nimport type { SecurityContext } from './security-context.ts';\nimport cors, { type CorsConfigSource } from '../cors.ts';\nimport type { Middleware } from '../types.ts';\nimport { type AsyncLocalStorage } from 'node:async_hooks';\nimport type { ServerWebExchange } from '../../../types/web/server';\nimport x509 from './x509.ts';\nimport { subjectX500PrincipalExtractor } from './preauth/x509.ts';\nimport { userDetailsServiceAuthenticationManager } from './users.ts';\nimport type { UserDetailsPasswordService, UserDetailsService } from './users/types.ts';\n\nexport type HttpSecurityConfig = {\n authorize?: Array<[\n 'any-exchange' | ServerWebExchangeMatcher,\n ( { access: 'permitted' | 'denied' | 'authenticated' }\n | { access: 'has-any-authority', authorities: string[] }\n | { access: 'has-ip-address', address: string })\n ]>,\n headers?: {\n disabled?: boolean\n xss?: { disabled?: boolean }\n },\n x509?: {\n disabled?: boolean\n /** Extract principal from Subject Alternative Name. Use 'email' to extract from email SAN. If undefined, uses subject (default). */\n principalAltName?: 'email'\n }\n cors?: {\n disabled?: boolean\n }\n basic?: {\n disabled?: boolean\n realm?: string\n },\n jwt?: {\n disabled?: boolean;\n issuerUri?: string; // base URI for the issuer, e.g. 'https://example.com'\n issuer?: string;\n audience?: string | string[]; // audience for the JWT, e.g. 'https://example.com/api'\n }\n}\n\nconst filterOrder = {\n first: Number.MAX_SAFE_INTEGER,\n http_headers: 1 * 100,\n https_redirect: 2 * 100,\n cors: 3 * 100,\n http_basic: 6 * 100,\n authentication: 8 * 100,\n security_context_server_web_exchange: 15 * 100,\n error_translation: 18 * 100,\n authorization: 19 * 100,\n last: Number.MAX_SAFE_INTEGER\n}\nconst filterOrderSymbol = Symbol.for(\"filterOrder\");\n\nexport default (config: HttpSecurityConfig,\n context: {\n storage: AsyncLocalStorage<{ securityContext?: Promise<SecurityContext> }>\n corsConfigSource?: CorsConfigSource,\n userDetailsService?: UserDetailsService,\n userDetailsPasswordService?: UserDetailsPasswordService,\n authenticationManager?: AuthenticationManager,\n }): Middleware => {\n\n const getService = <T>(name: string, defaultService?: T): T => {\n if (context === undefined) {\n return defaultService as T; // will not throw but return defaultService which may be undefined\n }\n if (name === 'UserDetailsService' && context.userDetailsService !== undefined) {\n return context.userDetailsService as T;\n }\n if (name === 'AuthenticationManager' && context.authenticationManager !== undefined) {\n return context.authenticationManager as T;\n }\n if (defaultService !== undefined) {\n return defaultService;\n }\n throw new Error(`No service registered with name: ${name}`);\n };\n\n const authenticationManager = (): AuthenticationManager | undefined => {\n if (context.authenticationManager !== undefined) {\n return context.authenticationManager;\n }\n if (context.userDetailsService !== undefined) {\n const manager = userDetailsServiceAuthenticationManager(context.userDetailsService, {\n userDetailsPasswordService: context.userDetailsPasswordService\n });\n return manager;\n }\n }\n\n\n const middleware: Middleware = [];\n\n class ServerHttpSecurity {\n #authenticationEntryPoint?: ServerAuthenticationEntryPoint;\n readonly #defaultEntryPoints: Array<[ServerWebExchangeMatcher, ServerAuthenticationEntryPoint]> = [];\n #authenticationManager?: AuthenticationManager;\n\n set authenticationManager(authenticationManager: AuthenticationManager | undefined) {\n this.#authenticationManager = authenticationManager;\n }\n\n get authenticationEntryPoint(): ServerAuthenticationEntryPoint | undefined {\n if (this.#authenticationEntryPoint !== undefined || this.#defaultEntryPoints.length === 0) {\n return this.#authenticationEntryPoint!;\n }\n if (this.#defaultEntryPoints.length === 1) {\n return this.#defaultEntryPoints[0][1];\n }\n return delegatingEntryPoint({\n entryPoints: this.#defaultEntryPoints,\n defaultEntryPoint: this.#defaultEntryPoints[this.#defaultEntryPoints.length - 1][1]\n });\n }\n\n\n build() {\n if (config.headers !== undefined && config.headers.disabled !== true) {\n const writer = headers(config.headers);\n writer[filterOrderSymbol] = filterOrder.http_headers;\n middleware.push(writer);\n }\n if (config.x509 !== undefined && config.x509.disabled !== true) {\n\n const filter = x509({\n storage: context.storage,\n getService,\n extractor: subjectX500PrincipalExtractor({ principalAltName: config.x509.principalAltName })\n });\n filter[filterOrderSymbol] = filterOrder.authentication;\n middleware.push(filter);\n }\n if (config.cors?.disabled !== true && context.corsConfigSource !== undefined) {\n const filter: (ctx: ServerWebExchange, next: () => Promise<void>) => Promise<void> = cors({corsConfigSource: context.corsConfigSource });\n filter[filterOrderSymbol] = filterOrder.cors;\n middleware.push(filter);\n }\n\n if (config.basic !== undefined && config.basic?.disabled !== true) {\n\n const defaultSuccessHandlers: ServerAuthenticationSuccessHandler[] = [\n async ({exchange: _, next}, _authentication) => {\n return next();\n }\n ];\n\n const filter = httpBasic({\n storage: context.storage,\n manager: this.#authenticationManager!,\n defaultEntryPoints: this.#defaultEntryPoints,\n defaultSuccessHandlers,\n });\n filter[filterOrderSymbol] = filterOrder.http_basic;\n middleware.push(filter);\n }\n if (config.jwt !== undefined && config.jwt.disabled !== true) {\n\n const verifier = jwtVerifier({\n issuerBaseUri: config.jwt.issuerUri,\n issuer: config.jwt.issuer,\n audience: config.jwt.audience\n });\n const decoder = async (token: string): Promise<Jwt> => {\n try {\n const {payload} = await verifier(token);\n return {\n tokenValue: token,\n subject: payload.sub,\n getClaimAsString(claim: string): string | undefined {\n return payload[claim] as string | undefined;\n }\n };\n } catch (e) {\n if (e instanceof JwtVerifyError) {\n throw new BadJwtError(e.message, {cause: e});\n }\n throw new JwtError(\"error occurred while attempting to decoding jwt\", {cause: e});\n }\n }\n\n\n const authenticationConverter = serverBearerTokenAuthenticationConverter({uriQueryParameter: true});\n const authenticationConverterMatcher: ServerWebExchangeMatcher = async (exchange) => {\n try {\n const a = await authenticationConverter(exchange)\n if (a === undefined) {\n return NO_MATCH;\n }\n return match();\n }\n catch (e) {\n return NO_MATCH;\n }\n }\n\n const entryPoint = bearerTokenServerAuthenticationEntryPoint({});\n\n this.#defaultEntryPoints.push([authenticationConverterMatcher, entryPoint]);\n\n const filter = resourceServer({\n storage: context.storage,\n entryPoint: entryPoint,\n converter: authenticationConverter,\n jwt: {decoder}});\n filter[filterOrderSymbol] = filterOrder.authentication;\n middleware.push(filter);\n\n }\n const exchangeF = exchangeFilter({storage: context.storage});\n middleware.push(exchangeF);\n exchangeF[filterOrderSymbol] = filterOrder.security_context_server_web_exchange;\n\n\n if (config.authorize !== undefined) {\n const errorFf = errorFilter({authenticationEntryPoint: this.authenticationEntryPoint});\n errorFf[filterOrderSymbol] = filterOrder.error_translation;\n middleware.push(errorFf)\n const buildAuthorizationManager = (authorize: HttpSecurityConfig['authorize']) => {\n const mappings: ServerWebExchangeMatcherEntry<DefaultAuthorizationManager<{\n exchange: ServerWebExchange\n }>>[] = [];\n let anyExchangeRegistered = false;\n for (const [matcher, access] of authorize ?? []) {\n let serverMatcher: ServerWebExchangeMatcher;\n if (matcher === 'any-exchange') {\n anyExchangeRegistered = true;\n serverMatcher = anyExchange;\n } else if (anyExchangeRegistered) {\n throw new Error(\"Cannot register other matchers after 'any-exchange' matcher\");\n } else {\n serverMatcher = matcher;\n }\n let manager: DefaultAuthorizationManager<{ exchange: ServerWebExchange }>;\n if (access.access === 'permitted') {\n manager = new DefaultAuthorizationManager(async () => new AuthorizationDecision(true));\n manager.toString = () => 'AuthorizationManager[permitted]';\n } else if (access.access === 'denied') {\n manager = new DefaultAuthorizationManager(async () => new AuthorizationDecision(false));\n manager.toString = () => 'AuthorizationManager[denied]';\n } else if (access.access === 'authenticated') {\n manager = new DefaultAuthorizationManager(async (p: Promise<Authentication | undefined>) => {\n const authentication = await p;\n if (authentication !== undefined) {\n return new AuthorizationDecision(authentication.authenticated);\n }\n return new AuthorizationDecision(false);\n });\n manager.toString = () => 'AuthorizationManager[authenticated]';\n } else {\n throw new Error(`Unknown access type: ${JSON.stringify(access)}`);\n }\n mappings.push([serverMatcher, manager]);\n }\n return delegatingAuthorizationManager({mappings});\n }\n const manager = buildAuthorizationManager(config.authorize);\n const filter = authorizationFilter({manager, storage: context.storage});\n filter[filterOrderSymbol] = filterOrder.authorization;\n middleware.push(filter);\n\n }\n\n middleware.sort((a, b) => {\n const aOrder = a[filterOrderSymbol] ?? filterOrder.last;\n const bOrder = b[filterOrderSymbol] ?? filterOrder.last;\n return aOrder - bOrder;\n });\n }\n }\n\n\n const security = new ServerHttpSecurity();\n security.authenticationManager = authenticationManager();\n security.build();\n\n\n return middleware;\n};\n", "import {\n type Authentication,\n AccessDeniedError,\n AuthenticationError,\n InsufficientAuthenticationError,\n type ServerAuthenticationEntryPoint,\n isAuthentication\n} from './types.ts';\nimport { httpBasicEntryPoint } from './http-basic-entry-point.ts';\nimport type { ServerWebExchange } from '../../../types/web/server';\nimport { HttpStatus } from '../../http/status.ts';\n\nasync function commenceAuthentication(exchange: ServerWebExchange, authentication: Authentication | undefined, entryPoint: ServerAuthenticationEntryPoint) {\n const cause = new InsufficientAuthenticationError(`Full authentication is required to access this resource.`);\n const e: AuthenticationError = new AuthenticationError(\"Access Denied\", {cause});\n if (authentication) {\n e.authentication = authentication;\n }\n await entryPoint(exchange, e);\n}\nexport function httpStatusAccessDeniedHandler(httpStatus: HttpStatus) {\n return async (exchange: ServerWebExchange, _error: AccessDeniedError) => {\n exchange.response.setStatusCode(httpStatus);\n exchange.response.headers.set(\"Content-Type\", \"text/plain; charset=utf-8\");\n const buffer = Buffer.from(\"Access Denied\", \"utf-8\");\n exchange.response.headers.set('Content-Length', buffer.length);\n await exchange.response.body(buffer);\n };\n}\n\nexport const errorFilter = (opts: {\n authenticationEntryPoint?: ServerAuthenticationEntryPoint\n}) => {\n const accessDeniedHandler = httpStatusAccessDeniedHandler(HttpStatus.FORBIDDEN);\n const authenticationEntryPoint = opts.authenticationEntryPoint ?? httpBasicEntryPoint();\n return async (exchange: ServerWebExchange, next: () => Promise<void>) => {\n try {\n await next();\n } catch (error) {\n if (error instanceof AccessDeniedError) {\n const principal = await exchange.principal();\n if (!isAuthentication(principal)) {\n await commenceAuthentication(exchange, undefined, authenticationEntryPoint);\n }\n else {\n if (!principal.authenticated) {\n await accessDeniedHandler(exchange, error);\n }\n await commenceAuthentication(exchange, principal, authenticationEntryPoint);\n }\n return;\n }\n throw error;\n }\n };\n}\n", "import type {ServerWebExchangeMatcherEntry} from '../util/matchers.ts';\nimport {type Authentication, AuthorizationDecision, type AuthorizationManager, DefaultAuthorizationManager} from './types.ts';\nimport getLogger from '../../logger.ts';\nimport type {ServerWebExchange} from '../../../types/web/server';\n\nconst logger = getLogger('security.auth');\n\nexport default function delegatingAuthorizationManager(opts: { mappings: Array<ServerWebExchangeMatcherEntry<AuthorizationManager<{ exchange: ServerWebExchange }>>> }) {\n const check = async (authentication: Promise<Authentication | undefined>, exchange: ServerWebExchange): Promise<AuthorizationDecision> => {\n let decision: AuthorizationDecision;\n for (const [matcher, manager] of opts.mappings) {\n if ((await matcher(exchange))?.match) {\n logger.debug(`checking authorization on '${exchange.request.path}' using [${matcher}, ${manager}]`);\n const checkResult = await manager.authorize(authentication, {exchange});\n if (checkResult !== undefined) {\n decision = checkResult;\n break;\n }\n }\n }\n decision ??= new AuthorizationDecision(false);\n return decision;\n\n }\n return new DefaultAuthorizationManager(check);\n}\n", "import { AccessDeniedError, type AuthorizationManager } from './types.ts';\nimport { AsyncStorageSecurityContextHolder, type SecurityContext } from './security-context.ts';\nimport type { AsyncLocalStorage } from 'node:async_hooks';\nimport type { ServerWebExchange } from '../../../types/web/server';\n\nimport getLogger from '../../logger.ts';\n\nconst logger = getLogger('security.auth');\n\nexport default function authorizationFilter(opts: {\n storage: AsyncLocalStorage<{ securityContext?: Promise<SecurityContext> }>,\n manager: AuthorizationManager<ServerWebExchange>\n}) {\n\n const { manager, storage } = opts;\n\n return async (exchange: ServerWebExchange, next: () => Promise<void>) => {\n const promise = AsyncStorageSecurityContextHolder.getContext(storage)\n .then(c => c?.authentication);\n try {\n await manager.verify(promise, exchange);\n if (logger.enabledFor('debug')) {\n logger.debug('authorization successful')\n }\n } catch (error) {\n if (error instanceof AccessDeniedError) {\n if (logger.enabledFor('debug')) {\n logger.debug(`authorization failed: ${error.message}`);\n }\n }\n throw error;\n }\n await next();\n };\n}\n", "import { AsyncStorageSecurityContextHolder, type SecurityContext } from './security-context.ts';\nimport { ServerWebExchangeDecorator } from '../exchange.ts';\nimport type { ServerWebExchange } from '../../../types/web/server';\nimport type { Principal } from '../../../types/auth';\nimport type { AsyncLocalStorage } from 'node:async_hooks';\n\n\nexport class SecurityContextServerWebExchange extends ServerWebExchangeDecorator {\n readonly #context: () => Promise<SecurityContext | undefined>;\n constructor(exchange: ServerWebExchange, context: () => Promise<SecurityContext | undefined>) {\n super(exchange);\n this.#context = context;\n }\n\n async principal<T extends Principal>(): Promise<T | undefined> {\n const context = await this.#context();\n return context?.authentication as (T | undefined);\n }\n}\n\nexport const exchangeFilter = (opts: {storage: AsyncLocalStorage<{ securityContext?: Promise<SecurityContext> }>}) => {\n const storage = opts.storage;\n return async (exchange: ServerWebExchange, next: (exchange: ServerWebExchange) => Promise<void>) => {\n await next(new SecurityContextServerWebExchange(exchange, async () => await AsyncStorageSecurityContextHolder.getContext(storage)));\n }\n}\n", "import type { AbstractAuthenticationToken, AuthenticationConverter } from './types.ts';\nimport type { X509PrincipalExtractor } from './preauth/x509.ts';\nimport type { ServerWebExchange } from '../../../types/web/server';\n\nexport const x509Converter = (opts: { principalExtractor: X509PrincipalExtractor }): AuthenticationConverter => {\n const { principalExtractor } = opts;\n return async (exchange: ServerWebExchange): Promise<AbstractAuthenticationToken | undefined> => {\n const sslInfo = exchange.request.sslInfo;\n if (sslInfo === undefined) {\n // no SslInfo provided with a request, skipping x509 authentication\n return;\n }\n if (sslInfo.peerCertificate === undefined) {\n // no peer certificate found in SslInfo, skipping x509 authentication\n return;\n }\n const clientCertificate = sslInfo.peerCertificate;\n const principal = principalExtractor(clientCertificate);\n return {\n type: 'PreAuthenticated',\n authenticated: false,\n principal,\n name: principal ?? '',\n credentials: clientCertificate\n };\n }\n}\n", "import type {X509Certificate} from 'node:crypto';\nimport { BadCredentialsError } from '../types.ts';\n\nexport type X509PrincipalExtractor = (cert: X509Certificate) => string;\n\n/**\n * Extracts principal from X.509 certificate.\n * By default, extracts from certificate subject.\n * If principalAltName is 'email', extracts from email in Subject Alternative Name.\n */\nexport const subjectX500PrincipalExtractor: (opts?: {\n principalAltName?: 'email'\n}) => X509PrincipalExtractor = (opts) => {\n const extractFromEmail = opts?.principalAltName === 'email';\n const subjectDnRegEx = /CN=(.*?)(?:,|$)/mi;\n return (cert: X509Certificate): string => {\n if (extractFromEmail) {\n const email = cert.subjectAltName?.split(', ').find((altName) => altName.startsWith('email:'));\n if (email) {\n return email.replace('email:', '');\n }\n }\n // Default: extract from subject\n const result = subjectDnRegEx.exec(cert.subject);\n if (result === null) {\n throw new BadCredentialsError(`Cannot extract principal from subject DN: ${cert.subject}`);\n }\n const username = result[1];\n return username;\n }\n}\n", "import type { PasswordEncoder } from './index.ts';\n\nexport abstract class AbstractPasswordEncoder implements PasswordEncoder {\n async encode(rawPassword?: string): Promise<string | undefined> {\n if (rawPassword === undefined || rawPassword === null) {\n return undefined\n }\n return await this.encodeDefinedPassword(rawPassword.toString());\n }\n\n abstract encodeDefinedPassword(rawPassword: string): Promise<string>;\n\n async matches(rawPassword?: string, encodedPassword?: string): Promise<boolean> {\n if (!rawPassword || !encodedPassword) {\n return false;\n }\n return await this.matchesDefined(rawPassword.toString(), encodedPassword);\n }\n\n abstract matchesDefined(rawPassword: string, encodedPassword: string): Promise<boolean>;\n\n\n upgradeEncoding(encodedPassword?: string): boolean {\n if (!encodedPassword) {\n return false;\n }\n return this.upgradeEncodingDefined(encodedPassword);\n }\n\n protected upgradeEncodingDefined(encodedPassword: string): boolean {\n return false;\n }\n\n}\n\nexport class DelegatingPasswordEncoder extends AbstractPasswordEncoder {\n static DEFAULT_ID_PREFIX = '{'; // {\n static DEFAULT_ID_SUFFIX = '}'; // }\n readonly #idPrefix: string;\n readonly #idSuffix: string;\n readonly #idForEncode: string;\n readonly #encoderForEncode: PasswordEncoder;\n readonly #encoders: Map<string, PasswordEncoder>\n\n #defaultEncoderForMatches: PasswordEncoder = new class extends AbstractPasswordEncoder {\n readonly #outer: DelegatingPasswordEncoder;\n constructor(outer: DelegatingPasswordEncoder) {\n super();\n this.#outer = outer;\n }\n async encodeDefinedPassword(rawPassword: string): Promise<string> {\n throw new Error('encode is not supported');\n }\n\n async matchesDefined(rawPassword: string, prefixEncodedPassword: string): Promise<boolean> {\n const id = this.#outer.#extractId(prefixEncodedPassword);\n if (!id) {\n throw new Error(`No password encoder mapped for id ${id}`);\n }\n if (prefixEncodedPassword) {\n const start = prefixEncodedPassword.indexOf(this.#outer.#idPrefix);\n const end = prefixEncodedPassword.indexOf(this.#outer.#idSuffix, start + this.#outer.#idPrefix.length);\n if (start === -1 && end === -1) {\n throw new Error(`No prefix found in encoded password`);\n }\n }\n throw new Error(`malformed password encoder prefix`);\n }\n }(this);\n\n constructor(idForEncode: string, encoders: Map<string, PasswordEncoder>, idPrefix:string = DelegatingPasswordEncoder.DEFAULT_ID_PREFIX, idSuffix: string = DelegatingPasswordEncoder.DEFAULT_ID_SUFFIX) {\n if (idForEncode === undefined || idForEncode === null) {\n throw new Error('idForEncode cannot be null or undefined');\n }\n if (idPrefix === undefined || idPrefix === null) {\n throw new Error(`idPrefix cannot be null or undefined`);\n }\n if (!idSuffix) {\n throw new Error(`idSuffix cannot be empty`);\n }\n if (idPrefix.indexOf(idSuffix) !== -1) {\n throw new Error(`idPrefix \"${idPrefix}\" cannot contain idSuffix \"${idSuffix}\"`);\n }\n if (!encoders.has(idForEncode)) {\n throw new Error(`No PasswordEncoder mapped for id \"${idForEncode}\"`);\n }\n for (const id of encoders.keys()) {\n if (id === null) {\n continue;\n }\n if (idPrefix && id.includes(idPrefix)) {\n throw new Error(`id \"${id}\" cannot include ${idPrefix}`);\n }\n if (idSuffix && id.includes(idSuffix)) {\n throw new Error(`id \"${id}\" cannot include ${idSuffix}`);\n }\n }\n super();\n this.#idForEncode = idForEncode;\n this.#encoderForEncode = encoders.get(idForEncode)!;\n this.#encoders = new Map(encoders);\n this.#idPrefix = idPrefix;\n this.#idSuffix = idSuffix;\n }\n\n set defaultPasswordEncoderForMatches(encoder: PasswordEncoder) {\n if (encoder === null || encoder === undefined) {\n throw new Error('defaultPasswordEncoderForMatches cannot be null or undefined');\n }\n this.#defaultEncoderForMatches = encoder;\n }\n\n async encodeDefinedPassword(rawPassword: string): Promise<string> {\n const encoded = await this.#encoderForEncode.encode(rawPassword);\n return `${this.#idPrefix}${this.#idForEncode}${this.#idSuffix}${encoded}`;\n }\n\n async matchesDefined(rawPassword: string, prefixEncodedPassword: string): Promise<boolean> {\n const id = this.#extractId(prefixEncodedPassword);\n const delegate = id ? this.#encoders.get(id) : undefined;\n if (delegate === undefined) {\n return await this.#defaultEncoderForMatches.matches(rawPassword, prefixEncodedPassword);\n }\n else {\n const encodedPassword = this.#extractEncodedPassword(prefixEncodedPassword);\n return await delegate.matches(rawPassword, encodedPassword);\n }\n }\n\n #extractId(encodedPassword?: string): string | undefined {\n if (encodedPassword === undefined) {\n return undefined;\n }\n const start = encodedPassword.indexOf(this.#idPrefix);\n if (start !== 0) {\n return undefined;\n }\n const end = encodedPassword.indexOf(this.#idSuffix, start + this.#idPrefix.length);\n if (end === -1) {\n return undefined;\n }\n return encodedPassword.substring(start + this.#idPrefix.length, end);\n }\n\n protected upgradeEncodingDefined(prefixEncodedPassword: string): boolean {\n const id = this.#extractId(prefixEncodedPassword);\n if (this.#idForEncode !== id) {\n // todo case-insensitive compare?\n return true;\n }\n else {\n const encodedPassword = this.#extractEncodedPassword(prefixEncodedPassword);\n return this.#encoderForEncode.upgradeEncoding?.(encodedPassword) ?? false;\n }\n }\n\n #extractEncodedPassword(prefixEncodedPassword: string) {\n const start = prefixEncodedPassword.indexOf(this.#idSuffix);\n return prefixEncodedPassword.substring(start + this.#idSuffix.length);\n }\n\n}\n\nexport class NoopPasswordEncoder extends AbstractPasswordEncoder {\n static readonly #INSTANCE = new NoopPasswordEncoder();\n\n static get instance(): NoopPasswordEncoder {\n return NoopPasswordEncoder.#INSTANCE;\n }\n\n private constructor() {\n super();\n }\n\n async encodeDefinedPassword(rawPassword: string): Promise<string> {\n return rawPassword.toString();\n }\n\n async matchesDefined(rawPassword: string, encodedPassword: string): Promise<boolean> {\n return rawPassword.toString() === encodedPassword;\n }\n}\n", "import { AbstractPasswordEncoder } from './password.ts';\nimport { argon2, keygen } from '@interopio/gateway-server/tools';\n\n/**\n * Constant-time buffer comparison to prevent timing attacks.\n *\n * @param a - First buffer\n * @param b - Second buffer\n * @returns true if buffers are equal, false otherwise\n */\nfunction bufferEquals(a: Buffer, b: Buffer): boolean {\n if (a.length !== b.length) {\n return false;\n }\n let diff = 0;\n for (let i = 0; i < a.length; i++) {\n diff |= a[i] ^ b[i];\n }\n return diff === 0;\n}\n\n\n\nexport class Argon2PasswordEncoder extends AbstractPasswordEncoder {\n readonly #saltLength: number;\n readonly #hashLength: number;\n readonly #parallelism: number;\n readonly #memory: number\n readonly #passes: number;\n\n constructor(\n saltLength: number = argon2.DEFAULT_SALT_LENGTH,\n hashLength: number = argon2.DEFAULT_HASH_LENGTH,\n parallelism: number = argon2.DEFAULT_PARALLELISM,\n memory: number = argon2.DEFAULT_MEMORY,\n passes: number = argon2.DEFAULT_PASSES\n ) {\n super();\n this.#saltLength = saltLength;\n this.#hashLength = hashLength;\n this.#parallelism = parallelism;\n this.#memory = memory;\n this.#passes = passes;\n }\n\n async matchesDefined(rawPassword: string, encodedPassword: string): Promise<boolean> {\n try {\n const decoded = argon2.decode(encodedPassword);\n const hash = await argon2.createHash(\n decoded.algorithm,\n rawPassword,\n decoded.hash.length,\n decoded.parameters\n );\n return bufferEquals(decoded.hash, hash);\n } catch {\n return false;\n }\n }\n\n async encodeDefinedPassword(rawPassword: string): Promise<string> {\n const nonce = keygen.createSalt(this.#saltLength);\n const parameters = {\n memory: this.#memory,\n passes: this.#passes,\n parallelism: this.#parallelism,\n nonce\n };\n const hash = await argon2.createHash(\n 'argon2id',\n rawPassword,\n this.#hashLength,\n parameters\n );\n return argon2.encode({\n algorithm: 'argon2id',\n version: argon2.ARGON2_VERSION,\n parameters,\n hash\n });\n }\n\n upgradeEncodingDefined(encodedPassword: string): boolean {\n const decoded = argon2.decode(encodedPassword);\n return decoded.version < argon2.ARGON2_VERSION || decoded.parameters.memory < this.#memory || decoded.parameters.passes < this.#passes;\n }\n}\n", "import { DelegatingPasswordEncoder, NoopPasswordEncoder } from './password.ts';\nimport { Argon2PasswordEncoder } from './argon2.ts';\n\nexport const MAX_PASSWORD_LENGTH = 4096;\n\nexport interface PasswordEncoder {\n encode(rawPassword?: string): Promise<string | undefined>;\n\n matches(rawPassword?: string, encodedPassword?: string): Promise<boolean>;\n\n upgradeEncoding?(encodedPassword?: string): boolean;\n}\n\nexport function createDelegatingPasswordEncoder(): PasswordEncoder {\n const idForEncode = 'argon2id';\n const encoders: Map<string, PasswordEncoder> = new Map<string, PasswordEncoder>([\n [idForEncode, new Argon2PasswordEncoder()], ['noop', NoopPasswordEncoder.instance]]);\n return new DelegatingPasswordEncoder(idForEncode, encoders, DelegatingPasswordEncoder.DEFAULT_ID_PREFIX, DelegatingPasswordEncoder.DEFAULT_ID_SUFFIX);\n}\n", "import { AuthenticationError, type GrantedAuthority, type CredentialsHolder } from '../types.ts';\n\nexport type UserDetails = {\n readonly username: string;\n readonly password?: string | null; // null means credentials have been erased\n readonly authorities: ReadonlyArray<GrantedAuthority>;\n\n readonly accountExpired?: boolean;\n // Indicates whether the user's account is locked. A locked account prevents authentication.\n readonly accountLocked?: boolean;\n // Indicates whether the user's credentials (password) has expired. Expired credentials prevent authentication.\n readonly credentialsExpired?: boolean;\n // Indicates whether the user is enabled or disabled. A disabled user cannot be authenticated.\n readonly disabled?: boolean;\n};\n\nexport type UserDetailsChecker = (user: UserDetails) => void;\n\nexport interface UserDetailsService {\n findByUsername(username: string): Promise<UserDetails | undefined>;\n}\n\nexport interface UserDetailsPasswordService {\n updatePassword(user: UserDetails, newPassword?: string): Promise<UserDetails>;\n}\n\nexport const NoopUserDetailsPasswordService: UserDetailsPasswordService = {\n async updatePassword(user: UserDetails, _newPassword?: string): Promise<UserDetails> {\n return user;\n }\n}\n\nexport class UsernameNotFoundError extends AuthenticationError {\n readonly username?: string;\n\n constructor(message: string, username?: string, options?: ErrorOptions) {\n super(message, options);\n this.username = username;\n }\n}\n\nexport type User = UserDetails & CredentialsHolder & { toString(): string };\n\nexport class UserBuilder {\n #username!: string;\n #password?: string | null;\n #authorities: ReadonlyArray<GrantedAuthority> = [];\n #accountExpired?: boolean;\n #accountLocked?: boolean;\n #credentialsExpired?: boolean;\n #disabled?: boolean;\n\n #passwordEncoder: (rawPassword?: string | null) => string | undefined | null = (rawPassword) => rawPassword;\n\n private constructor() {\n }\n\n static ofUsername(username: string): UserBuilder {\n return new UserBuilder().username(username);\n }\n\n static ofUserDetails(user: UserDetails): UserBuilder {\n const builder = UserBuilder.ofUsername(user.username)\n .accountExpired(user.accountExpired ?? false)\n .accountLocked(user.accountLocked ?? false)\n .authorities(user.authorities)\n .credentialsExpired(user.credentialsExpired ?? false)\n .disabled(user.disabled ?? false);\n if (user.password !== undefined) {\n builder.password(user.password);\n }\n return builder;\n }\n\n username(username: string): this {\n if (!username) {\n throw new TypeError('username cannot be empty');\n }\n this.#username = username;\n return this;\n }\n\n password(password?: string | null): this {\n this.#password = password;\n return this;\n }\n\n passwordEncoder(encoder: (rawPassword?: string | null) => string | null | undefined): this {\n if (!encoder) {\n throw new TypeError('password encoder cannot be null or undefined');\n }\n this.#passwordEncoder = encoder;\n return this;\n }\n\n roles(...roles: string[]): this {\n return this.authorities(roles.map(role => {\n if (role.startsWith('role:')) {\n throw new Error(`${role} must not start with 'role:' (it is automatically added)`);\n }\n const authority = `role:${role}`;\n return { authority };\n }));\n }\n\n authorities(authorities: ReadonlyArray<GrantedAuthority>): this {\n this.#authorities = [...authorities];\n return this;\n }\n\n accountExpired(accountExpired: boolean): this {\n this.#accountExpired = accountExpired;\n return this;\n }\n\n accountLocked(accountLocked: boolean): this {\n this.#accountLocked = accountLocked;\n return this;\n }\n\n credentialsExpired(credentialsExpired: boolean): this {\n this.#credentialsExpired = credentialsExpired;\n return this;\n }\n\n disabled(disabled: boolean): this {\n this.#disabled = disabled;\n return this;\n }\n\n build(): User {\n if (!this.#username) {\n throw new TypeError('username is required');\n }\n let encodedPassword: string | null | undefined = this.#password !== undefined ? this.#passwordEncoder(this.#password) : undefined;\n return {\n username: this.#username,\n password: encodedPassword,\n authorities: this.#authorities,\n accountExpired: this.#accountExpired,\n accountLocked: this.#accountLocked,\n credentialsExpired: this.#credentialsExpired,\n disabled: this.#disabled,\n eraseCredentials(): void {\n encodedPassword = null;\n },\n toString(): string {\n return `User(username=${this.username}, password=[PROTECTED], authorities=${JSON.stringify(this.authorities)}, accountExpired=${this.accountExpired}, accountLocked=${this.accountLocked}, credentialsExpired=${this.credentialsExpired}, disabled=${this.disabled})`;\n }\n }\n }\n}\n", "import {\n type AbstractAuthenticationToken,\n AccountExpiredError,\n type AuthenticatedPrincipal,\n type Authentication,\n type AuthenticationManager,\n BadCredentialsError,\n CredentialsExpiredError,\n DisabledError,\n LockedError\n} from './types.ts';\nimport { createDelegatingPasswordEncoder, type PasswordEncoder } from './crypto/index.ts';\nimport getLogger from '../../logger.ts';\nimport {\n NoopUserDetailsPasswordService,\n type UserDetails,\n type UserDetailsChecker,\n type UserDetailsPasswordService,\n type UserDetailsService,\n UsernameNotFoundError\n} from './users/types.ts';\n\nconst logger = getLogger('security.users');\n\nexport function userDetailsServiceAuthenticationManager(\n userDetailsService: UserDetailsService,\n options?: {\n preAuthenticationChecks?: UserDetailsChecker;\n postAuthenticationChecks?: UserDetailsChecker;\n passwordEncoder?: PasswordEncoder;\n userDetailsPasswordService?: UserDetailsPasswordService;\n }\n): AuthenticationManager {\n const preAuthenticationChecks = options?.preAuthenticationChecks ?? ((user: UserDetails) => {\n if (user.accountLocked) {\n logger.debug(`user account is locked`);\n throw new LockedError(`User account is locked`);\n }\n if (user.disabled) {\n logger.debug(`user account is disabled`);\n throw new DisabledError(`User is disabled`);\n }\n if (user.accountExpired) {\n logger.debug(`user account is expired`);\n throw new AccountExpiredError(`User account has expired`);\n }\n });\n const postAuthenticationChecks = options?.postAuthenticationChecks ?? ((user: UserDetails) => {\n if (user.credentialsExpired) {\n logger.debug(`user credentials have expired`);\n throw new CredentialsExpiredError(`User credentials have expired`);\n }\n });\n const passwordEncoder = options?.passwordEncoder ?? createDelegatingPasswordEncoder();\n\n const userDetailsPasswordService: UserDetailsPasswordService = options?.userDetailsPasswordService ?? NoopUserDetailsPasswordService;\n\n const upgradeEncodingIfNeeded = async (userDetails: UserDetails, presentedPassword?: string) => {\n const existingEncodedPassword = userDetails.password;\n const upgradeEncoding = existingEncodedPassword !== undefined\n && passwordEncoder.upgradeEncoding?.(existingEncodedPassword!);\n if (upgradeEncoding) {\n const newEncodedPassword = await passwordEncoder.encode(presentedPassword);\n return await userDetailsPasswordService.updatePassword(userDetails, newEncodedPassword);\n }\n return userDetails;\n }\n\n return async (authentication: Authentication): Promise<AbstractAuthenticationToken> => {\n\n const username = authentication.name!;\n const presentedPassword = (authentication.credentials !== undefined && authentication.credentials !== null) ? authentication.credentials.toString() : undefined;\n // retrieve user\n const user = await userDetailsService.findByUsername(username);\n\n if (!user) {\n throw new Error(`User not found: ${username}`);\n }\n\n preAuthenticationChecks(user);\n if (!(await passwordEncoder.matches(presentedPassword, user.password!))) {\n throw new BadCredentialsError('Invalid Credentials');\n }\n const principal = await upgradeEncodingIfNeeded(user, presentedPassword);\n\n postAuthenticationChecks(principal);\n let credentials = principal.password;\n return {\n type: 'UsernamePassword',\n principal: principal,\n credentials: credentials,\n authorities: principal.authorities,\n authenticated: true,\n name: principal.username,\n eraseCredentials() {\n credentials = null;\n }\n };\n };\n}\n\nexport function accountStatusUserDetailsChecker(): UserDetailsChecker {\n return (user: UserDetails) => {\n if (user.accountLocked) {\n logger.debug(`failed to authenticate since user account is locked`);\n throw new LockedError(`User account is locked`);\n }\n if (user.disabled) {\n logger.debug(`failed to authenticate user account is disabled`);\n throw new DisabledError(`User is disabled`);\n }\n if (user.accountExpired) {\n logger.debug(`failed to authenticate since user account is expired`);\n throw new AccountExpiredError(`User account has expired`);\n }\n if (user.credentialsExpired) {\n logger.debug(`failed to authenticate since user credentials have expired`);\n throw new CredentialsExpiredError(`User credentials have expired`);\n }\n }\n}\n\nexport function preAuthenticatedAuthenticationManager(opts: {\n userDetailsService: UserDetailsService,\n userDetailsChecker?: UserDetailsChecker\n}): AuthenticationManager {\n const userDetailsService = opts.userDetailsService;\n const userDetailsChecker = opts.userDetailsChecker ?? accountStatusUserDetailsChecker();\n\n const supports = (authentication: Authentication): authentication is AbstractAuthenticationToken & AuthenticatedPrincipal => {\n return (authentication.type === 'PreAuthenticated' && authentication.name !== undefined);\n }\n\n return async (authentication: Authentication): Promise<AbstractAuthenticationToken> => {\n const userDetails = supports(authentication) && await userDetailsService.findByUsername(authentication.name);\n if (!userDetails) {\n throw new UsernameNotFoundError(`user not found`, authentication.name);\n }\n userDetailsChecker(userDetails);\n let erasableCredentials = authentication.credentials;\n const result: AbstractAuthenticationToken = {\n type: 'PreAuthenticated',\n principal: userDetails,\n credentials: erasableCredentials,\n authorities: userDetails.authorities,\n authenticated: true,\n details: userDetails,\n name: userDetails.username,\n eraseCredentials() {\n erasableCredentials = null;\n }\n };\n return result;\n };\n}\n", "import authenticationFilter from './authentication-filter.ts';\nimport type { AsyncLocalStorage } from 'node:async_hooks';\nimport { x509Converter } from './x509-converter.ts';\nimport { subjectX500PrincipalExtractor, type X509PrincipalExtractor } from './preauth/x509.ts';\nimport type { AuthenticationConverter, AuthenticationManager } from './types.ts';\nimport { preAuthenticatedAuthenticationManager } from './users.ts';\n\n\nexport default function x509(opts: {\n readonly storage: AsyncLocalStorage< {} >,\n readonly manager?: AuthenticationManager,\n readonly extractor?: X509PrincipalExtractor,\n readonly converter?: AuthenticationConverter,\n getService: <T>(type: string) => T\n}) {\n const manager = opts.manager ?? preAuthenticatedAuthenticationManager({\n userDetailsService: opts.getService('UserDetailsService')\n });\n const principalExtractor = opts.extractor ?? subjectX500PrincipalExtractor();\n const converter = opts.converter ?? x509Converter({ principalExtractor })\n return authenticationFilter({\n storage: opts.storage,\n manager,\n converter\n })\n}\n", "import type { UserDetails, UserDetailsPasswordService, UserDetailsService } from './types.ts';\n\nexport class MapUserDetailsService implements UserDetailsService, UserDetailsPasswordService {\n readonly #users = new Map<string, UserDetails>();\n\n constructor(...users: UserDetails[]) {\n for (const user of users) {\n this.#users.set(this.#getKey(user.username), user);\n }\n }\n\n async findByUsername(username: string): Promise<UserDetails | undefined> {\n const key = this.#getKey(username);\n const result = this.#users.get(key);\n return result !== undefined ? { ...(result) } : undefined;\n }\n\n async updatePassword(user: UserDetails, newPassword?: string): Promise<UserDetails> {\n const userDetails = { ...(user), password: newPassword };\n // what if user does not exist?\n if (userDetails) {\n const key = this.#getKey(user.username);\n this.#users.set(key, userDetails);\n }\n return userDetails;\n }\n\n #getKey(username: string) {\n return username.toLowerCase();\n }\n}\n", "import { createCorsConfigSource } from './cors.ts';\nimport type { RouteConfig } from './route.ts';\nimport security, { type HttpSecurityConfig } from '../server/security/config.ts';\nimport { and, pattern, type ServerWebExchangeMatcher, upgradeMatcher } from '../server/util/matchers.ts';\nimport type { CorsConfigSource } from '../server/cors.ts';\nimport type { Middleware } from '../server/types.ts';\nimport type { AuthorizationRule } from '../../types/auth';\nimport { MapUserDetailsService } from '../server/security/users/memory.ts';\nimport { UserBuilder, type UserDetails } from '../server/security/users/types.ts';\nimport { randomUUID } from 'node:crypto';\nimport { MAX_PASSWORD_LENGTH, type PasswordEncoder } from '../server/security/crypto/index.ts';\nimport getLogger from '../logger.ts';\n\nconst logger = getLogger('auth');\n\nexport function createSecurityConfig(context: RouteConfig): HttpSecurityConfig {\n const authorize: HttpSecurityConfig['authorize'] = [];\n const type = context.authConfig?.type;\n const defaultAccess: AuthorizationRule = { access: type !== 'none' ? 'authenticated' : 'permitted' };\n if (logger.enabledFor('info')) {\n logger.info(`using auth type: ${type ?? 'none'}, default access: ${defaultAccess.access}`);\n }\n for (const [path, route] of context.sockets) {\n const rule = route.authorize ?? defaultAccess;\n let matcher: ServerWebExchangeMatcher = pattern(path, { method: 'GET' });\n matcher = and([upgradeMatcher, matcher]);\n authorize.push([matcher, rule]);\n }\n authorize.push([pattern('/', { method: 'GET' }), { access: 'permitted' }]);\n authorize.push([pattern('/favicon.ico', {method: 'GET'}), { access: 'permitted' }]);\n authorize.push([pattern('/health', {method: 'GET'}), { access: 'permitted' }]);\n if (context.authorize.length > 0) {\n authorize.push(...context.authorize);\n }\n\n authorize.push(['any-exchange', defaultAccess]); // default rule for all other exchanges\n return {\n authorize,\n cors: {\n disabled: context.corsConfig === false,\n },\n x509: {\n disabled: type !== 'x509',\n ...context.authConfig?.x509,\n },\n basic: {\n disabled: type !== 'basic',\n ...context.authConfig?.basic,\n },\n jwt: {\n disabled: type !== 'oauth2',\n ...context.authConfig?.oauth2?.jwt\n }\n }\n}\n\nexport function createUserDetailsService(context: RouteConfig) {\n // if (context.userDetailsService) {\n // return context.userDetailsService;\n // }\n\n function getOrDeducePassword(user: { password?: string }, encoder?: PasswordEncoder): string {\n let password = user.password;\n if (password === undefined) {\n // generate password\n const generatedPassword = randomUUID().replaceAll('-', '');\n if (logger.enabledFor('info')) {\n logger.info(`\\n\\n using generated password: ${generatedPassword}\\n\\nThis generated password is for development only. Your authentication configuration should be updated before running in production.\\n`);\n }\n password = generatedPassword;\n }\n if (password.length > MAX_PASSWORD_LENGTH) {\n throw new Error(`Password length exceeds maximum length of ${MAX_PASSWORD_LENGTH} characters`);\n }\n if ((encoder !== undefined && encoder !== null) || /^\\{.+}.*$/.test(password)) {\n return password;\n }\n return `{noop}${password}`;\n }\n\n const user = { name : 'dev-user', roles: [], ...(context.authConfig?.user) };\n const password = getOrDeducePassword(user);\n const roles = user.roles;\n const userDetails: UserDetails = UserBuilder.ofUsername(user.name).password(password).roles(...(roles)).build();\n return new MapUserDetailsService(userDetails);\n}\n\nexport async function httpSecurity(context: RouteConfig): Promise<Middleware> {\n const corsConfigSource: CorsConfigSource = createCorsConfigSource(context);\n const userDetailsService = createUserDetailsService(context);\n const config = createSecurityConfig(context);\n const { storage } = context;\n return security(config, {\n storage,\n corsConfigSource,\n userDetailsService,\n userDetailsPasswordService: userDetailsService\n });\n}\n", "import type { HttpHandler, WebHandler } from './types';\nimport { DefaultWebExchange, ServerHttpResponseDecorator } from './exchange.ts';\nimport { AsyncLocalStorage } from 'node:async_hooks';\nimport type { Logger } from '@interopio/gateway/logging/api';\nimport type { HttpHeaders } from '../../types/web/http';\nimport type {\n ServerHttpRequest,\n ServerHttpResponse,\n ServerWebExchange\n} from '../../types/web/server';\nimport getLogger from '../logger.ts';\nimport { HttpStatus } from '../http/status.ts';\n\nexport class HttpHeadResponseDecorator extends ServerHttpResponseDecorator {\n\n}\n\nclass HandlerAdapter {\n\n readonly #logger: Logger\n #enableLoggingRequestDetails: boolean = false;\n readonly #delegate: WebHandler;\n #storage?: AsyncLocalStorage<{ exchange: ServerWebExchange }>;\n\n constructor(logger: Logger, delegate: WebHandler) {\n this.#logger = logger;\n this.#delegate = delegate;\n }\n\n protected createExchange(request: ServerHttpRequest, response: ServerHttpResponse): ServerWebExchange {\n\n const exchange = new DefaultWebExchange(request, response);\n return exchange;\n }\n\n set storage(storage: AsyncLocalStorage<{ exchange: ServerWebExchange }>) {\n this.#storage = storage;\n }\n\n set enableLoggingRequestDetails(value: boolean) {\n this.#enableLoggingRequestDetails = value;\n }\n\n formatHeaders(headers: HttpHeaders): string {\n let result = '{';\n\n for (const key of headers.keys()) {\n if (!this.#enableLoggingRequestDetails) {\n result += 'masked, ';\n break;\n } else {\n const value = headers.get(key);\n result += `\"${key}\": \"${value}\", `;\n }\n }\n if (result.endsWith(', ')) {\n result = result.slice(0, -2);\n }\n result += '}';\n return result;\n\n }\n\n formatRequest(request: ServerHttpRequest): string {\n const query = request.URL.search;\n return `HTTP ${request.method} \"${request.path}${query}`;\n }\n\n logRequest(exchange: ServerWebExchange) {\n if (this.#logger.enabledFor('debug')) {\n const trace = this.#logger.enabledFor('trace');\n this.#logger.debug(`${exchange.logPrefix}${this.formatRequest(exchange.request)}${trace ? `, headers: ${this.formatHeaders(exchange.request.headers)}` : ''}\"`);\n\n }\n }\n\n logResponse(exchange: ServerWebExchange) {\n if (this.#logger.enabledFor('debug')) {\n const trace = this.#logger.enabledFor('trace');\n const status = exchange.response.statusCode;\n this.#logger.debug(`${exchange.logPrefix}Completed ${status ?? '200 OK'}${trace ? `, headers: ${this.formatHeaders(exchange.response.headers)}` : ''}\"`);\n }\n }\n\n handleUnresolvedError(exchange: ServerWebExchange, error: Error) {\n const {request, response, logPrefix} = exchange;\n\n if (response.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR)) {\n this.#logger.error(`${logPrefix}500 Server Error for ${this.formatRequest(request)}`, error);\n return;\n }\n // todo if client disconnected, we should not log an error\n\n this.#logger.error(`${logPrefix}Error [${error.message} for ${this.formatRequest(request)}, but already ended (${response.statusCode})`, error);\n throw error;\n\n }\n\n async web(exchange: ServerWebExchange): Promise<void> {\n return await this.#delegate(exchange);\n }\n\n async http(request: ServerHttpRequest, response: ServerHttpResponse): Promise<void> {\n\n const exchange = this.createExchange(request, response);\n const callback = () => {\n this.logRequest(exchange);\n return this.web(exchange)\n .then(() => {\n this.logResponse(exchange);\n })\n .catch((error: Error) => {\n this.handleUnresolvedError(exchange, error)\n })\n .then(async () => {\n await exchange.response.end();\n });\n };\n\n await new Promise<void>((resolve, reject) => {\n if (this.#storage !== undefined) {\n this.#storage.run({exchange}, () => {\n callback().then(() => resolve()).catch((error) => reject(error));\n });\n } else {\n callback().then(() => resolve()).catch((error) => reject(error));\n }\n });\n }\n}\n\nexport class WebHttpHandlerBuilder {\n readonly #webHandler: WebHandler;\n #storage?: AsyncLocalStorage<{ exchange: ServerWebExchange }> = new AsyncLocalStorage();\n #handlerDecorator?: (handler: HttpHandler) => HttpHandler;\n\n storage(storage: AsyncLocalStorage<{ exchange: ServerWebExchange }>): this {\n this.#storage = storage;\n return this;\n }\n\n httpHandlerDecorator(decorator: (handler: HttpHandler) => HttpHandler): this {\n if (this.#handlerDecorator === undefined) {\n this.#handlerDecorator = decorator;\n } else {\n const previousDecorator = this.#handlerDecorator;\n this.#handlerDecorator = (handler: HttpHandler) => {\n handler = previousDecorator(handler);\n return decorator(handler);\n }\n }\n return this;\n }\n\n constructor(webHandler: WebHandler) {\n this.#webHandler = webHandler;\n }\n\n build(): HttpHandler {\n const logger = getLogger('http');\n\n const adapter = new HandlerAdapter(logger, this.#webHandler);\n if (this.#storage !== undefined) adapter.storage = this.#storage;\n adapter.enableLoggingRequestDetails = false;\n const adapted: HttpHandler = async (request, response) => adapter.http(request, response);\n\n\n return this.#handlerDecorator ? this.#handlerDecorator(adapted) : adapted;\n }\n}\n", "import type { AsyncLocalStorage } from \"node:async_hooks\";\nimport { WebSocketServer } from 'ws';\nimport type { ServerHttpResponse, ServerWebExchange } from '../../types/web/server';\nimport { HttpStatus } from '../http/status.ts';\nimport getLogger, { regexAwareReplacer } from '../logger.ts';\nimport {\n ExtendedHttpIncomingMessage,\n ExtendedHttpServerResponse,\n ServerHttpRequestDecorator,\n ServerHttpResponseDecorator\n} from './exchange.ts';\nimport { createHandshakeInfo, type SocketRoute } from './socket.ts';\nimport { acceptsOrigin } from './ws-client-verify.ts';\nimport { ExtendedWebSocket, PingManager } from './ws-pings.ts';\n\nconst logger = getLogger('ws');\n\nfunction upgradeStrategy(path: string, route: SocketRoute, wss: WebSocketServer, onSocketError: (err: Error) => void) {\n return (exchange: ServerWebExchange) => {\n\n const { logPrefix, request } = exchange;\n const req = ServerHttpRequestDecorator.getNativeRequest<ExtendedHttpIncomingMessage>(request);\n req.exchange = exchange;\n const { socket, upgradeHead } = req;\n\n const host = request.host;\n socket.removeListener('error', onSocketError);\n if (route.maxConnections !== undefined && wss.clients?.size >= route.maxConnections) {\n logger.warn(`${logPrefix}dropping ws connection request on ${host}${path}. max connections exceeded.`);\n socket.destroy();\n return;\n }\n\n const origin = request.headers.one('origin');\n if (!acceptsOrigin(origin, route.originFilters)) {\n if (logger.enabledFor('info')) {\n logger.info(`${logPrefix}dropping ws connection request on ${host}${path}. origin ${origin ?? '<missing>'}`);\n }\n socket.destroy();\n return;\n }\n if (logger.enabledFor('debug')) {\n logger.debug(`${logPrefix}accepted new ws connection request on ${host}${path}`);\n }\n\n wss.handleUpgrade(req, socket, upgradeHead!, (client, req) => {\n wss.emit('connection', client, req);\n });\n }\n}\n\nfunction applyHandshakeHeaders(headers: string[], response: ServerHttpResponse) {\n const seen = new Set<string>(); // track headers we've taken care of\n headers.forEach((header, index) => {\n if (index === 0 && header.startsWith('HTTP/1.1 101 ')) {\n response.setStatusCode(HttpStatus.SWITCHING_PROTOCOLS);\n return;\n }\n const [name, value] = header.split(': ');\n if (response.headers.has(name)) {\n headers[index] = `${name}: ${response.headers.one(name)}`;\n }\n else {\n response.headers.set(name, value);\n }\n seen.add(name.toLowerCase());\n });\n const nativeResponse = ServerHttpResponseDecorator.getNativeResponse<ExtendedHttpServerResponse>(response);\n for (const name of nativeResponse.getRawHeaderNames()) {\n // if we have already set this header, skip it\n const nameLowerCase = name.toLowerCase();\n if (!seen.has(nameLowerCase)) {\n const value = response.headers.get(nameLowerCase);\n if (value !== undefined) {\n headers.push(`${name}: ${value}`);\n }\n }\n }\n nativeResponse.markHeadersSent();\n}\n\nexport async function initRoute(path: string,\n route: SocketRoute,\n endpoint: string,\n storage: AsyncLocalStorage<{ securityContext? }>,\n onSocketError: (err: Error) => void): Promise<void> {\n try {\n logger.info(`creating ws server for [${path}]. max connections: ${route.maxConnections ?? '<unlimited>'}, origin filters: ${route.originFilters ? JSON.stringify(route.originFilters, regexAwareReplacer) : '<none>'}, ping: ${typeof route.ping === 'number' ? route.ping + 'ms' : route.ping ? JSON.stringify(route.ping) : '<none>'}`);\n const wss = new WebSocketServer<typeof ExtendedWebSocket, typeof ExtendedHttpIncomingMessage>({\n noServer: true,\n WebSocket: ExtendedWebSocket,\n autoPong: false\n });\n\n const pings = new PingManager(logger.child('pings'), () => [path, wss.clients], route.ping);\n\n const handler = await route.factory({ endpoint, storage });\n wss\n .on('error', (err: Error) => {\n logger.error(`error starting the ws server for [${path}]`, err);\n })\n .on('listening', () => {\n logger.info(`ws server for [${path}] is listening`);\n })\n .on('headers', (headers, request) => {\n if (request.exchange !== undefined) {\n const { response } = request.exchange;\n applyHandshakeHeaders(headers, response);\n }\n })\n .on('connection', (socket, request) => {\n\n const handshake = createHandshakeInfo(request, socket.protocol);\n\n socket.on('pong', (data) => {\n pings.handlePong(handshake, socket, data);\n });\n socket.on('ping', (data: Buffer) => {\n pings.handlePing(handshake, socket, data);\n });\n handler({ socket, handshake });\n });\n wss.on('close', () => {\n pings.close();\n });\n\n route.upgradeStrategy = upgradeStrategy(path, route, wss, onSocketError);\n route.close = async () => {\n await handler.close?.call(handler);\n logger.info(`stopping ws server for [${path}]. clients: ${wss.clients?.size ?? 0}`);\n wss.clients?.forEach(client => {\n client.terminate();\n });\n wss.close();\n }\n }\n catch (e) {\n logger.warn(`failed to init route ${path}`, e);\n }\n\n}\n", "import { type ExtendedHttpIncomingMessage, HttpServerRequest } from './exchange.ts';\nimport { MapHttpHeaders } from '../http/exchange.ts';\nimport type { AuthorizationRule, Principal } from '../../types/auth';\nimport type { WebSocketHandshakeInfo } from '../../types/web/socket';\nimport type { Middleware } from './types.ts';\nimport type { ServerWebExchange, ServerWebSocketHandler } from '../../types/web/server';\nimport { upgradeMatcher } from './util/matchers.ts';\nimport type { ProcessedOriginFilters } from './ws-client-verify.ts';\nimport { HttpStatus } from '../http/status.ts';\nimport type { AsyncLocalStorage } from 'node:async_hooks';\n\nexport function createHandshakeInfo(req: ExtendedHttpIncomingMessage, protocol?: string): WebSocketHandshakeInfo {\n const exchange = req?.exchange;\n const request = exchange?.request ?? new HttpServerRequest(req);\n const principalPromiseProvider = exchange?.principal;\n const principal = principalPromiseProvider ? principalPromiseProvider.bind(exchange) : async function principal<P extends Principal> (): Promise<P | undefined> { return undefined; };\n const url = request.URL;\n const headers = new MapHttpHeaders();\n for (const key of request.headers.keys()) {\n headers.set(key, request.headers.list(key));\n }\n const cookies = request.cookies;\n const logPrefix = exchange?.logPrefix ?? `[${request.id}] `;\n const remoteAddress = request.remoteAddress;\n const handshake: WebSocketHandshakeInfo = {\n url,\n headers,\n cookies,\n principal,\n protocol,\n remoteAddress,\n logPrefix,\n };\n return handshake;\n}\n\nexport function webSockets(context: { sockets: Map<string, SocketRoute> }): Middleware {\n // websocket upgrade handler\n const sockets = async (exchange: ServerWebExchange, next: () => Promise<void>) => {\n const request = exchange.request;\n const path = request.path ?? '/';\n\n const routes = context.sockets;\n const route = (routes.get(path) ?? Array.from(routes.values()).find(route => {\n if (path === '/' && route.default === true) {\n return true;\n }\n }));\n\n if (route !== undefined) {\n const {request, response} = exchange;\n const upgradeMatchResult = await upgradeMatcher(exchange);\n if ((request.method === 'GET' || request.method === 'CONNECT') && upgradeMatchResult.match) {\n if (route.upgradeStrategy !== undefined) {\n route.upgradeStrategy(exchange);\n return;\n }\n else {\n throw new Error(`No upgrade strategy defined for route on ${path}`);\n }\n\n } else {\n if (route.default) {\n // allow default route to pass through\n await next();\n return;\n }\n\n response.setStatusCode(HttpStatus.UPGRADE_REQUIRED);\n response.headers\n .set('Upgrade', 'websocket')\n .set('Connection', 'Upgrade')\n .set('Content-Type', 'text/plain');\n\n const buffer = Buffer.from(`This service [${request.path}] requires use of the websocket protocol.`, 'utf-8');\n await response.body(buffer);\n }\n } else {\n await next();\n }\n };\n return [sockets];\n}\n\nexport type SocketRoute = {\n readonly default?: boolean,\n readonly ping?: number | {interval: number, data?: 'timestamp' | 'empty'},\n readonly maxConnections?: number\n readonly authorize?: AuthorizationRule,\n readonly originFilters?: ProcessedOriginFilters\n readonly factory: (server: { endpoint: string, storage?: AsyncLocalStorage<{ exchange?, securityContext? }> }) => Promise<ServerWebSocketHandler>,\n // set later in listening\n upgradeStrategy?: (exchange: ServerWebExchange) => void,\n close?: () => Promise<void>\n}\n", "import { addressAndPort } from './address.ts';\nimport type { Logger } from '../logger.ts';\nimport { WebSocket } from 'ws';\nimport type { WebSocketHandshakeInfo } from '../../types/web/socket';\n\nexport class ExtendedWebSocket extends WebSocket {\n constructor(_first: unknown, _second?: unknown, options?: unknown) {\n /* eslint-disable @typescript-eslint/no-explicit-any */\n super(null as unknown as any, undefined, options as any);\n }\n\n connected?: boolean;\n}\n\nexport type PingConfig = { interval: number, data?: 'timestamp' | 'empty' };\n\nexport class PingManager {\n static readonly #EMPTY_BUFFER = Buffer.alloc(0);\n static #LAST_TIMESTAMP_BUFFER: [number, Buffer] = [0, Buffer.alloc(8)];\n\n readonly #pingData: () => Buffer;\n readonly #pingInterval: number | undefined;\n readonly #pingIntervalId?: ReturnType<typeof setInterval>;\n readonly #mask = false;\n readonly #logger: Logger;\n\n constructor(logger: Logger, supplier: () => [string, Set<ExtendedWebSocket>], ping?: number | PingConfig) {\n this.#logger = logger;\n this.#pingInterval = typeof ping === 'number' ? ping : ping?.interval;\n this.#pingData =\n typeof ping === 'number' || ping?.data === 'timestamp'\n ? () => PingManager.#createBufferFromTimestamp(Date.now())\n : () => PingManager.#EMPTY_BUFFER;\n\n if (this.#pingInterval) {\n this.#pingIntervalId = setInterval(() => {\n const [path, clients] = supplier();\n for (const client of clients) {\n if (this.#terminateIfDisconnected(client, path)) {\n continue;\n }\n this.#markAndSendPing(client, path);\n }\n }, this.#pingInterval);\n\n }\n }\n\n #terminateIfDisconnected(client: ExtendedWebSocket, path: string) {\n if (client.connected === false) {\n if (this.#logger.enabledFor('debug')) {\n this.#logger.debug(`terminating unresponsive ws client on [${path}]`);\n }\n client.terminate();\n return true;\n }\n return false;\n }\n\n #markAndSendPing(client: ExtendedWebSocket, path: string) {\n client.connected = false;\n const data = this.#pingData();\n if (this.#logger.enabledFor('trace')) {\n this.#logger.debug(`pinging ws client on [${path}]`);\n }\n client.ping(data, this.#mask, (err: Error) => {\n if (err && this.#logger.enabledFor('warn')) {\n this.#logger.warn(`failed to ping ws client on [${path}]`, err);\n }\n });\n }\n\n static #createBufferFromTimestamp(now = Date.now()): Buffer {\n if (now - PingManager.#LAST_TIMESTAMP_BUFFER[0] > 0) {\n const buffer = Buffer.allocUnsafe(8);\n buffer.writeBigInt64BE(BigInt(now), 0);\n PingManager.#LAST_TIMESTAMP_BUFFER = [now, buffer];\n }\n return PingManager.#LAST_TIMESTAMP_BUFFER[1];\n }\n\n static #createTimestampFromBuffer(data: Buffer): number {\n if (data.length === 8) {\n return Number(data.readBigInt64BE(0));\n }\n return 0;\n }\n\n close() {\n clearInterval(this.#pingIntervalId);\n }\n\n handlePing(handshake: WebSocketHandshakeInfo, socket: ExtendedWebSocket, data: Buffer): void {\n socket.connected = true;\n socket.pong(data, false, (err: Error) => {\n if (err && this.#logger.enabledFor('warn')) {\n this.#logger.warn(`${handshake.logPrefix}failed to pong ws client ${addressAndPort(handshake.remoteAddress)}`, err);\n }\n });\n }\n\n handlePong(handshake: WebSocketHandshakeInfo, socket: ExtendedWebSocket, data: Buffer): void {\n socket.connected = true;\n if (this.#logger.enabledFor('warn')) {\n const sent = PingManager.#createTimestampFromBuffer(data);\n if (sent > 0) {\n const latency = Date.now() - sent;\n if (this.#logger.enabledFor('debug')) {\n this.#logger.debug(`${handshake.logPrefix}ws client ${addressAndPort(handshake.remoteAddress)} ping-pong latency: ${latency}ms`);\n }\n if (this.#pingInterval && latency > this.#pingInterval / 2 && this.#logger.enabledFor('warn')) {\n this.#logger.warn(`${handshake.logPrefix}ws client ${addressAndPort(handshake.remoteAddress)} high ping-pong latency: ${latency}ms`);\n }\n }\n }\n }\n}\n", "import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';\nimport { dirname } from 'node:path';\nimport type { TlsOptions } from 'node:tls';\nimport { KEYUTIL, X509 } from 'jsrsasign';\nimport { mkcert } from '@interopio/gateway-server/tools';\nimport type { GatewayServer } from '@interopio/gateway-server';\nimport getLogger from '../../logger.ts';\n\nconst logger = getLogger('ssl');\n\nexport type ServerCertificateConfig = {\n /** Hostname for the server certificate (used in CN and SAN) */\n host: string;\n /** Path to CA private key file (PEM format), for auto-generating server certificates */\n key?: string;\n /** Passphrase for encrypted CA private key */\n passphrase?: string;\n};\n\nexport function secureContextOptions(ssl: GatewayServer.SslConfig, serverCertificate?: ServerCertificateConfig): TlsOptions {\n // Prepare common SSL/TLS options (client certificate verification)\n const commonOptions: TlsOptions = {};\n\n if (ssl.requestCert !== undefined) {\n commonOptions.requestCert = ssl.requestCert;\n }\n if (ssl.rejectUnauthorized !== undefined) {\n commonOptions.rejectUnauthorized = ssl.rejectUnauthorized;\n }\n\n // Mode 1: Explicit key and cert provided - check if files exist and use them\n if (ssl.key && ssl.cert && existsSync(ssl.key) && existsSync(ssl.cert)) {\n logger.info(`using SSL/TLS certificate ${ssl.cert} with private key in ${ssl.key}${ssl.passphrase ? ' (password-protected)' : ''}`);\n const options: TlsOptions = {\n key: readFileSync(ssl.key),\n cert: readFileSync(ssl.cert),\n ...commonOptions\n };\n if (ssl.passphrase) {\n options.passphrase = ssl.passphrase;\n }\n // Only set ca if requestCert is true (ca is for validating client certificates)\n if (ssl.requestCert && ssl.ca && existsSync(ssl.ca)) {\n options.ca = readFileSync(ssl.ca);\n }\n return options;\n }\n\n // Mode 1b: Key and cert not explicitly provided, but default files exist - use them\n if (!ssl.key && !ssl.cert) {\n const defaultKeyPath = './gateway-server.key';\n const defaultCertPath = './gateway-server.crt';\n\n if (existsSync(defaultKeyPath) && existsSync(defaultCertPath)) {\n logger.info(`using SSL/TLS certificate ${defaultCertPath} with private key in ${defaultKeyPath}${ssl.passphrase ? ' (password-protected)' : ''}`);\n const options: TlsOptions = {\n key: readFileSync(defaultKeyPath),\n cert: readFileSync(defaultCertPath),\n ...commonOptions\n };\n if (ssl.passphrase) {\n options.passphrase = ssl.passphrase;\n }\n // Only set ca if requestCert is true (ca is for validating client certificates)\n if (ssl.requestCert && ssl.ca && existsSync(ssl.ca)) {\n options.ca = readFileSync(ssl.ca);\n }\n return options;\n }\n }\n\n // Mode 2: Generate server certificate using CA key (from auth.x509.key)\n // If serverCertificate is undefined, skip certificate generation\n if (!serverCertificate) {\n throw new Error('SSL/TLS enabled but no server certificate provided. Either provide ssl.key and ssl.cert, or configure auth.x509.key for auto-generation.');\n }\n\n // Note: CA key is primarily for client certificate generation, incidentally used for server cert\n const caKeyPath = serverCertificate.key ?? 'gateway-ca.key';\n const caPemPath = ssl.ca ?? `${caKeyPath.replace(/\\.key$/, '.crt')}`;\n const passphrase = serverCertificate.passphrase ?? ssl.passphrase;\n\n // Auto-generate Root CA if it doesn't exist\n\n if (!existsSync(caKeyPath)) {\n if (existsSync(caPemPath)) {\n throw new Error(`CA key file not found: ${caKeyPath} (CA certificate exists: ${caPemPath})`);\n }\n const rootCA = mkcert.generateRootCA({ name: mkcert.DEFAULT_CA_NAME, passphrase });\n\n // Ensure directory exists\n const keyDir = dirname(caKeyPath);\n if (keyDir && keyDir !== '.' && !existsSync(keyDir)) {\n mkdirSync(keyDir, { recursive: true });\n }\n const certDir = dirname(caPemPath);\n if (certDir && certDir !== '.' && certDir !== keyDir && !existsSync(certDir)) {\n mkdirSync(certDir, { recursive: true });\n\n }\n writeFileSync(caKeyPath, rootCA.key, { mode: 0o400 });\n writeFileSync(caPemPath, rootCA.cert, { mode: 0o644 });\n logger.info(`created new local Root CA in ${caPemPath}, ${caKeyPath}${passphrase ? ' (password-protected)' : ''}`);\n }\n\n // Load CA key (with optional passphrase)\n const caKeyPem = readFileSync(caKeyPath, 'utf8');\n const caKeyObj = KEYUTIL.getKey(caKeyPem, passphrase);\n\n // Extract issuer from CA certificate\n const caCertPem = readFileSync(caPemPath, 'utf8');\n const caCert = new X509();\n caCert.readCertPEM(caCertPem);\n const issuer = caCert.getSubjectString();\n\n // Use hostname from serverCertificate config\n const hostname = serverCertificate.host;\n\n // Generate server certificate with correct issuer and hostname\n logger.debug(`generating server certificate signed by: ${issuer} for host: ${hostname}`);\n const serverCert = mkcert.generateCert(caKeyObj, issuer, [hostname], false); // false = server cert\n\n // Only save to disk if key or cert paths are explicitly provided\n if (ssl.key || ssl.cert) {\n const keyPath = ssl.key || './gateway-server.key';\n const certPath = ssl.cert || './gateway-server.crt';\n\n // Ensure directory exists for key\n const keyDir = dirname(keyPath);\n if (keyDir && keyDir !== '.' && !existsSync(keyDir)) {\n mkdirSync(keyDir, { recursive: true });\n }\n // Ensure directory exists for cert\n const certDir = dirname(certPath);\n if (certDir && certDir !== '.' && certDir !== keyDir && !existsSync(certDir)) {\n mkdirSync(certDir, { recursive: true });\n }\n\n writeFileSync(keyPath, serverCert.key, { mode: 0o600 });\n writeFileSync(certPath, serverCert.cert, { mode: 0o644 });\n\n logger.info(`generated server certificate saved to ${certPath} with private key in ${keyPath}${passphrase ? ' (password-protected)' : ''}`);\n } else {\n logger.info(`using in-memory server certificate for host: ${hostname}`);\n }\n const result: TlsOptions = {\n key: serverCert.key,\n cert: serverCert.cert,\n ...commonOptions\n };\n\n // Only set ca if requestCert is true (ca is for validating client certificates)\n // At this point, CA file is guaranteed to exist (either pre-existing or just generated)\n if (ssl.requestCert && ssl.ca && existsSync(caPemPath)) {\n result.ca = readFileSync(caPemPath);\n }\n\n return result;\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["index_exports", "__export", "server_exports", "index_default", "__toCommonJS", "server_exports", "__export", "Factory", "VERSION", "import_node_http", "import_node_https", "import_node_async_hooks", "import_node_os", "PORT_RANGE_MATCHER", "validPort", "port", "portRange", "trimmed", "matchResult", "start", "end", "i", "localIp", "first", "a", "addresses", "details", "info", "acc", "addressAndPort", "address", "GatewayLogging", "getLogger", "name", "regexAwareReplacer", "_key", "value", "import_gateway", "import_node_async_hooks", "log", "getLogger", "codec", "principalName", "authentication", "name", "principal", "initClient", "gateway", "socket", "authenticationPromise", "remoteAddress", "key", "addressAndPort", "host", "opts", "err", "reason", "data", "create", "environment", "handshake", "logPrefix", "principalPromise", "user", "gw", "client", "contextFn", "_isBinary", "code", "core_default", "import_gateway", "log", "getLogger", "generateRandomGatewayId", "GatewayManager", "#defaultGatewayId", "#defaultGateway", "#managedGateways", "#principalToGatewayId", "#config", "#started", "#environment", "config", "environment", "principal", "gatewayId", "gateway", "allGateways", "gId", "id", "handler", "opts", "compose", "middleware", "fns", "fn", "ctx", "next", "dispatch", "dispatchedCtx", "nextCalled", "nextResolved", "result", "nextCtx", "import_node_net", "import_tough_cookie", "parseHost", "headers", "defaultHost", "host", "port", "isForwardedSsl", "v", "parseProtocol", "defaultProtocol", "proto", "parseRemoteAddress", "url", "remoteAddress", "AbstractHttpMessage", "#headers", "AbstractHttpRequest", "_AbstractHttpRequest", "#id", "parseCookies", "AbstractHttpResponse", "parseResponseCookies", "responseCookie", "parseHeader", "value", "list", "start", "end", "i", "toList", "values", "s", "cs", "tc", "cookie", "parsed", "result", "AbstractHttpHeaders", "name", "MapHttpHeaders", "prev", "DefaultHttpStatusCode", "#value", "value", "HttpStatus", "_HttpStatus", "#VALUES", "key", "code", "status", "#phrase", "phrase", "httpStatusCode", "import_node_http", "ExtendedHttpIncomingMessage", "http", "ExtendedHttpServerResponse", "AbstractServerHttpRequest", "AbstractHttpRequest", "#sslInfo", "AbstractServerHttpResponse", "AbstractHttpResponse", "#cookies", "#statusCode", "#state", "#commitActions", "statusCode", "httpStatusCode", "cookie", "action", "state", "body", "buffer", "error", "writeAction", "allActions", "acc", "cur", "_error", "HttpServerRequest", "#url", "#req", "req", "IncomingMessageHeaders", "dh", "dp", "family", "address", "port", "remoteAddress", "DefaultSslInfo", "chunks", "chunk", "text", "blob", "remoteIp", "socket", "AbstractHttpHeaders", "#msg", "msg", "name", "value", "OutgoingMessageHeaders", "v", "HttpServerResponse", "#res", "res", "status", "resolve", "reject", "e", "ServerHttpRequestDecorator", "_ServerHttpRequestDecorator", "#delegate", "request", "ServerHttpResponseDecorator", "_ServerHttpResponseDecorator", "response", "ServerWebExchangeDecorator", "_ServerWebExchangeDecorator", "exchange", "DefaultWebExchange", "#attributes", "#logId", "#logPrefix", "LOG_ID_ATTRIBUTE", "import_node_v8", "import_promises", "log", "getLogger", "DEFAULT_OPTIONS", "fetchStats", "dumpHeap", "opts", "prefix", "target", "fileExists", "_", "dumpFileName", "lastFileName", "e", "i", "currentFileName", "nextFileName", "firstFileName", "path", "processStats", "stats", "state", "limit", "used", "start", "merged", "stopped", "report", "interval", "command", "run", "channel", "stop", "m", "serverHeader", "version", "server", "response", "next", "server_header_default", "import_gateway", "log", "getLogger", "acceptsMissing", "originFilters", "tryMatch", "origin", "block", "allow", "acceptsNonMatched", "acceptsOrigin", "matchResult", "regexifyOriginFilters", "or", "matchers", "exchange", "matcher", "match", "NO_MATCH", "and", "m", "not", "anyExchange", "_exchange", "EMPTY_OBJECT", "variables", "pattern", "opts", "method", "request", "path", "mediaType", "shouldIgnore", "requestedMediaType", "ignoredMediaType", "requestMediaTypes", "upgradeMatcher", "import_gateway", "configure", "app", "config", "routes", "applyCors", "request", "options", "cors", "path", "configurer", "handlers", "handler", "matcher", "pattern", "middleware", "exchange", "next", "match", "variables", "sockets", "factory", "route", "regexifyOriginFilters", "import_gateway", "isSameOrigin", "request", "origin", "url", "actualProtocol", "actualHost", "originUrl", "originHost", "originProtocol", "isCorsRequest", "isPreFlightRequest", "VARY_HEADERS", "processRequest", "exchange", "config", "response", "responseHeaders", "varyHeaders", "header", "h", "logger", "rejectRequest", "preFlightRequest", "handleInternal", "DEFAULT_PERMIT_ALL", "DEFAULT_PERMIT_METHODS", "PERMIT_DEFAULT_CONFIG", "validateCorsConfig", "allowHeaders", "ALL", "allowOrigins", "validateAllowCredentials", "validateAllowPrivateNetwork", "trimTrailingSlash", "combine", "source", "other", "combined", "v", "combineCorsConfig", "corsFilter", "opts", "processor", "ctx", "next", "cors_default", "getLogger", "HttpStatus", "requestOrigin", "allowOrigin", "checkOrigin", "requestMethod", "getMethodToUse", "allowMethods", "checkMethods", "requestHeaders", "getHeadersToUse", "checkHeaders", "exposeHeaders", "DEFAULT_METHODS", "allowedOrigins", "originToCheck", "allowedOrigin", "allowedMethods", "allowedHeaders", "allowAnyHeader", "result", "requestHeader", "value", "allowedHeader", "isPreFlight", "headers", "matchingCorsConfigSource", "matcher", "import_gateway", "createCorsConfigSource", "context", "routes", "cors", "defaultCorsConfig", "combineCorsConfig", "PERMIT_DEFAULT_CONFIG", "validatedConfigs", "path", "route", "routeCorsConfig", "matcher", "config", "and", "upgradeMatcher", "pattern", "validateCorsConfig", "appConfigs", "m", "added", "entry", "matchingCorsConfigSource", "isAuthentication", "principal", "AuthenticationError", "value", "InsufficientAuthenticationError", "BadCredentialsError", "AccountStatusError", "message", "LockedError", "DisabledError", "AccountExpiredError", "CredentialsExpiredError", "AccessDeniedError", "AuthorizationDecision", "granted", "DefaultAuthorizationManager", "#check", "check", "authentication", "object", "AuthenticationServiceError", "AuthenticationError", "staticServerHttpHeadersWriter", "headers", "exchange", "containsNoHeaders", "response", "name", "value", "cacheControlServerHttpHeadersWriter", "MapHttpHeaders", "contentTypeServerHttpHeadersWriter", "strictTransportSecurityServerHttpHeadersWriter", "maxAgeInSeconds", "includeSubDomains", "preload", "headerValue", "delegate", "isSecure", "frameOptionsServerHttpHeadersWriter", "mode", "xssProtectionServerHttpHeadersWriter", "permissionsPolicyServerHttpHeadersWriter", "policyDirectives", "contentSecurityPolicyServerHttpHeadersWriter", "reportOnly", "headerName", "refererPolicyServerHttpHeadersWriter", "policy", "crossOriginOpenerPolicyServerHttpHeadersWriter", "crossOriginEmbedderPolicyServerHttpHeadersWriter", "crossOriginResourcePolicyServerHttpHeadersWriter", "compositeServerHttpHeadersWriter", "writers", "writer", "opts", "next", "serverAuthenticationEntryPointFailureHandler", "opts", "entryPoint", "rethrowAuthenticationServiceError", "exchange", "error", "AuthenticationServiceError", "DEFAULT_REALM", "createHeaderValue", "realm", "httpBasicEntryPoint", "opts", "headerValue", "exchange", "_error", "response", "HttpStatus", "BASIC", "httpBasicAuthenticationConverter", "opts", "credentialsEncoding", "exchange", "request", "authorization", "credentials", "parts", "principal", "erasableCredentials", "import_node_async_hooks", "AsyncStorageSecurityContextHolder", "_AsyncStorageSecurityContextHolder", "storage", "securityContext", "authentication", "authenticate", "exchange", "next", "token", "managerResolver", "successHandler", "storage", "authentication", "onAuthenticationSuccess", "e", "AuthenticationError", "filterExchange", "AsyncStorageSecurityContextHolder", "authenticationFilter", "opts", "auth", "anyExchange", "httpBasicAuthenticationConverter", "serverAuthenticationEntryPointFailureHandler", "httpBasicEntryPoint", "manager", "_exchange", "error", "httpStatusEntryPoint", "opts", "exchange", "_error", "logger", "getLogger", "delegatingEntryPoint", "opts", "defaultEntryPoint", "response", "_error", "HttpStatus", "exchange", "error", "matcher", "entryPoint", "delegatingSuccessHandler", "handlers", "exchange", "next", "authentication", "handler", "httpBasic", "opts", "xhrMatcher", "exchange", "match", "NO_MATCH", "defaultEntryPoint", "delegatingEntryPoint", "httpStatusEntryPoint", "HttpStatus", "httpBasicEntryPoint", "entryPoint", "manager", "restMatcher", "mediaType", "notHtmlMatcher", "not", "restNoHtmlMatcher", "and", "preferredMatcher", "or", "failureHandler", "serverAuthenticationEntryPointFailureHandler", "successHandler", "delegatingSuccessHandler", "converter", "httpBasicAuthenticationConverter", "authenticationFilter", "BearerTokenErrorCodes", "DEFAULT_URI", "invalidToken", "message", "HttpStatus", "invalidRequest", "ACCESS_TOKEN_PARAMETER_NAME", "authorizationPattern", "Oauth2AuthenticationError", "AuthenticationError", "error", "message", "options", "isBearerTokenAuthenticationToken", "authentication", "serverBearerTokenAuthenticationConverter", "opts", "exchange", "request", "resolveFromAuthorizationHeader", "token", "resolveFromQueryString", "resolveFromBody", "rs", "r", "resolveToken", "accessTokens", "invalidRequest", "accessToken", "headers", "headerName", "authorization", "match", "invalidToken", "resolveTokens", "parameters", "allow", "token_converter_default", "computeWWWAuthenticate", "parameters", "wwwAuthenticate", "i", "key", "value", "isBearerTokenError", "error", "getStatus", "authError", "Oauth2AuthenticationError", "HttpStatus", "createParameters", "realm", "bearerTokenServerAuthenticationEntryPoint", "opts", "exchange", "status", "response", "token_entry_point_default", "jwtAuthConverter", "opts", "principalClaimName", "jwt", "asyncJwtConverter", "converter", "JwtError", "BadJwtError", "onError", "error", "Oauth2AuthenticationError", "invalidToken", "AuthenticationServiceError", "jwtAuthManager", "decoder", "authConverter", "authentication", "isBearerTokenAuthenticationToken", "token", "e", "resourceServer", "opts", "entryPoint", "token_entry_point_default", "converter", "token_converter_default", "failureHandler", "serverAuthenticationEntryPointFailureHandler", "authenticationFilter", "manager", "jwtAuthManager", "_exchange", "import_jwt", "commenceAuthentication", "exchange", "authentication", "entryPoint", "cause", "InsufficientAuthenticationError", "e", "AuthenticationError", "httpStatusAccessDeniedHandler", "httpStatus", "_error", "buffer", "errorFilter", "opts", "accessDeniedHandler", "HttpStatus", "authenticationEntryPoint", "httpBasicEntryPoint", "next", "error", "AccessDeniedError", "principal", "isAuthentication", "logger", "getLogger", "delegatingAuthorizationManager", "opts", "check", "authentication", "exchange", "decision", "matcher", "manager", "checkResult", "AuthorizationDecision", "DefaultAuthorizationManager", "logger", "getLogger", "authorizationFilter", "opts", "manager", "storage", "exchange", "next", "promise", "AsyncStorageSecurityContextHolder", "c", "error", "AccessDeniedError", "SecurityContextServerWebExchange", "ServerWebExchangeDecorator", "#context", "exchange", "context", "exchangeFilter", "opts", "storage", "next", "AsyncStorageSecurityContextHolder", "x509Converter", "opts", "principalExtractor", "exchange", "sslInfo", "clientCertificate", "principal", "subjectX500PrincipalExtractor", "opts", "extractFromEmail", "subjectDnRegEx", "cert", "email", "altName", "result", "BadCredentialsError", "AbstractPasswordEncoder", "rawPassword", "encodedPassword", "DelegatingPasswordEncoder", "_DelegatingPasswordEncoder", "#idPrefix", "#idSuffix", "#idForEncode", "#encoderForEncode", "#encoders", "#defaultEncoderForMatches", "#outer", "outer", "prefixEncodedPassword", "id", "#extractId", "start", "end", "idForEncode", "encoders", "idPrefix", "idSuffix", "encoder", "encoded", "delegate", "#extractEncodedPassword", "NoopPasswordEncoder", "_NoopPasswordEncoder", "#INSTANCE", "import_tools", "bufferEquals", "a", "b", "diff", "i", "Argon2PasswordEncoder", "AbstractPasswordEncoder", "#saltLength", "#hashLength", "#parallelism", "#memory", "#passes", "saltLength", "hashLength", "parallelism", "memory", "passes", "rawPassword", "encodedPassword", "decoded", "hash", "nonce", "parameters", "MAX_PASSWORD_LENGTH", "createDelegatingPasswordEncoder", "idForEncode", "encoders", "Argon2PasswordEncoder", "NoopPasswordEncoder", "DelegatingPasswordEncoder", "NoopUserDetailsPasswordService", "user", "_newPassword", "UsernameNotFoundError", "AuthenticationError", "message", "username", "options", "UserBuilder", "_UserBuilder", "#username", "#password", "#authorities", "#accountExpired", "#accountLocked", "#credentialsExpired", "#disabled", "#passwordEncoder", "rawPassword", "builder", "password", "encoder", "roles", "role", "authorities", "accountExpired", "accountLocked", "credentialsExpired", "disabled", "encodedPassword", "logger", "getLogger", "userDetailsServiceAuthenticationManager", "userDetailsService", "options", "preAuthenticationChecks", "user", "LockedError", "DisabledError", "AccountExpiredError", "postAuthenticationChecks", "CredentialsExpiredError", "passwordEncoder", "createDelegatingPasswordEncoder", "userDetailsPasswordService", "NoopUserDetailsPasswordService", "upgradeEncodingIfNeeded", "userDetails", "presentedPassword", "existingEncodedPassword", "newEncodedPassword", "authentication", "username", "BadCredentialsError", "principal", "credentials", "accountStatusUserDetailsChecker", "preAuthenticatedAuthenticationManager", "opts", "userDetailsChecker", "supports", "UsernameNotFoundError", "erasableCredentials", "x509", "opts", "manager", "preAuthenticatedAuthenticationManager", "principalExtractor", "subjectX500PrincipalExtractor", "converter", "x509Converter", "authenticationFilter", "filterOrder", "filterOrderSymbol", "config_default", "config", "context", "getService", "name", "defaultService", "authenticationManager", "userDetailsServiceAuthenticationManager", "middleware", "ServerHttpSecurity", "#authenticationEntryPoint", "#defaultEntryPoints", "#authenticationManager", "delegatingEntryPoint", "writer", "headers", "filter", "x509", "subjectX500PrincipalExtractor", "cors_default", "defaultSuccessHandlers", "_", "next", "_authentication", "httpBasic", "verifier", "decoder", "token", "payload", "claim", "e", "BadJwtError", "JwtError", "authenticationConverter", "token_converter_default", "authenticationConverterMatcher", "exchange", "NO_MATCH", "match", "entryPoint", "token_entry_point_default", "resourceServer", "exchangeF", "exchangeFilter", "errorFf", "errorFilter", "manager", "authorize", "mappings", "anyExchangeRegistered", "matcher", "access", "serverMatcher", "anyExchange", "DefaultAuthorizationManager", "AuthorizationDecision", "p", "authentication", "delegatingAuthorizationManager", "authorizationFilter", "a", "b", "aOrder", "bOrder", "security", "MapUserDetailsService", "#users", "users", "user", "#getKey", "username", "key", "result", "newPassword", "userDetails", "import_node_crypto", "logger", "getLogger", "createSecurityConfig", "context", "authorize", "type", "defaultAccess", "path", "route", "rule", "matcher", "pattern", "and", "upgradeMatcher", "createUserDetailsService", "getOrDeducePassword", "user", "encoder", "password", "generatedPassword", "MAX_PASSWORD_LENGTH", "roles", "userDetails", "UserBuilder", "MapUserDetailsService", "httpSecurity", "corsConfigSource", "createCorsConfigSource", "userDetailsService", "config", "storage", "config_default", "import_node_async_hooks", "HttpHeadResponseDecorator", "ServerHttpResponseDecorator", "HandlerAdapter", "#logger", "#enableLoggingRequestDetails", "#delegate", "#storage", "logger", "delegate", "request", "response", "DefaultWebExchange", "storage", "value", "headers", "result", "key", "query", "exchange", "trace", "status", "error", "logPrefix", "HttpStatus", "callback", "resolve", "reject", "WebHttpHandlerBuilder", "#webHandler", "#handlerDecorator", "decorator", "previousDecorator", "handler", "webHandler", "getLogger", "adapter", "adapted", "import_ws", "createHandshakeInfo", "req", "protocol", "exchange", "request", "HttpServerRequest", "principalPromiseProvider", "principal", "url", "headers", "MapHttpHeaders", "key", "cookies", "logPrefix", "remoteAddress", "webSockets", "context", "next", "path", "routes", "route", "response", "upgradeMatchResult", "upgradeMatcher", "HttpStatus", "buffer", "import_ws", "ExtendedWebSocket", "_first", "_second", "options", "PingManager", "_PingManager", "#EMPTY_BUFFER", "#LAST_TIMESTAMP_BUFFER", "#pingData", "#pingInterval", "#pingIntervalId", "#mask", "#logger", "logger", "supplier", "ping", "#createBufferFromTimestamp", "path", "clients", "client", "#terminateIfDisconnected", "#markAndSendPing", "data", "err", "now", "buffer", "#createTimestampFromBuffer", "handshake", "socket", "addressAndPort", "sent", "latency", "logger", "getLogger", "upgradeStrategy", "path", "route", "wss", "onSocketError", "exchange", "logPrefix", "request", "req", "ServerHttpRequestDecorator", "socket", "upgradeHead", "host", "origin", "acceptsOrigin", "client", "applyHandshakeHeaders", "headers", "response", "seen", "header", "index", "HttpStatus", "name", "value", "nativeResponse", "ServerHttpResponseDecorator", "nameLowerCase", "initRoute", "endpoint", "storage", "regexAwareReplacer", "ExtendedWebSocket", "pings", "PingManager", "handler", "err", "handshake", "createHandshakeInfo", "data", "e", "import_node_fs", "import_node_path", "import_jsrsasign", "import_tools", "logger", "getLogger", "secureContextOptions", "ssl", "serverCertificate", "commonOptions", "options", "defaultKeyPath", "defaultCertPath", "caKeyPath", "caPemPath", "passphrase", "rootCA", "keyDir", "certDir", "caKeyPem", "caKeyObj", "caCertPem", "caCert", "issuer", "hostname", "serverCert", "keyPath", "certPath", "result", "import_package", "logger", "getLogger", "createListener", "builder", "onSocketError", "httpHandler", "req", "resOrUpgradeHead", "res", "ExtendedHttpServerResponse", "request", "HttpServerRequest", "response", "HttpServerResponse", "decoratedResponse", "HttpHeadResponseDecorator", "promisify", "fn", "resolve", "reject", "r", "err", "memoryMonitor", "config", "start", "VERSION", "info", "initBuilder", "context", "storage", "security", "httpSecurity", "sockets", "webSockets", "handler", "compose", "server_header_default", "next", "HttpStatus", "buffer", "_next", "WebHttpHandlerBuilder", "Factory", "options", "ssl", "host", "serverCertificate", "createServer", "https", "secureContextOptions", "http", "monitor", "gatewayManager", "GatewayManager", "configure", "configurer", "core_default", "ports", "portRange", "listener", "server", "ExtendedHttpIncomingMessage", "e", "port", "path", "route", "endpoint", "localIp", "initRoute", "addressAndPort", "_socket", "head", "address", "cb", "stop", "index_default", "Factory"]
|
|
3
|
+
"sources": ["../src/index.ts", "../src/server.ts", "../src/server/address.ts", "../src/logger.ts", "../src/gateway/ws/core.ts", "../src/gateway/gateway-manager.ts", "../src/gateway/config.ts", "../src/common/compose.ts", "../src/http/exchange.ts", "../src/http/status.ts", "../src/server/exchange.ts", "../src/server/monitoring.ts", "../src/server/server-header.ts", "../src/server/ws-client-verify.ts", "../src/server/util/matchers.ts", "../src/app/route.ts", "../src/server/cors.ts", "../src/app/cors.ts", "../src/server/security/types.ts", "../src/server/security/http-headers.ts", "../src/server/security/entry-point-failure-handler.ts", "../src/server/security/http-basic-entry-point.ts", "../src/server/security/http-basic-converter.ts", "../src/server/security/security-context.ts", "../src/server/security/authentication-filter.ts", "../src/server/security/http-status-entry-point.ts", "../src/server/security/delegating-entry-point.ts", "../src/server/security/delegating-success-handler.ts", "../src/server/security/http-basic.ts", "../src/server/security/oauth2/token-error.ts", "../src/server/security/oauth2/token-converter.ts", "../src/server/security/oauth2/token-entry-point.ts", "../src/server/security/oauth2/jwt-auth-manager.ts", "../src/server/security/oauth2-resource-server.ts", "../src/server/security/config.ts", "../src/server/security/error-filter.ts", "../src/server/security/delegating-authorization-manager.ts", "../src/server/security/authorization-filter.ts", "../src/server/security/exchange-filter.ts", "../src/server/security/x509-converter.ts", "../src/server/security/preauth/x509.ts", "../src/server/security/crypto/password.ts", "../src/server/security/crypto/argon2.ts", "../src/server/security/crypto/index.ts", "../src/server/security/users/types.ts", "../src/server/security/users.ts", "../src/server/security/x509.ts", "../src/server/security/users/memory.ts", "../src/app/auth.ts", "../src/server/handler.ts", "../src/server/ws.ts", "../src/server/socket.ts", "../src/server/ws-pings.ts", "../src/server/ssl/config.ts", "../src/server/welcome-page.ts"],
|
|
4
|
+
"sourcesContent": ["import * as GatewayServer from './server.ts';\n\nexport { GatewayServer };\nexport default GatewayServer.Factory;\n", "import http from 'node:http';\nimport https from 'node:https';\nimport type { AddressInfo, Socket } from 'node:net';\nimport { AsyncLocalStorage } from 'node:async_hooks';\nimport wsGateway from './gateway/ws/core.ts';\nimport { GatewayManager } from './gateway/gateway-manager.ts';\nimport { compose } from './common/compose.ts';\nimport {\n ExtendedHttpIncomingMessage,\n ExtendedHttpServerResponse,\n HttpServerRequest,\n HttpServerResponse\n} from './server/exchange.ts';\nimport getLogger from './logger.ts';\nimport { addressAndPort, localIp, portRange } from './server/address.ts';\nimport * as monitoring from './server/monitoring.ts';\nimport { GatewayServer } from '@interopio/gateway-server';\nimport serverHeader from './server/server-header.ts';\nimport { configure, type RouteConfig } from './app/route.ts';\nimport { httpSecurity } from './app/auth.ts';\nimport type { ServerConfigurer, ServerHttpResponse, ServerWebExchange } from '../types/web/server';\nimport { HttpHeadResponseDecorator, WebHttpHandlerBuilder } from './server/handler.ts';\nimport { initRoute } from './server/ws.ts';\nimport { type SocketRoute, webSockets } from './server/socket.ts';\nimport { HttpStatus } from './http/status.ts';\nimport { secureContextOptions } from './server/ssl/config.ts';\n\nconst logger = getLogger('app');\n\n\ntype RequestListener<\n Request extends typeof ExtendedHttpIncomingMessage = typeof ExtendedHttpIncomingMessage,\n Response extends typeof ExtendedHttpServerResponse<InstanceType<Request>> = typeof ExtendedHttpServerResponse,\n> = (req: InstanceType<Request>, resOrUpgradeHead: (InstanceType<Response> & { req: InstanceType<Request> }) | Buffer<ArrayBufferLike>) => void;\n\ntype ServerOptions = http.ServerOptions<typeof ExtendedHttpIncomingMessage, typeof ExtendedHttpServerResponse>;\n\nasync function createListener(builder: WebHttpHandlerBuilder,\n onSocketError: (err: Error) => void): Promise<RequestListener> {\n\n const httpHandler = builder.build();\n return async (req: ExtendedHttpIncomingMessage, resOrUpgradeHead: ExtendedHttpServerResponse | Buffer<ArrayBufferLike>) => {\n req.socket.addListener('error', onSocketError);\n let res: ExtendedHttpServerResponse;\n if (resOrUpgradeHead instanceof ExtendedHttpServerResponse) {\n res = resOrUpgradeHead;\n }\n else {\n req.upgradeHead = resOrUpgradeHead;\n res = new ExtendedHttpServerResponse(req);\n res.assignSocket(req.socket);\n }\n const request = new HttpServerRequest(req);\n const response = new HttpServerResponse(res);\n const decoratedResponse: ServerHttpResponse = request.method === 'HEAD' ? new HttpHeadResponseDecorator(response) : response;\n\n await httpHandler(request, decoratedResponse)\n\n };\n}\n\nfunction promisify<T>(fn: (callback?: (err?: Error) => void) => T): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n const r = fn((err?: Error) => {\n if (err) {\n reject(err);\n } else {\n resolve(r);\n }\n });\n });\n}\n\nfunction memoryMonitor(config?: GatewayServer.ServerConfig['memory']) {\n if (config) {\n return monitoring.start({\n memoryLimit: config.memory_limit,\n dumpLocation: config.dump_location,\n dumpPrefix: config.dump_prefix,\n reportInterval: config.report_interval,\n maxBackups: config.max_backups\n });\n }\n}\n\nimport info from '@interopio/gateway-server/package.json' with { type: 'json' };\nimport welcomePage from './server/welcome-page.ts';\nexport const VERSION = `${info.name} - v${info.version}`;\n\nasync function initBuilder(context: RouteConfig) {\n const storage = context.storage;\n const security = await httpSecurity(context);\n // websocket upgrade handler\n const sockets = webSockets(context);\n const handler = compose<ServerWebExchange>(\n serverHeader(VERSION, context.serverHeader),\n ...security,\n ...sockets,\n ...context.middleware,\n // health check\n async ({ request, response }, next) => {\n if (request.method === 'GET' && request.path === '/health') {\n response.setStatusCode(HttpStatus.OK);\n const buffer = Buffer.from('UP', 'utf-8');\n response.headers.set('Content-Type', 'text/plain; charset=utf-8');\n await response.body(buffer);\n }\n else {\n await next();\n }\n },\n await welcomePage(context.resourcesConfig?.locations),\n // not found\n async ({response}, _next) => {\n response.setStatusCode(HttpStatus.NOT_FOUND);\n await response.end();\n }\n );\n\n return new WebHttpHandlerBuilder(handler).storage(storage);\n}\n\nexport const Factory = async (options: GatewayServer.ServerConfig): Promise<GatewayServer.Server> => {\n const ssl = options.ssl;\n const host = options.host;\n\n // Build serverCertificate config if auth.x509.key is provided\n const serverCertificate = options.auth?.x509?.key ? {\n host: host ?? 'localhost',\n key: options.auth.x509.key,\n passphrase: options.auth.x509.passphrase\n } : undefined;\n\n const createServer = ssl\n ? (options: ServerOptions, handler: RequestListener) => https.createServer({...options, ...secureContextOptions(ssl, serverCertificate)}, handler)\n : (options: ServerOptions, handler: RequestListener) => http.createServer(options, handler);\n const monitor = memoryMonitor(options.memory);\n const context: RouteConfig = {\n middleware: [],\n corsConfig: options.cors,\n cors: [],\n authConfig: options.auth,\n authorize: [],\n storage: new AsyncLocalStorage<{ exchange: ServerWebExchange }>(),\n sockets: new Map<string, SocketRoute>(),\n resourcesConfig: options.resources,\n };\n\n // Create gateway manager to handle default and per-principal gateway instances\n const gatewayManager = new GatewayManager({\n baseConfig: { ...(options.gateway) },\n scope: options.gateway?.scope ?? 'principal'\n });\n\n if (options.gateway) {\n const path = options.gateway.route ? (options.gateway.route === '/' ? undefined : options.gateway.route) : undefined;\n\n await configure(async (configurer: ServerConfigurer) => {\n configurer.socket({ path, factory: wsGateway.bind(gatewayManager), options: options.gateway })\n }, options, context);\n\n }\n if (options.app) {\n await configure(options.app, options, context)\n }\n\n const ports = portRange(options.port ?? 0);\n const onSocketError = (err: Error) => logger.error(`socket error: ${err}`, err);\n const builder = await initBuilder(context);\n\n const listener = await createListener(builder, onSocketError);\n\n const serverP = new Promise<http.Server<typeof ExtendedHttpIncomingMessage, typeof ExtendedHttpServerResponse>>((resolve, reject) => {\n\n const server = createServer({\n IncomingMessage: ExtendedHttpIncomingMessage,\n ServerResponse: ExtendedHttpServerResponse,\n ...options.http\n }, listener);\n\n server.on('error', (e: Error) => {\n if (e['code'] === 'EADDRINUSE') {\n logger.debug(`port ${e['port']} already in use on address ${e['address']}`);\n const {value: port} = ports.next();\n if (port) {\n logger.info(`retry starting server on port ${port} and host ${host ?? '<unspecified>'}`);\n server.close();\n server.listen(port, host);\n } else {\n logger.warn(`all configured port(s) ${options.port} are in use. closing...`);\n server.close();\n reject(e);\n }\n } else {\n logger.error(`server error: ${e.message}`, e);\n reject(e);\n }\n });\n server\n .on('listening', async () => {\n const info = server.address() as AddressInfo;\n\n for (const [path, route] of context.sockets) {\n const endpoint = `${ssl ? 'wss' : 'ws'}://${localIp}:${info.port}${path}`;\n await initRoute(path, route, endpoint, context.storage, onSocketError);\n }\n logger.info(`http server listening on ${ ssl ? 'https' : 'http' }://${addressAndPort(info)}`);\n resolve(server);\n });\n server\n .on('upgrade', (req: ExtendedHttpIncomingMessage, _socket: Socket, head: Buffer<ArrayBufferLike>) => {\n try {\n listener(req, head);\n } catch (err) {\n logger.error(`upgrade error: ${err}`, err);\n }\n })\n .on('close', async () => {\n logger.info(`http server closed.`);\n });\n try {\n const {value: port} = ports.next();\n server.listen(port, host);\n } catch (e) {\n logger.error(`error starting web socket server`, e);\n reject(e instanceof Error ? e : new Error(`listen failed: ${e}`));\n }\n });\n const server = await serverP;\n return new class implements GatewayServer.Server {\n // Expose the gateway manager which implements ScopedGateway\n readonly gateway = gatewayManager;\n\n get address(): AddressInfo | null {\n const address = server.address();\n return typeof address === 'object' ? address : null;\n }\n\n async close(): Promise<void> {\n for (const [path, route] of context.sockets) {\n try {\n if (route.close !== undefined) {\n await route.close();\n }\n } catch (e) {\n logger.warn(`error closing route ${path}`, e);\n }\n }\n await promisify(cb => {\n server.closeAllConnections();\n server.close(cb);\n });\n if (monitor) {\n await monitoring.stop(monitor);\n }\n // Stop all gateways (default + per-principal)\n await gatewayManager.stop();\n }\n }\n}\n", "import type { AddressInfo } from 'node:net';\nimport { type NetworkInterfaceInfo, networkInterfaces } from 'node:os';\n\nconst PORT_RANGE_MATCHER = /^(\\d+|(0x[\\da-f]+))(-(\\d+|(0x[\\da-f]+)))?$/i;\nfunction validPort(port: number) {\n if (port > 0xFFFF) throw new Error(`bad port ${port}`);\n return port;\n}\n\n/**\n * parse port range. port can be number or string representing comma separated\n * list of port ranges for e.g. \"3434,8380-8385\"\n * @param port\n */\nexport function* portRange(port: number | string): Generator<number> {\n if (typeof port === 'string') {\n for (const portRange of port.split(',')) {\n const trimmed = portRange.trim();\n const matchResult = PORT_RANGE_MATCHER.exec(trimmed);\n if (matchResult) {\n const start = parseInt(matchResult[1]);\n const end = parseInt(matchResult[4] ?? matchResult[1]);\n for (let i = validPort(start); i < validPort(end) + 1; i++) {\n yield i;\n }\n }\n else {\n throw new Error(`'${portRange}' is not a valid port or range.`);\n }\n }\n } else {\n yield validPort(port);\n }\n}\n\nexport const localIp = (() => {\n function first<T>(a: T[]): T | undefined {\n return a.length > 0 ? a[0] : undefined;\n }\n const addresses = Object.values(networkInterfaces())\n .flatMap((details?: NetworkInterfaceInfo[]) => {\n return (details ?? []).filter((info) => info.family === 'IPv4');\n }).reduce((acc, info) => {\n acc[info.internal ? 'internal' : 'external'].push(info);\n return acc;\n }, {internal: [] as NetworkInterfaceInfo[], external: [] as NetworkInterfaceInfo[]});\n return (first(addresses.internal) ?? first(addresses.external))?.address;\n})();\n\nexport function addressAndPort(address?: AddressInfo) {\n if (address) {\n if (address.family === 'IPv6') {\n return `[${address.address}]:${address.port}`;\n }\n return `${address.address}:${address.port}`;\n }\n}\n", "import * as GatewayLogging from '@interopio/gateway/logging/core';\n\nexport type Logger = GatewayLogging.Logger;\n\nexport default function getLogger(name: string): Logger {\n return GatewayLogging.getLogger(`gateway.server.${name}`);\n}\n\n// This function is used to ensure that RegExp objects are displayed correctly when logging.\nexport function regexAwareReplacer<T>(_key: string, value: T): string | T {\n return value instanceof RegExp ? value.toString() : value;\n}\n", "import { addressAndPort } from '../../server/address.ts';\nimport type { WebSocket } from 'ws';\nimport getLogger from '../../logger.ts';\nimport type { Authentication } from '../../server/security/types.ts';\nimport { IOGateway } from '@interopio/gateway';\nimport { GatewayManager } from '../gateway-manager.ts';\n\nimport type {ServerWebSocketHandler} from '../../../types/web/server';\nimport type {AddressInfo} from 'node:net';\nimport {AsyncLocalStorage} from 'node:async_hooks';\n\nconst log = getLogger('ws');\nconst codec = IOGateway.Encoding.json<IOGateway.Message>();\n\nfunction principalName(authentication: Authentication): string | undefined {\n let name: string | undefined;\n if (authentication.authenticated) {\n name = authentication.name;\n if (name === undefined) {\n if (authentication['principal'] !== undefined) {\n const principal = authentication['principal'];\n if (typeof principal === 'object' && principal !== null && ('username' in principal || 'name' in principal)) {\n name = (principal as { username?: string }).username ?? (principal as { name?: string }).name;\n }\n if (name === undefined) {\n if (principal === undefined || principal === null) {\n name = '';\n }\n else {\n name = String(principal);\n }\n }\n }\n }\n }\n return name;\n}\n\nfunction initClient(gateway: IOGateway.Gateway,\n socket: WebSocket,\n authenticationPromise: () => Promise<Authentication | undefined>,\n remoteAddress?: AddressInfo\n): IOGateway.GatewayClient<string> | undefined {\n const key = addressAndPort(remoteAddress);\n const host = remoteAddress?.address ?? '<unknown>';\n const opts = {\n key,\n host,\n codec,\n onAuthenticate: async (): Promise<IOGateway.Auth.AuthenticationSuccess> => {\n const authentication = (await authenticationPromise());\n if (authentication?.authenticated) {\n return {type: 'success', user: principalName(authentication)};\n }\n throw new Error(`no valid client authentication ${key}`);\n },\n onPing: () => {\n socket.ping((err?: Error) => {\n if (err) {\n log.warn(`failed to ping ${key}`, err);\n }\n else {\n log.info(`ping sent to ${key}`);\n }\n });\n },\n onDisconnect: (reason: 'inactive' | 'shutdown') => {\n switch (reason) {\n case 'inactive': {\n log.warn(`no heartbeat (ping) received from ${key}, closing socket`);\n socket.close(4001, 'ping expected');\n break;\n }\n case 'shutdown': {\n socket.close(1001, 'shutdown');\n break;\n }\n }\n }\n };\n try {\n return gateway.client((data) => socket.send(data), opts as IOGateway.GatewayClientOptions<string>);\n } catch (err) {\n log.warn(`${key} failed to create client`, err);\n }\n}\n\nasync function create(this: GatewayManager, environment: {\n endpoint: string,\n storage?: AsyncLocalStorage<{ }>\n}): Promise<ServerWebSocketHandler> {\n log.info(`starting gateway on ${environment.endpoint}`);\n await this.start(environment);\n\n\n return async ({socket, handshake}) => {\n const { logPrefix, remoteAddress, principal: principalPromise } = handshake;\n const user = (await principalPromise())?.name;\n log.info(`${logPrefix}connected on gw as ${user ?? '<anonymous>'}`);\n\n const gw = await this.getGateway(user);\n const client = initClient(gw, socket, principalPromise, remoteAddress);\n if (!client) {\n log.error(`${logPrefix}gw client init failed`);\n socket.terminate();\n return;\n }\n socket.on('error', (err: Error) => {\n log.error(`${logPrefix}websocket error: ${err}`, err);\n });\n\n const contextFn = environment.storage !== undefined ? AsyncLocalStorage.snapshot() : undefined;\n socket.on('message', (data, _isBinary) => {\n if (Array.isArray(data)) {\n data = Buffer.concat(data);\n }\n // JSON.parse will invoke abstract operation ToString (coerce it) prior parsing (https://262.ecma-international.org/5.1/#sec-15.12.2)\n if (contextFn !== undefined) {\n contextFn(() => client.send(data as unknown as string))\n }\n else {\n client.send(data as unknown as string);\n }\n\n });\n socket.on('close', (code) => {\n log.info(`${logPrefix}disconnected from gw. code: ${code}`);\n client.close();\n });\n }\n}\n\nexport default create;\n", "import { IOGateway } from '@interopio/gateway';\nimport getLogger from '../logger.ts';\nimport type { GatewayServer } from '../../gateway-server.ts';\nimport { processGatewayConfig } from './config.ts';\n\nconst log = getLogger('gateway-manager');\n\nfunction generateRandomGatewayId(): string {\n return globalThis.crypto.randomUUID().replaceAll('-', '');\n}\n\n\nexport interface GatewayManagerConfig {\n /**\n * Base gateway configuration to use for all gateway instances.\n */\n baseConfig: IOGateway.GatewayConfig & {\n metrics?: IOGateway.MetricsConfig & { enabled?: boolean },\n mesh?: IOGateway.MeshConfig & { enabled?: boolean }\n };\n\n /**\n * Gateway scope - determines how gateway instances are managed:\n * - 'principal': Each authenticated principal gets their own gateway instance.\n * A default (shared) gateway instance handles all unauthenticated connections.\n * - 'singleton': All connections share the same gateway instance\n *\n * Default: 'principal'\n */\n scope?: 'singleton' | 'principal';\n}\n\n/**\n * Manages multiple Gateway instances - one default and optionally one per authenticated principal.\n * Each gateway instance gets a unique node ID to ensure proper isolation.\n */\nexport class GatewayManager implements GatewayServer.ScopedGateway {\n readonly #defaultGatewayId: string;\n readonly #defaultGateway: IOGateway.Gateway;\n readonly #managedGateways = new Map<string, IOGateway.Gateway>();\n readonly #principalToGatewayId = new Map<string, string>();\n readonly #config: GatewayManagerConfig;\n #started = false;\n #environment?: { endpoint?: string };\n\n constructor(config: GatewayManagerConfig) {\n this.#config = {\n baseConfig: processGatewayConfig(config.baseConfig),\n scope: config.scope ?? 'principal'\n }\n\n // Use configured gateway ID or generate a random one for the default gateway\n this.#defaultGatewayId = config.baseConfig.node ?? generateRandomGatewayId();\n\n if (log.enabledFor('debug')) {\n log.debug(`creating default gateway with gateway id: ${this.#defaultGatewayId}`);\n }\n\n this.#defaultGateway = IOGateway.Factory({...this.#config.baseConfig, node: this.#defaultGatewayId});\n }\n\n /**\n * Starts the default gateway.\n */\n async start(environment?: { endpoint?: string }): Promise<this> {\n if (this.#started) {\n return this;\n }\n\n // Store environment for use with per-principal gateways\n this.#environment = environment;\n\n log.debug('starting default gateway');\n await this.#defaultGateway.start(environment);\n this.#started = true;\n return this;\n }\n\n /**\n * Gets a gateway instance for the given principal.\n * If scope is 'singleton' or no principal is provided, returns the default gateway.\n * Otherwise, creates a new gateway instance for the principal if it doesn't exist.\n */\n async getGateway(principal?: string): Promise<IOGateway.Gateway> {\n // If scope is singleton or no principal, use default\n if (this.#config.scope === 'singleton' || !principal) {\n return this.#defaultGateway;\n }\n\n // Check if we already have a gateway for this principal\n const gatewayId = this.#principalToGatewayId.get(principal);\n let gateway = gatewayId ? this.#managedGateways.get(gatewayId) : undefined;\n\n if (!gateway) {\n if (log.enabledFor('debug')) {\n log.debug(`no existing gateway for principal '${principal}', creating new one`);\n }\n gateway = await this.#createPrincipalGateway(principal);\n } else {\n if (log.enabledFor('debug')) {\n log.debug(`reusing existing gateway for principal '${principal}'`);\n }\n }\n\n return gateway;\n }\n\n /**\n * Creates a new gateway instance for a specific principal with a unique gateway ID.\n */\n async #createPrincipalGateway(principal: string): Promise<IOGateway.Gateway> {\n const gatewayId = generateRandomGatewayId();\n const config = {\n ...this.#config.baseConfig,\n node: gatewayId\n };\n\n if (log.enabledFor('debug')) {\n log.debug(`creating gateway for principal '${principal}' with gateway id: ${config.node}`);\n }\n const gateway = IOGateway.Factory(config);\n\n // Track the principal-to-gateway ID mapping\n this.#principalToGatewayId.set(principal, gatewayId);\n this.#managedGateways.set(gatewayId, gateway);\n\n // Start the gateway with the same environment as the default gateway\n await gateway.start(this.#environment);\n\n return gateway;\n }\n\n // ScopedGateway interface methods\n\n /**\n * Get all gateway instances including the default.\n */\n getGateways(): Map<string, IOGateway.Gateway> {\n const allGateways = new Map<string, IOGateway.Gateway>(this.#managedGateways);\n allGateways.set(this.#defaultGatewayId, this.#defaultGateway);\n return allGateways;\n }\n\n /**\n * Gets information about specific or all active gateways.\n * - If no gatewayId is provided: returns aggregated info for all gateways (default + managed).\n * - If default gateway ID is provided: returns info only for the default gateway.\n * - If a non-default gateway ID is provided: returns info only for that specific gateway. If not found, throws an error.\n */\n info(gatewayId?: string): Record<string, unknown> {\n // Case 1: Specific non-default gateway ID provided\n if (gatewayId && this.#defaultGatewayId !== gatewayId) {\n const gateway = this.#managedGateways.get(gatewayId);\n if (gateway) {\n return gateway.info();\n } else {\n throw new Error(`no gateway found with ID: ${gatewayId}`);\n }\n }\n\n // Case 2: Default gateway ID explicitly provided - return only default info\n if (gatewayId === this.#defaultGatewayId) {\n return this.#defaultGateway.info();\n }\n\n // Case 3: No gateway ID provided - return aggregated info\n return {\n ...this.#defaultGateway.info(),\n managedGateways: this.#managedGateways.size,\n scope: this.#config.scope\n };\n }\n\n /**\n * Stops specific or all gateway instances.\n * - If no gatewayId is provided: stops all gateways (default + managed), returning the stopped default.\n * - If default gateway ID is provided: stops only the default gateway, leaving managed gateways running.\n * - If a non-default gateway ID is provided: stops only that specific gateway. If not found, throws an error.\n * @param gatewayId - ID of the gateway to stop.\n * @returns stopped gateway instance.\n */\n async stop(gatewayId?: string): Promise<IOGateway.Gateway> {\n // Case 1: Specific non-default gateway ID provided\n if (gatewayId && this.#defaultGatewayId !== gatewayId) {\n const gateway = this.#managedGateways.get(gatewayId);\n if (gateway) {\n log.info(`stopping gateway with ID: ${gatewayId}`);\n await gateway.stop();\n this.#managedGateways.delete(gatewayId);\n\n // Remove principal mapping for this gateway\n for (const [principal, gId] of this.#principalToGatewayId.entries()) {\n if (gId === gatewayId) {\n this.#principalToGatewayId.delete(principal);\n break;\n }\n }\n\n return gateway;\n } else {\n throw new Error(`no gateway found with ID: ${gatewayId}`);\n }\n }\n\n // Case 2: Default gateway ID explicitly provided - stop only default\n if (gatewayId === this.#defaultGatewayId) {\n log.debug('stopping default gateway (managed gateways will continue running)');\n await this.#defaultGateway.stop();\n this.#started = false;\n return this.#defaultGateway;\n }\n\n // Case 3: No gateway ID provided - stop all gateways\n log.info(`stopping all gateways (1 default + ${this.#managedGateways.size} managed)`);\n\n // Stop all managed gateways\n for (const [id, gateway] of this.#managedGateways.entries()) {\n if (log.enabledFor('debug')) {\n log.debug(`stopping gateway with ID: ${id}`);\n }\n await gateway.stop();\n }\n this.#managedGateways.clear();\n this.#principalToGatewayId.clear();\n\n log.debug('stopping default gateway');\n await this.#defaultGateway.stop();\n this.#started = false;\n return this.#defaultGateway;\n }\n\n\n /**\n * Get the gateway ID for a specific principal.\n */\n getPrincipalGatewayId(principal: string): string | undefined {\n return this.#principalToGatewayId.get(principal);\n }\n\n /**\n * Get all principal-to-gateway ID mappings.\n */\n getPrincipalGatewayIds(): Map<string, string> {\n return new Map(this.#principalToGatewayId);\n }\n\n\n // Gateway interface delegation to defaultGateway\n\n /**\n * Get the default gateway instance.\n */\n getDefaultGateway(): IOGateway.Gateway {\n return this.#defaultGateway;\n }\n\n /**\n * Create a gateway client with the specified handler.\n * Delegates to the default gateway.\n */\n client<T = IOGateway.Message>(\n handler: (this: IOGateway.GatewayClient<T>, msg: T) => void,\n opts?: IOGateway.GatewayClientOptions<T>\n ): IOGateway.GatewayClient<T> {\n return this.#defaultGateway.client(handler, opts);\n }\n\n /**\n * Connect to the gateway with the specified handler.\n * Delegates to the default gateway.\n * @deprecated\n */\n async connect(\n handler: (client: IOGateway.GatewayClient, msg: IOGateway.Message) => void\n ): Promise<IOGateway.GatewayClient> {\n return this.#defaultGateway.connect(handler);\n }\n\n /**\n * Gets the number of active principal gateways.\n */\n getPrincipalCount(): number {\n return this.#managedGateways.size;\n }\n}\n", "import { IOGateway } from '@interopio/gateway';\n\n/**\n * Processes visibility rules by converting string matchers to RegExp where appropriate.\n */\nexport function processVisibilityRules<K extends string>(rules?: IOGateway.VisibilityRule<K>[]) {\n if (rules !== undefined) {\n return rules.map(rule => {\n const result = {...rule} as IOGateway.VisibilityRule<K>;\n\n // Process all keys in the rule that might be matchers (context, method, domain, etc.)\n // Exclude known non-matcher properties: identity and restrictions\n for (const [key, value] of Object.entries(rule)) {\n if (key !== 'identity' && key !== 'restrictions' && value !== undefined) {\n // Value should be a Matcher type (string, RegExp, or array)\n (result as Record<K, IOGateway.Filtering.Matcher>)[key] = IOGateway.Filtering.regexify(value as IOGateway.Filtering.Matcher);\n }\n }\n\n // Process identity matchers separately\n if (rule.identity !== undefined) {\n result.identity = {};\n for (const [key, value] of Object.entries(rule.identity)) {\n result.identity[key] = IOGateway.Filtering.regexify(value);\n }\n }\n\n return result;\n });\n }\n}\n\n/**\n * Processes metric filters by converting matchers to RegExp and merging deprecated properties.\n */\nexport function processMetricFilters(filters?: IOGateway.MetricFilters): IOGateway.MetricFilters | undefined {\n if (!filters) {\n return undefined;\n }\n\n const result = {...filters};\n\n if (filters.publishers) {\n result.publishers = filters.publishers.map(publisher => {\n const { metrics: originalMetrics, identity: originalIdentity, ...rest } = publisher;\n\n // Build result object with proper typing\n type ProcessedPublisher = Omit<typeof publisher, 'metrics' | 'identity'> & {\n identity: Record<string, IOGateway.Filtering.Matcher>;\n metrics: {\n allow?: IOGateway.Filtering.Matcher[];\n block?: IOGateway.Filtering.Matcher[];\n };\n };\n\n const processedPublisher = { ...rest } as ProcessedPublisher;\n\n // Process identity matchers (always set, even if empty)\n processedPublisher.identity = {};\n if (originalIdentity) {\n for (const [key, value] of Object.entries(originalIdentity)) {\n processedPublisher.identity[key] = IOGateway.Filtering.regexify(value);\n }\n }\n\n // Process metrics matchers (allow, block, whitelist, blacklist)\n // Note: whitelist/blacklist are deprecated, merge them with allow/block\n processedPublisher.metrics = {};\n if (originalMetrics) {\n const allow = (originalMetrics.allow ?? originalMetrics.whitelist ?? []).map(m => IOGateway.Filtering.regexify(m));\n const block = (originalMetrics.block ?? originalMetrics.blacklist ?? []).map(m => IOGateway.Filtering.regexify(m));\n\n // Only include non-empty arrays to avoid meaningless empty filters\n if (allow.length > 0) {\n processedPublisher.metrics.allow = allow;\n }\n if (block.length > 0) {\n processedPublisher.metrics.block = block;\n }\n }\n\n return processedPublisher as typeof publisher;\n });\n }\n\n return result;\n}\n\n/**\n * Processes publisher configuration by processing its filters.\n */\nexport function processPublisherConfig<T extends IOGateway.BasicMetricsPublisherConfig>(publisherConfig?: T): T | undefined {\n if (!publisherConfig) {\n return undefined;\n }\n\n const result = {...publisherConfig};\n\n if (publisherConfig.filters) {\n result.filters = processMetricFilters(publisherConfig.filters);\n }\n\n return result;\n}\n\n/**\n * Processes mesh configuration, returning undefined if disabled.\n */\nexport function processMeshConfig(meshConfig?: IOGateway.MeshConfig & { enabled?: boolean }): IOGateway.MeshConfig | undefined {\n if (meshConfig?.enabled === false) {\n return undefined;\n }\n return meshConfig;\n}\n\n/**\n * Processes metrics configuration by handling filters and publisher configs.\n */\nexport function processMetricsConfig(config?: IOGateway.MetricsConfig & { enabled?: boolean }): IOGateway.MetricsConfig | undefined {\n if (config === undefined || config?.enabled === false) {\n return undefined;\n }\n const result = { ...(config) };\n\n // Process top-level filters\n if (config.filters) {\n result.filters = processMetricFilters(config.filters);\n }\n\n // Process file publisher config\n if (config.file) {\n result.file = processPublisherConfig(config.file);\n }\n\n // Process rest publisher config\n if (config.rest) {\n result.rest = processPublisherConfig(config.rest);\n }\n\n // Process publishers array (which can contain custom publishers with filters)\n if (config.publishers) {\n result.publishers = config.publishers.map(publisher => {\n if (typeof publisher === 'string') {\n return [publisher];\n }\n // It's a CustomMetricsPublisherConfig\n const c = processPublisherConfig(publisher);\n if (c !== undefined) {\n return [c];\n }\n return [];\n }).flat();\n }\n\n return result;\n}\n\n/**\n * Processes gateway configuration by converting string matchers to RegExp and handling special flags.\n * This ensures that configurations loaded from JSON files work correctly.\n */\nexport function processGatewayConfig(config: IOGateway.GatewayConfig & {\n metrics?: IOGateway.MetricsConfig & { enabled?: boolean },\n mesh?: IOGateway.MeshConfig & { enabled?: boolean }\n}): IOGateway.GatewayConfig {\n // regexify in case config is coming from JSON config file\n const result = {...config};\n\n if (config.contexts) {\n result.contexts = {\n ...config.contexts,\n visibility: processVisibilityRules(config.contexts.visibility)\n };\n }\n\n if (config.methods) {\n result.methods = {\n ...config.methods,\n visibility: processVisibilityRules(config.methods.visibility)\n };\n }\n\n if (config.peers) {\n result.peers = {\n ...config.peers,\n visibility: processVisibilityRules(config.peers.visibility)\n };\n }\n\n if (config.metrics) {\n result.metrics = processMetricsConfig(config.metrics);\n }\n\n if (config.mesh) {\n result.mesh = processMeshConfig(config.mesh);\n }\n\n return result;\n}\n", "type MiddlewareFunction<T> = ((ctx: T, next: (ctx?: T) => Promise<void>) => Promise<void>) | ((ctx: T) => Promise<void>);\n\n// https://github.com/koajs/compose/blob/master/index.js\n/**\n * @typeParam T - Type of context passed through the middleware\n * @param middleware middleware stack\n * @return {MiddlewareFunction}\n */\nexport function compose<T>(...middleware: MiddlewareFunction<T>[]): (ctx: T) => Promise<void> {\n if (!Array.isArray(middleware)) {\n throw new Error('middleware must be array!');\n }\n const fns = middleware.flat();\n for (const fn of fns) {\n if (typeof fn !== 'function') {\n throw new Error('middleware must be compose of functions!');\n }\n }\n return async function (ctx: T, next?: (ctx?: T) => Promise<void>) {\n const dispatch = async (i: number, dispatchedCtx: T): Promise<void> => {\n const fn = i === fns.length ? next : fns[i];\n if (fn === undefined) {\n return;\n }\n let nextCalled = false;\n let nextResolved = false;\n const nextFn = async (nextCtx?: T) => {\n if (nextCalled) {\n throw new Error('next() called multiple times');\n }\n nextCalled = true;\n try {\n return await dispatch(i + 1, nextCtx ?? dispatchedCtx);\n }\n finally {\n nextResolved = true;\n }\n };\n const result = await fn(dispatchedCtx, nextFn);\n if (nextCalled && !nextResolved) {\n throw new Error('middleware resolved before downstream.\\n\\t You are probably missing an await or return statement in your middleware function.');\n }\n return result;\n }\n\n return dispatch(0, ctx);\n }\n}\n", "import type {\n HeaderValues,\n HttpCookie,\n HttpHeaders,\n MutableHttpHeaders,\n ReadonlyHeaderValues,\n ResponseCookie\n} from '../../types/web/http';\nimport { type AddressInfo, isIP } from 'node:net';\nimport { Cookie } from 'tough-cookie';\n\nfunction parseHost(headers: HttpHeaders, defaultHost?: string): string | undefined {\n let host = headers.get('x-forwarded-host');\n if (Array.isArray(host)) {\n host = host[0];\n }\n if (host) {\n const port = headers.one('x-forwarded-port');\n if (port) {\n host = `${host}:${port}`;\n }\n }\n host ??= headers.one('host');\n if (Array.isArray(host)) {\n host = host[0];\n }\n if (host) {\n return (host as string).split(',', 1)[0].trim();\n }\n\n return defaultHost;\n}\n\nfunction isForwardedSsl(headers: HttpHeaders): boolean {\n const v = headers.one('x-forwarded-ssl');\n return (typeof v === 'string') && (v.toLowerCase() === 'on');\n}\n\nfunction parseProtocol(headers: HttpHeaders, defaultProtocol: string): string {\n let proto = headers.get('x-forwarded-proto');\n\n if (Array.isArray(proto)) {\n proto = proto[0];\n }\n if (proto !== undefined) {\n return (proto as string).split(',', 1)[0].trim();\n }\n else if (isForwardedSsl(headers)) {\n return 'https';\n }\n return defaultProtocol;\n}\n\nfunction parseRemoteAddress(url: URL, headers: HttpHeaders, remoteAddress?: AddressInfo) : AddressInfo | undefined {\n const port = remoteAddress ? remoteAddress.port : 'https:' === url.protocol ? 443 : 80;\n\n let host = headers.one('x-forwarded-for');\n if (Array.isArray(host)) {\n host = host[0];\n }\n if (host !== undefined) {\n host = (host as string).split(',', 1)[0].trim();\n return { address: host, port: Number(port), family: isIP(host) === 6 ? 'IPv6' : 'IPv4' };\n }\n}\n\nexport abstract class AbstractHttpMessage<Headers extends HttpHeaders = HttpHeaders> {\n readonly #headers: Headers;\n protected constructor(headers: Headers) {\n this.#headers = headers;\n }\n get headers(): Headers {\n return this.#headers;\n }\n}\n\nexport abstract class AbstractHttpRequest<Headers extends HttpHeaders = HttpHeaders> extends AbstractHttpMessage<Headers> {\n private static logIdCounter = 0;\n #id?: string\n\n get id(): string {\n if (this.#id === undefined) {\n this.#id = `${this.initId()}-${++AbstractHttpRequest.logIdCounter}`;\n\n }\n return this.#id;\n }\n\n protected initId(): string {\n return 'request';\n }\n\n get cookies(): HttpCookie[] {\n return parseCookies(this.headers);\n }\n\n protected parseHost(defaultHost?: string): string | undefined {\n return parseHost(this.headers, defaultHost);\n }\n\n protected parseProtocol(defaultProtocol: string): string {\n return parseProtocol(this.headers, defaultProtocol);\n }\n\n abstract get URL(): URL;\n\n protected parseRemoteAddress(remoteAddress?: AddressInfo) {\n return parseRemoteAddress(this.URL, this.headers, remoteAddress);\n }\n}\n\nexport abstract class AbstractHttpResponse<Headers extends HttpHeaders = HttpHeaders> extends AbstractHttpMessage<Headers> {\n get cookies(): ResponseCookie[] {\n return parseResponseCookies(this.headers);\n }\n\n protected setCookieValue(responseCookie: ResponseCookie): string {\n const cookie = new Cookie({\n key: responseCookie.name,\n value: responseCookie.value,\n maxAge: responseCookie.maxAge,\n domain: responseCookie.domain,\n path: responseCookie.path,\n secure: responseCookie.secure,\n httpOnly: responseCookie.httpOnly,\n sameSite: responseCookie.sameSite\n });\n return cookie.toString();\n }\n\n}\n\nfunction parseHeader(value: string): string[] {\n const list: string[] = [];\n {\n let start = 0;\n let end = 0;\n\n for (let i = 0; i < value.length; i++) {\n switch (value.charCodeAt(i)) {\n case 0x20: // space\n if (start === end) {\n start = end = i + 1;\n }\n break;\n case 0x2c: // comma\n list.push(value.slice(start, end));\n start = end = i + 1;\n break;\n default:\n end = end + 1;\n break;\n }\n }\n list.push(value.slice(start, end));\n }\n\n return list;\n}\n\nfunction toList(values: number | string | (readonly string[]) | undefined): string[] {\n if (typeof values === 'string') {\n values = [values];\n }\n if (typeof values === 'number') {\n values = [String(values)];\n }\n const list: string[] = [];\n if (values) {\n for (const value of values) {\n if (value) {\n list.push(...parseHeader(value));\n }\n }\n }\n return list;\n}\n\nfunction parseCookies(headers: HttpHeaders): HttpCookie[] {\n return headers.list('cookie')\n .map(s => s.split(';').map((cs) => Cookie.parse(cs)))\n .flat(1)\n .filter((tc) => tc !== undefined)\n .map((tc) => {\n const result: HttpCookie = Object.freeze({name: tc.key, value: tc.value});\n return result;\n });\n}\n\ntype Mutable<T> = {-readonly [K in keyof T]: T[K]};\n\nfunction parseResponseCookies(headers: HttpHeaders): ResponseCookie[] {\n return headers.list('set-cookie').map((cookie) => {\n const parsed = Cookie.parse(cookie);\n if (parsed) {\n const result: Mutable<ResponseCookie> = {name: parsed.key, value: parsed.value, maxAge: Number(parsed.maxAge ?? -1)};\n if (parsed.httpOnly) result.httpOnly = true;\n if (parsed.domain) result.domain = parsed.domain;\n if (parsed.path) result.path = parsed.path;\n if (parsed.secure) result.secure = true;\n if (parsed.httpOnly) result.httpOnly = true;\n if (parsed.sameSite) result.sameSite = parsed.sameSite as 'strict' | 'lax' | 'none';\n return Object.freeze(result);\n }\n }).filter((cookie): cookie is ResponseCookie => cookie !== undefined);\n}\n\n\nexport abstract class AbstractHttpHeaders<Values extends HeaderValues | ReadonlyHeaderValues> {\n protected constructor() {}\n abstract get(name: string): Values\n\n toList(name: string): string[] {\n const values = this.get(name);\n return toList(values);\n }\n}\n\nexport class MapHttpHeaders extends Map<string, (readonly string[])> implements MutableHttpHeaders {\n\n get(name: string) {\n return super.get(name.toLowerCase());\n }\n\n one(name: string): string | undefined {\n return this.get(name)?.[0];\n }\n\n list(name: string) {\n const values = super.get(name.toLowerCase());\n return toList(values);\n }\n\n set(name: string, value: number | string | (readonly string[]) | undefined): this {\n if (typeof value === 'number') {\n value = String(value);\n }\n if (typeof value === 'string') {\n value = [value];\n }\n if (value) {\n return super.set(name.toLowerCase(), value);\n }\n else {\n super.delete(name.toLowerCase());\n return this;\n }\n }\n\n add(name: string, value: string | (readonly string[])) {\n const prev = super.get(name.toLowerCase());\n if (typeof value === 'string') {\n value = [value];\n }\n if (prev) {\n value = prev.concat(value);\n }\n this.set(name, value);\n return this;\n }\n}\n", "import type {HttpStatusCode} from '../../types/web/http';\n\nclass DefaultHttpStatusCode implements HttpStatusCode {\n readonly #value: number;\n constructor(value: number) {\n this.#value = value;\n }\n get value(): number {\n return this.#value;\n }\n\n toString(): string {\n return this.#value.toString();\n }\n}\n\nexport class HttpStatus implements HttpStatusCode {\n static readonly CONTINUE = new HttpStatus(100, 'Continue');\n static readonly SWITCHING_PROTOCOLS = new HttpStatus(101, 'Switching Protocols');\n\n // 2xx Success\n\n static readonly OK = new HttpStatus(200, 'OK');\n static readonly CREATED = new HttpStatus(201, 'Created');\n static readonly ACCEPTED = new HttpStatus(202, 'Accepted');\n static readonly NON_AUTHORITATIVE_INFORMATION = new HttpStatus(203, 'Non-Authoritative Information');\n static readonly NO_CONTENT = new HttpStatus(204, 'No Content');\n static readonly RESET_CONTENT = new HttpStatus(205, 'Reset Content');\n static readonly PARTIAL_CONTENT = new HttpStatus(206, 'Partial Content');\n static readonly MULTI_STATUS = new HttpStatus(207, 'Multi-Status');\n\n static readonly IM_USED = new HttpStatus(226, 'IM Used');\n\n\n // 3xx Redirection\n static readonly MULTIPLE_CHOICES = new HttpStatus(300, 'Multiple Choices');\n static readonly MOVED_PERMANENTLY = new HttpStatus(301, 'Moved Permanently');\n\n // 4xx Client Error\n\n static readonly BAD_REQUEST = new HttpStatus(400, 'Bad Request');\n static readonly UNAUTHORIZED = new HttpStatus(401, 'Unauthorized');\n static readonly FORBIDDEN = new HttpStatus(403, 'Forbidden');\n static readonly NOT_FOUND = new HttpStatus(404, 'Not Found');\n static readonly METHOD_NOT_ALLOWED = new HttpStatus(405, 'Method Not Allowed');\n static readonly NOT_ACCEPTABLE = new HttpStatus(406, 'Not Acceptable');\n static readonly PROXY_AUTHENTICATION_REQUIRED = new HttpStatus(407, 'Proxy Authentication Required');\n static readonly REQUEST_TIMEOUT = new HttpStatus(408, 'Request Timeout');\n static readonly CONFLICT = new HttpStatus(409, 'Conflict');\n static readonly GONE = new HttpStatus(410, 'Gone');\n static readonly LENGTH_REQUIRED = new HttpStatus(411, 'Length Required');\n static readonly PRECONDITION_FAILED = new HttpStatus(412, 'Precondition Failed');\n static readonly PAYLOAD_TOO_LARGE = new HttpStatus(413, 'Payload Too Large');\n static readonly URI_TOO_LONG = new HttpStatus(414, 'URI Too Long');\n static readonly UNSUPPORTED_MEDIA_TYPE = new HttpStatus(415, 'Unsupported Media Type');\n\n static readonly EXPECTATION_FAILED = new HttpStatus(417, 'Expectation Failed');\n static readonly IM_A_TEAPOT = new HttpStatus(418, 'I\\'m a teapot');\n\n static readonly TOO_EARLY = new HttpStatus(425, 'Too Early');\n static readonly UPGRADE_REQUIRED = new HttpStatus(426, 'Upgrade Required');\n static readonly PRECONDITION_REQUIRED = new HttpStatus(428, 'Precondition Required');\n static readonly TOO_MANY_REQUESTS = new HttpStatus(429, 'Too Many Requests');\n static readonly REQUEST_HEADER_FIELDS_TOO_LARGE = new HttpStatus(431, 'Request Header Fields Too Large');\n static readonly UNAVAILABLE_FOR_LEGAL_REASONS = new HttpStatus(451, 'Unavailable For Legal Reasons');\n\n // 5xx Server Error\n static readonly INTERNAL_SERVER_ERROR = new HttpStatus(500, 'Internal Server Error');\n static readonly NOT_IMPLEMENTED = new HttpStatus(501, 'Not Implemented');\n static readonly BAD_GATEWAY = new HttpStatus(502, 'Bad Gateway');\n static readonly SERVICE_UNAVAILABLE = new HttpStatus(503, 'Service Unavailable');\n static readonly GATEWAY_TIMEOUT = new HttpStatus(504, 'Gateway Timeout');\n static readonly HTTP_VERSION_NOT_SUPPORTED = new HttpStatus(505, 'HTTP Version Not Supported');\n static readonly VARIANT_ALSO_NEGOTIATES = new HttpStatus(506, 'Variant Also Negotiates');\n static readonly INSUFFICIENT_STORAGE = new HttpStatus(507, 'Insufficient Storage');\n static readonly LOOP_DETECTED = new HttpStatus(508, 'Loop Detected');\n static readonly NOT_EXTENDED = new HttpStatus(510, 'Not Extended');\n static readonly NETWORK_AUTHENTICATION_REQUIRED = new HttpStatus(511, 'Network Authentication Required');\n\n static readonly #VALUES: HttpStatus[] = [];\n static {\n Object.keys(HttpStatus)\n .filter(key => key !== 'VALUES' && key !== 'resolve')\n .forEach(key => {\n const value = HttpStatus[key];\n if (value instanceof HttpStatus) {\n Object.defineProperty(value, 'name', { enumerable: true, value: key, writable: false });\n HttpStatus.#VALUES.push(value);\n }\n })\n\n }\n\n static resolve(code: number): HttpStatus | undefined {\n for (const status of HttpStatus.#VALUES) {\n if (status.value === code) {\n return status;\n }\n }\n }\n\n readonly #value: number;\n readonly #phrase: string;\n\n private constructor(value: number, phrase: string) {\n this.#value = value;\n this.#phrase = phrase;\n }\n\n get value(): number {\n return this.#value;\n }\n get phrase(): string {\n return this.#phrase;\n }\n\n toString() {\n return `${this.#value} ${this['name']}`;\n }\n}\n\n\nexport function httpStatusCode(value: number | HttpStatusCode): HttpStatusCode {\n if (typeof value === 'number') {\n if (value < 100 || value > 999) {\n throw new Error(`status code ${value} should be in range 100-999`);\n }\n const status = HttpStatus.resolve(value);\n if (status !== undefined) {\n return status;\n }\n return new DefaultHttpStatusCode(value);\n }\n return value;\n}\n", "import type { Principal } from '../../types/auth';\nimport type {\n BodyChunk,\n HeaderValue,\n HeaderValues,\n HttpCookie,\n HttpMethod,\n HttpStatusCode,\n MutableHttpHeaders,\n ReadonlyHeaderValues,\n ReadonlyHttpHeaders,\n ResponseCookie\n} from '../../types/web/http'\n\nimport type {\n ServerHttpRequest,\n ServerHttpResponse,\n ServerWebExchange,\n SslInfo\n} from '../../types/web/server';\nimport { AbstractHttpHeaders, AbstractHttpRequest, AbstractHttpResponse } from '../http/exchange.ts';\nimport { httpStatusCode } from '../http/status.ts';\nimport type { X509Certificate} from 'node:crypto';\nimport http from 'node:http';\nimport http2 from 'node:http2';\nimport net from 'node:net';\nimport type { TLSSocket } from 'node:tls';\n\nexport class ExtendedHttpIncomingMessage extends http.IncomingMessage {\n // circular reference to the exchange\n exchange?: ServerWebExchange;\n\n upgradeHead?: Buffer<ArrayBufferLike>\n\n\n get urlBang(): string {\n return this.url!;\n }\n\n get socketEncrypted(): boolean {\n // see tls.TLSSocket#encrypted\n return this.socket['encrypted'] === true;\n }\n}\n\nexport class ExtendedHttpServerResponse<Request extends ExtendedHttpIncomingMessage = ExtendedHttpIncomingMessage> extends http.ServerResponse<Request> {\n\n markHeadersSent(): void {\n this['_header'] = true; // prevent response from being sent\n }\n\n getRawHeaderNames(): string[] {\n return super['getRawHeaderNames']();\n }\n}\n\nabstract class AbstractServerHttpRequest extends AbstractHttpRequest<ReadonlyHttpHeaders> {\n #sslInfo?: SslInfo\n\n abstract getNativeRequest<T>(): T;\n\n protected abstract initSslInfo(): SslInfo | undefined;\n\n get sslInfo(): SslInfo | undefined {\n if (this.#sslInfo === undefined) {\n this.#sslInfo = this.initSslInfo();\n }\n return this.#sslInfo;\n }\n}\n\nexport abstract class AbstractServerHttpResponse extends AbstractHttpResponse<MutableHttpHeaders> {\n #cookies: ResponseCookie[] = [];\n #statusCode?: HttpStatusCode;\n #state: 'new' | 'committing' | 'commit-action-failed' | 'committed' = 'new';\n #commitActions: (() => Promise<void>)[] = [];\n\n setStatusCode(statusCode?: HttpStatusCode): boolean {\n if (this.#state === 'committed') {\n return false;\n }\n else {\n this.#statusCode = statusCode;\n return true;\n }\n }\n\n setRawStatusCode(statusCode?: number): boolean {\n return this.setStatusCode(statusCode === undefined ? undefined : httpStatusCode(statusCode));\n };\n\n get statusCode(): HttpStatusCode | undefined {\n return this.#statusCode;\n }\n\n addCookie(cookie: ResponseCookie): this {\n if (this.#state === 'committed') {\n throw new Error(`Cannot add cookie ${JSON.stringify(cookie)} because HTTP response has already been committed`);\n }\n this.#cookies.push(cookie);\n return this;\n }\n\n abstract getNativeResponse<T>(): T;\n\n beforeCommit(action: () => Promise<void>): void {\n this.#commitActions.push(action);\n }\n\n get commited(): boolean {\n const state = this.#state;\n return state !== 'new' && state !== 'commit-action-failed';\n }\n\n async body(body: ReadableStream<BodyChunk> | Promise<BodyChunk | void> | BodyChunk): Promise<boolean> {\n if (body instanceof ReadableStream) {\n throw new Error('ReadableStream body not supported yet');\n }\n const buffer = await body;\n try {\n // touch buffers if needed\n\n return await this.doCommit(async () => {\n\n return await this.bodyInternal(Promise.resolve(buffer));\n\n }).catch(error => {\n // release buffers\n throw error;\n });\n }\n catch (error) {\n // clear content headers\n throw error;\n }\n }\n\n abstract bodyInternal(body: Promise<BodyChunk | void>): Promise<boolean>;\n\n async end(): Promise<boolean> {\n if (!this.commited) {\n return this.doCommit(async () => {\n return await this.bodyInternal(Promise.resolve());\n });\n }\n else {\n return Promise.resolve(false);\n }\n }\n\n protected doCommit(writeAction?: () => Promise<boolean>): Promise<boolean> {\n const state = this.#state;\n let allActions = Promise.resolve();\n if (state === 'new') {\n this.#state = 'committing';\n if (this.#commitActions.length > 0) {\n allActions = this.#commitActions\n .reduce(\n (acc, cur) => acc.then(() => cur()),\n Promise.resolve())\n .catch((_error) => {\n const state = this.#state;\n if (state === 'committing') {\n this.#state = 'commit-action-failed';\n // clear content headers\n }\n });\n }\n }\n else if (state === 'commit-action-failed') {\n this.#state = 'committing';\n // skip commit actions\n } else {\n return Promise.resolve(false);\n }\n\n allActions = allActions.then(() => {\n this.applyStatusCode();\n this.applyHeaders();\n this.applyCookies();\n this.#state = 'committed';\n });\n\n\n return allActions.then(async () => {\n return writeAction !== undefined ? await writeAction() : true;\n });\n }\n\n protected applyStatusCode(): void {}\n protected applyHeaders(): void {}\n protected applyCookies(): void {}\n}\nexport class HttpServerRequest extends AbstractServerHttpRequest implements ServerHttpRequest {\n\n #url?: URL;\n #cookies?: HttpCookie[];\n readonly #req: ExtendedHttpIncomingMessage;\n\n constructor(req: ExtendedHttpIncomingMessage) {\n super(new IncomingMessageHeaders(req));\n this.#req = req;\n }\n\n getNativeRequest<T>(): T {\n return this.#req as T;\n }\n\n get upgrade() {\n return this.#req['upgrade'];\n }\n\n get http2(): boolean {\n return this.#req.httpVersionMajor >= 2;\n }\n\n get path() {\n return this.URL?.pathname;\n }\n\n get URL() {\n this.#url ??= new URL(this.#req.urlBang, `${this.protocol}://${this.host}`);\n return this.#url;\n }\n\n get query() {\n return this.URL?.search;\n }\n\n get method() {\n return this.#req.method as HttpMethod;\n }\n\n get host() {\n let dh: string | undefined = undefined;\n if (this.#req.httpVersionMajor >= 2) {\n dh = (this.#req.headers as http2.IncomingHttpHeaders)[':authority'];\n }\n dh ??= this.#req.socket.remoteAddress;\n return super.parseHost(dh);\n }\n\n get protocol() {\n let dp: string | undefined = undefined;\n if (this.#req.httpVersionMajor > 2) {\n dp = (this.#req.headers as http2.IncomingHttpHeaders)[':scheme'];\n }\n dp ??= this.#req.socketEncrypted ? 'https' : 'http';\n return super.parseProtocol(dp);\n }\n\n get socket() {\n return this.#req.socket;\n }\n\n get remoteAddress(): net.AddressInfo | undefined {\n const family = this.#req.socket.remoteFamily;\n const address = this.#req.socket.remoteAddress;\n const port = this.#req.socket.remotePort;\n const remoteAddress = (!family || !address || !port) ? undefined : { family, address, port };\n return super.parseRemoteAddress(remoteAddress) ?? remoteAddress;\n }\n\n protected initSslInfo(): SslInfo | undefined {\n if (this.#req.socketEncrypted) {\n return new DefaultSslInfo(this.#req.socket as TLSSocket);\n }\n }\n\n get cookies(): HttpCookie[] {\n this.#cookies ??= super.cookies\n return this.#cookies;\n }\n\n get body(): ReadableStream<BodyChunk> {\n return http.IncomingMessage.toWeb(this.#req) as ReadableStream<BodyChunk>;\n }\n\n async blob() {\n const chunks: BodyChunk[] = [];\n if (this.body !== undefined) {\n for await (const chunk of this.body) {\n chunks.push(chunk);\n }\n }\n return new Blob(chunks, {type: this.headers.one('content-type') as string || 'application/octet-stream'});\n }\n\n\n async text() {\n const blob = await this.blob();\n return await blob.text();\n }\n\n async formData() {\n const blob = await this.blob();\n const text = await blob.text();\n return new URLSearchParams(text);\n }\n\n async json() {\n const blob = await this.blob();\n if (blob.size === 0) {\n return undefined;\n }\n const text = await blob.text();\n return JSON.parse(text);\n }\n\n\n protected initId(): string {\n const remoteIp = this.#req.socket.remoteAddress;\n if (!remoteIp) {\n throw new Error('Socket has no remote address');\n }\n return `${remoteIp}:${this.#req.socket.remotePort}`;\n }\n}\n\nclass DefaultSslInfo implements SslInfo {\n readonly peerCertificate?: X509Certificate;\n constructor(socket: TLSSocket) {\n this.peerCertificate = socket.getPeerX509Certificate();\n }\n}\n\nclass IncomingMessageHeaders extends AbstractHttpHeaders<ReadonlyHeaderValues> implements ReadonlyHttpHeaders {\n readonly #msg: ExtendedHttpIncomingMessage;\n\n constructor(msg: ExtendedHttpIncomingMessage) {\n super();\n this.#msg = msg;\n }\n\n has(name: string): boolean {\n return this.#msg.headers[name] !== undefined;\n }\n\n get(name: string): string | (readonly string[]) | undefined {\n return this.#msg.headers[name];\n }\n\n list(name: string): string[] {\n return super.toList(name);\n }\n\n one(name: string): string | undefined {\n const value = this.#msg.headers[name];\n if (Array.isArray(value)) {\n return value[0];\n }\n return value;\n }\n\n keys() {\n return Object.keys(this.#msg.headers).values();\n }\n}\n\nclass OutgoingMessageHeaders extends AbstractHttpHeaders<HeaderValues> implements MutableHttpHeaders {\n readonly #msg: ExtendedHttpServerResponse;\n\n constructor(msg: ExtendedHttpServerResponse) {\n super();\n this.#msg = msg;\n }\n\n has(name: string): boolean {\n return this.#msg.hasHeader(name);\n }\n\n keys() {\n return this.#msg.getHeaderNames().values();\n }\n\n get(name: string): HeaderValues {\n return this.#msg.getHeader(name);\n }\n\n one(name: string): HeaderValue {\n const value = this.#msg.getHeader(name);\n if (Array.isArray(value)) {\n return value[0];\n }\n return value;\n }\n\n set(name: string, value: HeaderValues): this {\n if (!this.#msg.headersSent) {\n if (Array.isArray(value)) {\n value = value.map(v => typeof v === 'number' ? String(v) : v);\n } else if (typeof value === 'number') {\n value = String(value);\n }\n\n if (value) {\n this.#msg.setHeader(name, value);\n }\n else {\n this.#msg.removeHeader(name);\n }\n }\n return this;\n }\n\n add(name: string, value: string | (readonly string[])): this {\n if (!this.#msg.headersSent) {\n this.#msg.appendHeader(name, value);\n }\n return this;\n }\n\n list(name: string): string[] {\n return super.toList(name);\n }\n}\n\nexport class HttpServerResponse extends AbstractServerHttpResponse implements ServerHttpResponse {\n readonly #res: ExtendedHttpServerResponse;\n\n constructor(res: ExtendedHttpServerResponse) {\n super(new OutgoingMessageHeaders(res));\n this.#res = res;\n }\n\n getNativeResponse<T>(): T {\n return this.#res as T;\n }\n\n get statusCode(): HttpStatusCode {\n const status = super.statusCode;\n return status ?? {value: this.#res.statusCode};\n }\n\n applyStatusCode() {\n const status = super.statusCode;\n if (status !== undefined) {\n this.#res.statusCode = status.value;\n }\n }\n\n addCookie(cookie: ResponseCookie): this {\n this.headers.add('Set-Cookie', super.setCookieValue(cookie));\n return this;\n }\n\n async bodyInternal(body: Promise<BodyChunk | void>): Promise<boolean> {\n if (!this.#res.headersSent) {\n if (body instanceof ReadableStream) {\n // http.IncomingMessage.fromWeb(body)\n throw new Error('ReadableStream body not supported in response');\n }\n else {\n const chunk = await body;\n return await new Promise<boolean>((resolve, reject) => {\n try {\n if (chunk === undefined) {\n this.#res.end(() => {\n resolve(true);\n });\n } else {\n if (!this.headers.has('content-length')) {\n // set Content-Length if not already set\n if (typeof chunk === 'string') {\n this.headers.set('Content-Length', Buffer.byteLength(chunk));\n }\n else if (chunk instanceof Blob) {\n this.headers.set('Content-Length', chunk.size);\n }\n else {\n this.headers.set('Content-Length', chunk.byteLength);\n }\n }\n this.#res.end(chunk, () => {\n resolve(true);\n });\n }\n } catch (e) {\n reject(e instanceof Error ? e : new Error(`end failed: ${e}`));\n }\n });\n }\n }\n else {\n return false; // already ended\n }\n }\n}\n\nexport class ServerHttpRequestDecorator implements ServerHttpRequest {\n readonly #delegate: ServerHttpRequest;\n\n constructor(request: ServerHttpRequest) {\n this.#delegate = request;\n }\n\n get delegate(): ServerHttpRequest {\n return this.#delegate;\n }\n\n get id(): string {\n return this.#delegate.id;\n }\n\n get method(): HttpMethod {\n return this.#delegate.method;\n }\n\n get path(): string {\n return this.#delegate.path;\n }\n\n get protocol() {\n return this.#delegate.protocol;\n }\n\n get host(): string | undefined {\n return this.#delegate.host;\n }\n\n get URL(): URL {\n return this.#delegate.URL;\n }\n\n get headers(): ReadonlyHttpHeaders {\n return this.#delegate.headers;\n }\n\n get cookies(): HttpCookie[] {\n return this.#delegate.cookies;\n }\n\n get remoteAddress() {\n return this.#delegate.remoteAddress;\n }\n\n get upgrade() {\n return this.#delegate.upgrade;\n }\n\n get sslInfo() {\n return this.#delegate.sslInfo;\n }\n\n get body(): ReadableStream<BodyChunk> | undefined {\n return this.#delegate.body;\n }\n async blob(): Promise<Blob> {\n return await this.#delegate.blob();\n }\n async text(): Promise<string> {\n return await this.#delegate.text();\n }\n async formData(): Promise<URLSearchParams> {\n return await this.#delegate.formData();\n }\n async json(): Promise<unknown> {\n return await this.#delegate.json();\n }\n\n toString(): string {\n return `${ServerHttpRequestDecorator.name} [delegate: ${this.delegate.toString()}]`;\n }\n\n public static getNativeRequest<T>(request: ServerHttpRequest): T {\n if (request instanceof AbstractServerHttpRequest) {\n return request.getNativeRequest<T>();\n }\n else if (request instanceof ServerHttpRequestDecorator) {\n return ServerHttpRequestDecorator.getNativeRequest<T>(request.delegate);\n }\n else {\n throw new Error(`Cannot get native request from ${request.constructor.name}`);\n }\n }\n}\nexport class ServerHttpResponseDecorator implements ServerHttpResponse {\n readonly #delegate: ServerHttpResponse;\n\n constructor(response: ServerHttpResponse) {\n this.#delegate = response;\n }\n\n get delegate(): ServerHttpResponse {\n return this.#delegate;\n }\n\n setStatusCode(statusCode: HttpStatusCode): boolean {\n return this.delegate.setStatusCode(statusCode);\n }\n\n setRawStatusCode(statusCode?: number): boolean {\n return this.delegate.setRawStatusCode(statusCode);\n }\n\n get statusCode(): HttpStatusCode {\n return this.delegate.statusCode;\n }\n\n get cookies(): ResponseCookie[] {\n return this.delegate.cookies;\n }\n\n addCookie(cookie: ResponseCookie): this {\n this.delegate.addCookie(cookie);\n return this;\n }\n\n async end(): Promise<boolean> {\n return await this.delegate.end();\n }\n\n async body(body: ReadableStream<BodyChunk> | Promise<BodyChunk | void> | BodyChunk): Promise<boolean> {\n return await this.#delegate.body(body);\n }\n\n get headers(): MutableHttpHeaders {\n return this.#delegate.headers;\n }\n\n toString(): string {\n return `${ServerHttpResponseDecorator.name} [delegate: ${this.delegate.toString()}]`;\n }\n\n public static getNativeResponse<T>(response: ServerHttpResponse): T {\n if (response instanceof AbstractServerHttpResponse) {\n return response.getNativeResponse<T>();\n }\n else if (response instanceof ServerHttpResponseDecorator) {\n return ServerHttpResponseDecorator.getNativeResponse<T>(response.delegate);\n }\n else {\n throw new Error(`Cannot get native response from ${response.constructor.name}`);\n }\n }\n}\n\nexport class ServerWebExchangeDecorator implements ServerWebExchange {\n readonly #delegate: ServerWebExchange;\n\n protected constructor(exchange: ServerWebExchange) {\n this.#delegate = exchange;\n }\n\n get delegate(): ServerWebExchange {\n return this.#delegate;\n }\n\n get request(): ServerHttpRequest {\n return this.#delegate.request;\n }\n\n get response(): ServerHttpResponse {\n return this.#delegate.response;\n }\n\n attribute<T>(name: string): T | undefined {\n return this.#delegate.attribute(name);\n }\n\n principal<P extends Principal>(): Promise<P | undefined> {\n return this.#delegate.principal();\n }\n\n get logPrefix(): string {\n return this.#delegate.logPrefix;\n }\n\n toString() {\n return `${ServerWebExchangeDecorator.name} [delegate: ${this.delegate}]`;\n }\n}\n\nexport class DefaultWebExchange<Request extends ServerHttpRequest, Response extends ServerHttpResponse> {\n readonly request: Request;\n readonly response: Response;\n readonly #attributes: Record<string, unknown> = {};\n #logId?: unknown;\n #logPrefix: string = '';\n\n constructor(request: Request, response: Response) {\n this.#attributes[LOG_ID_ATTRIBUTE] = request.id;\n this.request = request;\n this.response = response;\n }\n\n get method(): HttpMethod {\n return this.request.method;\n }\n\n get path(): string | null | undefined {\n return this.request.path;\n }\n\n get attributes(): Record<string, unknown> {\n return this.#attributes;\n }\n\n attribute<T>(name: string): T | undefined {\n return this.attributes[name] as T;\n }\n\n principal<P extends Principal>(): Promise<P | undefined> {\n return Promise.resolve(undefined);\n }\n\n get logPrefix(): string {\n const value = this.attribute(LOG_ID_ATTRIBUTE);\n if (this.#logId !== value) {\n this.#logId = value;\n this.#logPrefix = value !== undefined ? `[${value}] ` : '';\n }\n return this.#logPrefix;\n }\n}\n\nexport const LOG_ID_ATTRIBUTE = 'io.interop.gateway.server.log_id';\n\n", "import getLogger from '../logger.ts';\nimport { getHeapStatistics, writeHeapSnapshot, type HeapInfo } from 'node:v8';\nimport type { PathLike } from 'node:fs';\nimport { access, mkdir, rename, unlink } from 'node:fs/promises';\n\nconst log = getLogger('monitoring');\n\nexport type Options = typeof DEFAULT_OPTIONS;\n\nexport type Command = 'run' | 'dump' | 'stop';\nexport type Channel = (command?: Command) => Promise<boolean>;\n\nconst DEFAULT_OPTIONS = {\n memoryLimit: 1024 * 1024 * 1024, // 1GB\n reportInterval: 10 * 60 * 1000, // 10 min\n dumpLocation: '.', // current folder\n maxBackups: 10,\n dumpPrefix: 'Heap'\n}\n\nfunction fetchStats(): HeapInfo {\n return getHeapStatistics();\n}\n\nasync function dumpHeap(opts: Options) {\n const prefix = opts.dumpPrefix ?? 'Heap';\n const target = `${opts.dumpLocation}/${prefix}.heapsnapshot`;\n if (log.enabledFor('debug')) {\n log.debug(`starting heap dump in ${target}`);\n }\n\n await fileExists(opts.dumpLocation)\n .catch(async (_) => {\n if (log.enabledFor('debug')) {\n log.debug(`dump location ${opts.dumpLocation} does not exists. Will try to create it`);\n }\n try {\n await mkdir(opts.dumpLocation, {recursive: true});\n log.info(`dump location dir ${opts.dumpLocation} successfully created`);\n } catch (e) {\n log.error(`failed to create dump location ${opts.dumpLocation}`);\n }\n });\n const dumpFileName = writeHeapSnapshot(target);\n log.info(`heap dumped`);\n try {\n log.debug(`rolling snapshot backups`);\n const lastFileName = `${opts.dumpLocation}/${prefix}.${opts.maxBackups}.heapsnapshot`;\n await fileExists(lastFileName)\n .then(async () => {\n if (log.enabledFor('debug')) {\n log.debug(`deleting ${lastFileName}`);\n }\n try {\n await unlink(lastFileName);\n } catch (e) {\n log.warn(`failed to delete ${lastFileName}`, e);\n }\n })\n .catch(() => {\n /* do nothing*/\n });\n for (let i = opts.maxBackups - 1; i > 0; i--) {\n const currentFileName = `${opts.dumpLocation}/${prefix}.${i}.heapsnapshot`;\n const nextFileName = `${opts.dumpLocation}/${prefix}.${i + 1}.heapsnapshot`;\n await fileExists(currentFileName)\n .then(async () => {\n try {\n await rename(currentFileName, nextFileName);\n } catch (e) {\n log.warn(`failed to rename ${currentFileName} to ${nextFileName}`, e);\n }\n })\n .catch(() => {\n /* do nothing*/\n });\n }\n const firstFileName = `${opts.dumpLocation}/${prefix}.${1}.heapsnapshot`;\n try {\n await rename(dumpFileName, firstFileName);\n } catch (e) {\n log.warn(`failed to rename ${dumpFileName} to ${firstFileName}`, e);\n }\n log.debug('snapshots rolled');\n } catch (e) {\n log.error('error rolling backups', e);\n throw e;\n }\n}\n\nasync function fileExists(path: PathLike): Promise<void> {\n if (log.enabledFor('trace')) {\n log.debug(`checking file ${path}`);\n }\n await access(path);\n}\n\nasync function processStats(stats: HeapInfo, state: {\n memoryLimitExceeded: boolean,\n snapshot?: boolean\n}, opts: Options) {\n if (log.enabledFor('debug')) {\n log.debug(`processing heap stats ${JSON.stringify(stats)}`);\n }\n const limit = Math.min(opts.memoryLimit, (0.95 * stats.heap_size_limit));\n const used = stats.used_heap_size;\n log.info(`heap stats ${JSON.stringify(stats)}`);\n if (used >= limit) {\n log.warn(`used heap ${used} bytes exceeds memory limit ${limit} bytes`);\n if (state.memoryLimitExceeded) {\n delete state.snapshot;\n } else {\n state.memoryLimitExceeded = true;\n state.snapshot = true;\n }\n await dumpHeap(opts);\n } else {\n state.memoryLimitExceeded = false;\n delete state.snapshot;\n }\n}\n\nexport function start(opts?: Partial<Options>): Options & { channel: Channel } {\n const merged: Options = {...DEFAULT_OPTIONS, ...opts};\n\n let stopped = false;\n const state = {memoryLimitExceeded: false};\n const report = async () => {\n const stats = fetchStats();\n await processStats(stats, state, merged);\n }\n const interval = setInterval(report, merged.reportInterval);\n const channel = async (command?: Command) => {\n if (!stopped) {\n command ??= 'run';\n switch (command) {\n case 'run': {\n await report();\n break;\n }\n case 'dump': {\n await dumpHeap(merged);\n break;\n }\n case 'stop': {\n stopped = true;\n clearInterval(interval);\n log.info('exit memory diagnostic');\n break;\n }\n }\n\n }\n return stopped;\n }\n\n return {...merged, channel};\n}\n\nasync function run({channel}: { channel: Channel }, command?: Command) {\n if (!await channel(command)) {\n log.warn(`cannot execute command \"${command}\" already closed`)\n }\n}\n\n\nexport async function stop(m: { channel: Channel }) {\n return await run(m, 'stop');\n}\n", "import type {ServerWebExchange} from '../../types/web/server';\n\nconst serverHeader = (version: string, server?: string | false) => {\n server ??= version;\n return async ({ response }: ServerWebExchange, next: () => Promise<void>) => {\n if (server !== false && !response.headers.has('server')) {\n response.headers.set('Server', server);\n }\n await next();\n }\n};\n\nexport default (version: string, server?: string | false) => serverHeader(version, server);\n", "import { IOGateway } from '@interopio/gateway';\nimport type { OriginFilters } from '../../types/web/server';\nimport getLogger from '../logger.ts';\n\nconst log = getLogger('gateway.ws.client-verify');\n\nexport type ProcessedOriginFilters\n = Required<Omit<OriginFilters, 'blacklist' | 'whitelist'>>\n //| Required<Omit<GatewayServer.OriginFilters, 'block' | 'allow'>>\n ;\n\nfunction acceptsMissing(originFilters: ProcessedOriginFilters): boolean {\n switch (originFilters.missing) {\n case 'allow': // fall-through\n case 'whitelist':\n return true;\n case 'block': // fall-through\n case 'blacklist':\n return false;\n default:\n return false;\n }\n}\n\nfunction tryMatch(originFilters: ProcessedOriginFilters, origin: string): boolean | undefined {\n const block = originFilters.block ?? originFilters['blacklist'];\n const allow = originFilters.allow ?? originFilters['whitelist'];\n if (block.length > 0 && IOGateway.Filtering.valuesMatch(block, origin)) {\n log.warn(`origin ${origin} matches block filter`);\n return false;\n } else if (allow.length > 0 && IOGateway.Filtering.valuesMatch(allow, origin)) {\n if (log.enabledFor('debug')) {\n log.debug(`origin ${origin} matches allow filter`);\n }\n return true;\n }\n}\n\nfunction acceptsNonMatched(originFilters: ProcessedOriginFilters): boolean {\n switch (originFilters.non_matched) {\n case 'allow': // fall-through\n case 'whitelist':\n return true;\n case 'block': // fall-through\n case 'blacklist':\n return false;\n default:\n return false;\n }\n}\n\nexport function acceptsOrigin(origin?: string, originFilters?: ProcessedOriginFilters): boolean {\n if (!originFilters) {\n return true;\n }\n if (!origin) {\n return acceptsMissing(originFilters);\n } else {\n const matchResult: boolean | undefined = tryMatch(originFilters, origin);\n if (matchResult) {\n return matchResult;\n } else {\n return acceptsNonMatched(originFilters);\n }\n }\n}\n\nexport function regexifyOriginFilters(originFilters?: OriginFilters): ProcessedOriginFilters | undefined {\n if (originFilters) {\n const block = (originFilters.block ?? originFilters.blacklist ?? []).map(IOGateway.Filtering.regexify);\n const allow = (originFilters.allow ?? originFilters.whitelist ?? []).map(IOGateway.Filtering.regexify);\n return {\n non_matched: originFilters.non_matched ?? 'allow',\n missing: originFilters.missing ?? 'allow',\n allow,\n block,\n }\n }\n}\n", "import type {ServerWebExchange} from '../../../types/web/server';\n\nexport type MatchResult = Readonly<{ match: boolean, variables: Readonly<Record<string, string>> }>;\n\nexport interface ServerWebExchangeMatcher {\n /**\n * Matches the given exchange against the matcher.\n * @param exchange The web exchange to match.\n * @returns A promise that resolves to true if the exchange matches, false otherwise.\n */\n (exchange: ServerWebExchange): Promise<MatchResult>;\n\n /**\n * Returns a string representation of the matcher.\n * @returns A string representation of the matcher.\n */\n toString(): string;\n}\n\nexport type ServerWebExchangeMatcherEntry<T> = Readonly<[ServerWebExchangeMatcher, T]>\n\nexport const or: (matchers: ServerWebExchangeMatcher[]) => ServerWebExchangeMatcher = (matchers: ServerWebExchangeMatcher[]): ServerWebExchangeMatcher => {\n return async (exchange: ServerWebExchange): Promise<MatchResult> => {\n for (const matcher of matchers) {\n const result = await matcher(exchange);\n if (result.match) {\n return match();\n }\n }\n return NO_MATCH;\n };\n}\n\nexport const and: (matchers: ServerWebExchangeMatcher[]) => ServerWebExchangeMatcher = (matchers: ServerWebExchangeMatcher[]) => {\n const matcher = async (exchange: ServerWebExchange): Promise<MatchResult> => {\n for (const matcher of matchers) {\n const result = await matcher(exchange);\n if (!result.match) {\n return NO_MATCH;\n }\n }\n return match();\n };\n matcher.toString = () => `and(${matchers.map(m => m.toString()).join(', ')})`;\n return matcher;\n}\n\n\nexport const not: (matcher: ServerWebExchangeMatcher) => ServerWebExchangeMatcher = (matcher: ServerWebExchangeMatcher): ServerWebExchangeMatcher => {\n return async (exchange: ServerWebExchange): Promise<MatchResult> => {\n const result = await matcher(exchange);\n return result.match ? NO_MATCH : match();\n };\n}\n\nexport const anyExchange: ServerWebExchangeMatcher = async (_exchange: ServerWebExchange): Promise<MatchResult> => {\n return match();\n}\nanyExchange.toString = () => 'any-exchange';\n\nconst EMPTY_OBJECT = Object.freeze({});\nexport const NO_MATCH: MatchResult = Object.freeze({match: false, variables: EMPTY_OBJECT});\nexport const match = (variables: Record<string, string> = EMPTY_OBJECT): MatchResult => {\n return { match: true, variables };\n}\n\nexport const pattern: ((pattern: string | RegExp, opts?: {method?: string}) => ServerWebExchangeMatcher) = (pattern, opts) => {\n const method = opts?.method;\n const matcher = async (exchange: ServerWebExchange): Promise<MatchResult> => {\n const request = exchange.request;\n const path = request.path;\n if (method !== undefined && request.method !== method) {\n return NO_MATCH;\n }\n if (typeof pattern === 'string') {\n if (path === pattern) {\n return match();\n }\n return NO_MATCH;\n }\n else {\n const match = pattern.exec(path);\n if (match === null) {\n return NO_MATCH;\n }\n return {match: true, variables: {...match.groups}};\n }\n };\n matcher.toString = () => {\n return `pattern(${pattern.toString()}, method=${method ?? '<any>'})`;\n }\n return matcher\n\n}\nexport const mediaType : ((opts: { mediaTypes: string[], ignoredMediaTypes?: string[], useEquality?: boolean }) => ServerWebExchangeMatcher) = (opts): ServerWebExchangeMatcher => {\n\n const shouldIgnore = (requestedMediaType: string): boolean => {\n if (opts.ignoredMediaTypes !== undefined) {\n for (const ignoredMediaType of opts.ignoredMediaTypes) {\n if (requestedMediaType === ignoredMediaType || ignoredMediaType === '*/*') {\n return true;\n }\n }\n }\n return false;\n }\n\n return async (exchange: ServerWebExchange): Promise<MatchResult> => {\n const request = exchange.request;\n let requestMediaTypes: string[];\n try {\n requestMediaTypes = request.headers.list('accept');\n }\n catch (e) {\n return NO_MATCH;\n }\n for (const requestedMediaType of requestMediaTypes) {\n if (shouldIgnore(requestedMediaType)) {\n continue;\n }\n for (const mediaType of opts.mediaTypes) {\n if (requestedMediaType.startsWith(mediaType)) {\n return match();\n }\n }\n }\n\n return NO_MATCH;\n };\n}\n\nexport const upgradeMatcher: ServerWebExchangeMatcher = async ({request}: ServerWebExchange): Promise<MatchResult> => {\n const upgrade = request.upgrade && request.headers.one('upgrade')?.toLowerCase() === 'websocket';\n return upgrade ? match() : NO_MATCH;\n};\nupgradeMatcher.toString = () => 'websocket upgrade';\n", "import { regexifyOriginFilters } from '../server/ws-client-verify.ts';\nimport type { SecurityContext } from '../server/security/security-context.ts';\nimport { pattern, type ServerWebExchangeMatcher } from '../server/util/matchers.ts';\nimport type { CorsConfig } from '../server/cors.ts';\nimport type { Middleware } from '../server/types.ts';\nimport type { AsyncLocalStorage } from 'node:async_hooks';\nimport type { SocketRoute } from '../server/socket.ts';\nimport { GatewayServer } from '@interopio/gateway-server';\nimport type {\n ServerConfigurer,\n ServerConfigurerHandlerSpec,\n ServerConfigurerSocketSpec,\n ServerExchangeOptions,\n ServerWebExchange\n} from '../../types/web/server';\nimport type { AuthorizationRule } from '../../types/auth';\nimport { IOGateway } from '@interopio/gateway';\n\nexport type PathPattern = string | RegExp;\nexport type RouteConfig = Readonly<{\n readonly storage: AsyncLocalStorage<{\n exchange: ServerWebExchange,\n securityContext?: Promise<SecurityContext>\n }>,\n readonly serverHeader?: string | false\n readonly corsConfig?: GatewayServer.ServerConfig['cors'],\n readonly authConfig?: GatewayServer.ServerConfig['auth'],\n readonly middleware: Middleware,\n readonly cors: Array<[PathPattern, CorsConfig | undefined]>,\n readonly authorize: Array<[ServerWebExchangeMatcher, AuthorizationRule]>\n readonly sockets: Map<string, SocketRoute>\n readonly resourcesConfig?: GatewayServer.ServerConfig['resources']\n}>\n\nexport async function configure(app: GatewayServer.ServerCustomizer, config: GatewayServer.ServerConfig, routes: RouteConfig): Promise<void> {\n const applyCors = (request: ServerConfigurerHandlerSpec['request'], options?: ServerExchangeOptions) => {\n // // disable CORS for this route\n // if (options?.cors === false) {\n // const path = request.path as (PathPattern);\n // routes.cors.push([request.path, undefined]);\n // }\n if (options?.cors) {\n const cors: CorsConfig = options.cors === true ? {\n allowOrigins: options.origins?.allow?.map(IOGateway.Filtering.regexify),\n allowMethods: request.method === undefined ? ['*'] : [request.method],\n allowCredentials: options.authorize?.access !== 'permitted' ? true : undefined,\n } : options.cors;\n const path = request.path as (PathPattern);\n routes.cors.push([path, cors]);\n }\n }\n\n const configurer = new class implements ServerConfigurer {\n\n handle(...handlers: Array<ServerConfigurerHandlerSpec>) {\n handlers.forEach(({request, options, handler}) => {\n const matcher = pattern(IOGateway.Filtering.regexify(request.path) as string | RegExp, {method: request.method});\n if (options?.authorize) {\n routes.authorize.push([matcher, options.authorize]);\n }\n\n applyCors(request, options);\n const middleware = async (exchange: ServerWebExchange, next: () => Promise<void>): Promise<void> => {\n const {match, variables} = await matcher(exchange);\n if (match) {\n await handler(exchange, variables);\n } else {\n await next();\n }\n };\n routes.middleware.push(middleware);\n });\n }\n\n socket(...sockets: Array<ServerConfigurerSocketSpec>) {\n for (const {path, factory, options} of sockets) {\n const route = path ?? '/';\n\n // cors and authorize are currently handled for ws\n routes.sockets.set(route, {\n default: path === undefined || path === '/',\n ping: options?.ping,\n factory: factory,\n maxConnections: options?.maxConnections,\n authorize: options?.authorize,\n originFilters: regexifyOriginFilters(options?.origins)\n });\n }\n }\n };\n await app(configurer, config);\n}\n", "import type { ServerWebExchangeMatcher } from './util/matchers.ts';\nimport { HttpStatus } from '../http/status.ts';\nimport getLogger from '../logger.ts';\nimport type { HttpRequest, ReadonlyHttpHeaders } from '../../types/web/http';\nimport type { ServerHttpResponse, ServerWebExchange } from '../../types/web/server';\nimport { IOGateway } from '@interopio/gateway';\n\nfunction isSameOrigin(request: HttpRequest<ReadonlyHttpHeaders>) {\n const origin = request.headers.one('origin');\n if (origin === undefined) {\n return true;\n }\n const url = request.URL;\n const actualProtocol = url.protocol;\n const actualHost = url.host;\n\n const originUrl = URL.parse(origin); // URL.parse requires Node.js 20.18 || 22.1\n\n const originHost = originUrl?.host;\n const originProtocol = originUrl?.protocol;\n return actualProtocol === originProtocol\n && actualHost === originHost;\n}\n\n/**\n * Returns `true` if the request is a valid CORS one by checking `Origin` header presence and ensuring origins differ.\n */\nexport function isCorsRequest(request: HttpRequest<ReadonlyHttpHeaders>): boolean {\n return request.headers.has('origin') && !isSameOrigin(request);\n\n}\n\nexport function isPreFlightRequest(request: HttpRequest): boolean {\n return request.method === 'OPTIONS'\n && request.headers.has('origin')\n && request.headers.has('access-control-request-method');\n}\n\nconst VARY_HEADERS: readonly string[] = ['Origin', 'Access-Control-Request-Method', 'Access-Control-Request-Headers'];\n\n/**\n * Processes a request given a {@link CorsConfig}.\n *\n * @param exchange the current exchange\n * @param config the CORS configuration to use, possibly `undefined` in which case pre-flight requests are rejected, but all others allowed\n * @returns `false` if the request is rejected, `true` otherwise\n */\nexport const processRequest: CorsProcessor = (exchange: ServerWebExchange, config?: CorsConfig): boolean => {\n const {request, response} = exchange;\n const responseHeaders = response.headers;\n\n if (!responseHeaders.has('Vary')) {\n responseHeaders.set('Vary', VARY_HEADERS.join(', '));\n }\n else {\n const varyHeaders = responseHeaders.list('Vary');\n for (const header of VARY_HEADERS) {\n if (!varyHeaders.find(h => h === header)) {\n varyHeaders.push(header);\n }\n }\n responseHeaders.set('Vary', varyHeaders.join(', '));\n }\n\n try {\n if (!isCorsRequest(request)) {\n return true;\n }\n }\n catch (e) {\n if(logger.enabledFor('debug')) {\n logger.debug(`reject: origin is malformed`);\n }\n rejectRequest(response);\n return false;\n }\n\n if (responseHeaders.has('access-control-allow-origin')) {\n if (logger.enabledFor('trace')) {\n logger.debug(`skip: already contains \"Access-Control-Allow-Origin\"`);\n }\n return true;\n }\n\n const preFlightRequest = isPreFlightRequest(request);\n\n if (config) {\n return handleInternal(exchange, config, preFlightRequest);\n }\n if (preFlightRequest) {\n rejectRequest(response);\n return false;\n }\n return true;\n}\n\nexport type CorsConfig = Readonly<{\n allowOrigins?: '*' | IOGateway.Filtering.Matcher[]\n allowMethods?:'*' | string[]\n allowHeaders?: '*' | string[]\n exposeHeaders?: string[]\n allowCredentials?: boolean\n allowPrivateNetwork?: boolean\n maxAge?: number\n}>;\n\nconst DEFAULT_PERMIT_ALL = ['*'];\nconst DEFAULT_PERMIT_METHODS = ['GET', 'HEAD', 'POST'];\nexport const PERMIT_DEFAULT_CONFIG: CorsConfig = {\n allowOrigins: DEFAULT_PERMIT_ALL,\n allowMethods: DEFAULT_PERMIT_METHODS,\n allowHeaders: DEFAULT_PERMIT_ALL,\n maxAge: 1800 // 30 minutes\n}\nexport /*testing*/ function validateCorsConfig(config?: CorsConfig): CorsConfig | undefined {\n if (config) {\n const allowHeaders = config.allowHeaders;\n if (allowHeaders && allowHeaders !== ALL) {\n config = {\n ...config,\n allowHeaders: allowHeaders.map(header => header.toLowerCase())\n };\n }\n const allowOrigins = config.allowOrigins;\n if (allowOrigins) {\n if (allowOrigins === '*') {\n validateAllowCredentials(config);\n validateAllowPrivateNetwork(config);\n }\n else {\n config = {\n ...config,\n allowOrigins: allowOrigins.map(origin => {\n if (typeof origin === 'string' && origin !== ALL) {\n origin = IOGateway.Filtering.regexify(origin);\n if (typeof origin === 'string') {\n // exact match\n return trimTrailingSlash(origin).toLowerCase();\n }\n }\n return origin;\n })\n };\n }\n }\n return config;\n }\n}\n\nfunction combine<T = (string | IOGateway.Filtering.Matcher)>(source?: '*' | T[], other?: '*' | T[]): T[] | undefined {\n if (other === undefined) {\n return source !== undefined ? (source === ALL ? [ALL as T] : source) : [];\n }\n if (source === undefined) {\n return other === ALL ? [ALL as T] : other;\n }\n if (source == DEFAULT_PERMIT_ALL || source === DEFAULT_PERMIT_METHODS) {\n return other === ALL ? [ALL as T] : other;\n }\n if (other == DEFAULT_PERMIT_ALL || other === DEFAULT_PERMIT_METHODS) {\n return source === ALL ? [ALL as T] : source;\n }\n if (source === ALL || source.includes(ALL as T) || other === ALL || other.includes(ALL as T)) {\n return [ALL as T];\n }\n const combined = new Set<T>();\n source.forEach((v) => combined.add(v));\n other.forEach((v) => combined.add(v));\n return Array.from(combined);\n}\nexport const combineCorsConfig = (source: CorsConfig, other?: CorsConfig): CorsConfig => {\n if (other === undefined) {\n return source;\n }\n const config: CorsConfig = {\n allowOrigins: combine(source.allowOrigins, other?.allowOrigins),\n allowMethods: combine(source.allowMethods, other?.allowMethods),\n allowHeaders: combine(source.allowHeaders, other?.allowHeaders),\n exposeHeaders: combine(source.exposeHeaders, other?.exposeHeaders),\n allowCredentials: other?.allowCredentials ?? source.allowCredentials,\n allowPrivateNetwork: other?.allowPrivateNetwork ?? source.allowPrivateNetwork,\n maxAge: other?.maxAge ?? source.maxAge\n }\n return config;\n\n}\n\nexport type CorsConfigSource = (exchange: ServerWebExchange) => Promise<CorsConfig | undefined>;\nexport type CorsProcessor = (exchange: ServerWebExchange, config?: CorsConfig) => boolean;\n\nconst corsFilter = (opts: {corsConfigSource: CorsConfigSource, corsProcessor?: CorsProcessor}) => {\n const source = opts.corsConfigSource;\n const processor = opts.corsProcessor ?? processRequest;\n if (source === undefined) {\n throw new Error('corsConfigSource is required');\n }\n if (processor === undefined) {\n throw new Error('corsProcessor is required');\n }\n return async (ctx: ServerWebExchange, next: () => Promise<void>) => {\n const config = await source(ctx);\n const isValid = processor(ctx, config);\n if (!isValid || isPreFlightRequest(ctx.request)) {\n return;\n } else {\n await next();\n }\n };\n}\n\nexport default corsFilter;\n\n\nconst logger = getLogger('cors');\n\nfunction rejectRequest(response: ServerHttpResponse) {\n response.setStatusCode(HttpStatus.FORBIDDEN);\n}\n\nfunction handleInternal(exchange: ServerWebExchange,\n config: CorsConfig, preFlightRequest: boolean): boolean {\n const {request, response} = exchange;\n const responseHeaders = response.headers;\n\n const requestOrigin = request.headers.one('origin');\n const allowOrigin = checkOrigin(config, requestOrigin);\n\n if (allowOrigin === undefined) {\n if (logger.enabledFor('debug')) {\n logger.debug(`reject: '${requestOrigin}' origin is not allowed`);\n }\n rejectRequest(response);\n return false;\n }\n\n const requestMethod = getMethodToUse(request, preFlightRequest);\n const allowMethods = checkMethods(config, requestMethod);\n if (allowMethods === undefined) {\n if (logger.enabledFor('debug')) {\n logger.debug(`reject: HTTP '${requestMethod}' is not allowed`);\n }\n rejectRequest(response);\n return false;\n }\n\n const requestHeaders = getHeadersToUse(request, preFlightRequest);\n const allowHeaders = checkHeaders(config, requestHeaders);\n if (preFlightRequest && allowHeaders === undefined) {\n if (logger.enabledFor('debug')) {\n logger.debug(`reject: headers '${requestHeaders}' are not allowed`);\n }\n rejectRequest(response);\n return false;\n }\n\n responseHeaders.set('Access-Control-Allow-Origin', allowOrigin);\n\n if (preFlightRequest) {\n responseHeaders.set('Access-Control-Allow-Methods', allowMethods.join(','));\n\n }\n if (preFlightRequest && allowHeaders !== undefined && allowHeaders.length > 0) {\n responseHeaders.set('Access-Control-Allow-Headers', allowHeaders.join(', '));\n }\n const exposeHeaders = config.exposeHeaders;\n if (exposeHeaders && exposeHeaders.length > 0) {\n responseHeaders.set('Access-Control-Expose-Headers', exposeHeaders.join(', '));\n }\n if (config.allowCredentials) {\n responseHeaders.set('Access-Control-Allow-Credentials', 'true');\n }\n if (config.allowPrivateNetwork && request.headers.one('access-control-request-private-network') === 'true') {\n responseHeaders.set('Access-Control-Allow-Private-Network', 'true');\n }\n\n if (preFlightRequest && config.maxAge !== undefined) {\n responseHeaders.set('Access-Control-Max-Age', config.maxAge.toString());\n }\n return true;\n}\n\nconst ALL = '*';\nconst DEFAULT_METHODS = ['GET', 'HEAD'];\n\nfunction validateAllowCredentials(config: CorsConfig) {\n if (config.allowCredentials === true && config.allowOrigins === ALL) {\n throw new Error(`when allowCredentials is true allowOrigins cannot be \"*\"`);\n }\n}\n\nfunction validateAllowPrivateNetwork(config: CorsConfig) {\n if (config.allowPrivateNetwork === true && config.allowOrigins === ALL) {\n throw new Error(`when allowPrivateNetwork is true allowOrigins cannot be \"*\"`);\n }\n}\n\nfunction checkOrigin(config: CorsConfig, origin? :string): string | undefined {\n if (origin) {\n const allowedOrigins = config.allowOrigins;\n if (allowedOrigins) {\n if (allowedOrigins === ALL) {\n validateAllowCredentials(config);\n validateAllowPrivateNetwork(config);\n return ALL;\n }\n const originToCheck = trimTrailingSlash(origin.toLowerCase());\n\n for (const allowedOrigin of allowedOrigins) {\n if ((allowedOrigin === ALL) || IOGateway.Filtering.valueMatches(allowedOrigin, originToCheck)) {\n return origin;\n }\n }\n }\n }\n}\n\nfunction checkMethods(config: CorsConfig, requestMethod?: string): string[] | undefined {\n if (requestMethod) {\n const allowedMethods = config.allowMethods ?? DEFAULT_METHODS;\n if (allowedMethods === ALL) {\n return [requestMethod];\n }\n if (IOGateway.Filtering.valuesMatch(allowedMethods, requestMethod)) {\n return allowedMethods;\n }\n }\n}\n\nfunction checkHeaders(config: CorsConfig, requestHeaders?: string[]): string[] | undefined {\n if (requestHeaders === undefined) {\n return;\n }\n if (requestHeaders.length == 0) {\n return [];\n }\n const allowedHeaders = config.allowHeaders;\n if (allowedHeaders === undefined) {\n return;\n }\n const allowAnyHeader = allowedHeaders === ALL || allowedHeaders.includes(ALL);\n const result: string[] = [];\n for (const requestHeader of requestHeaders) {\n const value = requestHeader?.trim();\n if (value) {\n if (allowAnyHeader) {\n result.push(value);\n }\n else {\n for (const allowedHeader of allowedHeaders) {\n if (value.toLowerCase() === allowedHeader) {\n result.push(value);\n break;\n }\n }\n }\n }\n }\n if (result.length > 0) {\n return result;\n }\n}\n\nfunction trimTrailingSlash(origin: string): string {\n return origin.endsWith('/') ? origin.slice(0, -1) : origin;\n}\n\nfunction getMethodToUse(request: HttpRequest<ReadonlyHttpHeaders>, isPreFlight: boolean): string | undefined {\n return (isPreFlight ? request.headers.one('access-control-request-method') : request.method);\n}\n\nfunction getHeadersToUse(request: HttpRequest, isPreFlight: boolean): string[] {\n const headers = request.headers;\n return (isPreFlight ? headers.list('access-control-request-headers') : Array.from(headers.keys()));\n}\n\nexport const matchingCorsConfigSource = (opts: {mappings: Array<[ServerWebExchangeMatcher, CorsConfig | undefined]>}): CorsConfigSource => {\n return async (exchange: ServerWebExchange) => {\n for (const [matcher, config] of opts.mappings) {\n if ((await matcher(exchange)).match) {\n logger.debug(`resolved cors config on '${exchange.request.path}' using ${matcher}: ${JSON.stringify(config)}`);\n return config;\n }\n }\n }\n}\n", "import type { RouteConfig, PathPattern } from './route.ts';\nimport {\n combineCorsConfig,\n type CorsConfig,\n type CorsConfigSource,\n matchingCorsConfigSource,\n PERMIT_DEFAULT_CONFIG,\n validateCorsConfig\n} from '../server/cors.ts';\nimport { and, pattern, type ServerWebExchangeMatcher, upgradeMatcher } from '../server/util/matchers.ts';\nimport { IOGateway } from '@interopio/gateway';\n\nexport function createCorsConfigSource(context: Pick<RouteConfig, 'sockets' | 'cors' | 'corsConfig'>): CorsConfigSource {\n const {sockets: routes, cors} = context;\n\n // create a default CORS config that allows all origins and methods and then combine it with the provided corsConfig\n const defaultCorsConfig: CorsConfig | undefined = context.corsConfig === false ? undefined : combineCorsConfig(PERMIT_DEFAULT_CONFIG, context.corsConfig);\n\n const validatedConfigs: Array<[ServerWebExchangeMatcher, CorsConfig | undefined]> = [];\n\n // for each socket route, combine the default CORS config, then any app CORS config that match, and finally the route CORS config\n for (const [path, route] of routes) {\n let routeCorsConfig: CorsConfig | undefined = defaultCorsConfig;\n for (const [matcher, config] of cors) {\n if (IOGateway.Filtering.valueMatches(matcher, path)) {\n if (config === undefined) {\n routeCorsConfig = undefined;\n }\n else {\n routeCorsConfig = routeCorsConfig === undefined ? config : combineCorsConfig(routeCorsConfig, config);\n }\n }\n }\n const config = context.corsConfig === false ? undefined : {\n allowOrigins: route.originFilters?.allow,\n allowMethods: ['GET', 'CONNECT', 'OPTIONS'],\n allowHeaders: [\n 'Upgrade',\n 'Connection',\n 'Origin',\n 'Sec-Websocket-Key',\n 'Sec-Websocket-Version',\n 'Sec-Websocket-Protocol',\n 'Sec-Websocket-Extensions'\n ],\n exposeHeaders: ['Sec-Websocket-Accept', 'Sec-Websocket-Protocol', 'Sec-Websocket-Extensions'],\n allowCredentials: route.authorize?.access !== 'permitted' ? true : undefined,\n };\n routeCorsConfig = routeCorsConfig === undefined ? config : combineCorsConfig(routeCorsConfig, config);\n\n validatedConfigs.push([\n and([upgradeMatcher, pattern(path)]),\n validateCorsConfig(routeCorsConfig)]);\n }\n\n const appConfigs: Array<[PathPattern, CorsConfig | undefined]> = [];\n // add app CORS configs\n for (const [matcher, config] of cors) {\n let [, routeCorsConfig] = appConfigs.find(([m]) => String(m) === String(matcher)) ?? [matcher, defaultCorsConfig];\n\n routeCorsConfig = routeCorsConfig === undefined ? config : combineCorsConfig(routeCorsConfig, config);\n let added = false;\n for (const entry of appConfigs) {\n if (String(entry[0]) === String(matcher)) {\n entry[1] = routeCorsConfig;\n added = true;\n break;\n }\n }\n if (!added) {\n appConfigs.push([matcher, routeCorsConfig]);\n }\n }\n for (const [matcher, config] of appConfigs) {\n validatedConfigs.push([pattern(matcher), validateCorsConfig(config)]);\n }\n\n validatedConfigs.push([pattern(/\\/api\\/.*/), validateCorsConfig(defaultCorsConfig)]);\n\n\n return matchingCorsConfigSource({mappings: validatedConfigs});\n}\n", "import type { Principal } from '../../../types/auth';\nimport type { ServerWebExchange } from '../../../types/web/server';\n\n// A principal that has been authenticated and has a name.\nexport type AuthenticatedPrincipal = Principal & { readonly name: string };\n\nexport type Authentication = Principal & {\n type: string;\n readonly authorities?: ReadonlyArray<GrantedAuthority>;\n readonly credentials?: unknown;\n readonly details?: unknown;\n readonly principal?: unknown;\n authenticated: boolean;\n}\n\nexport type GrantedAuthority = {\n readonly authority?: string;\n}\n\n// An interface for holding credentials that can be erased. Not CredentialsContainer to avoid confusion with web Credential Management API .\nexport interface CredentialsHolder {\n eraseCredentials?(): void;\n}\n\nexport type AbstractAuthenticationToken = Authentication & CredentialsHolder & {\n readonly name: string;\n details?: unknown;\n}\n\nexport function isAuthentication(principal?: Principal): principal is Authentication {\n return principal !== undefined && typeof principal['type'] === 'string' && typeof principal['authenticated'] === 'boolean';\n}\n\nexport type AuthenticationConverter = (exchange: ServerWebExchange) => Promise<Authentication | undefined>;\n\nexport class AuthenticationError extends Error {\n private _authentication?: Authentication;\n\n get authentication(): Authentication | undefined {\n return this._authentication;\n }\n\n set authentication(value: Authentication) {\n if (value === undefined) {\n throw new TypeError(\"Authentication cannot be undefined\");\n }\n this._authentication = value;\n }\n}\n\nexport class InsufficientAuthenticationError extends AuthenticationError {}\n\nexport class BadCredentialsError extends AuthenticationError {}\n\nabstract class AccountStatusError extends AuthenticationError {\n protected constructor(message: string) {\n super(message);\n }\n}\n\nexport class LockedError extends AccountStatusError {\n constructor(message: string) {\n super(message);\n }\n}\n\nexport class DisabledError extends AccountStatusError {\n constructor(message: string) {\n super(message);\n }\n}\n\nexport class AccountExpiredError extends AccountStatusError {\n constructor(message: string) {\n super(message);\n }\n}\n\nexport class CredentialsExpiredError extends AccountStatusError {\n constructor(message: string) {\n super(message);\n }\n}\n\n\nexport class AuthenticationCredentialsNotFoundError extends AuthenticationError {}\n\nexport class AccessDeniedError extends Error {}\n\nexport type AuthenticationManager = (authentication: Authentication) => Promise<Authentication | undefined>;\n\nexport type AuthorizationManager<T> = {\n\n /**\n * Determines if access should be granted to the given object for the provided authentication.\n * @param authentication\n * @param object\n */\n verify(authentication: Promise<Authentication | undefined>, object: T): Promise<void>,\n /**\n * Checks if the authentication is authorized to access the given object.\n * @param authentication\n * @param object\n */\n authorize: (authentication: Promise<Authentication | undefined>, object: T) => Promise<AuthorizationResult | undefined>;\n}\nexport interface AuthorizationResult {readonly granted: boolean;}\nexport class AuthorizationDecision implements AuthorizationResult {\n constructor(granted: boolean) {\n this.granted = granted;\n }\n\n readonly granted: boolean;\n}\nexport class DefaultAuthorizationManager<T> implements AuthorizationManager<T> {\n readonly #check: (authentication: Promise<Authentication | undefined>, object: T) => Promise<AuthorizationDecision | undefined>;\n\n constructor(check: (authentication: Promise<Authentication | undefined>, object: T) => Promise<AuthorizationDecision>) {\n this.#check = check;\n }\n\n async verify(authentication: Promise<Authentication | undefined>, object: T): Promise<void> {\n const decision = await this.#check(authentication, object);\n if (!decision?.granted) {\n throw new AccessDeniedError(\"Access denied\");\n }\n }\n\n async authorize(authentication: Promise<Authentication | undefined>, object: T) {\n return await this.#check(authentication, object);\n }\n}\n\nexport class AuthenticationServiceError extends AuthenticationError {}\nexport type ServerAuthenticationSuccessHandler = (filterExchange: {exchange: ServerWebExchange, next: () => Promise<void>}, authentication: Authentication) => Promise<void>;\nexport type ServerAuthenticationFailureHandler = (filterExchange: {exchange: ServerWebExchange, next: () => Promise<void>}, error: AuthenticationError) => Promise<void>;\nexport type ServerAuthenticationEntryPoint = (exchange: ServerWebExchange, error: AuthenticationError) => Promise<void>;\nexport type ServerAccessDeniedHandler = (exchange: ServerWebExchange, error: AccessDeniedError) => Promise<void>;\n", "import { MapHttpHeaders } from '../../http/exchange.ts';\nimport type { ServerWebExchange } from '../../../types/web/server';\n\ntype ServerHttpHeadersWriter = (exchange: ServerWebExchange) => Promise<void>;\n\nconst staticServerHttpHeadersWriter = (headers: MapHttpHeaders): ServerHttpHeadersWriter => {\n return async (exchange: ServerWebExchange) => {\n let containsNoHeaders = true;\n const {response} = exchange;\n for (const name of headers.keys()) {\n if (response.headers.has(name)) {\n containsNoHeaders = false;\n }\n }\n if (containsNoHeaders) {\n for (const [name, value] of headers) {\n response.headers.set(name, value);\n }\n }\n }\n}\n\nconst cacheControlServerHttpHeadersWriter = () => staticServerHttpHeadersWriter(\n new MapHttpHeaders()\n .add('cache-control', 'no-cache, no-store, max-age=0, must-revalidate')\n .add('pragma', 'no-cache')\n .add('expires', '0'));\n\nconst contentTypeServerHttpHeadersWriter = () => staticServerHttpHeadersWriter(\n new MapHttpHeaders()\n .add('x-content-type-options', 'nosniff'));\n\nconst strictTransportSecurityServerHttpHeadersWriter = (maxAgeInSeconds: number, includeSubDomains: boolean, preload: boolean) => {\n let headerValue = `max-age=${maxAgeInSeconds}`;\n if (includeSubDomains) {\n headerValue += ' ; includeSubDomains';\n }\n if (preload) {\n headerValue += ' ; preload';\n }\n const delegate = staticServerHttpHeadersWriter(\n new MapHttpHeaders()\n .add('strict-transport-security', headerValue))\n\n const isSecure = (exchange: ServerWebExchange) => {\n const protocol = exchange.request.URL.protocol;\n return protocol === 'https:';\n }\n\n return async (exchange: ServerWebExchange) => {\n if (isSecure(exchange)) {\n await delegate(exchange);\n }\n }\n};\n\ntype FrameOptionsMode = 'DENY' | 'SAMEORIGIN';\nconst frameOptionsServerHttpHeadersWriter = (mode: FrameOptionsMode) => {\n return staticServerHttpHeadersWriter(\n new MapHttpHeaders()\n .add('x-frame-options', mode))\n};\n\ntype XssProtectionHeaderValue = '0' | '1' | '1; mode=block';\nconst xssProtectionServerHttpHeadersWriter = (headerValue: XssProtectionHeaderValue) => staticServerHttpHeadersWriter(\n new MapHttpHeaders()\n .add('x-xss-protection', headerValue));\n\n\nconst permissionsPolicyServerHttpHeadersWriter = (policyDirectives?: string) => {\n\n const delegate = policyDirectives === undefined ? undefined : staticServerHttpHeadersWriter(\n new MapHttpHeaders()\n .add('permissions-policy', policyDirectives));\n return async (exchange: ServerWebExchange) => {\n if (delegate !== undefined) {\n await delegate(exchange);\n }\n }\n}\nconst contentSecurityPolicyServerHttpHeadersWriter = (policyDirectives?: string, reportOnly?: boolean) => {\n const headerName = reportOnly ? 'content-security-policy-report-only' : 'content-security-policy';\n const delegate = policyDirectives === undefined ? undefined : staticServerHttpHeadersWriter(\n new MapHttpHeaders()\n .add(headerName, policyDirectives));\n return async (exchange: ServerWebExchange) => {\n if (delegate !== undefined) {\n await delegate(exchange);\n }\n }\n};\n\ntype ReferrerPolicy =\n 'no-referrer'\n | 'no-referrer-when-downgrade'\n | 'origin'\n | 'origin-when-cross-origin'\n | 'same-origin'\n | 'strict-origin'\n | 'strict-origin-when-cross-origin'\n | 'unsafe-url';\nconst refererPolicyServerHttpHeadersWriter = (policy: ReferrerPolicy = 'no-referrer') => {\n return staticServerHttpHeadersWriter(\n new MapHttpHeaders()\n .add('referer-policy', policy));\n}\n\ntype CrossOriginOpenerPolicy = 'unsafe-none' | 'same-origin' | 'same-origin-allow-popups';\nconst crossOriginOpenerPolicyServerHttpHeadersWriter = (policy?: CrossOriginOpenerPolicy) => {\n const delegate = policy === undefined ? undefined : staticServerHttpHeadersWriter(\n new MapHttpHeaders()\n .add('cross-origin-opener-policy', policy));\n return async (exchange: ServerWebExchange) => {\n if (delegate !== undefined) {\n await delegate(exchange);\n }\n }\n}\n\ntype CrossOriginEmbedderPolicy = 'unsafe-none' | 'require-corp';\nconst crossOriginEmbedderPolicyServerHttpHeadersWriter = (policy?: CrossOriginEmbedderPolicy) => {\n const delegate = policy === undefined ? undefined : staticServerHttpHeadersWriter(\n new MapHttpHeaders()\n .add('cross-origin-embedder-policy', policy));\n return async (exchange: ServerWebExchange) => {\n if (delegate !== undefined) {\n await delegate(exchange);\n }\n }\n}\n\ntype CrossOriginResourcePolicy = 'same-origin' | 'same-site' | 'cross-origin';\nconst crossOriginResourcePolicyServerHttpHeadersWriter = (policy?: CrossOriginResourcePolicy) => {\n const delegate = policy === undefined ? undefined : staticServerHttpHeadersWriter(\n new MapHttpHeaders()\n .add('cross-origin-resource-policy', policy));\n return async (exchange: ServerWebExchange) => {\n if (delegate !== undefined) {\n await delegate(exchange);\n }\n }\n}\n\nconst compositeServerHttpHeadersWriter = (\n ...writers: ServerHttpHeadersWriter[]\n): ServerHttpHeadersWriter => {\n return async (exchange: ServerWebExchange) => {\n for (const writer of writers) {\n await writer(exchange);\n }\n }\n}\n\nexport default function headers(opts?: {\n cache?: { disabled?: boolean }\n contentType?: { disabled?: boolean },\n frameOptions?: { disabled?: boolean, mode?: FrameOptionsMode },\n hsts?: { disabled?: boolean, maxAge?: number, includeSubDomains?: boolean, preload?: boolean },\n xss?: { disabled?: boolean, headerValue?: XssProtectionHeaderValue },\n permissionsPolicy?: { disabled?: boolean, policyDirectives?: string },\n contentSecurityPolicy?: { disabled?: boolean, policyDirectives?: string, reportOnly?: boolean },\n refererPolicy?: { disabled?: boolean, policy?: ReferrerPolicy },\n crossOriginOpenerPolicy?: { disabled?: boolean, policy?: CrossOriginOpenerPolicy },\n crossOriginEmbedderPolicy?: { disabled?: boolean, policy?: CrossOriginEmbedderPolicy },\n crossOriginResourcePolicy?: { disabled?: boolean, policy?: CrossOriginResourcePolicy }\n writers?: ServerHttpHeadersWriter[]\n}) {\n const writers: ServerHttpHeadersWriter[] = [];\n if (!opts?.cache?.disabled) {\n writers.push(cacheControlServerHttpHeadersWriter());\n }\n if (!opts?.contentType?.disabled) {\n writers.push(contentTypeServerHttpHeadersWriter());\n }\n if (!opts?.hsts?.disabled) {\n writers.push(strictTransportSecurityServerHttpHeadersWriter(opts?.hsts?.maxAge ?? 365 * 24 * 60 * 60, opts?.hsts?.includeSubDomains ?? true, opts?.hsts?.preload ?? false));\n }\n if (!opts?.frameOptions?.disabled) {\n writers.push(frameOptionsServerHttpHeadersWriter(opts?.frameOptions?.mode ?? 'DENY'));\n }\n if (!opts?.xss?.disabled) {\n writers.push(xssProtectionServerHttpHeadersWriter(opts?.xss?.headerValue ?? '0'));\n }\n if (!opts?.permissionsPolicy?.disabled) {\n writers.push(permissionsPolicyServerHttpHeadersWriter(opts?.permissionsPolicy?.policyDirectives));\n }\n if (!opts?.contentSecurityPolicy?.disabled) {\n writers.push(contentSecurityPolicyServerHttpHeadersWriter(opts?.contentSecurityPolicy?.policyDirectives ?? \"default-src 'self'\", opts?.contentSecurityPolicy?.reportOnly));\n }\n if (!opts?.refererPolicy?.disabled) {\n writers.push(refererPolicyServerHttpHeadersWriter(opts?.refererPolicy?.policy ?? 'no-referrer'));\n }\n if (!opts?.crossOriginOpenerPolicy?.disabled) {\n writers.push(crossOriginOpenerPolicyServerHttpHeadersWriter(opts?.crossOriginOpenerPolicy?.policy));\n }\n if (!opts?.crossOriginEmbedderPolicy?.disabled) {\n writers.push(crossOriginEmbedderPolicyServerHttpHeadersWriter(opts?.crossOriginEmbedderPolicy?.policy));\n }\n if (!opts?.crossOriginResourcePolicy?.disabled) {\n writers.push(crossOriginResourcePolicyServerHttpHeadersWriter(opts?.crossOriginResourcePolicy?.policy));\n }\n if (opts?.writers) {\n writers.push(...opts.writers);\n }\n const writer = compositeServerHttpHeadersWriter(...writers);\n\n return async (exchange: ServerWebExchange, next: () => Promise<void>) => {\n await writer(exchange);\n await next();\n }\n}\n", "import {\n AuthenticationServiceError,\n type ServerAuthenticationEntryPoint,\n type ServerAuthenticationFailureHandler\n} from './types.ts';\n\nexport const serverAuthenticationEntryPointFailureHandler = (opts: {\n entryPoint: ServerAuthenticationEntryPoint,\n rethrowAuthenticationServiceError?: boolean\n}): ServerAuthenticationFailureHandler => {\n const entryPoint = opts.entryPoint;\n const rethrowAuthenticationServiceError = opts?.rethrowAuthenticationServiceError ?? true;\n return async ({exchange}, error) => {\n if (!rethrowAuthenticationServiceError) {\n return entryPoint(exchange, error);\n }\n if (!(error instanceof AuthenticationServiceError)) {\n return entryPoint(exchange, error);\n }\n throw error;\n\n };\n\n\n}\n", "import type { ServerAuthenticationEntryPoint } from './types.ts';\nimport { HttpStatus } from '../../http/status.ts';\n\nconst DEFAULT_REALM = 'Realm';\nconst createHeaderValue = (realm: string): string => {\n return `Basic realm=\"${realm}\"`;\n}\n\nexport const httpBasicEntryPoint = (opts?: { realm?: string }): ServerAuthenticationEntryPoint => {\n const headerValue = createHeaderValue(opts?.realm ?? DEFAULT_REALM);\n return async (exchange, _error) => {\n const {response} = exchange;\n response.setStatusCode(HttpStatus.UNAUTHORIZED);\n response.headers.set('WWW-Authenticate', headerValue);\n };\n}\n", "import type { AbstractAuthenticationToken, AuthenticationConverter } from './types.ts';\n\nconst BASIC = 'Basic ';\n\nexport const httpBasicAuthenticationConverter = (opts?: {credentialsEncoding?: BufferEncoding}): AuthenticationConverter => {\n const credentialsEncoding = opts?.credentialsEncoding ?? 'utf-8';\n\n return async (exchange): Promise<AbstractAuthenticationToken | undefined> => {\n const { request } = exchange;\n const authorization = request.headers.one(\"authorization\");\n if (!authorization || !(/basic/i).test(authorization.substring(0,))) {\n return;\n }\n const credentials = authorization.length <= BASIC.length ? '' : authorization.substring(BASIC.length);\n const decoded = Buffer.from(credentials, 'base64').toString(credentialsEncoding);\n const parts = decoded.split(\":\", 2);\n if (parts.length !== 2) {\n return undefined;\n }\n const principal = parts[0];\n let erasableCredentials: string | null = parts[1];\n return {\n type: 'UsernamePassword',\n authenticated: false,\n principal,\n credentials: erasableCredentials,\n name: principal,\n eraseCredentials: () => {\n erasableCredentials = null;\n },\n };\n }\n\n}\n", "import type { Authentication } from './types';\nimport { AsyncLocalStorage } from 'node:async_hooks';\n\nexport interface SecurityContext {\n authentication?: Authentication;\n}\n\nexport class AsyncStorageSecurityContextHolder {\n private static hasSecurityContext(storage: AsyncLocalStorage<{\n securityContext?: Promise<SecurityContext>\n }>): boolean {\n return storage.getStore()?.securityContext !== undefined;\n }\n\n private static async getSecurityContext(storage: AsyncLocalStorage<{\n securityContext?: Promise<SecurityContext>\n }>): Promise<SecurityContext | undefined> {\n return await storage.getStore()?.securityContext;\n }\n\n public static clearSecurityContext(storage: AsyncLocalStorage<{ securityContext?: Promise<SecurityContext> }>) {\n delete storage.getStore()?.securityContext;\n }\n\n public static withSecurityContext(securityContext: Promise<SecurityContext>) {\n return (storage: AsyncLocalStorage<{ securityContext?: Promise<SecurityContext> }> = new AsyncLocalStorage<{\n securityContext?: Promise<SecurityContext>\n }>()) => {\n storage.getStore()!.securityContext = securityContext;\n return storage;\n };\n }\n\n public static withAuthentication(authentication: Authentication) {\n return AsyncStorageSecurityContextHolder.withSecurityContext(Promise.resolve({authentication}));\n }\n\n public static async getContext(storage: AsyncLocalStorage<{ securityContext?: Promise<SecurityContext> }>): Promise<SecurityContext | undefined> {\n if (AsyncStorageSecurityContextHolder.hasSecurityContext(storage)) {\n return AsyncStorageSecurityContextHolder.getSecurityContext(storage);\n }\n }\n}\n\n", "import { type Authentication } from './types.ts';\nimport {\n type AuthenticationConverter,\n AuthenticationError,\n type AuthenticationManager,\n type ServerAuthenticationFailureHandler,\n type ServerAuthenticationSuccessHandler\n} from './types.ts';\nimport { serverAuthenticationEntryPointFailureHandler } from './entry-point-failure-handler.ts';\nimport { httpBasicEntryPoint } from './http-basic-entry-point.ts';\nimport { httpBasicAuthenticationConverter } from './http-basic-converter.ts';\nimport { anyExchange, type ServerWebExchangeMatcher } from '../util/matchers.ts';\nimport { AsyncStorageSecurityContextHolder, type SecurityContext } from './security-context.ts';\nimport { AsyncLocalStorage } from 'node:async_hooks';\nimport type { ServerWebExchange } from '../../../types/web/server'\n\nasync function authenticate(exchange: ServerWebExchange,\n next: () => Promise<void>,\n token: Authentication,\n managerResolver: (exchange: ServerWebExchange) => Promise<AuthenticationManager | undefined>,\n successHandler: ServerAuthenticationSuccessHandler,\n storage: AsyncLocalStorage<{ securityContext?: Promise<SecurityContext> }>): Promise<void> {\n const authManager = await managerResolver(exchange);\n const authentication = await authManager?.(token);\n if (authentication === undefined) {\n throw new Error(\"No authentication manager found for the exchange\");\n }\n try {\n await onAuthenticationSuccess(authentication, {exchange, next}, successHandler, storage);\n } catch (e) {\n if (e instanceof AuthenticationError) {\n // todo debug log\n }\n throw e;\n }\n}\n\nasync function onAuthenticationSuccess(authentication: Authentication,\n filterExchange: {exchange: ServerWebExchange, next: () => Promise<void>},\n successHandler: ServerAuthenticationSuccessHandler,\n storage: AsyncLocalStorage<{ securityContext?: Promise<SecurityContext> }>): Promise<void> {\n AsyncStorageSecurityContextHolder.withAuthentication(authentication)(storage);\n await successHandler(filterExchange, authentication);\n\n}\n\nexport type AuthenticationFilterOptions = {\n storage: AsyncLocalStorage<{securityContext?: Promise<SecurityContext>}>\n managerResolver?: (exchange: ServerWebExchange) => Promise<AuthenticationManager | undefined>,\n manager?: AuthenticationManager,\n successHandler?: ServerAuthenticationSuccessHandler,\n // converter is a function that converts the exchange to an authentication object\n converter?: AuthenticationConverter,\n failureHandler?: ServerAuthenticationFailureHandler\n // matcher is a function that checks if the exchange must be authenticated\n matcher?: ServerWebExchangeMatcher,\n};\n\nexport default function authenticationFilter(opts: AuthenticationFilterOptions) {\n const auth = {\n matcher: anyExchange,\n successHandler: async({next}) => {\n await next();\n },\n converter: httpBasicAuthenticationConverter({}),\n failureHandler: serverAuthenticationEntryPointFailureHandler({ entryPoint: httpBasicEntryPoint({}) }),\n ...opts\n };\n let managerResolver = auth.managerResolver;\n if (managerResolver === undefined && auth.manager !== undefined) {\n const manager: AuthenticationManager = auth.manager;\n managerResolver = async (_exchange: ServerWebExchange) => {\n return manager;\n };\n }\n if (managerResolver === undefined) {\n throw new Error(\"Authentication filter requires a managerResolver or a manager\");\n }\n return async (exchange: ServerWebExchange, next: () => Promise<void>): Promise<void> => {\n const matchResult = await auth.matcher(exchange);\n const token = matchResult.match ? await auth.converter(exchange) : undefined;\n if (token === undefined) {\n await next();\n return;\n }\n\n try {\n await authenticate(exchange, next, token, managerResolver, auth.successHandler, auth.storage);\n\n } catch (error) {\n if (error instanceof AuthenticationError) {\n await auth.failureHandler({exchange, next}, error);\n return;\n }\n throw error; // Re-throw the error to be handled by the next middleware or error handler\n }\n };\n}\n", "import type { AuthenticationError, ServerAuthenticationEntryPoint } from './types.ts';\nimport { HttpStatus } from \"../../http/status.ts\";\n\nexport const httpStatusEntryPoint = (opts: {\n httpStatus: HttpStatus\n}): ServerAuthenticationEntryPoint => {\n return async (exchange, _error: AuthenticationError) => {\n const response = exchange.response;\n response.setStatusCode(opts.httpStatus);\n };\n}\n", "import {AuthenticationError, type ServerAuthenticationEntryPoint} from './types.ts';\nimport {type ServerWebExchangeMatcher} from '../util/matchers.ts';\nimport {HttpStatus} from '../../http/status.ts';\nimport getLogger from '../../logger.ts';\nimport type {ServerWebExchange} from '../../../types/web/server';\n\nconst logger = getLogger('auth.entry-point');\n\nexport const delegatingEntryPoint = (opts: {\n entryPoints: Array<[ServerWebExchangeMatcher, ServerAuthenticationEntryPoint]>;\n defaultEntryPoint: ServerAuthenticationEntryPoint;\n}): ServerAuthenticationEntryPoint => {\n const defaultEntryPoint = opts.defaultEntryPoint ?? (async ({response}, _error) => {\n response.setStatusCode(HttpStatus.UNAUTHORIZED);\n await response.end();\n });\n return async (exchange: ServerWebExchange, error: AuthenticationError) => {\n for (const [matcher, entryPoint] of opts.entryPoints) {\n if (logger.enabledFor('debug')) {\n logger.debug(`trying to match using: ${matcher}`);\n }\n const match = await matcher(exchange);\n if (match.match) {\n if (logger.enabledFor('debug')) {\n logger.debug(`match found. using default entry point ${entryPoint}`);\n }\n return entryPoint(exchange, error);\n }\n }\n if (logger.enabledFor('debug')) {\n logger.debug(`no match found. using default entry point ${defaultEntryPoint}`);\n }\n return defaultEntryPoint(exchange, error);\n };\n}\n", "import type {Authentication, ServerAuthenticationSuccessHandler} from './types.ts';\n\nexport const delegatingSuccessHandler = (handlers: Array<ServerAuthenticationSuccessHandler>) => {\n\n return async ({exchange, next}, authentication: Authentication) => {\n for (const handler of handlers) {\n await handler({exchange, next}, authentication);\n }\n };\n}\n", "import authenticationFilter from './authentication-filter.ts';\nimport { serverAuthenticationEntryPointFailureHandler } from './entry-point-failure-handler.ts';\nimport type {\n AuthenticationManager,\n ServerAuthenticationEntryPoint,\n ServerAuthenticationFailureHandler,\n ServerAuthenticationSuccessHandler\n} from './types.ts';\nimport { httpStatusEntryPoint } from './http-status-entry-point.ts';\nimport { httpBasicEntryPoint } from './http-basic-entry-point.ts';\nimport { delegatingEntryPoint } from './delegating-entry-point.ts';\nimport { httpBasicAuthenticationConverter } from './http-basic-converter.ts';\nimport { delegatingSuccessHandler } from './delegating-success-handler.ts';\nimport type { SecurityContext } from './security-context.ts';\nimport type { MatchResult, ServerWebExchangeMatcher } from '../util/matchers.ts';\nimport * as matchers from '../util/matchers.ts';\nimport { HttpStatus } from '../../http/status.ts';\nimport { AsyncLocalStorage } from 'node:async_hooks';\nimport type { ServerWebExchange } from '../../../types/web/server';\n\nexport default function httpBasic(opts: {\n readonly storage: AsyncLocalStorage<{securityContext?: Promise<SecurityContext>}>\n readonly manager: AuthenticationManager;\n readonly entryPoint?: ServerAuthenticationEntryPoint;\n readonly failureHandler?: ServerAuthenticationFailureHandler;\n readonly successHandlers?: ServerAuthenticationSuccessHandler[];\n defaultEntryPoints: Array<[ServerWebExchangeMatcher, ServerAuthenticationEntryPoint]>;\n defaultSuccessHandlers: ServerAuthenticationSuccessHandler[];\n}) {\n\n const xhrMatcher: ServerWebExchangeMatcher = async (exchange: ServerWebExchange): Promise<MatchResult> => {\n const headers = exchange.request.headers;\n const h = headers.list('X-Requested-With');\n if (h.includes('XMLHttpRequest')) {\n return matchers.match();\n }\n return matchers.NO_MATCH;\n }\n\n const defaultEntryPoint = delegatingEntryPoint({\n entryPoints: [[xhrMatcher, httpStatusEntryPoint({httpStatus: HttpStatus.UNAUTHORIZED})]],\n defaultEntryPoint: httpBasicEntryPoint({})\n });\n\n const entryPoint = opts.entryPoint ?? defaultEntryPoint;\n\n const manager = opts.manager;\n\n const restMatcher = matchers.mediaType({\n mediaTypes: [\n 'application/atom+xml',\n 'application/x-www-form-urlencoded',\n 'application/json',\n 'application/octet-stream',\n 'application/xml',\n 'multipart/form-data',\n 'text/xml'\n ],\n ignoredMediaTypes: ['*/*']\n });\n\n const notHtmlMatcher = matchers.not(matchers.mediaType({ mediaTypes: ['text/html'] }));\n const restNoHtmlMatcher = matchers.and([notHtmlMatcher, restMatcher]);\n const preferredMatcher = matchers.or([xhrMatcher, restNoHtmlMatcher]);\n opts.defaultEntryPoints.push([preferredMatcher, entryPoint]);\n const failureHandler = opts.failureHandler ?? serverAuthenticationEntryPointFailureHandler({entryPoint});\n const successHandler = delegatingSuccessHandler(opts.successHandlers ?? opts.defaultSuccessHandlers);\n const converter = httpBasicAuthenticationConverter({});\n return authenticationFilter({\n storage: opts.storage,\n manager,\n failureHandler,\n successHandler,\n converter\n });\n}\n\n", "import { HttpStatus } from '../../../http/status.ts';\n\nexport type OAuth2Error = {\n readonly errorCode: string\n readonly description?: string\n readonly uri?: string\n}\n\nexport type BearerTokenError = OAuth2Error & {\n readonly httpStatus: HttpStatus\n readonly scope?: string\n}\n\nexport const BearerTokenErrorCodes = {\n invalid_request: 'invalid_request',\n invalid_token: 'invalid_token',\n insufficient_scope: 'insufficient_scope',\n}\n\nconst DEFAULT_URI = \"https://tools.ietf.org/html/rfc6750#section-3.1\";\n\nexport function invalidToken(message: string): BearerTokenError {\n return {\n errorCode: BearerTokenErrorCodes.invalid_token,\n httpStatus: HttpStatus.UNAUTHORIZED,\n description: message,\n uri: DEFAULT_URI\n };\n}\n\nexport function invalidRequest(message: string): BearerTokenError {\n return {\n errorCode: BearerTokenErrorCodes.invalid_request,\n httpStatus: HttpStatus.BAD_REQUEST,\n description: message,\n uri: DEFAULT_URI\n };\n}\n\nexport function insufficientScope(message: string, scope?: string): BearerTokenError {\n return {\n errorCode: BearerTokenErrorCodes.insufficient_scope,\n httpStatus: HttpStatus.FORBIDDEN,\n description: message,\n uri: DEFAULT_URI,\n scope\n };\n}\n", "import { type Authentication, type AuthenticationConverter, AuthenticationError } from '../types.ts';\nimport { invalidRequest, invalidToken, type OAuth2Error } from './token-error.ts';\nimport type { ReadonlyHttpHeaders } from '../../../../types/web/http';\nimport type { ServerHttpRequest, ServerWebExchange } from '../../../../types/web/server';\n\nconst ACCESS_TOKEN_PARAMETER_NAME = 'access_token';\nconst authorizationPattern = /^Bearer\\s+(?<token>[a-zA-Z0-9-._~+/]+=*)$/i;\n\nexport class Oauth2AuthenticationError extends AuthenticationError {\n readonly error: OAuth2Error;\n\n constructor(error: string | OAuth2Error, message?: string, options?: ErrorOptions) {\n super(message ?? (typeof error === 'string' ? undefined : error.description), options);\n this.error = typeof error === 'string' ? {errorCode: error} : error;\n }\n}\n\nexport type BearerTokenAuthenticationToken = Authentication & {\n type: 'BearerToken';\n token: string;\n}\n\nexport const isBearerTokenAuthenticationToken = (authentication: Authentication): authentication is BearerTokenAuthenticationToken => {\n return authentication.type === 'BearerToken';\n}\n\nconst serverBearerTokenAuthenticationConverter = (opts?: {headerName?: string, uriQueryParameter?: boolean, formEncodedBodyParameter?: boolean }): AuthenticationConverter => {\n return async (exchange: ServerWebExchange) => {\n const {request} = exchange;\n return Promise.all<string[] | undefined>([\n resolveFromAuthorizationHeader(request.headers, opts?.headerName).then((token?: string) => token !== undefined ? [token] : undefined),\n resolveFromQueryString(request, opts?.uriQueryParameter),\n resolveFromBody(exchange, opts?.formEncodedBodyParameter)\n ])\n .then(rs => rs.filter(r => r !== undefined).flat(1))\n .then(resolveToken)\n .then(token => {\n if (token) return {authenticated: false, type: 'BearerToken', token};\n });\n }\n}\n\nasync function resolveToken(accessTokens: string[]) {\n if (accessTokens.length === 0) {\n return;\n }\n if (accessTokens.length > 1) {\n const error = invalidRequest('Found multiple access tokens in the request');\n throw new Oauth2AuthenticationError(error);\n }\n\n const accessToken = accessTokens[0];\n if (!accessToken || accessToken.length === 0) {\n const error = invalidRequest('The requested access token parameter is an empty string');\n throw new Oauth2AuthenticationError(error);\n }\n return accessToken;\n}\n\nasync function resolveFromAuthorizationHeader(headers: ReadonlyHttpHeaders, headerName: string = 'authorization'): Promise<string | undefined> {\n const authorization = headers.one(headerName);\n if (!authorization || !(/bearer/i).test(authorization.substring(0,))) {\n return;\n }\n const match = authorizationPattern.exec(authorization);\n if (match === null) {\n const error = invalidToken('Bearer token is malformed');\n throw new Oauth2AuthenticationError(error);\n }\n return match.groups?.token;\n}\n\nasync function resolveTokens(parameters: URLSearchParams): Promise<string[] | undefined> {\n const accessTokens = parameters.getAll(ACCESS_TOKEN_PARAMETER_NAME);\n if (accessTokens.length === 0) {\n return;\n }\n return accessTokens;\n}\n\nasync function resolveFromQueryString(request: ServerHttpRequest, allow = false): Promise<string[] | undefined> {\n if (!allow || request.method !== 'GET') {\n return;\n }\n return resolveTokens(request.URL.searchParams);\n}\n\nasync function resolveFromBody(exchange: ServerWebExchange, allow = false): Promise<string[] | undefined> {\n const {request} = exchange;\n if (!allow\n || ('application/x-www-form-urlencoded' !== request.headers.one('content-type'))\n || request.method !== 'POST') {\n return;\n }\n const parameters = await exchange.request.formData();\n if (parameters) {\n return resolveTokens(parameters);\n }\n}\n\nexport default serverBearerTokenAuthenticationConverter;\n", "import { AuthenticationError, type ServerAuthenticationEntryPoint } from '../types.ts';\nimport { Oauth2AuthenticationError } from './token-converter.ts';\nimport type { BearerTokenError, OAuth2Error } from './token-error.ts';\nimport { HttpStatus } from '../../../http/status.ts';\n\nfunction computeWWWAuthenticate(parameters: Map<string, string>) {\n let wwwAuthenticate = 'Bearer';\n if (parameters.size !== 0) {\n wwwAuthenticate += ' ';\n let i = 0;\n for (const [key, value] of parameters) {\n wwwAuthenticate += `${key}=\"${value}\"`;\n if (i !== parameters.size - 1) {\n wwwAuthenticate += ', ';\n }\n i++;\n }\n }\n return wwwAuthenticate;\n}\n\nconst isBearerTokenError = (error: OAuth2Error): error is BearerTokenError => {\n return (error as BearerTokenError).httpStatus !== undefined;\n}\n\nfunction getStatus(authError: AuthenticationError): HttpStatus {\n if (authError instanceof Oauth2AuthenticationError) {\n const {error} = authError;\n if (isBearerTokenError(error)) {\n return error.httpStatus;\n }\n }\n return HttpStatus.UNAUTHORIZED;\n}\n\nfunction createParameters(authError: AuthenticationError, realm?: string) {\n const parameters = new Map<string, string>();\n if (realm) {\n parameters.set('realm', realm);\n }\n if (authError instanceof Oauth2AuthenticationError) {\n const {error} = authError;\n parameters.set('error', error.errorCode);\n if (error.description) {\n parameters.set('error_description', error.description);\n }\n if (error.uri) {\n parameters.set('error_uri', error.uri);\n }\n if (isBearerTokenError(error) && error.scope) {\n parameters.set('scope', error.scope);\n }\n }\n return parameters;\n}\n\nconst bearerTokenServerAuthenticationEntryPoint = (opts?: { realmName?: string }): ServerAuthenticationEntryPoint => {\n return async (exchange, error) => {\n const status = getStatus(error);\n const parameters = createParameters(error, opts?.realmName)\n const wwwAuthenticate = computeWWWAuthenticate(parameters);\n const {response} = exchange;\n response.headers.set('WWW-Authenticate', wwwAuthenticate);\n response.setStatusCode(status);\n await response.end();\n };\n}\n\nexport default bearerTokenServerAuthenticationEntryPoint;\n", "import {\n type AbstractAuthenticationToken,\n type Authentication,\n type AuthenticationManager,\n AuthenticationServiceError\n} from '../types.ts';\nimport { invalidToken } from './token-error.ts';\nimport { isBearerTokenAuthenticationToken, Oauth2AuthenticationError } from './token-converter.ts';\n\nexport interface Jwt extends OAuth2Token {\n readonly subject?: string\n\n getClaimAsString(claim: string): string | undefined\n}\n\nexport type OAuth2Token = {\n readonly tokenValue: string;\n readonly issuedAt?: Date;\n readonly expiresAt?: Date;\n}\n\ntype AbstractOAuth2TokenAuthenticationToken<T extends OAuth2Token> = AbstractAuthenticationToken & {\n // token: T;\n}\n\n\nconst jwtAuthConverter = (opts?: { principalClaimName?: string}): (jwt: Jwt) => AbstractAuthenticationToken => {\n const principalClaimName = opts?.principalClaimName ?? 'sub';\n\n return (jwt: Jwt) => {\n const name = jwt.getClaimAsString(principalClaimName)!;\n const authentication: (AbstractOAuth2TokenAuthenticationToken<any> & { type: 'JwtToken' }) = { type: 'JwtToken', authenticated: true, name };\n return authentication;\n };\n}\n\nconst asyncJwtConverter = (converter: (jwt: Jwt) => Authentication): (jwt: Jwt) => Promise<Authentication> => {\n return async (jwt: Jwt) => {\n return converter(jwt);\n };\n};\n\nexport class JwtError extends Error {}\nexport class BadJwtError extends JwtError {}\n\n\nfunction onError(error: JwtError) {\n if (error instanceof BadJwtError) {\n return new Oauth2AuthenticationError(invalidToken(error.message), error.message, {cause: error});\n }\n throw new AuthenticationServiceError(error.message, {cause: error});\n\n}\n\nexport default function jwtAuthManager(opts: {\n decoder: (token: string) => Promise<Jwt>\n authConverter?: (jwt: Jwt) => Promise<Authentication>\n}): AuthenticationManager {\n const decoder = opts.decoder;\n const authConverter = opts.authConverter ?? asyncJwtConverter(jwtAuthConverter({}));\n return async (authentication) => {\n if (isBearerTokenAuthenticationToken(authentication)) {\n const token = authentication.token;\n try {\n const jwt = await decoder(token);\n return await authConverter(jwt);\n } catch (e) {\n if (e instanceof JwtError) {\n throw onError(e);\n }\n throw e;\n }\n }\n }\n}\n", "import authenticationFilter from './authentication-filter.ts';\nimport type {\n Authentication,\n AuthenticationConverter,\n AuthenticationManager,\n ServerAuthenticationEntryPoint,\n ServerAuthenticationFailureHandler\n} from './types.ts';\nimport serverBearerTokenAuthenticationConverter from './oauth2/token-converter.ts';\nimport { serverAuthenticationEntryPointFailureHandler } from './entry-point-failure-handler.ts';\nimport bearerTokenServerAuthenticationEntryPoint from './oauth2/token-entry-point.ts';\nimport jwtAuthManager, { type Jwt } from './oauth2/jwt-auth-manager.ts';\nimport type { SecurityContext } from './security-context.ts';\nimport { AsyncLocalStorage } from 'node:async_hooks';\nimport type { ServerWebExchange } from '../../../types/web/server';\n\nexport default function resourceServer(opts: {\n readonly storage: AsyncLocalStorage<{securityContext?: Promise<SecurityContext>}>,\n converter?: AuthenticationConverter,\n failureHandler?: ServerAuthenticationFailureHandler,\n entryPoint?: ServerAuthenticationEntryPoint,\n managerResolver?: (exchange: ServerWebExchange) => Promise<AuthenticationManager | undefined>,\n jwt?: {\n manager?: AuthenticationManager,\n decoder: (token: string) => Promise<Jwt>,\n authConverter?: (jwt: Jwt) => Promise<Authentication>\n }\n}): (exchange: ServerWebExchange, next: () => Promise<void>) => Promise<void> {\n const entryPoint = opts.entryPoint ?? bearerTokenServerAuthenticationEntryPoint({});\n const converter = opts?.converter ?? serverBearerTokenAuthenticationConverter({});\n const failureHandler = opts.failureHandler ?? serverAuthenticationEntryPointFailureHandler({entryPoint})\n if (opts.managerResolver!== undefined) {\n return authenticationFilter({\n storage: opts.storage,\n converter,\n failureHandler,\n managerResolver: opts.managerResolver,\n });\n }\n if (opts.jwt !== undefined) {\n\n const manager = opts.jwt.manager ?? jwtAuthManager(opts.jwt);\n return authenticationFilter({\n storage: opts.storage,\n converter,\n failureHandler,\n managerResolver: async (_exchange: ServerWebExchange) => {\n return manager;\n },\n });\n }\n throw new Error(\"Invalid resource server configuration: either managerResolver or jwt must be provided\");\n}\n", "import {\n type Authentication,\n type AuthenticationManager,\n AuthorizationDecision,\n DefaultAuthorizationManager,\n type ServerAuthenticationEntryPoint,\n type ServerAuthenticationSuccessHandler\n} from './types.ts';\nimport headers from './http-headers.ts';\nimport httpBasic from './http-basic.ts';\nimport resourceServer from './oauth2-resource-server.ts';\nimport serverBearerTokenAuthenticationConverter from './oauth2/token-converter.ts';\nimport bearerTokenServerAuthenticationEntryPoint from './oauth2/token-entry-point.ts';\nimport { BadJwtError, type Jwt, JwtError } from './oauth2/jwt-auth-manager.ts';\nimport { jwtVerifier, JwtVerifyError } from '@interopio/gateway/jose/jwt';\nimport {\n anyExchange,\n match,\n NO_MATCH,\n type ServerWebExchangeMatcher,\n type ServerWebExchangeMatcherEntry\n} from '../util/matchers.ts';\nimport { errorFilter } from './error-filter.ts';\nimport { delegatingEntryPoint } from './delegating-entry-point.ts';\nimport delegatingAuthorizationManager from './delegating-authorization-manager.ts';\nimport authorizationFilter from './authorization-filter.ts';\nimport { exchangeFilter } from './exchange-filter.ts';\nimport type { SecurityContext } from './security-context.ts';\nimport cors, { type CorsConfigSource } from '../cors.ts';\nimport type { Middleware } from '../types.ts';\nimport { type AsyncLocalStorage } from 'node:async_hooks';\nimport type { ServerWebExchange } from '../../../types/web/server';\nimport x509 from './x509.ts';\nimport { subjectX500PrincipalExtractor } from './preauth/x509.ts';\nimport { userDetailsServiceAuthenticationManager } from './users.ts';\nimport type { UserDetailsPasswordService, UserDetailsService } from './users/types.ts';\n\nexport type HttpSecurityConfig = {\n authorize?: Array<[\n 'any-exchange' | ServerWebExchangeMatcher,\n ( { access: 'permitted' | 'denied' | 'authenticated' }\n | { access: 'has-any-authority', authorities: string[] }\n | { access: 'has-ip-address', address: string })\n ]>,\n headers?: {\n disabled?: boolean\n xss?: { disabled?: boolean }\n },\n x509?: {\n disabled?: boolean\n /** Extract principal from Subject Alternative Name. Use 'email' to extract from email SAN. If undefined, uses subject (default). */\n principalAltName?: 'email'\n }\n cors?: {\n disabled?: boolean\n }\n basic?: {\n disabled?: boolean\n realm?: string\n },\n jwt?: {\n disabled?: boolean;\n issuerUri?: string; // base URI for the issuer, e.g. 'https://example.com'\n issuer?: string;\n audience?: string | string[]; // audience for the JWT, e.g. 'https://example.com/api'\n }\n}\n\nconst filterOrder = {\n first: Number.MAX_SAFE_INTEGER,\n http_headers: 1 * 100,\n https_redirect: 2 * 100,\n cors: 3 * 100,\n http_basic: 6 * 100,\n authentication: 8 * 100,\n security_context_server_web_exchange: 15 * 100,\n error_translation: 18 * 100,\n authorization: 19 * 100,\n last: Number.MAX_SAFE_INTEGER\n}\nconst filterOrderSymbol = Symbol.for(\"filterOrder\");\n\nexport default (config: HttpSecurityConfig,\n context: {\n storage: AsyncLocalStorage<{ securityContext?: Promise<SecurityContext> }>\n corsConfigSource?: CorsConfigSource,\n userDetailsService?: UserDetailsService,\n userDetailsPasswordService?: UserDetailsPasswordService,\n authenticationManager?: AuthenticationManager,\n }): Middleware => {\n\n const getService = <T>(name: string, defaultService?: T): T => {\n if (context === undefined) {\n return defaultService as T; // will not throw but return defaultService which may be undefined\n }\n if (name === 'UserDetailsService' && context.userDetailsService !== undefined) {\n return context.userDetailsService as T;\n }\n if (name === 'AuthenticationManager' && context.authenticationManager !== undefined) {\n return context.authenticationManager as T;\n }\n if (defaultService !== undefined) {\n return defaultService;\n }\n throw new Error(`No service registered with name: ${name}`);\n };\n\n const authenticationManager = (): AuthenticationManager | undefined => {\n if (context.authenticationManager !== undefined) {\n return context.authenticationManager;\n }\n if (context.userDetailsService !== undefined) {\n const manager = userDetailsServiceAuthenticationManager(context.userDetailsService, {\n userDetailsPasswordService: context.userDetailsPasswordService\n });\n return manager;\n }\n }\n\n\n const middleware: Middleware = [];\n\n class ServerHttpSecurity {\n #authenticationEntryPoint?: ServerAuthenticationEntryPoint;\n readonly #defaultEntryPoints: Array<[ServerWebExchangeMatcher, ServerAuthenticationEntryPoint]> = [];\n #authenticationManager?: AuthenticationManager;\n\n set authenticationManager(authenticationManager: AuthenticationManager | undefined) {\n this.#authenticationManager = authenticationManager;\n }\n\n get authenticationEntryPoint(): ServerAuthenticationEntryPoint | undefined {\n if (this.#authenticationEntryPoint !== undefined || this.#defaultEntryPoints.length === 0) {\n return this.#authenticationEntryPoint!;\n }\n if (this.#defaultEntryPoints.length === 1) {\n return this.#defaultEntryPoints[0][1];\n }\n return delegatingEntryPoint({\n entryPoints: this.#defaultEntryPoints,\n defaultEntryPoint: this.#defaultEntryPoints[this.#defaultEntryPoints.length - 1][1]\n });\n }\n\n\n build() {\n if (config.headers !== undefined && config.headers.disabled !== true) {\n const writer = headers(config.headers);\n writer[filterOrderSymbol] = filterOrder.http_headers;\n middleware.push(writer);\n }\n if (config.x509 !== undefined && config.x509.disabled !== true) {\n\n const filter = x509({\n storage: context.storage,\n getService,\n extractor: subjectX500PrincipalExtractor({ principalAltName: config.x509.principalAltName })\n });\n filter[filterOrderSymbol] = filterOrder.authentication;\n middleware.push(filter);\n }\n if (config.cors?.disabled !== true && context.corsConfigSource !== undefined) {\n const filter: (ctx: ServerWebExchange, next: () => Promise<void>) => Promise<void> = cors({corsConfigSource: context.corsConfigSource });\n filter[filterOrderSymbol] = filterOrder.cors;\n middleware.push(filter);\n }\n\n if (config.basic !== undefined && config.basic?.disabled !== true) {\n\n const defaultSuccessHandlers: ServerAuthenticationSuccessHandler[] = [\n async ({exchange: _, next}, _authentication) => {\n return next();\n }\n ];\n\n const filter = httpBasic({\n storage: context.storage,\n manager: this.#authenticationManager!,\n defaultEntryPoints: this.#defaultEntryPoints,\n defaultSuccessHandlers,\n });\n filter[filterOrderSymbol] = filterOrder.http_basic;\n middleware.push(filter);\n }\n if (config.jwt !== undefined && config.jwt.disabled !== true) {\n\n const verifier = jwtVerifier({\n issuerBaseUri: config.jwt.issuerUri,\n issuer: config.jwt.issuer,\n audience: config.jwt.audience\n });\n const decoder = async (token: string): Promise<Jwt> => {\n try {\n const {payload} = await verifier(token);\n return {\n tokenValue: token,\n subject: payload.sub,\n getClaimAsString(claim: string): string | undefined {\n return payload[claim] as string | undefined;\n }\n };\n } catch (e) {\n if (e instanceof JwtVerifyError) {\n throw new BadJwtError(e.message, {cause: e});\n }\n throw new JwtError(\"error occurred while attempting to decoding jwt\", {cause: e});\n }\n }\n\n\n const authenticationConverter = serverBearerTokenAuthenticationConverter({uriQueryParameter: true});\n const authenticationConverterMatcher: ServerWebExchangeMatcher = async (exchange) => {\n try {\n const a = await authenticationConverter(exchange)\n if (a === undefined) {\n return NO_MATCH;\n }\n return match();\n }\n catch (e) {\n return NO_MATCH;\n }\n }\n\n const entryPoint = bearerTokenServerAuthenticationEntryPoint({});\n\n this.#defaultEntryPoints.push([authenticationConverterMatcher, entryPoint]);\n\n const filter = resourceServer({\n storage: context.storage,\n entryPoint: entryPoint,\n converter: authenticationConverter,\n jwt: {decoder}});\n filter[filterOrderSymbol] = filterOrder.authentication;\n middleware.push(filter);\n\n }\n const exchangeF = exchangeFilter({storage: context.storage});\n middleware.push(exchangeF);\n exchangeF[filterOrderSymbol] = filterOrder.security_context_server_web_exchange;\n\n\n if (config.authorize !== undefined) {\n const errorFf = errorFilter({authenticationEntryPoint: this.authenticationEntryPoint});\n errorFf[filterOrderSymbol] = filterOrder.error_translation;\n middleware.push(errorFf)\n const buildAuthorizationManager = (authorize: HttpSecurityConfig['authorize']) => {\n const mappings: ServerWebExchangeMatcherEntry<DefaultAuthorizationManager<{\n exchange: ServerWebExchange\n }>>[] = [];\n let anyExchangeRegistered = false;\n for (const [matcher, access] of authorize ?? []) {\n let serverMatcher: ServerWebExchangeMatcher;\n if (matcher === 'any-exchange') {\n anyExchangeRegistered = true;\n serverMatcher = anyExchange;\n } else if (anyExchangeRegistered) {\n throw new Error(\"Cannot register other matchers after 'any-exchange' matcher\");\n } else {\n serverMatcher = matcher;\n }\n let manager: DefaultAuthorizationManager<{ exchange: ServerWebExchange }>;\n if (access.access === 'permitted') {\n manager = new DefaultAuthorizationManager(async () => new AuthorizationDecision(true));\n manager.toString = () => 'AuthorizationManager[permitted]';\n } else if (access.access === 'denied') {\n manager = new DefaultAuthorizationManager(async () => new AuthorizationDecision(false));\n manager.toString = () => 'AuthorizationManager[denied]';\n } else if (access.access === 'authenticated') {\n manager = new DefaultAuthorizationManager(async (p: Promise<Authentication | undefined>) => {\n const authentication = await p;\n if (authentication !== undefined) {\n return new AuthorizationDecision(authentication.authenticated);\n }\n return new AuthorizationDecision(false);\n });\n manager.toString = () => 'AuthorizationManager[authenticated]';\n } else {\n throw new Error(`Unknown access type: ${JSON.stringify(access)}`);\n }\n mappings.push([serverMatcher, manager]);\n }\n return delegatingAuthorizationManager({mappings});\n }\n const manager = buildAuthorizationManager(config.authorize);\n const filter = authorizationFilter({manager, storage: context.storage});\n filter[filterOrderSymbol] = filterOrder.authorization;\n middleware.push(filter);\n\n }\n\n middleware.sort((a, b) => {\n const aOrder = a[filterOrderSymbol] ?? filterOrder.last;\n const bOrder = b[filterOrderSymbol] ?? filterOrder.last;\n return aOrder - bOrder;\n });\n }\n }\n\n\n const security = new ServerHttpSecurity();\n security.authenticationManager = authenticationManager();\n security.build();\n\n\n return middleware;\n};\n", "import {\n type Authentication,\n AccessDeniedError,\n AuthenticationError,\n InsufficientAuthenticationError,\n type ServerAuthenticationEntryPoint,\n isAuthentication\n} from './types.ts';\nimport { httpBasicEntryPoint } from './http-basic-entry-point.ts';\nimport type { ServerWebExchange } from '../../../types/web/server';\nimport { HttpStatus } from '../../http/status.ts';\n\nasync function commenceAuthentication(exchange: ServerWebExchange, authentication: Authentication | undefined, entryPoint: ServerAuthenticationEntryPoint) {\n const cause = new InsufficientAuthenticationError(`Full authentication is required to access this resource.`);\n const e: AuthenticationError = new AuthenticationError(\"Access Denied\", {cause});\n if (authentication) {\n e.authentication = authentication;\n }\n await entryPoint(exchange, e);\n}\nexport function httpStatusAccessDeniedHandler(httpStatus: HttpStatus) {\n return async (exchange: ServerWebExchange, _error: AccessDeniedError) => {\n exchange.response.setStatusCode(httpStatus);\n exchange.response.headers.set(\"Content-Type\", \"text/plain; charset=utf-8\");\n const buffer = Buffer.from(\"Access Denied\", \"utf-8\");\n exchange.response.headers.set('Content-Length', buffer.length);\n await exchange.response.body(buffer);\n };\n}\n\nexport const errorFilter = (opts: {\n authenticationEntryPoint?: ServerAuthenticationEntryPoint\n}) => {\n const accessDeniedHandler = httpStatusAccessDeniedHandler(HttpStatus.FORBIDDEN);\n const authenticationEntryPoint = opts.authenticationEntryPoint ?? httpBasicEntryPoint();\n return async (exchange: ServerWebExchange, next: () => Promise<void>) => {\n try {\n await next();\n } catch (error) {\n if (error instanceof AccessDeniedError) {\n const principal = await exchange.principal();\n if (!isAuthentication(principal)) {\n await commenceAuthentication(exchange, undefined, authenticationEntryPoint);\n }\n else {\n if (!principal.authenticated) {\n await accessDeniedHandler(exchange, error);\n }\n await commenceAuthentication(exchange, principal, authenticationEntryPoint);\n }\n return;\n }\n throw error;\n }\n };\n}\n", "import type {ServerWebExchangeMatcherEntry} from '../util/matchers.ts';\nimport {type Authentication, AuthorizationDecision, type AuthorizationManager, DefaultAuthorizationManager} from './types.ts';\nimport getLogger from '../../logger.ts';\nimport type {ServerWebExchange} from '../../../types/web/server';\n\nconst logger = getLogger('security.auth');\n\nexport default function delegatingAuthorizationManager(opts: { mappings: Array<ServerWebExchangeMatcherEntry<AuthorizationManager<{ exchange: ServerWebExchange }>>> }) {\n const check = async (authentication: Promise<Authentication | undefined>, exchange: ServerWebExchange): Promise<AuthorizationDecision> => {\n let decision: AuthorizationDecision;\n for (const [matcher, manager] of opts.mappings) {\n if ((await matcher(exchange))?.match) {\n logger.debug(`checking authorization on '${exchange.request.path}' using [${matcher}, ${manager}]`);\n const checkResult = await manager.authorize(authentication, {exchange});\n if (checkResult !== undefined) {\n decision = checkResult;\n break;\n }\n }\n }\n decision ??= new AuthorizationDecision(false);\n return decision;\n\n }\n return new DefaultAuthorizationManager(check);\n}\n", "import { AccessDeniedError, type AuthorizationManager } from './types.ts';\nimport { AsyncStorageSecurityContextHolder, type SecurityContext } from './security-context.ts';\nimport type { AsyncLocalStorage } from 'node:async_hooks';\nimport type { ServerWebExchange } from '../../../types/web/server';\n\nimport getLogger from '../../logger.ts';\n\nconst logger = getLogger('security.auth');\n\nexport default function authorizationFilter(opts: {\n storage: AsyncLocalStorage<{ securityContext?: Promise<SecurityContext> }>,\n manager: AuthorizationManager<ServerWebExchange>\n}) {\n\n const { manager, storage } = opts;\n\n return async (exchange: ServerWebExchange, next: () => Promise<void>) => {\n const promise = AsyncStorageSecurityContextHolder.getContext(storage)\n .then(c => c?.authentication);\n try {\n await manager.verify(promise, exchange);\n if (logger.enabledFor('debug')) {\n logger.debug('authorization successful')\n }\n } catch (error) {\n if (error instanceof AccessDeniedError) {\n if (logger.enabledFor('debug')) {\n logger.debug(`authorization failed: ${error.message}`);\n }\n }\n throw error;\n }\n await next();\n };\n}\n", "import { AsyncStorageSecurityContextHolder, type SecurityContext } from './security-context.ts';\nimport { ServerWebExchangeDecorator } from '../exchange.ts';\nimport type { ServerWebExchange } from '../../../types/web/server';\nimport type { Principal } from '../../../types/auth';\nimport type { AsyncLocalStorage } from 'node:async_hooks';\n\n\nexport class SecurityContextServerWebExchange extends ServerWebExchangeDecorator {\n readonly #context: () => Promise<SecurityContext | undefined>;\n constructor(exchange: ServerWebExchange, context: () => Promise<SecurityContext | undefined>) {\n super(exchange);\n this.#context = context;\n }\n\n async principal<T extends Principal>(): Promise<T | undefined> {\n const context = await this.#context();\n return context?.authentication as (T | undefined);\n }\n}\n\nexport const exchangeFilter = (opts: {storage: AsyncLocalStorage<{ securityContext?: Promise<SecurityContext> }>}) => {\n const storage = opts.storage;\n return async (exchange: ServerWebExchange, next: (exchange: ServerWebExchange) => Promise<void>) => {\n await next(new SecurityContextServerWebExchange(exchange, async () => await AsyncStorageSecurityContextHolder.getContext(storage)));\n }\n}\n", "import type { AbstractAuthenticationToken, AuthenticationConverter } from './types.ts';\nimport type { X509PrincipalExtractor } from './preauth/x509.ts';\nimport type { ServerWebExchange } from '../../../types/web/server';\n\nexport const x509Converter = (opts: { principalExtractor: X509PrincipalExtractor }): AuthenticationConverter => {\n const { principalExtractor } = opts;\n return async (exchange: ServerWebExchange): Promise<AbstractAuthenticationToken | undefined> => {\n const sslInfo = exchange.request.sslInfo;\n if (sslInfo === undefined) {\n // no SslInfo provided with a request, skipping x509 authentication\n return;\n }\n if (sslInfo.peerCertificate === undefined) {\n // no peer certificate found in SslInfo, skipping x509 authentication\n return;\n }\n const clientCertificate = sslInfo.peerCertificate;\n const principal = principalExtractor(clientCertificate);\n return {\n type: 'PreAuthenticated',\n authenticated: false,\n principal,\n name: principal ?? '',\n credentials: clientCertificate\n };\n }\n}\n", "import type {X509Certificate} from 'node:crypto';\nimport { BadCredentialsError } from '../types.ts';\n\nexport type X509PrincipalExtractor = (cert: X509Certificate) => string;\n\n/**\n * Extracts principal from X.509 certificate.\n * By default, extracts from certificate subject.\n * If principalAltName is 'email', extracts from email in Subject Alternative Name.\n */\nexport const subjectX500PrincipalExtractor: (opts?: {\n principalAltName?: 'email'\n}) => X509PrincipalExtractor = (opts) => {\n const extractFromEmail = opts?.principalAltName === 'email';\n const subjectDnRegEx = /CN=(.*?)(?:,|$)/mi;\n return (cert: X509Certificate): string => {\n if (extractFromEmail) {\n const email = cert.subjectAltName?.split(', ').find((altName) => altName.startsWith('email:'));\n if (email) {\n return email.replace('email:', '');\n }\n }\n // Default: extract from subject\n const result = subjectDnRegEx.exec(cert.subject);\n if (result === null) {\n throw new BadCredentialsError(`Cannot extract principal from subject DN: ${cert.subject}`);\n }\n const username = result[1];\n return username;\n }\n}\n", "import type { PasswordEncoder } from './index.ts';\n\nexport abstract class AbstractPasswordEncoder implements PasswordEncoder {\n async encode(rawPassword?: string): Promise<string | undefined> {\n if (rawPassword === undefined || rawPassword === null) {\n return undefined\n }\n return await this.encodeDefinedPassword(rawPassword.toString());\n }\n\n abstract encodeDefinedPassword(rawPassword: string): Promise<string>;\n\n async matches(rawPassword?: string, encodedPassword?: string): Promise<boolean> {\n if (!rawPassword || !encodedPassword) {\n return false;\n }\n return await this.matchesDefined(rawPassword.toString(), encodedPassword);\n }\n\n abstract matchesDefined(rawPassword: string, encodedPassword: string): Promise<boolean>;\n\n\n upgradeEncoding(encodedPassword?: string): boolean {\n if (!encodedPassword) {\n return false;\n }\n return this.upgradeEncodingDefined(encodedPassword);\n }\n\n protected upgradeEncodingDefined(encodedPassword: string): boolean {\n return false;\n }\n\n}\n\nexport class DelegatingPasswordEncoder extends AbstractPasswordEncoder {\n static DEFAULT_ID_PREFIX = '{'; // {\n static DEFAULT_ID_SUFFIX = '}'; // }\n readonly #idPrefix: string;\n readonly #idSuffix: string;\n readonly #idForEncode: string;\n readonly #encoderForEncode: PasswordEncoder;\n readonly #encoders: Map<string, PasswordEncoder>\n\n #defaultEncoderForMatches: PasswordEncoder = new class extends AbstractPasswordEncoder {\n readonly #outer: DelegatingPasswordEncoder;\n constructor(outer: DelegatingPasswordEncoder) {\n super();\n this.#outer = outer;\n }\n async encodeDefinedPassword(rawPassword: string): Promise<string> {\n throw new Error('encode is not supported');\n }\n\n async matchesDefined(rawPassword: string, prefixEncodedPassword: string): Promise<boolean> {\n const id = this.#outer.#extractId(prefixEncodedPassword);\n if (!id) {\n throw new Error(`No password encoder mapped for id ${id}`);\n }\n if (prefixEncodedPassword) {\n const start = prefixEncodedPassword.indexOf(this.#outer.#idPrefix);\n const end = prefixEncodedPassword.indexOf(this.#outer.#idSuffix, start + this.#outer.#idPrefix.length);\n if (start === -1 && end === -1) {\n throw new Error(`No prefix found in encoded password`);\n }\n }\n throw new Error(`malformed password encoder prefix`);\n }\n }(this);\n\n constructor(idForEncode: string, encoders: Map<string, PasswordEncoder>, idPrefix:string = DelegatingPasswordEncoder.DEFAULT_ID_PREFIX, idSuffix: string = DelegatingPasswordEncoder.DEFAULT_ID_SUFFIX) {\n if (idForEncode === undefined || idForEncode === null) {\n throw new Error('idForEncode cannot be null or undefined');\n }\n if (idPrefix === undefined || idPrefix === null) {\n throw new Error(`idPrefix cannot be null or undefined`);\n }\n if (!idSuffix) {\n throw new Error(`idSuffix cannot be empty`);\n }\n if (idPrefix.indexOf(idSuffix) !== -1) {\n throw new Error(`idPrefix \"${idPrefix}\" cannot contain idSuffix \"${idSuffix}\"`);\n }\n if (!encoders.has(idForEncode)) {\n throw new Error(`No PasswordEncoder mapped for id \"${idForEncode}\"`);\n }\n for (const id of encoders.keys()) {\n if (id === null) {\n continue;\n }\n if (idPrefix && id.includes(idPrefix)) {\n throw new Error(`id \"${id}\" cannot include ${idPrefix}`);\n }\n if (idSuffix && id.includes(idSuffix)) {\n throw new Error(`id \"${id}\" cannot include ${idSuffix}`);\n }\n }\n super();\n this.#idForEncode = idForEncode;\n this.#encoderForEncode = encoders.get(idForEncode)!;\n this.#encoders = new Map(encoders);\n this.#idPrefix = idPrefix;\n this.#idSuffix = idSuffix;\n }\n\n set defaultPasswordEncoderForMatches(encoder: PasswordEncoder) {\n if (encoder === null || encoder === undefined) {\n throw new Error('defaultPasswordEncoderForMatches cannot be null or undefined');\n }\n this.#defaultEncoderForMatches = encoder;\n }\n\n async encodeDefinedPassword(rawPassword: string): Promise<string> {\n const encoded = await this.#encoderForEncode.encode(rawPassword);\n return `${this.#idPrefix}${this.#idForEncode}${this.#idSuffix}${encoded}`;\n }\n\n async matchesDefined(rawPassword: string, prefixEncodedPassword: string): Promise<boolean> {\n const id = this.#extractId(prefixEncodedPassword);\n const delegate = id ? this.#encoders.get(id) : undefined;\n if (delegate === undefined) {\n return await this.#defaultEncoderForMatches.matches(rawPassword, prefixEncodedPassword);\n }\n else {\n const encodedPassword = this.#extractEncodedPassword(prefixEncodedPassword);\n return await delegate.matches(rawPassword, encodedPassword);\n }\n }\n\n #extractId(encodedPassword?: string): string | undefined {\n if (encodedPassword === undefined) {\n return undefined;\n }\n const start = encodedPassword.indexOf(this.#idPrefix);\n if (start !== 0) {\n return undefined;\n }\n const end = encodedPassword.indexOf(this.#idSuffix, start + this.#idPrefix.length);\n if (end === -1) {\n return undefined;\n }\n return encodedPassword.substring(start + this.#idPrefix.length, end);\n }\n\n protected upgradeEncodingDefined(prefixEncodedPassword: string): boolean {\n const id = this.#extractId(prefixEncodedPassword);\n if (this.#idForEncode !== id) {\n // todo case-insensitive compare?\n return true;\n }\n else {\n const encodedPassword = this.#extractEncodedPassword(prefixEncodedPassword);\n return this.#encoderForEncode.upgradeEncoding?.(encodedPassword) ?? false;\n }\n }\n\n #extractEncodedPassword(prefixEncodedPassword: string) {\n const start = prefixEncodedPassword.indexOf(this.#idSuffix);\n return prefixEncodedPassword.substring(start + this.#idSuffix.length);\n }\n\n}\n\nexport class NoopPasswordEncoder extends AbstractPasswordEncoder {\n static readonly #INSTANCE = new NoopPasswordEncoder();\n\n static get instance(): NoopPasswordEncoder {\n return NoopPasswordEncoder.#INSTANCE;\n }\n\n private constructor() {\n super();\n }\n\n async encodeDefinedPassword(rawPassword: string): Promise<string> {\n return rawPassword.toString();\n }\n\n async matchesDefined(rawPassword: string, encodedPassword: string): Promise<boolean> {\n return rawPassword.toString() === encodedPassword;\n }\n}\n", "import { AbstractPasswordEncoder } from './password.ts';\nimport { argon2, keygen } from '@interopio/gateway-server/tools';\n\n/**\n * Constant-time buffer comparison to prevent timing attacks.\n *\n * @param a - First buffer\n * @param b - Second buffer\n * @returns true if buffers are equal, false otherwise\n */\nfunction bufferEquals(a: Buffer, b: Buffer): boolean {\n if (a.length !== b.length) {\n return false;\n }\n let diff = 0;\n for (let i = 0; i < a.length; i++) {\n diff |= a[i] ^ b[i];\n }\n return diff === 0;\n}\n\n\n\nexport class Argon2PasswordEncoder extends AbstractPasswordEncoder {\n readonly #saltLength: number;\n readonly #hashLength: number;\n readonly #parallelism: number;\n readonly #memory: number\n readonly #passes: number;\n\n constructor(\n saltLength: number = argon2.DEFAULT_SALT_LENGTH,\n hashLength: number = argon2.DEFAULT_HASH_LENGTH,\n parallelism: number = argon2.DEFAULT_PARALLELISM,\n memory: number = argon2.DEFAULT_MEMORY,\n passes: number = argon2.DEFAULT_PASSES\n ) {\n super();\n this.#saltLength = saltLength;\n this.#hashLength = hashLength;\n this.#parallelism = parallelism;\n this.#memory = memory;\n this.#passes = passes;\n }\n\n async matchesDefined(rawPassword: string, encodedPassword: string): Promise<boolean> {\n try {\n const decoded = argon2.decode(encodedPassword);\n const hash = await argon2.createHash(\n decoded.algorithm,\n rawPassword,\n decoded.hash.length,\n decoded.parameters\n );\n return bufferEquals(decoded.hash, hash);\n } catch {\n return false;\n }\n }\n\n async encodeDefinedPassword(rawPassword: string): Promise<string> {\n const nonce = keygen.createSalt(this.#saltLength);\n const parameters = {\n memory: this.#memory,\n passes: this.#passes,\n parallelism: this.#parallelism,\n nonce\n };\n const hash = await argon2.createHash(\n 'argon2id',\n rawPassword,\n this.#hashLength,\n parameters\n );\n return argon2.encode({\n algorithm: 'argon2id',\n version: argon2.ARGON2_VERSION,\n parameters,\n hash\n });\n }\n\n upgradeEncodingDefined(encodedPassword: string): boolean {\n const decoded = argon2.decode(encodedPassword);\n return decoded.version < argon2.ARGON2_VERSION || decoded.parameters.memory < this.#memory || decoded.parameters.passes < this.#passes;\n }\n}\n", "import { DelegatingPasswordEncoder, NoopPasswordEncoder } from './password.ts';\nimport { Argon2PasswordEncoder } from './argon2.ts';\n\nexport const MAX_PASSWORD_LENGTH = 4096;\n\nexport interface PasswordEncoder {\n encode(rawPassword?: string): Promise<string | undefined>;\n\n matches(rawPassword?: string, encodedPassword?: string): Promise<boolean>;\n\n upgradeEncoding?(encodedPassword?: string): boolean;\n}\n\nexport function createDelegatingPasswordEncoder(): PasswordEncoder {\n const idForEncode = 'argon2id';\n const encoders: Map<string, PasswordEncoder> = new Map<string, PasswordEncoder>([\n [idForEncode, new Argon2PasswordEncoder()], ['noop', NoopPasswordEncoder.instance]]);\n return new DelegatingPasswordEncoder(idForEncode, encoders, DelegatingPasswordEncoder.DEFAULT_ID_PREFIX, DelegatingPasswordEncoder.DEFAULT_ID_SUFFIX);\n}\n", "import { AuthenticationError, type GrantedAuthority, type CredentialsHolder } from '../types.ts';\n\nexport type UserDetails = {\n readonly username: string;\n readonly password?: string | null; // null means credentials have been erased\n readonly authorities: ReadonlyArray<GrantedAuthority>;\n\n readonly accountExpired?: boolean;\n // Indicates whether the user's account is locked. A locked account prevents authentication.\n readonly accountLocked?: boolean;\n // Indicates whether the user's credentials (password) has expired. Expired credentials prevent authentication.\n readonly credentialsExpired?: boolean;\n // Indicates whether the user is enabled or disabled. A disabled user cannot be authenticated.\n readonly disabled?: boolean;\n};\n\nexport type UserDetailsChecker = (user: UserDetails) => void;\n\nexport interface UserDetailsService {\n findByUsername(username: string): Promise<UserDetails | undefined>;\n}\n\nexport interface UserDetailsPasswordService {\n updatePassword(user: UserDetails, newPassword?: string): Promise<UserDetails>;\n}\n\nexport const NoopUserDetailsPasswordService: UserDetailsPasswordService = {\n async updatePassword(user: UserDetails, _newPassword?: string): Promise<UserDetails> {\n return user;\n }\n}\n\nexport class UsernameNotFoundError extends AuthenticationError {\n readonly username?: string;\n\n constructor(message: string, username?: string, options?: ErrorOptions) {\n super(message, options);\n this.username = username;\n }\n}\n\nexport type User = UserDetails & CredentialsHolder & { toString(): string };\n\nexport class UserBuilder {\n #username!: string;\n #password?: string | null;\n #authorities: ReadonlyArray<GrantedAuthority> = [];\n #accountExpired?: boolean;\n #accountLocked?: boolean;\n #credentialsExpired?: boolean;\n #disabled?: boolean;\n\n #passwordEncoder: (rawPassword?: string | null) => string | undefined | null = (rawPassword) => rawPassword;\n\n private constructor() {\n }\n\n static ofUsername(username: string): UserBuilder {\n return new UserBuilder().username(username);\n }\n\n static ofUserDetails(user: UserDetails): UserBuilder {\n const builder = UserBuilder.ofUsername(user.username)\n .accountExpired(user.accountExpired ?? false)\n .accountLocked(user.accountLocked ?? false)\n .authorities(user.authorities)\n .credentialsExpired(user.credentialsExpired ?? false)\n .disabled(user.disabled ?? false);\n if (user.password !== undefined) {\n builder.password(user.password);\n }\n return builder;\n }\n\n username(username: string): this {\n if (!username) {\n throw new TypeError('username cannot be empty');\n }\n this.#username = username;\n return this;\n }\n\n password(password?: string | null): this {\n this.#password = password;\n return this;\n }\n\n passwordEncoder(encoder: (rawPassword?: string | null) => string | null | undefined): this {\n if (!encoder) {\n throw new TypeError('password encoder cannot be null or undefined');\n }\n this.#passwordEncoder = encoder;\n return this;\n }\n\n roles(...roles: string[]): this {\n return this.authorities(roles.map(role => {\n if (role.startsWith('role:')) {\n throw new Error(`${role} must not start with 'role:' (it is automatically added)`);\n }\n const authority = `role:${role}`;\n return { authority };\n }));\n }\n\n authorities(authorities: ReadonlyArray<GrantedAuthority>): this {\n this.#authorities = [...authorities];\n return this;\n }\n\n accountExpired(accountExpired: boolean): this {\n this.#accountExpired = accountExpired;\n return this;\n }\n\n accountLocked(accountLocked: boolean): this {\n this.#accountLocked = accountLocked;\n return this;\n }\n\n credentialsExpired(credentialsExpired: boolean): this {\n this.#credentialsExpired = credentialsExpired;\n return this;\n }\n\n disabled(disabled: boolean): this {\n this.#disabled = disabled;\n return this;\n }\n\n build(): User {\n if (!this.#username) {\n throw new TypeError('username is required');\n }\n let encodedPassword: string | null | undefined = this.#password !== undefined ? this.#passwordEncoder(this.#password) : undefined;\n return {\n username: this.#username,\n password: encodedPassword,\n authorities: this.#authorities,\n accountExpired: this.#accountExpired,\n accountLocked: this.#accountLocked,\n credentialsExpired: this.#credentialsExpired,\n disabled: this.#disabled,\n eraseCredentials(): void {\n encodedPassword = null;\n },\n toString(): string {\n return `User(username=${this.username}, password=[PROTECTED], authorities=${JSON.stringify(this.authorities)}, accountExpired=${this.accountExpired}, accountLocked=${this.accountLocked}, credentialsExpired=${this.credentialsExpired}, disabled=${this.disabled})`;\n }\n }\n }\n}\n", "import {\n type AbstractAuthenticationToken,\n AccountExpiredError,\n type AuthenticatedPrincipal,\n type Authentication,\n type AuthenticationManager,\n BadCredentialsError,\n CredentialsExpiredError,\n DisabledError,\n LockedError\n} from './types.ts';\nimport { createDelegatingPasswordEncoder, type PasswordEncoder } from './crypto/index.ts';\nimport getLogger from '../../logger.ts';\nimport {\n NoopUserDetailsPasswordService,\n type UserDetails,\n type UserDetailsChecker,\n type UserDetailsPasswordService,\n type UserDetailsService,\n UsernameNotFoundError\n} from './users/types.ts';\n\nconst logger = getLogger('security.users');\n\nexport function userDetailsServiceAuthenticationManager(\n userDetailsService: UserDetailsService,\n options?: {\n preAuthenticationChecks?: UserDetailsChecker;\n postAuthenticationChecks?: UserDetailsChecker;\n passwordEncoder?: PasswordEncoder;\n userDetailsPasswordService?: UserDetailsPasswordService;\n }\n): AuthenticationManager {\n const preAuthenticationChecks = options?.preAuthenticationChecks ?? ((user: UserDetails) => {\n if (user.accountLocked) {\n logger.debug(`user account is locked`);\n throw new LockedError(`User account is locked`);\n }\n if (user.disabled) {\n logger.debug(`user account is disabled`);\n throw new DisabledError(`User is disabled`);\n }\n if (user.accountExpired) {\n logger.debug(`user account is expired`);\n throw new AccountExpiredError(`User account has expired`);\n }\n });\n const postAuthenticationChecks = options?.postAuthenticationChecks ?? ((user: UserDetails) => {\n if (user.credentialsExpired) {\n logger.debug(`user credentials have expired`);\n throw new CredentialsExpiredError(`User credentials have expired`);\n }\n });\n const passwordEncoder = options?.passwordEncoder ?? createDelegatingPasswordEncoder();\n\n const userDetailsPasswordService: UserDetailsPasswordService = options?.userDetailsPasswordService ?? NoopUserDetailsPasswordService;\n\n const upgradeEncodingIfNeeded = async (userDetails: UserDetails, presentedPassword?: string) => {\n const existingEncodedPassword = userDetails.password;\n const upgradeEncoding = existingEncodedPassword !== undefined\n && passwordEncoder.upgradeEncoding?.(existingEncodedPassword!);\n if (upgradeEncoding) {\n const newEncodedPassword = await passwordEncoder.encode(presentedPassword);\n return await userDetailsPasswordService.updatePassword(userDetails, newEncodedPassword);\n }\n return userDetails;\n }\n\n return async (authentication: Authentication): Promise<AbstractAuthenticationToken> => {\n\n const username = authentication.name!;\n const presentedPassword = (authentication.credentials !== undefined && authentication.credentials !== null) ? authentication.credentials.toString() : undefined;\n // retrieve user\n const user = await userDetailsService.findByUsername(username);\n\n if (!user) {\n throw new Error(`User not found: ${username}`);\n }\n\n preAuthenticationChecks(user);\n if (!(await passwordEncoder.matches(presentedPassword, user.password!))) {\n throw new BadCredentialsError('Invalid Credentials');\n }\n const principal = await upgradeEncodingIfNeeded(user, presentedPassword);\n\n postAuthenticationChecks(principal);\n let credentials = principal.password;\n return {\n type: 'UsernamePassword',\n principal: principal,\n credentials: credentials,\n authorities: principal.authorities,\n authenticated: true,\n name: principal.username,\n eraseCredentials() {\n credentials = null;\n }\n };\n };\n}\n\nexport function accountStatusUserDetailsChecker(): UserDetailsChecker {\n return (user: UserDetails) => {\n if (user.accountLocked) {\n logger.debug(`failed to authenticate since user account is locked`);\n throw new LockedError(`User account is locked`);\n }\n if (user.disabled) {\n logger.debug(`failed to authenticate user account is disabled`);\n throw new DisabledError(`User is disabled`);\n }\n if (user.accountExpired) {\n logger.debug(`failed to authenticate since user account is expired`);\n throw new AccountExpiredError(`User account has expired`);\n }\n if (user.credentialsExpired) {\n logger.debug(`failed to authenticate since user credentials have expired`);\n throw new CredentialsExpiredError(`User credentials have expired`);\n }\n }\n}\n\nexport function preAuthenticatedAuthenticationManager(opts: {\n userDetailsService: UserDetailsService,\n userDetailsChecker?: UserDetailsChecker\n}): AuthenticationManager {\n const userDetailsService = opts.userDetailsService;\n const userDetailsChecker = opts.userDetailsChecker ?? accountStatusUserDetailsChecker();\n\n const supports = (authentication: Authentication): authentication is AbstractAuthenticationToken & AuthenticatedPrincipal => {\n return (authentication.type === 'PreAuthenticated' && authentication.name !== undefined);\n }\n\n return async (authentication: Authentication): Promise<AbstractAuthenticationToken> => {\n const userDetails = supports(authentication) && await userDetailsService.findByUsername(authentication.name);\n if (!userDetails) {\n throw new UsernameNotFoundError(`user not found`, authentication.name);\n }\n userDetailsChecker(userDetails);\n let erasableCredentials = authentication.credentials;\n const result: AbstractAuthenticationToken = {\n type: 'PreAuthenticated',\n principal: userDetails,\n credentials: erasableCredentials,\n authorities: userDetails.authorities,\n authenticated: true,\n details: userDetails,\n name: userDetails.username,\n eraseCredentials() {\n erasableCredentials = null;\n }\n };\n return result;\n };\n}\n", "import authenticationFilter from './authentication-filter.ts';\nimport type { AsyncLocalStorage } from 'node:async_hooks';\nimport { x509Converter } from './x509-converter.ts';\nimport { subjectX500PrincipalExtractor, type X509PrincipalExtractor } from './preauth/x509.ts';\nimport type { AuthenticationConverter, AuthenticationManager } from './types.ts';\nimport { preAuthenticatedAuthenticationManager } from './users.ts';\n\n\nexport default function x509(opts: {\n readonly storage: AsyncLocalStorage< {} >,\n readonly manager?: AuthenticationManager,\n readonly extractor?: X509PrincipalExtractor,\n readonly converter?: AuthenticationConverter,\n getService: <T>(type: string) => T\n}) {\n const manager = opts.manager ?? preAuthenticatedAuthenticationManager({\n userDetailsService: opts.getService('UserDetailsService')\n });\n const principalExtractor = opts.extractor ?? subjectX500PrincipalExtractor();\n const converter = opts.converter ?? x509Converter({ principalExtractor })\n return authenticationFilter({\n storage: opts.storage,\n manager,\n converter\n })\n}\n", "import type { UserDetails, UserDetailsPasswordService, UserDetailsService } from './types.ts';\n\nexport class MapUserDetailsService implements UserDetailsService, UserDetailsPasswordService {\n readonly #users = new Map<string, UserDetails>();\n\n constructor(...users: UserDetails[]) {\n for (const user of users) {\n this.#users.set(this.#getKey(user.username), user);\n }\n }\n\n async findByUsername(username: string): Promise<UserDetails | undefined> {\n const key = this.#getKey(username);\n const result = this.#users.get(key);\n return result !== undefined ? { ...(result) } : undefined;\n }\n\n async updatePassword(user: UserDetails, newPassword?: string): Promise<UserDetails> {\n const userDetails = { ...(user), password: newPassword };\n // what if user does not exist?\n if (userDetails) {\n const key = this.#getKey(user.username);\n this.#users.set(key, userDetails);\n }\n return userDetails;\n }\n\n #getKey(username: string) {\n return username.toLowerCase();\n }\n}\n", "import { createCorsConfigSource } from './cors.ts';\nimport type { RouteConfig } from './route.ts';\nimport security, { type HttpSecurityConfig } from '../server/security/config.ts';\nimport { and, pattern, type ServerWebExchangeMatcher, upgradeMatcher } from '../server/util/matchers.ts';\nimport type { CorsConfigSource } from '../server/cors.ts';\nimport type { Middleware } from '../server/types.ts';\nimport type { AuthorizationRule } from '../../types/auth';\nimport { MapUserDetailsService } from '../server/security/users/memory.ts';\nimport { UserBuilder, type UserDetails } from '../server/security/users/types.ts';\nimport { randomUUID } from 'node:crypto';\nimport { MAX_PASSWORD_LENGTH, type PasswordEncoder } from '../server/security/crypto/index.ts';\nimport getLogger from '../logger.ts';\n\nconst logger = getLogger('auth');\n\nexport function createSecurityConfig(context: RouteConfig): HttpSecurityConfig {\n const authorize: HttpSecurityConfig['authorize'] = [];\n const type = context.authConfig?.type;\n const defaultAccess: AuthorizationRule = { access: type !== 'none' ? 'authenticated' : 'permitted' };\n if (logger.enabledFor('info')) {\n logger.info(`using auth type: ${type ?? 'none'}, default access: ${defaultAccess.access}`);\n }\n for (const [path, route] of context.sockets) {\n const rule = route.authorize ?? defaultAccess;\n let matcher: ServerWebExchangeMatcher = pattern(path, { method: 'GET' });\n matcher = and([upgradeMatcher, matcher]);\n authorize.push([matcher, rule]);\n }\n authorize.push([pattern('/', { method: 'GET' }), { access: 'permitted' }]);\n authorize.push([pattern('/favicon.ico', {method: 'GET'}), { access: 'permitted' }]);\n authorize.push([pattern('/health', {method: 'GET'}), { access: 'permitted' }]);\n if (context.authorize.length > 0) {\n authorize.push(...context.authorize);\n }\n\n authorize.push(['any-exchange', defaultAccess]); // default rule for all other exchanges\n return {\n authorize,\n cors: {\n disabled: context.corsConfig === false,\n },\n x509: {\n disabled: type !== 'x509',\n ...context.authConfig?.x509,\n },\n basic: {\n disabled: type !== 'basic',\n ...context.authConfig?.basic,\n },\n jwt: {\n disabled: type !== 'oauth2',\n ...context.authConfig?.oauth2?.jwt\n }\n }\n}\n\nexport function createUserDetailsService(context: RouteConfig) {\n // if (context.userDetailsService) {\n // return context.userDetailsService;\n // }\n if (context.authConfig?.type === 'none') {\n return undefined;\n }\n\n function getOrDeducePassword(user: { password?: string }, encoder?: PasswordEncoder): string | null {\n if (context.authConfig?.type === 'x509') {\n return null;\n }\n let password = user.password;\n if (password === undefined) {\n // generate password\n const generatedPassword = randomUUID().replaceAll('-', '');\n if (logger.enabledFor('info')) {\n logger.info(`\\n\\n using generated password: ${generatedPassword}\\n\\nThis generated password is for development only. Your authentication configuration should be updated before running in production.\\n`);\n }\n password = generatedPassword;\n }\n if (password.length > MAX_PASSWORD_LENGTH) {\n throw new Error(`Password length exceeds maximum length of ${MAX_PASSWORD_LENGTH} characters`);\n }\n if ((encoder !== undefined && encoder !== null) || /^\\{.+}.*$/.test(password)) {\n return password;\n }\n return `{noop}${password}`;\n }\n\n const user = { name : 'dev-user', roles: [], ...(context.authConfig?.user) };\n const password = getOrDeducePassword(user);\n const roles = user.roles;\n const userDetails: UserDetails = UserBuilder.ofUsername(user.name).password(password).roles(...(roles)).build();\n return new MapUserDetailsService(userDetails);\n}\n\nexport async function httpSecurity(context: RouteConfig): Promise<Middleware> {\n const corsConfigSource: CorsConfigSource = createCorsConfigSource(context);\n const config = createSecurityConfig(context);\n const userDetailsService = createUserDetailsService(context);\n const { storage } = context;\n return security(config, {\n storage,\n corsConfigSource,\n userDetailsService,\n userDetailsPasswordService: userDetailsService\n });\n}\n", "import type { HttpHandler, Middleware, WebHandler } from './types';\nimport { DefaultWebExchange, ServerHttpResponseDecorator } from './exchange.ts';\nimport { AsyncLocalStorage } from 'node:async_hooks';\nimport type { Logger } from '@interopio/gateway/logging/api';\nimport type { HttpHeaders } from '../../types/web/http';\nimport type {\n ServerHttpRequest,\n ServerHttpResponse,\n ServerWebExchange\n} from '../../types/web/server';\nimport getLogger from '../logger.ts';\nimport { HttpStatus } from '../http/status.ts';\n\nexport class HttpHeadResponseDecorator extends ServerHttpResponseDecorator {\n\n}\n\nfunction checkAndLogClientDisconnectedError(error: Error, logger: Logger): boolean {\n if (error === null || error === undefined) {\n return false;\n }\n const { code, message } = error as any;\n const isClientDisconnected =\n code === 'ECONNRESET' ||\n code === 'EPIPE' ||\n code === 'ERR_STREAM_PREMATURE_CLOSE' ||\n message?.toLowerCase().includes('client aborted') ||\n message?.toLowerCase().includes('socket hang up') ||\n message?.toLowerCase().includes('aborted');\n if (isClientDisconnected) {\n if (logger.enabledFor('trace')) {\n logger.trace('looks like the client has gone away:', error);\n }\n else if (logger.enabledFor('debug')) {\n logger.debug(`looks like the client has gone away: ${error.message} (For full stack trace enable trace logging level.)`);\n }\n return true;\n }\n return false;\n}\n\nclass HandlerAdapter {\n\n readonly #logger: Logger\n #enableLoggingRequestDetails: boolean = false;\n readonly #delegate: WebHandler;\n #storage?: AsyncLocalStorage<{ exchange: ServerWebExchange }>;\n\n constructor(logger: Logger, delegate: WebHandler) {\n this.#logger = logger;\n this.#delegate = delegate;\n }\n\n protected createExchange(request: ServerHttpRequest, response: ServerHttpResponse): ServerWebExchange {\n\n const exchange = new DefaultWebExchange(request, response);\n return exchange;\n }\n\n set storage(storage: AsyncLocalStorage<{ exchange: ServerWebExchange }>) {\n this.#storage = storage;\n }\n\n set enableLoggingRequestDetails(value: boolean) {\n this.#enableLoggingRequestDetails = value;\n }\n\n formatHeaders(headers: HttpHeaders): string {\n let result = '{';\n\n for (const key of headers.keys()) {\n if (!this.#enableLoggingRequestDetails) {\n result += 'masked, ';\n break;\n } else {\n const value = headers.get(key);\n result += `\"${key}\": \"${value}\", `;\n }\n }\n if (result.endsWith(', ')) {\n result = result.slice(0, -2);\n }\n result += '}';\n return result;\n\n }\n\n formatRequest(request: ServerHttpRequest): string {\n const query = request.URL.search;\n return `HTTP ${request.method} \"${request.path}${query}`;\n }\n\n logRequest(exchange: ServerWebExchange) {\n if (this.#logger.enabledFor('debug')) {\n const trace = this.#logger.enabledFor('trace');\n this.#logger.debug(`${exchange.logPrefix}${this.formatRequest(exchange.request)}${trace ? `, headers: ${this.formatHeaders(exchange.request.headers)}` : ''}\"`);\n\n }\n }\n\n logResponse(exchange: ServerWebExchange) {\n if (this.#logger.enabledFor('debug')) {\n const trace = this.#logger.enabledFor('trace');\n const status = exchange.response.statusCode;\n this.#logger.debug(`${exchange.logPrefix}Completed ${status ?? '200 OK'}${trace ? `, headers: ${this.formatHeaders(exchange.response.headers)}` : ''}\"`);\n }\n }\n\n handleUnresolvedError(exchange: ServerWebExchange, error: Error) {\n const {request, response, logPrefix} = exchange;\n\n if (response.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR)) {\n this.#logger.error(`${logPrefix}500 Server Error for ${this.formatRequest(request)}`, error);\n return;\n }\n if (checkAndLogClientDisconnectedError(error, this.#logger)) {\n // todo notify observers\n return;\n }\n\n this.#logger.error(`${logPrefix}Error [${error.message} for ${this.formatRequest(request)}, but already ended (${response.statusCode})`, error);\n throw error;\n\n }\n\n async web(exchange: ServerWebExchange): Promise<void> {\n return await this.#delegate(exchange);\n }\n\n async http(request: ServerHttpRequest, response: ServerHttpResponse): Promise<void> {\n\n const exchange = this.createExchange(request, response);\n const callback = () => {\n this.logRequest(exchange);\n return this.web(exchange)\n .then(() => {\n this.logResponse(exchange);\n })\n .catch((error: Error) => {\n this.handleUnresolvedError(exchange, error)\n })\n .then(async () => {\n await exchange.response.end();\n });\n };\n\n await new Promise<void>((resolve, reject) => {\n if (this.#storage !== undefined) {\n this.#storage.run({exchange}, () => {\n callback().then(() => resolve()).catch((error) => reject(error));\n });\n } else {\n callback().then(() => resolve()).catch((error) => reject(error));\n }\n });\n }\n}\n\nexport class WebHttpHandlerBuilder {\n readonly #webHandler: WebHandler;\n readonly #middleware: Middleware = [];\n #storage?: AsyncLocalStorage<{ exchange: ServerWebExchange }> = new AsyncLocalStorage();\n #handlerDecorator?: (handler: HttpHandler) => HttpHandler;\n\n constructor(webHandler: WebHandler) {\n this.#webHandler = webHandler;\n }\n\n middleware(consumer: (middleware: Middleware) => void): this {\n consumer(this.#middleware);\n return this;\n }\n\n storage(storage: AsyncLocalStorage<{ exchange: ServerWebExchange }>): this {\n this.#storage = storage;\n return this;\n }\n\n httpHandlerDecorator(decorator: (handler: HttpHandler) => HttpHandler): this {\n if (this.#handlerDecorator === undefined) {\n this.#handlerDecorator = decorator;\n }\n else {\n const previousDecorator = this.#handlerDecorator;\n this.#handlerDecorator = (handler: HttpHandler) => {\n handler = decorator(handler);\n handler = previousDecorator(handler);\n return handler;\n }\n }\n return this;\n }\n\n hasHttpHandlerDecorator(): boolean {\n return this.#handlerDecorator !== undefined;\n }\n\n build(): HttpHandler {\n const logger = getLogger('http');\n\n const adapter = new HandlerAdapter(logger, this.#webHandler);\n if (this.#storage !== undefined) adapter.storage = this.#storage;\n adapter.enableLoggingRequestDetails = false;\n const adapted: HttpHandler = async (request, response) => adapter.http(request, response);\n\n\n return this.#handlerDecorator ? this.#handlerDecorator(adapted) : adapted;\n }\n}\n", "import type { AsyncLocalStorage } from \"node:async_hooks\";\nimport { WebSocketServer } from 'ws';\nimport type { ServerHttpResponse, ServerWebExchange } from '../../types/web/server';\nimport { HttpStatus } from '../http/status.ts';\nimport getLogger, { regexAwareReplacer } from '../logger.ts';\nimport {\n ExtendedHttpIncomingMessage,\n ExtendedHttpServerResponse,\n ServerHttpRequestDecorator,\n ServerHttpResponseDecorator\n} from './exchange.ts';\nimport { createHandshakeInfo, type SocketRoute } from './socket.ts';\nimport { acceptsOrigin } from './ws-client-verify.ts';\nimport { ExtendedWebSocket, PingManager } from './ws-pings.ts';\n\nconst logger = getLogger('ws');\n\nfunction upgradeStrategy(path: string, route: SocketRoute, wss: WebSocketServer, onSocketError: (err: Error) => void) {\n return (exchange: ServerWebExchange) => {\n\n const { logPrefix, request } = exchange;\n const req = ServerHttpRequestDecorator.getNativeRequest<ExtendedHttpIncomingMessage>(request);\n req.exchange = exchange;\n const { socket, upgradeHead } = req;\n\n const host = request.host;\n socket.removeListener('error', onSocketError);\n if (route.maxConnections !== undefined && wss.clients?.size >= route.maxConnections) {\n logger.warn(`${logPrefix}dropping ws connection request on ${host}${path}. max connections exceeded.`);\n socket.destroy();\n return;\n }\n\n const origin = request.headers.one('origin');\n if (!acceptsOrigin(origin, route.originFilters)) {\n if (logger.enabledFor('info')) {\n logger.info(`${logPrefix}dropping ws connection request on ${host}${path}. origin ${origin ?? '<missing>'}`);\n }\n socket.destroy();\n return;\n }\n if (logger.enabledFor('debug')) {\n logger.debug(`${logPrefix}accepted new ws connection request on ${host}${path}`);\n }\n\n wss.handleUpgrade(req, socket, upgradeHead!, (client, req) => {\n wss.emit('connection', client, req);\n });\n }\n}\n\nfunction applyHandshakeHeaders(headers: string[], response: ServerHttpResponse) {\n const seen = new Set<string>(); // track headers we've taken care of\n headers.forEach((header, index) => {\n if (index === 0 && header.startsWith('HTTP/1.1 101 ')) {\n response.setStatusCode(HttpStatus.SWITCHING_PROTOCOLS);\n return;\n }\n const [name, value] = header.split(': ');\n if (response.headers.has(name)) {\n headers[index] = `${name}: ${response.headers.one(name)}`;\n }\n else {\n response.headers.set(name, value);\n }\n seen.add(name.toLowerCase());\n });\n const nativeResponse = ServerHttpResponseDecorator.getNativeResponse<ExtendedHttpServerResponse>(response);\n for (const name of nativeResponse.getRawHeaderNames()) {\n // if we have already set this header, skip it\n const nameLowerCase = name.toLowerCase();\n if (!seen.has(nameLowerCase)) {\n const value = response.headers.get(nameLowerCase);\n if (value !== undefined) {\n headers.push(`${name}: ${value}`);\n }\n }\n }\n nativeResponse.markHeadersSent();\n}\n\nexport async function initRoute(path: string,\n route: SocketRoute,\n endpoint: string,\n storage: AsyncLocalStorage<{ securityContext? }>,\n onSocketError: (err: Error) => void): Promise<void> {\n try {\n logger.info(`creating ws server for [${path}]. max connections: ${route.maxConnections ?? '<unlimited>'}, origin filters: ${route.originFilters ? JSON.stringify(route.originFilters, regexAwareReplacer) : '<none>'}, ping: ${typeof route.ping === 'number' ? route.ping + 'ms' : route.ping ? JSON.stringify(route.ping) : '<none>'}`);\n const wss = new WebSocketServer<typeof ExtendedWebSocket, typeof ExtendedHttpIncomingMessage>({\n noServer: true,\n WebSocket: ExtendedWebSocket,\n autoPong: false\n });\n\n const pings = new PingManager(logger.child('pings'), () => [path, wss.clients], route.ping);\n\n const handler = await route.factory({ endpoint, storage });\n wss\n .on('error', (err: Error) => {\n logger.error(`error starting the ws server for [${path}]`, err);\n })\n .on('listening', () => {\n logger.info(`ws server for [${path}] is listening`);\n })\n .on('headers', (headers, request) => {\n if (request.exchange !== undefined) {\n const { response } = request.exchange;\n applyHandshakeHeaders(headers, response);\n }\n })\n .on('connection', (socket, request) => {\n\n const handshake = createHandshakeInfo(request, socket.protocol);\n\n socket.on('pong', (data) => {\n pings.handlePong(handshake, socket, data);\n });\n socket.on('ping', (data: Buffer) => {\n pings.handlePing(handshake, socket, data);\n });\n handler({ socket, handshake });\n });\n wss.on('close', () => {\n pings.close();\n });\n\n route.upgradeStrategy = upgradeStrategy(path, route, wss, onSocketError);\n route.close = async () => {\n await handler.close?.call(handler);\n logger.info(`stopping ws server for [${path}]. clients: ${wss.clients?.size ?? 0}`);\n wss.clients?.forEach(client => {\n client.terminate();\n });\n wss.close();\n }\n }\n catch (e) {\n logger.warn(`failed to init route ${path}`, e);\n }\n\n}\n", "import { type ExtendedHttpIncomingMessage, HttpServerRequest } from './exchange.ts';\nimport { MapHttpHeaders } from '../http/exchange.ts';\nimport type { AuthorizationRule, Principal } from '../../types/auth';\nimport type { WebSocketHandshakeInfo } from '../../types/web/socket';\nimport type { Middleware } from './types.ts';\nimport type { ServerWebExchange, ServerWebSocketHandler } from '../../types/web/server';\nimport { upgradeMatcher } from './util/matchers.ts';\nimport type { ProcessedOriginFilters } from './ws-client-verify.ts';\nimport { HttpStatus } from '../http/status.ts';\nimport type { AsyncLocalStorage } from 'node:async_hooks';\n\nexport function createHandshakeInfo(req: ExtendedHttpIncomingMessage, protocol?: string): WebSocketHandshakeInfo {\n const exchange = req?.exchange;\n const request = exchange?.request ?? new HttpServerRequest(req);\n const principalPromiseProvider = exchange?.principal;\n const principal = principalPromiseProvider ? principalPromiseProvider.bind(exchange) : async function principal<P extends Principal> (): Promise<P | undefined> { return undefined; };\n const url = request.URL;\n const headers = new MapHttpHeaders();\n for (const key of request.headers.keys()) {\n headers.set(key, request.headers.list(key));\n }\n const cookies = request.cookies;\n const logPrefix = exchange?.logPrefix ?? `[${request.id}] `;\n const remoteAddress = request.remoteAddress;\n const handshake: WebSocketHandshakeInfo = {\n url,\n headers,\n cookies,\n principal,\n protocol,\n remoteAddress,\n logPrefix,\n };\n return handshake;\n}\n\nexport function webSockets(context: { sockets: Map<string, SocketRoute> }): Middleware {\n // websocket upgrade handler\n const sockets = async (exchange: ServerWebExchange, next: () => Promise<void>) => {\n const request = exchange.request;\n const path = request.path ?? '/';\n\n const routes = context.sockets;\n const route = (routes.get(path) ?? Array.from(routes.values()).find(route => {\n if (path === '/' && route.default === true) {\n return true;\n }\n }));\n\n if (route !== undefined) {\n const {request, response} = exchange;\n const upgradeMatchResult = await upgradeMatcher(exchange);\n if ((request.method === 'GET' || request.method === 'CONNECT') && upgradeMatchResult.match) {\n if (route.upgradeStrategy !== undefined) {\n route.upgradeStrategy(exchange);\n return;\n }\n else {\n throw new Error(`No upgrade strategy defined for route on ${path}`);\n }\n }\n else {\n if (route.default) {\n // allow default route to pass through\n await next();\n return;\n }\n\n response.setStatusCode(HttpStatus.UPGRADE_REQUIRED);\n response.headers\n .set('Upgrade', 'websocket')\n .set('Connection', 'Upgrade')\n .set('Content-Type', 'text/plain');\n\n const buffer = Buffer.from(`This service [${request.path}] requires use of the websocket protocol.`, 'utf-8');\n await response.body(buffer);\n }\n } else {\n await next();\n }\n };\n return [sockets];\n}\n\nexport type SocketRoute = {\n readonly default?: boolean,\n readonly ping?: number | { interval: number, data?: 'timestamp' | 'empty' },\n readonly maxConnections?: number\n readonly authorize?: AuthorizationRule,\n readonly originFilters?: ProcessedOriginFilters\n readonly factory: (server: { endpoint: string, storage?: AsyncLocalStorage<{ exchange?, securityContext? }> }) => Promise<ServerWebSocketHandler>,\n // set later in listening\n upgradeStrategy?: (exchange: ServerWebExchange) => void,\n close?: () => Promise<void>\n}\n", "import { addressAndPort } from './address.ts';\nimport type { Logger } from '../logger.ts';\nimport { WebSocket } from 'ws';\nimport type { WebSocketHandshakeInfo } from '../../types/web/socket';\n\nexport class ExtendedWebSocket extends WebSocket {\n constructor(_first: unknown, _second?: unknown, options?: unknown) {\n /* eslint-disable @typescript-eslint/no-explicit-any */\n super(null as unknown as any, undefined, options as any);\n }\n\n connected?: boolean;\n}\n\nexport type PingConfig = { interval: number, data?: 'timestamp' | 'empty' };\n\nexport class PingManager {\n static readonly #EMPTY_BUFFER = Buffer.alloc(0);\n static #LAST_TIMESTAMP_BUFFER: [number, Buffer] = [0, Buffer.alloc(8)];\n\n readonly #pingData: () => Buffer;\n readonly #pingInterval: number | undefined;\n readonly #pingIntervalId?: ReturnType<typeof setInterval>;\n readonly #mask = false;\n readonly #logger: Logger;\n\n constructor(logger: Logger, supplier: () => [string, Set<ExtendedWebSocket>], ping?: number | PingConfig) {\n this.#logger = logger;\n this.#pingInterval = typeof ping === 'number' ? ping : ping?.interval;\n this.#pingData =\n typeof ping === 'number' || ping?.data === 'timestamp'\n ? () => PingManager.#createBufferFromTimestamp(Date.now())\n : () => PingManager.#EMPTY_BUFFER;\n\n if (this.#pingInterval) {\n this.#pingIntervalId = setInterval(() => {\n const [path, clients] = supplier();\n for (const client of clients) {\n if (this.#terminateIfDisconnected(client, path)) {\n continue;\n }\n this.#markAndSendPing(client, path);\n }\n }, this.#pingInterval);\n\n }\n }\n\n #terminateIfDisconnected(client: ExtendedWebSocket, path: string) {\n if (client.connected === false) {\n if (this.#logger.enabledFor('debug')) {\n this.#logger.debug(`terminating unresponsive ws client on [${path}]`);\n }\n client.terminate();\n return true;\n }\n return false;\n }\n\n #markAndSendPing(client: ExtendedWebSocket, path: string) {\n client.connected = false;\n const data = this.#pingData();\n if (this.#logger.enabledFor('trace')) {\n this.#logger.debug(`pinging ws client on [${path}]`);\n }\n client.ping(data, this.#mask, (err: Error) => {\n if (err && this.#logger.enabledFor('warn')) {\n this.#logger.warn(`failed to ping ws client on [${path}]`, err);\n }\n });\n }\n\n static #createBufferFromTimestamp(now = Date.now()): Buffer {\n if (now - PingManager.#LAST_TIMESTAMP_BUFFER[0] > 0) {\n const buffer = Buffer.allocUnsafe(8);\n buffer.writeBigInt64BE(BigInt(now), 0);\n PingManager.#LAST_TIMESTAMP_BUFFER = [now, buffer];\n }\n return PingManager.#LAST_TIMESTAMP_BUFFER[1];\n }\n\n static #createTimestampFromBuffer(data: Buffer): number {\n if (data.length === 8) {\n return Number(data.readBigInt64BE(0));\n }\n return 0;\n }\n\n close() {\n clearInterval(this.#pingIntervalId);\n }\n\n handlePing(handshake: WebSocketHandshakeInfo, socket: ExtendedWebSocket, data: Buffer): void {\n socket.connected = true;\n socket.pong(data, false, (err: Error) => {\n if (err && this.#logger.enabledFor('warn')) {\n this.#logger.warn(`${handshake.logPrefix}failed to pong ws client ${addressAndPort(handshake.remoteAddress)}`, err);\n }\n });\n }\n\n handlePong(handshake: WebSocketHandshakeInfo, socket: ExtendedWebSocket, data: Buffer): void {\n socket.connected = true;\n if (this.#logger.enabledFor('warn')) {\n const sent = PingManager.#createTimestampFromBuffer(data);\n if (sent > 0) {\n const latency = Date.now() - sent;\n if (this.#logger.enabledFor('debug')) {\n this.#logger.debug(`${handshake.logPrefix}ws client ${addressAndPort(handshake.remoteAddress)} ping-pong latency: ${latency}ms`);\n }\n if (this.#pingInterval && latency > this.#pingInterval / 2 && this.#logger.enabledFor('warn')) {\n this.#logger.warn(`${handshake.logPrefix}ws client ${addressAndPort(handshake.remoteAddress)} high ping-pong latency: ${latency}ms`);\n }\n }\n }\n }\n}\n", "import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';\nimport { dirname } from 'node:path';\nimport type { TlsOptions } from 'node:tls';\nimport { KEYUTIL, X509 } from 'jsrsasign';\nimport { mkcert } from '@interopio/gateway-server/tools';\nimport type { GatewayServer } from '@interopio/gateway-server';\nimport getLogger from '../../logger.ts';\n\nconst logger = getLogger('ssl');\n\nexport type ServerCertificateConfig = {\n /** Hostname for the server certificate (used in CN and SAN) */\n host: string;\n /** Path to CA private key file (PEM format), for auto-generating server certificates */\n key?: string;\n /** Passphrase for encrypted CA private key */\n passphrase?: string;\n};\n\nexport function secureContextOptions(ssl: GatewayServer.SslConfig, serverCertificate?: ServerCertificateConfig): TlsOptions {\n // Prepare common SSL/TLS options (client certificate verification)\n const commonOptions: TlsOptions = {};\n\n if (ssl.requestCert !== undefined) {\n commonOptions.requestCert = ssl.requestCert;\n }\n if (ssl.rejectUnauthorized !== undefined) {\n commonOptions.rejectUnauthorized = ssl.rejectUnauthorized;\n }\n\n // Mode 1: Explicit key and cert provided - check if files exist and use them\n if (ssl.key && ssl.cert && existsSync(ssl.key) && existsSync(ssl.cert)) {\n logger.info(`using SSL/TLS certificate ${ssl.cert} with private key in ${ssl.key}${ssl.passphrase ? ' (password-protected)' : ''}`);\n const options: TlsOptions = {\n key: readFileSync(ssl.key),\n cert: readFileSync(ssl.cert),\n ...commonOptions\n };\n if (ssl.passphrase) {\n options.passphrase = ssl.passphrase;\n }\n // Only set ca if requestCert is true (ca is for validating client certificates)\n if (ssl.requestCert && ssl.ca && existsSync(ssl.ca)) {\n options.ca = readFileSync(ssl.ca);\n }\n return options;\n }\n\n // Mode 1b: Key and cert not explicitly provided, but default files exist - use them\n if (!ssl.key && !ssl.cert) {\n const defaultKeyPath = './gateway-server.key';\n const defaultCertPath = './gateway-server.crt';\n\n if (existsSync(defaultKeyPath) && existsSync(defaultCertPath)) {\n logger.info(`using SSL/TLS certificate ${defaultCertPath} with private key in ${defaultKeyPath}${ssl.passphrase ? ' (password-protected)' : ''}`);\n const options: TlsOptions = {\n key: readFileSync(defaultKeyPath),\n cert: readFileSync(defaultCertPath),\n ...commonOptions\n };\n if (ssl.passphrase) {\n options.passphrase = ssl.passphrase;\n }\n // Only set ca if requestCert is true (ca is for validating client certificates)\n if (ssl.requestCert && ssl.ca && existsSync(ssl.ca)) {\n options.ca = readFileSync(ssl.ca);\n }\n return options;\n }\n }\n\n // Mode 2: Generate server certificate using CA key (from auth.x509.key)\n // If serverCertificate is undefined, skip certificate generation\n if (!serverCertificate) {\n throw new Error('SSL/TLS enabled but no server certificate provided. Either provide ssl.key and ssl.cert, or configure auth.x509.key for auto-generation.');\n }\n\n // Note: CA key is primarily for client certificate generation, incidentally used for server cert\n const caKeyPath = serverCertificate.key ?? 'gateway-ca.key';\n const caPemPath = ssl.ca ?? `${caKeyPath.replace(/\\.key$/, '.crt')}`;\n const passphrase = serverCertificate.passphrase ?? ssl.passphrase;\n\n // Auto-generate Root CA if it doesn't exist\n\n if (!existsSync(caKeyPath)) {\n if (existsSync(caPemPath)) {\n throw new Error(`CA key file not found: ${caKeyPath} (CA certificate exists: ${caPemPath})`);\n }\n const rootCA = mkcert.generateRootCA({ name: mkcert.DEFAULT_CA_NAME, passphrase });\n\n // Ensure directory exists\n const keyDir = dirname(caKeyPath);\n if (keyDir && keyDir !== '.' && !existsSync(keyDir)) {\n mkdirSync(keyDir, { recursive: true });\n }\n const certDir = dirname(caPemPath);\n if (certDir && certDir !== '.' && certDir !== keyDir && !existsSync(certDir)) {\n mkdirSync(certDir, { recursive: true });\n\n }\n writeFileSync(caKeyPath, rootCA.key, { mode: 0o400 });\n writeFileSync(caPemPath, rootCA.cert, { mode: 0o644 });\n logger.info(`created new local Root CA in ${caPemPath}, ${caKeyPath}${passphrase ? ' (password-protected)' : ''}`);\n }\n\n // Load CA key (with optional passphrase)\n const caKeyPem = readFileSync(caKeyPath, 'utf8');\n const caKeyObj = KEYUTIL.getKey(caKeyPem, passphrase);\n\n // Extract issuer from CA certificate\n const caCertPem = readFileSync(caPemPath, 'utf8');\n const caCert = new X509();\n caCert.readCertPEM(caCertPem);\n const issuer = caCert.getSubjectString();\n\n // Use hostname from serverCertificate config\n const hostname = serverCertificate.host;\n\n // Generate server certificate with correct issuer and hostname\n logger.debug(`generating server certificate signed by: ${issuer} for host: ${hostname}`);\n const serverCert = mkcert.generateCert(caKeyObj, issuer, [hostname], false); // false = server cert\n\n // Only save to disk if key or cert paths are explicitly provided\n if (ssl.key || ssl.cert) {\n const keyPath = ssl.key || './gateway-server.key';\n const certPath = ssl.cert || './gateway-server.crt';\n\n // Ensure directory exists for key\n const keyDir = dirname(keyPath);\n if (keyDir && keyDir !== '.' && !existsSync(keyDir)) {\n mkdirSync(keyDir, { recursive: true });\n }\n // Ensure directory exists for cert\n const certDir = dirname(certPath);\n if (certDir && certDir !== '.' && certDir !== keyDir && !existsSync(certDir)) {\n mkdirSync(certDir, { recursive: true });\n }\n\n writeFileSync(keyPath, serverCert.key, { mode: 0o600 });\n writeFileSync(certPath, serverCert.cert, { mode: 0o644 });\n\n logger.info(`generated server certificate saved to ${certPath} with private key in ${keyPath}${passphrase ? ' (password-protected)' : ''}`);\n } else {\n logger.info(`using in-memory server certificate for host: ${hostname}`);\n }\n const result: TlsOptions = {\n key: serverCert.key,\n cert: serverCert.cert,\n ...commonOptions\n };\n\n // Only set ca if requestCert is true (ca is for validating client certificates)\n // At this point, CA file is guaranteed to exist (either pre-existing or just generated)\n if (ssl.requestCert && ssl.ca && existsSync(caPemPath)) {\n result.ca = readFileSync(caPemPath);\n }\n\n return result;\n}\n", "import type { ServerWebExchange } from '../../types/web/server';\nimport { mediaType } from './util/matchers.ts';\nimport { HttpStatus } from '../http/status.ts';\nimport { resolve } from 'node:path';\nimport { access, readFile } from 'node:fs/promises';\nimport { constants } from 'node:fs';\n\nasync function getWelcomePage(staticLocations?: string[]): Promise<string | undefined> {\n if (staticLocations) {\n for (const filePath of staticLocations) {\n const indexHtml = resolve(filePath, 'index.html');\n try {\n await access(indexHtml, constants.R_OK);\n // found readable welcome page\n return indexHtml;\n } catch {\n // continue to next candidate\n }\n }\n }\n}\n\nexport default async function welcomePageFactory(staticLocations?: string[]) {\n const welcomePage = await getWelcomePage(staticLocations);\n const htmlMatcher = mediaType({mediaTypes: ['text/html']});\n\n return async (exchange: ServerWebExchange, next: () => Promise<void>) => {\n const { request, response } = exchange;\n if (request.method === 'GET' && request.path === '/') {\n response.setStatusCode(HttpStatus.OK);\n if (welcomePage !== undefined && (await htmlMatcher(exchange)).match) {\n response.headers.set('Content-Type', 'text/html; charset=utf-8');\n await response.body(readFile(welcomePage));\n }\n else {\n response.headers.set('Content-Type', 'text/plain; charset=utf-8');\n const buffer = Buffer.from('io.Gateway Server', 'utf-8');\n await response.body(buffer);\n }\n }\n else {\n await next();\n }\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["index_exports", "__export", "server_exports", "index_default", "__toCommonJS", "server_exports", "__export", "Factory", "VERSION", "import_node_http", "import_node_https", "import_node_async_hooks", "import_node_os", "PORT_RANGE_MATCHER", "validPort", "port", "portRange", "trimmed", "matchResult", "start", "end", "i", "localIp", "first", "a", "addresses", "details", "info", "acc", "addressAndPort", "address", "GatewayLogging", "getLogger", "name", "regexAwareReplacer", "_key", "value", "import_gateway", "import_node_async_hooks", "log", "getLogger", "codec", "principalName", "authentication", "name", "principal", "initClient", "gateway", "socket", "authenticationPromise", "remoteAddress", "key", "addressAndPort", "host", "opts", "err", "reason", "data", "create", "environment", "handshake", "logPrefix", "principalPromise", "user", "gw", "client", "contextFn", "_isBinary", "code", "core_default", "import_gateway", "import_gateway", "processVisibilityRules", "rules", "rule", "result", "key", "value", "processMetricFilters", "filters", "publisher", "originalMetrics", "originalIdentity", "rest", "processedPublisher", "allow", "m", "block", "processPublisherConfig", "publisherConfig", "processMeshConfig", "meshConfig", "processMetricsConfig", "config", "c", "processGatewayConfig", "log", "getLogger", "generateRandomGatewayId", "GatewayManager", "#defaultGatewayId", "#defaultGateway", "#managedGateways", "#principalToGatewayId", "#config", "#started", "#environment", "config", "processGatewayConfig", "environment", "principal", "gatewayId", "gateway", "#createPrincipalGateway", "allGateways", "gId", "id", "handler", "opts", "compose", "middleware", "fns", "fn", "ctx", "next", "dispatch", "dispatchedCtx", "nextCalled", "nextResolved", "result", "nextCtx", "import_node_net", "import_tough_cookie", "parseHost", "headers", "defaultHost", "host", "port", "isForwardedSsl", "v", "parseProtocol", "defaultProtocol", "proto", "parseRemoteAddress", "url", "remoteAddress", "AbstractHttpMessage", "#headers", "AbstractHttpRequest", "_AbstractHttpRequest", "#id", "parseCookies", "AbstractHttpResponse", "parseResponseCookies", "responseCookie", "parseHeader", "value", "list", "start", "end", "i", "toList", "values", "s", "cs", "tc", "cookie", "parsed", "result", "AbstractHttpHeaders", "name", "MapHttpHeaders", "prev", "DefaultHttpStatusCode", "#value", "value", "HttpStatus", "_HttpStatus", "#VALUES", "key", "code", "status", "#phrase", "phrase", "httpStatusCode", "import_node_http", "ExtendedHttpIncomingMessage", "http", "ExtendedHttpServerResponse", "AbstractServerHttpRequest", "AbstractHttpRequest", "#sslInfo", "AbstractServerHttpResponse", "AbstractHttpResponse", "#cookies", "#statusCode", "#state", "#commitActions", "statusCode", "httpStatusCode", "cookie", "action", "state", "body", "buffer", "error", "writeAction", "allActions", "acc", "cur", "_error", "HttpServerRequest", "#url", "#req", "req", "IncomingMessageHeaders", "dh", "dp", "family", "address", "port", "remoteAddress", "DefaultSslInfo", "chunks", "chunk", "text", "blob", "remoteIp", "socket", "AbstractHttpHeaders", "#msg", "msg", "name", "value", "OutgoingMessageHeaders", "v", "HttpServerResponse", "#res", "res", "status", "resolve", "reject", "e", "ServerHttpRequestDecorator", "_ServerHttpRequestDecorator", "#delegate", "request", "ServerHttpResponseDecorator", "_ServerHttpResponseDecorator", "response", "ServerWebExchangeDecorator", "_ServerWebExchangeDecorator", "exchange", "DefaultWebExchange", "#attributes", "#logId", "#logPrefix", "LOG_ID_ATTRIBUTE", "import_node_v8", "import_promises", "log", "getLogger", "DEFAULT_OPTIONS", "fetchStats", "dumpHeap", "opts", "prefix", "target", "fileExists", "_", "dumpFileName", "lastFileName", "e", "i", "currentFileName", "nextFileName", "firstFileName", "path", "processStats", "stats", "state", "limit", "used", "start", "merged", "stopped", "report", "interval", "command", "run", "channel", "stop", "m", "serverHeader", "version", "server", "response", "next", "server_header_default", "import_gateway", "log", "getLogger", "acceptsMissing", "originFilters", "tryMatch", "origin", "block", "allow", "acceptsNonMatched", "acceptsOrigin", "matchResult", "regexifyOriginFilters", "or", "matchers", "exchange", "matcher", "match", "NO_MATCH", "and", "m", "not", "anyExchange", "_exchange", "EMPTY_OBJECT", "variables", "pattern", "opts", "method", "request", "path", "mediaType", "shouldIgnore", "requestedMediaType", "ignoredMediaType", "requestMediaTypes", "upgradeMatcher", "import_gateway", "configure", "app", "config", "routes", "applyCors", "request", "options", "cors", "path", "configurer", "handlers", "handler", "matcher", "pattern", "middleware", "exchange", "next", "match", "variables", "sockets", "factory", "route", "regexifyOriginFilters", "import_gateway", "isSameOrigin", "request", "origin", "url", "actualProtocol", "actualHost", "originUrl", "originHost", "originProtocol", "isCorsRequest", "isPreFlightRequest", "VARY_HEADERS", "processRequest", "exchange", "config", "response", "responseHeaders", "varyHeaders", "header", "h", "logger", "rejectRequest", "preFlightRequest", "handleInternal", "DEFAULT_PERMIT_ALL", "DEFAULT_PERMIT_METHODS", "PERMIT_DEFAULT_CONFIG", "validateCorsConfig", "allowHeaders", "ALL", "allowOrigins", "validateAllowCredentials", "validateAllowPrivateNetwork", "trimTrailingSlash", "combine", "source", "other", "combined", "v", "combineCorsConfig", "corsFilter", "opts", "processor", "ctx", "next", "cors_default", "getLogger", "HttpStatus", "requestOrigin", "allowOrigin", "checkOrigin", "requestMethod", "getMethodToUse", "allowMethods", "checkMethods", "requestHeaders", "getHeadersToUse", "checkHeaders", "exposeHeaders", "DEFAULT_METHODS", "allowedOrigins", "originToCheck", "allowedOrigin", "allowedMethods", "allowedHeaders", "allowAnyHeader", "result", "requestHeader", "value", "allowedHeader", "isPreFlight", "headers", "matchingCorsConfigSource", "matcher", "import_gateway", "createCorsConfigSource", "context", "routes", "cors", "defaultCorsConfig", "combineCorsConfig", "PERMIT_DEFAULT_CONFIG", "validatedConfigs", "path", "route", "routeCorsConfig", "matcher", "config", "and", "upgradeMatcher", "pattern", "validateCorsConfig", "appConfigs", "m", "added", "entry", "matchingCorsConfigSource", "isAuthentication", "principal", "AuthenticationError", "value", "InsufficientAuthenticationError", "BadCredentialsError", "AccountStatusError", "message", "LockedError", "DisabledError", "AccountExpiredError", "CredentialsExpiredError", "AccessDeniedError", "AuthorizationDecision", "granted", "DefaultAuthorizationManager", "#check", "check", "authentication", "object", "AuthenticationServiceError", "AuthenticationError", "staticServerHttpHeadersWriter", "headers", "exchange", "containsNoHeaders", "response", "name", "value", "cacheControlServerHttpHeadersWriter", "MapHttpHeaders", "contentTypeServerHttpHeadersWriter", "strictTransportSecurityServerHttpHeadersWriter", "maxAgeInSeconds", "includeSubDomains", "preload", "headerValue", "delegate", "isSecure", "frameOptionsServerHttpHeadersWriter", "mode", "xssProtectionServerHttpHeadersWriter", "permissionsPolicyServerHttpHeadersWriter", "policyDirectives", "contentSecurityPolicyServerHttpHeadersWriter", "reportOnly", "headerName", "refererPolicyServerHttpHeadersWriter", "policy", "crossOriginOpenerPolicyServerHttpHeadersWriter", "crossOriginEmbedderPolicyServerHttpHeadersWriter", "crossOriginResourcePolicyServerHttpHeadersWriter", "compositeServerHttpHeadersWriter", "writers", "writer", "opts", "next", "serverAuthenticationEntryPointFailureHandler", "opts", "entryPoint", "rethrowAuthenticationServiceError", "exchange", "error", "AuthenticationServiceError", "DEFAULT_REALM", "createHeaderValue", "realm", "httpBasicEntryPoint", "opts", "headerValue", "exchange", "_error", "response", "HttpStatus", "BASIC", "httpBasicAuthenticationConverter", "opts", "credentialsEncoding", "exchange", "request", "authorization", "credentials", "parts", "principal", "erasableCredentials", "import_node_async_hooks", "AsyncStorageSecurityContextHolder", "_AsyncStorageSecurityContextHolder", "storage", "securityContext", "authentication", "authenticate", "exchange", "next", "token", "managerResolver", "successHandler", "storage", "authentication", "onAuthenticationSuccess", "e", "AuthenticationError", "filterExchange", "AsyncStorageSecurityContextHolder", "authenticationFilter", "opts", "auth", "anyExchange", "httpBasicAuthenticationConverter", "serverAuthenticationEntryPointFailureHandler", "httpBasicEntryPoint", "manager", "_exchange", "error", "httpStatusEntryPoint", "opts", "exchange", "_error", "logger", "getLogger", "delegatingEntryPoint", "opts", "defaultEntryPoint", "response", "_error", "HttpStatus", "exchange", "error", "matcher", "entryPoint", "delegatingSuccessHandler", "handlers", "exchange", "next", "authentication", "handler", "httpBasic", "opts", "xhrMatcher", "exchange", "match", "NO_MATCH", "defaultEntryPoint", "delegatingEntryPoint", "httpStatusEntryPoint", "HttpStatus", "httpBasicEntryPoint", "entryPoint", "manager", "restMatcher", "mediaType", "notHtmlMatcher", "not", "restNoHtmlMatcher", "and", "preferredMatcher", "or", "failureHandler", "serverAuthenticationEntryPointFailureHandler", "successHandler", "delegatingSuccessHandler", "converter", "httpBasicAuthenticationConverter", "authenticationFilter", "BearerTokenErrorCodes", "DEFAULT_URI", "invalidToken", "message", "HttpStatus", "invalidRequest", "ACCESS_TOKEN_PARAMETER_NAME", "authorizationPattern", "Oauth2AuthenticationError", "AuthenticationError", "error", "message", "options", "isBearerTokenAuthenticationToken", "authentication", "serverBearerTokenAuthenticationConverter", "opts", "exchange", "request", "resolveFromAuthorizationHeader", "token", "resolveFromQueryString", "resolveFromBody", "rs", "r", "resolveToken", "accessTokens", "invalidRequest", "accessToken", "headers", "headerName", "authorization", "match", "invalidToken", "resolveTokens", "parameters", "allow", "token_converter_default", "computeWWWAuthenticate", "parameters", "wwwAuthenticate", "i", "key", "value", "isBearerTokenError", "error", "getStatus", "authError", "Oauth2AuthenticationError", "HttpStatus", "createParameters", "realm", "bearerTokenServerAuthenticationEntryPoint", "opts", "exchange", "status", "response", "token_entry_point_default", "jwtAuthConverter", "opts", "principalClaimName", "jwt", "asyncJwtConverter", "converter", "JwtError", "BadJwtError", "onError", "error", "Oauth2AuthenticationError", "invalidToken", "AuthenticationServiceError", "jwtAuthManager", "decoder", "authConverter", "authentication", "isBearerTokenAuthenticationToken", "token", "e", "resourceServer", "opts", "entryPoint", "token_entry_point_default", "converter", "token_converter_default", "failureHandler", "serverAuthenticationEntryPointFailureHandler", "authenticationFilter", "manager", "jwtAuthManager", "_exchange", "import_jwt", "commenceAuthentication", "exchange", "authentication", "entryPoint", "cause", "InsufficientAuthenticationError", "e", "AuthenticationError", "httpStatusAccessDeniedHandler", "httpStatus", "_error", "buffer", "errorFilter", "opts", "accessDeniedHandler", "HttpStatus", "authenticationEntryPoint", "httpBasicEntryPoint", "next", "error", "AccessDeniedError", "principal", "isAuthentication", "logger", "getLogger", "delegatingAuthorizationManager", "opts", "check", "authentication", "exchange", "decision", "matcher", "manager", "checkResult", "AuthorizationDecision", "DefaultAuthorizationManager", "logger", "getLogger", "authorizationFilter", "opts", "manager", "storage", "exchange", "next", "promise", "AsyncStorageSecurityContextHolder", "c", "error", "AccessDeniedError", "SecurityContextServerWebExchange", "ServerWebExchangeDecorator", "#context", "exchange", "context", "exchangeFilter", "opts", "storage", "next", "AsyncStorageSecurityContextHolder", "x509Converter", "opts", "principalExtractor", "exchange", "sslInfo", "clientCertificate", "principal", "subjectX500PrincipalExtractor", "opts", "extractFromEmail", "subjectDnRegEx", "cert", "email", "altName", "result", "BadCredentialsError", "AbstractPasswordEncoder", "rawPassword", "encodedPassword", "DelegatingPasswordEncoder", "_DelegatingPasswordEncoder", "#idPrefix", "#idSuffix", "#idForEncode", "#encoderForEncode", "#encoders", "#defaultEncoderForMatches", "#outer", "outer", "prefixEncodedPassword", "id", "#extractId", "start", "end", "idForEncode", "encoders", "idPrefix", "idSuffix", "encoder", "encoded", "delegate", "#extractEncodedPassword", "NoopPasswordEncoder", "_NoopPasswordEncoder", "#INSTANCE", "import_tools", "bufferEquals", "a", "b", "diff", "i", "Argon2PasswordEncoder", "AbstractPasswordEncoder", "#saltLength", "#hashLength", "#parallelism", "#memory", "#passes", "saltLength", "hashLength", "parallelism", "memory", "passes", "rawPassword", "encodedPassword", "decoded", "hash", "nonce", "parameters", "MAX_PASSWORD_LENGTH", "createDelegatingPasswordEncoder", "idForEncode", "encoders", "Argon2PasswordEncoder", "NoopPasswordEncoder", "DelegatingPasswordEncoder", "NoopUserDetailsPasswordService", "user", "_newPassword", "UsernameNotFoundError", "AuthenticationError", "message", "username", "options", "UserBuilder", "_UserBuilder", "#username", "#password", "#authorities", "#accountExpired", "#accountLocked", "#credentialsExpired", "#disabled", "#passwordEncoder", "rawPassword", "builder", "password", "encoder", "roles", "role", "authorities", "accountExpired", "accountLocked", "credentialsExpired", "disabled", "encodedPassword", "logger", "getLogger", "userDetailsServiceAuthenticationManager", "userDetailsService", "options", "preAuthenticationChecks", "user", "LockedError", "DisabledError", "AccountExpiredError", "postAuthenticationChecks", "CredentialsExpiredError", "passwordEncoder", "createDelegatingPasswordEncoder", "userDetailsPasswordService", "NoopUserDetailsPasswordService", "upgradeEncodingIfNeeded", "userDetails", "presentedPassword", "existingEncodedPassword", "newEncodedPassword", "authentication", "username", "BadCredentialsError", "principal", "credentials", "accountStatusUserDetailsChecker", "preAuthenticatedAuthenticationManager", "opts", "userDetailsChecker", "supports", "UsernameNotFoundError", "erasableCredentials", "x509", "opts", "manager", "preAuthenticatedAuthenticationManager", "principalExtractor", "subjectX500PrincipalExtractor", "converter", "x509Converter", "authenticationFilter", "filterOrder", "filterOrderSymbol", "config_default", "config", "context", "getService", "name", "defaultService", "authenticationManager", "userDetailsServiceAuthenticationManager", "middleware", "ServerHttpSecurity", "#authenticationEntryPoint", "#defaultEntryPoints", "#authenticationManager", "delegatingEntryPoint", "writer", "headers", "filter", "x509", "subjectX500PrincipalExtractor", "cors_default", "defaultSuccessHandlers", "_", "next", "_authentication", "httpBasic", "verifier", "decoder", "token", "payload", "claim", "e", "BadJwtError", "JwtError", "authenticationConverter", "token_converter_default", "authenticationConverterMatcher", "exchange", "NO_MATCH", "match", "entryPoint", "token_entry_point_default", "resourceServer", "exchangeF", "exchangeFilter", "errorFf", "errorFilter", "manager", "authorize", "mappings", "anyExchangeRegistered", "matcher", "access", "serverMatcher", "anyExchange", "DefaultAuthorizationManager", "AuthorizationDecision", "p", "authentication", "delegatingAuthorizationManager", "authorizationFilter", "a", "b", "aOrder", "bOrder", "security", "MapUserDetailsService", "#users", "users", "user", "#getKey", "username", "key", "result", "newPassword", "userDetails", "import_node_crypto", "logger", "getLogger", "createSecurityConfig", "context", "authorize", "type", "defaultAccess", "path", "route", "rule", "matcher", "pattern", "and", "upgradeMatcher", "createUserDetailsService", "getOrDeducePassword", "user", "encoder", "password", "generatedPassword", "MAX_PASSWORD_LENGTH", "roles", "userDetails", "UserBuilder", "MapUserDetailsService", "httpSecurity", "corsConfigSource", "createCorsConfigSource", "config", "userDetailsService", "storage", "config_default", "import_node_async_hooks", "HttpHeadResponseDecorator", "ServerHttpResponseDecorator", "checkAndLogClientDisconnectedError", "error", "logger", "code", "message", "HandlerAdapter", "#logger", "#enableLoggingRequestDetails", "#delegate", "#storage", "delegate", "request", "response", "DefaultWebExchange", "storage", "value", "headers", "result", "key", "query", "exchange", "trace", "status", "logPrefix", "HttpStatus", "callback", "resolve", "reject", "WebHttpHandlerBuilder", "#webHandler", "#middleware", "#handlerDecorator", "webHandler", "consumer", "decorator", "previousDecorator", "handler", "getLogger", "adapter", "adapted", "import_ws", "createHandshakeInfo", "req", "protocol", "exchange", "request", "HttpServerRequest", "principalPromiseProvider", "principal", "url", "headers", "MapHttpHeaders", "key", "cookies", "logPrefix", "remoteAddress", "webSockets", "context", "next", "path", "routes", "route", "response", "upgradeMatchResult", "upgradeMatcher", "HttpStatus", "buffer", "import_ws", "ExtendedWebSocket", "_first", "_second", "options", "PingManager", "_PingManager", "#EMPTY_BUFFER", "#LAST_TIMESTAMP_BUFFER", "#pingData", "#pingInterval", "#pingIntervalId", "#mask", "#logger", "logger", "supplier", "ping", "#createBufferFromTimestamp", "path", "clients", "client", "#terminateIfDisconnected", "#markAndSendPing", "data", "err", "now", "buffer", "#createTimestampFromBuffer", "handshake", "socket", "addressAndPort", "sent", "latency", "logger", "getLogger", "upgradeStrategy", "path", "route", "wss", "onSocketError", "exchange", "logPrefix", "request", "req", "ServerHttpRequestDecorator", "socket", "upgradeHead", "host", "origin", "acceptsOrigin", "client", "applyHandshakeHeaders", "headers", "response", "seen", "header", "index", "HttpStatus", "name", "value", "nativeResponse", "ServerHttpResponseDecorator", "nameLowerCase", "initRoute", "endpoint", "storage", "regexAwareReplacer", "ExtendedWebSocket", "pings", "PingManager", "handler", "err", "handshake", "createHandshakeInfo", "data", "e", "import_node_fs", "import_node_path", "import_jsrsasign", "import_tools", "logger", "getLogger", "secureContextOptions", "ssl", "serverCertificate", "commonOptions", "options", "defaultKeyPath", "defaultCertPath", "caKeyPath", "caPemPath", "passphrase", "rootCA", "keyDir", "certDir", "caKeyPem", "caKeyObj", "caCertPem", "caCert", "issuer", "hostname", "serverCert", "keyPath", "certPath", "result", "import_package", "import_node_path", "import_promises", "import_node_fs", "getWelcomePage", "staticLocations", "filePath", "indexHtml", "welcomePageFactory", "welcomePage", "htmlMatcher", "mediaType", "exchange", "next", "request", "response", "HttpStatus", "buffer", "logger", "getLogger", "createListener", "builder", "onSocketError", "httpHandler", "req", "resOrUpgradeHead", "res", "ExtendedHttpServerResponse", "request", "HttpServerRequest", "response", "HttpServerResponse", "decoratedResponse", "HttpHeadResponseDecorator", "promisify", "fn", "resolve", "reject", "r", "err", "memoryMonitor", "config", "start", "VERSION", "info", "initBuilder", "context", "storage", "security", "httpSecurity", "sockets", "webSockets", "handler", "compose", "server_header_default", "next", "HttpStatus", "buffer", "welcomePageFactory", "_next", "WebHttpHandlerBuilder", "Factory", "options", "ssl", "host", "serverCertificate", "createServer", "https", "secureContextOptions", "http", "monitor", "gatewayManager", "GatewayManager", "path", "configure", "configurer", "core_default", "ports", "portRange", "listener", "server", "ExtendedHttpIncomingMessage", "e", "port", "route", "endpoint", "localIp", "initRoute", "addressAndPort", "_socket", "head", "address", "cb", "stop", "index_default", "Factory"]
|
|
7
7
|
}
|