// Imports const express = require("express"); const fs = require("fs"); const Eta = require("eta"); const winston = require("winston"); const mysql = require("mysql"); const bodyParser = require("body-parser"); const bcrypt = require("bcrypt"); const { verify } = require("hcaptcha"); const csp = require(`helmet`); const session = require("express-session"); const nodemailer = require("nodemailer"); const crypto = require("crypto"); // Inting the logger const logger = winston.createLogger({ level: "debug", format: winston.format.json(), defaultMeta: { service: "user-service" }, transports: [ // // - Write all logs with level `error` and below to `error.log` // - Write all logs with level `info` and below to `combined.log` // new winston.transports.File({ filename: "error.log", level: "error" }), new winston.transports.File({ filename: "combined.log" }), ], }); logger.add( new winston.transports.Console({ format: winston.format.simple(), }) ); const app = express(); app.use(express.static("static")); app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json()); /* app.use(csp.contentSecurityPolicy({ useDefaults: true, contentSecurityPolicy: false, crossOriginEmbedderPolicy: false, directives: { "default-src": [`'self'`], "img-src": [`'self'`], scriptSrc: [`'self'`, `https://hcaptcha.com`, `https://*.hcaptcha.com`, `https://*.fontawesome.com`, "unsafe-inline", "unsafe-eval","'unsafe-inline'"], "script-src-attr": [`'self'`, `https://hcaptcha.com`, `https://*.hcaptcha.com`, `https://*.fontawesome.com`, "unsafe-inline", "unsafe-eval"], "frame-src": [`'self'`, `https://hcaptcha.com`, `https://*.hcaptcha.com`], "style-src": [`'self'`, `https://hcaptcha.com`, `https://*.hcaptcha.com`, `https://*.fontawesome.com`, `'unsafe-inline'`], "connect-src": [`'self'`, `https://hcaptcha.com`, `https://*.hcaptcha.com`, `https://*.fontawesome.com`], "font-src": [`'self'`, `https://*.fontawesome.com`], }, })) */ // Settings const port = 3000; const startUpTime = Math.floor(new Date().getTime() / 1000); const saltRounds = 10; // Load config try { const data = fs.readFileSync("config/default.json", "utf8"); const jsonContent = JSON.parse(data); let jsonConfig = jsonContent; if (jsonContent.redirectConfig) { const data = fs.readFileSync( "config/" + jsonContent.redirectConfig, "utf8" ); jsonConfig = JSON.parse(data); } var fontawesomeKey = jsonConfig.fontAwesome; var mapboxAccessToken = jsonConfig.mapboxAccessToken; var mysqlData = jsonConfig.mysql; var hCaptcha = jsonConfig.hCaptcha; var mailConf = jsonConfig.mail; var serverAdress = jsonConfig.serverAdress; var cookieSecret = jsonConfig.cookieSecret || "saF0DSF65AS4DF0S4D6F0S54DF0Fad"; } catch (error) { logger.error( "While reading the config an error occured. The error was: " + error ); } var transport = nodemailer.createTransport({ host: mailConf.host, port: mailConf.port, requireTLS: true, secure: false, debug: true, disableFileAccess: true, //authMethod: "START TLS", auth: { user: mailConf.username, pass: mailConf.password, }, }); //let transporter = nodemailer.createTransport(transport) //console.log(transport.host) logger.info("Testing SMTP connection"); transport.verify(function (error, success) { if (error) { logger.error(error); } else { logger.info("SMPT server is ready to accept messages"); } }); app.use(session({ secret: cookieSecret })); // Basic defines for html const author = "TheGreydiamond"; const desc = "The Elevatormap. A map for elevator spotters!"; const sitePrefix = "Elevatormap - "; let mysqlIsUpAndOkay = false; let mySQLstate = 0; // 0 -> Default failure 1 -> Missing strucutre // Prepare MYSQL var con = mysql.createConnection({ host: "localhost", user: mysqlData.user, password: mysqlData.password, database: mysqlData.database, }); // sendVerificationMail(2); function sendVerificationMail(userId) { // Query for the mail const stmt = "SELECT * FROM mailverification WHERE id=" + userId; con.query(stmt, function (err, result, fields) { if (err) throw err; // TODO proper error handling if (result.length == 0) { logger.warn( "sendVerificationMail failed because ID " + userId + " doesnt exist!" ); } else { const emailContent = "Hi! \n You have created an account for the open elevator map. To finalize the process please verify your E-Mail adress. Use this link: http://" + serverAdress + "/verify/" + result[0].token; let info = transport.sendMail({ from: '"Elevator map " <' + mailConf.username + ">", // sender address to: result[0].targetMail, // list of receivers subject: "[Elevator map] Please verify your Mailadress", // Subject line text: emailContent, // plain text body html: emailContent.replace("\n", "
"), // html body }); } console.log(result); }); /* let info = await transporter.sendMail({ from: '"Elevator map " <' + mysqlData.username + '>', // sender address to: "bar@example.com, baz@example.com", // list of receivers subject: "Hello ✔", // Subject line text: "Hello world?", // plain text body html: "Hello world?", // html body });*/ } function checkIfMySQLStructureIsReady() { if (mysqlIsUpAndOkay) { // Only if MySQL is ready logger.debug("Checking MySQL strucutre"); con.query("SHOW TABLES;", function (err, result, fields) { if (err) throw err; if (result.length == 0) { // There are no tables. Not good. logger.warn("There are no tables found"); if (mysqlData.allowCreation) { // Lets create it then logger.warn("Creating a new table"); const sql = "CREATE TABLE `" + mysqlData.database + "`.`elevators` ( `id` INT NOT NULL AUTO_INCREMENT , `lat` FLOAT NOT NULL , `lng` FLOAT NOT NULL , `manufacturer` VARCHAR(512) NOT NULL , `modell` VARCHAR(512) NOT NULL , `info` VARCHAR(512) NOT NULL , `visitabilty` INT NOT NULL , `technology` INT NOT NULL , `images` JSON NOT NULL , `amountOfFloors` INT NOT NULL , `maxPassangers` INT NOT NULL , `maxWeight` INT NOT NULL , PRIMARY KEY (`id`)) ENGINE = InnoDB;"; const newSql = "CREATE TABLE `" + mysqlData.database + "`.`users` ( `id` INT NOT NULL AUTO_INCREMENT , `email` VARCHAR(255) NOT NULL , `username` VARCHAR(255) NOT NULL , `passwordHash` VARCHAR(512) NOT NULL , `permLevel` INT NOT NULL DEFAULT '0' , `verificationState` INT NOT NULL DEFAULT '0' , PRIMARY KEY (`id`), UNIQUE KEY (`email`)) ENGINE = InnoDB;"; const newSqlMailVeri = "CREATE TABLE `" + mysqlData.database + "`.`mailverification` ( `id` INT NOT NULL AUTO_INCREMENT , `targetMail` VARCHAR(512) NOT NULL , `userID` INT NOT NULL , `token` VARCHAR(255) NOT NULL , PRIMARY KEY (`id`)) ENGINE = InnoDB;"; con.query(sql, function (err, result) { if (err) throw err; logger.info("Table created"); }); con.query(newSql, function (err, result) { if (err) throw err; logger.info("Usertable created"); }); con.query(newSqlMailVeri, function (err, result) { if (err) throw err; logger.info("Email verification table created"); }); } else { // We cannot do that. Welp. logger.warn( "MySQL tables are missing and the config denies creation of new ones." ); mysqlIsUpAndOkay = false; mySQLstate = 1; } } }); } else { logger.warn("Tried checking the tables even though MySQL wasn't ready."); } } con.connect(function (err) { if (err) { mysqlIsUpAndOkay = false; logger.error("Connction to MySQL failed"); } else { logger.info("Mysql is ready."); mysqlIsUpAndOkay = true; checkIfMySQLStructureIsReady(); } }); // Routes app.get("/", function (req, res) { const data = fs.readFileSync("templates/index.html", "utf8"); res.send( Eta.render(data, { author: author, desc: desc, siteTitel: sitePrefix + "Start", fontawesomeKey: fontawesomeKey, }) ); }); app.post("/login", function (req, res) { const password = req.body.pass; const mail = req.body.email; var sess = req.session; console.log(req.body.pass); // Check if okay if ( mail != undefined && mail != "" && password != undefined && password != "" ) { const mailRegex = /(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/; if (mailRegex.test(mail)) { const stmt = "SELECT * FROM users WHERE email='" + mail + "';"; con.query(stmt, function (err, result, fields) { if (err) throw err; // TODO proper error page if (result.length == 0) { const data = fs.readFileSync("templates/login.html", "utf8"); res.send( Eta.render(data, { author: author, desc: desc, siteTitel: sitePrefix + "Ok", fontawesomeKey: fontawesomeKey, error: true, errorMessage: "This user does not exist!", }) ); } else { bcrypt.compare( password, result[0].passwordHash, function (error, response) { if (response) { // Login okay sess.username = result[0].username; sess.id = result[0].id; sess.mail = result[0].email; const data = fs.readFileSync("templates/redirect.html", "utf8"); res.send( Eta.render(data, { author: author, desc: desc, siteTitel: sitePrefix + "Ok", fontawesomeKey: fontawesomeKey, url: "/profile", }) ); } else { // Password falsch const data = fs.readFileSync("templates/login.html", "utf8"); res.send( Eta.render(data, { author: author, desc: desc, siteTitel: sitePrefix + "Ok", fontawesomeKey: fontawesomeKey, error: true, errorMessage: "The given password is wrong.", }) ); } } ); } }); } else { const data = fs.readFileSync("templates/login.html", "utf8"); res.send( Eta.render(data, { author: author, desc: desc, siteTitel: sitePrefix + "Ok", fontawesomeKey: fontawesomeKey, error: true, errorMessage: "The given E-Mail is invalid.", }) ); } } else { logger.warn( "The login form did not sent all data. Dump: \n Password: " + password + " \n E-Mail: " + mail ); const data = fs.readFileSync("templates/genericError.html", "utf8"); var displayText = "The form did not sent all the information needed."; res.send( Eta.render(data, { author: author, desc: desc, siteTitel: sitePrefix + "Error", fontawesomeKey: fontawesomeKey, displayText: displayText, }) ); } }); app.get("/login", function (req, res) { if (mysqlIsUpAndOkay) { const data = fs.readFileSync("templates/login.html", "utf8"); res.send( Eta.render(data, { author: author, desc: desc, siteTitel: sitePrefix + "Login", fontawesomeKey: fontawesomeKey, }) ); } else { const data = fs.readFileSync("templates/dbError.html", "utf8"); var displayText = "This might be an artifact of a recent restart. Maybe wait a few minutes and reload this page."; if (startUpTime + 60 <= Math.floor(new Date().getTime() / 1000)) { displayText = "The server failed to connect to the MySQL server. This means it was unable to load any data."; } if (mySQLstate == 1) { displayText = "There is a problem with the database servers setup. Please check the log for more info."; } res.send( Eta.render(data, { author: author, desc: desc, siteTitel: sitePrefix + "Error", fontawesomeKey: fontawesomeKey, displayText: displayText, }) ); } }); app.get("/profile", function (req, res) { if (mysqlIsUpAndOkay) { if (req.session.username != undefined) { var Hour = new Date().getHours(); var greeting = "Good night, "; if (Hour > 18) { greeting = "Good evening, " } else if (Hour > 13) { greeting = "Good afternoon, "; } else if (Hour > 5) { greeting = "Good morning, "; } greeting += req.session.username const hash = crypto.createHash('md5').update(req.session.mail.replace(" ", "").toLowerCase()).digest('hex'); gravatarURL = "https://www.gravatar.com/avatar/" + hash const data = fs.readFileSync("templates/profile.html", "utf8"); res.send( Eta.render(data, { author: author, desc: desc, siteTitel: sitePrefix + "Profile", fontawesomeKey: fontawesomeKey, greeting: greeting, gravatarURL: gravatarURL }) ); } else { const data = fs.readFileSync("templates/redirect.html", "utf8"); res.send( Eta.render(data, { author: author, desc: desc, siteTitel: sitePrefix + "Profile", fontawesomeKey: fontawesomeKey, url: "/login", }) ); } } else { const data = fs.readFileSync("templates/dbError.html", "utf8"); var displayText = "This might be an artifact of a recent restart. Maybe wait a few minutes and reload this page."; if (startUpTime + 60 <= Math.floor(new Date().getTime() / 1000)) { displayText = "The server failed to connect to the MySQL server. This means it was unable to load any data."; } if (mySQLstate == 1) { displayText = "There is a problem with the database servers setup. Please check the log for more info."; } res.send( Eta.render(data, { author: author, desc: desc, siteTitel: sitePrefix + "Error", fontawesomeKey: fontawesomeKey, displayText: displayText, }) ); } }); app.get("/register", function (req, res) { if (mysqlIsUpAndOkay) { const data = fs.readFileSync("templates/register.html", "utf8"); res.send( Eta.render(data, { author: author, desc: desc, siteTitel: sitePrefix + "Register", fontawesomeKey: fontawesomeKey, sitekey: hCaptcha.sitekey, }) ); } else { const data = fs.readFileSync("templates/dbError.html", "utf8"); var displayText = "This might be an artifact of a recent restart. Maybe wait a few minutes and reload this page."; if (startUpTime + 60 <= Math.floor(new Date().getTime() / 1000)) { displayText = "The server failed to connect to the MySQL server. This means it was unable to load any data."; } if (mySQLstate == 1) { displayText = "There is a problem with the database servers setup. Please check the log for more info."; } res.send( Eta.render(data, { author: author, desc: desc, siteTitel: sitePrefix + "Error", fontawesomeKey: fontawesomeKey, displayText: displayText, }) ); } }); app.post("/register", function (req, res) { if (mysqlIsUpAndOkay) { var sess = req.session; var resu; verify(hCaptcha.secret, req.body["g-recaptcha-response"]).then( (data) => (resu = data) ); /*.catch(setTimeout(() => { //if(resu.success == false){ console.log("HERE"); const data = fs.readFileSync("templates/genericError.html", "utf8"); resu = "-1"; con res.send( Eta.render(data, { author: author, desc: desc, siteTitel: sitePrefix + "Error", fontawesomeKey: fontawesomeKey, displayText: "There was an issue with the Captcha", }) ); //} }, 0) );*/ if (req.body.pass == req.body.pass2) { const mailRegex = /(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/; if (mailRegex.test(req.body.email)) { setTimeout(() => { console.log(resu); if (resu.success == true) { bcrypt.hash(req.body.pass, saltRounds, (err, hash) => { const data = fs.readFileSync( "templates/genericError.html", "utf8" ); // SQL INSERT var stmt = "INSERT INTO users(email, username, passwordHash) VALUES(?, ?, ?)"; var stmt2 = "INSERT INTO mailverification(targetMail, userID, token) VALUES(?, ?, ?)"; crypto.randomBytes(48, function (err, buffer) { var token = buffer.toString("hex"); con.query( stmt, [req.body.email, req.body.username, token], (err, results1, fields) => { if (err) { res.send( Eta.render(data, { author: author, desc: desc, siteTitel: sitePrefix + "Error", fontawesomeKey: fontawesomeKey, displayText: "An error occured while creating your account.", }) ); return console.error(err.message); } else { // Create mail verification con.query( stmt2, [req.body.email, results1.insertId, hash], (err, results, fields) => { if (err) { res.send( Eta.render(data, { author: author, desc: desc, siteTitel: sitePrefix + "Error", fontawesomeKey: fontawesomeKey, displayText: "An error occured while creating your account.", }) ); return console.error(err.message); } else { sess.username = req.body.username; sess.id = results1.insertId; sess.mail = req.body.email; // get inserted id logger.info("Inserted Id:" + results.insertId); res.send( Eta.render(data, { author: author, desc: desc, siteTitel: sitePrefix + "Error", fontawesomeKey: fontawesomeKey, displayText: "OK " + hash, }) ); sendVerificationMail(results.insertId); } } ); } } ); }); }); } else { const data = fs.readFileSync("templates/register.html", "utf8"); res.send( Eta.render(data, { author: author, desc: desc, siteTitel: sitePrefix + "Register", fontawesomeKey: fontawesomeKey, sitekey: hCaptcha.sitekey, error: true, errorMessage: "You failed the captcha, please try again.", }) ); } }, 200); } else { // Passwords don't match up const data = fs.readFileSync("templates/register.html", "utf8"); res.send( Eta.render(data, { author: author, desc: desc, siteTitel: sitePrefix + "Register", fontawesomeKey: fontawesomeKey, sitekey: hCaptcha.sitekey, error: true, errorMessage: "The E-Mail given is not valid", }) ); } } else { // Passwords don't match up const data = fs.readFileSync("templates/register.html", "utf8"); res.send( Eta.render(data, { author: author, desc: desc, siteTitel: sitePrefix + "Register", fontawesomeKey: fontawesomeKey, sitekey: hCaptcha.sitekey, error: true, errorMessage: "The password have to match up.", }) ); } } else { const data = fs.readFileSync("templates/dbError.html", "utf8"); var displayText = "This might be an artifact of a recent restart. Maybe wait a few minutes and reload this page."; if (startUpTime + 60 <= Math.floor(new Date().getTime() / 1000)) { displayText = "The server failed to connect to the MySQL server. This means it was unable to load any data."; } if (mySQLstate == 1) { displayText = "There is a problem with the database servers setup. Please check the log for more info."; } res.send( Eta.render(data, { author: author, desc: desc, siteTitel: sitePrefix + "Error", fontawesomeKey: fontawesomeKey, displayText: displayText, }) ); } }); // Routes app.get("/verify*", function (req, res) { console.log(req.url.split("/")[2]); const data = fs.readFileSync("templates/genericError.html", "utf8"); const stmt = "SELECT * FROM mailverification WHERE token = ?;"; con.query(stmt, [req.url.split("/")[2]], function (err, result, fields) { if (err) { res.status(404); res.send( JSON.stringify({ state: "Failed", message: "Database error occured" }) ); logger.error(err); } else { if (result.length == 0) { res.status(404); res.send( JSON.stringify({ state: "Failed", message: "Link already done" }) ); } else { console.log(result); res.status(200); stmt2 = "DELETE FROM mailverification WHERE id=?"; console.log(result[0].id); con.query(stmt2, [result[0].id], function (err, result, fields) { // TODO handling of this //logger.debug(err) //console.log(result) }); stmt3 = "UPDATE users SET verificationState=1 WHERE email=?"; con.query( stmt3, [result[0].targetMail], function (err, result, fields) { // TODO handling of this //logger.debug(err) //console.log(result) } ); res.send(JSON.stringify({ state: "OK", message: "Done!" })); } } }); }); app.get("/logout", function (req, res) { req.session.destroy(); const data = fs.readFileSync("templates/redirect.html", "utf8"); res.send( Eta.render(data, { author: author, desc: desc, siteTitel: sitePrefix + "Logout", fontawesomeKey: fontawesomeKey, url: "/", }) ); }); app.get("/debug/showSessionInfo", function (req, res) { res.send(JSON.stringify(req.session)); }); app.get("/map", function (req, res) { if (mysqlIsUpAndOkay) { const data = fs.readFileSync("templates/map.html", "utf8"); res.send( Eta.render(data, { author: author, desc: desc, siteTitel: sitePrefix + "Map", fontawesomeKey: fontawesomeKey, mapboxAccessToken: mapboxAccessToken, }) ); } else { const data = fs.readFileSync("templates/dbError.html", "utf8"); var displayText = "This might be an artifact of a recent restart. Maybe wait a few minutes and reload this page."; if (startUpTime + 60 <= Math.floor(new Date().getTime() / 1000)) { displayText = "The server failed to connect to the MySQL server. This means it was unable to load any data."; } if (mySQLstate == 1) { displayText = "There is a problem with the database servers setup. Please check the log for more info."; } res.send( Eta.render(data, { author: author, desc: desc, siteTitel: sitePrefix + "Error", fontawesomeKey: fontawesomeKey, displayText: displayText, }) ); } }); app.get("/api/getElevators", function (req, res) { console.log(req.query); if ( req.query.lan != undefined && req.query.lat != undefined && req.query.radius != undefined ) { // All parameters are there res.setHeader("Content-Type", "application/json"); try { var lan = parseFloat(req.query.lan); var lat = parseFloat(req.query.lat); var radius = parseFloat(req.query.radius); } catch (error) { res.send( JSON.stringify({ state: "Failed", message: "Invalid arguments" }) ); res.status(400); return; } var lan = parseFloat(req.query.lan); var lat = parseFloat(req.query.lat); var radius = parseFloat(req.query.radius); // TODO: Return just the elevators in the viewers area con.query("SELECT * FROM elevators", function (err, result, fields) { if (err) { res.status(500); res.send( JSON.stringify({ state: "Failed", message: "A server side error occured.", results: [], }) ); logger.error("The server failed to execute a request"); mysqlIsUpAndOkay = false; } else { console.log(result[0]); res.status(200); res.send(JSON.stringify({ state: "Ok", message: "", results: result })); } }); } else { // Welp something is missing res.status(400); res.setHeader("Content-Type", "application/json"); res.send(JSON.stringify({ state: "Failed", message: "Missing arguments" })); } }); app.get("/api/getElevatorLocation", function (req, res) { console.log(req.query); if ( req.query.lan != undefined && req.query.lat != undefined && req.query.radius != undefined ) { // All parameters are there res.setHeader("Content-Type", "application/json"); try { var lan = parseFloat(req.query.lan); var lat = parseFloat(req.query.lat); var radius = parseFloat(req.query.radius); } catch (error) { res.send( JSON.stringify({ state: "Failed", message: "Invalid arguments" }) ); res.status(400); return; } var lan = parseFloat(req.query.lan); var lat = parseFloat(req.query.lat); var radius = parseFloat(req.query.radius); // TODO: Return just the elevators in the viewers area con.query( "SELECT id, lat, lng FROM elevators", function (err, result, fields) { if (err) { res.status(500); res.send( JSON.stringify({ state: "Failed", message: "A server side error occured.", results: [], }) ); logger.error("The server failed to execute a request"); mysqlIsUpAndOkay = false; } else { console.log(result[0]); res.status(200); res.send( JSON.stringify({ state: "Ok", message: "", results: result }) ); } } ); } else { // Welp something is missing res.status(400); res.setHeader("Content-Type", "application/json"); res.send(JSON.stringify({ state: "Failed", message: "Missing arguments" })); } }); app.get("/api/getElevatorById", function (req, res) { console.log(req.query); if (req.query.id != undefined) { // All parameters are there res.setHeader("Content-Type", "application/json"); try { var id = parseFloat(req.query.id); } catch (error) { res.send( JSON.stringify({ state: "Failed", message: "Invalid arguments" }) ); res.status(400); return; } var id = parseFloat(req.query.id); con.query( "SELECT * FROM elevators WHERE id=" + id, function (err, result, fields) { if (err) { res.status(500); res.send( JSON.stringify({ state: "Failed", message: "A server side error occured.", results: [], }) ); logger.error("The server failed to execute a request"); console.log(err); mysqlIsUpAndOkay = false; } else { console.log(result[0]); res.status(200); res.send( JSON.stringify({ state: "Ok", message: "Successful.", results: result, }) ); } } ); } else { // Welp something is missing res.status(400); res.setHeader("Content-Type", "application/json"); res.send(JSON.stringify({ state: "Failed", message: "Missing arguments" })); } }); // Some loops for handeling stuff setInterval(() => { if (mysqlIsUpAndOkay == false) { logger.warn("Retrying to connect to MySQL"); con = mysql.createConnection({ host: "localhost", user: mysqlData.user, password: mysqlData.password, database: mysqlData.database, }); con.connect(function (err) { if (err) { mysqlIsUpAndOkay = false; logger.error("Connction to MySQL failed"); } else { logger.info("Mysql is ready."); mysqlIsUpAndOkay = true; } }); } }, 60000); // App start app.listen(port, () => { logger.info(`Elevator map ready at http://localhost:${port}`); });