// FORSLAG TIL opax-web/backend/socketHandlers.js (ENDELIG KORRIGERT) /** * Normaliserer resultatet fra MCP-toolen 'get_git_status'. * Kaster feil hvis responsen ikke har forventet format. * @param {any} data - Rådata fra agentClient. * @returns {{status: string, details: string}} Normalisert status-objekt. */ function normalizeGitStatus(data) { if ( !data || typeof data !== 'object' || Array.isArray(data) || typeof data.status !== 'string' || typeof data.details !== 'string' ) { throw new Error('Unexpected Git status response shape.'); } return { status: data.status, details: data.details, }; } /** * Normaliserer resultatet fra MCP-toolen 'get_git_branch'. * Kaster feil hvis responsen ikke har forventet format. * @param {any} data - Rådata fra agentClient. * @returns {{current_branch: string}} Normalisert branch-objekt. */ function normalizeGitBranch(data) { if ( !data || typeof data !== 'object' || Array.isArray(data) || typeof data.current_branch !== 'string' ) { // I motsetning til forrige versjon, tillater vi ikke lenger null her. // Hvis branchen er borte, bør MCP-toolen returnere en tom string. // Ugyldig format skal alltid feile. throw new Error('Unexpected Git branch response shape.'); } return { current_branch: data.current_branch, }; } const SAFE_ACTIONS = { 'git:getStatus': { tool: 'get_git_status', responseEvent: 'git:status', errorMessage: 'Kunne ikke hente Git-status.', normalize: normalizeGitStatus, }, 'git:getBranch': { tool: 'get_git_branch', responseEvent: 'git:branch', errorMessage: 'Kunne ikke hente aktiv branch.', normalize: normalizeGitBranch, }, }; /** * Registrerer sikre, nettleser-eksponerte Socket.IO-handlere. * @param {import('socket.io').Socket} socket - Den tilkoblede socketen. * @param {{callAgentFn: function}} dependencies - Injisert avhengighet for å kalle MCP. */ export function registerBrowserSocketHandlers(socket, { callAgentFn }) { // Avvis den gamle, usikre mcp-call-handleren socket.on('mcp-call', (payload) => { const safeId = (payload && typeof payload.id === 'string' && payload.id.length <= 128) ? payload.id : null; socket.emit('mcp-result', { id: safeId, error: 'Denne funksjonen er ikke tilgjengelig.', }); }); // Registrer de nye, sikre handlerne for (const eventName in SAFE_ACTIONS) { const config = SAFE_ACTIONS[eventName]; socket.on(eventName, async () => { if (!socket.request.session?.user) { return socket.emit(`${config.responseEvent}:error`, { message: 'Du må være logget inn.' }); } try { const result = await callAgentFn(config.tool, {}); const normalizedData = config.normalize(result); socket.emit(`${config.responseEvent}:result`, { data: normalizedData }); } catch (e) { console.error(`[Socket Handler Error] Event: ${eventName}, User: ${socket.request.session.user.email}, Error:`, e); // e.message logges ikke eller sendes til klienten. socket.emit(`${config.responseEvent}:error`, { message: config.errorMessage }); } }); } }