/* ---------------------------------------------------------------------------- Question Server GitLab: This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ------------------------------------------------------------------------- */ const startHTTPS = true; const siteUrl = "https://qmining.tk"; // http(s)//asd.basd const ircURL = "https://kiwiirc.com/nextclient/irc.sub.fm/#qmining"; const express = require('express'); const bodyParser = require('body-parser'); const busboy = require('connect-busboy'); const fs = require('fs'); const app = express(); const http = require('http'); const https = require('https'); const logger = require('./logger.js'); const utils = require('./utils.js'); const actions = require('./actions.js'); const stat = require('./stat.js'); const recivedFiles = "public/recivedfiles"; const uloadFiles = "public/f"; const staticFile = "public/data/static"; const dataFile = "public/data.json"; const manFile = "public/man.html"; const simpOutFile = "public/simplified"; const inputFile = "stats/inputs"; const msgFile = "stats/msgs"; const logFile = "stats/logs"; const allLogFile = "/nlogs/log"; // https://certbot.eff.org/ const privkeyFile = "/etc/letsencrypt/live/qmining.tk/privkey.pem"; const fullchainFile = "/etc/letsencrypt/live/qmining.tk/fullchain.pem"; const chainFile = "/etc/letsencrypt/live/qmining.tk/chain.pem"; var certsLoaded = false; if (startHTTPS && utils.FileExists(privkeyFile) && utils.FileExists(fullchainFile) && utils.FileExists( chainFile)) { try { const key = fs.readFileSync(privkeyFile, "utf8"); const cert = fs.readFileSync(fullchainFile, "utf8"); const ca = fs.readFileSync(chainFile, "utf8"); var certs = { key: key, cert: cert, ca: ca }; certsLoaded = true; } catch (e) { logger.Log("Error loading cert files!", logger.GetColor("redbg")); } } const port = 8080; const httpsPort = 8443; app.set('view engine', 'ejs'); app.use(function(req, res, next) { res.on('finish', function() { logger.LogReq(req, true, res.statusCode); if (res.statusCode != 404) stat.LogStat(req.url); }); next(); }); app.use(express.static('public')); app.use(busboy({ limits: { fileSize: 10 * 1024 * 1024 } })); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ limit: '5mb', extended: true })); app.use(bodyParser.json({ limit: '5mb' })); app.get('/', function(req, res) { res.render('main', { siteurl: siteUrl, qa: actions.ProcessQA() }); res.end(); }); app.get('/sio', function(req, res) { res.render('uload'); res.end(); }); app.get('/manual', function(req, res) { res.render('man'); res.end(); logger.LogReq(req); }); app.get('/public', function(req, res) { var response = '@Plz update :)'; response += utils.ReadFile(staticFile); res.write(response); res.end(); }); app.get('/static', function(req, res) { var response = '@Plz update :)'; response += utils.ReadFile(staticFile); res.write(response); res.end(); }); app.get('/legacy', function(req, res) { var f = utils.ReadFile(dataFile); var d = actions.LoadJSON(f); let qcount = 0; for (let i = 0; i < d.length; i++) qcount += d.Subjects[i].length; let scount = d.length; res.render('alldata', { data: d, scount: scount, qcount: qcount, siteurl: siteUrl }); logger.LogReq(req); }); app.post('/postfeedback', function(req, res) { res.redirect('back'); logger.Log("New feedback message", logger.GetColor("bluebg"), true); utils.AppendToFile("\n\n" + logger.GetDateString() + ": " + req.body.message_field, msgFile); }); app.get('/postfeedback', function(req, res) { // TODO: res.redirect("/"); or if needs this anyways, becouse /postfeedback post handler already // redirects res.render('main', { sdata: utils.ReadFile(staticFile) }); }); app.post('/isAdding', function(req, res) { res.end('OK'); logger.LogReq(req); actions.ProcessIncomingRequest(req.body.datatoadd); utils.WriteBackup(); }); app.get('/lred', function(req, res) { res.redirect("/legacy"); res.end(); logger.LogReq(req); }); app.get('/menuClick', function(req, res) { res.redirect("/"); res.end(); logger.LogReq(req); }); app.get('/irc', function(req, res) { res.redirect(ircURL); res.end(); logger.LogReq(req); }); // all questions readable app.get('/allqr', function(req, res) { var f = utils.ReadFile(dataFile); var d = actions.LoadJSON(f); res.render('allqr', { d: d.toString().split('\n') }); logger.LogReq(req); }); app.get('/greasy', function(req, res) { res.redirect("https://greasyfork.org/en/scripts/38999-moodle-elearning-kmooc-test-help"); res.end(); logger.LogReq(req); }); app.get('/scriptgit', function(req, res) { res.redirect("https://gitlab.com/YourFriendlyNeighborhoodDealer/moodle-test-userscript"); res.end(); logger.LogReq(req); }); app.get('/servergit', function(req, res) { res.redirect("https://gitlab.com/YourFriendlyNeighborhoodDealer/question-node-server"); res.end(); logger.LogReq(req); }); function UploadFile(req, res, path, next) { var fstream; req.pipe(req.busboy); req.busboy.on('file', function(fieldname, file, filename) { logger.Log("Uploading: " + filename, logger.GetColor("blue")); utils.CreatePath(path, true); let d = new Date(); let fsplit = filename.split('.'); let fn = d.getHours() + "" + d.getMinutes() + "" + d.getSeconds() + "." + fsplit[fsplit.length - 1]; fstream = fs.createWriteStream(path + "/" + fn); file.pipe(fstream); fstream.on('close', function() { logger.Log("Upload Finished of " + path + "/" + fn, logger.GetColor("blue")); next(fn); }); fstream.on('error', function(err) { console.log(err); res.end("something bad happened :s"); }); }); } app.route('/fosuploader').post(function(req, res, next) { UploadFile(req, res, uloadFiles, (fn) => { res.redirect("/f/" + fn); }); }); app.route('/badtestsender').post(function(req, res, next) { UploadFile(req, res, recivedFiles, (fn) => { res.render("uploaded"); }); logger.LogReq(req); }); app.get('*', function(req, res) { res.render('404'); res.status(404); // utils.AppendToFile(logger.GetDateString() + ": " + "404 GET", logFile); }); app.post('*', function(req, res) { res.status(404); // utils.AppendToFile(logger.GetDateString() + ": " + "404 POST", logFile); }); var msg = ""; stat.Load(); const httpServer = http.createServer(app); httpServer.listen(port); msg += "Server listening on port " + port + " (http)"; if (startHTTPS && certsLoaded) { const httpsServer = https.createServer(certs, app); httpsServer.listen(httpsPort); msg += ", and " + httpsPort + " (https)..."; } else { logger.Log("Cert files does not exists, starting http only!", logger.GetColor("redbg")); } logger.Log(msg, logger.GetColor("yellow")); logger.Log("Node version: " + process.version);