randomayzer/tools/serve-production.cjs

29 lines
2.1 KiB
JavaScript

'use strict';
const http = require('node:http');
const next = require('next');
const { sanitizeProxyHeaders } = require('./production-transport.cjs');
async function main() {
if (process.env.NODE_ENV !== 'production') throw new Error('Production server requires NODE_ENV=production');
const origin = new URL(process.env.APP_BASE_URL);
const local = process.env.DEPLOYMENT_PROFILE === 'local-single-user';
if (origin.username || origin.password || origin.pathname !== '/' || origin.search || origin.hash) throw new Error('Invalid canonical origin');
if (local ? !(origin.protocol === 'http:' && ['localhost', '127.0.0.1', '[::1]'].includes(origin.hostname)) : origin.protocol !== 'https:') throw new Error('Invalid production origin/profile');
if (process.env.VK_REDIRECT_URI !== `${origin.origin}/api/auth/vk/callback`) throw new Error('Invalid VK redirect URI');
const trustedProxyIp = process.env.TRUSTED_PROXY_IP || '';
if (trustedProxyIp && (local || trustedProxyIp !== '10.77.0.1')) throw new Error('Only the configured VPS peer 10.77.0.1 is supported');
// TRUST_PROXY is safe only after this socket-aware ingress sanitizes the request.
process.env.TRUST_PROXY = 'true';
const app = next({ dev: false });
await app.prepare();
const handle = app.getRequestHandler();
const server = http.createServer({ maxHeaderSize: 16384 }, (req, res) => {
sanitizeProxyHeaders(req, { trustedProxyIp, origin });
handle(req, res).catch(() => { if (!res.headersSent) res.writeHead(500); res.end('Request failed'); });
});
server.requestTimeout = 120000;
server.headersTimeout = 20000;
// Container binds internally; Compose publishes only the exact host loopback/WG addresses.
server.listen(Number(process.env.PORT || 3100), process.env.BIND_ADDRESS || '127.0.0.1', () => console.log('Randomayzer production listener ready'));
for (const signal of ['SIGTERM', 'SIGINT']) process.on(signal, () => server.close(() => process.exit(0)));
}
main().catch(() => { console.error('Production startup failed: check canonical origin, redirect, profile and required environment'); process.exitCode = 1; });