// server.js const fs = require("fs"); const http = require("http"); const https = require("https"); const tls = require("tls"); const httpProxy = require("http-proxy"); const path = require("path"); // --------------------------- // Request Log Store // --------------------------- let requests = []; // Mutex not required in Node (single-threaded) function recordRequest(info) { requests.push(info); } // --------------------------- // IP Helpers // --------------------------- function isLocalIP(ip) { if (ip === "::1" || ip === "127.0.0.1") return true; return false; } function cleanIP(remoteAddr) { if (!remoteAddr) return ""; let ip = remoteAddr.split(":")[0].replace("[", "").replace("]", ""); if (ip.startsWith("::ffff:")) ip = ip.replace("::ffff:", ""); return ip; } // --------------------------- // Logging Middleware // --------------------------- function loggingMiddleware(next) { return (req, res) => { const rawIP = req.socket.remoteAddress; const ip = cleanIP(rawIP); let path = req.url.startsWith("/") ? req.url.slice(1) : req.url; if (path === "") path = "/"; const now = new Date(); const h = now.getHours(); const hour12 = h % 12 === 0 ? 12 : h % 12; const ampm = h < 12 ? "am" : "pm"; const timestamp = `${now.getMonth() + 1}.${now.getDate()} ${hour12}:${String(now.getMinutes()).padStart(2,"0")}:${String(now.getSeconds()).padStart(2,"0")}${ampm}`; if (isLocalIP(ip)) { console.log(`${req.headers.host} ${ip} ${path}`); } else { console.log( `\x1b[33m${timestamp}\x1b[0m ${ip} \x1b[94m${req.headers.host} ${path}\x1b[0m` ); } recordRequest({ Timestamp: new Date().toISOString(), Host: req.headers.host || "", IP: ip, Path: path, Method: req.method }); next(req, res); }; } // --------------------------- // Proxy helper // --------------------------- const proxy = httpProxy.createProxyServer({}); function serveProxy(req, res, port) { proxy.web(req, res, { target: `http://localhost:${port}` }); } proxy.on("error", (err, req, res) => { console.error("Proxy error:", err.message); if (res.headersSent) { res.end(); return; } res.writeHead(502, { "Content-Type": "text/plain" }); res.end("⚠️ target is unavailable. Please try again later."); }); proxy.on("proxyReq", (proxyReq, req, res) => { proxyReq.setHeader("X-Forwarded-Proto", "https"); }); // --------------------------- // Outside Requests // --------------------------- function getPortForHost(host) { host = host.toLowerCase(); if (host.endsWith(".parchment.page")) host = "parchment.page"; switch (host) { case "america.sun.museum": return 8000 case "thefiveprinciples.org": return 3001 case "americanforum.net": return 3002 case "hyperia.so": return 3003 case "pma.aryan.so": case "aryan.so": case "apply.aryan.so": return 3004 case "parchment.page": return 3005 case "government.forum": return 3006 case "noahkurtis.com": return 3007 case "comalyr.com": return 3008 case "blockcatcher.sun.museum": return 3009 case "git.sun.museum": return 4000 case "log.sun.museum": return 4001 case "admin.sun.museum": return 8080 default: return null } } function handler(req, res) { const port = getPortForHost(req.headers.host); if (port) return serveProxy(req, res, port); res.writeHead(200, {"Content-Type":"text/plain"}); res.end("Hello, World! You're from outside."); } // --------------------------- // Begin // --------------------------- function startServer() { const certs = {}; function loadCert(domain) { const base = `/etc/letsencrypt/live/${domain}`; const cert = { key: fs.readFileSync(`${base}/privkey.pem`, "utf8"), cert: fs.readFileSync(`${base}/fullchain.pem`, "utf8"), }; certs[domain] = cert; } loadCert("parchment.page-0001"); loadCert("hyperia.so-0001"); const httpsOptions = { SNICallback: (servername, cb) => { servername = servername.toLowerCase(); if (certs[servername]) { return cb(null, tls.createSecureContext(certs[servername])); } if (servername.endsWith(".parchment.page")) { return cb(null, tls.createSecureContext(certs["parchment.page-0001"])); } return cb(null, tls.createSecureContext(certs["hyperia.so-0001"])); }, minVersion: "TLSv1.2", }; const server = https.createServer(httpsOptions, loggingMiddleware(handler)); server.on("upgrade", (req, socket, head) => { const port = getPortForHost(req.headers.host); if (!port) return socket.destroy(); proxy.ws(req, socket, head, { target: `http://localhost:${port}` }); socket.on("error", (err) => { console.error("WebSocket error:", err.message); socket.destroy(); }); }); server.listen(3000, () => { console.log("🔒 HTTPS server running on port 3000"); }); } startServer()