const express = require('express') const app = express(); const status = require('http-status'); const fetch = require('node-fetch'); const cors = require('cors'); const bodyParser = require('body-parser'); var mysql = require('mysql'); var passport = require('passport'); var LocalStrategy = require('passport-local').Strategy; var session = require('express-session'); var MySQLStore = require('express-mysql-session')(session); const bcrypt = require('bcrypt'); const path = require('path'); var connection = mysql.createPool({ connectionLimit: 25, host: 'localhost', user: 'simcompanies', password: '', database: 'simcompanies' }); var sessionStore = new MySQLStore({ clearExpired: false, schema: { tableName: 'sessions', columnNames: { session_id: 'session_id', expires: 'expires', data: 'data' } } }, connection); const mockDataDay = require('./mockdata-test/day.json'); var resourceList; const saltRounds = 13; var serverStartupComplete = false; async function loadData() { var rL = await fetch("https://www.simcompanies.com/api/v3/en/encyclopedia/resources/"); resourceList = await rL.json(); serverStartupComplete = true; console.log("SERVER STARTUP COMPLETED"); } loadData(); app.use(cors({ credentials: true })); app.use(bodyParser.urlencoded({ extended: true })); app.use(bodyParser.json()); app.use(session({ secret: "simCoRoxUFocker", saveUninitialized: true, resave: true, store: sessionStore, "cookie": { "maxAge": 86400 * 1000 } })); app.use(passport.initialize()); app.use(passport.session()); app.get("*", function (req, res, next) { if (!serverStartupComplete) return res.send("Server is starting..."); else return next(); }); app.use(express.static(path.join(__dirname, 'frontend'))); app.use(express.static(`${__dirname}/./frontend`)); app.all("/*", function (req, res, next) { if (/^\/simcompanies\/API\/.*/.test(req.url)) req.url = req.url.substring(13); if (!/^\/API\/.*/.test(req.url)) { return res.sendFile(path.join(__dirname, 'frontend', 'index.html')); } else return next(); }); passport.use('local-login', new LocalStrategy({ usernameField: "email", passwordField: "password", passReqToCallback: true }, function (req, email, password, done) { email = mysql.escape(email); connection.query(`SELECT * from user WHERE email = ${email} AND deactivated = 0`, function (err, rows) { if (err) { return res.status(static.INTERNAL_SERVER_ERROR).send(); } if (!rows.length) { return done(null, false); } if (!bcrypt.compareSync(password, rows[0].password)) { return done(null, false); } return done(null, rows[0]); }) } )); passport.serializeUser(function (user, done) { done(null, user.id); }); passport.deserializeUser(function (id, done) { connection.query(`select * from user where id = ${id} AND deactivated = 0`, function (err, rows) { done(err, rows[0]); }) }); app.post("/API/user/login", passport.authenticate('local-login'), function (req, res) { res.status(status.OK).send(); }); app.put("/API/user/create", function (req, res) { let { email, password } = req.body; if (email && password) { email = mysql.escape(email); password = mysql.escape(bcrypt.hashSync(password, saltRounds)); connection.query(`INSERT INTO user (deactivated, email, password) values (1, ${email}, ${password})`, function (err, rows) { if (err) return res.send(status.INTERNAL_SERVER_ERROR).send(); return res.status(status.OK).send(); }); } else { res.status(status.BAD_REQUEST).send(); } }); app.all("*", function (req, res, next) { if (req.isAuthenticated()) { return next(); } else { res.status(status.UNAUTHORIZED).send(); } }); app.get("/API/testlogin", function (req, res) { res.status(status.OK).send(req.user["email"]); }); app.get('/API/day', function (req, res) { var date = new Date(req.query.date); const kind = parseInt(req.query.kind); if (date instanceof Date && Number.isInteger(kind)) { //Mock Data: if (kind === -1) return res.send(mockDataDay); if (!isNaN(date.getTime()) && kind >= 1 && kind <= 113) { const daybegin = `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`; date.setDate(date.getDate() + 1); const dayend = `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`; const querystring = `SELECT time, price FROM market WHERE kind = ${kind} AND time > "${daybegin}" AND time < "${dayend}"` connection.query(querystring, function (error, results, fields) { if (error) { throw error; } res.send(results); }); } else res.status(status.BAD_REQUEST).send("invalid data provided"); } else res.status(status.BAD_REQUEST).send("invalid data provided"); }); app.get('/API/resourcelist', function (req, res) { res.send(resourceList); }); app.listen(3001);