(socket: AuthenticatedSocket, roomManager: IRoomManager)
| 9 | const logger = createLogger('WorkflowHandlers') |
| 10 | |
| 11 | export function setupWorkflowHandlers(socket: AuthenticatedSocket, roomManager: IRoomManager) { |
| 12 | socket.on('join-workflow', async ({ workflowId, tabSessionId }) => { |
| 13 | try { |
| 14 | const userId = socket.userId |
| 15 | const userName = socket.userName |
| 16 | |
| 17 | if (!userId || !userName) { |
| 18 | logger.warn(`Join workflow rejected: Socket ${socket.id} not authenticated`) |
| 19 | socket.emit('join-workflow-error', { |
| 20 | workflowId, |
| 21 | error: 'Authentication required', |
| 22 | code: 'AUTHENTICATION_REQUIRED', |
| 23 | retryable: false, |
| 24 | }) |
| 25 | return |
| 26 | } |
| 27 | |
| 28 | if (!roomManager.isReady()) { |
| 29 | logger.warn(`Join workflow rejected: Room manager unavailable`) |
| 30 | socket.emit('join-workflow-error', { |
| 31 | workflowId, |
| 32 | error: 'Realtime unavailable', |
| 33 | code: 'ROOM_MANAGER_UNAVAILABLE', |
| 34 | retryable: true, |
| 35 | }) |
| 36 | return |
| 37 | } |
| 38 | |
| 39 | logger.info(`Join workflow request from ${userId} (${userName}) for workflow ${workflowId}`) |
| 40 | |
| 41 | // Verify workflow access |
| 42 | let userRole: string |
| 43 | try { |
| 44 | const accessInfo = await verifyWorkflowAccess(userId, workflowId) |
| 45 | if (!accessInfo.hasAccess) { |
| 46 | logger.warn(`User ${userId} (${userName}) denied access to workflow ${workflowId}`) |
| 47 | socket.emit('join-workflow-error', { |
| 48 | workflowId, |
| 49 | error: 'Access denied to workflow', |
| 50 | code: 'ACCESS_DENIED', |
| 51 | retryable: false, |
| 52 | }) |
| 53 | return |
| 54 | } |
| 55 | userRole = accessInfo.role || 'read' |
| 56 | } catch (error) { |
| 57 | logger.warn(`Error verifying workflow access for ${userId}:`, error) |
| 58 | socket.emit('join-workflow-error', { |
| 59 | workflowId, |
| 60 | error: 'Failed to verify workflow access', |
| 61 | code: 'VERIFY_WORKFLOW_ACCESS_FAILED', |
| 62 | retryable: true, |
| 63 | }) |
| 64 | return |
| 65 | } |
| 66 | |
| 67 | // Leave current room if in one |
| 68 | const currentWorkflowId = await roomManager.getWorkflowIdForSocket(socket.id) |
no test coverage detected