const http = require("http"); const https = require("https"); const fs = require("fs"); const url = require("url"); const scrape = require("./scrape.js"); const SQL_DBS = require("./database.js"); const DBPARSE = require("./dbparse.js"); const openFile = require("./open.js").file; const updateDB = require("./update.js"); async function init() { const build = { "./Cont/index.html": buildMain, "./Cont/index.css": buildDefault, "./Cont/devs/index.html": buildDevs, "./Cont/devs/index.css": buildDefault, "./Cont/404/index.css": buildDefault, "./Cont/non-main.css": buildDefault, "./Cont/Images/help.png": buildImage, "./Cont/Images/back.png": buildImage }; const errorPath = "./Cont/404/index.html"; const startDate = new Date(); let visitorCount = 0; // await for needed things in async let [foodsThisWeek, foodsNextWeek, dbcredentials, httpsKey, httpsCert] = await Promise.all([ scrape.food(scrape.link(1)), scrape.food(scrape.link(2)), openFile("../dblogin.txt"), openFile("../Certificate/key.pem"), openFile("../Certificate/cert.pem") ]); // https options, you need to get a certificate in the file ../Certificate for the server to work const httpsOpts = { key: httpsKey, cert: httpsCert }; // get the MySQL DB connection const SQLDB = new SQL_DBS.Database(JSON.parse(dbcredentials)); // get the food "database" const foods = [foodsThisWeek, foodsNextWeek]; // server code async function server(req, res) { // Lightweight analytics. Don't be evil. We just want to know if anyone uses this. visitorCount++; // validate inputs let q = url.parse(req.url, true); let ind = q.query.index; if (typeof ind === "string") ind = validateIndex(q.query.index.substring(0, 20)); else ind = ""; let d = q.query.day; if (typeof d === "string") d = antiXSS(d); else d = ""; q.query = { index: ind, day: d }; let path = "./Cont" + antiXSS(q.pathname); if (isDir(path)) path += ["/index.html", "index.html"][+(path[path.length - 1] === "/")]; // pack the data required by the builders let data; const args = { "path": path, "path404": errorPath, "query": q.query, "foods": foods, "sqldb": SQLDB }; // build the page const buildFound = +(typeof build[path] === "function"); res.writeHead([404, 200][buildFound]); data = await [build404, build[path]][buildFound](args); res.write(data); res.end(); } // start server const runningServer = https.createServer(httpsOpts, server).listen(8080); // stop server async function closeServer() { const uptime = ((new Date()).getTime() - startDate.getTime()) / 1000; console.log(`Stats:\nServer uptime: ${uptime} s\nVisitor count: ${visitorCount}\nVisitors per day: ${visitorCount / (uptime / (24 * 60 * 60))}\n\nShutting down...`); await SQLDB.close(); console.log("MySQL closed"); runningServer.close(); console.log("Server shut down"); console.log("Process exiting..."); process.exit(0); } process.on("SIGINT", closeServer); process.on("SIGQUIT", closeServer); process.on("SIGTERM", closeServer); } function validateIndex(sus) { return antiXSS(DBPARSE.cluttered(sus)); } function antiXSS(sus) { if (!(typeof sus === "string")) return ""; return replace(sus, ["<", ">", "(", ")"], ["<", ">", "(", ")"]); } function isDir(path) { return (DBPARSE.getNextChar(path.substring(1), ".") === -1); } function replace(s, from, to) { for (let i = 0; i < from.length; i++) { s = s.replaceAll(from[i], to[i]); } return s; } async function buildMain(args) { // get the passed arguments const path = args["path"]; const query = args["query"]; const foods = args["foods"]; const index = query.index; const SQLDB = args["sqldb"]; const data = await openFile(path); let data_string = data.toString("utf-8"); // here are the things to replace in the html page let res = {}; // get valid day const d = new Date(); let day = d.getDay(); day = (day + +(day === 0) * 7) - 1; const actualDay = day + (+(day === 0) * 7); day = +(!(day === 5) && !(day === 6)) * day; if ((typeof query.day === "string") && (parseInt(query.day).toString() === query.day) && (!isNaN(parseInt(query.day))) && (parseInt(query.day) >= 0) && (parseInt(query.day) < 5)) day = parseInt(query.day); // set the day selected (must be done manually with this replacement system) data_string = data_string.replace(`