// Static production server; no wallet, signing, chain state, RPC, DB, or secrets on the server. import http from 'node:http'; import { readFile } from 'node:fs/promises'; import { resolve, extname, sep } from 'node:path'; const root = resolve('dist'); const types = { '.html':'text/html; charset=utf-8', '.js':'text/javascript; charset=utf-8', '.css':'text/css; charset=utf-8', '.svg':'image/svg+xml', '.txt':'text/plain; charset=utf-8', '.json':'application/json' }; const security = { 'Content-Security-Policy': "default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data: blob:; frame-src blob:; connect-src 'self'; object-src 'none'; base-uri 'none'; frame-ancestors 'none'; form-action 'none'", 'X-Content-Type-Options':'nosniff', 'Referrer-Policy':'no-referrer', 'X-Frame-Options':'DENY', 'Permissions-Policy':'camera=(), microphone=(), geolocation=()', }; http.createServer(async (req,res) => { const send = (status, body, headers={}) => { res.writeHead(status, {...security,...headers}); res.end(req.method==='HEAD' ? undefined : body); }; if (!['GET','HEAD'].includes(req.method)) return send(405,'Method not allowed',{'Allow':'GET, HEAD'}); try { const path = decodeURIComponent(new URL(req.url,'http://localhost').pathname); if (path==='/healthz') return send(200,'ok',{'Content-Type':'text/plain'}); const target=resolve(root, '.'+(path==='/' ? '/index.html' : path)); if (!target.startsWith(root+sep)) return send(403,'Forbidden'); const data=await readFile(target); send(200,data,{'Content-Type':types[extname(target)]??'application/octet-stream','Cache-Control':path.startsWith('/assets/')?'public, max-age=31536000, immutable':'no-cache'}); } catch { send(404,'Not found'); } }).listen(Number(process.env.PORT || 8080),'0.0.0.0',()=>console.log(`Super Testnet static server listening on ${process.env.PORT || 8080}`));