// BizGaze Connect — backend entry point. // Thin wiring layer: HTTP request dispatch + WebSocket attach + listeners. // All logic lives in focused modules: // repos.js data-access (all SQL) // bizgaze.js BizGaze identity provider // lib.js HTTP helpers (json/readBody/parseCookies/now) // session.js currentUser / audit // presence.js shared in-memory live state (agents/sessions/shares) // routes.js HTTP JSON API (/api/*, /sso) // static.js static files + authenticated downloads (GET fallback) // signaling.js WebSocket signaling (consent + SDP/ICE relay) const http = require('http'); const https = require('https'); const fs = require('fs'); const path = require('path'); const { WebSocketServer } = require('ws'); const { PORT, HTTPS_PORT } = require('./config'); const { json } = require('./lib'); const routes = require('./routes'); const { handleGet } = require('./static'); const { onConnection } = require('./signaling'); // ---------- HTTP request dispatch ---------- const server = http.createServer((req, res) => { const key = `${req.method} ${req.url.split('?')[0]}`; // Route/static handlers are async now (DB adapter). Catch any rejection so a handler error becomes a // 500 instead of a hung request + unhandled promise rejection. let p; if (routes[key]) p = routes[key](req, res); else if (req.method === 'GET') p = handleGet(req, res); // downloads + static else return json(res, 404, { error: 'not found' }); if (p && typeof p.catch === 'function') p.catch((e) => { try { console.error('handler error', key, e && e.message); json(res, 500, { error: 'server error' }); } catch (_) {} }); }); // ---------- WebSocket signaling ---------- const wss = new WebSocketServer({ server, path: '/ws' }); wss.on('connection', onConnection); server.listen(PORT, () => { console.log(`HTTP on http://localhost:${PORT}`); try { require('./media').backfill(); } catch (e) {} // streaming renditions for older video uploads }); // HTTPS — required so other devices can share their screen (browsers block // screen capture on non-secure origins). Uses cert.pem/key.pem if present. let httpsServer = null; try { const certPath = path.join(__dirname, 'cert.pem'); const keyPath = path.join(__dirname, 'key.pem'); if (fs.existsSync(certPath) && fs.existsSync(keyPath)) { httpsServer = https.createServer( { cert: fs.readFileSync(certPath), key: fs.readFileSync(keyPath) }, (req, res) => server.emit('request', req, res) ); const wssSecure = new WebSocketServer({ server: httpsServer, path: '/ws' }); wssSecure.on('connection', onConnection); httpsServer.listen(HTTPS_PORT, () => { console.log(`HTTPS on https://localhost:${HTTPS_PORT} (use this address from other devices)`); console.log(` End user shares screen: https://:${HTTPS_PORT}/share`); console.log(` Technician connects: https://:${HTTPS_PORT}/connect`); }); } else { console.log('(No cert.pem/key.pem found — HTTPS disabled. Other devices can view but not share their screen.)'); } } catch (e) { console.log('HTTPS failed to start:', e.message); } module.exports = { server };