import http from 'node:http'; import httpProxy from 'http-proxy'; const PORT = Number(process.env.PORT || 8080); const TARGET = process.env.SUPABASE_TARGET || 'https://cksuehzcimitsxmeloes.supabase.co'; const allowedOrigins = new Set([ 'https://app.caterium.ru', 'https://caterium.ru', 'https://www.caterium.ru' ]); const proxy = httpProxy.createProxyServer({ target: TARGET, changeOrigin: true, xfwd: true, secure: true, ws: true }); proxy.on('proxyReq', (proxyReq) => { proxyReq.setHeader('host', new URL(TARGET).host); }); proxy.on('error', (err, req, res) => { console.error('[proxy:error]', err?.message || err); if (res && !res.headersSent) { res.writeHead(502, {'content-type':'application/json; charset=utf-8'}); } try { res?.end(JSON.stringify({error:'upstream_unavailable'})); } catch (_) {} }); function cors(req, res) { const origin = req.headers.origin; if (origin && !allowedOrigins.has(origin)) return false; if (origin) { res.setHeader('Access-Control-Allow-Origin', origin); res.setHeader('Vary', 'Origin'); } res.setHeader('Access-Control-Allow-Credentials', 'true'); res.setHeader('Access-Control-Allow-Headers', req.headers['access-control-request-headers'] || 'authorization,apikey,content-type,x-client-info,prefer,range'); res.setHeader('Access-Control-Allow-Methods', 'GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS'); return true; } const server = http.createServer((req, res) => { if (!cors(req, res)) { res.writeHead(403, {'content-type':'application/json; charset=utf-8'}); return res.end(JSON.stringify({error:'origin_not_allowed'})); } if (req.method === 'OPTIONS') { res.writeHead(204); return res.end(); } if (req.url === '/health' || req.url === '/healthz') { res.writeHead(200, {'content-type':'application/json; charset=utf-8'}); return res.end(JSON.stringify({ok:true,target:'supabase'})); } if (!/^\/(rest|auth|storage|functions|realtime)\/v1(?:\/|\?|$)/.test(req.url || '')) { res.writeHead(404, {'content-type':'application/json; charset=utf-8'}); return res.end(JSON.stringify({error:'route_not_allowed'})); } proxy.web(req, res); }); server.on('upgrade', (req, socket, head) => { const origin = req.headers.origin; if (origin && !allowedOrigins.has(origin)) return socket.destroy(); if (!/^\/realtime\/v1(?:\/|\?|$)/.test(req.url || '')) return socket.destroy(); proxy.ws(req, socket, head); }); server.listen(PORT, '0.0.0.0', () => { console.log(`[caterium-proxy] listening on ${PORT} -> ${TARGET}`); });