const express = require('express'); const cors = require('cors'); const { createProxyMiddleware } = require('http-proxy-middleware'); const fs = require('fs'); const path = require('path'); const WebSocket = require('ws'); const http = require('http'); const app = express(); const port = 3000; // Create HTTP server const server = http.createServer(app); // Create WebSocket server const wss = new WebSocket.Server({ server }); // WebSocket connections let connections = new Set(); // WebSocket connection handling wss.on('connection', (ws) => { connections.add(ws); console.log('[WS] Client connected'); ws.on('close', () => { connections.delete(ws); console.log('[WS] Client disconnected'); }); }); // Add request logging middleware app.use((req, res, next) => { console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`); console.log('[INCOMING HEADERS]', req.headers); // Log incoming headers next(); }); // Watch for changes to PVC.html fs.watch(path.join(__dirname, 'PVC.html'), (eventType, filename) => { if (eventType === 'change') { console.log(`[${new Date().toISOString()}] PVC.html updated`); // Notify all connected clients connections.forEach(client => { if (client.readyState === WebSocket.OPEN) { client.send('reload'); } }); } }); // Serve static files app.use(express.static('./')); // Enable CORS app.use(cors()); // Proxy middleware configuration const apiProxy = createProxyMiddleware({ router: (req) => { const apiUri = req.headers['x-api-uri']; if (!apiUri) { throw new Error('API URI not configured'); } return apiUri; }, changeOrigin: true, secure: false, logLevel: 'debug', pathRewrite: function (path, req) { // Just strip /proxy, don't add /api/v1 since it's in the backend URI return path.replace('/proxy', ''); }, onProxyReq: (proxyReq, req, res) => { // Preserve case sensitivity of the header const apiKey = req.headers['x-api-key']; if (apiKey) { proxyReq.setHeader('X-Api-Key', apiKey); console.log('[API KEY HEADER SET]', apiKey); // Log the key being set } else { console.log('[WARNING] No API key found in request headers'); } // Log all headers being sent to backend console.log('[OUTGOING HEADERS]', proxyReq.getHeaders()); }, onProxyRes: function(proxyRes, req, res) { proxyRes.headers['Access-Control-Allow-Origin'] = '*'; proxyRes.headers['Access-Control-Allow-Methods'] = 'GET, POST, OPTIONS'; proxyRes.headers['Access-Control-Allow-Headers'] = 'Content-Type,Accept,X-API-URI,X-Api-Key'; console.log(`[PROXY RES] ${req.method} ${req.path} -> ${proxyRes.statusCode}`); }, onError: (err, req, res) => { console.error('[PROXY ERROR]', err); } }); // Handle OPTIONS requests with correct case for header app.options('*', cors({ allowedHeaders: ['Content-Type', 'Accept', 'X-API-URI', 'X-Api-Key'] })); app.use('/proxy', apiProxy); // Use server.listen instead of app.listen server.listen(port, () => { console.log(`Proxy server running at http://localhost:${port}`); });