const express = require('express'); const cors = require('cors'); const path = require('path'); const fs = require('fs').promises; const { createProxyMiddleware, fixRequestBody } = require('http-proxy-middleware'); const app = express(); app.use(cors()); app.use(express.json()); // Add JSON body parser // Helpers function normalizeUrl(u) { try { return new URL(u); } catch { return null; } } // Env-configurable allowed origins for proxying const RAW_ALLOWED = process.env.ALLOWED_PROXY_ORIGINS || '*'; const ALLOW_ANY = RAW_ALLOWED.trim() === '*'; const allowedOrigins = ALLOW_ANY ? ['*'] : RAW_ALLOWED.split(',') .map((s) => s.trim()) .filter(Boolean); if (ALLOW_ANY) { console.log('[proxy] ALLOWED_PROXY_ORIGINS="*" (allow any http/https target)'); } else { console.log('[proxy] Allowed proxy origins:', allowedOrigins); } // Generic proxy endpoint app.use( '/proxy', (req, res, next) => { const targetUrlString = req.get('x-proxy-target'); if (!targetUrlString) { return res.status(400).send('Missing x-proxy-target header'); } const targetUrl = normalizeUrl(targetUrlString); if (!targetUrl) { return res.status(400).send('Invalid x-proxy-target URL'); } if (!ALLOW_ANY && !allowedOrigins.includes(targetUrl.origin)) { return res.status(403).send(`Proxy target origin "${targetUrl.origin}" not allowed.`); } // Pass the full URL to the proxy middleware req._proxyTarget = targetUrlString; next(); }, createProxyMiddleware({ router: (req) => new URL(req._proxyTarget).origin, changeOrigin: true, pathRewrite: (_path, req) => { const targetUrl = new URL(req._proxyTarget); return `${targetUrl.pathname}${targetUrl.search}`; }, secure: false, logLevel: 'debug', onProxyReq: fixRequestBody, // Fixes body for POST/PUT requests }) ); // API endpoint to save config app.post('/api/save-config', async (req, res) => { try { const configPath = path.join(__dirname, 'main_web/src/assets/config.json'); const configData = JSON.stringify(req.body, null, 2); await fs.writeFile(configPath, configData, 'utf8'); console.log('Config saved successfully to:', configPath); res.json({ success: true, message: 'Configuration saved successfully' }); } catch (error) { console.error('Error saving config:', error); res.status(500).json({ success: false, message: 'Failed to save configuration', error: error.message }); } }); const distPath = path.join(__dirname, 'dist'); app.use(express.static(distPath)); // Simple health check app.get('/__health', (req, res) => res.json({ ok: true })); // SPA fallback app.get('*', (req, res) => { res.sendFile(path.join(distPath, 'index.html')); }); const port = process.env.PORT || 8080; app.listen(port, () => { console.log(`Server running on http://localhost:${port}`); });