@aegis-fluxion/core 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +179 -0
- package/dist/index.cjs +424 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +26 -3
- package/dist/index.d.ts +26 -3
- package/dist/index.js +424 -9
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"names":["createECDH","createHash","randomBytes","createCipheriv","createDecipheriv","WebSocketServer","WebSocket","randomUUID"],"mappings":"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","file":"index.cjs","sourcesContent":["import {\r\n createCipheriv,\r\n createDecipheriv,\r\n createECDH,\r\n createHash,\r\n randomBytes,\r\n randomUUID\r\n} from \"node:crypto\";\r\nimport type { ECDH } from \"node:crypto\";\r\nimport type { IncomingMessage } from \"node:http\";\r\nimport WebSocket, { WebSocketServer } from \"ws\";\r\nimport type {\r\n ClientOptions,\r\n RawData,\r\n ServerOptions as WebSocketServerOptions\r\n} from \"ws\";\r\n\r\nconst DEFAULT_CLOSE_CODE = 1000;\r\nconst DEFAULT_CLOSE_REASON = \"\";\r\nconst INTERNAL_HANDSHAKE_EVENT = \"__handshake\";\r\nconst READY_EVENT = \"ready\";\r\nconst HANDSHAKE_CURVE = \"prime256v1\";\r\nconst ENCRYPTION_ALGORITHM = \"aes-256-gcm\";\r\nconst GCM_IV_LENGTH = 12;\r\nconst GCM_AUTH_TAG_LENGTH = 16;\r\nconst ENCRYPTION_KEY_LENGTH = 32;\r\nconst ENCRYPTED_PACKET_VERSION = 1;\r\nconst ENCRYPTED_PACKET_PREFIX_LENGTH = 1 + GCM_IV_LENGTH + GCM_AUTH_TAG_LENGTH;\r\nconst DEFAULT_HEARTBEAT_INTERVAL_MS = 15_000;\r\nconst DEFAULT_HEARTBEAT_TIMEOUT_MS = 15_000;\r\nconst DEFAULT_RECONNECT_INITIAL_DELAY_MS = 250;\r\nconst DEFAULT_RECONNECT_MAX_DELAY_MS = 10_000;\r\nconst DEFAULT_RECONNECT_FACTOR = 2;\r\nconst DEFAULT_RECONNECT_JITTER_RATIO = 0.2;\r\n\r\ninterface HandshakePayload {\r\n publicKey: string;\r\n}\r\n\r\ninterface ServerHandshakeState {\r\n ecdh: ECDH;\r\n localPublicKey: string;\r\n isReady: boolean;\r\n}\r\n\r\ninterface ClientHandshakeState {\r\n ecdh: ECDH;\r\n localPublicKey: string;\r\n isReady: boolean;\r\n sharedSecret: Buffer | null;\r\n encryptionKey: Buffer | null;\r\n}\r\n\r\ninterface EncryptedPacketParts {\r\n iv: Buffer;\r\n authTag: Buffer;\r\n ciphertext: Buffer;\r\n}\r\n\r\nexport interface SecureEnvelope<TData = unknown> {\r\n event: string;\r\n data: TData;\r\n}\r\n\r\nexport interface SecureServerHeartbeatOptions {\r\n enabled?: boolean;\r\n intervalMs?: number;\r\n timeoutMs?: number;\r\n}\r\n\r\nexport interface SecureServerOptions extends WebSocketServerOptions {\r\n heartbeat?: SecureServerHeartbeatOptions;\r\n}\r\n\r\nexport interface SecureClientReconnectOptions {\r\n enabled?: boolean;\r\n initialDelayMs?: number;\r\n maxDelayMs?: number;\r\n factor?: number;\r\n jitterRatio?: number;\r\n maxAttempts?: number | null;\r\n}\r\n\r\nexport interface SecureClientOptions {\r\n protocols?: string | string[];\r\n wsOptions?: ClientOptions;\r\n autoConnect?: boolean;\r\n reconnect?: boolean | SecureClientReconnectOptions;\r\n}\r\n\r\nexport interface SecureServerClient {\r\n id: string;\r\n socket: WebSocket;\r\n request: IncomingMessage;\r\n join: (room: string) => boolean;\r\n leave: (room: string) => boolean;\r\n leaveAll: () => number;\r\n}\r\n\r\nexport interface SecureServerRoomOperator {\r\n emit: (event: string, data: unknown) => SecureServer;\r\n}\r\n\r\nexport type SecureErrorHandler = (error: Error) => void;\r\n\r\nexport type SecureServerEventHandler = (\r\n data: unknown,\r\n client: SecureServerClient\r\n) => void;\r\n\r\nexport type SecureServerConnectionHandler = (\r\n client: SecureServerClient\r\n) => void;\r\n\r\nexport type SecureServerDisconnectHandler = (\r\n client: SecureServerClient,\r\n code: number,\r\n reason: string\r\n) => void;\r\n\r\nexport type SecureServerReadyHandler = (client: SecureServerClient) => void;\r\n\r\nexport type SecureClientEventHandler = (data: unknown) => void;\r\n\r\nexport type SecureClientConnectHandler = () => void;\r\n\r\nexport type SecureClientDisconnectHandler = (\r\n code: number,\r\n reason: string\r\n) => void;\r\n\r\nexport type SecureClientReadyHandler = () => void;\r\n\r\nexport type SecureServerLifecycleEvent =\r\n | \"connection\"\r\n | \"disconnect\"\r\n | \"ready\"\r\n | \"error\";\r\n\r\nexport type SecureClientLifecycleEvent =\r\n | \"connect\"\r\n | \"disconnect\"\r\n | \"ready\"\r\n | \"error\";\r\n\r\nexport interface SecureServerEventMap {\r\n connection: SecureServerConnectionHandler;\r\n disconnect: SecureServerDisconnectHandler;\r\n ready: SecureServerReadyHandler;\r\n error: SecureErrorHandler;\r\n}\r\n\r\nexport interface SecureClientEventMap {\r\n connect: SecureClientConnectHandler;\r\n disconnect: SecureClientDisconnectHandler;\r\n ready: SecureClientReadyHandler;\r\n error: SecureErrorHandler;\r\n}\r\n\r\nfunction normalizeToError(error: unknown, fallbackMessage: string): Error {\r\n if (error instanceof Error) {\r\n return error;\r\n }\r\n\r\n if (typeof error === \"string\" && error.trim().length > 0) {\r\n return new Error(error);\r\n }\r\n\r\n return new Error(fallbackMessage);\r\n}\r\n\r\nfunction decodeRawData(rawData: RawData): string {\r\n if (typeof rawData === \"string\") {\r\n return rawData;\r\n }\r\n\r\n if (rawData instanceof ArrayBuffer) {\r\n return Buffer.from(rawData).toString(\"utf8\");\r\n }\r\n\r\n if (Array.isArray(rawData)) {\r\n return Buffer.concat(rawData).toString(\"utf8\");\r\n }\r\n\r\n return rawData.toString(\"utf8\");\r\n}\r\n\r\nfunction rawDataToBuffer(rawData: RawData): Buffer {\r\n if (typeof rawData === \"string\") {\r\n return Buffer.from(rawData, \"utf8\");\r\n }\r\n\r\n if (rawData instanceof ArrayBuffer) {\r\n return Buffer.from(rawData);\r\n }\r\n\r\n if (Array.isArray(rawData)) {\r\n return Buffer.concat(rawData);\r\n }\r\n\r\n return Buffer.from(rawData);\r\n}\r\n\r\nfunction serializeEnvelope(event: string, data: unknown): string {\r\n const envelope: SecureEnvelope = { event, data };\r\n return JSON.stringify(envelope);\r\n}\r\n\r\nfunction parseEnvelope(rawData: RawData): SecureEnvelope {\r\n const decoded = decodeRawData(rawData);\r\n const parsed = JSON.parse(decoded) as Partial<SecureEnvelope>;\r\n\r\n if (\r\n typeof parsed !== \"object\" ||\r\n parsed === null ||\r\n typeof parsed.event !== \"string\"\r\n ) {\r\n throw new Error(\"Invalid message format. Expected { event: string, data: unknown }.\");\r\n }\r\n\r\n return {\r\n event: parsed.event,\r\n data: parsed.data\r\n };\r\n}\r\n\r\nfunction parseEnvelopeFromText(decodedPayload: string): SecureEnvelope {\r\n const parsed = JSON.parse(decodedPayload) as Partial<SecureEnvelope>;\r\n\r\n if (\r\n typeof parsed !== \"object\" ||\r\n parsed === null ||\r\n typeof parsed.event !== \"string\"\r\n ) {\r\n throw new Error(\"Invalid message format. Expected { event: string, data: unknown }.\");\r\n }\r\n\r\n return {\r\n event: parsed.event,\r\n data: parsed.data\r\n };\r\n}\r\n\r\nfunction decodeCloseReason(reason: Buffer): string {\r\n return reason.toString(\"utf8\");\r\n}\r\n\r\nfunction isReservedEmitEvent(event: string): boolean {\r\n return event === INTERNAL_HANDSHAKE_EVENT || event === READY_EVENT;\r\n}\r\n\r\nfunction createEphemeralHandshakeState(): { ecdh: ECDH; localPublicKey: string } {\r\n const ecdh = createECDH(HANDSHAKE_CURVE);\r\n ecdh.generateKeys();\r\n\r\n return {\r\n ecdh,\r\n localPublicKey: ecdh.getPublicKey(\"base64\")\r\n };\r\n}\r\n\r\nfunction parseHandshakePayload(data: unknown): HandshakePayload {\r\n if (typeof data !== \"object\" || data === null) {\r\n throw new Error(\"Invalid handshake payload format.\");\r\n }\r\n\r\n const payload = data as Partial<HandshakePayload>;\r\n\r\n if (typeof payload.publicKey !== \"string\" || payload.publicKey.length === 0) {\r\n throw new Error(\"Handshake payload must include a non-empty public key.\");\r\n }\r\n\r\n return {\r\n publicKey: payload.publicKey\r\n };\r\n}\r\n\r\nfunction deriveEncryptionKey(sharedSecret: Buffer): Buffer {\r\n const derivedKey = createHash(\"sha256\").update(sharedSecret).digest();\r\n\r\n if (derivedKey.length !== ENCRYPTION_KEY_LENGTH) {\r\n throw new Error(\"Failed to derive a valid AES-256 key.\");\r\n }\r\n\r\n return derivedKey;\r\n}\r\n\r\nfunction encryptSerializedEnvelope(serializedEnvelope: string, encryptionKey: Buffer): Buffer {\r\n const iv = randomBytes(GCM_IV_LENGTH);\r\n const cipher = createCipheriv(ENCRYPTION_ALGORITHM, encryptionKey, iv);\r\n const ciphertext = Buffer.concat([\r\n cipher.update(serializedEnvelope, \"utf8\"),\r\n cipher.final()\r\n ]);\r\n const authTag = cipher.getAuthTag();\r\n\r\n return Buffer.concat([\r\n Buffer.from([ENCRYPTED_PACKET_VERSION]),\r\n iv,\r\n authTag,\r\n ciphertext\r\n ]);\r\n}\r\n\r\nfunction parseEncryptedPacket(rawData: RawData): EncryptedPacketParts {\r\n const packetBuffer = rawDataToBuffer(rawData);\r\n\r\n if (packetBuffer.length <= ENCRYPTED_PACKET_PREFIX_LENGTH) {\r\n throw new Error(\"Encrypted packet is too short.\");\r\n }\r\n\r\n const version = packetBuffer.readUInt8(0);\r\n\r\n if (version !== ENCRYPTED_PACKET_VERSION) {\r\n throw new Error(\"Unsupported encrypted packet version.\");\r\n }\r\n\r\n const ivStart = 1;\r\n const ivEnd = ivStart + GCM_IV_LENGTH;\r\n const authTagStart = ivEnd;\r\n const authTagEnd = authTagStart + GCM_AUTH_TAG_LENGTH;\r\n\r\n const iv = packetBuffer.subarray(ivStart, ivEnd);\r\n const authTag = packetBuffer.subarray(authTagStart, authTagEnd);\r\n const ciphertext = packetBuffer.subarray(authTagEnd);\r\n\r\n if (ciphertext.length === 0) {\r\n throw new Error(\"Encrypted payload is empty.\");\r\n }\r\n\r\n return {\r\n iv,\r\n authTag,\r\n ciphertext\r\n };\r\n}\r\n\r\nfunction decryptSerializedEnvelope(rawData: RawData, encryptionKey: Buffer): string {\r\n const encryptedPacket = parseEncryptedPacket(rawData);\r\n const decipher = createDecipheriv(\r\n ENCRYPTION_ALGORITHM,\r\n encryptionKey,\r\n encryptedPacket.iv\r\n );\r\n\r\n decipher.setAuthTag(encryptedPacket.authTag);\r\n\r\n const plaintext = Buffer.concat([\r\n decipher.update(encryptedPacket.ciphertext),\r\n decipher.final()\r\n ]);\r\n\r\n return plaintext.toString(\"utf8\");\r\n}\r\n\r\nexport class SecureServer {\r\n private readonly socketServer: WebSocketServer;\r\n\r\n private readonly heartbeatConfig: Required<SecureServerHeartbeatOptions>;\r\n\r\n private heartbeatIntervalHandle: ReturnType<typeof setInterval> | null = null;\r\n\r\n private readonly clientsById = new Map<string, SecureServerClient>();\r\n\r\n private readonly clientIdBySocket = new Map<WebSocket, string>();\r\n\r\n private readonly customEventHandlers = new Map<string, Set<SecureServerEventHandler>>();\r\n\r\n private readonly connectionHandlers = new Set<SecureServerConnectionHandler>();\r\n\r\n private readonly disconnectHandlers = new Set<SecureServerDisconnectHandler>();\r\n\r\n private readonly readyHandlers = new Set<SecureServerReadyHandler>();\r\n\r\n private readonly errorHandlers = new Set<SecureErrorHandler>();\r\n\r\n private readonly handshakeStateBySocket = new WeakMap<WebSocket, ServerHandshakeState>();\r\n\r\n private readonly sharedSecretBySocket = new WeakMap<WebSocket, Buffer>();\r\n\r\n private readonly encryptionKeyBySocket = new WeakMap<WebSocket, Buffer>();\r\n\r\n private readonly pendingPayloadsBySocket = new WeakMap<WebSocket, SecureEnvelope[]>();\r\n\r\n private readonly heartbeatStateBySocket = new WeakMap<\r\n WebSocket,\r\n { awaitingPong: boolean; lastPingAt: number }\r\n >();\r\n\r\n private readonly roomMembersByName = new Map<string, Set<string>>();\r\n\r\n private readonly roomNamesByClientId = new Map<string, Set<string>>();\r\n\r\n public constructor(options: SecureServerOptions) {\r\n const { heartbeat, ...socketServerOptions } = options;\r\n\r\n this.heartbeatConfig = this.resolveHeartbeatConfig(heartbeat);\r\n this.socketServer = new WebSocketServer(socketServerOptions);\r\n this.bindSocketServerEvents();\r\n this.startHeartbeatLoop();\r\n }\r\n\r\n public get clientCount(): number {\r\n return this.clientsById.size;\r\n }\r\n\r\n public get clients(): ReadonlyMap<string, SecureServerClient> {\r\n return this.clientsById;\r\n }\r\n\r\n public on(event: \"connection\", handler: SecureServerConnectionHandler): this;\r\n public on(event: \"disconnect\", handler: SecureServerDisconnectHandler): this;\r\n public on(event: \"ready\", handler: SecureServerReadyHandler): this;\r\n public on(event: \"error\", handler: SecureErrorHandler): this;\r\n public on(event: string, handler: SecureServerEventHandler): this;\r\n public on(event: string, handler: unknown): this {\r\n try {\r\n if (event === \"connection\") {\r\n this.connectionHandlers.add(handler as SecureServerConnectionHandler);\r\n return this;\r\n }\r\n\r\n if (event === \"disconnect\") {\r\n this.disconnectHandlers.add(handler as SecureServerDisconnectHandler);\r\n return this;\r\n }\r\n\r\n if (event === READY_EVENT) {\r\n this.readyHandlers.add(handler as SecureServerReadyHandler);\r\n return this;\r\n }\r\n\r\n if (event === \"error\") {\r\n this.errorHandlers.add(handler as SecureErrorHandler);\r\n return this;\r\n }\r\n\r\n if (event === INTERNAL_HANDSHAKE_EVENT) {\r\n throw new Error(`The event \"${INTERNAL_HANDSHAKE_EVENT}\" is reserved for internal use.`);\r\n }\r\n\r\n const typedHandler = handler as SecureServerEventHandler;\r\n const listeners = this.customEventHandlers.get(event) ?? new Set<SecureServerEventHandler>();\r\n listeners.add(typedHandler);\r\n this.customEventHandlers.set(event, listeners);\r\n } catch (error) {\r\n this.notifyError(\r\n normalizeToError(error, \"Failed to register server event handler.\")\r\n );\r\n }\r\n\r\n return this;\r\n }\r\n\r\n public off(event: \"connection\", handler: SecureServerConnectionHandler): this;\r\n public off(event: \"disconnect\", handler: SecureServerDisconnectHandler): this;\r\n public off(event: \"ready\", handler: SecureServerReadyHandler): this;\r\n public off(event: \"error\", handler: SecureErrorHandler): this;\r\n public off(event: string, handler: SecureServerEventHandler): this;\r\n public off(event: string, handler: unknown): this {\r\n try {\r\n if (event === \"connection\") {\r\n this.connectionHandlers.delete(handler as SecureServerConnectionHandler);\r\n return this;\r\n }\r\n\r\n if (event === \"disconnect\") {\r\n this.disconnectHandlers.delete(handler as SecureServerDisconnectHandler);\r\n return this;\r\n }\r\n\r\n if (event === READY_EVENT) {\r\n this.readyHandlers.delete(handler as SecureServerReadyHandler);\r\n return this;\r\n }\r\n\r\n if (event === \"error\") {\r\n this.errorHandlers.delete(handler as SecureErrorHandler);\r\n return this;\r\n }\r\n\r\n if (event === INTERNAL_HANDSHAKE_EVENT) {\r\n return this;\r\n }\r\n\r\n const listeners = this.customEventHandlers.get(event);\r\n\r\n if (!listeners) {\r\n return this;\r\n }\r\n\r\n listeners.delete(handler as SecureServerEventHandler);\r\n\r\n if (listeners.size === 0) {\r\n this.customEventHandlers.delete(event);\r\n }\r\n } catch (error) {\r\n this.notifyError(\r\n normalizeToError(error, \"Failed to remove server event handler.\")\r\n );\r\n }\r\n\r\n return this;\r\n }\r\n\r\n public emit(event: string, data: unknown): this {\r\n try {\r\n if (isReservedEmitEvent(event)) {\r\n throw new Error(`The event \"${event}\" is reserved and cannot be emitted manually.`);\r\n }\r\n\r\n const envelope: SecureEnvelope = { event, data };\r\n\r\n for (const client of this.clientsById.values()) {\r\n this.sendOrQueuePayload(client.socket, envelope);\r\n }\r\n } catch (error) {\r\n this.notifyError(normalizeToError(error, \"Failed to emit server event.\"));\r\n }\r\n\r\n return this;\r\n }\r\n\r\n public emitTo(clientId: string, event: string, data: unknown): boolean {\r\n try {\r\n if (isReservedEmitEvent(event)) {\r\n throw new Error(`The event \"${event}\" is reserved and cannot be emitted manually.`);\r\n }\r\n\r\n const client = this.clientsById.get(clientId);\r\n\r\n if (!client) {\r\n throw new Error(`Client with id ${clientId} was not found.`);\r\n }\r\n\r\n this.sendOrQueuePayload(client.socket, { event, data });\r\n return true;\r\n } catch (error) {\r\n this.notifyError(normalizeToError(error, \"Failed to emit event to client.\"));\r\n return false;\r\n }\r\n }\r\n\r\n public to(room: string): SecureServerRoomOperator {\r\n const normalizedRoom = this.normalizeRoomName(room);\r\n\r\n return {\r\n emit: (event: string, data: unknown): SecureServer => {\r\n try {\r\n this.emitToRoom(normalizedRoom, event, data);\r\n } catch (error) {\r\n this.notifyError(\r\n normalizeToError(error, `Failed to emit event to room ${normalizedRoom}.`)\r\n );\r\n }\r\n\r\n return this;\r\n }\r\n };\r\n }\r\n\r\n public close(\r\n code: number = DEFAULT_CLOSE_CODE,\r\n reason: string = DEFAULT_CLOSE_REASON\r\n ): void {\r\n try {\r\n this.stopHeartbeatLoop();\r\n\r\n for (const client of this.clientsById.values()) {\r\n if (\r\n client.socket.readyState === WebSocket.OPEN ||\r\n client.socket.readyState === WebSocket.CONNECTING\r\n ) {\r\n client.socket.close(code, reason);\r\n }\r\n }\r\n\r\n this.socketServer.close();\r\n } catch (error) {\r\n this.notifyError(normalizeToError(error, \"Failed to close server.\"));\r\n }\r\n }\r\n\r\n private resolveHeartbeatConfig(\r\n heartbeatOptions: SecureServerHeartbeatOptions | undefined\r\n ): Required<SecureServerHeartbeatOptions> {\r\n const intervalMs = heartbeatOptions?.intervalMs ?? DEFAULT_HEARTBEAT_INTERVAL_MS;\r\n const timeoutMs = heartbeatOptions?.timeoutMs ?? DEFAULT_HEARTBEAT_TIMEOUT_MS;\r\n\r\n if (!Number.isFinite(intervalMs) || intervalMs <= 0) {\r\n throw new Error(\"Server heartbeat intervalMs must be a positive number.\");\r\n }\r\n\r\n if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {\r\n throw new Error(\"Server heartbeat timeoutMs must be a positive number.\");\r\n }\r\n\r\n return {\r\n enabled: heartbeatOptions?.enabled ?? true,\r\n intervalMs,\r\n timeoutMs\r\n };\r\n }\r\n\r\n private startHeartbeatLoop(): void {\r\n if (!this.heartbeatConfig.enabled || this.heartbeatIntervalHandle) {\r\n return;\r\n }\r\n\r\n this.heartbeatIntervalHandle = setInterval(() => {\r\n this.performHeartbeatSweep();\r\n }, this.heartbeatConfig.intervalMs);\r\n\r\n this.heartbeatIntervalHandle.unref?.();\r\n }\r\n\r\n private stopHeartbeatLoop(): void {\r\n if (!this.heartbeatIntervalHandle) {\r\n return;\r\n }\r\n\r\n clearInterval(this.heartbeatIntervalHandle);\r\n this.heartbeatIntervalHandle = null;\r\n }\r\n\r\n private performHeartbeatSweep(): void {\r\n const now = Date.now();\r\n\r\n for (const client of this.clientsById.values()) {\r\n const socket = client.socket;\r\n\r\n if (socket.readyState !== WebSocket.OPEN) {\r\n continue;\r\n }\r\n\r\n const heartbeatState = this.heartbeatStateBySocket.get(socket) ?? {\r\n awaitingPong: false,\r\n lastPingAt: 0\r\n };\r\n\r\n if (\r\n heartbeatState.awaitingPong &&\r\n now - heartbeatState.lastPingAt >= this.heartbeatConfig.timeoutMs\r\n ) {\r\n this.sharedSecretBySocket.delete(socket);\r\n this.encryptionKeyBySocket.delete(socket);\r\n this.pendingPayloadsBySocket.delete(socket);\r\n this.handshakeStateBySocket.delete(socket);\r\n this.heartbeatStateBySocket.delete(socket);\r\n socket.terminate();\r\n continue;\r\n }\r\n\r\n if (heartbeatState.awaitingPong) {\r\n continue;\r\n }\r\n\r\n heartbeatState.awaitingPong = true;\r\n heartbeatState.lastPingAt = now;\r\n this.heartbeatStateBySocket.set(socket, heartbeatState);\r\n\r\n try {\r\n socket.ping();\r\n } catch (error) {\r\n this.notifyError(\r\n normalizeToError(error, `Failed to send heartbeat ping to client ${client.id}.`)\r\n );\r\n }\r\n }\r\n }\r\n\r\n private handleHeartbeatPong(socket: WebSocket): void {\r\n const heartbeatState = this.heartbeatStateBySocket.get(socket);\r\n\r\n if (!heartbeatState) {\r\n return;\r\n }\r\n\r\n heartbeatState.awaitingPong = false;\r\n heartbeatState.lastPingAt = 0;\r\n this.heartbeatStateBySocket.set(socket, heartbeatState);\r\n }\r\n\r\n private bindSocketServerEvents(): void {\r\n this.socketServer.on(\"connection\", (socket: WebSocket, request: IncomingMessage) => {\r\n this.handleConnection(socket, request);\r\n });\r\n\r\n this.socketServer.on(\"error\", (error: Error) => {\r\n this.notifyError(normalizeToError(error, \"WebSocket server encountered an error.\"));\r\n });\r\n }\r\n\r\n private handleConnection(socket: WebSocket, request: IncomingMessage): void {\r\n try {\r\n const clientId = randomUUID();\r\n const handshakeState = this.createServerHandshakeState();\r\n const client = this.createSecureServerClient(clientId, socket, request);\r\n\r\n this.clientsById.set(clientId, client);\r\n this.clientIdBySocket.set(socket, clientId);\r\n this.handshakeStateBySocket.set(socket, handshakeState);\r\n this.pendingPayloadsBySocket.set(socket, []);\r\n this.heartbeatStateBySocket.set(socket, {\r\n awaitingPong: false,\r\n lastPingAt: 0\r\n });\r\n this.roomNamesByClientId.set(clientId, new Set<string>());\r\n\r\n socket.on(\"message\", (rawData: RawData) => {\r\n this.handleIncomingMessage(client, rawData);\r\n });\r\n\r\n socket.on(\"close\", (code: number, reason: Buffer) => {\r\n this.handleDisconnection(client, code, reason);\r\n });\r\n\r\n socket.on(\"pong\", () => {\r\n this.handleHeartbeatPong(client.socket);\r\n });\r\n\r\n socket.on(\"error\", (error: Error) => {\r\n this.notifyError(\r\n normalizeToError(\r\n error,\r\n `Client socket error detected for client ${client.id}.`\r\n )\r\n );\r\n });\r\n\r\n this.sendInternalHandshake(socket, handshakeState.localPublicKey);\r\n this.notifyConnection(client);\r\n } catch (error) {\r\n this.notifyError(normalizeToError(error, \"Failed to handle client connection.\"));\r\n }\r\n }\r\n\r\n private handleIncomingMessage(client: SecureServerClient, rawData: RawData): void {\r\n try {\r\n let envelope: SecureEnvelope | null = null;\r\n\r\n try {\r\n envelope = parseEnvelope(rawData);\r\n } catch {\r\n envelope = null;\r\n }\r\n\r\n if (envelope?.event === INTERNAL_HANDSHAKE_EVENT) {\r\n this.handleInternalHandshake(client, envelope.data);\r\n return;\r\n }\r\n\r\n if (envelope !== null) {\r\n this.notifyError(\r\n new Error(\r\n `Plaintext event \"${envelope.event}\" was rejected for client ${client.id}.`\r\n )\r\n );\r\n return;\r\n }\r\n\r\n if (!this.isClientHandshakeReady(client.socket)) {\r\n this.notifyError(\r\n new Error(`Encrypted payload was received before handshake completion for client ${client.id}.`)\r\n );\r\n return;\r\n }\r\n\r\n const encryptionKey = this.encryptionKeyBySocket.get(client.socket);\r\n\r\n if (!encryptionKey) {\r\n this.notifyError(new Error(`Missing encryption key for client ${client.id}.`));\r\n return;\r\n }\r\n\r\n let decryptedPayload: string;\r\n\r\n try {\r\n decryptedPayload = decryptSerializedEnvelope(rawData, encryptionKey);\r\n } catch {\r\n console.warn(\"Tampered data detected and dropped\");\r\n return;\r\n }\r\n\r\n const decryptedEnvelope = parseEnvelopeFromText(decryptedPayload);\r\n this.dispatchCustomEvent(decryptedEnvelope.event, decryptedEnvelope.data, client);\r\n } catch (error) {\r\n this.notifyError(normalizeToError(error, \"Failed to process incoming server message.\"));\r\n }\r\n }\r\n\r\n private handleDisconnection(client: SecureServerClient, code: number, reason: Buffer): void {\r\n try {\r\n client.leaveAll();\r\n this.clientsById.delete(client.id);\r\n this.clientIdBySocket.delete(client.socket);\r\n this.handshakeStateBySocket.delete(client.socket);\r\n this.sharedSecretBySocket.delete(client.socket);\r\n this.encryptionKeyBySocket.delete(client.socket);\r\n this.pendingPayloadsBySocket.delete(client.socket);\r\n this.heartbeatStateBySocket.delete(client.socket);\r\n\r\n const decodedReason = decodeCloseReason(reason);\r\n\r\n for (const handler of this.disconnectHandlers) {\r\n try {\r\n handler(client, code, decodedReason);\r\n } catch (handlerError) {\r\n this.notifyError(\r\n normalizeToError(\r\n handlerError,\r\n `Disconnect handler failed for client ${client.id}.`\r\n )\r\n );\r\n }\r\n }\r\n } catch (error) {\r\n this.notifyError(normalizeToError(error, \"Failed to process client disconnection.\"));\r\n }\r\n }\r\n\r\n private dispatchCustomEvent(\r\n event: string,\r\n data: unknown,\r\n client: SecureServerClient\r\n ): void {\r\n const handlers = this.customEventHandlers.get(event);\r\n\r\n if (!handlers || handlers.size === 0) {\r\n return;\r\n }\r\n\r\n for (const handler of handlers) {\r\n try {\r\n handler(data, client);\r\n } catch (error) {\r\n this.notifyError(\r\n normalizeToError(\r\n error,\r\n `Server event handler failed for event ${event}.`\r\n )\r\n );\r\n }\r\n }\r\n }\r\n\r\n private sendRaw(socket: WebSocket, payload: string): void {\r\n try {\r\n if (socket.readyState !== WebSocket.OPEN) {\r\n return;\r\n }\r\n\r\n socket.send(payload);\r\n } catch (error) {\r\n this.notifyError(normalizeToError(error, \"Failed to send server payload.\"));\r\n }\r\n }\r\n\r\n private sendEncryptedEnvelope(socket: WebSocket, envelope: SecureEnvelope): void {\r\n try {\r\n if (socket.readyState !== WebSocket.OPEN) {\r\n return;\r\n }\r\n\r\n const encryptionKey = this.encryptionKeyBySocket.get(socket);\r\n\r\n if (!encryptionKey) {\r\n throw new Error(\"Missing encryption key for connected socket.\");\r\n }\r\n\r\n const encryptedPayload = encryptSerializedEnvelope(\r\n serializeEnvelope(envelope.event, envelope.data),\r\n encryptionKey\r\n );\r\n\r\n socket.send(encryptedPayload);\r\n } catch (error) {\r\n this.notifyError(normalizeToError(error, \"Failed to send encrypted server payload.\"));\r\n }\r\n }\r\n\r\n private notifyConnection(client: SecureServerClient): void {\r\n for (const handler of this.connectionHandlers) {\r\n try {\r\n handler(client);\r\n } catch (error) {\r\n this.notifyError(\r\n normalizeToError(error, `Connection handler failed for client ${client.id}.`)\r\n );\r\n }\r\n }\r\n }\r\n\r\n private notifyReady(client: SecureServerClient): void {\r\n for (const handler of this.readyHandlers) {\r\n try {\r\n handler(client);\r\n } catch (error) {\r\n this.notifyError(\r\n normalizeToError(error, `Ready handler failed for client ${client.id}.`)\r\n );\r\n }\r\n }\r\n }\r\n\r\n private notifyError(error: Error): void {\r\n if (this.errorHandlers.size === 0) {\r\n return;\r\n }\r\n\r\n for (const handler of this.errorHandlers) {\r\n try {\r\n handler(error);\r\n } catch {\r\n // Error handlers should not throw into the event loop.\r\n }\r\n }\r\n }\r\n\r\n private createServerHandshakeState(): ServerHandshakeState {\r\n const { ecdh, localPublicKey } = createEphemeralHandshakeState();\r\n\r\n return {\r\n ecdh,\r\n localPublicKey,\r\n isReady: false\r\n };\r\n }\r\n\r\n private sendInternalHandshake(socket: WebSocket, localPublicKey: string): void {\r\n this.sendRaw(\r\n socket,\r\n serializeEnvelope(INTERNAL_HANDSHAKE_EVENT, {\r\n publicKey: localPublicKey\r\n })\r\n );\r\n }\r\n\r\n private handleInternalHandshake(client: SecureServerClient, data: unknown): void {\r\n try {\r\n const payload = parseHandshakePayload(data);\r\n const handshakeState = this.handshakeStateBySocket.get(client.socket);\r\n\r\n if (!handshakeState) {\r\n throw new Error(`Missing handshake state for client ${client.id}.`);\r\n }\r\n\r\n if (handshakeState.isReady) {\r\n return;\r\n }\r\n\r\n const remotePublicKey = Buffer.from(payload.publicKey, \"base64\");\r\n const sharedSecret = handshakeState.ecdh.computeSecret(remotePublicKey);\r\n const encryptionKey = deriveEncryptionKey(sharedSecret);\r\n\r\n this.sharedSecretBySocket.set(client.socket, sharedSecret);\r\n this.encryptionKeyBySocket.set(client.socket, encryptionKey);\r\n handshakeState.isReady = true;\r\n\r\n this.flushQueuedPayloads(client.socket);\r\n this.notifyReady(client);\r\n } catch (error) {\r\n this.notifyError(normalizeToError(error, \"Failed to complete server handshake.\"));\r\n }\r\n }\r\n\r\n private isClientHandshakeReady(socket: WebSocket): boolean {\r\n return this.handshakeStateBySocket.get(socket)?.isReady ?? false;\r\n }\r\n\r\n private sendOrQueuePayload(socket: WebSocket, envelope: SecureEnvelope): void {\r\n if (!this.isClientHandshakeReady(socket)) {\r\n this.queuePayload(socket, envelope);\r\n return;\r\n }\r\n\r\n this.sendEncryptedEnvelope(socket, envelope);\r\n }\r\n\r\n private queuePayload(socket: WebSocket, envelope: SecureEnvelope): void {\r\n const pendingPayloads = this.pendingPayloadsBySocket.get(socket) ?? [];\r\n pendingPayloads.push(envelope);\r\n this.pendingPayloadsBySocket.set(socket, pendingPayloads);\r\n }\r\n\r\n private flushQueuedPayloads(socket: WebSocket): void {\r\n const pendingPayloads = this.pendingPayloadsBySocket.get(socket);\r\n\r\n if (!pendingPayloads || pendingPayloads.length === 0) {\r\n return;\r\n }\r\n\r\n this.pendingPayloadsBySocket.delete(socket);\r\n\r\n for (const envelope of pendingPayloads) {\r\n this.sendEncryptedEnvelope(socket, envelope);\r\n }\r\n }\r\n\r\n private createSecureServerClient(\r\n clientId: string,\r\n socket: WebSocket,\r\n request: IncomingMessage\r\n ): SecureServerClient {\r\n return {\r\n id: clientId,\r\n socket,\r\n request,\r\n join: (room: string): boolean => this.joinClientToRoom(clientId, room),\r\n leave: (room: string): boolean => this.leaveClientFromRoom(clientId, room),\r\n leaveAll: (): number => this.leaveClientFromAllRooms(clientId)\r\n };\r\n }\r\n\r\n private normalizeRoomName(room: string): string {\r\n if (typeof room !== \"string\") {\r\n throw new Error(\"Room name must be a string.\");\r\n }\r\n\r\n const normalizedRoom = room.trim();\r\n\r\n if (normalizedRoom.length === 0) {\r\n throw new Error(\"Room name cannot be empty.\");\r\n }\r\n\r\n return normalizedRoom;\r\n }\r\n\r\n private joinClientToRoom(clientId: string, room: string): boolean {\r\n const normalizedRoom = this.normalizeRoomName(room);\r\n\r\n if (!this.clientsById.has(clientId)) {\r\n return false;\r\n }\r\n\r\n const clientRooms = this.roomNamesByClientId.get(clientId) ?? new Set<string>();\r\n\r\n if (clientRooms.has(normalizedRoom)) {\r\n this.roomNamesByClientId.set(clientId, clientRooms);\r\n return false;\r\n }\r\n\r\n clientRooms.add(normalizedRoom);\r\n this.roomNamesByClientId.set(clientId, clientRooms);\r\n\r\n const roomMembers = this.roomMembersByName.get(normalizedRoom) ?? new Set<string>();\r\n roomMembers.add(clientId);\r\n this.roomMembersByName.set(normalizedRoom, roomMembers);\r\n\r\n return true;\r\n }\r\n\r\n private leaveClientFromRoom(clientId: string, room: string): boolean {\r\n const normalizedRoom = this.normalizeRoomName(room);\r\n const clientRooms = this.roomNamesByClientId.get(clientId);\r\n\r\n if (!clientRooms || !clientRooms.delete(normalizedRoom)) {\r\n return false;\r\n }\r\n\r\n if (clientRooms.size === 0) {\r\n this.roomNamesByClientId.delete(clientId);\r\n }\r\n\r\n const roomMembers = this.roomMembersByName.get(normalizedRoom);\r\n\r\n if (roomMembers) {\r\n roomMembers.delete(clientId);\r\n\r\n if (roomMembers.size === 0) {\r\n this.roomMembersByName.delete(normalizedRoom);\r\n }\r\n }\r\n\r\n return true;\r\n }\r\n\r\n private leaveClientFromAllRooms(clientId: string): number {\r\n const clientRooms = this.roomNamesByClientId.get(clientId);\r\n\r\n if (!clientRooms || clientRooms.size === 0) {\r\n this.roomNamesByClientId.delete(clientId);\r\n return 0;\r\n }\r\n\r\n const roomNames = [...clientRooms];\r\n this.roomNamesByClientId.delete(clientId);\r\n\r\n for (const roomName of roomNames) {\r\n const roomMembers = this.roomMembersByName.get(roomName);\r\n\r\n if (!roomMembers) {\r\n continue;\r\n }\r\n\r\n roomMembers.delete(clientId);\r\n\r\n if (roomMembers.size === 0) {\r\n this.roomMembersByName.delete(roomName);\r\n }\r\n }\r\n\r\n return roomNames.length;\r\n }\r\n\r\n private emitToRoom(room: string, event: string, data: unknown): void {\r\n if (isReservedEmitEvent(event)) {\r\n throw new Error(`The event \"${event}\" is reserved and cannot be emitted manually.`);\r\n }\r\n\r\n const roomMembers = this.roomMembersByName.get(room);\r\n\r\n if (!roomMembers || roomMembers.size === 0) {\r\n return;\r\n }\r\n\r\n const envelope: SecureEnvelope = { event, data };\r\n\r\n for (const clientId of roomMembers) {\r\n const client = this.clientsById.get(clientId);\r\n\r\n if (!client) {\r\n continue;\r\n }\r\n\r\n this.sendOrQueuePayload(client.socket, envelope);\r\n }\r\n }\r\n}\r\n\r\nexport class SecureClient {\r\n private socket: WebSocket | null = null;\r\n\r\n private readonly reconnectConfig: Required<SecureClientReconnectOptions>;\r\n\r\n private reconnectAttemptCount = 0;\r\n\r\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\r\n\r\n private isManualDisconnectRequested = false;\r\n\r\n private readonly customEventHandlers = new Map<string, Set<SecureClientEventHandler>>();\r\n\r\n private readonly connectHandlers = new Set<SecureClientConnectHandler>();\r\n\r\n private readonly disconnectHandlers = new Set<SecureClientDisconnectHandler>();\r\n\r\n private readonly readyHandlers = new Set<SecureClientReadyHandler>();\r\n\r\n private readonly errorHandlers = new Set<SecureErrorHandler>();\r\n\r\n private handshakeState: ClientHandshakeState | null = null;\r\n\r\n private pendingPayloadQueue: SecureEnvelope[] = [];\r\n\r\n public constructor(\r\n private readonly url: string,\r\n private readonly options: SecureClientOptions = {}\r\n ) {\r\n this.reconnectConfig = this.resolveReconnectConfig(this.options.reconnect);\r\n\r\n if (this.options.autoConnect ?? true) {\r\n this.connect();\r\n }\r\n }\r\n\r\n public get readyState(): number | null {\r\n return this.socket?.readyState ?? null;\r\n }\r\n\r\n public isConnected(): boolean {\r\n return this.socket?.readyState === WebSocket.OPEN;\r\n }\r\n\r\n public connect(): void {\r\n try {\r\n if (\r\n this.socket &&\r\n (this.socket.readyState === WebSocket.OPEN ||\r\n this.socket.readyState === WebSocket.CONNECTING)\r\n ) {\r\n return;\r\n }\r\n\r\n this.clearReconnectTimer();\r\n this.isManualDisconnectRequested = false;\r\n\r\n const socket = this.createSocket();\r\n this.socket = socket;\r\n this.handshakeState = this.createClientHandshakeState();\r\n this.pendingPayloadQueue = [];\r\n this.bindSocketEvents(socket);\r\n } catch (error) {\r\n this.notifyError(normalizeToError(error, \"Failed to connect client.\"));\r\n\r\n if (!this.isManualDisconnectRequested) {\r\n this.scheduleReconnect();\r\n }\r\n }\r\n }\r\n\r\n public disconnect(\r\n code: number = DEFAULT_CLOSE_CODE,\r\n reason: string = DEFAULT_CLOSE_REASON\r\n ): void {\r\n try {\r\n this.isManualDisconnectRequested = true;\r\n this.clearReconnectTimer();\r\n\r\n if (!this.socket) {\r\n return;\r\n }\r\n\r\n if (\r\n this.socket.readyState === WebSocket.CLOSING ||\r\n this.socket.readyState === WebSocket.CLOSED\r\n ) {\r\n return;\r\n }\r\n\r\n this.socket.close(code, reason);\r\n } catch (error) {\r\n this.notifyError(normalizeToError(error, \"Failed to disconnect client.\"));\r\n }\r\n }\r\n\r\n public on(event: \"connect\", handler: SecureClientConnectHandler): this;\r\n public on(event: \"disconnect\", handler: SecureClientDisconnectHandler): this;\r\n public on(event: \"ready\", handler: SecureClientReadyHandler): this;\r\n public on(event: \"error\", handler: SecureErrorHandler): this;\r\n public on(event: string, handler: SecureClientEventHandler): this;\r\n public on(event: string, handler: unknown): this {\r\n try {\r\n if (event === \"connect\") {\r\n this.connectHandlers.add(handler as SecureClientConnectHandler);\r\n return this;\r\n }\r\n\r\n if (event === \"disconnect\") {\r\n this.disconnectHandlers.add(handler as SecureClientDisconnectHandler);\r\n return this;\r\n }\r\n\r\n if (event === READY_EVENT) {\r\n this.readyHandlers.add(handler as SecureClientReadyHandler);\r\n return this;\r\n }\r\n\r\n if (event === \"error\") {\r\n this.errorHandlers.add(handler as SecureErrorHandler);\r\n return this;\r\n }\r\n\r\n if (event === INTERNAL_HANDSHAKE_EVENT) {\r\n throw new Error(`The event \"${INTERNAL_HANDSHAKE_EVENT}\" is reserved for internal use.`);\r\n }\r\n\r\n const typedHandler = handler as SecureClientEventHandler;\r\n const listeners = this.customEventHandlers.get(event) ?? new Set<SecureClientEventHandler>();\r\n listeners.add(typedHandler);\r\n this.customEventHandlers.set(event, listeners);\r\n } catch (error) {\r\n this.notifyError(\r\n normalizeToError(error, \"Failed to register client event handler.\")\r\n );\r\n }\r\n\r\n return this;\r\n }\r\n\r\n public off(event: \"connect\", handler: SecureClientConnectHandler): this;\r\n public off(event: \"disconnect\", handler: SecureClientDisconnectHandler): this;\r\n public off(event: \"ready\", handler: SecureClientReadyHandler): this;\r\n public off(event: \"error\", handler: SecureErrorHandler): this;\r\n public off(event: string, handler: SecureClientEventHandler): this;\r\n public off(event: string, handler: unknown): this {\r\n try {\r\n if (event === \"connect\") {\r\n this.connectHandlers.delete(handler as SecureClientConnectHandler);\r\n return this;\r\n }\r\n\r\n if (event === \"disconnect\") {\r\n this.disconnectHandlers.delete(handler as SecureClientDisconnectHandler);\r\n return this;\r\n }\r\n\r\n if (event === READY_EVENT) {\r\n this.readyHandlers.delete(handler as SecureClientReadyHandler);\r\n return this;\r\n }\r\n\r\n if (event === \"error\") {\r\n this.errorHandlers.delete(handler as SecureErrorHandler);\r\n return this;\r\n }\r\n\r\n if (event === INTERNAL_HANDSHAKE_EVENT) {\r\n return this;\r\n }\r\n\r\n const listeners = this.customEventHandlers.get(event);\r\n\r\n if (!listeners) {\r\n return this;\r\n }\r\n\r\n listeners.delete(handler as SecureClientEventHandler);\r\n\r\n if (listeners.size === 0) {\r\n this.customEventHandlers.delete(event);\r\n }\r\n } catch (error) {\r\n this.notifyError(\r\n normalizeToError(error, \"Failed to remove client event handler.\")\r\n );\r\n }\r\n\r\n return this;\r\n }\r\n\r\n public emit(event: string, data: unknown): boolean {\r\n try {\r\n if (isReservedEmitEvent(event)) {\r\n throw new Error(`The event \"${event}\" is reserved and cannot be emitted manually.`);\r\n }\r\n\r\n if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {\r\n throw new Error(\"Client socket is not connected.\");\r\n }\r\n\r\n const envelope: SecureEnvelope = { event, data };\r\n\r\n if (!this.isHandshakeReady()) {\r\n this.pendingPayloadQueue.push(envelope);\r\n return true;\r\n }\r\n\r\n this.sendEncryptedEnvelope(envelope);\r\n return true;\r\n } catch (error) {\r\n this.notifyError(normalizeToError(error, \"Failed to emit client event.\"));\r\n return false;\r\n }\r\n }\r\n\r\n private resolveReconnectConfig(\r\n reconnectOptions: boolean | SecureClientReconnectOptions | undefined\r\n ): Required<SecureClientReconnectOptions> {\r\n if (typeof reconnectOptions === \"boolean\") {\r\n return {\r\n enabled: reconnectOptions,\r\n initialDelayMs: DEFAULT_RECONNECT_INITIAL_DELAY_MS,\r\n maxDelayMs: DEFAULT_RECONNECT_MAX_DELAY_MS,\r\n factor: DEFAULT_RECONNECT_FACTOR,\r\n jitterRatio: DEFAULT_RECONNECT_JITTER_RATIO,\r\n maxAttempts: null\r\n };\r\n }\r\n\r\n const initialDelayMs = reconnectOptions?.initialDelayMs ?? DEFAULT_RECONNECT_INITIAL_DELAY_MS;\r\n const maxDelayMs = reconnectOptions?.maxDelayMs ?? DEFAULT_RECONNECT_MAX_DELAY_MS;\r\n const factor = reconnectOptions?.factor ?? DEFAULT_RECONNECT_FACTOR;\r\n const jitterRatio = reconnectOptions?.jitterRatio ?? DEFAULT_RECONNECT_JITTER_RATIO;\r\n const maxAttempts = reconnectOptions?.maxAttempts ?? null;\r\n\r\n if (!Number.isFinite(initialDelayMs) || initialDelayMs < 0) {\r\n throw new Error(\"Client reconnect initialDelayMs must be a non-negative number.\");\r\n }\r\n\r\n if (!Number.isFinite(maxDelayMs) || maxDelayMs < 0) {\r\n throw new Error(\"Client reconnect maxDelayMs must be a non-negative number.\");\r\n }\r\n\r\n if (maxDelayMs < initialDelayMs) {\r\n throw new Error(\"Client reconnect maxDelayMs must be greater than or equal to initialDelayMs.\");\r\n }\r\n\r\n if (!Number.isFinite(factor) || factor < 1) {\r\n throw new Error(\"Client reconnect factor must be greater than or equal to 1.\");\r\n }\r\n\r\n if (!Number.isFinite(jitterRatio) || jitterRatio < 0 || jitterRatio > 1) {\r\n throw new Error(\"Client reconnect jitterRatio must be between 0 and 1.\");\r\n }\r\n\r\n if (\r\n maxAttempts !== null &&\r\n (!Number.isInteger(maxAttempts) || maxAttempts < 0)\r\n ) {\r\n throw new Error(\"Client reconnect maxAttempts must be a non-negative integer or null.\");\r\n }\r\n\r\n return {\r\n enabled: reconnectOptions?.enabled ?? true,\r\n initialDelayMs,\r\n maxDelayMs,\r\n factor,\r\n jitterRatio,\r\n maxAttempts\r\n };\r\n }\r\n\r\n private scheduleReconnect(): void {\r\n if (!this.reconnectConfig.enabled || this.reconnectTimer) {\r\n return;\r\n }\r\n\r\n if (\r\n this.reconnectConfig.maxAttempts !== null &&\r\n this.reconnectAttemptCount >= this.reconnectConfig.maxAttempts\r\n ) {\r\n return;\r\n }\r\n\r\n this.reconnectAttemptCount += 1;\r\n const delayMs = this.computeReconnectDelay(this.reconnectAttemptCount);\r\n\r\n this.reconnectTimer = setTimeout(() => {\r\n this.reconnectTimer = null;\r\n this.connect();\r\n }, delayMs);\r\n\r\n this.reconnectTimer.unref?.();\r\n }\r\n\r\n private computeReconnectDelay(attemptNumber: number): number {\r\n const exponentialDelay = Math.min(\r\n this.reconnectConfig.maxDelayMs,\r\n this.reconnectConfig.initialDelayMs *\r\n Math.pow(this.reconnectConfig.factor, Math.max(0, attemptNumber - 1))\r\n );\r\n\r\n if (this.reconnectConfig.jitterRatio === 0 || exponentialDelay === 0) {\r\n return Math.round(exponentialDelay);\r\n }\r\n\r\n const jitterDelta = exponentialDelay * this.reconnectConfig.jitterRatio;\r\n const jitterOffset = (Math.random() * 2 - 1) * jitterDelta;\r\n\r\n return Math.max(0, Math.round(exponentialDelay + jitterOffset));\r\n }\r\n\r\n private clearReconnectTimer(): void {\r\n if (!this.reconnectTimer) {\r\n return;\r\n }\r\n\r\n clearTimeout(this.reconnectTimer);\r\n this.reconnectTimer = null;\r\n }\r\n\r\n private createSocket(): WebSocket {\r\n if (this.options.protocols !== undefined) {\r\n return new WebSocket(this.url, this.options.protocols, this.options.wsOptions);\r\n }\r\n\r\n if (this.options.wsOptions !== undefined) {\r\n return new WebSocket(this.url, this.options.wsOptions);\r\n }\r\n\r\n return new WebSocket(this.url);\r\n }\r\n\r\n private bindSocketEvents(socket: WebSocket): void {\r\n socket.on(\"open\", () => {\r\n this.clearReconnectTimer();\r\n this.reconnectAttemptCount = 0;\r\n this.sendInternalHandshake();\r\n this.notifyConnect();\r\n });\r\n\r\n socket.on(\"message\", (rawData: RawData) => {\r\n this.handleIncomingMessage(rawData);\r\n });\r\n\r\n socket.on(\"close\", (code: number, reason: Buffer) => {\r\n this.handleDisconnect(code, reason);\r\n });\r\n\r\n socket.on(\"error\", (error: Error) => {\r\n this.notifyError(normalizeToError(error, \"Client socket encountered an error.\"));\r\n });\r\n }\r\n\r\n private handleIncomingMessage(rawData: RawData): void {\r\n try {\r\n let envelope: SecureEnvelope | null = null;\r\n\r\n try {\r\n envelope = parseEnvelope(rawData);\r\n } catch {\r\n envelope = null;\r\n }\r\n\r\n if (envelope?.event === INTERNAL_HANDSHAKE_EVENT) {\r\n this.handleInternalHandshake(envelope.data);\r\n return;\r\n }\r\n\r\n if (envelope !== null) {\r\n this.notifyError(\r\n new Error(`Plaintext event \"${envelope.event}\" was rejected on client.`)\r\n );\r\n return;\r\n }\r\n\r\n if (!this.isHandshakeReady()) {\r\n this.notifyError(new Error(\"Encrypted payload was received before handshake completion.\"));\r\n return;\r\n }\r\n\r\n const encryptionKey = this.handshakeState?.encryptionKey;\r\n\r\n if (!encryptionKey) {\r\n this.notifyError(new Error(\"Missing encryption key for client payload decryption.\"));\r\n return;\r\n }\r\n\r\n let decryptedPayload: string;\r\n\r\n try {\r\n decryptedPayload = decryptSerializedEnvelope(rawData, encryptionKey);\r\n } catch {\r\n console.warn(\"Tampered data detected and dropped\");\r\n return;\r\n }\r\n\r\n const decryptedEnvelope = parseEnvelopeFromText(decryptedPayload);\r\n this.dispatchCustomEvent(decryptedEnvelope.event, decryptedEnvelope.data);\r\n } catch (error) {\r\n this.notifyError(normalizeToError(error, \"Failed to process incoming client message.\"));\r\n }\r\n }\r\n\r\n private handleDisconnect(code: number, reason: Buffer): void {\r\n try {\r\n this.socket = null;\r\n this.handshakeState = null;\r\n this.pendingPayloadQueue = [];\r\n const decodedReason = decodeCloseReason(reason);\r\n\r\n for (const handler of this.disconnectHandlers) {\r\n try {\r\n handler(code, decodedReason);\r\n } catch (handlerError) {\r\n this.notifyError(\r\n normalizeToError(handlerError, \"Client disconnect handler failed.\")\r\n );\r\n }\r\n }\r\n\r\n if (!this.isManualDisconnectRequested) {\r\n this.scheduleReconnect();\r\n }\r\n\r\n this.isManualDisconnectRequested = false;\r\n } catch (error) {\r\n this.notifyError(normalizeToError(error, \"Failed to handle client disconnect.\"));\r\n }\r\n }\r\n\r\n private dispatchCustomEvent(event: string, data: unknown): void {\r\n const handlers = this.customEventHandlers.get(event);\r\n\r\n if (!handlers || handlers.size === 0) {\r\n return;\r\n }\r\n\r\n for (const handler of handlers) {\r\n try {\r\n handler(data);\r\n } catch (error) {\r\n this.notifyError(\r\n normalizeToError(error, `Client event handler failed for event ${event}.`)\r\n );\r\n }\r\n }\r\n }\r\n\r\n private notifyConnect(): void {\r\n for (const handler of this.connectHandlers) {\r\n try {\r\n handler();\r\n } catch (error) {\r\n this.notifyError(normalizeToError(error, \"Client connect handler failed.\"));\r\n }\r\n }\r\n }\r\n\r\n private notifyReady(): void {\r\n for (const handler of this.readyHandlers) {\r\n try {\r\n handler();\r\n } catch (error) {\r\n this.notifyError(normalizeToError(error, \"Client ready handler failed.\"));\r\n }\r\n }\r\n }\r\n\r\n private notifyError(error: Error): void {\r\n if (this.errorHandlers.size === 0) {\r\n return;\r\n }\r\n\r\n for (const handler of this.errorHandlers) {\r\n try {\r\n handler(error);\r\n } catch {\r\n // Error handlers should not throw into the event loop.\r\n }\r\n }\r\n }\r\n\r\n private sendEncryptedEnvelope(envelope: SecureEnvelope): void {\r\n try {\r\n if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {\r\n throw new Error(\"Client socket is not connected.\");\r\n }\r\n\r\n const encryptionKey = this.handshakeState?.encryptionKey;\r\n\r\n if (!encryptionKey) {\r\n throw new Error(\"Missing encryption key for client payload encryption.\");\r\n }\r\n\r\n const encryptedPayload = encryptSerializedEnvelope(\r\n serializeEnvelope(envelope.event, envelope.data),\r\n encryptionKey\r\n );\r\n\r\n this.socket.send(encryptedPayload);\r\n } catch (error) {\r\n this.notifyError(normalizeToError(error, \"Failed to send encrypted client payload.\"));\r\n }\r\n }\r\n\r\n private createClientHandshakeState(): ClientHandshakeState {\r\n const { ecdh, localPublicKey } = createEphemeralHandshakeState();\r\n\r\n return {\r\n ecdh,\r\n localPublicKey,\r\n isReady: false,\r\n sharedSecret: null,\r\n encryptionKey: null\r\n };\r\n }\r\n\r\n private sendInternalHandshake(): void {\r\n try {\r\n if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {\r\n return;\r\n }\r\n\r\n if (!this.handshakeState) {\r\n throw new Error(\"Missing client handshake state.\");\r\n }\r\n\r\n this.socket.send(\r\n serializeEnvelope(INTERNAL_HANDSHAKE_EVENT, {\r\n publicKey: this.handshakeState.localPublicKey\r\n })\r\n );\r\n } catch (error) {\r\n this.notifyError(normalizeToError(error, \"Failed to send client handshake payload.\"));\r\n }\r\n }\r\n\r\n private handleInternalHandshake(data: unknown): void {\r\n try {\r\n const payload = parseHandshakePayload(data);\r\n\r\n if (!this.handshakeState) {\r\n throw new Error(\"Missing client handshake state.\");\r\n }\r\n\r\n if (this.handshakeState.isReady) {\r\n return;\r\n }\r\n\r\n const remotePublicKey = Buffer.from(payload.publicKey, \"base64\");\r\n const sharedSecret = this.handshakeState.ecdh.computeSecret(remotePublicKey);\r\n\r\n this.handshakeState.sharedSecret = sharedSecret;\r\n this.handshakeState.encryptionKey = deriveEncryptionKey(sharedSecret);\r\n this.handshakeState.isReady = true;\r\n\r\n this.flushPendingPayloadQueue();\r\n this.notifyReady();\r\n } catch (error) {\r\n this.notifyError(normalizeToError(error, \"Failed to complete client handshake.\"));\r\n }\r\n }\r\n\r\n private isHandshakeReady(): boolean {\r\n return this.handshakeState?.isReady ?? false;\r\n }\r\n\r\n private flushPendingPayloadQueue(): void {\r\n if (!this.socket || this.socket.readyState !== WebSocket.OPEN || !this.isHandshakeReady()) {\r\n return;\r\n }\r\n\r\n const pendingPayloads = this.pendingPayloadQueue;\r\n this.pendingPayloadQueue = [];\r\n\r\n for (const envelope of pendingPayloads) {\r\n this.sendEncryptedEnvelope(envelope);\r\n }\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":["createECDH","createHash","randomBytes","createCipheriv","createDecipheriv","WebSocketServer","WebSocket","randomUUID"],"mappings":"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","file":"index.cjs","sourcesContent":["import {\r\n createCipheriv,\r\n createDecipheriv,\r\n createECDH,\r\n createHash,\r\n randomBytes,\r\n randomUUID\r\n} from \"node:crypto\";\r\nimport type { ECDH } from \"node:crypto\";\r\nimport type { IncomingMessage } from \"node:http\";\r\nimport WebSocket, { WebSocketServer } from \"ws\";\r\nimport type {\r\n ClientOptions,\r\n RawData,\r\n ServerOptions as WebSocketServerOptions\r\n} from \"ws\";\r\n\r\nconst DEFAULT_CLOSE_CODE = 1000;\r\nconst DEFAULT_CLOSE_REASON = \"\";\r\nconst INTERNAL_HANDSHAKE_EVENT = \"__handshake\";\r\nconst INTERNAL_RPC_REQUEST_EVENT = \"__rpc:req\";\r\nconst INTERNAL_RPC_RESPONSE_EVENT = \"__rpc:res\";\r\nconst READY_EVENT = \"ready\";\r\nconst HANDSHAKE_CURVE = \"prime256v1\";\r\nconst ENCRYPTION_ALGORITHM = \"aes-256-gcm\";\r\nconst GCM_IV_LENGTH = 12;\r\nconst GCM_AUTH_TAG_LENGTH = 16;\r\nconst ENCRYPTION_KEY_LENGTH = 32;\r\nconst ENCRYPTED_PACKET_VERSION = 1;\r\nconst ENCRYPTED_PACKET_PREFIX_LENGTH = 1 + GCM_IV_LENGTH + GCM_AUTH_TAG_LENGTH;\r\nconst DEFAULT_HEARTBEAT_INTERVAL_MS = 15_000;\r\nconst DEFAULT_HEARTBEAT_TIMEOUT_MS = 15_000;\r\nconst DEFAULT_RECONNECT_INITIAL_DELAY_MS = 250;\r\nconst DEFAULT_RECONNECT_MAX_DELAY_MS = 10_000;\r\nconst DEFAULT_RECONNECT_FACTOR = 2;\r\nconst DEFAULT_RECONNECT_JITTER_RATIO = 0.2;\r\nconst DEFAULT_RPC_TIMEOUT_MS = 5_000;\r\n\r\ninterface HandshakePayload {\r\n publicKey: string;\r\n}\r\n\r\ninterface ServerHandshakeState {\r\n ecdh: ECDH;\r\n localPublicKey: string;\r\n isReady: boolean;\r\n}\r\n\r\ninterface ClientHandshakeState {\r\n ecdh: ECDH;\r\n localPublicKey: string;\r\n isReady: boolean;\r\n sharedSecret: Buffer | null;\r\n encryptionKey: Buffer | null;\r\n}\r\n\r\ninterface EncryptedPacketParts {\r\n iv: Buffer;\r\n authTag: Buffer;\r\n ciphertext: Buffer;\r\n}\r\n\r\ninterface RpcRequestPayload {\r\n id: string;\r\n event: string;\r\n data: unknown;\r\n}\r\n\r\ninterface RpcResponsePayload {\r\n id: string;\r\n ok: boolean;\r\n data?: unknown;\r\n error?: string;\r\n}\r\n\r\ninterface PendingRpcRequest {\r\n resolve: (value: unknown) => void;\r\n reject: (reason?: unknown) => void;\r\n timeoutHandle: ReturnType<typeof setTimeout>;\r\n}\r\n\r\nexport interface SecureEnvelope<TData = unknown> {\r\n event: string;\r\n data: TData;\r\n}\r\n\r\nexport interface SecureAckOptions {\r\n timeoutMs?: number;\r\n}\r\n\r\nexport type SecureAckCallback = (\r\n error: Error | null,\r\n response?: unknown\r\n) => void;\r\n\r\nexport interface SecureServerHeartbeatOptions {\r\n enabled?: boolean;\r\n intervalMs?: number;\r\n timeoutMs?: number;\r\n}\r\n\r\nexport interface SecureServerOptions extends WebSocketServerOptions {\r\n heartbeat?: SecureServerHeartbeatOptions;\r\n}\r\n\r\nexport interface SecureClientReconnectOptions {\r\n enabled?: boolean;\r\n initialDelayMs?: number;\r\n maxDelayMs?: number;\r\n factor?: number;\r\n jitterRatio?: number;\r\n maxAttempts?: number | null;\r\n}\r\n\r\nexport interface SecureClientOptions {\r\n protocols?: string | string[];\r\n wsOptions?: ClientOptions;\r\n autoConnect?: boolean;\r\n reconnect?: boolean | SecureClientReconnectOptions;\r\n}\r\n\r\nexport interface SecureServerClient {\r\n id: string;\r\n socket: WebSocket;\r\n request: IncomingMessage;\r\n emit: (\r\n event: string,\r\n data: unknown,\r\n callbackOrOptions?: SecureAckCallback | SecureAckOptions,\r\n maybeCallback?: SecureAckCallback\r\n ) => boolean | Promise<unknown>;\r\n join: (room: string) => boolean;\r\n leave: (room: string) => boolean;\r\n leaveAll: () => number;\r\n}\r\n\r\nexport interface SecureServerRoomOperator {\r\n emit: (event: string, data: unknown) => SecureServer;\r\n}\r\n\r\nexport type SecureErrorHandler = (error: Error) => void;\r\n\r\nexport type SecureServerEventHandler = (\r\n data: unknown,\r\n client: SecureServerClient\r\n) => unknown | Promise<unknown>;\r\n\r\nexport type SecureServerConnectionHandler = (\r\n client: SecureServerClient\r\n) => void;\r\n\r\nexport type SecureServerDisconnectHandler = (\r\n client: SecureServerClient,\r\n code: number,\r\n reason: string\r\n) => void;\r\n\r\nexport type SecureServerReadyHandler = (client: SecureServerClient) => void;\r\n\r\nexport type SecureClientEventHandler = (data: unknown) => unknown | Promise<unknown>;\r\n\r\nexport type SecureClientConnectHandler = () => void;\r\n\r\nexport type SecureClientDisconnectHandler = (\r\n code: number,\r\n reason: string\r\n) => void;\r\n\r\nexport type SecureClientReadyHandler = () => void;\r\n\r\nexport type SecureServerLifecycleEvent =\r\n | \"connection\"\r\n | \"disconnect\"\r\n | \"ready\"\r\n | \"error\";\r\n\r\nexport type SecureClientLifecycleEvent =\r\n | \"connect\"\r\n | \"disconnect\"\r\n | \"ready\"\r\n | \"error\";\r\n\r\nexport interface SecureServerEventMap {\r\n connection: SecureServerConnectionHandler;\r\n disconnect: SecureServerDisconnectHandler;\r\n ready: SecureServerReadyHandler;\r\n error: SecureErrorHandler;\r\n}\r\n\r\nexport interface SecureClientEventMap {\r\n connect: SecureClientConnectHandler;\r\n disconnect: SecureClientDisconnectHandler;\r\n ready: SecureClientReadyHandler;\r\n error: SecureErrorHandler;\r\n}\r\n\r\nfunction normalizeToError(error: unknown, fallbackMessage: string): Error {\r\n if (error instanceof Error) {\r\n return error;\r\n }\r\n\r\n if (typeof error === \"string\" && error.trim().length > 0) {\r\n return new Error(error);\r\n }\r\n\r\n return new Error(fallbackMessage);\r\n}\r\n\r\nfunction decodeRawData(rawData: RawData): string {\r\n if (typeof rawData === \"string\") {\r\n return rawData;\r\n }\r\n\r\n if (rawData instanceof ArrayBuffer) {\r\n return Buffer.from(rawData).toString(\"utf8\");\r\n }\r\n\r\n if (Array.isArray(rawData)) {\r\n return Buffer.concat(rawData).toString(\"utf8\");\r\n }\r\n\r\n return rawData.toString(\"utf8\");\r\n}\r\n\r\nfunction rawDataToBuffer(rawData: RawData): Buffer {\r\n if (typeof rawData === \"string\") {\r\n return Buffer.from(rawData, \"utf8\");\r\n }\r\n\r\n if (rawData instanceof ArrayBuffer) {\r\n return Buffer.from(rawData);\r\n }\r\n\r\n if (Array.isArray(rawData)) {\r\n return Buffer.concat(rawData);\r\n }\r\n\r\n return Buffer.from(rawData);\r\n}\r\n\r\nfunction serializeEnvelope(event: string, data: unknown): string {\r\n const envelope: SecureEnvelope = { event, data };\r\n return JSON.stringify(envelope);\r\n}\r\n\r\nfunction parseEnvelope(rawData: RawData): SecureEnvelope {\r\n const decoded = decodeRawData(rawData);\r\n const parsed = JSON.parse(decoded) as Partial<SecureEnvelope>;\r\n\r\n if (\r\n typeof parsed !== \"object\" ||\r\n parsed === null ||\r\n typeof parsed.event !== \"string\"\r\n ) {\r\n throw new Error(\"Invalid message format. Expected { event: string, data: unknown }.\");\r\n }\r\n\r\n return {\r\n event: parsed.event,\r\n data: parsed.data\r\n };\r\n}\r\n\r\nfunction parseEnvelopeFromText(decodedPayload: string): SecureEnvelope {\r\n const parsed = JSON.parse(decodedPayload) as Partial<SecureEnvelope>;\r\n\r\n if (\r\n typeof parsed !== \"object\" ||\r\n parsed === null ||\r\n typeof parsed.event !== \"string\"\r\n ) {\r\n throw new Error(\"Invalid message format. Expected { event: string, data: unknown }.\");\r\n }\r\n\r\n return {\r\n event: parsed.event,\r\n data: parsed.data\r\n };\r\n}\r\n\r\nfunction decodeCloseReason(reason: Buffer): string {\r\n return reason.toString(\"utf8\");\r\n}\r\n\r\nfunction isReservedEmitEvent(event: string): boolean {\r\n return (\r\n event === INTERNAL_HANDSHAKE_EVENT ||\r\n event === INTERNAL_RPC_REQUEST_EVENT ||\r\n event === INTERNAL_RPC_RESPONSE_EVENT ||\r\n event === READY_EVENT\r\n );\r\n}\r\n\r\nfunction isPromiseLike(value: unknown): value is PromiseLike<unknown> {\r\n return typeof value === \"object\" && value !== null && \"then\" in value;\r\n}\r\n\r\nfunction normalizeRpcTimeout(timeoutMs: number | undefined): number {\r\n const resolvedTimeoutMs = timeoutMs ?? DEFAULT_RPC_TIMEOUT_MS;\r\n\r\n if (!Number.isFinite(resolvedTimeoutMs) || resolvedTimeoutMs <= 0) {\r\n throw new Error(\"ACK timeoutMs must be a positive number.\");\r\n }\r\n\r\n return resolvedTimeoutMs;\r\n}\r\n\r\nfunction parseRpcRequestPayload(data: unknown): RpcRequestPayload {\r\n if (typeof data !== \"object\" || data === null) {\r\n throw new Error(\"Invalid RPC request payload format.\");\r\n }\r\n\r\n const payload = data as Partial<RpcRequestPayload>;\r\n\r\n if (typeof payload.id !== \"string\" || payload.id.trim().length === 0) {\r\n throw new Error(\"RPC request payload must include a non-empty id.\");\r\n }\r\n\r\n if (typeof payload.event !== \"string\" || payload.event.trim().length === 0) {\r\n throw new Error(\"RPC request payload must include a non-empty event.\");\r\n }\r\n\r\n return {\r\n id: payload.id,\r\n event: payload.event,\r\n data: payload.data\r\n };\r\n}\r\n\r\nfunction parseRpcResponsePayload(data: unknown): RpcResponsePayload {\r\n if (typeof data !== \"object\" || data === null) {\r\n throw new Error(\"Invalid RPC response payload format.\");\r\n }\r\n\r\n const payload = data as Partial<RpcResponsePayload>;\r\n\r\n if (typeof payload.id !== \"string\" || payload.id.trim().length === 0) {\r\n throw new Error(\"RPC response payload must include a non-empty id.\");\r\n }\r\n\r\n if (typeof payload.ok !== \"boolean\") {\r\n throw new Error(\"RPC response payload must include a boolean ok field.\");\r\n }\r\n\r\n if (payload.error !== undefined && typeof payload.error !== \"string\") {\r\n throw new Error(\"RPC response payload error must be a string when provided.\");\r\n }\r\n\r\n const parsedPayload: RpcResponsePayload = {\r\n id: payload.id,\r\n ok: payload.ok,\r\n data: payload.data\r\n };\r\n\r\n if (payload.error !== undefined) {\r\n parsedPayload.error = payload.error;\r\n }\r\n\r\n return parsedPayload;\r\n}\r\n\r\nfunction resolveAckArguments(\r\n callbackOrOptions?: SecureAckCallback | SecureAckOptions,\r\n maybeCallback?: SecureAckCallback\r\n): {\r\n expectsAck: boolean;\r\n callback?: SecureAckCallback;\r\n timeoutMs: number;\r\n} {\r\n if (callbackOrOptions === undefined && maybeCallback === undefined) {\r\n return {\r\n expectsAck: false,\r\n timeoutMs: DEFAULT_RPC_TIMEOUT_MS\r\n };\r\n }\r\n\r\n if (typeof callbackOrOptions === \"function\") {\r\n if (maybeCallback !== undefined) {\r\n throw new Error(\"ACK callback was provided more than once.\");\r\n }\r\n\r\n return {\r\n expectsAck: true,\r\n callback: callbackOrOptions,\r\n timeoutMs: DEFAULT_RPC_TIMEOUT_MS\r\n };\r\n }\r\n\r\n const options = callbackOrOptions;\r\n\r\n if (options !== undefined && (typeof options !== \"object\" || options === null)) {\r\n throw new Error(\"ACK options must be an object.\");\r\n }\r\n\r\n if (maybeCallback !== undefined && typeof maybeCallback !== \"function\") {\r\n throw new Error(\"ACK callback must be a function.\");\r\n }\r\n\r\n return {\r\n ...(maybeCallback ? { callback: maybeCallback } : {}),\r\n expectsAck: true,\r\n timeoutMs: normalizeRpcTimeout(options?.timeoutMs)\r\n };\r\n}\r\n\r\nfunction createEphemeralHandshakeState(): { ecdh: ECDH; localPublicKey: string } {\r\n const ecdh = createECDH(HANDSHAKE_CURVE);\r\n ecdh.generateKeys();\r\n\r\n return {\r\n ecdh,\r\n localPublicKey: ecdh.getPublicKey(\"base64\")\r\n };\r\n}\r\n\r\nfunction parseHandshakePayload(data: unknown): HandshakePayload {\r\n if (typeof data !== \"object\" || data === null) {\r\n throw new Error(\"Invalid handshake payload format.\");\r\n }\r\n\r\n const payload = data as Partial<HandshakePayload>;\r\n\r\n if (typeof payload.publicKey !== \"string\" || payload.publicKey.length === 0) {\r\n throw new Error(\"Handshake payload must include a non-empty public key.\");\r\n }\r\n\r\n return {\r\n publicKey: payload.publicKey\r\n };\r\n}\r\n\r\nfunction deriveEncryptionKey(sharedSecret: Buffer): Buffer {\r\n const derivedKey = createHash(\"sha256\").update(sharedSecret).digest();\r\n\r\n if (derivedKey.length !== ENCRYPTION_KEY_LENGTH) {\r\n throw new Error(\"Failed to derive a valid AES-256 key.\");\r\n }\r\n\r\n return derivedKey;\r\n}\r\n\r\nfunction encryptSerializedEnvelope(serializedEnvelope: string, encryptionKey: Buffer): Buffer {\r\n const iv = randomBytes(GCM_IV_LENGTH);\r\n const cipher = createCipheriv(ENCRYPTION_ALGORITHM, encryptionKey, iv);\r\n const ciphertext = Buffer.concat([\r\n cipher.update(serializedEnvelope, \"utf8\"),\r\n cipher.final()\r\n ]);\r\n const authTag = cipher.getAuthTag();\r\n\r\n return Buffer.concat([\r\n Buffer.from([ENCRYPTED_PACKET_VERSION]),\r\n iv,\r\n authTag,\r\n ciphertext\r\n ]);\r\n}\r\n\r\nfunction parseEncryptedPacket(rawData: RawData): EncryptedPacketParts {\r\n const packetBuffer = rawDataToBuffer(rawData);\r\n\r\n if (packetBuffer.length <= ENCRYPTED_PACKET_PREFIX_LENGTH) {\r\n throw new Error(\"Encrypted packet is too short.\");\r\n }\r\n\r\n const version = packetBuffer.readUInt8(0);\r\n\r\n if (version !== ENCRYPTED_PACKET_VERSION) {\r\n throw new Error(\"Unsupported encrypted packet version.\");\r\n }\r\n\r\n const ivStart = 1;\r\n const ivEnd = ivStart + GCM_IV_LENGTH;\r\n const authTagStart = ivEnd;\r\n const authTagEnd = authTagStart + GCM_AUTH_TAG_LENGTH;\r\n\r\n const iv = packetBuffer.subarray(ivStart, ivEnd);\r\n const authTag = packetBuffer.subarray(authTagStart, authTagEnd);\r\n const ciphertext = packetBuffer.subarray(authTagEnd);\r\n\r\n if (ciphertext.length === 0) {\r\n throw new Error(\"Encrypted payload is empty.\");\r\n }\r\n\r\n return {\r\n iv,\r\n authTag,\r\n ciphertext\r\n };\r\n}\r\n\r\nfunction decryptSerializedEnvelope(rawData: RawData, encryptionKey: Buffer): string {\r\n const encryptedPacket = parseEncryptedPacket(rawData);\r\n const decipher = createDecipheriv(\r\n ENCRYPTION_ALGORITHM,\r\n encryptionKey,\r\n encryptedPacket.iv\r\n );\r\n\r\n decipher.setAuthTag(encryptedPacket.authTag);\r\n\r\n const plaintext = Buffer.concat([\r\n decipher.update(encryptedPacket.ciphertext),\r\n decipher.final()\r\n ]);\r\n\r\n return plaintext.toString(\"utf8\");\r\n}\r\n\r\nexport class SecureServer {\r\n private readonly socketServer: WebSocketServer;\r\n\r\n private readonly heartbeatConfig: Required<SecureServerHeartbeatOptions>;\r\n\r\n private heartbeatIntervalHandle: ReturnType<typeof setInterval> | null = null;\r\n\r\n private readonly clientsById = new Map<string, SecureServerClient>();\r\n\r\n private readonly clientIdBySocket = new Map<WebSocket, string>();\r\n\r\n private readonly customEventHandlers = new Map<string, Set<SecureServerEventHandler>>();\r\n\r\n private readonly connectionHandlers = new Set<SecureServerConnectionHandler>();\r\n\r\n private readonly disconnectHandlers = new Set<SecureServerDisconnectHandler>();\r\n\r\n private readonly readyHandlers = new Set<SecureServerReadyHandler>();\r\n\r\n private readonly errorHandlers = new Set<SecureErrorHandler>();\r\n\r\n private readonly handshakeStateBySocket = new WeakMap<WebSocket, ServerHandshakeState>();\r\n\r\n private readonly sharedSecretBySocket = new WeakMap<WebSocket, Buffer>();\r\n\r\n private readonly encryptionKeyBySocket = new WeakMap<WebSocket, Buffer>();\r\n\r\n private readonly pendingPayloadsBySocket = new WeakMap<WebSocket, SecureEnvelope[]>();\r\n\r\n private readonly pendingRpcRequestsBySocket = new WeakMap<\r\n WebSocket,\r\n Map<string, PendingRpcRequest>\r\n >();\r\n\r\n private readonly heartbeatStateBySocket = new WeakMap<\r\n WebSocket,\r\n { awaitingPong: boolean; lastPingAt: number }\r\n >();\r\n\r\n private readonly roomMembersByName = new Map<string, Set<string>>();\r\n\r\n private readonly roomNamesByClientId = new Map<string, Set<string>>();\r\n\r\n public constructor(options: SecureServerOptions) {\r\n const { heartbeat, ...socketServerOptions } = options;\r\n\r\n this.heartbeatConfig = this.resolveHeartbeatConfig(heartbeat);\r\n this.socketServer = new WebSocketServer(socketServerOptions);\r\n this.bindSocketServerEvents();\r\n this.startHeartbeatLoop();\r\n }\r\n\r\n public get clientCount(): number {\r\n return this.clientsById.size;\r\n }\r\n\r\n public get clients(): ReadonlyMap<string, SecureServerClient> {\r\n return this.clientsById;\r\n }\r\n\r\n public on(event: \"connection\", handler: SecureServerConnectionHandler): this;\r\n public on(event: \"disconnect\", handler: SecureServerDisconnectHandler): this;\r\n public on(event: \"ready\", handler: SecureServerReadyHandler): this;\r\n public on(event: \"error\", handler: SecureErrorHandler): this;\r\n public on(event: string, handler: SecureServerEventHandler): this;\r\n public on(event: string, handler: unknown): this {\r\n try {\r\n if (event === \"connection\") {\r\n this.connectionHandlers.add(handler as SecureServerConnectionHandler);\r\n return this;\r\n }\r\n\r\n if (event === \"disconnect\") {\r\n this.disconnectHandlers.add(handler as SecureServerDisconnectHandler);\r\n return this;\r\n }\r\n\r\n if (event === READY_EVENT) {\r\n this.readyHandlers.add(handler as SecureServerReadyHandler);\r\n return this;\r\n }\r\n\r\n if (event === \"error\") {\r\n this.errorHandlers.add(handler as SecureErrorHandler);\r\n return this;\r\n }\r\n\r\n if (event === INTERNAL_HANDSHAKE_EVENT) {\r\n throw new Error(`The event \"${INTERNAL_HANDSHAKE_EVENT}\" is reserved for internal use.`);\r\n }\r\n\r\n const typedHandler = handler as SecureServerEventHandler;\r\n const listeners = this.customEventHandlers.get(event) ?? new Set<SecureServerEventHandler>();\r\n listeners.add(typedHandler);\r\n this.customEventHandlers.set(event, listeners);\r\n } catch (error) {\r\n this.notifyError(\r\n normalizeToError(error, \"Failed to register server event handler.\")\r\n );\r\n }\r\n\r\n return this;\r\n }\r\n\r\n public off(event: \"connection\", handler: SecureServerConnectionHandler): this;\r\n public off(event: \"disconnect\", handler: SecureServerDisconnectHandler): this;\r\n public off(event: \"ready\", handler: SecureServerReadyHandler): this;\r\n public off(event: \"error\", handler: SecureErrorHandler): this;\r\n public off(event: string, handler: SecureServerEventHandler): this;\r\n public off(event: string, handler: unknown): this {\r\n try {\r\n if (event === \"connection\") {\r\n this.connectionHandlers.delete(handler as SecureServerConnectionHandler);\r\n return this;\r\n }\r\n\r\n if (event === \"disconnect\") {\r\n this.disconnectHandlers.delete(handler as SecureServerDisconnectHandler);\r\n return this;\r\n }\r\n\r\n if (event === READY_EVENT) {\r\n this.readyHandlers.delete(handler as SecureServerReadyHandler);\r\n return this;\r\n }\r\n\r\n if (event === \"error\") {\r\n this.errorHandlers.delete(handler as SecureErrorHandler);\r\n return this;\r\n }\r\n\r\n if (event === INTERNAL_HANDSHAKE_EVENT) {\r\n return this;\r\n }\r\n\r\n const listeners = this.customEventHandlers.get(event);\r\n\r\n if (!listeners) {\r\n return this;\r\n }\r\n\r\n listeners.delete(handler as SecureServerEventHandler);\r\n\r\n if (listeners.size === 0) {\r\n this.customEventHandlers.delete(event);\r\n }\r\n } catch (error) {\r\n this.notifyError(\r\n normalizeToError(error, \"Failed to remove server event handler.\")\r\n );\r\n }\r\n\r\n return this;\r\n }\r\n\r\n public emit(event: string, data: unknown): this {\r\n try {\r\n if (isReservedEmitEvent(event)) {\r\n throw new Error(`The event \"${event}\" is reserved and cannot be emitted manually.`);\r\n }\r\n\r\n const envelope: SecureEnvelope = { event, data };\r\n\r\n for (const client of this.clientsById.values()) {\r\n this.sendOrQueuePayload(client.socket, envelope);\r\n }\r\n } catch (error) {\r\n this.notifyError(normalizeToError(error, \"Failed to emit server event.\"));\r\n }\r\n\r\n return this;\r\n }\r\n\r\n public emitTo(clientId: string, event: string, data: unknown): boolean;\r\n public emitTo(\r\n clientId: string,\r\n event: string,\r\n data: unknown,\r\n callback: SecureAckCallback\r\n ): boolean;\r\n public emitTo(\r\n clientId: string,\r\n event: string,\r\n data: unknown,\r\n options: SecureAckOptions\r\n ): Promise<unknown>;\r\n public emitTo(\r\n clientId: string,\r\n event: string,\r\n data: unknown,\r\n options: SecureAckOptions,\r\n callback: SecureAckCallback\r\n ): boolean;\r\n public emitTo(\r\n clientId: string,\r\n event: string,\r\n data: unknown,\r\n callbackOrOptions?: SecureAckCallback | SecureAckOptions,\r\n maybeCallback?: SecureAckCallback\r\n ): boolean | Promise<unknown> {\r\n const ackArgs = resolveAckArguments(callbackOrOptions, maybeCallback);\r\n\r\n try {\r\n if (isReservedEmitEvent(event)) {\r\n throw new Error(`The event \"${event}\" is reserved and cannot be emitted manually.`);\r\n }\r\n\r\n const client = this.clientsById.get(clientId);\r\n\r\n if (!client) {\r\n throw new Error(`Client with id ${clientId} was not found.`);\r\n }\r\n\r\n if (!ackArgs.expectsAck) {\r\n this.sendOrQueuePayload(client.socket, { event, data });\r\n return true;\r\n }\r\n\r\n const ackPromise = this.sendRpcRequest(\r\n client.socket,\r\n event,\r\n data,\r\n ackArgs.timeoutMs\r\n );\r\n\r\n if (ackArgs.callback) {\r\n ackPromise\r\n .then((response) => {\r\n ackArgs.callback?.(null, response);\r\n })\r\n .catch((error) => {\r\n ackArgs.callback?.(\r\n normalizeToError(error, `ACK callback failed for client ${client.id}.`)\r\n );\r\n });\r\n\r\n return true;\r\n }\r\n\r\n return ackPromise;\r\n } catch (error) {\r\n const normalizedError = normalizeToError(error, \"Failed to emit event to client.\");\r\n this.notifyError(normalizedError);\r\n\r\n if (ackArgs.callback) {\r\n ackArgs.callback(normalizedError);\r\n return false;\r\n }\r\n\r\n if (ackArgs.expectsAck) {\r\n return Promise.reject(normalizedError);\r\n }\r\n\r\n return false;\r\n }\r\n }\r\n\r\n public to(room: string): SecureServerRoomOperator {\r\n const normalizedRoom = this.normalizeRoomName(room);\r\n\r\n return {\r\n emit: (event: string, data: unknown): SecureServer => {\r\n try {\r\n this.emitToRoom(normalizedRoom, event, data);\r\n } catch (error) {\r\n this.notifyError(\r\n normalizeToError(error, `Failed to emit event to room ${normalizedRoom}.`)\r\n );\r\n }\r\n\r\n return this;\r\n }\r\n };\r\n }\r\n\r\n public close(\r\n code: number = DEFAULT_CLOSE_CODE,\r\n reason: string = DEFAULT_CLOSE_REASON\r\n ): void {\r\n try {\r\n this.stopHeartbeatLoop();\r\n\r\n for (const client of this.clientsById.values()) {\r\n this.rejectPendingRpcRequests(\r\n client.socket,\r\n new Error(\"Server closed before ACK response was received.\")\r\n );\r\n\r\n if (\r\n client.socket.readyState === WebSocket.OPEN ||\r\n client.socket.readyState === WebSocket.CONNECTING\r\n ) {\r\n client.socket.close(code, reason);\r\n }\r\n }\r\n\r\n this.socketServer.close();\r\n } catch (error) {\r\n this.notifyError(normalizeToError(error, \"Failed to close server.\"));\r\n }\r\n }\r\n\r\n private resolveHeartbeatConfig(\r\n heartbeatOptions: SecureServerHeartbeatOptions | undefined\r\n ): Required<SecureServerHeartbeatOptions> {\r\n const intervalMs = heartbeatOptions?.intervalMs ?? DEFAULT_HEARTBEAT_INTERVAL_MS;\r\n const timeoutMs = heartbeatOptions?.timeoutMs ?? DEFAULT_HEARTBEAT_TIMEOUT_MS;\r\n\r\n if (!Number.isFinite(intervalMs) || intervalMs <= 0) {\r\n throw new Error(\"Server heartbeat intervalMs must be a positive number.\");\r\n }\r\n\r\n if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {\r\n throw new Error(\"Server heartbeat timeoutMs must be a positive number.\");\r\n }\r\n\r\n return {\r\n enabled: heartbeatOptions?.enabled ?? true,\r\n intervalMs,\r\n timeoutMs\r\n };\r\n }\r\n\r\n private startHeartbeatLoop(): void {\r\n if (!this.heartbeatConfig.enabled || this.heartbeatIntervalHandle) {\r\n return;\r\n }\r\n\r\n this.heartbeatIntervalHandle = setInterval(() => {\r\n this.performHeartbeatSweep();\r\n }, this.heartbeatConfig.intervalMs);\r\n\r\n this.heartbeatIntervalHandle.unref?.();\r\n }\r\n\r\n private stopHeartbeatLoop(): void {\r\n if (!this.heartbeatIntervalHandle) {\r\n return;\r\n }\r\n\r\n clearInterval(this.heartbeatIntervalHandle);\r\n this.heartbeatIntervalHandle = null;\r\n }\r\n\r\n private performHeartbeatSweep(): void {\r\n const now = Date.now();\r\n\r\n for (const client of this.clientsById.values()) {\r\n const socket = client.socket;\r\n\r\n if (socket.readyState !== WebSocket.OPEN) {\r\n continue;\r\n }\r\n\r\n const heartbeatState = this.heartbeatStateBySocket.get(socket) ?? {\r\n awaitingPong: false,\r\n lastPingAt: 0\r\n };\r\n\r\n if (\r\n heartbeatState.awaitingPong &&\r\n now - heartbeatState.lastPingAt >= this.heartbeatConfig.timeoutMs\r\n ) {\r\n this.rejectPendingRpcRequests(\r\n socket,\r\n new Error(`Heartbeat timeout while waiting for client ${client.id} ACK response.`)\r\n );\r\n this.sharedSecretBySocket.delete(socket);\r\n this.encryptionKeyBySocket.delete(socket);\r\n this.pendingPayloadsBySocket.delete(socket);\r\n this.pendingRpcRequestsBySocket.delete(socket);\r\n this.handshakeStateBySocket.delete(socket);\r\n this.heartbeatStateBySocket.delete(socket);\r\n socket.terminate();\r\n continue;\r\n }\r\n\r\n if (heartbeatState.awaitingPong) {\r\n continue;\r\n }\r\n\r\n heartbeatState.awaitingPong = true;\r\n heartbeatState.lastPingAt = now;\r\n this.heartbeatStateBySocket.set(socket, heartbeatState);\r\n\r\n try {\r\n socket.ping();\r\n } catch (error) {\r\n this.notifyError(\r\n normalizeToError(error, `Failed to send heartbeat ping to client ${client.id}.`)\r\n );\r\n }\r\n }\r\n }\r\n\r\n private handleHeartbeatPong(socket: WebSocket): void {\r\n const heartbeatState = this.heartbeatStateBySocket.get(socket);\r\n\r\n if (!heartbeatState) {\r\n return;\r\n }\r\n\r\n heartbeatState.awaitingPong = false;\r\n heartbeatState.lastPingAt = 0;\r\n this.heartbeatStateBySocket.set(socket, heartbeatState);\r\n }\r\n\r\n private bindSocketServerEvents(): void {\r\n this.socketServer.on(\"connection\", (socket: WebSocket, request: IncomingMessage) => {\r\n this.handleConnection(socket, request);\r\n });\r\n\r\n this.socketServer.on(\"error\", (error: Error) => {\r\n this.notifyError(normalizeToError(error, \"WebSocket server encountered an error.\"));\r\n });\r\n }\r\n\r\n private handleConnection(socket: WebSocket, request: IncomingMessage): void {\r\n try {\r\n const clientId = randomUUID();\r\n const handshakeState = this.createServerHandshakeState();\r\n const client = this.createSecureServerClient(clientId, socket, request);\r\n\r\n this.clientsById.set(clientId, client);\r\n this.clientIdBySocket.set(socket, clientId);\r\n this.handshakeStateBySocket.set(socket, handshakeState);\r\n this.pendingPayloadsBySocket.set(socket, []);\r\n this.pendingRpcRequestsBySocket.set(socket, new Map<string, PendingRpcRequest>());\r\n this.heartbeatStateBySocket.set(socket, {\r\n awaitingPong: false,\r\n lastPingAt: 0\r\n });\r\n this.roomNamesByClientId.set(clientId, new Set<string>());\r\n\r\n socket.on(\"message\", (rawData: RawData) => {\r\n this.handleIncomingMessage(client, rawData);\r\n });\r\n\r\n socket.on(\"close\", (code: number, reason: Buffer) => {\r\n this.handleDisconnection(client, code, reason);\r\n });\r\n\r\n socket.on(\"pong\", () => {\r\n this.handleHeartbeatPong(client.socket);\r\n });\r\n\r\n socket.on(\"error\", (error: Error) => {\r\n this.notifyError(\r\n normalizeToError(\r\n error,\r\n `Client socket error detected for client ${client.id}.`\r\n )\r\n );\r\n });\r\n\r\n this.sendInternalHandshake(socket, handshakeState.localPublicKey);\r\n this.notifyConnection(client);\r\n } catch (error) {\r\n this.notifyError(normalizeToError(error, \"Failed to handle client connection.\"));\r\n }\r\n }\r\n\r\n private handleIncomingMessage(client: SecureServerClient, rawData: RawData): void {\r\n try {\r\n let envelope: SecureEnvelope | null = null;\r\n\r\n try {\r\n envelope = parseEnvelope(rawData);\r\n } catch {\r\n envelope = null;\r\n }\r\n\r\n if (envelope?.event === INTERNAL_HANDSHAKE_EVENT) {\r\n this.handleInternalHandshake(client, envelope.data);\r\n return;\r\n }\r\n\r\n if (envelope !== null) {\r\n this.notifyError(\r\n new Error(\r\n `Plaintext event \"${envelope.event}\" was rejected for client ${client.id}.`\r\n )\r\n );\r\n return;\r\n }\r\n\r\n if (!this.isClientHandshakeReady(client.socket)) {\r\n this.notifyError(\r\n new Error(`Encrypted payload was received before handshake completion for client ${client.id}.`)\r\n );\r\n return;\r\n }\r\n\r\n const encryptionKey = this.encryptionKeyBySocket.get(client.socket);\r\n\r\n if (!encryptionKey) {\r\n this.notifyError(new Error(`Missing encryption key for client ${client.id}.`));\r\n return;\r\n }\r\n\r\n let decryptedPayload: string;\r\n\r\n try {\r\n decryptedPayload = decryptSerializedEnvelope(rawData, encryptionKey);\r\n } catch {\r\n console.warn(\"Tampered data detected and dropped\");\r\n return;\r\n }\r\n\r\n const decryptedEnvelope = parseEnvelopeFromText(decryptedPayload);\r\n\r\n if (decryptedEnvelope.event === INTERNAL_RPC_RESPONSE_EVENT) {\r\n this.handleRpcResponse(client.socket, decryptedEnvelope.data);\r\n return;\r\n }\r\n\r\n if (decryptedEnvelope.event === INTERNAL_RPC_REQUEST_EVENT) {\r\n void this.handleRpcRequest(client, decryptedEnvelope.data);\r\n return;\r\n }\r\n\r\n this.dispatchCustomEvent(decryptedEnvelope.event, decryptedEnvelope.data, client);\r\n } catch (error) {\r\n this.notifyError(normalizeToError(error, \"Failed to process incoming server message.\"));\r\n }\r\n }\r\n\r\n private handleDisconnection(client: SecureServerClient, code: number, reason: Buffer): void {\r\n try {\r\n client.leaveAll();\r\n this.clientsById.delete(client.id);\r\n this.clientIdBySocket.delete(client.socket);\r\n this.handshakeStateBySocket.delete(client.socket);\r\n this.sharedSecretBySocket.delete(client.socket);\r\n this.encryptionKeyBySocket.delete(client.socket);\r\n this.pendingPayloadsBySocket.delete(client.socket);\r\n this.rejectPendingRpcRequests(\r\n client.socket,\r\n new Error(`Client ${client.id} disconnected before ACK response was received.`)\r\n );\r\n this.pendingRpcRequestsBySocket.delete(client.socket);\r\n this.heartbeatStateBySocket.delete(client.socket);\r\n\r\n const decodedReason = decodeCloseReason(reason);\r\n\r\n for (const handler of this.disconnectHandlers) {\r\n try {\r\n handler(client, code, decodedReason);\r\n } catch (handlerError) {\r\n this.notifyError(\r\n normalizeToError(\r\n handlerError,\r\n `Disconnect handler failed for client ${client.id}.`\r\n )\r\n );\r\n }\r\n }\r\n } catch (error) {\r\n this.notifyError(normalizeToError(error, \"Failed to process client disconnection.\"));\r\n }\r\n }\r\n\r\n private dispatchCustomEvent(\r\n event: string,\r\n data: unknown,\r\n client: SecureServerClient\r\n ): void {\r\n const handlers = this.customEventHandlers.get(event);\r\n\r\n if (!handlers || handlers.size === 0) {\r\n return;\r\n }\r\n\r\n for (const handler of handlers) {\r\n try {\r\n const handlerResult = handler(data, client);\r\n\r\n if (isPromiseLike(handlerResult)) {\r\n void Promise.resolve(handlerResult).catch((error) => {\r\n this.notifyError(\r\n normalizeToError(\r\n error,\r\n `Server event handler failed for event ${event}.`\r\n )\r\n );\r\n });\r\n }\r\n } catch (error) {\r\n this.notifyError(\r\n normalizeToError(\r\n error,\r\n `Server event handler failed for event ${event}.`\r\n )\r\n );\r\n }\r\n }\r\n }\r\n\r\n private sendRaw(socket: WebSocket, payload: string): void {\r\n try {\r\n if (socket.readyState !== WebSocket.OPEN) {\r\n return;\r\n }\r\n\r\n socket.send(payload);\r\n } catch (error) {\r\n this.notifyError(normalizeToError(error, \"Failed to send server payload.\"));\r\n }\r\n }\r\n\r\n private sendEncryptedEnvelope(socket: WebSocket, envelope: SecureEnvelope): void {\r\n try {\r\n if (socket.readyState !== WebSocket.OPEN) {\r\n return;\r\n }\r\n\r\n const encryptionKey = this.encryptionKeyBySocket.get(socket);\r\n\r\n if (!encryptionKey) {\r\n throw new Error(\"Missing encryption key for connected socket.\");\r\n }\r\n\r\n const encryptedPayload = encryptSerializedEnvelope(\r\n serializeEnvelope(envelope.event, envelope.data),\r\n encryptionKey\r\n );\r\n\r\n socket.send(encryptedPayload);\r\n } catch (error) {\r\n this.notifyError(normalizeToError(error, \"Failed to send encrypted server payload.\"));\r\n }\r\n }\r\n\r\n private sendRpcRequest(\r\n socket: WebSocket,\r\n event: string,\r\n data: unknown,\r\n timeoutMs: number\r\n ): Promise<unknown> {\r\n if (socket.readyState !== WebSocket.OPEN && socket.readyState !== WebSocket.CONNECTING) {\r\n throw new Error(\"Client socket is not connected for ACK request.\");\r\n }\r\n\r\n const pendingRequests =\r\n this.pendingRpcRequestsBySocket.get(socket) ?? new Map<string, PendingRpcRequest>();\r\n this.pendingRpcRequestsBySocket.set(socket, pendingRequests);\r\n\r\n const requestId = randomUUID();\r\n\r\n return new Promise<unknown>((resolve, reject) => {\r\n const timeoutHandle = setTimeout(() => {\r\n pendingRequests.delete(requestId);\r\n reject(new Error(`ACK response timed out after ${timeoutMs}ms for event \"${event}\".`));\r\n }, timeoutMs);\r\n\r\n timeoutHandle.unref?.();\r\n\r\n pendingRequests.set(requestId, {\r\n resolve,\r\n reject,\r\n timeoutHandle\r\n });\r\n\r\n this.sendOrQueuePayload(socket, {\r\n event: INTERNAL_RPC_REQUEST_EVENT,\r\n data: {\r\n id: requestId,\r\n event,\r\n data\r\n } satisfies RpcRequestPayload\r\n });\r\n });\r\n }\r\n\r\n private handleRpcResponse(socket: WebSocket, data: unknown): void {\r\n try {\r\n const responsePayload = parseRpcResponsePayload(data);\r\n const pendingRequests = this.pendingRpcRequestsBySocket.get(socket);\r\n\r\n if (!pendingRequests) {\r\n return;\r\n }\r\n\r\n const pendingRequest = pendingRequests.get(responsePayload.id);\r\n\r\n if (!pendingRequest) {\r\n return;\r\n }\r\n\r\n clearTimeout(pendingRequest.timeoutHandle);\r\n pendingRequests.delete(responsePayload.id);\r\n\r\n if (responsePayload.ok) {\r\n pendingRequest.resolve(responsePayload.data);\r\n return;\r\n }\r\n\r\n pendingRequest.reject(\r\n new Error(responsePayload.error ?? \"ACK request failed without an error message.\")\r\n );\r\n } catch (error) {\r\n this.notifyError(normalizeToError(error, \"Failed to process server ACK response.\"));\r\n }\r\n }\r\n\r\n private async handleRpcRequest(client: SecureServerClient, data: unknown): Promise<void> {\r\n let rpcRequestPayload: RpcRequestPayload;\r\n\r\n try {\r\n rpcRequestPayload = parseRpcRequestPayload(data);\r\n } catch (error) {\r\n this.notifyError(normalizeToError(error, \"Invalid server ACK request payload.\"));\r\n return;\r\n }\r\n\r\n try {\r\n const ackResponse = await this.executeRpcRequestHandler(\r\n rpcRequestPayload.event,\r\n rpcRequestPayload.data,\r\n client\r\n );\r\n\r\n this.sendEncryptedEnvelope(client.socket, {\r\n event: INTERNAL_RPC_RESPONSE_EVENT,\r\n data: {\r\n id: rpcRequestPayload.id,\r\n ok: true,\r\n data: ackResponse\r\n } satisfies RpcResponsePayload\r\n });\r\n } catch (error) {\r\n const normalizedError = normalizeToError(error, \"Server ACK request handler failed.\");\r\n\r\n this.sendEncryptedEnvelope(client.socket, {\r\n event: INTERNAL_RPC_RESPONSE_EVENT,\r\n data: {\r\n id: rpcRequestPayload.id,\r\n ok: false,\r\n error: normalizedError.message\r\n } satisfies RpcResponsePayload\r\n });\r\n\r\n this.notifyError(normalizedError);\r\n }\r\n }\r\n\r\n private async executeRpcRequestHandler(\r\n event: string,\r\n data: unknown,\r\n client: SecureServerClient\r\n ): Promise<unknown> {\r\n const handlers = this.customEventHandlers.get(event);\r\n\r\n if (!handlers || handlers.size === 0) {\r\n throw new Error(`No handler is registered for ACK request event \"${event}\".`);\r\n }\r\n\r\n const firstHandler = handlers.values().next().value as SecureServerEventHandler;\r\n return Promise.resolve(firstHandler(data, client));\r\n }\r\n\r\n private rejectPendingRpcRequests(socket: WebSocket, error: Error): void {\r\n const pendingRequests = this.pendingRpcRequestsBySocket.get(socket);\r\n\r\n if (!pendingRequests) {\r\n return;\r\n }\r\n\r\n for (const pendingRequest of pendingRequests.values()) {\r\n clearTimeout(pendingRequest.timeoutHandle);\r\n pendingRequest.reject(error);\r\n }\r\n\r\n pendingRequests.clear();\r\n }\r\n\r\n private notifyConnection(client: SecureServerClient): void {\r\n for (const handler of this.connectionHandlers) {\r\n try {\r\n handler(client);\r\n } catch (error) {\r\n this.notifyError(\r\n normalizeToError(error, `Connection handler failed for client ${client.id}.`)\r\n );\r\n }\r\n }\r\n }\r\n\r\n private notifyReady(client: SecureServerClient): void {\r\n for (const handler of this.readyHandlers) {\r\n try {\r\n handler(client);\r\n } catch (error) {\r\n this.notifyError(\r\n normalizeToError(error, `Ready handler failed for client ${client.id}.`)\r\n );\r\n }\r\n }\r\n }\r\n\r\n private notifyError(error: Error): void {\r\n if (this.errorHandlers.size === 0) {\r\n return;\r\n }\r\n\r\n for (const handler of this.errorHandlers) {\r\n try {\r\n handler(error);\r\n } catch {\r\n // Error handlers should not throw into the event loop.\r\n }\r\n }\r\n }\r\n\r\n private createServerHandshakeState(): ServerHandshakeState {\r\n const { ecdh, localPublicKey } = createEphemeralHandshakeState();\r\n\r\n return {\r\n ecdh,\r\n localPublicKey,\r\n isReady: false\r\n };\r\n }\r\n\r\n private sendInternalHandshake(socket: WebSocket, localPublicKey: string): void {\r\n this.sendRaw(\r\n socket,\r\n serializeEnvelope(INTERNAL_HANDSHAKE_EVENT, {\r\n publicKey: localPublicKey\r\n })\r\n );\r\n }\r\n\r\n private handleInternalHandshake(client: SecureServerClient, data: unknown): void {\r\n try {\r\n const payload = parseHandshakePayload(data);\r\n const handshakeState = this.handshakeStateBySocket.get(client.socket);\r\n\r\n if (!handshakeState) {\r\n throw new Error(`Missing handshake state for client ${client.id}.`);\r\n }\r\n\r\n if (handshakeState.isReady) {\r\n return;\r\n }\r\n\r\n const remotePublicKey = Buffer.from(payload.publicKey, \"base64\");\r\n const sharedSecret = handshakeState.ecdh.computeSecret(remotePublicKey);\r\n const encryptionKey = deriveEncryptionKey(sharedSecret);\r\n\r\n this.sharedSecretBySocket.set(client.socket, sharedSecret);\r\n this.encryptionKeyBySocket.set(client.socket, encryptionKey);\r\n handshakeState.isReady = true;\r\n\r\n this.flushQueuedPayloads(client.socket);\r\n this.notifyReady(client);\r\n } catch (error) {\r\n this.notifyError(normalizeToError(error, \"Failed to complete server handshake.\"));\r\n }\r\n }\r\n\r\n private isClientHandshakeReady(socket: WebSocket): boolean {\r\n return this.handshakeStateBySocket.get(socket)?.isReady ?? false;\r\n }\r\n\r\n private sendOrQueuePayload(socket: WebSocket, envelope: SecureEnvelope): void {\r\n if (!this.isClientHandshakeReady(socket)) {\r\n this.queuePayload(socket, envelope);\r\n return;\r\n }\r\n\r\n this.sendEncryptedEnvelope(socket, envelope);\r\n }\r\n\r\n private queuePayload(socket: WebSocket, envelope: SecureEnvelope): void {\r\n const pendingPayloads = this.pendingPayloadsBySocket.get(socket) ?? [];\r\n pendingPayloads.push(envelope);\r\n this.pendingPayloadsBySocket.set(socket, pendingPayloads);\r\n }\r\n\r\n private flushQueuedPayloads(socket: WebSocket): void {\r\n const pendingPayloads = this.pendingPayloadsBySocket.get(socket);\r\n\r\n if (!pendingPayloads || pendingPayloads.length === 0) {\r\n return;\r\n }\r\n\r\n this.pendingPayloadsBySocket.delete(socket);\r\n\r\n for (const envelope of pendingPayloads) {\r\n this.sendEncryptedEnvelope(socket, envelope);\r\n }\r\n }\r\n\r\n private createSecureServerClient(\r\n clientId: string,\r\n socket: WebSocket,\r\n request: IncomingMessage\r\n ): SecureServerClient {\r\n return {\r\n id: clientId,\r\n socket,\r\n request,\r\n emit: (\r\n event: string,\r\n data: unknown,\r\n callbackOrOptions?: SecureAckCallback | SecureAckOptions,\r\n maybeCallback?: SecureAckCallback\r\n ): boolean | Promise<unknown> => {\r\n if (callbackOrOptions === undefined && maybeCallback === undefined) {\r\n return this.emitTo(clientId, event, data);\r\n }\r\n\r\n if (typeof callbackOrOptions === \"function\") {\r\n return this.emitTo(clientId, event, data, callbackOrOptions);\r\n }\r\n\r\n if (maybeCallback) {\r\n return this.emitTo(\r\n clientId,\r\n event,\r\n data,\r\n callbackOrOptions ?? {},\r\n maybeCallback\r\n );\r\n }\r\n\r\n return this.emitTo(clientId, event, data, callbackOrOptions ?? {});\r\n },\r\n join: (room: string): boolean => this.joinClientToRoom(clientId, room),\r\n leave: (room: string): boolean => this.leaveClientFromRoom(clientId, room),\r\n leaveAll: (): number => this.leaveClientFromAllRooms(clientId)\r\n };\r\n }\r\n\r\n private normalizeRoomName(room: string): string {\r\n if (typeof room !== \"string\") {\r\n throw new Error(\"Room name must be a string.\");\r\n }\r\n\r\n const normalizedRoom = room.trim();\r\n\r\n if (normalizedRoom.length === 0) {\r\n throw new Error(\"Room name cannot be empty.\");\r\n }\r\n\r\n return normalizedRoom;\r\n }\r\n\r\n private joinClientToRoom(clientId: string, room: string): boolean {\r\n const normalizedRoom = this.normalizeRoomName(room);\r\n\r\n if (!this.clientsById.has(clientId)) {\r\n return false;\r\n }\r\n\r\n const clientRooms = this.roomNamesByClientId.get(clientId) ?? new Set<string>();\r\n\r\n if (clientRooms.has(normalizedRoom)) {\r\n this.roomNamesByClientId.set(clientId, clientRooms);\r\n return false;\r\n }\r\n\r\n clientRooms.add(normalizedRoom);\r\n this.roomNamesByClientId.set(clientId, clientRooms);\r\n\r\n const roomMembers = this.roomMembersByName.get(normalizedRoom) ?? new Set<string>();\r\n roomMembers.add(clientId);\r\n this.roomMembersByName.set(normalizedRoom, roomMembers);\r\n\r\n return true;\r\n }\r\n\r\n private leaveClientFromRoom(clientId: string, room: string): boolean {\r\n const normalizedRoom = this.normalizeRoomName(room);\r\n const clientRooms = this.roomNamesByClientId.get(clientId);\r\n\r\n if (!clientRooms || !clientRooms.delete(normalizedRoom)) {\r\n return false;\r\n }\r\n\r\n if (clientRooms.size === 0) {\r\n this.roomNamesByClientId.delete(clientId);\r\n }\r\n\r\n const roomMembers = this.roomMembersByName.get(normalizedRoom);\r\n\r\n if (roomMembers) {\r\n roomMembers.delete(clientId);\r\n\r\n if (roomMembers.size === 0) {\r\n this.roomMembersByName.delete(normalizedRoom);\r\n }\r\n }\r\n\r\n return true;\r\n }\r\n\r\n private leaveClientFromAllRooms(clientId: string): number {\r\n const clientRooms = this.roomNamesByClientId.get(clientId);\r\n\r\n if (!clientRooms || clientRooms.size === 0) {\r\n this.roomNamesByClientId.delete(clientId);\r\n return 0;\r\n }\r\n\r\n const roomNames = [...clientRooms];\r\n this.roomNamesByClientId.delete(clientId);\r\n\r\n for (const roomName of roomNames) {\r\n const roomMembers = this.roomMembersByName.get(roomName);\r\n\r\n if (!roomMembers) {\r\n continue;\r\n }\r\n\r\n roomMembers.delete(clientId);\r\n\r\n if (roomMembers.size === 0) {\r\n this.roomMembersByName.delete(roomName);\r\n }\r\n }\r\n\r\n return roomNames.length;\r\n }\r\n\r\n private emitToRoom(room: string, event: string, data: unknown): void {\r\n if (isReservedEmitEvent(event)) {\r\n throw new Error(`The event \"${event}\" is reserved and cannot be emitted manually.`);\r\n }\r\n\r\n const roomMembers = this.roomMembersByName.get(room);\r\n\r\n if (!roomMembers || roomMembers.size === 0) {\r\n return;\r\n }\r\n\r\n const envelope: SecureEnvelope = { event, data };\r\n\r\n for (const clientId of roomMembers) {\r\n const client = this.clientsById.get(clientId);\r\n\r\n if (!client) {\r\n continue;\r\n }\r\n\r\n this.sendOrQueuePayload(client.socket, envelope);\r\n }\r\n }\r\n}\r\n\r\nexport class SecureClient {\r\n private socket: WebSocket | null = null;\r\n\r\n private readonly reconnectConfig: Required<SecureClientReconnectOptions>;\r\n\r\n private reconnectAttemptCount = 0;\r\n\r\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\r\n\r\n private isManualDisconnectRequested = false;\r\n\r\n private readonly customEventHandlers = new Map<string, Set<SecureClientEventHandler>>();\r\n\r\n private readonly connectHandlers = new Set<SecureClientConnectHandler>();\r\n\r\n private readonly disconnectHandlers = new Set<SecureClientDisconnectHandler>();\r\n\r\n private readonly readyHandlers = new Set<SecureClientReadyHandler>();\r\n\r\n private readonly errorHandlers = new Set<SecureErrorHandler>();\r\n\r\n private handshakeState: ClientHandshakeState | null = null;\r\n\r\n private pendingPayloadQueue: SecureEnvelope[] = [];\r\n\r\n private readonly pendingRpcRequests = new Map<string, PendingRpcRequest>();\r\n\r\n public constructor(\r\n private readonly url: string,\r\n private readonly options: SecureClientOptions = {}\r\n ) {\r\n this.reconnectConfig = this.resolveReconnectConfig(this.options.reconnect);\r\n\r\n if (this.options.autoConnect ?? true) {\r\n this.connect();\r\n }\r\n }\r\n\r\n public get readyState(): number | null {\r\n return this.socket?.readyState ?? null;\r\n }\r\n\r\n public isConnected(): boolean {\r\n return this.socket?.readyState === WebSocket.OPEN;\r\n }\r\n\r\n public connect(): void {\r\n try {\r\n if (\r\n this.socket &&\r\n (this.socket.readyState === WebSocket.OPEN ||\r\n this.socket.readyState === WebSocket.CONNECTING)\r\n ) {\r\n return;\r\n }\r\n\r\n this.clearReconnectTimer();\r\n this.isManualDisconnectRequested = false;\r\n\r\n const socket = this.createSocket();\r\n this.socket = socket;\r\n this.handshakeState = this.createClientHandshakeState();\r\n this.pendingPayloadQueue = [];\r\n this.bindSocketEvents(socket);\r\n } catch (error) {\r\n this.notifyError(normalizeToError(error, \"Failed to connect client.\"));\r\n\r\n if (!this.isManualDisconnectRequested) {\r\n this.scheduleReconnect();\r\n }\r\n }\r\n }\r\n\r\n public disconnect(\r\n code: number = DEFAULT_CLOSE_CODE,\r\n reason: string = DEFAULT_CLOSE_REASON\r\n ): void {\r\n try {\r\n this.isManualDisconnectRequested = true;\r\n this.clearReconnectTimer();\r\n\r\n if (!this.socket) {\r\n return;\r\n }\r\n\r\n if (\r\n this.socket.readyState === WebSocket.CLOSING ||\r\n this.socket.readyState === WebSocket.CLOSED\r\n ) {\r\n return;\r\n }\r\n\r\n this.socket.close(code, reason);\r\n } catch (error) {\r\n this.notifyError(normalizeToError(error, \"Failed to disconnect client.\"));\r\n }\r\n }\r\n\r\n public on(event: \"connect\", handler: SecureClientConnectHandler): this;\r\n public on(event: \"disconnect\", handler: SecureClientDisconnectHandler): this;\r\n public on(event: \"ready\", handler: SecureClientReadyHandler): this;\r\n public on(event: \"error\", handler: SecureErrorHandler): this;\r\n public on(event: string, handler: SecureClientEventHandler): this;\r\n public on(event: string, handler: unknown): this {\r\n try {\r\n if (event === \"connect\") {\r\n this.connectHandlers.add(handler as SecureClientConnectHandler);\r\n return this;\r\n }\r\n\r\n if (event === \"disconnect\") {\r\n this.disconnectHandlers.add(handler as SecureClientDisconnectHandler);\r\n return this;\r\n }\r\n\r\n if (event === READY_EVENT) {\r\n this.readyHandlers.add(handler as SecureClientReadyHandler);\r\n return this;\r\n }\r\n\r\n if (event === \"error\") {\r\n this.errorHandlers.add(handler as SecureErrorHandler);\r\n return this;\r\n }\r\n\r\n if (event === INTERNAL_HANDSHAKE_EVENT) {\r\n throw new Error(`The event \"${INTERNAL_HANDSHAKE_EVENT}\" is reserved for internal use.`);\r\n }\r\n\r\n const typedHandler = handler as SecureClientEventHandler;\r\n const listeners = this.customEventHandlers.get(event) ?? new Set<SecureClientEventHandler>();\r\n listeners.add(typedHandler);\r\n this.customEventHandlers.set(event, listeners);\r\n } catch (error) {\r\n this.notifyError(\r\n normalizeToError(error, \"Failed to register client event handler.\")\r\n );\r\n }\r\n\r\n return this;\r\n }\r\n\r\n public off(event: \"connect\", handler: SecureClientConnectHandler): this;\r\n public off(event: \"disconnect\", handler: SecureClientDisconnectHandler): this;\r\n public off(event: \"ready\", handler: SecureClientReadyHandler): this;\r\n public off(event: \"error\", handler: SecureErrorHandler): this;\r\n public off(event: string, handler: SecureClientEventHandler): this;\r\n public off(event: string, handler: unknown): this {\r\n try {\r\n if (event === \"connect\") {\r\n this.connectHandlers.delete(handler as SecureClientConnectHandler);\r\n return this;\r\n }\r\n\r\n if (event === \"disconnect\") {\r\n this.disconnectHandlers.delete(handler as SecureClientDisconnectHandler);\r\n return this;\r\n }\r\n\r\n if (event === READY_EVENT) {\r\n this.readyHandlers.delete(handler as SecureClientReadyHandler);\r\n return this;\r\n }\r\n\r\n if (event === \"error\") {\r\n this.errorHandlers.delete(handler as SecureErrorHandler);\r\n return this;\r\n }\r\n\r\n if (event === INTERNAL_HANDSHAKE_EVENT) {\r\n return this;\r\n }\r\n\r\n const listeners = this.customEventHandlers.get(event);\r\n\r\n if (!listeners) {\r\n return this;\r\n }\r\n\r\n listeners.delete(handler as SecureClientEventHandler);\r\n\r\n if (listeners.size === 0) {\r\n this.customEventHandlers.delete(event);\r\n }\r\n } catch (error) {\r\n this.notifyError(\r\n normalizeToError(error, \"Failed to remove client event handler.\")\r\n );\r\n }\r\n\r\n return this;\r\n }\r\n\r\n public emit(event: string, data: unknown): boolean;\r\n public emit(event: string, data: unknown, callback: SecureAckCallback): boolean;\r\n public emit(event: string, data: unknown, options: SecureAckOptions): Promise<unknown>;\r\n public emit(\r\n event: string,\r\n data: unknown,\r\n options: SecureAckOptions,\r\n callback: SecureAckCallback\r\n ): boolean;\r\n public emit(\r\n event: string,\r\n data: unknown,\r\n callbackOrOptions?: SecureAckCallback | SecureAckOptions,\r\n maybeCallback?: SecureAckCallback\r\n ): boolean | Promise<unknown> {\r\n const ackArgs = resolveAckArguments(callbackOrOptions, maybeCallback);\r\n\r\n try {\r\n if (isReservedEmitEvent(event)) {\r\n throw new Error(`The event \"${event}\" is reserved and cannot be emitted manually.`);\r\n }\r\n\r\n if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {\r\n throw new Error(\"Client socket is not connected.\");\r\n }\r\n\r\n if (ackArgs.expectsAck) {\r\n const ackPromise = this.sendRpcRequest(event, data, ackArgs.timeoutMs);\r\n\r\n if (ackArgs.callback) {\r\n ackPromise\r\n .then((response) => {\r\n ackArgs.callback?.(null, response);\r\n })\r\n .catch((error) => {\r\n ackArgs.callback?.(\r\n normalizeToError(error, `ACK callback failed for event \"${event}\".`)\r\n );\r\n });\r\n\r\n return true;\r\n }\r\n\r\n return ackPromise;\r\n }\r\n\r\n const envelope: SecureEnvelope = { event, data };\r\n\r\n if (!this.isHandshakeReady()) {\r\n this.pendingPayloadQueue.push(envelope);\r\n return true;\r\n }\r\n\r\n this.sendEncryptedEnvelope(envelope);\r\n return true;\r\n } catch (error) {\r\n const normalizedError = normalizeToError(error, \"Failed to emit client event.\");\r\n this.notifyError(normalizedError);\r\n\r\n if (ackArgs.callback) {\r\n ackArgs.callback(normalizedError);\r\n return false;\r\n }\r\n\r\n if (ackArgs.expectsAck) {\r\n return Promise.reject(normalizedError);\r\n }\r\n\r\n return false;\r\n }\r\n }\r\n\r\n private resolveReconnectConfig(\r\n reconnectOptions: boolean | SecureClientReconnectOptions | undefined\r\n ): Required<SecureClientReconnectOptions> {\r\n if (typeof reconnectOptions === \"boolean\") {\r\n return {\r\n enabled: reconnectOptions,\r\n initialDelayMs: DEFAULT_RECONNECT_INITIAL_DELAY_MS,\r\n maxDelayMs: DEFAULT_RECONNECT_MAX_DELAY_MS,\r\n factor: DEFAULT_RECONNECT_FACTOR,\r\n jitterRatio: DEFAULT_RECONNECT_JITTER_RATIO,\r\n maxAttempts: null\r\n };\r\n }\r\n\r\n const initialDelayMs = reconnectOptions?.initialDelayMs ?? DEFAULT_RECONNECT_INITIAL_DELAY_MS;\r\n const maxDelayMs = reconnectOptions?.maxDelayMs ?? DEFAULT_RECONNECT_MAX_DELAY_MS;\r\n const factor = reconnectOptions?.factor ?? DEFAULT_RECONNECT_FACTOR;\r\n const jitterRatio = reconnectOptions?.jitterRatio ?? DEFAULT_RECONNECT_JITTER_RATIO;\r\n const maxAttempts = reconnectOptions?.maxAttempts ?? null;\r\n\r\n if (!Number.isFinite(initialDelayMs) || initialDelayMs < 0) {\r\n throw new Error(\"Client reconnect initialDelayMs must be a non-negative number.\");\r\n }\r\n\r\n if (!Number.isFinite(maxDelayMs) || maxDelayMs < 0) {\r\n throw new Error(\"Client reconnect maxDelayMs must be a non-negative number.\");\r\n }\r\n\r\n if (maxDelayMs < initialDelayMs) {\r\n throw new Error(\"Client reconnect maxDelayMs must be greater than or equal to initialDelayMs.\");\r\n }\r\n\r\n if (!Number.isFinite(factor) || factor < 1) {\r\n throw new Error(\"Client reconnect factor must be greater than or equal to 1.\");\r\n }\r\n\r\n if (!Number.isFinite(jitterRatio) || jitterRatio < 0 || jitterRatio > 1) {\r\n throw new Error(\"Client reconnect jitterRatio must be between 0 and 1.\");\r\n }\r\n\r\n if (\r\n maxAttempts !== null &&\r\n (!Number.isInteger(maxAttempts) || maxAttempts < 0)\r\n ) {\r\n throw new Error(\"Client reconnect maxAttempts must be a non-negative integer or null.\");\r\n }\r\n\r\n return {\r\n enabled: reconnectOptions?.enabled ?? true,\r\n initialDelayMs,\r\n maxDelayMs,\r\n factor,\r\n jitterRatio,\r\n maxAttempts\r\n };\r\n }\r\n\r\n private scheduleReconnect(): void {\r\n if (!this.reconnectConfig.enabled || this.reconnectTimer) {\r\n return;\r\n }\r\n\r\n if (\r\n this.reconnectConfig.maxAttempts !== null &&\r\n this.reconnectAttemptCount >= this.reconnectConfig.maxAttempts\r\n ) {\r\n return;\r\n }\r\n\r\n this.reconnectAttemptCount += 1;\r\n const delayMs = this.computeReconnectDelay(this.reconnectAttemptCount);\r\n\r\n this.reconnectTimer = setTimeout(() => {\r\n this.reconnectTimer = null;\r\n this.connect();\r\n }, delayMs);\r\n\r\n this.reconnectTimer.unref?.();\r\n }\r\n\r\n private computeReconnectDelay(attemptNumber: number): number {\r\n const exponentialDelay = Math.min(\r\n this.reconnectConfig.maxDelayMs,\r\n this.reconnectConfig.initialDelayMs *\r\n Math.pow(this.reconnectConfig.factor, Math.max(0, attemptNumber - 1))\r\n );\r\n\r\n if (this.reconnectConfig.jitterRatio === 0 || exponentialDelay === 0) {\r\n return Math.round(exponentialDelay);\r\n }\r\n\r\n const jitterDelta = exponentialDelay * this.reconnectConfig.jitterRatio;\r\n const jitterOffset = (Math.random() * 2 - 1) * jitterDelta;\r\n\r\n return Math.max(0, Math.round(exponentialDelay + jitterOffset));\r\n }\r\n\r\n private clearReconnectTimer(): void {\r\n if (!this.reconnectTimer) {\r\n return;\r\n }\r\n\r\n clearTimeout(this.reconnectTimer);\r\n this.reconnectTimer = null;\r\n }\r\n\r\n private createSocket(): WebSocket {\r\n if (this.options.protocols !== undefined) {\r\n return new WebSocket(this.url, this.options.protocols, this.options.wsOptions);\r\n }\r\n\r\n if (this.options.wsOptions !== undefined) {\r\n return new WebSocket(this.url, this.options.wsOptions);\r\n }\r\n\r\n return new WebSocket(this.url);\r\n }\r\n\r\n private bindSocketEvents(socket: WebSocket): void {\r\n socket.on(\"open\", () => {\r\n this.clearReconnectTimer();\r\n this.reconnectAttemptCount = 0;\r\n this.sendInternalHandshake();\r\n this.notifyConnect();\r\n });\r\n\r\n socket.on(\"message\", (rawData: RawData) => {\r\n this.handleIncomingMessage(rawData);\r\n });\r\n\r\n socket.on(\"close\", (code: number, reason: Buffer) => {\r\n this.handleDisconnect(code, reason);\r\n });\r\n\r\n socket.on(\"error\", (error: Error) => {\r\n this.notifyError(normalizeToError(error, \"Client socket encountered an error.\"));\r\n });\r\n }\r\n\r\n private handleIncomingMessage(rawData: RawData): void {\r\n try {\r\n let envelope: SecureEnvelope | null = null;\r\n\r\n try {\r\n envelope = parseEnvelope(rawData);\r\n } catch {\r\n envelope = null;\r\n }\r\n\r\n if (envelope?.event === INTERNAL_HANDSHAKE_EVENT) {\r\n this.handleInternalHandshake(envelope.data);\r\n return;\r\n }\r\n\r\n if (envelope !== null) {\r\n this.notifyError(\r\n new Error(`Plaintext event \"${envelope.event}\" was rejected on client.`)\r\n );\r\n return;\r\n }\r\n\r\n if (!this.isHandshakeReady()) {\r\n this.notifyError(new Error(\"Encrypted payload was received before handshake completion.\"));\r\n return;\r\n }\r\n\r\n const encryptionKey = this.handshakeState?.encryptionKey;\r\n\r\n if (!encryptionKey) {\r\n this.notifyError(new Error(\"Missing encryption key for client payload decryption.\"));\r\n return;\r\n }\r\n\r\n let decryptedPayload: string;\r\n\r\n try {\r\n decryptedPayload = decryptSerializedEnvelope(rawData, encryptionKey);\r\n } catch {\r\n console.warn(\"Tampered data detected and dropped\");\r\n return;\r\n }\r\n\r\n const decryptedEnvelope = parseEnvelopeFromText(decryptedPayload);\r\n\r\n if (decryptedEnvelope.event === INTERNAL_RPC_RESPONSE_EVENT) {\r\n this.handleRpcResponse(decryptedEnvelope.data);\r\n return;\r\n }\r\n\r\n if (decryptedEnvelope.event === INTERNAL_RPC_REQUEST_EVENT) {\r\n void this.handleRpcRequest(decryptedEnvelope.data);\r\n return;\r\n }\r\n\r\n this.dispatchCustomEvent(decryptedEnvelope.event, decryptedEnvelope.data);\r\n } catch (error) {\r\n this.notifyError(normalizeToError(error, \"Failed to process incoming client message.\"));\r\n }\r\n }\r\n\r\n private handleDisconnect(code: number, reason: Buffer): void {\r\n try {\r\n this.socket = null;\r\n this.handshakeState = null;\r\n this.pendingPayloadQueue = [];\r\n this.rejectPendingRpcRequests(\r\n new Error(\"Client disconnected before ACK response was received.\")\r\n );\r\n const decodedReason = decodeCloseReason(reason);\r\n\r\n for (const handler of this.disconnectHandlers) {\r\n try {\r\n handler(code, decodedReason);\r\n } catch (handlerError) {\r\n this.notifyError(\r\n normalizeToError(handlerError, \"Client disconnect handler failed.\")\r\n );\r\n }\r\n }\r\n\r\n if (!this.isManualDisconnectRequested) {\r\n this.scheduleReconnect();\r\n }\r\n\r\n this.isManualDisconnectRequested = false;\r\n } catch (error) {\r\n this.notifyError(normalizeToError(error, \"Failed to handle client disconnect.\"));\r\n }\r\n }\r\n\r\n private dispatchCustomEvent(event: string, data: unknown): void {\r\n const handlers = this.customEventHandlers.get(event);\r\n\r\n if (!handlers || handlers.size === 0) {\r\n return;\r\n }\r\n\r\n for (const handler of handlers) {\r\n try {\r\n const handlerResult = handler(data);\r\n\r\n if (isPromiseLike(handlerResult)) {\r\n void Promise.resolve(handlerResult).catch((error) => {\r\n this.notifyError(\r\n normalizeToError(\r\n error,\r\n `Client event handler failed for event ${event}.`\r\n )\r\n );\r\n });\r\n }\r\n } catch (error) {\r\n this.notifyError(\r\n normalizeToError(error, `Client event handler failed for event ${event}.`)\r\n );\r\n }\r\n }\r\n }\r\n\r\n private notifyConnect(): void {\r\n for (const handler of this.connectHandlers) {\r\n try {\r\n handler();\r\n } catch (error) {\r\n this.notifyError(normalizeToError(error, \"Client connect handler failed.\"));\r\n }\r\n }\r\n }\r\n\r\n private notifyReady(): void {\r\n for (const handler of this.readyHandlers) {\r\n try {\r\n handler();\r\n } catch (error) {\r\n this.notifyError(normalizeToError(error, \"Client ready handler failed.\"));\r\n }\r\n }\r\n }\r\n\r\n private notifyError(error: Error): void {\r\n if (this.errorHandlers.size === 0) {\r\n return;\r\n }\r\n\r\n for (const handler of this.errorHandlers) {\r\n try {\r\n handler(error);\r\n } catch {\r\n // Error handlers should not throw into the event loop.\r\n }\r\n }\r\n }\r\n\r\n private sendEncryptedEnvelope(envelope: SecureEnvelope): void {\r\n try {\r\n if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {\r\n throw new Error(\"Client socket is not connected.\");\r\n }\r\n\r\n const encryptionKey = this.handshakeState?.encryptionKey;\r\n\r\n if (!encryptionKey) {\r\n throw new Error(\"Missing encryption key for client payload encryption.\");\r\n }\r\n\r\n const encryptedPayload = encryptSerializedEnvelope(\r\n serializeEnvelope(envelope.event, envelope.data),\r\n encryptionKey\r\n );\r\n\r\n this.socket.send(encryptedPayload);\r\n } catch (error) {\r\n this.notifyError(normalizeToError(error, \"Failed to send encrypted client payload.\"));\r\n }\r\n }\r\n\r\n private sendRpcRequest(\r\n event: string,\r\n data: unknown,\r\n timeoutMs: number\r\n ): Promise<unknown> {\r\n if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {\r\n throw new Error(\"Client socket is not connected for ACK request.\");\r\n }\r\n\r\n const requestId = randomUUID();\r\n\r\n return new Promise<unknown>((resolve, reject) => {\r\n const timeoutHandle = setTimeout(() => {\r\n this.pendingRpcRequests.delete(requestId);\r\n reject(new Error(`ACK response timed out after ${timeoutMs}ms for event \"${event}\".`));\r\n }, timeoutMs);\r\n\r\n timeoutHandle.unref?.();\r\n\r\n this.pendingRpcRequests.set(requestId, {\r\n resolve,\r\n reject,\r\n timeoutHandle\r\n });\r\n\r\n const rpcRequestEnvelope: SecureEnvelope<RpcRequestPayload> = {\r\n event: INTERNAL_RPC_REQUEST_EVENT,\r\n data: {\r\n id: requestId,\r\n event,\r\n data\r\n }\r\n };\r\n\r\n if (!this.isHandshakeReady()) {\r\n this.pendingPayloadQueue.push(rpcRequestEnvelope);\r\n return;\r\n }\r\n\r\n this.sendEncryptedEnvelope(rpcRequestEnvelope);\r\n });\r\n }\r\n\r\n private handleRpcResponse(data: unknown): void {\r\n try {\r\n const responsePayload = parseRpcResponsePayload(data);\r\n const pendingRequest = this.pendingRpcRequests.get(responsePayload.id);\r\n\r\n if (!pendingRequest) {\r\n return;\r\n }\r\n\r\n clearTimeout(pendingRequest.timeoutHandle);\r\n this.pendingRpcRequests.delete(responsePayload.id);\r\n\r\n if (responsePayload.ok) {\r\n pendingRequest.resolve(responsePayload.data);\r\n return;\r\n }\r\n\r\n pendingRequest.reject(\r\n new Error(responsePayload.error ?? \"ACK request failed without an error message.\")\r\n );\r\n } catch (error) {\r\n this.notifyError(normalizeToError(error, \"Failed to process client ACK response.\"));\r\n }\r\n }\r\n\r\n private async handleRpcRequest(data: unknown): Promise<void> {\r\n let rpcRequestPayload: RpcRequestPayload;\r\n\r\n try {\r\n rpcRequestPayload = parseRpcRequestPayload(data);\r\n } catch (error) {\r\n this.notifyError(normalizeToError(error, \"Invalid client ACK request payload.\"));\r\n return;\r\n }\r\n\r\n try {\r\n const ackResponse = await this.executeRpcRequestHandler(\r\n rpcRequestPayload.event,\r\n rpcRequestPayload.data\r\n );\r\n\r\n this.sendEncryptedEnvelope({\r\n event: INTERNAL_RPC_RESPONSE_EVENT,\r\n data: {\r\n id: rpcRequestPayload.id,\r\n ok: true,\r\n data: ackResponse\r\n } satisfies RpcResponsePayload\r\n });\r\n } catch (error) {\r\n const normalizedError = normalizeToError(error, \"Client ACK request handler failed.\");\r\n\r\n this.sendEncryptedEnvelope({\r\n event: INTERNAL_RPC_RESPONSE_EVENT,\r\n data: {\r\n id: rpcRequestPayload.id,\r\n ok: false,\r\n error: normalizedError.message\r\n } satisfies RpcResponsePayload\r\n });\r\n\r\n this.notifyError(normalizedError);\r\n }\r\n }\r\n\r\n private async executeRpcRequestHandler(event: string, data: unknown): Promise<unknown> {\r\n const handlers = this.customEventHandlers.get(event);\r\n\r\n if (!handlers || handlers.size === 0) {\r\n throw new Error(`No handler is registered for ACK request event \"${event}\".`);\r\n }\r\n\r\n const firstHandler = handlers.values().next().value as SecureClientEventHandler;\r\n return Promise.resolve(firstHandler(data));\r\n }\r\n\r\n private rejectPendingRpcRequests(error: Error): void {\r\n for (const pendingRequest of this.pendingRpcRequests.values()) {\r\n clearTimeout(pendingRequest.timeoutHandle);\r\n pendingRequest.reject(error);\r\n }\r\n\r\n this.pendingRpcRequests.clear();\r\n }\r\n\r\n private createClientHandshakeState(): ClientHandshakeState {\r\n const { ecdh, localPublicKey } = createEphemeralHandshakeState();\r\n\r\n return {\r\n ecdh,\r\n localPublicKey,\r\n isReady: false,\r\n sharedSecret: null,\r\n encryptionKey: null\r\n };\r\n }\r\n\r\n private sendInternalHandshake(): void {\r\n try {\r\n if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {\r\n return;\r\n }\r\n\r\n if (!this.handshakeState) {\r\n throw new Error(\"Missing client handshake state.\");\r\n }\r\n\r\n this.socket.send(\r\n serializeEnvelope(INTERNAL_HANDSHAKE_EVENT, {\r\n publicKey: this.handshakeState.localPublicKey\r\n })\r\n );\r\n } catch (error) {\r\n this.notifyError(normalizeToError(error, \"Failed to send client handshake payload.\"));\r\n }\r\n }\r\n\r\n private handleInternalHandshake(data: unknown): void {\r\n try {\r\n const payload = parseHandshakePayload(data);\r\n\r\n if (!this.handshakeState) {\r\n throw new Error(\"Missing client handshake state.\");\r\n }\r\n\r\n if (this.handshakeState.isReady) {\r\n return;\r\n }\r\n\r\n const remotePublicKey = Buffer.from(payload.publicKey, \"base64\");\r\n const sharedSecret = this.handshakeState.ecdh.computeSecret(remotePublicKey);\r\n\r\n this.handshakeState.sharedSecret = sharedSecret;\r\n this.handshakeState.encryptionKey = deriveEncryptionKey(sharedSecret);\r\n this.handshakeState.isReady = true;\r\n\r\n this.flushPendingPayloadQueue();\r\n this.notifyReady();\r\n } catch (error) {\r\n this.notifyError(normalizeToError(error, \"Failed to complete client handshake.\"));\r\n }\r\n }\r\n\r\n private isHandshakeReady(): boolean {\r\n return this.handshakeState?.isReady ?? false;\r\n }\r\n\r\n private flushPendingPayloadQueue(): void {\r\n if (!this.socket || this.socket.readyState !== WebSocket.OPEN || !this.isHandshakeReady()) {\r\n return;\r\n }\r\n\r\n const pendingPayloads = this.pendingPayloadQueue;\r\n this.pendingPayloadQueue = [];\r\n\r\n for (const envelope of pendingPayloads) {\r\n this.sendEncryptedEnvelope(envelope);\r\n }\r\n }\r\n}\r\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -5,6 +5,10 @@ interface SecureEnvelope<TData = unknown> {
|
|
|
5
5
|
event: string;
|
|
6
6
|
data: TData;
|
|
7
7
|
}
|
|
8
|
+
interface SecureAckOptions {
|
|
9
|
+
timeoutMs?: number;
|
|
10
|
+
}
|
|
11
|
+
type SecureAckCallback = (error: Error | null, response?: unknown) => void;
|
|
8
12
|
interface SecureServerHeartbeatOptions {
|
|
9
13
|
enabled?: boolean;
|
|
10
14
|
intervalMs?: number;
|
|
@@ -31,6 +35,7 @@ interface SecureServerClient {
|
|
|
31
35
|
id: string;
|
|
32
36
|
socket: WebSocket;
|
|
33
37
|
request: IncomingMessage;
|
|
38
|
+
emit: (event: string, data: unknown, callbackOrOptions?: SecureAckCallback | SecureAckOptions, maybeCallback?: SecureAckCallback) => boolean | Promise<unknown>;
|
|
34
39
|
join: (room: string) => boolean;
|
|
35
40
|
leave: (room: string) => boolean;
|
|
36
41
|
leaveAll: () => number;
|
|
@@ -39,11 +44,11 @@ interface SecureServerRoomOperator {
|
|
|
39
44
|
emit: (event: string, data: unknown) => SecureServer;
|
|
40
45
|
}
|
|
41
46
|
type SecureErrorHandler = (error: Error) => void;
|
|
42
|
-
type SecureServerEventHandler = (data: unknown, client: SecureServerClient) =>
|
|
47
|
+
type SecureServerEventHandler = (data: unknown, client: SecureServerClient) => unknown | Promise<unknown>;
|
|
43
48
|
type SecureServerConnectionHandler = (client: SecureServerClient) => void;
|
|
44
49
|
type SecureServerDisconnectHandler = (client: SecureServerClient, code: number, reason: string) => void;
|
|
45
50
|
type SecureServerReadyHandler = (client: SecureServerClient) => void;
|
|
46
|
-
type SecureClientEventHandler = (data: unknown) =>
|
|
51
|
+
type SecureClientEventHandler = (data: unknown) => unknown | Promise<unknown>;
|
|
47
52
|
type SecureClientConnectHandler = () => void;
|
|
48
53
|
type SecureClientDisconnectHandler = (code: number, reason: string) => void;
|
|
49
54
|
type SecureClientReadyHandler = () => void;
|
|
@@ -76,6 +81,7 @@ declare class SecureServer {
|
|
|
76
81
|
private readonly sharedSecretBySocket;
|
|
77
82
|
private readonly encryptionKeyBySocket;
|
|
78
83
|
private readonly pendingPayloadsBySocket;
|
|
84
|
+
private readonly pendingRpcRequestsBySocket;
|
|
79
85
|
private readonly heartbeatStateBySocket;
|
|
80
86
|
private readonly roomMembersByName;
|
|
81
87
|
private readonly roomNamesByClientId;
|
|
@@ -94,6 +100,9 @@ declare class SecureServer {
|
|
|
94
100
|
off(event: string, handler: SecureServerEventHandler): this;
|
|
95
101
|
emit(event: string, data: unknown): this;
|
|
96
102
|
emitTo(clientId: string, event: string, data: unknown): boolean;
|
|
103
|
+
emitTo(clientId: string, event: string, data: unknown, callback: SecureAckCallback): boolean;
|
|
104
|
+
emitTo(clientId: string, event: string, data: unknown, options: SecureAckOptions): Promise<unknown>;
|
|
105
|
+
emitTo(clientId: string, event: string, data: unknown, options: SecureAckOptions, callback: SecureAckCallback): boolean;
|
|
97
106
|
to(room: string): SecureServerRoomOperator;
|
|
98
107
|
close(code?: number, reason?: string): void;
|
|
99
108
|
private resolveHeartbeatConfig;
|
|
@@ -108,6 +117,11 @@ declare class SecureServer {
|
|
|
108
117
|
private dispatchCustomEvent;
|
|
109
118
|
private sendRaw;
|
|
110
119
|
private sendEncryptedEnvelope;
|
|
120
|
+
private sendRpcRequest;
|
|
121
|
+
private handleRpcResponse;
|
|
122
|
+
private handleRpcRequest;
|
|
123
|
+
private executeRpcRequestHandler;
|
|
124
|
+
private rejectPendingRpcRequests;
|
|
111
125
|
private notifyConnection;
|
|
112
126
|
private notifyReady;
|
|
113
127
|
private notifyError;
|
|
@@ -140,6 +154,7 @@ declare class SecureClient {
|
|
|
140
154
|
private readonly errorHandlers;
|
|
141
155
|
private handshakeState;
|
|
142
156
|
private pendingPayloadQueue;
|
|
157
|
+
private readonly pendingRpcRequests;
|
|
143
158
|
constructor(url: string, options?: SecureClientOptions);
|
|
144
159
|
get readyState(): number | null;
|
|
145
160
|
isConnected(): boolean;
|
|
@@ -156,6 +171,9 @@ declare class SecureClient {
|
|
|
156
171
|
off(event: "error", handler: SecureErrorHandler): this;
|
|
157
172
|
off(event: string, handler: SecureClientEventHandler): this;
|
|
158
173
|
emit(event: string, data: unknown): boolean;
|
|
174
|
+
emit(event: string, data: unknown, callback: SecureAckCallback): boolean;
|
|
175
|
+
emit(event: string, data: unknown, options: SecureAckOptions): Promise<unknown>;
|
|
176
|
+
emit(event: string, data: unknown, options: SecureAckOptions, callback: SecureAckCallback): boolean;
|
|
159
177
|
private resolveReconnectConfig;
|
|
160
178
|
private scheduleReconnect;
|
|
161
179
|
private computeReconnectDelay;
|
|
@@ -169,6 +187,11 @@ declare class SecureClient {
|
|
|
169
187
|
private notifyReady;
|
|
170
188
|
private notifyError;
|
|
171
189
|
private sendEncryptedEnvelope;
|
|
190
|
+
private sendRpcRequest;
|
|
191
|
+
private handleRpcResponse;
|
|
192
|
+
private handleRpcRequest;
|
|
193
|
+
private executeRpcRequestHandler;
|
|
194
|
+
private rejectPendingRpcRequests;
|
|
172
195
|
private createClientHandshakeState;
|
|
173
196
|
private sendInternalHandshake;
|
|
174
197
|
private handleInternalHandshake;
|
|
@@ -176,4 +199,4 @@ declare class SecureClient {
|
|
|
176
199
|
private flushPendingPayloadQueue;
|
|
177
200
|
}
|
|
178
201
|
|
|
179
|
-
export { SecureClient, type SecureClientConnectHandler, type SecureClientDisconnectHandler, type SecureClientEventHandler, type SecureClientEventMap, type SecureClientLifecycleEvent, type SecureClientOptions, type SecureClientReadyHandler, type SecureClientReconnectOptions, type SecureEnvelope, type SecureErrorHandler, SecureServer, type SecureServerClient, type SecureServerConnectionHandler, type SecureServerDisconnectHandler, type SecureServerEventHandler, type SecureServerEventMap, type SecureServerHeartbeatOptions, type SecureServerLifecycleEvent, type SecureServerOptions, type SecureServerReadyHandler, type SecureServerRoomOperator };
|
|
202
|
+
export { type SecureAckCallback, type SecureAckOptions, SecureClient, type SecureClientConnectHandler, type SecureClientDisconnectHandler, type SecureClientEventHandler, type SecureClientEventMap, type SecureClientLifecycleEvent, type SecureClientOptions, type SecureClientReadyHandler, type SecureClientReconnectOptions, type SecureEnvelope, type SecureErrorHandler, SecureServer, type SecureServerClient, type SecureServerConnectionHandler, type SecureServerDisconnectHandler, type SecureServerEventHandler, type SecureServerEventMap, type SecureServerHeartbeatOptions, type SecureServerLifecycleEvent, type SecureServerOptions, type SecureServerReadyHandler, type SecureServerRoomOperator };
|