Spaces:
Running
Running
| import type { Server as SocketIOServer } from 'socket.io'; | |
| import jwt from 'jsonwebtoken'; | |
| import { config } from '../config/env.js'; | |
| import pino from 'pino'; | |
| const logger = pino({ level: 'info', transport: { target: 'pino-pretty', options: { colorize: true } } }); | |
| export function setupScanEvents(io: SocketIOServer) { | |
| io.on('connection', (socket) => { | |
| // Authenticate the socket connection using JWT from cookies or auth query | |
| let userId: string | null = null; | |
| try { | |
| const cookieHeader = socket.handshake.headers.cookie || ''; | |
| const tokenMatch = cookieHeader.match(/token=([^;]+)/); | |
| const token = tokenMatch?.[1] || (socket.handshake.auth?.token as string); | |
| if (token) { | |
| const payload = jwt.verify(token, config.JWT_SECRET) as { userId: string }; | |
| userId = payload.userId; | |
| // Join user-specific room so events are scoped | |
| socket.join(`user:${userId}`); | |
| logger.info({ socketId: socket.id, userId }, 'Client authenticated and joined user room'); | |
| } else { | |
| logger.warn({ socketId: socket.id }, 'Client connected without auth token'); | |
| } | |
| } catch (err) { | |
| logger.warn({ socketId: socket.id }, 'Client connected with invalid token'); | |
| } | |
| socket.on('scan:join', (jobId: string) => { | |
| socket.join(`scan:${jobId}`); | |
| logger.info({ socketId: socket.id, jobId }, 'Client joined scan room'); | |
| }); | |
| socket.on('scan:leave', (jobId: string) => { | |
| socket.leave(`scan:${jobId}`); | |
| }); | |
| socket.on('disconnect', () => { | |
| logger.info(`Client disconnected: ${socket.id}`); | |
| }); | |
| }); | |
| } | |