UNPKG

@gacua/backend

Version:

GACUA Backend

74 lines 3.02 kB
/** * @license * Copyright 2025 MuleRun * SPDX-License-Identifier: Apache-2.0 */ import { WebSocketServer } from 'ws'; import { URL } from 'url'; import { randomUUID } from 'crypto'; import { handleMessage } from './handle-message.js'; import { validateTokenString } from '../auth/token.js'; import { logger } from '../logger.js'; const wsLogger = logger.child({ module: 'websocket' }); export function setupWebSocketServer(server) { wsLogger.info('Setting up WebSocket server'); const wss = new WebSocketServer({ server, verifyClient: (info) => { const url = new URL(info.req.url || '', `http://${info.req.headers.host}`); const token = url.searchParams.get('token'); wsLogger.debug({ origin: info.origin, userAgent: info.req.headers['user-agent'], remoteAddress: info.req.socket.remoteAddress, }, 'WebSocket connection attempt'); if (!validateTokenString(token || '')) { wsLogger.warn({ origin: info.origin, remoteAddress: info.req.socket.remoteAddress, hasToken: !!token, }, 'WebSocket connection rejected: Invalid or missing token'); return false; } wsLogger.debug({ origin: info.origin }, 'WebSocket token validation successful'); return true; }, }); let connectionCounter = 0; const wsConnections = new Map(); wss.on('connection', (ws, req) => { const connectionId = `ws-${connectionCounter++}-${randomUUID()}`; const connectionLogger = wsLogger.child({ connectionId }); wsConnections.set(ws, { connectionId, logger: connectionLogger }); connectionLogger.info({ remoteAddress: req.socket.remoteAddress, userAgent: req.headers['user-agent'], timestamp: new Date().toISOString(), }, 'WebSocket connection established'); ws.on('message', async (message) => { connectionLogger.debug('Received WebSocket message'); try { await handleMessage(ws, message); connectionLogger.debug('WebSocket message handled successfully'); } catch (error) { connectionLogger.error({ err: error }, 'Failed to handle WebSocket message'); } }); ws.on('close', (code, reason) => { connectionLogger.info({ closeCode: code, closeReason: reason?.toString(), }, 'WebSocket connection closed'); wsConnections.delete(ws); }); ws.on('error', (error) => { connectionLogger.error({ err: error }, 'WebSocket connection error'); }); ws.on('pong', () => { connectionLogger.debug('Received WebSocket pong'); }); }); wsLogger.info('WebSocket server setup completed'); } //# sourceMappingURL=index.js.map