Files
Admin/index.js
2025-12-20 14:39:14 -06:00

202 lines
5.4 KiB
JavaScript

// server.js
const fs = require("fs");
const http = require("http");
const https = require("https");
const tls = require("tls");
const httpProxy = require("http-proxy");
const { WebSocketServer } = require('ws')
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);
try {
res.statusCode = 502;
res.end("Bad Gateway");
} catch {}
});
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()