@interopio/gateway-server 0.21.0 → 0.23.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.
@@ -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/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"]
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/media-type.ts", "../src/utils/mime-type-utils.ts", "../src/http/headers.ts", "../src/http/status.ts", "../src/server/exchange.ts", "../src/http/server/path.ts", "../src/http/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/web/cors/utils.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/web/server/handler.ts", "../src/server/security/web.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/codec/hints.ts", "../src/codec/encoder.ts", "../src/http/codec/core.ts", "../src/http/codec/multipart.ts", "../src/http/codec/config.ts", "../src/manage/server.ts", "../src/server/welcome-page.ts", "../src/web/server/adapter.ts", "../src/web/util/client.ts", "../src/web/async/fn/server/request.ts", "../src/web/util/pattern/internal/path-element.ts", "../src/web/util/pattern/internal/separator-path-element.ts", "../src/web/util/pattern/internal/wildcard-path-element.ts", "../src/web/util/pattern/internal/capture-segments-path-element.ts", "../src/web/util/pattern/internal/wildcard-segments-path-element.ts", "../src/web/util/pattern/path-pattern.ts", "../src/web/util/pattern/pattern-parse-error.ts", "../src/web/util/pattern/internal/capture-variable-path-element.ts", "../src/web/util/pattern/internal/single-char-wildcarded-path-element.ts", "../src/web/util/pattern/internal/regex-path-element.ts", "../src/web/util/pattern/internal/literal-path-element.ts", "../src/web/util/pattern/internal/path-pattern-parser.ts", "../src/web/util/pattern/path-pattern-parser.ts", "../src/web/async/fn/server/router.ts", "../src/web/async/fn/server/response.ts", "../src/server/error.ts", "../src/web/error.ts", "../src/web/server/error.ts", "../src/web/async/handler.ts", "../src/web/async/fn/server/handler.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 type { ServerConfig } from '../types/config.d.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.d.ts';\nimport { HttpHeadResponseDecorator } 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';\nimport codecConfig from './http/codec/config.ts';\nimport { gatewayCommandPipeServer} from './manage/server.ts';\n\nconst logger = getLogger('app');\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\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 try {\n const request = new HttpServerRequest(req);\n const response = new HttpServerResponse(res);\n const decoratedResponse: ServerHttpResponse = request.method === 'HEAD' ? new HttpHeadResponseDecorator(response) : response;\n const hp: Promise<void> = httpHandler(request, decoratedResponse)\n try {\n await hp;\n if (logger.enabledFor('trace')) {\n logger.debug(`${request.id} handling completed.`);\n }\n }\n catch (e) {\n if (e instanceof Error && e['code'] === 'ERR_INVALID_URL') {\n throw e; // Let the outer catch handle this and return 400 Bad Request\n }\n if (logger.enabledFor('trace')) {\n logger.debug(`${request.id} failed to complete: ${e instanceof Error ? e.message : e}`);\n }\n }\n }\n catch (e) {\n if (e instanceof Error && e['code'] === 'ERR_INVALID_URL') {\n if (logger.enabledFor('debug')) {\n logger.debug(`failed to get request URI: ${e.message}`);\n }\n res.statusCode = 400; // Bad Request\n res.end(http.STATUS_CODES[400]);\n return Promise.resolve();\n }\n throw e;\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?: 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';\nimport { WebHttpHandlerBuilder } from './web/server/adapter.ts';\nimport { DefaultErrorAttributes, DefaultWebErrorHandler } from './server/error.ts';\nimport { WebFilterChainProxy } from './server/security/web.ts';\nimport { ResponseStatusError } from './web/server/error.ts';\nimport { DispatcherHandler } from './web/async/handler.ts';\nimport {\n HandlerFunctionAdapter,\n RouterFunctionMapping,\n ServerResponseResultHandler\n} from './web/async/fn/server/handler.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 codecConfigurer = codecConfig.serverConfigurer.create();\n codecConfigurer.defaultCodecs.enableLoggingRequestDetails(true);\n const welcomePageRouterFunctionMapping = new RouterFunctionMapping();\n // welcomePageRouterFunctionMapping.init(await welcomePage(context.resourcesConfig?.locations));\n const h = new DispatcherHandler(\n [welcomePageRouterFunctionMapping],\n [new HandlerFunctionAdapter()],\n [new ServerResponseResultHandler(codecConfigurer.writers)]\n )\n const handler = {\n handle: compose<ServerWebExchange>(\n serverHeader(VERSION, context.serverHeader),\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 throw new ResponseStatusError(HttpStatus.NOT_FOUND);\n // response.setStatusCode(HttpStatus.NOT_FOUND);\n // await response.end();\n }\n )\n };\n\n return new WebHttpHandlerBuilder(handler)\n .filter(new WebFilterChainProxy(security))\n .codecConfigurer(codecConfigurer)\n .exceptionHandler(\n new DefaultWebErrorHandler(\n codecConfigurer.readers,\n codecConfigurer.writers,\n new DefaultErrorAttributes()))\n .storage(storage);\n}\n\nexport const Factory = async (options: 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 const fullServer = 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 if (options.management?.server.path) {\n gatewayCommandPipeServer({\n options: options.management.server,\n info: async () => ({\n pid: process.pid,\n type: 'gateway-server',\n ...(fullServer.gateway.info())\n }),\n logger: logger.child('management'),\n shutdown: options.management.commands?.['shutdown'].enabled ? async () => {\n if (logger.enabledFor('info')) {\n logger.info(`stopping gateway-server...`);\n }\n await fullServer.close();\n } : undefined\n });\n }\n\n return fullServer;\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 { HttpCookie, HttpHeaders, ResponseCookie } 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 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", "import { extname } from 'node:path';\nimport { MIMEType } from 'node:util';\nimport {\n APPLICATION_OCTET_STREAM_VALUE, InvalidMimeTypeError,\n isWildcardSubtype,\n isWildcardType\n} from '../utils/mime-type-utils.ts';\n\n//excerpt from mime types database\nconst mimeTypes = `\napplication/octet-stream bin dms lrf mar so dist distz pkg bpk dump elc deploy\napplication/json json\napplication/wasm wasm\napplication/x-pkcs12 p12 pfx\ntext/css css\ntext/csv csv\ntext/html html htm\ntext/javascript js mjs\ntext/plain txt text conf def list log in\n`\n\nexport class MediaType extends MIMEType {\n static readonly ALL: MediaType = new MediaType('*/*');\n static readonly APPLICATION_OCTET_STREAM: MediaType = new MediaType(APPLICATION_OCTET_STREAM_VALUE);\n static readonly APPLICATION_JSON: MediaType = new MediaType('application/json');\n static readonly APPLICATION_NDJSON: MediaType = new MediaType('application/x-ndjson');\n\n static readonly MULTIPART_FORM_DATA: MediaType = new MediaType('multipart/form-data');\n\n static readonly TEXT_PLAIN: MediaType = new MediaType('text/plain');\n static readonly TEXT_HTML: MediaType = new MediaType('text/html');\n\n static readonly #PARAM_QUALITY_FACTOR = 'q';\n\n private constructor(input: string) {\n super(input);\n this.#checkToken(this.type);\n this.#checkToken(this.subtype);\n for (const [key, value] of this.params) {\n this.checkParameters(key, value);\n }\n }\n\n protected checkParameters(key: string, value: string) {\n this.#checkToken(key);\n if (!isQuoted(value)) {\n this.#checkToken(value);\n }\n if (key === MediaType.#PARAM_QUALITY_FACTOR) {\n const unquotedValue = unquote(value);\n const q = parseFloat(unquotedValue);\n if (isNaN(q) || q < 0.0 || q > 1.0) {\n throw new InvalidMediaTypeError(`Invalid quality value: ${value}`);\n }\n }\n }\n\n #checkToken(token: string) {\n for (let i = 0; i < token.length; i++) {\n const c = token.charCodeAt(i);\n if (c < 0x20 // control characters\n || c > 0x7E // non-ASCII characters\n || c === 0x28 // (\n || c === 0x29 // )\n || c === 0x3C // <\n || c === 0x3E // >\n || c === 0x40 // @\n || c === 0x2C // ,\n || c === 0x3B // ;\n || c === 0x3A // :\n || c === 0x5C // \\\n || c === 0x22 // \"\n || c === 0x35 // /\n || c === 0x5B // [\n || c === 0x5D // ]\n || c === 0x3F // ?\n || c === 0x3D // =\n || c === 0x7B // {\n || c === 0x7D // }\n || c === 0x20 // space\n || c === 0x09 // tab\n ) {\n throw new InvalidMediaTypeError(`Invalid token: ${token}`);\n }\n }\n }\n\n\n get quality(): number {\n const qualityFactor = this.params.get(MediaType.#PARAM_QUALITY_FACTOR);\n return (qualityFactor !== null) ? parseFloat(unquote(qualityFactor)) : 1.0;\n }\n\n static parseMediaType(input: string): MediaType {\n return new MediaType(input);\n }\n\n static parseMediaTypesList(mediaTypes: string): MediaType[] {\n if (!mediaTypes?.trim()) {\n return [];\n }\n return mediaTypes.split(',')\n .map(type => type.trim())\n .filter(type => type.length > 0)\n .map(type => MediaType.parseMediaType(type));\n }\n\n static parseMediaTypes(...mediaTypes: string[]): MediaType[] {\n if (!mediaTypes) {\n return [];\n }\n else if (mediaTypes.length === 1) {\n return MediaType.parseMediaTypesList(mediaTypes[0]);\n }\n else {\n return mediaTypes.flatMap(mediaType => MediaType.parseMediaTypesList(mediaType));\n }\n }\n\n static asMediaType(mimeType: MIMEType): MediaType {\n if (mimeType instanceof MediaType) {\n return mimeType;\n }\n return new MediaType(mimeType.toString());\n }\n\n static asMediaTypes(...mimeTypes: MIMEType[]): MediaType[] {\n return mimeTypes.map(mimeType => MediaType.asMediaType(mimeType));\n }\n}\n\nexport class InvalidMediaTypeError extends Error {\n constructor(message: string) {\n super(message);\n }\n}\n\nconst fileExtensionToMediaTypes: Map<string, MediaType[]> = (function parseMimeTypes(): Map<string, MediaType[]> {\n const map = new Map<string, MediaType[]>();\n\n for (const line of mimeTypes.trim().split('\\n')) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#')) continue;\n\n const parts = trimmed.split(/\\s+/);\n if (parts.length < 2) continue;\n\n const [mimeType, ...extensions] = parts;\n const mediaType = MediaType.parseMediaType(mimeType);\n\n for (const ext of extensions) {\n const key = '.' + ext.toLowerCase();\n const existing = map.get(key);\n if (existing) {\n existing.push(mediaType);\n }\n else {\n map.set(key, [mediaType]);\n }\n }\n }\n\n return map;\n})();\n\nexport function getMediaType(filename?: string): MediaType | undefined {\n return getMediaTypes(filename)[0];\n}\n\nexport function getMediaTypes(filename?: string): MediaType[] {\n const extension = filename ? extname(filename) : '';\n let mediaTypes: MediaType[] | undefined = undefined;\n if (extension) {\n mediaTypes = fileExtensionToMediaTypes.get(extension.toLowerCase());\n }\n return mediaTypes ?? [];\n}\n\nfunction isQuoted(s: string): boolean {\n return s.length >= 2 && (\n (s.startsWith('\"') && s.endsWith('\"')) ||\n (s.startsWith(\"'\") && s.endsWith(\"'\")));\n}\n\nfunction unquote(s: string) {\n if (isQuoted(s)) {\n return s.substring(1, s.length - 1);\n }\n return s;\n}\n\nfunction isMoreSpecific(a: MIMEType, b: MIMEType): boolean {\n if (a instanceof MediaType) {\n if (b instanceof MediaType) {\n const aQuality = a.quality;\n const bQuality = b.quality;\n if (aQuality > bQuality) {\n return true;\n }\n else if (aQuality < bQuality) {\n return false;\n }\n }\n }\n const aWildcard = isWildcardType(a);\n const bWildcard = isWildcardType(b);\n if (aWildcard && !bWildcard) { // */* > text/*\n return false;\n }\n else if (!aWildcard && bWildcard) { // text/* < */*\n return true;\n }\n else {\n const aWildcardSubtype = isWildcardSubtype(a);\n const bWildcardSubtype = isWildcardSubtype(b);\n if (aWildcardSubtype && !bWildcardSubtype) { // text/* > text/html\n return false;\n }\n else if (!aWildcardSubtype && bWildcardSubtype) { // text/html < text/*\n return true;\n }\n else if (a.type === b.type && a.subtype === b.subtype) {\n const aParamsSize = Array.from(a.params.keys()).length;\n const bParamsSize = Array.from(b.params.keys()).length;\n return aParamsSize > bParamsSize; // text/html;level=1 > text/html\n }\n else {\n return false; // both are equally specific\n }\n }\n}\n\nfunction isLessSpecific(a: MIMEType, b: MIMEType): boolean {\n return isMoreSpecific(b, a);\n}\n\nfunction bubbleSort<T>(list: T[], swap: (a: T, b: T) => boolean) {\n const n = list.length;\n for (let i = 0; i < n; i++) {\n for (let j = 1; j < n - i; j++) {\n const prev = list[j - 1];\n const curr = list[j];\n if (swap(prev, curr)) {\n list[j] = prev;\n list[j - 1] = curr;\n }\n }\n }\n}\n\nexport function sortBySpecificity<T extends MIMEType>(mimeTypes: T[]) {\n if (mimeTypes === undefined) {\n throw new Error('mimeTypes must not be undefined');\n }\n if (mimeTypes.length > 100) {\n throw new InvalidMimeTypeError(`too many elements`);\n }\n bubbleSort(mimeTypes, isLessSpecific);\n\n}\n", "import { MIMEType } from 'node:util';\n\nexport const WILDCARD_TYPE = '*';\nexport const ALL = new MIMEType(`${WILDCARD_TYPE}/${WILDCARD_TYPE}`);\nexport const APPLICATION_OCTET_STREAM_VALUE = 'application/octet-stream';\nexport const APPLICATION_OCTET_STREAM = new MIMEType(APPLICATION_OCTET_STREAM_VALUE);\n\nexport function isWildcardType(mimeType: MIMEType): boolean {\n return mimeType.type === WILDCARD_TYPE;\n}\n\nexport function isWildcardSubtype(mimeType: MIMEType): boolean {\n return mimeType.subtype === WILDCARD_TYPE || mimeType.subtype.startsWith(`${WILDCARD_TYPE}+`);\n}\n\nexport function isConcrete(mimeType: MIMEType): boolean {\n return !isWildcardType(mimeType) && !isWildcardSubtype(mimeType);\n}\n\n\nexport class InvalidMimeTypeError extends Error {\n readonly mimeType: string;\n constructor(mimeType: string, message?: string, options?: ErrorOptions) {\n super(message === undefined ? `Invalid MIME type \"${mimeType}\"` : `Invalid MIME type \"${mimeType}\": ${message}`, options);\n this.mimeType = mimeType;\n }\n}\n\nexport function createMimeType(type: string, subtype: string, charset?: string): MIMEType {\n const input = `${type}/${subtype}`;\n let result: MIMEType;\n try {\n result = new MIMEType(input);\n }\n catch (error) {\n throw new InvalidMimeTypeError(input, undefined, { cause: error } );\n }\n if (charset) {\n result.params.set('charset', charset);\n }\n return result;\n}\n\nexport function getSubtypeSuffix(mimeType: MIMEType): string | null {\n const suffixIndex = mimeType.subtype.lastIndexOf('+');\n if (suffixIndex !== -1 && suffixIndex < mimeType.subtype.length) {\n return mimeType.subtype.substring(suffixIndex + 1);\n }\n return null;\n\n}\n\nexport function isCompatibleWith(a: MIMEType, b?: MIMEType): boolean {\n if (!b) {\n return false;\n }\n\n if (isWildcardType(a) || isWildcardType(b)) {\n return true;\n }\n\n else if (a.type === b.type) {\n if (a.subtype === b.subtype) {\n return true;\n }\n if (isWildcardSubtype(a) || isWildcardSubtype(b)) {\n const aSuffix = getSubtypeSuffix(a);\n const bSuffix = getSubtypeSuffix(b);\n if (a.subtype === WILDCARD_TYPE || b.subtype === WILDCARD_TYPE) {\n return true;\n }\n else if (isWildcardSubtype(a) && bSuffix !== null) {\n return aSuffix === b.subtype || aSuffix === bSuffix;\n }\n else if (isWildcardSubtype(b) && aSuffix !== null) {\n return a.subtype === bSuffix || bSuffix === aSuffix;\n }\n }\n }\n return false;\n}\n", "import type {\n HeaderValues,\n HttpHeaders,\n MutableHttpHeaders,\n ReadonlyHeaderValues, ReadonlyHttpHeaders\n} from '../../types/web/http';\nimport { MediaType } from './media-type.ts';\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\nexport abstract class AbstractHttpHeaders<Values extends HeaderValues | ReadonlyHeaderValues> {\n protected constructor() {\n }\n\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\nexport const EMPTY_HTTP_HEADERS: ReadonlyHttpHeaders = new MapHttpHeaders();\n\n\nexport function getContentType(headers: HttpHeaders): MediaType | undefined {\n const value = headers.one('content-type');\n return value ? MediaType.parseMediaType(value as string) : undefined;\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 RequestPath,\n ServerHttpRequest,\n ServerHttpResponse,\n ServerWebExchange,\n SslInfo\n} from '../../types/web/server';\nimport { AbstractHttpResponse } from '../http/exchange.ts';\nimport { AbstractHttpHeaders } from '../http/headers.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';\nimport { AbstractServerHttpRequest } from '../http/server/exchange.ts';\nimport type { ServerCodecConfigurer } from '../http/codec/types.ts';\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\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 requestPath(): RequestPath {\n return this.#delegate.requestPath;\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 get attributes(): Map<string, unknown> {\n return this.#delegate.attributes;\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: Map<string, unknown> = new Map();\n #logId?: unknown;\n #logPrefix: string = '';\n\n constructor(request: Request, response: Response, codecConfigurer: ServerCodecConfigurer) {\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(): Map<string, unknown> {\n return this.#attributes;\n }\n\n attribute<T>(name: string): T | undefined {\n return this.attributes.get(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.web.server.exchange.log_id';\n\n", "import type { PathContainer, PathContainerElement, PathSegment, Separator } from '../../../types/path';\n\nexport function subPath(container: PathContainer, start: number, end?: number): PathContainer {\n const elements = container.elements;\n end = end ?? elements.length;\n if (start === 0 && end === elements.length) {\n return container;\n }\n if (start === end) {\n return DefaultPathContainer.EMPTY_PATH;\n }\n if (!(start >= 0 && start < elements.length)) throw new Error('start index out of bounds: ' + start);\n if (!(start >= 0 && end <= elements.length)) throw new Error('end index out of bounds: ' + end);\n if (!(start < end)) throw new Error('start index must be less than end index: ' + start + ' >= ' + end);\n const slice = elements.slice(start, end);\n const path = slice.map(e => e.value).join('');\n return new DefaultPathContainer(path, slice);\n}\n\nexport function isSeparator(element: PathContainerElement): element is Separator {\n return element.value.length === 1 && element['valueToMatch'] === undefined && element['parameters'] === undefined;\n}\n\nexport function isPathSegment(element: PathContainerElement): element is PathSegment {\n return !isSeparator(element);\n}\n\nexport type Options = {\n readonly separator: number; // char code 0x2f for '/' and 0x2e for '.'\n readonly decodeAndParseParameters: boolean;\n}\nexport const HTTP_OPTIONS: Options = {\n separator: '/'.charCodeAt(0),\n decodeAndParseParameters: true,\n}\n\nexport const MESSAGING_OPTIONS: Options = {\n separator: '.'.charCodeAt(0),\n decodeAndParseParameters: false,\n}\n\nexport function parsePath(path: string, options?: Options): PathContainer {\n return DefaultPathContainer.createFromUrlPath(path, options ?? HTTP_OPTIONS);\n}\n\ntype DefaultSeparator = Separator & { readonly encoded: string };\n\nclass DefaultPathContainer implements PathContainer {\n static readonly EMPTY_PATH: PathContainer = new DefaultPathContainer('', []);\n static readonly #SEPARATORS: Map<number, DefaultSeparator> = new Map([\n ['/'.charCodeAt(0), { value: '/', encoded: '%2F' }],\n ['.'.charCodeAt(0), { value: '.', encoded: '%2E' }],\n ]);\n\n readonly #path: string;\n readonly #elements: readonly PathContainerElement[];\n\n constructor(path: string, elements: PathContainerElement[]) {\n this.#path = path;\n this.#elements = Object.freeze(elements);\n }\n\n get value(): string {\n return this.#path;\n }\n\n get elements(): readonly PathContainerElement[] {\n return this.#elements;\n }\n\n static createFromUrlPath(path: string, options: Options): PathContainer {\n if (path === '') {\n return DefaultPathContainer.EMPTY_PATH;\n }\n const separator = options.separator;\n const separatorElement = DefaultPathContainer.#SEPARATORS.get(separator);\n if (separatorElement === undefined) {\n throw new Error('Unsupported separator: ' + separator);\n }\n\n const elements: PathContainerElement[] = [];\n let start: number;\n if (path.charCodeAt(0) === separator) {\n start = 1;\n elements.push(separatorElement);\n }\n else {\n start = 0;\n }\n\n while (start < path.length) {\n let end = -1;\n for (let i = start; i < path.length; i++) {\n if (path.charCodeAt(i) === separator) {\n end = i;\n break;\n }\n }\n const segment = (end !== -1) ? path.substring(start, end) : path.substring(start);\n\n if (segment.length > 0) {\n elements.push(options.decodeAndParseParameters ?\n DefaultPathContainer.#decodeAndParsePathSegment(segment) :\n DefaultPathSegment.from(segment, separatorElement)\n );\n }\n if (end === -1) {\n break;\n }\n elements.push(separatorElement);\n start = end + 1;\n }\n return new DefaultPathContainer(path, elements);\n }\n\n static #decodeAndParsePathSegment(segment: string): PathSegment {\n const paramsIndex = segment.indexOf(';');\n if (paramsIndex === -1) {\n const valueToMatch = decodeURIComponent(segment);\n return DefaultPathSegment.from(segment, valueToMatch);\n }\n else {\n const valueToMatch = decodeURIComponent(segment.substring(0, paramsIndex));\n const pathParameterContent = segment.substring(paramsIndex);\n const parameters = DefaultPathContainer.#parsePathParameters(pathParameterContent);\n return DefaultPathSegment.from(segment, valueToMatch, parameters);\n }\n }\n\n static #parsePathParameters(content: string): Map<string, readonly string[]> {\n const parameters: Map<string, string[]> = new Map<string, string[]>();\n let start = 1; // skip initial ';'\n while (start < content.length) {\n let end = -1;\n for (let i = start; i < content.length; i++) {\n if (content.charAt(i) === ';') {\n end = i;\n break;\n }\n }\n const parameter = (end !== -1) ? content.substring(start, end) : content.substring(start);\n DefaultPathContainer.#parsePathParameterValue(parameter, parameters);\n if (end === -1) {\n break;\n }\n start = end + 1;\n }\n if (parameters.size > 0) {\n // freeze all value arrays and the map itself for runtime immutability\n for (const values of parameters.values()) {\n Object.freeze(values);\n }\n }\n return parameters;\n }\n\n static #parsePathParameterValue(input: string, output: Map<string, string[]>): void {\n if (input) {\n const eqIndex = input.indexOf('=');\n if (eqIndex !== -1) {\n const name = decodeURIComponent(input.substring(0, eqIndex));\n if (name.trim()) {\n const value = input.substring(eqIndex + 1);\n for (const v of value.split(',')) {\n const values = output.get(name);\n if (values !== undefined) {\n values.push(decodeURIComponent(v));\n }\n else {\n output.set(name, [decodeURIComponent(v)]);\n }\n }\n }\n }\n else {\n const name = decodeURIComponent(input);\n if (name.trim()) {\n const values = output.get(name);\n if (values !== undefined) {\n values.push('');\n }\n else {\n output.set(name, ['']);\n }\n }\n }\n }\n }\n}\n\nclass DefaultPathSegment implements PathSegment {\n static readonly #EMPTY_PARAMS: ReadonlyMap<string, readonly string[]> = new Map<string, readonly string[]>();\n\n static from(value: string, separatorOrValueToMatch: string | DefaultSeparator, parameters?: Map<string, readonly string[]>): PathSegment {\n if (typeof separatorOrValueToMatch === 'string') {\n const valueToMatch = separatorOrValueToMatch;\n return new DefaultPathSegment(value, valueToMatch, parameters);\n }\n else {\n const separator = separatorOrValueToMatch;\n const valueToMatch = (value.includes(separator.encoded)) ? value.replaceAll(separator.encoded, separator.value) : value;\n return DefaultPathSegment.from(value, valueToMatch, parameters);\n }\n }\n\n readonly #value: string;\n readonly #valueToMatch: string;\n readonly #parameters: ReadonlyMap<string, readonly string[]>;\n\n constructor(value: string, valueToMatch: string, parameters: ReadonlyMap<string, readonly string[]> = DefaultPathSegment.#EMPTY_PARAMS) {\n this.#value = value;\n this.#valueToMatch = valueToMatch;\n this.#parameters = parameters;\n }\n\n get value(): string {\n return this.#value;\n }\n\n get valueToMatch(): string {\n return this.#valueToMatch;\n }\n\n get parameters(): ReadonlyMap<string, readonly string[]> {\n return this.#parameters;\n }\n\n}\n", "import type { ReadonlyHttpHeaders } from '../../../types/web/http';\nimport type { RequestPath, SslInfo } from '../../../types/web/server';\nimport type { PathContainer } from '../../../types/path';\nimport { AbstractHttpRequest } from '../exchange.ts';\nimport { parsePath, subPath } from './path.ts';\n\nexport function parseRequestPath(uri: string | URL, contextPath?: string) {\n if (typeof uri === 'string') {\n return DefaultRequestPath.parse(uri, contextPath);\n }\n else {\n return parseRequestPath(uri.href, contextPath);\n }\n}\n\nclass DefaultRequestPath implements RequestPath {\n\n static #initContextPath(path: PathContainer, contextPath?: string): PathContainer {\n if (!(contextPath && contextPath.trim()) || contextPath.charAt(0) !== '/') {\n return parsePath('');\n }\n\n DefaultRequestPath.#validateContextPath(path.value, contextPath);\n\n const length = contextPath.length;\n let counter = 0;\n\n for (let i = 0; i < path.elements.length; i++) {\n const element = path.elements[i];\n counter += element.value.length;\n if (length === counter) {\n return subPath(path, 0, i + 1);\n }\n }\n\n // should not reach here\n throw new Error(`Failed to initialize context path: '${contextPath}' for request path: '${path.value}'`);\n }\n\n static #validateContextPath(fullPath: string, contextPath: string): void {\n const length = contextPath.length;\n if (contextPath.charAt(0) !== '/' || contextPath.charAt(length - 1) === '/') {\n throw new Error(`Invalid context path: '${contextPath}'. Context path must start with '/' and must not end with '/'`);\n }\n if (!fullPath.startsWith(contextPath)) {\n throw new Error(`Invalid context path: '${contextPath}'. Context path must be a prefix of request path: '${fullPath}'`);\n }\n if (fullPath.length > length && fullPath.charAt(length) !== '/') {\n throw new Error(`Invalid context path: '${contextPath}'. Context path must match to full path segments for request path: '${fullPath}'`);\n }\n }\n\n static #extractPathWithinApplication(fullPath: PathContainer, contextPath: PathContainer): PathContainer {\n const contextPathLength = contextPath.elements.length;\n return subPath(fullPath, contextPathLength);\n }\n\n static parse(rawPath: string, contextPath?: string) {\n const fullPath = parsePath(rawPath);\n const contextPathContainer = DefaultRequestPath.#initContextPath(fullPath, contextPath);\n const pathWithinApplication = DefaultRequestPath.#extractPathWithinApplication(fullPath, contextPathContainer);\n return new DefaultRequestPath(\n parsePath(rawPath),\n contextPathContainer,\n pathWithinApplication\n )\n }\n\n readonly #fullPath: PathContainer;\n readonly #contextPath: PathContainer;\n readonly #pathWithinApplication: PathContainer;\n\n private constructor(fullPath: PathContainer, contextPath: PathContainer, pathWithinApplication: PathContainer) {\n this.#fullPath = fullPath;\n this.#contextPath = contextPath;\n this.#pathWithinApplication = pathWithinApplication;\n }\n\n // path container\n get value() {\n return this.#fullPath.value;\n }\n\n get elements() {\n return this.#fullPath.elements;\n }\n\n // request path\n get contextPath() {\n return this.#contextPath;\n }\n\n get pathWithinApplication() {\n return this.#pathWithinApplication;\n }\n\n modifyContextPath(contextPath: string): RequestPath {\n const contextPathContainer = DefaultRequestPath.#initContextPath(this, contextPath);\n const pathWithinApplication = DefaultRequestPath.#extractPathWithinApplication(this, contextPathContainer);\n return new DefaultRequestPath(\n this,\n contextPathContainer,\n pathWithinApplication\n );\n }\n\n toString(): string {\n return this.#fullPath.toString();\n }\n}\n\nexport abstract class AbstractServerHttpRequest extends AbstractHttpRequest<ReadonlyHttpHeaders> {\n #sslInfo?: SslInfo\n #path?: RequestPath\n #contextPath?: string;\n\n abstract getNativeRequest<T>(): T;\n\n get requestPath(): RequestPath {\n if (this.#path === undefined) {\n this.#path = parseRequestPath(this.URL.pathname, this.#contextPath)\n }\n return this.#path;\n }\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", "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 { Middleware } from '../server/types.ts';\nimport type { AsyncLocalStorage } from 'node:async_hooks';\nimport type { SocketRoute } from '../server/socket.ts';\nimport type { ServerConfig, ServerCustomizer } from '../../types/config';\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';\nimport type { CorsConfig } from '../web/cors/types.ts';\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?: ServerConfig['cors'],\n readonly authConfig?: 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?: ServerConfig['resources']\n}>\n\nexport async function configure(app: ServerCustomizer, config: 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';\nimport type { CorsConfig, CorsConfigSource, CorsProcessor } from '../web/cors/types.ts';\nimport { isCorsRequest, isPreFlightRequest } from '../web/cors/utils.ts';\nimport type { WebFilterChain } from '../web/server/types.ts';\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\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\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 {\n filter: async (ctx: ServerWebExchange, chain: WebFilterChain) => {\n const config = await source(ctx);\n const isValid = processor(ctx, config);\n if (!isValid || isPreFlightRequest(ctx.request)) {\n return;\n }\n else {\n await chain.filter(ctx);\n }\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 { HttpRequest, ReadonlyHttpHeaders } from '../../../types/web/http';\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", "import type { RouteConfig, PathPattern } from './route.ts';\nimport {\n combineCorsConfig,\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';\nimport type { CorsConfig, CorsConfigSource } from '../web/cors/types.ts';\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';\nimport type { WebFilterChain } from '../../web/server/types.ts';\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, chain: WebFilterChain}, authentication: Authentication) => Promise<void>;\nexport type ServerAuthenticationFailureHandler = (filterExchange: {exchange: ServerWebExchange, chain: WebFilterChain}, error: AuthenticationError) => Promise<void>;\nexport type ServerAuthenticationEntryPoint = (exchange: ServerWebExchange, error: AuthenticationError) => Promise<void>;\nexport type ServerAccessDeniedHandler = (exchange: ServerWebExchange, error: AccessDeniedError) => Promise<void>;\n", "import type { ServerWebExchange } from '../../../types/web/server';\nimport { MapHttpHeaders } from '../../http/headers.ts';\nimport type { WebFilter, WebFilterChain } from '../../web/server/types.ts';\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}): WebFilter {\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 {\n filter: async (exchange: ServerWebExchange, chain: WebFilterChain) => {\n await writer(exchange);\n return chain.filter(exchange);\n }\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'\nimport type { WebFilter, WebFilterChain } from '../../web/server/types.ts';\n\nasync function authenticate(exchange: ServerWebExchange,\n chain: WebFilterChain,\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, chain}, 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, chain: WebFilterChain},\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): WebFilter {\n const auth = {\n matcher: anyExchange,\n successHandler: async({exchange, chain}: {exchange: ServerWebExchange, chain: WebFilterChain}) => {\n await chain.filter(exchange);\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 {\n filter: async (exchange: ServerWebExchange, chain: WebFilterChain): 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 chain.filter(exchange);\n return;\n }\n\n try {\n await authenticate(exchange, chain, token, managerResolver, auth.successHandler, auth.storage);\n\n }\n catch (error) {\n if (error instanceof AuthenticationError) {\n await auth.failureHandler({ exchange, chain }, 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}\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, chain}, authentication: Authentication) => {\n for (const handler of handlers) {\n await handler({exchange, chain}, 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';\nimport type { WebFilter } from '../../web/server/types.ts';\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}): WebFilter {\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 from '../cors.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';\nimport type { CorsConfigSource } from '../../web/cors/types.ts';\nimport type { WebFilter } from '../../web/server/types.ts';\nimport { MatcherSecurityWebFilterChain, type SecurityWebFilterChain } from './web.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 }): SecurityWebFilterChain => {\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: WebFilter[] = [];\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: WebFilter = 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: WebFilter = 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: WebFilter = 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, chain}, _authentication) => {\n return await chain.filter(exchange);\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: WebFilter = 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: WebFilter = 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: WebFilter = 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: WebFilter = 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 new MatcherSecurityWebFilterChain(anyExchange, ...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';\nimport type { WebFilterChain } from '../../web/server/types.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 {\n filter: async (exchange: ServerWebExchange, chain: WebFilterChain) => {\n try {\n await chain.filter(exchange);\n }\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}\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';\nimport type { WebFilterChain } from '../../web/server/types.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 {\n filter: async (exchange: ServerWebExchange, chain: WebFilterChain) => {\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 }\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 chain.filter(exchange);\n }\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';\nimport type { WebFilterChain } from '../../web/server/types.ts';\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 {\n filter: async (exchange: ServerWebExchange, chain: WebFilterChain) => {\n await chain.filter(new SecurityContextServerWebExchange(exchange, async () => await AsyncStorageSecurityContextHolder.getContext(storage)));\n }\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';\nimport type { WebFilter } from '../../web/server/types.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}): WebFilter {\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", "\nimport type { ServerWebExchange } from '../../../types/web/server';\nimport type { WebErrorHandler, WebFilter, WebFilterChain, WebHandler } from './types.ts';\n\nexport class WebHandlerDecorator implements WebHandler {\n readonly #delegate: WebHandler;\n\n constructor(delegate: WebHandler) {\n if (delegate === null || delegate === undefined) throw new Error('delegate must not be null or undefined');\n this.#delegate = delegate;\n }\n\n get delegate(): WebHandler {\n return this.#delegate;\n }\n\n async handle(exchange: ServerWebExchange): Promise<void> {\n return await this.#delegate.handle(exchange);\n }\n\n toString(): string {\n return `WebHandlerDecorator[delegate=${this.#delegate}]`;\n }\n}\n\nexport class ErrorHandlingWebHandler extends WebHandlerDecorator {\n readonly #errorHandlers: Array<WebErrorHandler>;\n constructor(delegate: WebHandler, ...errorHandlers: Array<WebErrorHandler>) {\n super(delegate);\n this.#errorHandlers = [... (errorHandlers)];\n Object.freeze(this.#errorHandlers);\n }\n\n get errorHandlers(): ReadonlyArray<WebErrorHandler> {\n return this.#errorHandlers;\n }\n\n handle(exchange: ServerWebExchange): Promise<void> {\n let completion: Promise<void>;\n try {\n completion = super.handle(exchange);\n }\n catch (e) {\n completion = Promise.reject(e);\n }\n\n // set handled web error attribute\n //exchange.attribute()\n for (const handler of this.#errorHandlers) {\n completion = completion.catch(async (reason) => {\n const error = reason instanceof Error ? reason : new Error(String(reason));\n await handler.handle(exchange, error);\n });\n }\n return completion;\n }\n}\n\nexport class DefaultWebFilterChain implements WebFilterChain {\n readonly #filters: WebFilter[];\n readonly #handler: WebHandler;\n\n /*readonly */ #current?: WebFilter;\n /*readonly */ #chian?: DefaultWebFilterChain;\n\n static of(handler: WebHandler, ...filters: WebFilter[]) {\n const allFilters = [...filters];\n const result = new DefaultWebFilterChain(filters, handler);\n const chain = DefaultWebFilterChain.initChain(filters, handler);\n result.#current = chain.#current;\n result.#chian = chain.#chian;\n return result;\n }\n\n private static initChain(filters: WebFilter[], handler: WebHandler): DefaultWebFilterChain {\n let chain = new DefaultWebFilterChain(filters, handler, undefined, undefined);\n for (const current of [...filters].reverse()) {\n chain = new DefaultWebFilterChain(filters, handler, current, chain);\n }\n return chain;\n }\n\n private constructor(filters: WebFilter[], handler: WebHandler, current? : WebFilter, chain?: DefaultWebFilterChain) {\n this.#filters = filters;\n this.#handler = handler;\n this.#current = current;\n this.#chian = chain;\n }\n\n get filters(): ReadonlyArray<WebFilter> {\n return this.#filters;\n }\n\n get handler(): WebHandler {\n return this.#handler;\n }\n\n async filter(exchange: ServerWebExchange): Promise<void> {\n if (this.#current !== undefined && this.#chian !== undefined) {\n await this.#invokeFilter(this.#current, this.#chian, exchange);\n }\n else {\n await this.#handler.handle(exchange);\n }\n }\n\n #invokeFilter(filter: WebFilter, chain: DefaultWebFilterChain, exchange: ServerWebExchange): Promise<void> {\n return filter.filter(exchange, chain);\n }\n}\n\nexport class FilteringWebHandler extends WebHandlerDecorator {\n readonly #chain: DefaultWebFilterChain;\n\n constructor(handler: WebHandler, ...filters: Array<WebFilter>) {\n super(handler);\n this.#chain = DefaultWebFilterChain.of(handler, ...(filters));\n }\n\n get filters() {\n return this.#chain.filters;\n }\n\n handle(exchange: ServerWebExchange): Promise<void> {\n return this.#chain.filter(exchange);\n }\n}\n", "import type { WebFilter, WebFilterChain } from '../../web/server/types.ts';\nimport type { ServerWebExchange } from '../../../types/web/server';\nimport { DefaultWebFilterChain } from '../../web/server/handler.ts';\nimport { HttpStatus } from '../../http/status.ts';\nimport type { ServerWebExchangeMatcher } from '../util/matchers.ts';\n\nexport class WebFilterChainProxy implements WebFilter {\n #filters: SecurityWebFilterChain[]\n #firewall: ServerWebExchangeFirewall = new StrictServerWebExchangeFirewall();\n #decorator: WebFilterChainDecorator = new DefaultWebFilterChainDecorator();\n #exchangeRejectedHandler: ServerExchangeRejectedHandler = new HttpStatusExchangeRejectedHandler();\n\n constructor(...filters: SecurityWebFilterChain[]) {\n this.#filters = [...filters];\n }\n\n async filter(exchange: ServerWebExchange, chain: WebFilterChain): Promise<void> {\n const firewalledExchange = await this.#firewall.firewalledExchange(exchange);\n try {\n await this.#filterFirewalledExchange(firewalledExchange, chain);\n }\n catch (e) {\n if (e instanceof ServerExchangeRejectedError) {\n await this.#exchangeRejectedHandler.handle(exchange, e)\n }\n else {\n throw e;\n }\n }\n }\n\n async #filterFirewalledExchange(firewalledExchange: ServerWebExchange, chain: WebFilterChain) {\n for (const securityFilterChain of this.#filters) {\n if (await securityFilterChain.matches(firewalledExchange)) {\n const filters = await securityFilterChain.webFilters();\n const currentChain = this.#decorator.decorate(chain, filters);\n await currentChain.filter(firewalledExchange);\n return;\n }\n }\n await this.#decorator.decorate(chain).filter(firewalledExchange);\n }\n\n set firewall(firewall: ServerWebExchangeFirewall) {\n if (!firewall) {\n throw new Error('firewall must be provided');\n }\n this.#firewall = firewall;\n }\n\n set decorator(decorator: WebFilterChainDecorator) {\n if (!decorator) {\n throw new Error('decorator must be provided');\n }\n this.#decorator = decorator;\n }\n\n set exchangeRejectedHandler(handler: ServerExchangeRejectedHandler) {\n if (!handler) {\n throw new Error('handler must be provided');\n }\n this.#exchangeRejectedHandler = handler;\n }\n}\n\nexport interface WebFilterChainDecorator {\n decorate(chain: WebFilterChain, filters?: WebFilter[]): WebFilterChain;\n}\n\nclass DefaultWebFilterChainDecorator implements WebFilterChainDecorator {\n decorate(original: WebFilterChain, filters?: WebFilter[]): WebFilterChain {\n filters = filters || [];\n return DefaultWebFilterChain.of({handle: (exchange) => original.filter(exchange) }, ...filters);\n }\n}\nexport interface SecurityWebFilterChain {\n matches(exchange: ServerWebExchange): Promise<boolean>;\n webFilters(): Promise<WebFilter[]>;\n}\nexport class MatcherSecurityWebFilterChain implements SecurityWebFilterChain {\n readonly #matcher: ServerWebExchangeMatcher\n readonly #filters: WebFilter[];\n\n constructor(matcher: ServerWebExchangeMatcher, ...filters: WebFilter[]) {\n this.#matcher = matcher;\n this.#filters = filters;\n }\n\n async matches(exchange: ServerWebExchange): Promise<boolean> {\n return (await this.#matcher(exchange))?.match === true;\n }\n async webFilters(): Promise<WebFilter[]> {\n return this.#filters;\n }\n}\n\nexport interface ServerWebExchangeFirewall {\n firewalledExchange(exchange: ServerWebExchange): Promise<ServerWebExchange>;\n}\nclass StrictServerWebExchangeFirewall {\n async firewalledExchange(exchange: ServerWebExchange): Promise<ServerWebExchange> {\n return exchange;\n }\n}\n\nexport class ServerExchangeRejectedError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'ServerExchangeRejectedError';\n }\n}\nexport interface ServerExchangeRejectedHandler {\n handle(exchange: ServerWebExchange, error: ServerExchangeRejectedError): Promise<void>;\n}\n\nclass HttpStatusExchangeRejectedHandler implements ServerExchangeRejectedHandler {\n readonly #status: HttpStatus;\n constructor(status: HttpStatus = HttpStatus.BAD_REQUEST) {\n this.#status = status;\n }\n async handle(exchange: ServerWebExchange, error: ServerExchangeRejectedError): Promise<void> {\n exchange.response.setStatusCode(this.#status);\n }\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 { 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';\nimport type { CorsConfigSource } from '../web/cors/types.ts';\nimport type { SecurityWebFilterChain } from '../server/security/web.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<SecurityWebFilterChain> {\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 { ServerHttpResponseDecorator } from './exchange.ts';\n\nexport class HttpHeadResponseDecorator extends ServerHttpResponseDecorator {\n\n}\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 { AuthorizationRule, Principal } from '../../types/auth';\nimport type { WebSocketHandshakeInfo } from '../../types/web/socket';\nimport type { ServerWebExchange, ServerWebSocketHandler } from '../../types/web/server';\n\nimport { HttpStatus } from '../http/status.ts';\nimport { MapHttpHeaders } from '../http/headers.ts';\nimport type { Middleware } from './types.ts';\nimport { type ExtendedHttpIncomingMessage, HttpServerRequest } from './exchange.ts';\nimport { upgradeMatcher } from './util/matchers.ts';\nimport type { ProcessedOriginFilters } from './ws-client-verify.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 { SslConfig } from '../../../types/config';\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: 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", "export function isLoggingSuppressed(hints?: Map<string, unknown>): boolean {\n return hints?.get('io.gateway.logging.suppress') === true;\n}\n\nexport const LOG_PREFIX_HINT = 'io.gateway.logging.prefix';\n\nexport function getLogPrefix(hints?: Map<string, unknown>): string {\n if (hints?.has(LOG_PREFIX_HINT)) {\n return (hints.get(LOG_PREFIX_HINT) as string) ?? '';\n }\n return '';\n}\n", "import { MIMEType } from 'node:util';\nimport getLogger, { type Logger } from '../logger.ts';\nimport { ALL, createMimeType, isCompatibleWith } from '../utils/mime-type-utils.ts';\nimport { getLogPrefix, isLoggingSuppressed } from './hints.ts';\nimport type { Encoder } from './types.ts';\n\nexport abstract class AbstractEncoder<T> implements Encoder<T> {\n #encodableMimeTypes: readonly MIMEType[];\n protected logger: Logger = getLogger('codec.encoder');\n\n protected constructor(...supportedMimeTypes: MIMEType[]) {\n this.#encodableMimeTypes = [...supportedMimeTypes];\n }\n\n setLogger(logger: Logger) {\n this.logger = logger;\n }\n\n encodableMimeTypes(): readonly MIMEType[] {\n return this.#encodableMimeTypes;\n }\n\n canEncode(type, mimeType?: MIMEType): boolean {\n if (mimeType === undefined) {\n return true;\n }\n for (const supportedMimeType of this.#encodableMimeTypes) {\n if (isCompatibleWith(mimeType, supportedMimeType)) {\n return true;\n }\n }\n return false;\n }\n\n abstract encode(input: Promise<T> | T, mimeType?: MIMEType, hints?: Map<string, unknown>): Promise<BlobPart>;\n}\n\nexport class BlobEncoder extends AbstractEncoder<BlobPart> {\n constructor() {\n super(ALL);\n }\n\n canEncode(type, mimeType?: MIMEType): boolean {\n return super.canEncode(type, mimeType);\n }\n\n async encode(input: Promise<BlobPart> | BlobPart, mimeType?: MIMEType, hints?: Map<string, unknown>): Promise<BlobPart> {\n const part = await input;\n if (this.logger.enabledFor('debug') && !isLoggingSuppressed(hints)) {\n this.#logValue(part);\n }\n return part;\n }\n\n #logValue(part: BlobPart, hints?: Map<string, unknown>): void {\n const prefix = getLogPrefix(hints);\n this.logger.debug(`${prefix}Encoding value of type ${typeof part} with size ${part['byteLength'] ?? part['size'] ?? part['length']}`);\n }\n}\n\n\nexport class StringEncoder extends AbstractEncoder<string> {\n private constructor(...mimeTypes: MIMEType[]) {\n super(...mimeTypes);\n }\n\n canEncode(type, mimeType?: MIMEType): boolean {\n return super.canEncode(type, mimeType) && type === 'string';\n }\n\n async encode(input: Promise<string> | string, mimeType?: MIMEType, hints?: Map<string, unknown>): Promise<BlobPart> {\n input = await input;\n if (!isLoggingSuppressed(hints) && this.logger.enabledFor('debug')) {\n const logPrefix = getLogPrefix(hints);\n const traceEnabled = this.logger.enabledFor('trace');\n this.logger.debug(`${logPrefix}Writing ${traceEnabled ? `${input}` : `${input.substring(0, 100)}...`}`);\n }\n return input;\n }\n\n static textPlainOnly(): StringEncoder {\n return new StringEncoder(createMimeType('text','plain', 'utf-8'));\n }\n static allMimeTypes(): StringEncoder {\n return new StringEncoder(createMimeType('text', 'plain', 'utf-8'), ALL);\n }\n}\n", "import getLogger, { Logger } from '../../logger.ts';\n\nexport abstract class LoggingCodecSupport {\n protected log: Logger = getLogger('http.codec');\n #enableLoggingRequestDetails = false;\n\n set enableLoggingRequestDetails(enable: boolean) {\n this.#enableLoggingRequestDetails = enable;\n }\n\n get enableLoggingRequestDetails(): boolean {\n return this.#enableLoggingRequestDetails;\n }\n}\n", "import { HttpMessageReader } from './types.ts';\nimport { MediaType } from '../media-type.ts';\nimport { isCompatibleWith } from '../../utils/mime-type-utils.ts';\nimport type { HttpInputMessage } from '../../../types/web/http';\nimport { LoggingCodecSupport } from './core.ts';\n\nexport class MultipartHttpMessageReader extends LoggingCodecSupport implements HttpMessageReader<FormData> {\n static readonly MEDIA_TYPES = Object.freeze([MediaType.MULTIPART_FORM_DATA]);\n #partReader: HttpMessageReader<[string, FormDataEntryValue]>;\n\n constructor(partReader: HttpMessageReader<[string, FormDataEntryValue]>) {\n super();\n this.#partReader = partReader;\n }\n\n get partReader() {\n return this.#partReader;\n }\n\n getReadableMediaTypes(): ReadonlyArray<MediaType> {\n return MultipartHttpMessageReader.MEDIA_TYPES;\n }\n\n\n canRead(type, mediaType?: MediaType): boolean {\n return this.#supportsMediaType(mediaType) && (type.name === FormData.name);\n }\n\n #supportsMediaType(mediaType?: MediaType): boolean {\n if (mediaType === undefined) return true;\n\n for (const supportedMediaType of MultipartHttpMessageReader.MEDIA_TYPES) {\n if (isCompatibleWith(supportedMediaType, mediaType)) {\n return true;\n }\n }\n return false;\n }\n\n async readPromise(type, message: HttpInputMessage, hints: Map<string, unknown>): Promise<FormData> {\n const stream = this.#partReader.read(type, message, hints);\n const result = new FormData();\n for await (const [name, value] of stream) {\n result.append(name, value)\n }\n return result;\n }\n\n\n read(type, message: HttpInputMessage, hints: Map<string, unknown>): ReadableStream<FormData> {\n throw new Error(`not implemented yet`);\n }\n\n}\n\n\nexport class DefaultPartHttpMessageReader extends LoggingCodecSupport implements HttpMessageReader<[string, FormDataEntryValue]> {\n getReadableMediaTypes(): ReadonlyArray<MediaType> {\n return [MediaType.MULTIPART_FORM_DATA];\n }\n\n canRead(type, mediaType?: MediaType): boolean {\n return type === 'string' || type.name === File.name && (\n mediaType === undefined || isCompatibleWith(MediaType.MULTIPART_FORM_DATA, mediaType)\n );\n }\n\n readPromise(type, message: HttpInputMessage, hints: Map<string, unknown>): Promise<[string, FormDataEntryValue]> {\n throw new Error(`not implemented yet`);\n }\n\n read(type, message: HttpInputMessage, hints: Map<string, unknown>): ReadableStream<[string, FormDataEntryValue]> {\n throw new Error(`not implemented yet`);\n }\n}\n", "import type {\n CodecConfigurer,\n DefaultCodecs,\n HttpMessageReader,\n HttpMessageWriter,\n ServerCodecConfigurer,\n ServerDefaultCodecs\n} from './types.ts';\nimport type { HttpOutputMessage, MutableHttpHeaders } from '../../../types/web/http';\nimport { AbstractEncoder, BlobEncoder, StringEncoder } from '../../codec/encoder.ts';\nimport type { Encoder } from '../../codec/types.ts';\nimport { MediaType } from '../media-type.ts';\nimport { isConcrete } from '../../utils/mime-type-utils.ts';\nimport { getContentType } from '../headers.ts';\nimport { DefaultPartHttpMessageReader, MultipartHttpMessageReader } from './multipart.ts';\n\n\nclass EncoderHttpMessageWriter<T> implements HttpMessageWriter {\n readonly #encoder: Encoder<T>;\n readonly #mediaTypes: readonly MediaType[];\n #defaultMediaType?: MediaType;\n\n constructor(encoder: Encoder<T>) {\n EncoderHttpMessageWriter.initLogger(encoder);\n this.#encoder = encoder;\n this.#mediaTypes = MediaType.asMediaTypes(...encoder.encodableMimeTypes());\n this.#defaultMediaType = this.#mediaTypes.find(mediaType => isConcrete(mediaType));\n }\n\n get encoder(): Encoder<T> {\n return this.#encoder;\n }\n\n getWriteableMediaTypes(): ReadonlyArray<MediaType> {\n return this.#mediaTypes;\n }\n\n canWrite(type, mediaType?: MediaType): boolean {\n return this.#encoder.canEncode(type, mediaType);\n }\n\n async write(input: Promise<T> | T, type, message: HttpOutputMessage<MutableHttpHeaders>, mediaType?: MediaType, hints?: Map<string, unknown>): Promise<void> {\n const resolvedMediaType = this.#updateContentType(message, mediaType);\n const part = this.#encoder.encode(input, resolvedMediaType, hints);\n await message.body(part);\n }\n\n private static initLogger(encoder: Encoder<unknown>): void {\n if (encoder instanceof AbstractEncoder) {\n // encoder.setLogger();\n }\n }\n\n #updateContentType(message: HttpOutputMessage<MutableHttpHeaders>, mediaType?: MediaType) {\n let resolvedMediaType = getContentType(message.headers);\n if (resolvedMediaType) {\n return resolvedMediaType;\n }\n let fallback = this.#defaultMediaType;\n resolvedMediaType = (useFallback(mediaType, fallback) ? fallback : mediaType);\n if (resolvedMediaType) {\n resolvedMediaType = addDefaultCharsetIfNeeded(resolvedMediaType, fallback);\n message.headers.set('Content-Type', resolvedMediaType.toString());\n }\n }\n}\n\nfunction addDefaultCharsetIfNeeded(main: MediaType, defaultType?: MediaType): MediaType {\n if (!main.params.has('charset') && defaultType !== undefined) {\n const defaultCharset = defaultType.params.get('charset');\n if (defaultCharset) {\n const result = MediaType.parseMediaType(main.toString());\n result.params.set('charset', defaultCharset);\n return result;\n }\n }\n return main;\n}\n\nfunction useFallback(main?: MediaType, fallback?: MediaType): boolean {\n return (main === undefined || !isConcrete(main) || main.essence === MediaType.APPLICATION_OCTET_STREAM.essence) && fallback !== undefined;\n}\n\nclass BaseDefaultCodecs implements DefaultCodecs {\n #multipartReader?: HttpMessageReader<unknown>;\n #maxInMemorySize?: number;\n #enableLoggingRequestDetails?: boolean;\n #registerDefaults = true;\n #writers = Array<HttpMessageWriter>();\n #readers = Array<HttpMessageReader>();\n\n constructor() {\n this.initReaders();\n this.initWriters();\n }\n\n multipartReader(reader: HttpMessageReader<unknown>) {\n this.#multipartReader = reader;\n this.initReaders();\n }\n\n registerDefaults(registerDefaults: boolean) {\n if (this.#registerDefaults !== registerDefaults) {\n this.#registerDefaults = registerDefaults;\n this.initReaders();\n this.initWriters();\n }\n }\n\n protected initReaders(): void {\n this.#readers.length = 0;\n if (!this.#registerDefaults) {\n return;\n }\n\n if (this.#multipartReader !== undefined) {\n this.addCodec(this.#readers, this.#multipartReader);\n }\n else {\n const partReader = new DefaultPartHttpMessageReader();\n this.addCodec(this.#readers, partReader);\n this.addCodec(this.#readers, new MultipartHttpMessageReader(partReader));\n }\n }\n\n protected initWriters(): void {\n this.#writers.length = 0;\n if (!this.#registerDefaults) {\n return;\n }\n this.#writers.push(...this.#getBaseWriters());\n this.extendWriters(this.#writers);\n }\n\n protected extendWriters(writers: Array<HttpMessageWriter>): void {\n }\n\n #getBaseWriters(): HttpMessageWriter[] {\n if (!this.#registerDefaults) {\n return [];\n }\n const writers = Array<HttpMessageWriter>();\n this.addCodec(writers, new EncoderHttpMessageWriter(new BlobEncoder()));\n return writers;\n }\n\n maxInMemorySize(bytes: number) {\n if (this.#maxInMemorySize !== bytes) {\n this.#maxInMemorySize = bytes;\n this.initReaders();\n }\n }\n\n enableLoggingRequestDetails(enable: boolean) {\n if (this.#enableLoggingRequestDetails !== enable) {\n this.#enableLoggingRequestDetails = enable;\n this.initReaders();\n this.initWriters();\n }\n }\n\n get catchAllReaders() {\n if (!this.#registerDefaults) {\n return [];\n }\n const readers = Array<HttpMessageReader>();\n\n return readers;\n }\n\n get typedWriters() {\n return this.#writers;\n }\n\n get typedReaders() {\n return this.#readers;\n }\n\n get catchAllWriters(): readonly HttpMessageWriter[]{\n if (!this.#registerDefaults) {\n return [];\n }\n const result = Array<HttpMessageWriter>();\n this.addCodec(result, new EncoderHttpMessageWriter(StringEncoder.allMimeTypes()));\n return result;\n }\n\n protected addCodec<T >(codecs: Array<T>, codec: T) {\n this.#initCodec(codec);\n codecs.push(codec);\n }\n\n #initCodec(codec: unknown): void {\n if (codec instanceof EncoderHttpMessageWriter) {\n codec = codec.encoder;\n }\n if (codec === undefined) {\n return;\n }\n const size = this.#maxInMemorySize;\n if (size !== undefined) {\n // todo\n }\n\n const enable = this.#enableLoggingRequestDetails;\n if (enable !== undefined) {\n if (codec instanceof MultipartHttpMessageReader) {\n codec.enableLoggingRequestDetails = enable;\n }\n if (codec instanceof DefaultPartHttpMessageReader) {\n codec.enableLoggingRequestDetails = enable;\n }\n }\n }\n}\nabstract class BaseCodecConfigurer implements CodecConfigurer {\n protected readonly baseDefaultCodecs: BaseDefaultCodecs;\n\n protected constructor(defaultCodecs: BaseDefaultCodecs) {\n this.baseDefaultCodecs = defaultCodecs;\n }\n\n get defaultCodecs(): DefaultCodecs {\n return this.baseDefaultCodecs;\n }\n\n registerDefaults(registerDefaults: boolean) {\n this.baseDefaultCodecs.registerDefaults(registerDefaults);\n }\n\n get readers() {\n const result = new Array<HttpMessageReader>();\n result.push(...this.baseDefaultCodecs.typedReaders);\n result.push(...this.baseDefaultCodecs.catchAllReaders);\n return result;\n }\n\n get writers(): readonly HttpMessageWriter[] {\n const result = new Array<HttpMessageWriter>();\n result.push(...this.baseDefaultCodecs.typedWriters);\n result.push(...this.baseDefaultCodecs.catchAllWriters);\n return result;\n }\n\n}\n\nclass ServerDefaultCodecsImpl extends BaseDefaultCodecs implements ServerDefaultCodecs {\n\n}\nclass DefaultServerCodecConfigurer extends BaseCodecConfigurer implements ServerCodecConfigurer {\n constructor() {\n super(new ServerDefaultCodecsImpl());\n }\n}\n\nfunction createServerCodecConfigurer(): ServerCodecConfigurer {\n return new DefaultServerCodecConfigurer();\n}\n\nexport default {\n serverConfigurer: {\n create: createServerCodecConfigurer\n }\n}\n", "import type { Logger } from '@interopio/gateway/logging/api';\nimport { createServer, type ListenOptions } from 'node:net';\nimport type { ManagementCommand } from '../../types/manage.d.ts';\nimport type { PipeServerOptions } from './types.d.ts';\n\n\nfunction createPipeCommandServer({ logger, options, handler, onClose }: {\n options: ListenOptions,\n logger: Logger,\n handler: (msg: ManagementCommand) => Promise<unknown>,\n onClose?: () => void\n}) {\n const pipeName = options.path;\n if (logger.enabledFor('info')) {\n logger.info(`[${pipeName}] opening command server pipe, waiting for the data...`);\n }\n try {\n const server = createServer((stream) => {\n if (logger.enabledFor('debug')) {\n logger.debug(`[${pipeName}] command pipe server got client, waiting for the data...`);\n }\n stream.on('close', () => {\n if (logger.enabledFor('debug')) {\n logger.debug(`[${pipeName}] client closed`);\n }\n });\n stream.on('error', (error) => {\n logger.error(`[${pipeName}] error on pipe stream`, error);\n });\n stream.on(\"data\", async (...args) => {\n try {\n const asString = args.toString();\n const msg = JSON.parse(asString) as ManagementCommand;\n if (logger.enabledFor('info')) {\n logger.info(`[${pipeName}] received command ${msg.command}`);\n }\n handler(msg)\n .then((result) => {\n const response = JSON.stringify({ result });\n if (logger.enabledFor('info')) {\n logger.info(`[${pipeName}] command ${msg.command} processed successfully. sending : ${response}`);\n }\n stream.write(response, (e) => {\n if (e) {\n if (logger.enabledFor('debug')) {\n logger.debug(`[${pipeName}] error while sending response for command ${msg.command}`, e);\n }\n }\n });\n\n })\n .catch((error: { message: string }) => {\n const response = JSON.stringify({ error: error.message });\n logger.error(`[${pipeName}] processing command ${msg.command} failed, sending ${response}`, error);\n stream.write(response, (e) => {\n if (e) {\n if (logger.enabledFor('debug')) {\n logger.debug(`[${pipeName}] error while sending error response for command ${msg.command}`, e);\n }\n }\n });\n })\n .finally(() => {\n if (msg.command === \"shutdown\") {\n if (logger.enabledFor('info')) {\n logger.info(`[${pipeName}] stopping management pipe server`);\n }\n server.close(onClose);\n }\n });\n }\n catch (error) {\n logger.error(`[${pipeName}] unable to parse the data`, error);\n }\n });\n });\n server.on(\"listening\", () => {\n if (logger.enabledFor('info')) {\n logger.info(`[${pipeName}] connected to the pipe, waiting for the data...`);\n }\n });\n server.on(\"error\", (error) => {\n logger.error(`[${pipeName}] error while opening the pipe - ${pipeName}`, error);\n throw error;\n });\n server.listen(options);\n }\n catch (cause) {\n const msg = `error while opening the pipe - ${pipeName}`;\n logger.error(msg, cause);\n const error = new Error(msg) as Error & { cause?: unknown };\n error.cause = cause;\n throw error;\n }\n}\n\nexport function gatewayCommandPipeServer({ options, logger, shutdown, info }: PipeServerOptions) {\n createPipeCommandServer({\n options,\n logger,\n onClose: () => {\n if (logger.enabledFor('info')) {\n logger.info(`[${options.path}] command server closed, exiting gateway-server process`);\n }\n process.exit(0);\n },\n handler: async (msg) => {\n if (msg.command === \"shutdown\") {\n if(shutdown) {\n await shutdown?.();\n return \"gateway-server stopped\";\n }\n else {\n return \"gateway-server stopping is disabled\";\n }\n }\n else if (msg.command === \"get-info\" || msg.command === \"info\") {\n return await info();\n }\n }\n });\n}\n", "import { resolve } from 'node:path';\nimport { access, readFile } from 'node:fs/promises';\nimport { constants } from 'node:fs';\nimport type { ServerWebExchange } from '../../types/web/server';\nimport { HttpStatus } from '../http/status.ts';\nimport { mediaType } from './util/matchers.ts';\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 }\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", "import type { Logger } from '@interopio/gateway/logging/api';\nimport { AsyncLocalStorage } from 'node:async_hooks';\nimport type { Middleware, ServerHttpRequest, ServerHttpResponse, ServerWebExchange } from '../../../types/web/server';\nimport { DefaultWebExchange } from '../../server/exchange.ts';\nimport type { HttpHeaders } from '../../../types/web/http';\nimport { HttpStatus } from '../../http/status.ts';\nimport getLogger from '../../logger.ts';\nimport { checkAndLogClientDisconnectedError } from '../util/client.ts';\nimport type { WebErrorHandler, WebFilter, WebHandler } from './types.ts';\nimport { ErrorHandlingWebHandler, FilteringWebHandler } from './handler.ts';\nimport type { HttpHandler } from '../../http/server/types.ts';\nimport { ServerCodecConfigurer } from '../../http/codec/types.ts';\nimport codecConfig from '../../http/codec/config.ts';\nimport { LoggingCodecSupport } from '../../http/codec/core.ts';\n\nclass HttpWebHandlerAdapter {\n\n readonly #logger: Logger;\n\n #codecConfigurer: ServerCodecConfigurer = undefined!;\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 get codecConfigurer(): ServerCodecConfigurer {\n if (this.#codecConfigurer === undefined) {\n this.codecConfigurer = codecConfig.serverConfigurer.create()\n }\n return this.#codecConfigurer;\n }\n\n set codecConfigurer(configurer: ServerCodecConfigurer) {\n if (configurer === null || configurer === undefined) {\n throw new Error('codecConfigurer must not be null or undefined');\n }\n this.#codecConfigurer = configurer;\n\n this.#enableLoggingRequestDetails = false;\n for (const reader of this.#codecConfigurer.readers) {\n if (reader instanceof LoggingCodecSupport && reader.enableLoggingRequestDetails) {\n this.#enableLoggingRequestDetails = true;\n break;\n }\n }\n }\n\n protected createExchange(request: ServerHttpRequest, response: ServerHttpResponse): ServerWebExchange {\n const exchange = new DefaultWebExchange(request, response, this.codecConfigurer);\n return exchange;\n }\n\n set storage(storage: AsyncLocalStorage<{ exchange: ServerWebExchange }>) {\n this.#storage = storage;\n }\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 }\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 else if (checkAndLogClientDisconnectedError(error, this.#logger)) {\n // todo notify observers\n return;\n }\n else {\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\n async web(exchange: ServerWebExchange): Promise<void> {\n return await this.#delegate.handle(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 }\n else {\n callback().then(() => resolve()).catch((error) => reject(error));\n }\n });\n }\n}\n\nexport class WebHttpHandlerBuilder {\n readonly #webHandler: WebHandler;\n readonly #filters: WebFilter[] = [];\n readonly #exceptionHandlers: WebErrorHandler[] = [];\n readonly #middleware: Middleware = [];\n #handlerDecorator?: (handler: HttpHandler) => HttpHandler;\n #storage?: AsyncLocalStorage<{ exchange: ServerWebExchange }> = new AsyncLocalStorage();\n #codecConfigurer?: ServerCodecConfigurer;\n\n constructor(webHandler: WebHandler) {\n this.#webHandler = webHandler;\n }\n\n static webHandler(webHandler: WebHandler): WebHttpHandlerBuilder {\n return new WebHttpHandlerBuilder(webHandler);\n }\n\n filter(...filters: WebFilter[]): this {\n if (filters) {\n this.#filters.push(...filters);\n }\n return this;\n }\n\n middleware(consumer: (middleware: Middleware) => void): this {\n consumer(this.#middleware);\n return this;\n }\n\n exceptionHandler(...handlers: WebErrorHandler[]): this {\n if (handlers) {\n this.#exceptionHandlers.push(...handlers);\n }\n return this;\n }\n\n exceptionHandlers(consumer: (handlers: WebErrorHandler[]) => void): this {\n consumer(this.#exceptionHandlers);\n return this;\n }\n\n storage(storage: AsyncLocalStorage<{ exchange: ServerWebExchange }>): this {\n this.#storage = storage;\n return this;\n }\n\n codecConfigurer(configurer: ServerCodecConfigurer): this {\n this.#codecConfigurer = configurer;\n return this;\n }\n\n hasCodecConfigurer(): boolean {\n return this.#codecConfigurer !== undefined;\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 let decorated: WebHandler = new FilteringWebHandler(this.#webHandler, ...this.#filters);\n decorated = new ErrorHandlingWebHandler(decorated, ...this.#exceptionHandlers);\n\n const adapter = new HttpWebHandlerAdapter(logger, decorated);\n if (this.#storage !== undefined) adapter.storage = this.#storage;\n if (this.#codecConfigurer !== undefined) {\n adapter.codecConfigurer = this.#codecConfigurer;\n }\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 { Logger } from '@interopio/gateway/logging/api';\n\nexport function isClientDisconnectedError(error: Error): boolean {\n if (error === null || error === undefined) {\n return false;\n }\n const { code, message } = error as any;\n return 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}\n\nexport function checkAndLogClientDisconnectedError(error: Error, logger: Logger): boolean {\n const isClientDisconnected = isClientDisconnectedError(error);\n if (isClientDisconnected) {\n if (logger.enabledFor('trace')) {\n logger.debug('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", "import type { ServerHttpRequest, ServerWebExchange } from '../../../../../types/web/server';\nimport type { ReadonlyHttpHeaders } from '../../../../../types/web/http';\nimport type { ServerRequest, ServerRequestHeaders } from './types.ts';\nimport { MIMEType } from 'node:util';\nimport { MediaType } from '../../../../http/media-type.ts';\nimport { getContentType } from '../../../../http/headers.ts';\nimport type { HttpMessageReader } from '../../../../http/codec/types.ts';\n\nexport default {\n create: (exchange: ServerWebExchange, messageReaders: readonly HttpMessageReader[]) : ServerRequest => {\n return new DefaultServerRequest(exchange, messageReaders);\n }\n}\n\nclass DefaultServerRequestHeaders implements ServerRequestHeaders {\n readonly #headers: ReadonlyHttpHeaders;\n constructor(headers: ReadonlyHttpHeaders) {\n this.#headers = headers;\n }\n\n accept(): MIMEType[] {\n return MediaType.parseMediaTypes(...this.#headers.list('accept'));\n }\n\n contentLength(): number | undefined {\n const value = this.#headers.one('content-length');\n return value !== undefined ? Number.parseInt(value) : undefined;\n }\n\n contentType(): MIMEType | undefined {\n return getContentType(this.#headers);\n }\n\n header(name: string): string[] {\n return this.#headers.list(name);\n }\n\n firstHeader(name: string): string | undefined {\n const list = this.#headers.list(name);\n return list.length > 0 ? list[0] : undefined;\n }\n\n asHttpHeaders(): ReadonlyHttpHeaders {\n return this.#headers;\n }\n}\n\nexport class DefaultServerRequest implements ServerRequest {\n readonly exchange: ServerWebExchange;\n readonly messageReaders: readonly HttpMessageReader[];\n readonly #headers: ServerRequestHeaders;\n constructor(exchange: ServerWebExchange, messageReaders: readonly HttpMessageReader[]) {\n this.exchange = exchange;\n this.messageReaders = [...messageReaders];\n this.#headers = new DefaultServerRequestHeaders(exchange.request.headers);\n }\n\n get attributes(): Map<string, unknown> {\n return this.exchange.attributes;\n }\n\n get headers() {\n return this.#headers;\n }\n\n get method() {\n return this.request.method;\n }\n\n get URL() {\n return this.request.URL;\n }\n\n get requestPath() {\n return this.request.requestPath;\n }\n\n queryParam(name: string): string | null {\n return this.request.URL.searchParams.get(name);\n }\n\n get principal() {\n return this.exchange.principal();\n }\n\n get request(): ServerHttpRequest {\n return this.exchange.request;\n }\n}\n", "import { MatchingContext } from '../path-pattern.ts';\n\n/*internal*/ export abstract class PathElement {\n protected static readonly WILDCARD_WEIGHT = 100;\n protected static readonly CAPTURE_VARIABLE_WEIGHT = 1;\n\n protected static readonly NO_PARAMETERS: Map<string, readonly string[]> = new Map();\n\n // position in the pattern where this path element starts\n protected readonly pos: number;\n // the separator used in this path pattern\n protected readonly separator: number;\n\n // the next path element in the chain\n /*protected*/ next?: PathElement;\n // the previous path element in the chain\n /*protected*/ prev?: PathElement;\n\n /*internal*/ protected constructor(pos: number, separator: number) {\n this.pos = pos;\n this.separator = separator;\n }\n\n abstract matches(candidatePos: number, matchingContext: MatchingContext): boolean;\n\n abstract get normalizedLength(): number;\n\n abstract get chars(): Uint16Array;\n\n get captureCount(): number {\n return 0;\n }\n\n get wildcardCount(): number {\n return 0;\n }\n\n get score(): number {\n return 0;\n }\n\n get literal() {\n return false;\n }\n\n /*protected final*/\n noMorePattern() {\n return this.next === undefined;\n }\n\n}\n", "import { PathElement } from './path-element.ts';\nimport { MatchingContext } from '../path-pattern.ts';\n\n/*internal*/ export class SeparatorPathElement extends PathElement {\n constructor(pos: number, separator: number) {\n super(pos, separator);\n }\n\n matches(pathIndex: number, matchingContext: MatchingContext): boolean {\n if (pathIndex < matchingContext.pathLength && matchingContext.isSeparator(pathIndex)) {\n if (this.noMorePattern()) {\n if (matchingContext.determinedRemainingPath) {\n matchingContext.remainingPathIndex = pathIndex + 1;\n return true;\n }\n else {\n return (pathIndex + 1 === matchingContext.pathLength);\n }\n }\n else {\n pathIndex++;\n return (this.next !== undefined && this.next.matches(pathIndex, matchingContext));\n }\n }\n return false;\n }\n\n get normalizedLength() {\n return 1;\n }\n\n get chars(): Uint16Array {\n return new Uint16Array([this.separator]);\n }\n\n get literal() {\n return true;\n }\n\n toString() {\n return `Separator(${String.fromCharCode(this.separator)})`;\n }\n}\n", "import { isPathSegment } from '../../../../http/server/path.ts';\nimport { PathElement } from './path-element.ts';\nimport { MatchingContext } from '../path-pattern.ts';\n\n/*internal*/ export class WildcardPathElement extends PathElement {\n constructor(pos: number, separator: number) {\n super(pos, separator);\n }\n\n matches(pathIndex: number, matchingContext: MatchingContext): boolean {\n let segmentData: string = undefined!;\n if (pathIndex < matchingContext.pathLength) {\n const element = matchingContext.pathElements[pathIndex];\n if (!isPathSegment(element)) {\n // should not match a separator\n return false;\n }\n segmentData = element.valueToMatch;\n pathIndex++;\n }\n\n if (this.noMorePattern()) {\n if (matchingContext.determinedRemainingPath) {\n matchingContext.remainingPathIndex = pathIndex;\n return true;\n }\n else {\n // and the path data has run out too\n return (pathIndex === matchingContext.pathLength);\n }\n }\n else {\n // within a path (e.g. /aa/*/bb) there must be at least one character to match the wildcard\n if (segmentData === undefined || segmentData.length === 0) {\n return false;\n }\n return (this.next !== undefined && this.next.matches(pathIndex, matchingContext));\n }\n }\n\n get normalizedLength(): number {\n return 1;\n }\n\n get chars() {\n return new Uint16Array(['*'.charCodeAt(0)]);\n }\n\n get wildcardCount(): number {\n return 1;\n }\n\n get score(): number {\n return PathElement.WILDCARD_WEIGHT;\n }\n\n toString() {\n return `Wildcard(*)`;\n }\n}\n", "import { PathElement } from './path-element.ts';\nimport { MatchingContext } from '../path-pattern.ts';\nimport { isPathSegment } from '../../../../http/server/path.ts';\nimport type { PathContainerElement } from '../../../../../types/path';\n\n/*internal*/ export class CaptureSegmentsPathElement extends PathElement {\n readonly #variableName: string;\n\n constructor(pos: number, captureDescriptor: Uint16Array, separator: number) {\n super(pos, separator);\n this.#variableName = String.fromCharCode(...captureDescriptor.slice(2, captureDescriptor.length - 1));\n }\n\n matches(pathIndex: number, matchingContext: MatchingContext): boolean {\n if (pathIndex === 0 && this.next !== undefined) {\n let endPathIndex = pathIndex;\n while (endPathIndex < matchingContext.pathLength) {\n if (this.next.matches(endPathIndex, matchingContext)) {\n this.#collectParameters(matchingContext, pathIndex, endPathIndex);\n return true;\n }\n endPathIndex++;\n }\n return false;\n }\n else if (pathIndex < matchingContext.pathLength && !matchingContext.isSeparator(pathIndex)) {\n return false;\n }\n if (matchingContext.determinedRemainingPath) {\n matchingContext.remainingPathIndex = matchingContext.pathLength;\n }\n this.#collectParameters(matchingContext, pathIndex, matchingContext.pathLength);\n return true;\n }\n\n #collectParameters(matchingContext: MatchingContext, startPathIndex: number, endPathIndex: number) {\n if (matchingContext.extractingVariables) {\n // collect the parameters from all the remaining path segments\n let parametersCollector = PathElement.NO_PARAMETERS;\n for (let i = startPathIndex; i < endPathIndex; i++) {\n const element = matchingContext.pathElements[i];\n if (isPathSegment(element)) {\n const { parameters } = element;\n if (parameters.size > 0) {\n if (parametersCollector === PathElement.NO_PARAMETERS) {\n parametersCollector = new Map<string, string[]>();\n }\n for (const [key, values] of parameters) {\n if (parametersCollector.has(key)) {\n const existingValues = parametersCollector.get(key)!;\n parametersCollector.set(key, existingValues.concat(values));\n }\n else {\n parametersCollector.set(key, values);\n }\n }\n }\n }\n }\n matchingContext.set(\n this.#variableName,\n this.#pathToString(startPathIndex, endPathIndex, matchingContext.pathElements), parametersCollector);\n }\n }\n\n #pathToString(fromSegment: number, toSegment: number, pathElements: readonly PathContainerElement[]): string {\n const sb: string[] = [];\n for (let i = fromSegment; i < toSegment; i++) {\n const element = pathElements[i];\n if (isPathSegment(element)) {\n sb.push(element.valueToMatch);\n }\n else {\n sb.push(element.value);\n }\n }\n return sb.join('');\n }\n\n get normalizedLength() {\n return 1;\n }\n\n get chars(): Uint16Array {\n const s = `${String.fromCharCode(this.separator)}{*${this.#variableName}}`;\n const result = new Uint16Array(s.length);\n for (let i = 0; i < s.length; i++) {\n result[i] = s.charCodeAt(i);\n }\n return result;\n }\n\n get wildcardCount(): number {\n return 0;\n }\n\n get captureCount(): number {\n return 1;\n }\n\n toString() {\n return `CaptureSegments(${String.fromCharCode(this.separator)}{*${this.#variableName}})`;\n }\n}\n", "import { PathElement } from './path-element.ts';\nimport { MatchingContext } from '../path-pattern.ts';\n\n/*internal*/ export class WildcardSegmentsPathElement extends PathElement {\n constructor(pos: number, separator: number) {\n super(pos, separator);\n }\n\n matches(pathIndex: number, matchingContext: MatchingContext): boolean {\n // wildcard segments at the start of the pattern\n if (pathIndex === 0 && this.next !== undefined) {\n let endPathIndex = pathIndex;\n while (endPathIndex < matchingContext.pathLength) {\n if (this.next.matches(endPathIndex, matchingContext)) {\n return true;\n }\n endPathIndex++;\n }\n return false;\n }\n // match until the end of the path\n else if (pathIndex < matchingContext.pathLength && !matchingContext.isSeparator(pathIndex)) {\n return false;\n }\n if (matchingContext.determinedRemainingPath) {\n matchingContext.remainingPathIndex = matchingContext.pathLength;\n }\n return true;\n }\n\n get normalizedLength() {\n return 1;\n }\n\n get chars(): Uint16Array {\n const s = `${String.fromCharCode(this.separator)}**`;\n const result = new Uint16Array(s.length);\n for (let i = 0; i < s.length; i++) {\n result[i] = s.charCodeAt(i);\n }\n return result;\n }\n\n get wildcardCount() {\n return 1;\n }\n\n toString() {\n return `WildcardSegments(${String.fromCharCode(this.separator)}**)`;\n }\n}\n", "import {\n isPathSegment,\n isSeparator,\n type Options,\n parsePath,\n subPath\n} from '../../../http/server/path.ts';\n\nimport { PathPatternParser } from './path-pattern-parser.ts';\nimport { PathElement } from './internal/path-element.ts';\nimport { SeparatorPathElement } from './internal/separator-path-element.ts';\nimport { WildcardPathElement } from './internal/wildcard-path-element.ts';\nimport { CaptureSegmentsPathElement } from './internal/capture-segments-path-element.ts';\nimport { WildcardSegmentsPathElement } from './internal/wildcard-segments-path-element.ts';\nimport type { PathContainer, PathContainerElement } from '../../../../types/path';\n\nexport /* internal */ class MatchingContext {\n readonly #candidate: PathContainer;\n readonly pathElements: readonly PathContainerElement[];\n readonly pathLength: number;\n #extractedUriVariables?: Map<string, string>;\n #extractedMatrixVariables?: Map<string, ReadonlyMap<string, readonly string[]>>;\n readonly extractingVariables: boolean = false;\n #determineRemainingPath: boolean = false;\n\n remainingPathIndex: number = 0;\n\n constructor(pathContainer: PathContainer, extractVariables: boolean) {\n this.#candidate = pathContainer;\n this.pathElements = pathContainer.elements;\n this.pathLength = this.pathElements.length;\n this.extractingVariables = extractVariables;\n }\n\n get determinedRemainingPath(): boolean {\n return this.#determineRemainingPath;\n }\n\n setMatchAllowExtraPath() {\n this.#determineRemainingPath = true;\n }\n\n\n set(key: string, value: string, parameters: ReadonlyMap<string, readonly string[]>) {\n if (this.#extractedUriVariables === undefined) {\n this.#extractedUriVariables = new Map();\n }\n this.#extractedUriVariables.set(key, value);\n\n if (parameters.size > 0) {\n if (this.#extractedMatrixVariables === undefined) {\n this.#extractedMatrixVariables = new Map();\n }\n this.#extractedMatrixVariables.set(key, parameters);\n }\n }\n\n get pathMatchResult() {\n if (this.#extractedUriVariables === undefined) {\n return PathMatchInfo.EMPTY;\n }\n else {\n return new PathMatchInfo(this.#extractedUriVariables, this.#extractedMatrixVariables);\n }\n }\n\n /*internal*/\n isSeparator(pathIndex: number): boolean {\n return isSeparator(this.pathElements[pathIndex]);\n }\n\n /*internal*/\n pathElementValue(pathIndex: number): string {\n const element = (pathIndex < this.pathLength) ? this.pathElements[pathIndex] : null;\n if (element !== null && isPathSegment(element)) {\n return element.valueToMatch;\n }\n else {\n return '';\n }\n }\n}\n\nexport class PathMatchInfo {\n static readonly EMPTY = new PathMatchInfo(new Map(), new Map());\n\n readonly uriVariables: ReadonlyMap<string, string>;\n readonly matrixVariables: ReadonlyMap<string, ReadonlyMap<string, readonly string[]>>;\n\n constructor(uriVars: ReadonlyMap<string, string>, matrixVars?: ReadonlyMap<string, ReadonlyMap<string, readonly string[]>>) {\n this.uriVariables = uriVars;\n this.matrixVariables = matrixVars ?? new Map();\n }\n\n toString(): string {\n return `PathMatchInfo(uriVariables=${this.uriVariables}, matrixVariables=${this.matrixVariables})`;\n }\n}\n\nexport class PathPattern {\n static readonly #EMPTY_PATH = parsePath('');\n static readonly SPECIFICITY_COMPARATOR = (a: PathPattern, b: PathPattern): number => {\n if (a === null || a === undefined) {\n return (b === null || b === undefined) ? 0 : 1;\n }\n else if (b === null || b === undefined) {\n return -1;\n }\n else {\n // catchAll true > catchAll false\n if (a.catchAll && !b.catchAll) {\n return 1;\n }\n else if (!a.catchAll && b.catchAll) {\n return -1;\n }\n else {\n // todo\n return 0;\n }\n }\n }\n\n readonly #patternString: string;\n readonly #parser: PathPatternParser;\n readonly #pathOptions: Options;\n readonly #caseSensitive: boolean;\n readonly #head?: PathElement;\n\n #capturedVariableCount: number = 0;\n #normalizedLength: number = 0;\n #endsWithSeparatorWildcard: boolean = false;\n #score: number = 0;\n // does the pattern ends with {*...}.\n #catchAll: boolean = false;\n\n constructor(patternText: string, parser: PathPatternParser, head?: PathElement) {\n this.#patternString = patternText;\n this.#parser = parser;\n this.#pathOptions = parser.pathOptions;\n this.#caseSensitive = parser.caseSensitive;\n this.#head = head;\n\n // Compute fields for fast comparison\n let current = head;\n while (current !== undefined) {\n this.#capturedVariableCount += current.captureCount;\n this.#normalizedLength += current.normalizedLength;\n this.#score += current.score;\n if (current instanceof CaptureSegmentsPathElement || current instanceof WildcardSegmentsPathElement) {\n this.#catchAll = true;\n }\n if (current instanceof SeparatorPathElement && current.next instanceof WildcardPathElement && current.next.next === undefined) {\n this.#endsWithSeparatorWildcard = true;\n }\n\n current = current.next;\n }\n }\n\n get patternString(): string {\n return this.#patternString;\n }\n\n get hasPatternSyntax(): boolean {\n return (this.#score > 0 || this.#catchAll || this.#patternString.indexOf('?') !== -1);\n }\n\n #hasLength(container?: PathContainer): container is PathContainer {\n return container !== undefined && container.elements.length > 0;\n }\n\n #pathContainerIsJustSeparator(container: PathContainer): boolean {\n return container.value.length === 1 && container.value.charCodeAt(0) === this.separator;\n }\n\n matches(pathContainer?: PathContainer): boolean {\n if (this.#head === undefined) {\n return !this.#hasLength(pathContainer);\n }\n else if (!this.#hasLength(pathContainer)) {\n if (this.#head instanceof WildcardSegmentsPathElement || this.#head instanceof CaptureSegmentsPathElement) {\n pathContainer = PathPattern.#EMPTY_PATH; // will allow CaptureTheRest to bind the variable to empty\n }\n else {\n return false;\n }\n }\n const matchingContext = new MatchingContext(pathContainer, false);\n return this.#head.matches(0, matchingContext);\n }\n\n matchAndExtract(pathContainer: undefined | PathContainer): PathMatchInfo | undefined {\n if (this.#head === undefined) {\n return (this.#hasLength(pathContainer) && !this.#pathContainerIsJustSeparator(pathContainer)) ? undefined : PathMatchInfo.EMPTY;\n }\n else if (!this.#hasLength(pathContainer)) {\n if (this.#head instanceof WildcardSegmentsPathElement || this.#head instanceof CaptureSegmentsPathElement) {\n pathContainer = PathPattern.#EMPTY_PATH; // will allow CaptureTheRest to bind the variable to empty\n }\n else {\n return undefined;\n }\n }\n const matchingContext = new MatchingContext(pathContainer, true);\n return this.#head.matches(0, matchingContext) ? matchingContext.pathMatchResult : undefined;\n }\n\n\n extractPathWithinPattern(path: PathContainer): PathContainer {\n const pathElements = path.elements;\n const pathElementsLength = pathElements.length;\n\n let startIndex = 0;\n\n let elem = this.#head;\n while (elem !== undefined) {\n if (!elem.literal) {\n break;\n }\n elem = elem.next;\n startIndex++;\n }\n if (elem === undefined) {\n // there is no pattern piece\n return parsePath('')\n }\n\n // skip leading separators that would be in the result\n while (startIndex < pathElementsLength && isSeparator(pathElements[startIndex])) {\n startIndex++;\n }\n\n let endIndex = pathElementsLength;\n // skip trailing separators that would be in the result\n while (endIndex > 0 && isSeparator(pathElements[endIndex - 1])) {\n endIndex--;\n }\n\n let multipleAdjacentSeparators = false;\n for (let i = startIndex; i < endIndex - 1; i++) {\n if (isSeparator(pathElements[i]) && isSeparator(pathElements[i + 1])) {\n multipleAdjacentSeparators = true;\n break;\n }\n }\n\n let resultPath: PathContainer;\n if (multipleAdjacentSeparators) {\n const sb : string[] = [];\n let i = startIndex;\n while (i < endIndex) {\n const e = pathElements[i++];\n sb.push(e.value);\n if (isSeparator(e)) {\n while (i < endIndex && isSeparator(pathElements[i])) {\n i++;\n }\n }\n }\n resultPath = parsePath(sb.join(''), this.#pathOptions);\n }\n else if (startIndex >= endIndex) {\n resultPath = parsePath('', this.#pathOptions);\n }\n else {\n resultPath = subPath(path, startIndex, endIndex);\n }\n return resultPath;\n }\n\n /* internal */\n get score(): number {\n return this.#score;\n }\n\n /* internal */\n get catchAll(): boolean {\n return this.#catchAll;\n }\n\n /* internal */\n get normalizedLength(): number {\n return this.#normalizedLength;\n }\n\n /* internal */\n get separator(): number {\n return this.#pathOptions.separator;\n }\n\n /* internal */\n get capturedVariableCount(): number {\n return this.#capturedVariableCount;\n }\n\n /* internal */\n toChainString(): string {\n const sb: string[] = [];\n let pe = this.#head;\n while (pe !== undefined) {\n sb.push(pe.toString());\n pe = pe.next;\n }\n return sb.join(' ');\n }\n\n /* internal */\n computePatternString(): string {\n const sb: string[] = [];\n let current = this.#head;\n while (current !== undefined) {\n sb.push(String.fromCharCode(...(current.chars)));\n current = current.next;\n }\n return sb.join('');\n }\n\n /* internal */\n get head(): PathElement | undefined {\n return this.#head;\n }\n\n}\n", "import { format } from 'node:util';\n\nconst PatternMessages = {\n MISSING_CLOSE_CAPTURE: \"Expected close capture character after variable name '}'\",\n MISSING_OPEN_CAPTURE: \"Missing preceding open capture character before variable name'{'\",\n ILLEGAL_NESTED_CAPTURE: \"Not allowed to nest variable captures\",\n CANNOT_HAVE_ADJACENT_CAPTURES: \"Adjacent captures are not allowed\",\n ILLEGAL_CHARACTER_AT_START_OF_CAPTURE_DESCRIPTOR: \"Char '%s' not allowed at start of captured variable name\",\n ILLEGAL_CHARACTER_IN_CAPTURE_DESCRIPTOR: \"Char '%s' is not allowed in a captured variable name\",\n CANNOT_HAVE_MANY_MULTISEGMENT_PATH_ELEMENTS: \"Multiple '{*...}' or '**' pattern elements are not allowed\",\n INVALID_LOCATION_FOR_MULTISEGMENT_PATH_ELEMENT: \"'{*...}' or '**' pattern elements should be placed at the start or end of the pattern\",\n MISSING_REGEX_CONSTRAINT: \"Missing regex constraint on capture\",\n ILLEGAL_DOUBLE_CAPTURE: \"Not allowed to capture ''{0}'' twice in the same pattern\",\n REGEX_PATTERN_SYNTAX_EXCEPTION: \"Exception occurred in regex pattern compilation\",\n CAPTURE_ALL_IS_STANDALONE_CONSTRUCT: \"'{*...}' cannot be mixed with other path elements in the same path segment\",\n}\n\nexport type PatternMessage = keyof typeof PatternMessages;\n\nexport class PatternParseError extends Error {\n\n readonly position: number;\n readonly messageType: PatternMessage;\n readonly inserts: readonly unknown[];\n readonly #pattern: Uint16Array;\n\n static formatMessage(messageType: PatternMessage, inserts: readonly unknown[]): string {\n return format(PatternMessages[messageType], ...inserts);\n }\n\n /* internal */ static createWithCause(cause: Error,\n position: number,\n pattern: Uint16Array,\n messageType: PatternMessage,\n ...inserts: readonly unknown[]): PatternParseError {\n const message = PatternParseError.formatMessage(messageType, inserts);\n return new PatternParseError(position, pattern, messageType, inserts, message, { cause });\n }\n\n /* internal */ static create(pos: number, pattern: Uint16Array, messageType: PatternMessage, ...inserts: readonly unknown[]): PatternParseError {\n const message = PatternParseError.formatMessage(messageType, inserts);\n return new PatternParseError(pos, pattern, messageType, inserts, message);\n }\n\n private constructor(\n pos: number,\n pattern: Uint16Array,\n messageType: PatternMessage,\n inserts: readonly unknown[],\n message: string,\n options?: { cause?: Error },\n ) {\n super(message, options);\n this.position = pos;\n this.#pattern = pattern;\n this.messageType = messageType;\n this.inserts = inserts;\n }\n\n toDetailedString(): string {\n const sb: string[] = [];\n sb.push(String.fromCharCode(...this.#pattern));\n sb.push('\\n');\n for (let i = 0; i < Math.max(0, this.position); i++) {\n sb.push(' ');\n }\n sb.push('^\\n');\n sb.push(this.message);\n return sb.join('');\n }\n}\n", "import { PathElement } from './path-element.ts';\nimport { MatchingContext } from '../path-pattern.ts';\n\nimport type { PathSegment } from '../../../../../types/path';\n\n/*internal*/ export class CaptureVariablePathElement extends PathElement {\n readonly variableName: string\n readonly #constraintPattern?: RegExp;\n\n constructor(pos: number, captureDescriptor: Uint16Array, caseSensitive: boolean, separator: number) {\n super(pos, separator);\n let colon = -1;\n for (let i = 0; i < captureDescriptor.length; i++) {\n if (captureDescriptor[i] === 58) { // ':'\n colon = i;\n break;\n }\n }\n if (colon === -1) {\n // no constraint\n this.variableName = String.fromCharCode(...captureDescriptor.slice(1, captureDescriptor.length - 1));\n this.#constraintPattern = undefined;\n }\n else {\n this.variableName = String.fromCharCode(...captureDescriptor.slice(1, colon));\n const patternText = String.fromCharCode(...captureDescriptor.slice(colon + 1, captureDescriptor.length - 1));\n // always set dotall to true\n const flags = caseSensitive ? 's' : 'si';\n this.#constraintPattern = new RegExp(patternText, flags);\n }\n }\n\n matches(pathIndex: number, matchingContext: MatchingContext): boolean {\n if (pathIndex >= matchingContext.pathLength) {\n // no more path left to match this element\n return false;\n }\n const candidateCapture = matchingContext.pathElementValue(pathIndex);\n if (candidateCapture.length === 0) {\n return false;\n }\n\n if (this.#constraintPattern !== undefined) {\n // TODO possible optimization - only regex match if rest of pattern matches?\n const exec = this.#constraintPattern.exec(candidateCapture);\n if (exec === null) {\n return false;\n }\n // Ensure the match covers the entire string (full match)\n if (exec.index !== 0 || exec[0].length !== candidateCapture.length) {\n return false;\n }\n if (exec.length > 1) {\n throw new TypeError(`No capture groups allowed in the constraint regex: ${this.#constraintPattern}`)\n }\n }\n\n let match = false;\n pathIndex++;\n if (this.noMorePattern()) {\n if (matchingContext.determinedRemainingPath) {\n matchingContext.remainingPathIndex = pathIndex;\n match = true;\n }\n else {\n // needs to be at least one character\n match = (pathIndex === matchingContext.pathLength);\n }\n }\n else {\n if (this.next !== undefined) {\n match = this.next.matches(pathIndex, matchingContext);\n }\n }\n\n if (match && matchingContext.extractingVariables) {\n matchingContext.set(\n this.variableName,\n candidateCapture,\n (matchingContext.pathElements[pathIndex - 1] as PathSegment).parameters\n );\n }\n return match;\n }\n\n get normalizedLength() {\n return 1;\n }\n\n get chars(): Uint16Array {\n const sb: string[] = [];\n sb.push('{');\n sb.push(this.variableName);\n if (this.#constraintPattern !== undefined) {\n sb.push(':');\n sb.push(this.#constraintPattern.source);\n }\n sb.push('}');\n const s = sb.join('');\n const result = new Uint16Array(s.length);\n for (let i = 0; i < s.length; i++) {\n result[i] = s.charCodeAt(i);\n }\n return result;\n }\n\n get wildcardCount() {\n return 0;\n }\n\n get captureCount(): number {\n return 1;\n }\n\n get score(): number {\n return PathElement.CAPTURE_VARIABLE_WEIGHT;\n }\n\n toString() {\n return `CaptureVariable({${this.variableName}${this.#constraintPattern ? ':' + this.#constraintPattern.source : ''}})`;\n }\n}\n", "import { isPathSegment } from '../../../../http/server/path.ts';\nimport { PathElement } from './path-element.ts';\nimport { MatchingContext } from '../path-pattern.ts';\n\n/*internal*/ export class SingleCharWildcardedPathElement extends PathElement {\n readonly #text: Uint16Array;\n readonly #len: number;\n readonly #questionMarkCount: number;\n readonly #caseSensitive: boolean;\n\n constructor(pos: number, literalText: Uint16Array, questionMarkCount: number, caseSensitive: boolean, separator: number) {\n super(pos, separator);\n this.#len = literalText.length;\n this.#questionMarkCount = questionMarkCount;\n this.#caseSensitive = caseSensitive;\n if (caseSensitive) {\n this.#text = literalText;\n }\n else {\n this.#text = new Uint16Array(literalText.length);\n for (let i = 0; i < literalText.length; i++) {\n this.#text[i] = String.fromCharCode(literalText[i]).toLowerCase().charCodeAt(0);\n }\n }\n }\n\n matches(pathIndex: number, matchingContext: MatchingContext): boolean {\n if (pathIndex >= matchingContext.pathLength) {\n // no more path left to match this element\n return false;\n }\n\n const element = matchingContext.pathElements[pathIndex];\n if (!isPathSegment(element)) {\n return false;\n }\n\n const value = element.valueToMatch;\n if (value.length !== this.#len) {\n // not enough data to match this path element\n return false;\n }\n if (this.#caseSensitive) {\n for (let i = 0; i < this.#len; i++) {\n const c = this.#text[i];\n if ((c !== '?'.charCodeAt(0)) && (c !== value.charCodeAt(i))) {\n return false;\n }\n }\n }\n else {\n for (let i = 0; i < this.#len; i++) {\n const c = this.#text[i];\n if ((c !== '?'.charCodeAt(0)) && (c !== String.fromCharCode(value.charCodeAt(i)).toLowerCase().charCodeAt(0))) {\n return false;\n }\n }\n }\n\n pathIndex++;\n if (this.noMorePattern()) {\n if (matchingContext.determinedRemainingPath) {\n matchingContext.remainingPathIndex = pathIndex;\n return true;\n }\n else {\n return (pathIndex === matchingContext.pathLength);\n }\n }\n else {\n return (this.next !== undefined && this.next.matches(pathIndex, matchingContext));\n }\n }\n\n get wildcardCount(): number {\n return this.#questionMarkCount;\n }\n\n get normalizedLength() {\n return this.#len;\n }\n\n get chars() {\n return this.#text;\n }\n\n toString() {\n return `SingleCharWildcarded(${String.fromCharCode(...(this.#text))})`;\n }\n}\n", "import { PathElement } from './path-element.ts';\nimport { MatchingContext } from '../path-pattern.ts';\nimport type { PathSegment } from '../../../../../types/path';\n\n/*internal*/\nexport class RegexPathElement extends PathElement {\n\n readonly #regex: Uint16Array;\n readonly #caseSensitive: boolean;\n readonly #pattern: RegExp;\n readonly #wildcardCount;\n readonly #variableNames: readonly string[];\n\n constructor(pos: number, regex: Uint16Array, caseSensitive: boolean, completePattern: Uint16Array, separator: number) {\n super(pos, separator);\n this.#regex = regex;\n this.#caseSensitive = caseSensitive;\n [this.#pattern, this.#wildcardCount, this.#variableNames] = this.#buildPattern(regex, completePattern);\n }\n\n #buildPattern(regex: Uint16Array, _completePattern: Uint16Array): [RegExp, number, readonly string[]] {\n const text = String.fromCharCode(...regex);\n const variableNames: string[] = [];\n let wildcardCount = 0;\n const patternBuilder: string[] = [];\n\n let pos = 0;\n while (pos < text.length) {\n const ch = text.charAt(pos);\n\n if (ch === '{') {\n // Start of a variable capture\n const closeBrace = text.indexOf('}', pos);\n if (closeBrace === -1) {\n throw new SyntaxError(`Missing closing brace in pattern: ${text}`);\n }\n\n const captureContent = text.substring(pos + 1, closeBrace);\n const colonIndex = captureContent.indexOf(':');\n\n let variableName: string;\n let constraint: string;\n\n if (colonIndex !== -1) {\n // Has constraint: {varname:constraint}\n variableName = captureContent.substring(0, colonIndex);\n constraint = captureContent.substring(colonIndex + 1);\n } else {\n // No constraint: {varname} - default to match anything except separator\n variableName = captureContent;\n constraint = '[^/]*';\n }\n\n // Handle {*varname} syntax for capture-all\n if (variableName.startsWith('*')) {\n variableName = variableName.substring(1);\n constraint = '.*';\n }\n\n variableNames.push(variableName);\n patternBuilder.push('(', constraint, ')');\n\n pos = closeBrace + 1;\n } else if (ch === '*') {\n // Wildcard - match anything except separator\n wildcardCount++;\n patternBuilder.push('[^/]*');\n pos++;\n } else if (ch === '?') {\n // Single character wildcard\n patternBuilder.push('.');\n pos++;\n } else if ('.+()[]^$|\\\\'.includes(ch)) {\n // Escape regex special characters\n patternBuilder.push('\\\\', ch);\n pos++;\n } else {\n patternBuilder.push(ch);\n pos++;\n }\n }\n\n const patternString = patternBuilder.join('');\n const flags = this.#caseSensitive ? 's' : 'si';\n\n return [new RegExp(`^${patternString}$`, flags), wildcardCount, variableNames];\n }\n\n matches(pathIndex: number, matchingContext: MatchingContext): boolean {\n const textToMatch = matchingContext.pathElementValue(pathIndex);\n const match = this.#pattern.exec(textToMatch);\n let matches = match !== null && match.index === 0 && match[0].length === textToMatch.length;\n if (matches) {\n if (this.noMorePattern()) {\n if (matchingContext.determinedRemainingPath && (this.#variableNames.length === 0 || textToMatch.length !== 0)) {\n matchingContext.remainingPathIndex = pathIndex + 1;\n matches = true;\n }\n else {\n // no more pattern, is there more data?\n // if pattern is capturing variables there must be some actual data to bind to them\n matches = (pathIndex + 1 >= matchingContext.pathLength) &&\n (this.#variableNames.length === 0 || textToMatch.length !== 0);\n }\n }\n else {\n matches = (this.next !== undefined && this.next.matches(pathIndex + 1, matchingContext));\n }\n }\n\n if (matches && matchingContext.extractingVariables) {\n // process captures\n if (this.#variableNames.length + 1 !== match?.length) {\n throw new Error(`The number of capturing groups in the pattern segment\n ${this.#pattern} does not match the number of variables it defines, which can occur if capturing groups are used in the regex itself. Use non-capturing groups (?:...) instead.`);\n }\n for (let i = 1; i < match.length; i++) {\n const name = this.#variableNames[i - 1];\n const value = match[i];\n matchingContext.set(\n name,\n value,\n (i == this.#variableNames.length) ? (matchingContext.pathElements[pathIndex] as PathSegment).parameters : PathElement.NO_PARAMETERS)\n }\n }\n return matches;\n }\n\n get variableNames(): readonly string[] {\n return this.#variableNames;\n }\n\n get normalizedLength() {\n let varsLength = 0;\n for (const name of this.#variableNames) {\n varsLength += name.length;\n }\n return (this.#regex.length - varsLength - this.#variableNames.length);\n }\n\n get chars(): Uint16Array {\n return this.#regex;\n }\n\n get captureCount() {\n return this.#variableNames.length;\n }\n\n get wildcardCount() {\n return this.#wildcardCount;\n }\n\n get score() {\n return this.captureCount * PathElement.CAPTURE_VARIABLE_WEIGHT + this.wildcardCount * PathElement.WILDCARD_WEIGHT;\n }\n\n toString() {\n return `Regex(${String.fromCharCode(...(this.#regex))})`;\n }\n\n\n}\n", "import { PathElement } from './path-element.ts';\nimport { MatchingContext } from '../path-pattern.ts';\nimport { isPathSegment } from '../../../../http/server/path.ts';\n\nexport class LiteralPathElement extends PathElement {\n readonly #text: string;\n readonly #len: number;\n readonly #caseSensitive: boolean;\n\n constructor(pos: number, literalText: Uint16Array, caseSensitive: boolean, separator: number) {\n super(pos, separator);\n this.#len = literalText.length;\n this.#caseSensitive = caseSensitive;\n this.#text = String.fromCharCode(...(literalText));\n }\n\n matches(pathIndex: number, matchingContext: MatchingContext): boolean {\n if (pathIndex >= matchingContext.pathLength) {\n // no more path to match\n return false;\n }\n const pathSegment = matchingContext.pathElements[pathIndex];\n if (!isPathSegment(pathSegment)) {\n return false;\n }\n const value = pathSegment.valueToMatch;\n if (value.length !== this.#len) {\n // not enough data to match this path element\n return false;\n }\n\n if (this.#caseSensitive) {\n if (this.#text !== value) {\n return false;\n }\n }\n else {\n if (this.#text.toLowerCase() !== value.toLowerCase()) {\n return false;\n }\n }\n\n pathIndex++;\n if (this.noMorePattern()) {\n if (matchingContext.determinedRemainingPath) {\n matchingContext.remainingPathIndex = pathIndex;\n return true;\n }\n else {\n return (pathIndex === matchingContext.pathLength);\n }\n }\n else {\n return this.next!.matches(pathIndex, matchingContext);\n }\n }\n\n get normalizedLength(): number {\n return this.#len;\n }\n\n get chars(): Uint16Array {\n const arr = new Uint16Array(this.#len);\n for (let i = 0; i < this.#len; i++) {\n arr[i] = this.#text.charCodeAt(i);\n }\n return arr;\n }\n\n get literal() {\n return true;\n }\n\n toString(): string {\n return `Literal(${this.#text})`;\n }\n\n}\n", "import { PathPatternParser } from '../path-pattern-parser.ts';\nimport { PathPattern } from '../path-pattern.ts';\nimport { PathElement } from './path-element.ts';\nimport { SeparatorPathElement } from './separator-path-element.ts';\nimport { WildcardPathElement } from './wildcard-path-element.ts';\nimport { CaptureSegmentsPathElement } from './capture-segments-path-element.ts';\nimport { PatternParseError } from '../pattern-parse-error.ts';\nimport { WildcardSegmentsPathElement } from './wildcard-segments-path-element.ts';\nimport { CaptureVariablePathElement } from './capture-variable-path-element.ts';\nimport { SingleCharWildcardedPathElement } from './single-char-wildcarded-path-element.ts';\nimport { RegexPathElement } from './regex-path-element.ts';\nimport { LiteralPathElement } from './literal-path-element.ts';\n\nfunction isJavaScriptIdentifierStartChar(ch: number) {\n return (ch === 36 || ch === 95 || // $ and _\n (ch >= 65 && ch <= 90) || // A..Z\n (ch >= 97 && ch <= 122)); // a..z;\n}\n\n\nfunction isJavaScriptIdentifierPartChar(ch: number) {\n return (ch === 36 || ch === 95 || // $ and _\n (ch >= 65 && ch <= 90) || // A..Z\n (ch >= 97 && ch <= 122) || // a..z;\n (ch >= 48 && ch <= 57)); // 0..9;\n}\n\n/*internal*/ export class InternalPathPatternParser {\n readonly #parser: PathPatternParser;\n\n // the input data for parsing\n #pathPatternData: Uint16Array = new Uint16Array(0);\n // the length of the input data\n #pathPatternLength: number = 0;\n // current parsing position\n #pos: number = 0;\n // how many ? characters in a particular path element\n #singleCharWildcardCount: number = 0;\n // is the path pattern using * characters in a particular path element\n #wildcard: boolean = false;\n // is the construct {*...} being used in a particular path element\n #isCaptureSegmentsVariable: boolean = false;\n // has the parser entered a {...} capture variable block in a particular path element\n #insideVariableCapture: boolean = false;\n // how many variable captures are occurring in a particular path element\n #variableCaptureCount: number = 0;\n // start of the most recent path element in a particular path element\n #pathElementStart: number = 0;\n // start of the most recent variable capture in a particular path element\n #variableCaptureStart: number = 0;\n // did we parse a WildcardSegments(**) or CaptureSegments({*foo}) PathElement already?\n #hasMultipleSegmentsElements: boolean = false;\n // variables captured in this path pattern\n #capturedVariableNames?: string[];\n // the head of the path element chain currently being built\n #headPE?: PathElement;\n // the most recently constructed path element in the chain\n #currentPE?: PathElement;\n\n constructor(parser: PathPatternParser) {\n this.#parser = parser;\n }\n\n parse(pathPattern: string): PathPattern {\n if (pathPattern === undefined || pathPattern === null) throw new TypeError(`pathPattern must be defined`);\n\n this.#pathPatternData = new Uint16Array(pathPattern.length);\n for (let i = 0; i < pathPattern.length; i++) {\n this.#pathPatternData[i] = pathPattern.charCodeAt(i);\n }\n this.#pathPatternLength = this.#pathPatternData.length;\n this.#headPE = undefined;\n this.#currentPE = undefined;\n this.#capturedVariableNames = undefined;\n this.#pathElementStart = -1;\n this.#pos = 0;\n this.#resetPathElementState();\n\n while (this.#pos < this.#pathPatternLength) {\n const ch = this.#pathPatternData[this.#pos];\n const separator = this.#parser.pathOptions.separator;\n if (ch === separator) {\n if (this.#pathElementStart !== -1) {\n this.#pushPathElement(this.#createPathElement());\n }\n this.#pushPathElement(new SeparatorPathElement(this.#pos, separator));\n }\n else {\n if (this.#pathElementStart === -1) {\n this.#pathElementStart = this.#pos;\n }\n if (ch === '?'.charCodeAt(0)) {\n this.#singleCharWildcardCount++;\n }\n else if (ch === '{'.charCodeAt(0)) {\n if (this.#insideVariableCapture) {\n throw PatternParseError.create(this.#pos, this.#pathPatternData, 'ILLEGAL_NESTED_CAPTURE');\n }\n // if we enforced that adjacent captures weren't allowed,\n // this would do it (this would be and error: /foo/{bar}{boo}/)\n // } else if (this.#pos > 0 && this.#pathPatternData[this.#pos - 1] === '}'.charCodeAt(0)) {\n // throw new PatternParseError(this.#pos, this.#pathPatternData, PatternMessage.CANNOT_HAVE_ADJACENT_CAPTURES);\n // }\n this.#insideVariableCapture = true;\n this.#variableCaptureStart = this.#pos;\n }\n else if (ch === '}'.charCodeAt(0)) {\n if (!this.#insideVariableCapture) {\n throw PatternParseError.create(this.#pos, this.#pathPatternData, 'MISSING_OPEN_CAPTURE');\n }\n this.#insideVariableCapture = false;\n this.#variableCaptureCount++;\n }\n else if (ch === ':'.charCodeAt(0)) {\n if (this.#insideVariableCapture && !this.#isCaptureSegmentsVariable) {\n this.#skipCaptureRegex();\n this.#insideVariableCapture = false;\n this.#variableCaptureCount++;\n }\n }\n else if (this.#isDoubleWildcard(separator)) {\n this.#checkValidMultipleSegmentsElements(this.#pos, this.#pos + 1);\n this.#pushPathElement(new WildcardSegmentsPathElement(this.#pos, separator));\n this.#hasMultipleSegmentsElements = true;\n this.#pos++;\n }\n else if (ch === '*'.charCodeAt(0)) {\n if (this.#insideVariableCapture && this.#variableCaptureStart == this.#pos - 1) {\n this.#isCaptureSegmentsVariable = true;\n }\n this.#wildcard = true;\n }\n if (this.#insideVariableCapture) {\n if ((this.#variableCaptureStart + 1 + (this.#isCaptureSegmentsVariable ? 1 : 0)) === this.#pos &&\n !isJavaScriptIdentifierStartChar(ch)) {\n throw PatternParseError.create(this.#pos, this.#pathPatternData, 'ILLEGAL_CHARACTER_AT_START_OF_CAPTURE_DESCRIPTOR', String.fromCharCode(ch));\n }\n else if ((this.#pos > (this.#variableCaptureStart + 1 + (this.#isCaptureSegmentsVariable ? 1 : 0)) &&\n !isJavaScriptIdentifierPartChar(ch) && ch !== '-'.charCodeAt(0))) {\n throw PatternParseError.create(this.#pos, this.#pathPatternData, 'ILLEGAL_CHARACTER_IN_CAPTURE_DESCRIPTOR', String.fromCharCode(ch));\n }\n }\n }\n this.#pos++;\n }\n if (this.#pathElementStart !== -1) {\n this.#pushPathElement(this.#createPathElement());\n }\n return new PathPattern(pathPattern, this.#parser, this.#headPE);\n }\n\n #getPathElementText(): Uint16Array {\n const pathElementText = new Uint16Array(this.#pos - this.#pathElementStart);\n let index = 0;\n for (let i = this.#pathElementStart; i < this.#pos; i++) {\n pathElementText[index++] = this.#pathPatternData[i];\n }\n return pathElementText;\n }\n\n #createPathElement(): PathElement {\n if (this.#insideVariableCapture) {\n throw PatternParseError.create(this.#pos, this.#pathPatternData, 'MISSING_CLOSE_CAPTURE');\n }\n\n let newPE: PathElement = undefined!;\n const separator = this.#parser.pathOptions.separator;\n\n if (this.#variableCaptureCount > 0) {\n if (this.#variableCaptureCount === 1 && this.#pathElementStart === this.#variableCaptureStart &&\n this.#pathPatternData[this.#pos - 1] === '}'.charCodeAt(0)) {\n if (this.#isCaptureSegmentsVariable) {\n // It is {*....}\n this.#checkValidMultipleSegmentsElements(this.#pathElementStart, this.#pos - 1);\n this.#hasMultipleSegmentsElements = true;\n newPE = new CaptureSegmentsPathElement(this.#pathElementStart, this.#getPathElementText(), separator);\n }\n else {\n // It is a full capture of this element (possibly with constraint), for example: /foo/{abc}/\n try {\n newPE = new CaptureVariablePathElement(this.#pathElementStart, this.#getPathElementText(), this.#parser.caseSensitive, separator);\n }\n catch (err) {\n if (err instanceof SyntaxError) {\n throw PatternParseError.createWithCause(err,\n this.#findRegExpStart(this.#pathPatternData, this.#pathElementStart) + (err['index'] ?? 0),\n this.#pathPatternData, 'REGEX_PATTERN_SYNTAX_EXCEPTION');\n }\n throw err;\n }\n this.#recordCapturedVariable(this.#pathElementStart, (newPE as CaptureVariablePathElement).variableName);\n }\n }\n else {\n if (this.#isCaptureSegmentsVariable) {\n throw PatternParseError.create(this.#pathElementStart, this.#pathPatternData, 'CAPTURE_ALL_IS_STANDALONE_CONSTRUCT');\n }\n const newRegexPE = new RegexPathElement(\n this.#pathElementStart,\n this.#getPathElementText(),\n this.#parser.caseSensitive,\n this.#pathPatternData, separator\n );\n for (const variableName of newRegexPE.variableNames) {\n this.#recordCapturedVariable(this.#pathElementStart, variableName);\n }\n newPE = newRegexPE;\n }\n }\n else {\n if (this.#wildcard) {\n if (this.#pos - 1 === this.#pathElementStart) {\n newPE = new WildcardPathElement(this.#pathElementStart, separator);\n }\n else {\n newPE = new RegexPathElement(\n this.#pathElementStart,\n this.#getPathElementText(),\n this.#parser.caseSensitive,\n this.#pathPatternData,\n separator\n );\n }\n }\n else if (this.#singleCharWildcardCount !== 0) {\n newPE = new SingleCharWildcardedPathElement(\n this.#pathElementStart,\n this.#getPathElementText(),\n this.#singleCharWildcardCount,\n this.#parser.caseSensitive,\n separator\n );\n }\n else {\n newPE = new LiteralPathElement(\n this.#pathElementStart,\n this.#getPathElementText(),\n this.#parser.caseSensitive,\n separator\n );\n }\n }\n\n return newPE;\n }\n\n #skipCaptureRegex() {\n this.#pos++;\n const regexStartPos = this.#pos;\n let curlyBracketDepth = 0; // how deep in nested {...} pairs we are\n let previousBackslash = false;\n\n while (this.#pos < this.#pathPatternLength) {\n const ch = this.#pathPatternData[this.#pos];\n if (ch === '\\\\'.charCodeAt(0) && !previousBackslash) {\n this.#pos++;\n previousBackslash = true;\n continue;\n }\n if (ch === '{'.charCodeAt(0) && !previousBackslash) {\n curlyBracketDepth++;\n }\n else if (ch === '}'.charCodeAt(0) && !previousBackslash) {\n if (curlyBracketDepth === 0) {\n if (regexStartPos == this.#pos) {\n throw PatternParseError.create(this.#pos, this.#pathPatternData, 'MISSING_REGEX_CONSTRAINT');\n }\n return;\n }\n curlyBracketDepth--;\n }\n if (ch == this.#parser.pathOptions.separator && !previousBackslash) {\n throw PatternParseError.create(this.#pos, this.#pathPatternData, 'MISSING_CLOSE_CAPTURE');\n }\n this.#pos++;\n previousBackslash = false;\n }\n throw PatternParseError.create(this.#pos - 1, this.#pathPatternData, 'MISSING_CLOSE_CAPTURE');\n }\n\n #isDoubleWildcard(separator: number): boolean {\n // next char is present\n if ((this.#pos + 1) >= this.#pathPatternLength) {\n return false;\n }\n // current char and next char are '*'\n if (this.#pathPatternData[this.#pos] !== '*'.charCodeAt(0) ||\n this.#pathPatternData[this.#pos + 1] !== '*'.charCodeAt(0)) {\n return false;\n }\n // previous char is separator, if any\n if ((this.#pos - 1 >= 0) && (this.#pathPatternData[this.#pos - 1] !== separator)) {\n return false;\n }\n // next char is separator, if any\n if ((this.#pos + 2 < this.#pathPatternLength) &&\n (this.#pathPatternData[this.#pos + 2] !== separator)) {\n return false;\n }\n return true;\n }\n\n #checkValidMultipleSegmentsElements(startPos: number, endPos: number) {\n if (this.#hasMultipleSegmentsElements) {\n throw PatternParseError.create(this.#pos, this.#pathPatternData, 'CANNOT_HAVE_MANY_MULTISEGMENT_PATH_ELEMENTS');\n }\n if (startPos > 1 && endPos !== (this.#pathPatternLength - 1)) {\n throw PatternParseError.create(this.#pos, this.#pathPatternData, 'INVALID_LOCATION_FOR_MULTISEGMENT_PATH_ELEMENT');\n }\n }\n\n #pushPathElement(newPathElement: PathElement) {\n if (newPathElement instanceof CaptureSegmentsPathElement ||\n newPathElement instanceof WildcardSegmentsPathElement) {\n // there must be a separator ahead of this thing\n // currentPE SHOULD be a SeparatorPathElement\n if (this.#currentPE === undefined) {\n this.#headPE = newPathElement;\n this.#currentPE = newPathElement;\n }\n else if (this.#currentPE instanceof SeparatorPathElement) {\n const peBeforeSeparator = this.#currentPE.prev;\n if (peBeforeSeparator === undefined) {\n // {*foo} is at the start\n this.#headPE = newPathElement;\n newPathElement.prev = undefined;\n }\n else {\n peBeforeSeparator.next = newPathElement;\n newPathElement.prev = peBeforeSeparator;\n }\n this.#currentPE = newPathElement;\n }\n else {\n throw new Error(`expected SeparatorPathElement before ${newPathElement} but was ${this.#currentPE}`);\n }\n }\n else {\n if (this.#headPE === undefined) {\n this.#headPE = newPathElement;\n this.#currentPE = newPathElement;\n }\n else if (this.#currentPE !== undefined) {\n this.#currentPE.next = newPathElement;\n newPathElement.prev = this.#currentPE;\n this.#currentPE = newPathElement;\n }\n }\n\n this.#resetPathElementState();\n }\n\n #findRegExpStart(data: Uint16Array, offset: number): number {\n let pos = offset;\n while (pos < data.length) {\n if (data[pos] === ':'.charCodeAt(0)) {\n return pos + 1;\n }\n pos++;\n }\n return -1;\n }\n\n #resetPathElementState() {\n this.#pathElementStart = -1;\n this.#singleCharWildcardCount = 0;\n this.#insideVariableCapture = false;\n this.#variableCaptureCount = 0;\n this.#wildcard = false;\n this.#isCaptureSegmentsVariable = false;\n this.#variableCaptureStart = -1;\n }\n\n #recordCapturedVariable(pos: number, variableName: string) {\n if (this.#capturedVariableNames === undefined) {\n this.#capturedVariableNames = [];\n }\n if (this.#capturedVariableNames?.find(v => v === variableName) !== undefined) {\n throw PatternParseError.create(pos, this.#pathPatternData, 'ILLEGAL_DOUBLE_CAPTURE', variableName);\n }\n this.#capturedVariableNames.push(variableName);\n }\n}\n", "import { HTTP_OPTIONS, type Options } from '../../../http/server/path.ts';\nimport type { PathPattern } from './path-pattern.ts';\n\nimport { InternalPathPatternParser } from './internal/path-pattern-parser.ts';\n\nexport class PathPatternParser {\n #caseSensitive: boolean = true;\n #pathOptions: Options = HTTP_OPTIONS;\n\n get caseSensitive(): boolean {\n return this.#caseSensitive;\n }\n set caseSensitive(value: boolean) {\n this.#caseSensitive = value;\n }\n\n get pathOptions(): Options {\n return this.#pathOptions;\n }\n set pathOptions(value: Options) {\n this.#pathOptions = value;\n }\n\n public initFullPathPattern(pattern: string): string {\n return (pattern && !pattern.startsWith('/') ? '/' + pattern : pattern);\n }\n\n parse(pathPattern: string): PathPattern {\n return new InternalPathPatternParser(this).parse(pathPattern);\n }\n\n static readonly DEFAULT: PathPatternParser = new class extends PathPatternParser {\n override get caseSensitive(): boolean {\n return super.caseSensitive;\n }\n override set caseSensitive(_value: boolean) {\n this.#raiseError();\n }\n override get pathOptions(): Options {\n return super.pathOptions;\n }\n override set pathOptions(_value: Options) {\n this.#raiseError();\n }\n\n #raiseError(): never {\n throw new Error('PathPatternParser.DEFAULT is immutable');\n }\n };\n}\n", "import type { HttpMethod } from '../../../../../types/web/http';\nimport { isPreFlightRequest } from '../../../cors/utils.ts';\nimport type { HandlerFunction, RouterFunction, ServerRequest, ServerRequestHeaders, ServerResponse } from './types.ts';\nimport { MediaType, sortBySpecificity } from '../../../../http/media-type.ts';\nimport getLogger from '../../../../logger.ts';\nimport { PathPatternParser } from '../../../util/pattern/path-pattern-parser.ts';\nimport type { MIMEType } from 'node:util';\nimport { isCompatibleWith } from '../../../../utils/mime-type-utils.ts';\n\nexport type RequestPredicate = {\n test(request: ServerRequest): boolean;\n and(other: RequestPredicate): RequestPredicate;\n or(other: RequestPredicate): RequestPredicate;\n negate(): RequestPredicate;\n toString(): string;\n};\n\nconst logger = getLogger('web.async.fn.router');\n\nexport const REQUEST_ATTRIBUTE = 'io.interop.web.async.fn.router.request';\nexport const URI_VARIABLES_ATTRIBUTE = 'io.interop.web.async.fn.router.variables';\nexport const MATCHING_PATTERN_ATTRIBUTE = 'io.interop.web.async.fn.router.pattern';\n\nfunction routerFunction<T extends ServerResponse>(route: RouterFunction<T>['route']): RouterFunction<T> {\n const result: RouterFunction<T> = {\n route: route,\n and: <T2 extends ServerResponse>(other: RouterFunction<T2>) => and(result, other)\n };\n return result;\n}\n\nfunction and<T1 extends ServerResponse, T2 extends ServerResponse>(first: RouterFunction<T1>, second: RouterFunction<T2>): RouterFunction<T1 | T2> {\n return routerFunction<T1 | T2>(async (request) => {\n const handler = first.route(request);\n if (handler !== undefined) {\n return handler;\n }\n return second.route(request);\n });\n}\n\nexport function route<T extends ServerResponse>(predicate: RequestPredicate, handlerFunction: HandlerFunction<T>): RouterFunction<T> {\n\n return routerFunction<T>(async (request: ServerRequest) => {\n if (predicate.test(request)) {\n if (logger.enabledFor(`trace`)) {\n const logPrefix = request.exchange.logPrefix;\n logger.debug(`${logPrefix}Matched ${predicate}`);\n }\n return handlerFunction;\n }\n else {\n return; // undefined\n }\n });\n}\n\nexport const predicates: {\n all: () => RequestPredicate;\n method: (method: HttpMethod) => RequestPredicate;\n methods: (...methods: HttpMethod[]) => RequestPredicate;\n path: (pattern: string) => RequestPredicate;\n pathPredicates: (patternParser: PathPatternParser)=> ((pattern: string) => RequestPredicate);\n headers: (predicate: (headers: ServerRequestHeaders) => boolean) => RequestPredicate;\n accept: (...mediaTypes: MIMEType[]) => RequestPredicate;\n GET: (pattern: string) => RequestPredicate;\n HEAD: (pattern: string) => RequestPredicate;\n POST: (pattern: string) => RequestPredicate;\n PUT: (pattern: string) => RequestPredicate;\n PATCH: (pattern: string) => RequestPredicate;\n DELETE: (pattern: string) => RequestPredicate;\n OPTIONS: (pattern: string) => RequestPredicate;\n queryParam: (name: string, valueOrPredicate: string | ((value: string) => boolean)) => RequestPredicate;\n} = function () {\n const logger = getLogger('request.predicates');\n\n function requestMethod(request: ServerRequest): HttpMethod {\n if (isPreFlightRequest(request.exchange.request)) {\n const accessControlRequestMethod = request.headers.firstHeader('Access-Control-Request-Method');\n if (accessControlRequestMethod !== undefined) {\n return accessControlRequestMethod.toUpperCase() as HttpMethod;\n }\n }\n return request.method;\n }\n\n function requestPredicate(predicate: (request: ServerRequest) => boolean): RequestPredicate {\n const result: RequestPredicate = {\n test: predicate,\n and: (other: RequestPredicate) => and(result, other),\n negate: () => negate(result),\n or: (other: RequestPredicate) => or(result, other),\n toString: () => predicate.toString(),\n };\n return result;\n }\n\n function and(first: RequestPredicate, other: RequestPredicate): RequestPredicate {\n return requestPredicate((request: ServerRequest) => first.test(request) && other.test(request));\n }\n\n function or(first: RequestPredicate, other: RequestPredicate): RequestPredicate {\n const orRequestPredicate = requestPredicate((request: ServerRequest) => first.test(request) || other.test(request));\n orRequestPredicate.toString = () => `(${first} || ${other})`;\n return orRequestPredicate;\n }\n function negate(delegate: RequestPredicate): RequestPredicate {\n const negateRequestPredicate = requestPredicate((request: ServerRequest) => !delegate.test(request));\n negateRequestPredicate.toString = () => `!${delegate}`;\n return negateRequestPredicate;\n }\n function method(httpMethod: HttpMethod): RequestPredicate {\n const singleHttpMethodPredicate = (request: ServerRequest) => {\n const method = requestMethod(request);\n const match = httpMethod === method;\n traceMatch('Method', httpMethod, method, match);\n return match;\n };\n singleHttpMethodPredicate.toString = () => `${httpMethod}`;\n return requestPredicate(singleHttpMethodPredicate)\n }\n function methods(...methods: HttpMethod[]): RequestPredicate {\n if (!methods) {\n throw new Error('At least one HTTP method must be provided');\n }\n if (methods.length === 1) {\n return method(methods[0]);\n }\n const httpMethods = new Set(...methods);\n const multipleHttpMethodsPredicate = (request: ServerRequest) => {\n const method = requestMethod(request);\n const match = httpMethods.has(method);\n traceMatch('Method', `[${[...httpMethods].join(', ')}]`, method, match);\n return match;\n }\n multipleHttpMethodsPredicate.toString = () => `[${methods.join(', ')}]`;\n return requestPredicate(multipleHttpMethodsPredicate);\n }\n function path(pattern: string): RequestPredicate {\n const parser = PathPatternParser.DEFAULT;\n pattern = parser.initFullPathPattern(pattern);\n return pathPredicates(parser)(pattern);\n }\n\n function pathPredicates(patternParser: PathPatternParser) {\n return (pattern: string): RequestPredicate => {\n const pathPattern = patternParser.parse(pattern);\n const pathPatternPredicate = (request: ServerRequest) => {\n const pathContainer = request.requestPath.pathWithinApplication;\n const info = pathPattern.matchAndExtract(pathContainer);\n traceMatch('Pattern', pathPattern.patternString, pathContainer.value, info !== undefined);\n if (info !== undefined) {\n\n // todo modify attributes\n return true;\n }\n else {\n return false;\n }\n };\n pathPatternPredicate.toString = () => pathPattern.patternString;\n return requestPredicate(pathPatternPredicate);\n }\n }\n function traceMatch(prefix: string, desired: unknown, actual: unknown, match: boolean) {\n if (logger.enabledFor('trace')) {\n logger.debug(`${prefix} \"${desired}\" ${match ? 'matches' : 'does not match'} against value \"${actual}\"`);\n }\n }\n\n function headers(headersPredicate: (headers: ServerRequestHeaders) => boolean): RequestPredicate {\n const result = (request: ServerRequest) => {\n if (isPreFlightRequest(request.exchange.request)) {\n return true;\n }\n else {\n return headersPredicate(request.headers);\n }\n };\n result.toString = () => headersPredicate.toString();\n return requestPredicate(result);\n }\n\n function accept(...mediaTypes: MIMEType[]) {\n if (!mediaTypes) {\n throw new Error('mediaTypes must not be empty');\n }\n\n function acceptedMediaTypes(headers: ServerRequestHeaders) {\n let acceptedMediaTypes = headers.accept();\n if (acceptedMediaTypes.length === 0) {\n acceptedMediaTypes = [MediaType.ALL];\n }\n else {\n sortBySpecificity(acceptedMediaTypes);\n }\n return acceptedMediaTypes;\n }\n\n if (mediaTypes.length === 1) {\n const mediaType = mediaTypes[0];\n const singleAcceptPredicate = (headers: ServerRequestHeaders) => {\n const accepted = acceptedMediaTypes(headers);\n let match = false;\n for (const acceptedMediaType of accepted) {\n if (isCompatibleWith(acceptedMediaType, mediaType)) {\n match = true;\n break;\n }\n }\n traceMatch('Accept', mediaType, accepted, match);\n return match;\n };\n singleAcceptPredicate.toString = () => `Accept: ${mediaType}`;\n return headers(singleAcceptPredicate);\n }\n else {\n const multipleAcceptsPredicate = (headers: ServerRequestHeaders) => {\n const accepted = acceptedMediaTypes(headers);\n let match = false;\n outer:\n for (const acceptedMediaType of accepted) {\n for (const mediaType of mediaTypes) {\n if (isCompatibleWith(acceptedMediaType, mediaType)) {\n match = true;\n break outer;\n }\n }\n }\n traceMatch('Accept', mediaTypes, accepted, match);\n return match;\n }\n multipleAcceptsPredicate.toString = () => `Accept: ${mediaTypes.join(', ')}`;\n return headers(multipleAcceptsPredicate)\n }\n }\n\n function queryParam(name: string, valueOrPredicate: string | ((value: string) => boolean)): RequestPredicate {\n const value = typeof valueOrPredicate === 'string' ? valueOrPredicate : undefined;\n const predicate = typeof valueOrPredicate === 'string' ? (v: string) => v === value : valueOrPredicate;\n const queryParamPredicate = (request: ServerRequest) => {\n const s = request.queryParam(name);\n return s !== null && s !== undefined && predicate(s);\n };\n\n queryParamPredicate.toString = () => {\n return `?${name} ${valueOrPredicate}`;\n };\n return requestPredicate(queryParamPredicate);\n }\n\n\n return {\n all: () => requestPredicate((request) => true),\n method,\n methods,\n path,\n pathPredicates,\n headers,\n accept,\n GET: (pattern: string) => method('GET').and(path(pattern)),\n HEAD: (pattern: string) => method('HEAD').and(path(pattern)),\n POST: (pattern: string) => method('POST').and(path(pattern)),\n PUT: (pattern: string) => method('PUT').and(path(pattern)),\n PATCH: (pattern: string) => method('PATCH').and(path(pattern)),\n DELETE: (pattern: string) => method('DELETE').and(path(pattern)),\n OPTIONS: (pattern: string) => method('OPTIONS').and(path(pattern)),\n queryParam,\n }\n}();\n", "import type { ErrorResponse } from '../../../error.ts';\nimport type {\n BodyChunk,\n HttpOutputMessage,\n HttpStatusCode,\n MutableHttpHeaders,\n ResponseCookie\n} from '../../../../../types/web/http';\nimport type { ServerHttpResponse, ServerWebExchange } from '../../../../../types/web/server';\nimport { getContentType, MapHttpHeaders } from '../../../../http/headers.ts';\nimport { HttpStatus, httpStatusCode } from '../../../../http/status.ts';\nimport type { ServerResponse, ServerResponseContext } from './types.ts';\nimport type { BodyInserter, BodyInserterContext } from '../types.ts';\nimport { MIMEType } from 'node:util';\nimport { LOG_PREFIX_HINT } from '../../../../codec/hints.ts';\n\nexport async function from(response: ErrorResponse) {\n return status(response.statusCode)\n .headers(headers => {\n for (const name of response.headers.keys()) {\n headers.add(name, response.headers.list(name));\n }\n })\n .bodyValue(response.body);\n}\n\nfunction status(status: HttpStatusCode | number): BodyBuilder {\n status = typeof status === 'number' ? httpStatusCode(status) : status;\n return new DefaultServerResponseBuilder(status);\n}\n\nfunction ok() {\n return status(HttpStatus.OK);\n}\n\nfunction created(location: URL) {\n const builder = status(HttpStatus.CREATED);\n return builder.location(location);\n}\n\nexport default {\n from,\n status,\n ok,\n created,\n}\n\nexport interface HeadersBuilder {\n headers(consumer: (headers: MutableHttpHeaders) => void): this;\n\n location(location: URL): this;\n\n build(): Promise<ServerResponse>\n\n build(writeFunction: (exchange: ServerWebExchange, context: ServerResponseContext) => Promise<void>): Promise<ServerResponse>\n}\n\nexport interface BodyBuilder extends HeadersBuilder {\n contentLength(length: number): this;\n contentType(contentType: MIMEType): this;\n bodyValue(body: unknown): Promise<ServerResponse>;\n}\n\nfunction writeWithMessageWriters(message: HttpOutputMessage<MutableHttpHeaders>,\n context: BodyInserterContext,\n promise: Promise<Awaited<ArrayBufferView<ArrayBuffer> | ArrayBuffer | Blob | string>>,\n bodyType) {\n const mediaType = getContentType(message.headers);\n for (const writer of context.messageWriters) {\n if (writer.canWrite(bodyType, mediaType)) {\n return writer.write(promise, bodyType, message, mediaType);\n }\n }\n return Promise.reject(new Error(`No HttpMessageWriter found for body type ${bodyType} and media type ${mediaType}`));\n}\n\nfunction bodyFromValue<T>(body: BodyChunk): BodyInserter<T> {\n return async (message: HttpOutputMessage<MutableHttpHeaders>, context: BodyInserterContext) => {\n return writeWithMessageWriters(message, context, Promise.resolve(body), typeof body);\n }\n}\n\nclass DefaultServerResponseBuilder implements BodyBuilder {\n readonly #statusCode: HttpStatusCode;\n readonly #headers: MutableHttpHeaders = new MapHttpHeaders();\n readonly #cookies: Map<string, ResponseCookie[]> = new Map();\n readonly #hints: Map<string, unknown> = new Map();\n\n constructor(statusCode: HttpStatusCode) {\n this.#statusCode = statusCode;\n }\n\n header(headerName: string, ...headerValues: string[]): this {\n for (const headerValue of headerValues) {\n this.#headers.add(headerName, headerValue);\n }\n return this;\n }\n\n cookie(cookie: ResponseCookie): this {\n const cookies = this.#cookies.get(cookie.name) ?? [];\n cookies.push(cookie);\n this.#cookies.set(cookie.name, cookies);\n return this;\n }\n\n headers(consumer: (headers: MutableHttpHeaders) => void): this {\n consumer(this.#headers);\n return this;\n }\n\n contentType(contentType: MIMEType): this {\n this.#headers.set('Content-Type', contentType.toString());\n return this;\n }\n\n contentLength(length: number): this {\n this.#headers.set('Content-Length', length.toString());\n return this;\n }\n\n location(location: URL | undefined): this {\n this.#headers.set('Location', location?.href);\n return this;\n }\n\n bodyValue(body: BodyChunk): Promise<ServerResponse> {\n return this.#initEntityResponse(body, bodyFromValue(body));\n }\n\n #initEntityResponse<T>(entity: T, inserter: BodyInserter<T>): Promise<ServerResponse> {\n return Promise.resolve(new DefaultEntityResponse<T>(this.#statusCode, this.#headers, new Map(this.#cookies), entity, inserter, new Map(this.#hints)));\n }\n\n build(writeFunction?: (exchange: ServerWebExchange, context: ServerResponseContext) => Promise<void>): Promise<ServerResponse> {\n if (writeFunction) {\n return Promise.resolve(new WriterFunctionServerResponse(this.#statusCode, this.#headers, this.#cookies, writeFunction));\n }\n else {\n return this.build(async (exchange, context) => {\n await exchange.response.end();\n });\n }\n }\n\n}\n\nexport abstract class AbstractServerResponse implements ServerResponse {\n readonly #statusCode: HttpStatusCode\n readonly #headers: MutableHttpHeaders\n readonly #cookies: Map<string, ResponseCookie[]>;\n\n /* internal */ readonly hints?: Map<string, unknown>;\n\n protected constructor(\n statusCode: HttpStatusCode,\n headers: MutableHttpHeaders,\n cookies: Map<string, ResponseCookie[]>,\n hints?: Map<string, unknown>\n ) {\n this.#statusCode = statusCode;\n this.#headers = headers;\n this.#cookies = cookies;\n this.hints = hints;\n }\n\n get statusCode() {\n return this.#statusCode;\n }\n\n get headers() {\n return this.#headers;\n }\n\n get cookies(): ResponseCookie[] {\n const allCookies: ResponseCookie[] = [];\n for (const cookieList of this.#cookies.values()) {\n allCookies.push(...cookieList);\n }\n return allCookies;\n }\n\n async writeTo(exchange: ServerWebExchange, context: ServerResponseContext): Promise<void> {\n this.#writeStatusAndHeaders(exchange.response);\n\n // todo check not modified\n\n return this.writeInternal(exchange, context);\n }\n\n #writeStatusAndHeaders(response: ServerHttpResponse) {\n response.setStatusCode(this.#statusCode);\n for (const name of this.#headers.keys()) {\n response.headers.add(name, this.#headers.list(name));\n }\n for (const cookieList of this.#cookies.values()) {\n for (const cookie of cookieList) {\n response.addCookie(cookie);\n }\n }\n }\n\n protected abstract writeInternal(exchange: ServerWebExchange, context: unknown): Promise<void>;\n}\n\nconst NO_HINTS = new Map<string, unknown>();\nclass WriterFunctionServerResponse extends AbstractServerResponse {\n readonly #writeFunction: (exchange: ServerWebExchange, context: ServerResponseContext) => Promise<void>;\n\n constructor(\n statusCode: HttpStatusCode,\n headers: MutableHttpHeaders,\n cookies: Map<string, ResponseCookie[]>,\n writeFunction: (exchange: ServerWebExchange, context: ServerResponseContext) => Promise<void>\n ) {\n super(statusCode, headers, cookies);\n this.#writeFunction = writeFunction;\n }\n\n protected async writeInternal(exchange: ServerWebExchange, context: ServerResponseContext): Promise<void> {\n await this.#writeFunction(exchange, context);\n }\n}\n\ninterface EntityResponse<T> extends ServerResponse {\n readonly entity: T;\n\n readonly inserter: BodyInserter<T>;\n\n readonly hints?: ReadonlyMap<string, unknown>;\n}\n\nclass DefaultEntityResponse<T> extends AbstractServerResponse implements EntityResponse<T> {\n readonly #entity: T;\n readonly #inserter: BodyInserter<T>;\n\n constructor(\n statusCode: HttpStatusCode,\n headers: MutableHttpHeaders,\n cookies: Map<string, ResponseCookie[]>,\n entity: T, inserter: BodyInserter<T>,\n hints: Map<string, unknown>) {\n super(statusCode, headers, cookies, hints);\n this.#entity = entity;\n this.#inserter = inserter;\n }\n\n get entity(): T {\n return this.#entity;\n }\n\n get inserter(): BodyInserter<T> {\n return this.#inserter;\n }\n\n protected async writeInternal(exchange: ServerWebExchange, { messageWriters }: ServerResponseContext): Promise<void> {\n\n this.hints?.set(LOG_PREFIX_HINT, exchange.logPrefix);\n await this.inserter(\n exchange.response,\n {\n messageWriters,\n serverRequest: exchange.request,\n hints: this.hints\n });\n }\n}\n", "import type { WebErrorHandler } from '../web/server/types.ts';\nimport type { ServerWebExchange } from '../../types/web/server';\nimport { HttpServerRequest, HttpServerResponse } from './exchange.ts';\nimport { isClientDisconnectedError } from '../web/util/client.ts';\nimport serverRequest from '../web/async/fn/server/request.ts';\nimport { route } from '../web/async/fn/server/router.ts';\nimport serverResponse from '../web/async/fn/server/response.ts';\nimport { MIMEType } from 'node:util';\nimport { HttpStatus } from '../http/status.ts';\nimport type { RouterFunction, ServerRequest, ServerResponse } from '../web/async/fn/server/types.ts';\nimport { predicates as r} from '../web/async/fn/server/router.ts';\nimport { ResponseStatusError } from '../web/server/error.ts';\nimport type { HttpMessageReader, HttpMessageWriter } from '../http/codec/types.ts';\nimport { ALL } from '../utils/mime-type-utils.ts';\n\nexport type ErrorAttributeKey = 'error' | 'trace' | 'message' | 'errors' | 'timestamp' | 'status' | 'reason' | 'requestId' | 'path';\n\nexport type ErrorAttributeOptions = {\n readonly includes: ReadonlyArray<ErrorAttributeKey>;\n}\n\nexport interface ErrorAttributes {\n getErrorAttributes(request: ServerRequest, options: ErrorAttributeOptions): Partial<Record<ErrorAttributeKey, unknown>>;\n\n getError(request: ServerRequest): Error;\n\n storeErrorInformation(error: Error, exchange: ServerWebExchange): void;\n}\n\nexport class DefaultErrorAttributes implements ErrorAttributes {\n static readonly ERROR_ATTRIBUTE = 'io.interop.web.server.exchange.error';\n\n getErrorAttributes(request: ServerRequest, options: ErrorAttributeOptions): Partial<Record<ErrorAttributeKey, unknown>> {\n const erroroAttributes = this.#getErrorAttributesInternal(request, options.includes.includes('trace'));\n return erroroAttributes;\n }\n\n getError(request: ServerRequest): Error {\n const error = request.attributes.get(DefaultErrorAttributes.ERROR_ATTRIBUTE);\n if (error === undefined) {\n throw new Error('No error found in request attributes');\n }\n return error as Error;\n }\n\n storeErrorInformation(error: Error, exchange: ServerWebExchange): void {\n exchange.attributes.set(DefaultErrorAttributes.ERROR_ATTRIBUTE, error);\n }\n\n #getErrorAttributesInternal(request: ServerRequest, includeStackTrace: boolean) {\n const errorAttributes: Partial<Record<ErrorAttributeKey, unknown>> = {};\n errorAttributes.timestamp = new Date();\n const error = this.getError(request);\n const errorStatus = this.#determineHttpStatus(error);\n errorAttributes.status = errorStatus.value;\n errorAttributes.reason = errorStatus.phrase;\n errorAttributes.requestId = request.exchange.request.id;\n\n this.#handleError(errorAttributes, error, includeStackTrace);\n return errorAttributes;\n\n }\n\n #determineHttpStatus(error: Error): HttpStatus {\n if (error instanceof ResponseStatusError) {\n const httpStatus = HttpStatus.resolve(error.statusCode.value);\n if (httpStatus) {\n return httpStatus;\n }\n }\n return HttpStatus.INTERNAL_SERVER_ERROR;\n }\n\n #handleError(errorAttributes: Partial<Record<ErrorAttributeKey, unknown>>, error: Error, includeStackTrace: boolean) {\n\n if (error instanceof ResponseStatusError) {\n errorAttributes.message = error.reason;\n }\n }\n}\n\nexport abstract class AbstractWebErrorHandler implements WebErrorHandler {\n\n readonly #errorAttributes: ErrorAttributes;\n readonly #messageReaders: readonly HttpMessageReader[];\n readonly #messageWriters: readonly HttpMessageWriter[];\n\n protected constructor(messageReaders: readonly HttpMessageReader[],\n messageWriters: readonly HttpMessageWriter[],\n errorAttributes: ErrorAttributes) {\n if (!messageWriters) {\n throw new Error('messageWriters must not be null.');\n }\n this.#errorAttributes = errorAttributes;\n this.#messageReaders = messageReaders;\n this.#messageWriters = messageWriters;\n }\n\n getErrorAttributes(request: ServerRequest, options: ErrorAttributeOptions) {\n return this.#errorAttributes.getErrorAttributes(request, options);\n }\n\n async handle(exchange: ServerWebExchange<HttpServerRequest, HttpServerResponse>, error: Error): Promise<void> {\n if (exchange.response.commited || this.#isDisconnectedClientError(error)) {\n return Promise.reject(error);\n }\n this.#errorAttributes.storeErrorInformation(error, exchange);\n const request = serverRequest.create(exchange, this.#messageReaders);\n const handler = await this.getRoutingFunction(this.#errorAttributes)?.route(request);\n if (handler) {\n const response = await handler(request);\n this.logError(request, response, error);\n await this.#write(exchange, response);\n }\n else {\n throw error;\n }\n }\n\n protected abstract getRoutingFunction(errorAttributes: ErrorAttributes): RouterFunction<ServerResponse>;\n\n\n protected logError(request: ServerRequest, response: ServerResponse, error: Error) {\n\n }\n\n #isDisconnectedClientError(error: Error) {\n return isClientDisconnectedError(error);\n }\n\n async #write(exchange: ServerWebExchange<HttpServerRequest, HttpServerResponse>, response: ServerResponse) {\n exchange.response.headers.set('Content-Type', response.headers.get('Content-Type'));\n const responseContext = {\n messageWriters: this.#messageWriters\n };\n return response.writeTo(exchange, responseContext);\n }\n}\n\nexport type ErrorProperties = {}\n\nexport class DefaultWebErrorHandler extends AbstractWebErrorHandler {\n static readonly #defaultErrorAttributes: DefaultErrorAttributes = new DefaultErrorAttributes();\n static readonly #ONLY_STATUS: ErrorAttributeOptions = { includes: ['status'] };\n\n constructor(readers: ReadonlyArray<HttpMessageReader>,\n writers: ReadonlyArray<HttpMessageWriter>,\n errorAttributes: ErrorAttributes,\n errorProperties: ErrorProperties = {}) {\n super(readers, writers, errorAttributes);\n }\n\n protected getRoutingFunction(errorAttributes: ErrorAttributes): RouterFunction<ServerResponse> {\n return route(r.all(), (request) => {\n return this.#renderErrorResponse(request);\n });\n }\n\n #getErrorAttributes(request: ServerRequest, mimeType: MIMEType) {\n return super.getErrorAttributes(request, this.getErrorAttributeOptions(request, mimeType));\n }\n\n protected getErrorAttributeOptions(request: ServerRequest, mimeType: MIMEType): ErrorAttributeOptions {\n return {\n includes: ['error', 'message', 'status', 'path']\n };\n }\n\n async #renderErrorResponse(request: ServerRequest): Promise<ServerResponse> {\n const errorAttributes = this.#getErrorAttributes(request, ALL);\n const status = this.#getHttpStatus(request, errorAttributes);\n return serverResponse.status(status).contentType(new MIMEType('application/json')).bodyValue(JSON.stringify(errorAttributes));\n }\n\n #getHttpStatus(request: ServerRequest, errorAttributes: Partial<Record<ErrorAttributeKey, unknown>>): number {\n return this.getHttpStatus(errorAttributes.status !== undefined ? errorAttributes\n : DefaultWebErrorHandler.#defaultErrorAttributes.getErrorAttributes(request, DefaultWebErrorHandler.#ONLY_STATUS));\n }\n\n protected getHttpStatus(errorAttributes: Partial<Record<ErrorAttributeKey, unknown>>): number {\n const status = errorAttributes.status;\n if (typeof status === 'number') {\n return status;\n }\n throw new Error(`Invalid status code: ${status}`);\n }\n}\n", "import type { HttpHeaders, HttpStatusCode, ReadonlyHttpHeaders } from '../../types/web/http';\nimport { MapHttpHeaders } from '../http/headers.ts';\n\n/**\n * RFC 9457 - Problem Details for HTTP APIs\n */\nexport type ProblemDetail = {\n title?: string;\n status: number;\n detail?: string;\n [key: string]: unknown;\n}\n\nexport type ErrorResponse = {\n readonly statusCode: HttpStatusCode;\n readonly headers: HttpHeaders;\n readonly body: ProblemDetail;\n}\n\nexport class ErrorResponseError extends Error implements ErrorResponse {\n readonly #status: HttpStatusCode;\n readonly #headers: ReadonlyHttpHeaders = new MapHttpHeaders();\n readonly body: ProblemDetail;\n\n constructor(status: HttpStatusCode, body?: ProblemDetail) {\n super();\n this.#status = status;\n this.body = body ?? ErrorResponseError.problemDetailFor(status);\n }\n\n get statusCode() {\n return this.#status\n }\n\n set detail(detail: string | undefined) {\n this.body.detail = detail;\n }\n\n get headers() {\n return this.#headers;\n }\n\n static problemDetailFor(status: HttpStatusCode, detail?: string): ProblemDetail {\n const problem: ProblemDetail = {\n status: status.value\n };\n if (detail !== undefined) {\n problem.detail = detail;\n }\n return problem;\n }\n}\n", "import { ErrorResponseError } from '../error.ts';\nimport type { HttpStatusCode } from '../../../types/web/http';\nimport { EMPTY_HTTP_HEADERS } from '../../http/headers.ts';\n\nexport class ResponseStatusError extends ErrorResponseError {\n readonly #reason?: string;\n\n constructor(status: HttpStatusCode, reason?: string) {\n super(status, ResponseStatusError.problemDetailFor(status, reason));\n this.#reason = reason;\n }\n\n get reason() {\n return this.#reason;\n }\n\n get headers() {\n return EMPTY_HTTP_HEADERS;\n }\n}\n", "import type { ServerWebExchange } from '../../../types/web/server';\nimport type { WebHandler } from '../server/types.ts';\nimport type { CorsConfigSource, PreFlightRequestHandler } from '../cors/types.ts';\nimport { isPreFlightRequest } from '../cors/utils.ts';\nimport { HttpStatus } from '../../http/status.ts';\nimport type { HandlerAdapter, HandlerMapping, HandlerResult, HandlerResultHandler } from './types.ts';\nimport getLogger from '../../logger.ts';\nimport { ResponseStatusError } from '../server/error.ts';\n\nexport const BEST_MATCHING_HANDLER_ATTRIBUTE = 'io.interop.web.async.handler.handler';\nexport const BEST_MATCHING_PATTERN_ATTRIBUTE = 'io.interop.web.async.handler.pattern';\nexport const URI_VARIABLES_ATTRIBUTE = 'io.interop.web.async.handler.variables';\n\nexport class DispatcherHandler implements WebHandler, PreFlightRequestHandler {\n #handlerMappings?: Array<HandlerMapping>;\n #handlerAdapters?: Array<HandlerAdapter>;\n #resultHandlers?: Array<HandlerResultHandler>;\n\n constructor(handlerMappings?: Array<HandlerMapping>,\n handlerAdapters?: Array<HandlerAdapter>,\n resultHandlers?: Array<HandlerResultHandler>) {\n this.#handlerMappings = handlerMappings;\n this.#handlerAdapters = handlerAdapters;\n this.#resultHandlers = resultHandlers;\n }\n async handle(exchange: ServerWebExchange): Promise<void> {\n if (!this.#handlerMappings) {\n return this.#createNotFoundError();\n }\n if (isPreFlightRequest(exchange.request)) {\n return this.handlePreFlight(exchange);\n }\n let handler: unknown;\n try {\n for (const mapping of this.#handlerMappings) {\n handler = await mapping.getHandler(exchange);\n if (handler !== undefined) {\n break;\n }\n }\n if (handler === undefined) {\n await this.#createNotFoundError();\n }\n }\n catch (e) {\n return this.#handleResultPromise(exchange, Promise.reject(e));\n }\n return this.#handleRequestWith(exchange, handler);\n }\n\n async #handleResultPromise(exchange: ServerWebExchange, resultPromise: Promise<HandlerResult>): Promise<void> {\n if (this.#handlerAdapters) {\n // dispatch exception handler\n }\n const result = await resultPromise;\n try {\n await this.#handleResult(exchange, result, `Handler ${result.handler}`);\n }\n catch (e) {\n const exceptionHandler = result.exceptionHandler;\n if (exceptionHandler) {\n const error = e instanceof Error ? e : new Error(String(e));\n const result2 = await exceptionHandler(exchange, error);\n await this.#handleResult(exchange, result2, `Exception handler ${result2.handler}, error=\"${error.message}\"`);\n }\n }\n }\n\n #handleResult(exchange: ServerWebExchange, result: HandlerResult, details: string): Promise<void> {\n if (this.#resultHandlers) {\n for (const handler of this.#resultHandlers) {\n if (handler.supports(result)) {\n details += ' [DispatcherHandler]';\n return handler.handle(exchange, result);\n }\n }\n }\n return Promise.reject(new Error(`No HandlerResultHandler for ${result.returnValue}`));\n }\n\n #handleRequestWith(exchange: ServerWebExchange, handler: unknown): Promise<void> {\n if (exchange.response.statusCode?.value === HttpStatus.FORBIDDEN.value) {\n return Promise.resolve(); // Pre-flight request was denied\n }\n if (this.#handlerAdapters) {\n for (const adapter of this.#handlerAdapters) {\n if (adapter.supports(handler)) {\n const resultPromise = adapter.handle(exchange, handler);\n return this.#handleResultPromise(exchange, resultPromise);\n }\n }\n }\n return Promise.reject(new Error(`No HandlerAdapter for handler ${handler}`));\n }\n\n\n #createNotFoundError<R>(): Promise<R> {\n return Promise.reject(new ResponseStatusError(HttpStatus.NOT_FOUND));\n }\n\n async handlePreFlight(exchange: ServerWebExchange): Promise<void> {\n let handler: unknown;\n for (const mapping of this.#handlerMappings ?? []) {\n handler = await mapping.getHandler(exchange);\n if (handler !== undefined) {\n break;\n }\n }\n // If no handler found, return 403 Forbidden\n if (handler === undefined) {\n exchange.response.setStatusCode(HttpStatus.FORBIDDEN);\n return;\n }\n }\n}\n\n\nexport abstract class AbstractHandlerMapping implements HandlerMapping {\n protected logger = getLogger('web.async.handler');\n #corsConfigSource?: CorsConfigSource;\n\n set corsConfigSource(source: CorsConfigSource) {\n if (source === undefined) {\n throw new Error('CorsConfigSource must not be undefined');\n }\n this.#corsConfigSource = source;\n }\n\n async getHandler(exchange: ServerWebExchange): Promise<unknown | undefined> {\n const handler = await this.getHandlerInternal(exchange);\n if (handler !== undefined) {\n if (this.logger.enabledFor('debug')) {\n this.logger.debug(`${exchange.logPrefix}Mapped to ${handler}`);\n }\n const request = exchange.request;\n if (this.hasCorsConfigSource(handler) || isPreFlightRequest(request)) {\n const config = this.#corsConfigSource !== undefined ? await this.#corsConfigSource(exchange) : undefined;\n const handlerConfig = this.getCorsConfig(handler, exchange);\n // Merge configs if both exist\n }\n return handler;\n }\n }\n\n protected abstract getHandlerInternal(exchange: ServerWebExchange): Promise<unknown | undefined>;\n\n protected hasCorsConfigSource(handler: unknown): boolean {\n return this.#corsConfigSource !== undefined;\n }\n\n protected getCorsConfig(handler: unknown, exchange: ServerWebExchange) {\n return undefined;\n }\n}\n", "import type { HandlerAdapter, HandlerResult, HandlerResultHandler } from '../../types.ts';\nimport type { ServerWebExchange } from '../../../../../types/web/server';\nimport { AbstractServerResponse } from './response.ts';\nimport type { HandlerFunction, RouterFunction, ServerRequest } from './types.ts';\nimport * as handler from '../../handler.ts';\nimport serverRequest from './request.ts';\nimport { MATCHING_PATTERN_ATTRIBUTE, REQUEST_ATTRIBUTE, URI_VARIABLES_ATTRIBUTE } from './router.ts';\nimport { PathPattern } from '../../../util/pattern/path-pattern.ts';\nimport type { HttpMessageReader, HttpMessageWriter } from '../../../../http/codec/types.ts';\nimport codecConfig from '../../../../http/codec/config.ts';\n\nexport class HandlerFunctionAdapter implements HandlerAdapter {\n supports(handler: unknown): boolean {\n return typeof handler === 'function';\n }\n async handle(exchange: ServerWebExchange, handler: unknown): Promise<HandlerResult> {\n const handlerFunction = handler as HandlerFunction;\n const request = exchange.attribute<ServerRequest>(REQUEST_ATTRIBUTE);\n if (!request) {\n throw new Error('ServerRequest is not found in exchange attributes.');\n }\n return handlerFunction(request).then(response => ({\n handler, returnValue: response\n }));\n\n }\n}\n\nexport class ServerResponseResultHandler implements HandlerResultHandler {\n readonly #messageWriters: readonly HttpMessageWriter[] = Array<HttpMessageWriter>();\n constructor(messageWriters: readonly HttpMessageWriter[]) {\n if (!messageWriters || messageWriters.length === 0) {\n throw new Error('messageWriters must not be empty.');\n }\n this.#messageWriters = messageWriters;\n }\n\n supports(result: HandlerResult): boolean {\n return result.returnValue instanceof AbstractServerResponse;\n }\n\n get messageWriters(): readonly HttpMessageWriter[] {\n return this.#messageWriters;\n }\n async handle(exchange: ServerWebExchange, result: HandlerResult): Promise<void> {\n const response = result.returnValue as AbstractServerResponse;\n if (response === undefined) {\n throw new Error('No ServerResponse');\n }\n return response.writeTo(exchange, {\n messageWriters: this.messageWriters\n });\n }\n}\n\nexport class RouterFunctionMapping extends handler.AbstractHandlerMapping {\n #routerFunction?: RouterFunction;\n #messageReaders: readonly HttpMessageReader[] = undefined!;\n constructor(routerFunction?: RouterFunction) {\n super();\n this.#routerFunction = routerFunction;\n }\n\n set messageReaders(messageReaders: readonly HttpMessageReader[]) {\n this.#messageReaders = messageReaders;\n }\n\n public init(...routerFunctions: Array<RouterFunction>): void {\n if (this.#messageReaders === undefined || this.#messageReaders.length === 0) {\n this.#messageReaders = codecConfig.serverConfigurer.create().readers;\n }\n if (this.#routerFunction) {\n throw new Error('RouterFunctionMapping is already initialized with a RouterFunction');\n }\n this.#routerFunction = routerFunctions.reduce((a, b) => a.and(b));\n\n }\n\n protected async getHandlerInternal(exchange: ServerWebExchange): Promise<unknown | undefined> {\n if (this.#routerFunction === undefined) {\n return; // undefined\n }\n const request = serverRequest.create(exchange, this.#messageReaders);\n const handlerFunction = await this.#routerFunction.route(request)\n if (handlerFunction !== undefined) {\n this.#setAttributes(exchange.attributes, request, handlerFunction);\n }\n return handlerFunction;\n }\n\n #setAttributes(attributes: Map<string, unknown>, request: unknown, handlerFunction: HandlerFunction): void {\n attributes.set(REQUEST_ATTRIBUTE, request);\n attributes.set(handler.BEST_MATCHING_HANDLER_ATTRIBUTE, handlerFunction);\n\n const pattern = attributes.get(MATCHING_PATTERN_ATTRIBUTE) as PathPattern;\n if (pattern) {\n attributes.set(handler.BEST_MATCHING_PATTERN_ATTRIBUTE, pattern);\n }\n const uriVariables = attributes.get(URI_VARIABLES_ATTRIBUTE);\n if (uriVariables !== undefined) {\n attributes.set(URI_VARIABLES_ATTRIBUTE, uriVariables);\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", "s", "cs", "tc", "cookie", "parsed", "result", "import_node_util", "import_node_util", "WILDCARD_TYPE", "ALL", "APPLICATION_OCTET_STREAM_VALUE", "APPLICATION_OCTET_STREAM", "isWildcardType", "mimeType", "isWildcardSubtype", "isConcrete", "InvalidMimeTypeError", "message", "options", "createMimeType", "type", "subtype", "charset", "input", "result", "error", "getSubtypeSuffix", "suffixIndex", "isCompatibleWith", "a", "b", "aSuffix", "bSuffix", "mimeTypes", "MediaType", "_MediaType", "APPLICATION_OCTET_STREAM_VALUE", "#PARAM_QUALITY_FACTOR", "input", "#checkToken", "key", "value", "isQuoted", "unquotedValue", "unquote", "q", "InvalidMediaTypeError", "token", "i", "c", "qualityFactor", "mediaTypes", "type", "mediaType", "mimeType", "message", "fileExtensionToMediaTypes", "map", "line", "trimmed", "parts", "extensions", "ext", "existing", "isQuoted", "s", "unquote", "isMoreSpecific", "a", "b", "MediaType", "aQuality", "bQuality", "aWildcard", "isWildcardType", "bWildcard", "aWildcardSubtype", "isWildcardSubtype", "bWildcardSubtype", "aParamsSize", "bParamsSize", "isLessSpecific", "bubbleSort", "list", "swap", "n", "i", "j", "prev", "curr", "sortBySpecificity", "mimeTypes", "InvalidMimeTypeError", "parseHeader", "value", "list", "start", "end", "i", "toList", "values", "AbstractHttpHeaders", "name", "MapHttpHeaders", "prev", "EMPTY_HTTP_HEADERS", "getContentType", "headers", "MediaType", "DefaultHttpStatusCode", "#value", "value", "HttpStatus", "_HttpStatus", "#VALUES", "key", "code", "status", "#phrase", "phrase", "httpStatusCode", "import_node_http", "subPath", "container", "start", "end", "elements", "DefaultPathContainer", "slice", "path", "e", "isSeparator", "element", "isPathSegment", "HTTP_OPTIONS", "parsePath", "path", "options", "DefaultPathContainer", "HTTP_OPTIONS", "_DefaultPathContainer", "#SEPARATORS", "#path", "#elements", "elements", "separator", "separatorElement", "start", "end", "i", "segment", "#decodeAndParsePathSegment", "DefaultPathSegment", "paramsIndex", "valueToMatch", "pathParameterContent", "parameters", "#parsePathParameters", "content", "parameter", "#parsePathParameterValue", "values", "input", "output", "eqIndex", "name", "value", "v", "_DefaultPathSegment", "#EMPTY_PARAMS", "separatorOrValueToMatch", "#value", "#valueToMatch", "#parameters", "parseRequestPath", "uri", "contextPath", "DefaultRequestPath", "_DefaultRequestPath", "#initContextPath", "path", "parsePath", "#validateContextPath", "length", "counter", "element", "subPath", "fullPath", "#extractPathWithinApplication", "contextPathLength", "rawPath", "contextPathContainer", "pathWithinApplication", "#fullPath", "#contextPath", "#pathWithinApplication", "AbstractServerHttpRequest", "AbstractHttpRequest", "#sslInfo", "#path", "ExtendedHttpIncomingMessage", "http", "ExtendedHttpServerResponse", "AbstractServerHttpResponse", "AbstractHttpResponse", "#cookies", "#statusCode", "#state", "#commitActions", "statusCode", "httpStatusCode", "cookie", "action", "state", "body", "buffer", "error", "writeAction", "allActions", "acc", "cur", "_error", "HttpServerRequest", "AbstractServerHttpRequest", "#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", "codecConfigurer", "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", "request", "response", "responseHeaders", "varyHeaders", "header", "h", "isCorsRequest", "logger", "rejectRequest", "preFlightRequest", "isPreFlightRequest", "handleInternal", "DEFAULT_PERMIT_ALL", "DEFAULT_PERMIT_METHODS", "PERMIT_DEFAULT_CONFIG", "validateCorsConfig", "allowHeaders", "ALL", "allowOrigins", "validateAllowCredentials", "validateAllowPrivateNetwork", "origin", "trimTrailingSlash", "combine", "source", "other", "combined", "v", "combineCorsConfig", "corsFilter", "opts", "processor", "ctx", "chain", "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", "chain", "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", "chain", "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", "chain", "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", "chain", "error", "AccessDeniedError", "principal", "isAuthentication", "logger", "getLogger", "delegatingAuthorizationManager", "opts", "check", "authentication", "exchange", "decision", "matcher", "manager", "checkResult", "AuthorizationDecision", "DefaultAuthorizationManager", "logger", "getLogger", "authorizationFilter", "opts", "manager", "storage", "exchange", "chain", "promise", "AsyncStorageSecurityContextHolder", "c", "error", "AccessDeniedError", "SecurityContextServerWebExchange", "ServerWebExchangeDecorator", "#context", "exchange", "context", "exchangeFilter", "opts", "storage", "chain", "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", "WebHandlerDecorator", "#delegate", "delegate", "exchange", "ErrorHandlingWebHandler", "#errorHandlers", "errorHandlers", "completion", "e", "handler", "reason", "error", "DefaultWebFilterChain", "_DefaultWebFilterChain", "#filters", "#handler", "#current", "#chian", "filters", "allFilters", "result", "chain", "current", "#invokeFilter", "filter", "FilteringWebHandler", "#chain", "WebFilterChainProxy", "#filters", "#firewall", "StrictServerWebExchangeFirewall", "#decorator", "DefaultWebFilterChainDecorator", "#exchangeRejectedHandler", "HttpStatusExchangeRejectedHandler", "filters", "exchange", "chain", "firewalledExchange", "#filterFirewalledExchange", "e", "ServerExchangeRejectedError", "securityFilterChain", "firewall", "decorator", "handler", "original", "DefaultWebFilterChain", "MatcherSecurityWebFilterChain", "#matcher", "matcher", "message", "#status", "status", "HttpStatus", "error", "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", "exchange", "chain", "_authentication", "httpBasic", "verifier", "decoder", "token", "payload", "claim", "e", "BadJwtError", "JwtError", "authenticationConverter", "token_converter_default", "authenticationConverterMatcher", "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", "MatcherSecurityWebFilterChain", "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", "HttpHeadResponseDecorator", "ServerHttpResponseDecorator", "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", "isLoggingSuppressed", "hints", "LOG_PREFIX_HINT", "getLogPrefix", "AbstractEncoder", "#encodableMimeTypes", "getLogger", "supportedMimeTypes", "logger", "type", "mimeType", "supportedMimeType", "isCompatibleWith", "BlobEncoder", "ALL", "input", "hints", "part", "isLoggingSuppressed", "#logValue", "prefix", "getLogPrefix", "StringEncoder", "_StringEncoder", "mimeTypes", "logPrefix", "traceEnabled", "createMimeType", "LoggingCodecSupport", "getLogger", "#enableLoggingRequestDetails", "enable", "MultipartHttpMessageReader", "_MultipartHttpMessageReader", "LoggingCodecSupport", "MediaType", "#partReader", "partReader", "type", "mediaType", "#supportsMediaType", "supportedMediaType", "isCompatibleWith", "message", "hints", "stream", "result", "name", "value", "DefaultPartHttpMessageReader", "EncoderHttpMessageWriter", "_EncoderHttpMessageWriter", "#encoder", "#mediaTypes", "#defaultMediaType", "encoder", "MediaType", "mediaType", "isConcrete", "type", "input", "message", "hints", "resolvedMediaType", "#updateContentType", "part", "AbstractEncoder", "getContentType", "fallback", "useFallback", "addDefaultCharsetIfNeeded", "main", "defaultType", "defaultCharset", "result", "BaseDefaultCodecs", "#multipartReader", "#maxInMemorySize", "#enableLoggingRequestDetails", "#registerDefaults", "#writers", "#readers", "reader", "registerDefaults", "partReader", "DefaultPartHttpMessageReader", "MultipartHttpMessageReader", "#getBaseWriters", "writers", "BlobEncoder", "bytes", "enable", "StringEncoder", "codecs", "codec", "#initCodec", "size", "BaseCodecConfigurer", "defaultCodecs", "ServerDefaultCodecsImpl", "DefaultServerCodecConfigurer", "createServerCodecConfigurer", "config_default", "import_node_net", "createPipeCommandServer", "logger", "options", "handler", "onClose", "pipeName", "server", "stream", "error", "args", "asString", "msg", "result", "response", "e", "cause", "gatewayCommandPipeServer", "shutdown", "info", "import_package", "import_node_path", "import_promises", "import_node_fs", "getWelcomePage", "staticLocations", "filePath", "indexHtml", "welcomePageFactory", "welcomePage", "htmlMatcher", "mediaType", "exchange", "next", "request", "response", "HttpStatus", "buffer", "import_node_async_hooks", "isClientDisconnectedError", "error", "code", "message", "checkAndLogClientDisconnectedError", "logger", "HttpWebHandlerAdapter", "#logger", "#codecConfigurer", "#enableLoggingRequestDetails", "#delegate", "#storage", "logger", "delegate", "config_default", "configurer", "reader", "LoggingCodecSupport", "request", "response", "DefaultWebExchange", "storage", "headers", "result", "key", "value", "query", "exchange", "trace", "status", "error", "logPrefix", "HttpStatus", "checkAndLogClientDisconnectedError", "callback", "resolve", "reject", "WebHttpHandlerBuilder", "_WebHttpHandlerBuilder", "#webHandler", "#filters", "#exceptionHandlers", "#middleware", "#handlerDecorator", "webHandler", "filters", "consumer", "handlers", "decorator", "previousDecorator", "handler", "getLogger", "decorated", "FilteringWebHandler", "ErrorHandlingWebHandler", "adapter", "adapted", "request_default", "exchange", "messageReaders", "DefaultServerRequest", "DefaultServerRequestHeaders", "#headers", "headers", "MediaType", "value", "getContentType", "name", "list", "PathElement", "pos", "separator", "SeparatorPathElement", "PathElement", "pos", "separator", "pathIndex", "matchingContext", "WildcardPathElement", "PathElement", "pos", "separator", "pathIndex", "matchingContext", "segmentData", "element", "isPathSegment", "CaptureSegmentsPathElement", "PathElement", "#variableName", "pos", "captureDescriptor", "separator", "pathIndex", "matchingContext", "endPathIndex", "#collectParameters", "startPathIndex", "parametersCollector", "element", "isPathSegment", "parameters", "key", "values", "existingValues", "#pathToString", "fromSegment", "toSegment", "pathElements", "sb", "s", "result", "i", "WildcardSegmentsPathElement", "PathElement", "pos", "separator", "pathIndex", "matchingContext", "endPathIndex", "s", "result", "i", "MatchingContext", "#candidate", "#extractedUriVariables", "#extractedMatrixVariables", "#determineRemainingPath", "pathContainer", "extractVariables", "key", "value", "parameters", "PathMatchInfo", "pathIndex", "isSeparator", "element", "isPathSegment", "_PathMatchInfo", "uriVars", "matrixVars", "PathPattern", "_PathPattern", "#EMPTY_PATH", "parsePath", "a", "b", "#patternString", "#parser", "#pathOptions", "#caseSensitive", "#head", "#capturedVariableCount", "#normalizedLength", "#endsWithSeparatorWildcard", "#score", "#catchAll", "patternText", "parser", "head", "current", "CaptureSegmentsPathElement", "WildcardSegmentsPathElement", "SeparatorPathElement", "WildcardPathElement", "#hasLength", "container", "#pathContainerIsJustSeparator", "matchingContext", "path", "pathElements", "pathElementsLength", "startIndex", "elem", "endIndex", "multipleAdjacentSeparators", "i", "resultPath", "sb", "e", "subPath", "pe", "import_node_util", "PatternMessages", "PatternParseError", "_PatternParseError", "#pattern", "messageType", "inserts", "cause", "position", "pattern", "message", "pos", "options", "sb", "i", "CaptureVariablePathElement", "PathElement", "#constraintPattern", "pos", "captureDescriptor", "caseSensitive", "separator", "colon", "i", "patternText", "flags", "pathIndex", "matchingContext", "candidateCapture", "exec", "match", "sb", "s", "result", "SingleCharWildcardedPathElement", "PathElement", "#text", "#len", "#questionMarkCount", "#caseSensitive", "pos", "literalText", "questionMarkCount", "caseSensitive", "separator", "i", "pathIndex", "matchingContext", "element", "isPathSegment", "value", "c", "RegexPathElement", "PathElement", "#regex", "#caseSensitive", "#pattern", "#wildcardCount", "#variableNames", "pos", "regex", "caseSensitive", "completePattern", "separator", "#buildPattern", "_completePattern", "text", "variableNames", "wildcardCount", "patternBuilder", "ch", "closeBrace", "captureContent", "colonIndex", "variableName", "constraint", "patternString", "flags", "pathIndex", "matchingContext", "textToMatch", "match", "matches", "i", "name", "value", "varsLength", "LiteralPathElement", "PathElement", "#text", "#len", "#caseSensitive", "pos", "literalText", "caseSensitive", "separator", "pathIndex", "matchingContext", "pathSegment", "isPathSegment", "value", "arr", "i", "isJavaScriptIdentifierStartChar", "ch", "isJavaScriptIdentifierPartChar", "InternalPathPatternParser", "#parser", "#pathPatternData", "#pathPatternLength", "#pos", "#singleCharWildcardCount", "#wildcard", "#isCaptureSegmentsVariable", "#insideVariableCapture", "#variableCaptureCount", "#pathElementStart", "#variableCaptureStart", "#hasMultipleSegmentsElements", "#capturedVariableNames", "#headPE", "#currentPE", "parser", "pathPattern", "i", "#resetPathElementState", "separator", "#pushPathElement", "#createPathElement", "SeparatorPathElement", "PatternParseError", "#skipCaptureRegex", "#isDoubleWildcard", "#checkValidMultipleSegmentsElements", "WildcardSegmentsPathElement", "PathPattern", "#getPathElementText", "pathElementText", "index", "newPE", "CaptureSegmentsPathElement", "CaptureVariablePathElement", "err", "#findRegExpStart", "#recordCapturedVariable", "newRegexPE", "RegexPathElement", "variableName", "WildcardPathElement", "SingleCharWildcardedPathElement", "LiteralPathElement", "regexStartPos", "curlyBracketDepth", "previousBackslash", "startPos", "endPos", "newPathElement", "peBeforeSeparator", "data", "offset", "pos", "v", "PathPatternParser", "_PathPatternParser", "#caseSensitive", "#pathOptions", "HTTP_OPTIONS", "value", "pattern", "pathPattern", "InternalPathPatternParser", "_value", "#raiseError", "logger", "getLogger", "REQUEST_ATTRIBUTE", "URI_VARIABLES_ATTRIBUTE", "MATCHING_PATTERN_ATTRIBUTE", "routerFunction", "route", "result", "other", "and", "first", "second", "request", "handler", "predicate", "handlerFunction", "logPrefix", "predicates", "requestMethod", "isPreFlightRequest", "accessControlRequestMethod", "requestPredicate", "negate", "or", "orRequestPredicate", "delegate", "negateRequestPredicate", "method", "httpMethod", "singleHttpMethodPredicate", "match", "traceMatch", "methods", "httpMethods", "multipleHttpMethodsPredicate", "path", "pattern", "parser", "PathPatternParser", "pathPredicates", "patternParser", "pathPattern", "pathPatternPredicate", "pathContainer", "info", "prefix", "desired", "actual", "headers", "headersPredicate", "accept", "mediaTypes", "acceptedMediaTypes", "MediaType", "sortBySpecificity", "mediaType", "singleAcceptPredicate", "accepted", "acceptedMediaType", "isCompatibleWith", "multipleAcceptsPredicate", "outer", "queryParam", "name", "valueOrPredicate", "value", "v", "queryParamPredicate", "s", "from", "response", "status", "headers", "name", "httpStatusCode", "DefaultServerResponseBuilder", "ok", "HttpStatus", "created", "location", "response_default", "writeWithMessageWriters", "message", "context", "promise", "bodyType", "mediaType", "getContentType", "writer", "bodyFromValue", "body", "#statusCode", "#headers", "MapHttpHeaders", "#cookies", "#hints", "statusCode", "headerName", "headerValues", "headerValue", "cookie", "cookies", "consumer", "contentType", "length", "#initEntityResponse", "entity", "inserter", "DefaultEntityResponse", "writeFunction", "WriterFunctionServerResponse", "exchange", "AbstractServerResponse", "hints", "allCookies", "cookieList", "#writeStatusAndHeaders", "WriterFunctionServerResponse", "AbstractServerResponse", "#writeFunction", "statusCode", "headers", "cookies", "writeFunction", "exchange", "context", "DefaultEntityResponse", "#entity", "#inserter", "entity", "inserter", "hints", "messageWriters", "LOG_PREFIX_HINT", "import_node_util", "ErrorResponseError", "_ErrorResponseError", "#status", "#headers", "MapHttpHeaders", "status", "body", "detail", "problem", "ResponseStatusError", "_ResponseStatusError", "ErrorResponseError", "#reason", "status", "reason", "EMPTY_HTTP_HEADERS", "DefaultErrorAttributes", "_DefaultErrorAttributes", "request", "options", "#getErrorAttributesInternal", "error", "exchange", "includeStackTrace", "errorAttributes", "errorStatus", "#determineHttpStatus", "#handleError", "ResponseStatusError", "httpStatus", "HttpStatus", "AbstractWebErrorHandler", "#errorAttributes", "#messageReaders", "#messageWriters", "messageReaders", "messageWriters", "#isDisconnectedClientError", "request_default", "handler", "response", "#write", "isClientDisconnectedError", "responseContext", "DefaultWebErrorHandler", "_DefaultWebErrorHandler", "#defaultErrorAttributes", "#ONLY_STATUS", "readers", "writers", "errorProperties", "route", "predicates", "#renderErrorResponse", "#getErrorAttributes", "mimeType", "ALL", "status", "#getHttpStatus", "response_default", "BEST_MATCHING_HANDLER_ATTRIBUTE", "BEST_MATCHING_PATTERN_ATTRIBUTE", "DispatcherHandler", "#handlerMappings", "#handlerAdapters", "#resultHandlers", "handlerMappings", "handlerAdapters", "resultHandlers", "exchange", "#createNotFoundError", "isPreFlightRequest", "handler", "mapping", "e", "#handleResultPromise", "#handleRequestWith", "resultPromise", "result", "#handleResult", "exceptionHandler", "error", "result2", "details", "HttpStatus", "adapter", "ResponseStatusError", "AbstractHandlerMapping", "getLogger", "#corsConfigSource", "source", "request", "config", "handlerConfig", "HandlerFunctionAdapter", "handler", "exchange", "handlerFunction", "request", "REQUEST_ATTRIBUTE", "response", "ServerResponseResultHandler", "#messageWriters", "messageWriters", "result", "AbstractServerResponse", "RouterFunctionMapping", "AbstractHandlerMapping", "#routerFunction", "#messageReaders", "routerFunction", "messageReaders", "routerFunctions", "config_default", "a", "b", "request_default", "#setAttributes", "attributes", "BEST_MATCHING_HANDLER_ATTRIBUTE", "pattern", "MATCHING_PATTERN_ATTRIBUTE", "BEST_MATCHING_PATTERN_ATTRIBUTE", "uriVariables", "URI_VARIABLES_ATTRIBUTE", "logger", "getLogger", "createListener", "builder", "onSocketError", "httpHandler", "req", "resOrUpgradeHead", "res", "ExtendedHttpServerResponse", "request", "HttpServerRequest", "response", "HttpServerResponse", "decoratedResponse", "HttpHeadResponseDecorator", "hp", "e", "http", "promisify", "fn", "resolve", "reject", "r", "err", "memoryMonitor", "config", "start", "VERSION", "info", "initBuilder", "context", "storage", "security", "httpSecurity", "sockets", "webSockets", "codecConfigurer", "config_default", "welcomePageRouterFunctionMapping", "RouterFunctionMapping", "h", "DispatcherHandler", "HandlerFunctionAdapter", "ServerResponseResultHandler", "handler", "compose", "server_header_default", "next", "HttpStatus", "buffer", "welcomePageFactory", "_next", "ResponseStatusError", "WebHttpHandlerBuilder", "WebFilterChainProxy", "DefaultWebErrorHandler", "DefaultErrorAttributes", "Factory", "options", "ssl", "host", "serverCertificate", "createServer", "https", "secureContextOptions", "monitor", "gatewayManager", "GatewayManager", "path", "configure", "configurer", "core_default", "ports", "portRange", "listener", "server", "ExtendedHttpIncomingMessage", "port", "route", "endpoint", "localIp", "initRoute", "addressAndPort", "_socket", "head", "fullServer", "address", "cb", "stop", "gatewayCommandPipeServer", "index_default", "Factory"]
7
7
  }