mirror of
https://github.com/TheGreyDiamond/elevatormapRewritten.git
synced 2026-01-31 08:10:24 +01:00
Compare commits
19 Commits
dd346d5017
...
refactor
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
81b9d0b26f | ||
|
|
e33a58e5ab | ||
|
|
fe33f7f316 | ||
|
|
ec01e7128b | ||
|
|
7eb0558e96 | ||
|
|
5f8c998aaa | ||
|
|
d1aa2868d7 | ||
|
|
ee13ae9cb2 | ||
|
|
0dfd47e258 | ||
|
|
bc2a66236e | ||
|
|
7d5fdcef9b | ||
|
|
b2708329c1 | ||
|
|
51d92c139d | ||
|
|
b05241f493 | ||
|
|
5f7385a1b6 | ||
|
|
f99a1808b0 | ||
|
|
72aaa6a047 | ||
|
|
3cb4a71c9f | ||
|
|
37e718ec80 |
3
.eslintignore
Normal file
3
.eslintignore
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
*.js
|
||||||
17
.eslintrc.json
Normal file
17
.eslintrc.json
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"root": true,
|
||||||
|
"parser": "@typescript-eslint/parser",
|
||||||
|
"plugins": [
|
||||||
|
"@typescript-eslint"
|
||||||
|
],
|
||||||
|
"extends": [
|
||||||
|
"eslint:recommended",
|
||||||
|
"plugin:@typescript-eslint/eslint-recommended",
|
||||||
|
"plugin:@typescript-eslint/recommended"
|
||||||
|
],
|
||||||
|
"rules": {
|
||||||
|
"@typescript-eslint/no-var-requires": 0,
|
||||||
|
"no-control-regex": 0
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -80,7 +80,6 @@ typings/
|
|||||||
|
|
||||||
# Nuxt.js build / generate output
|
# Nuxt.js build / generate output
|
||||||
.nuxt
|
.nuxt
|
||||||
dist
|
|
||||||
|
|
||||||
# Gatsby files
|
# Gatsby files
|
||||||
.cache/
|
.cache/
|
||||||
@@ -104,3 +103,6 @@ dist
|
|||||||
.tern-port
|
.tern-port
|
||||||
|
|
||||||
testingDONOTCOMMITME.json
|
testingDONOTCOMMITME.json
|
||||||
|
|
||||||
|
static/uploads/*
|
||||||
|
index.js
|
||||||
|
|||||||
7
LICENSE
Normal file
7
LICENSE
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
Copyright © 2021 TheGreydiamond
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
@@ -1,9 +1,24 @@
|
|||||||
{
|
{
|
||||||
"fontAwesome": "",
|
"fontAwesome": "",
|
||||||
"mapboxAccessToken": "",
|
"mapboxAccessToken": "",
|
||||||
|
"cookieSecret": "",
|
||||||
|
"serverAdress": "",
|
||||||
|
"port": 3000,
|
||||||
"mysql": {
|
"mysql": {
|
||||||
"user": "",
|
"user": "",
|
||||||
"password": "",
|
"password": "",
|
||||||
|
"database": "",
|
||||||
"allowCreation": true
|
"allowCreation": true
|
||||||
|
},
|
||||||
|
"hCaptcha":{
|
||||||
|
"sitekey": "",
|
||||||
|
"secret": ""
|
||||||
|
},
|
||||||
|
"mail": {
|
||||||
|
"host": "",
|
||||||
|
"port": 0,
|
||||||
|
"username": "",
|
||||||
|
"password": ""
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
BIN
etc/elevatormapLogo.png
Normal file
BIN
etc/elevatormapLogo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 198 KiB |
BIN
etc/elevatormapLogo.xcf
Normal file
BIN
etc/elevatormapLogo.xcf
Normal file
Binary file not shown.
996
index.js
996
index.js
@@ -1,996 +0,0 @@
|
|||||||
// 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", "<br>"), // 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: "<b>Hello world?</b>", // 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");
|
|
||||||
console.log(err)
|
|
||||||
} 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("/createElevator", function (req, res) {
|
|
||||||
if (mysqlIsUpAndOkay) {
|
|
||||||
const data = fs.readFileSync("templates/createElevator.html", "utf8");
|
|
||||||
res.send(
|
|
||||||
Eta.render(data, {
|
|
||||||
author: author,
|
|
||||||
desc: desc,
|
|
||||||
siteTitel: sitePrefix + "New elevator",
|
|
||||||
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");
|
|
||||||
console.log(err)
|
|
||||||
} else {
|
|
||||||
logger.info("Mysql is ready.");
|
|
||||||
mysqlIsUpAndOkay = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, 60000);
|
|
||||||
|
|
||||||
// App start
|
|
||||||
app.listen(port, () => {
|
|
||||||
logger.info(`Elevator map ready at http://localhost:${port}`);
|
|
||||||
});
|
|
||||||
332
index.ts
Normal file
332
index.ts
Normal file
@@ -0,0 +1,332 @@
|
|||||||
|
// 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 session = require("express-session");
|
||||||
|
const nodemailer = require("nodemailer");
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
|
||||||
|
const startUpTime = Math.floor(new Date().getTime() / 1000);
|
||||||
|
|
||||||
|
// Skeleton Variables
|
||||||
|
let fontawesomeKey = "";
|
||||||
|
let mapboxAccessToken = "";
|
||||||
|
let mysqlData = { "user": "", "password": "", "database": "", "allowCreation": false };
|
||||||
|
let mailConf = { "host": "", "port": 0, "username": "", "password": "" };
|
||||||
|
let serverAdress = "";
|
||||||
|
let cookieSecret = ""
|
||||||
|
let jsonConfigGlobal = {};
|
||||||
|
let port = 3000;
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
fontawesomeKey = jsonConfig.fontAwesome;
|
||||||
|
mapboxAccessToken = jsonConfig.mapboxAccessToken;
|
||||||
|
mysqlData = jsonConfig.mysql;
|
||||||
|
|
||||||
|
mailConf = jsonConfig.mail;
|
||||||
|
serverAdress = jsonConfig.serverAdress;
|
||||||
|
port = jsonConfig.port;
|
||||||
|
cookieSecret =
|
||||||
|
jsonConfig.cookieSecret || "saF0DSF65AS4DF0S4D6F0S54DF0Fad";
|
||||||
|
jsonConfigGlobal = jsonConfig;
|
||||||
|
} catch (error) {
|
||||||
|
logger.error(
|
||||||
|
"While reading the config an error occured. The error was: " + error
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Express (server) preperation
|
||||||
|
app.use(express.static("static"));
|
||||||
|
|
||||||
|
app.use(bodyParser.urlencoded({ extended: false }));
|
||||||
|
app.use(bodyParser.json());
|
||||||
|
app.use(session({ secret: cookieSecret }));
|
||||||
|
app.use(function (req, res, next) {
|
||||||
|
// PreShow Errorpage handler
|
||||||
|
const pathesWhichRequireDB = ["map", "login", "register"];
|
||||||
|
const pathesWhichRequireLogin = ["createElevator"];
|
||||||
|
const path = req.path
|
||||||
|
const pathesDes = path.split("/")
|
||||||
|
let requiresDB = false;
|
||||||
|
let requiresLogin = false;
|
||||||
|
let allowContinue = true;
|
||||||
|
console.log(pathesDes)
|
||||||
|
|
||||||
|
if (pathesWhichRequireLogin.indexOf(pathesDes[1]) > -1) {
|
||||||
|
requiresLogin = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pathesDes[1] == "api") {
|
||||||
|
requiresDB = true;
|
||||||
|
}
|
||||||
|
if (pathesWhichRequireDB.indexOf(pathesDes[1]) > -1) {
|
||||||
|
requiresDB = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requiresDB) {
|
||||||
|
if (!mysqlIsUpAndOkay) {
|
||||||
|
allowContinue = false;
|
||||||
|
const data = fs.readFileSync("templates/dbError.html", "utf8");
|
||||||
|
let 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: metainfo.author,
|
||||||
|
desc: metainfo.desc,
|
||||||
|
siteTitel: metainfo.sitePrefix + "Error",
|
||||||
|
fontawesomeKey: fontawesomeKey,
|
||||||
|
displayText: displayText,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requiresLogin) {
|
||||||
|
if (req.session.username == undefined) {
|
||||||
|
allowContinue = false;
|
||||||
|
const data = fs.readFileSync("templates/redirect.html", "utf8");
|
||||||
|
res.send(
|
||||||
|
Eta.render(data, {
|
||||||
|
author: metainfo.author,
|
||||||
|
desc: metainfo.desc,
|
||||||
|
siteTitel: metainfo.sitePrefix + "Redirect",
|
||||||
|
fontawesomeKey: fontawesomeKey,
|
||||||
|
url: "/login?r=" + path,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Time:', Date.now())
|
||||||
|
if (allowContinue) {
|
||||||
|
next()
|
||||||
|
} else {
|
||||||
|
console.log("Stopped further exec of route")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// Mail preperation
|
||||||
|
const transport = nodemailer.createTransport({
|
||||||
|
host: mailConf.host,
|
||||||
|
port: mailConf.port,
|
||||||
|
requireTLS: true,
|
||||||
|
secure: false,
|
||||||
|
debug: true,
|
||||||
|
disableFileAccess: true,
|
||||||
|
auth: {
|
||||||
|
user: mailConf.username,
|
||||||
|
pass: mailConf.password,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
logger.info("Testing SMTP connection");
|
||||||
|
transport.verify(function (error) {
|
||||||
|
if (error) {
|
||||||
|
logger.error(error);
|
||||||
|
} else {
|
||||||
|
logger.info("SMPT server is ready to accept messages");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Basic defines for html
|
||||||
|
const metainfo = {
|
||||||
|
author: "TheGreydiamond",
|
||||||
|
desc: "The Elevatormap. A map for elevator spotters!",
|
||||||
|
sitePrefix: "Elevatormap - "
|
||||||
|
}
|
||||||
|
|
||||||
|
let mysqlIsUpAndOkay = false;
|
||||||
|
let mySQLstate = 0; // 0 -> Default failure 1 -> Missing strucutre
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Prepare MYSQL
|
||||||
|
let con = mysql.createConnection({
|
||||||
|
host: "localhost",
|
||||||
|
user: mysqlData.user,
|
||||||
|
password: mysqlData.password,
|
||||||
|
database: mysqlData.database,
|
||||||
|
});
|
||||||
|
|
||||||
|
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 , `creator` 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");
|
||||||
|
console.log(err);
|
||||||
|
} else {
|
||||||
|
logger.info("Mysql is ready.");
|
||||||
|
mysqlIsUpAndOkay = true;
|
||||||
|
checkIfMySQLStructureIsReady();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Routes
|
||||||
|
app.get("/", function (req, res) { // Index page
|
||||||
|
const data = fs.readFileSync("templates/index.html", "utf8");
|
||||||
|
res.send(
|
||||||
|
Eta.render(data, {
|
||||||
|
author: metainfo.author,
|
||||||
|
desc: metainfo.desc,
|
||||||
|
siteTitel: metainfo.sitePrefix + "Start",
|
||||||
|
fontawesomeKey: fontawesomeKey,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/map", function (req, res) { // Map page showing all elevators
|
||||||
|
const data = fs.readFileSync("templates/map.html", "utf8");
|
||||||
|
res.send(
|
||||||
|
Eta.render(data, {
|
||||||
|
author: metainfo.author,
|
||||||
|
desc: metainfo.desc,
|
||||||
|
siteTitel: metainfo.sitePrefix + "Map",
|
||||||
|
fontawesomeKey: fontawesomeKey,
|
||||||
|
mapboxAccessToken: mapboxAccessToken,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/createElevator", function (req, res) { // Page to create a new elvator
|
||||||
|
const data = fs.readFileSync("templates/createElevator.html", "utf8");
|
||||||
|
res.send(
|
||||||
|
Eta.render(data, {
|
||||||
|
author: metainfo.author,
|
||||||
|
desc: metainfo.desc,
|
||||||
|
siteTitel: metainfo.sitePrefix + "New elevator",
|
||||||
|
fontawesomeKey: fontawesomeKey,
|
||||||
|
mapboxAccessToken: mapboxAccessToken,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
require('./routes/api.route.ts')(app, con, mysqlIsUpAndOkay, logger, metainfo);
|
||||||
|
require('./routes/debug.route.ts')(app, con, logger, metainfo);
|
||||||
|
require('./routes/auth.route.ts')(app, con, logger, metainfo, jsonConfigGlobal);
|
||||||
|
|
||||||
|
// Some loops for handeling stuff,
|
||||||
|
setInterval(() => {
|
||||||
|
if (mysqlIsUpAndOkay == false) { // SQL reconnect
|
||||||
|
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");
|
||||||
|
console.log(err);
|
||||||
|
} else {
|
||||||
|
logger.info("Mysql is ready.");
|
||||||
|
mysqlIsUpAndOkay = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, 60*1000); // Every minute
|
||||||
|
|
||||||
|
// App start
|
||||||
|
app.listen(port, () => {
|
||||||
|
logger.info(`Elevator map ready at http://localhost:${port}`);
|
||||||
|
});
|
||||||
4884
package-lock.json
generated
4884
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
29
package.json
29
package.json
@@ -4,29 +4,44 @@
|
|||||||
"description": "The elevatormap rewritten",
|
"description": "The elevatormap rewritten",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: no test specified\" && exit 1",
|
"makeJS": "tsc index.ts",
|
||||||
"start": "node index.js"
|
"lint": "eslint . --ext .ts",
|
||||||
|
"makeJSwatch": "tsc -w index.ts",
|
||||||
|
"start": "tsc index.ts && node index.js",
|
||||||
|
"preChecks": "npm outdated && npm audit",
|
||||||
|
"startBeforeMerge": "eslint . --ext .ts && tsc index.ts && node index.js",
|
||||||
|
"nodemon": "nodemon index.js"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/TheGreyDiamond/elevatormapRewritten.git"
|
"url": "git+https://github.com/TheGreyDiamond/elevatormapRewritten.git"
|
||||||
},
|
},
|
||||||
"author": "TheGreydiamond",
|
"author": "TheGreydiamond",
|
||||||
"license": "ISC",
|
"license": "MIT",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/TheGreyDiamond/elevatormapRewritten/issues"
|
"url": "https://github.com/TheGreyDiamond/elevatormapRewritten/issues"
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/TheGreyDiamond/elevatormapRewritten#readme",
|
"homepage": "https://github.com/TheGreyDiamond/elevatormapRewritten",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bcrypt": "^5.0.1",
|
"bcrypt": "^5.0.1",
|
||||||
"body-parser": "^1.19.0",
|
"body-parser": "^1.19.0",
|
||||||
"eta": "^1.12.1",
|
"eta": "^1.12.3",
|
||||||
"express": "^4.17.1",
|
"express": "^4.17.1",
|
||||||
"express-session": "^1.17.2",
|
"express-session": "^1.17.2",
|
||||||
"hcaptcha": "0.0.2",
|
"greeting-time": "^1.0.0",
|
||||||
|
"hcaptcha": "0.1.0",
|
||||||
"helmet": "^4.6.0",
|
"helmet": "^4.6.0",
|
||||||
|
"multer": "^1.4.2",
|
||||||
"mysql": "^2.18.1",
|
"mysql": "^2.18.1",
|
||||||
"nodemailer": "^6.6.1",
|
"nodemailer": "^6.6.2",
|
||||||
"winston": "^3.3.3"
|
"winston": "^3.3.3"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "^16.0.0",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^4.33.0",
|
||||||
|
"@typescript-eslint/parser": "^4.33.0",
|
||||||
|
"eslint": "^7.32.0",
|
||||||
|
"eslint-config-strongloop": "^2.1.0",
|
||||||
|
"typescript": "^4.2.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
311
routes/api.route.ts
Normal file
311
routes/api.route.ts
Normal file
@@ -0,0 +1,311 @@
|
|||||||
|
module.exports = function (app, con, mysqlIsUpAndOkay, logger) {
|
||||||
|
const multer = require("multer");
|
||||||
|
const upload = multer({ dest: "static/uploads/" });
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
|
||||||
|
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 {
|
||||||
|
const id = parseFloat(req.query.id);
|
||||||
|
} catch (error) {
|
||||||
|
res.send(
|
||||||
|
JSON.stringify({ state: "Failed", message: "Invalid arguments" })
|
||||||
|
);
|
||||||
|
res.status(400);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const id = parseFloat(req.query.id);
|
||||||
|
|
||||||
|
con.query(
|
||||||
|
"SELECT * FROM elevators WHERE id=" + id,
|
||||||
|
function (err, result) {
|
||||||
|
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" }));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/api/resolveNameById", function (req, res) {
|
||||||
|
if (req.query.id != undefined && req.query.id != "") {
|
||||||
|
const sql = "SELECT username FROM users WHERE id=?";
|
||||||
|
con.query(sql, [req.query.id], function (err, result) {
|
||||||
|
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.setHeader("Content-Type", "application/json");
|
||||||
|
res.send(
|
||||||
|
JSON.stringify({ state: "Ok", message: "", results: result })
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
res.status(400);
|
||||||
|
res.setHeader("Content-Type", "application/json");
|
||||||
|
res.send(JSON.stringify({ state: "Failed", message: "Missing argument: id" }));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
app.get("/api/getElevatorLocation", function (req, res) {
|
||||||
|
if (
|
||||||
|
req.query.lan != undefined &&
|
||||||
|
req.query.lat != undefined &&
|
||||||
|
req.query.radius != undefined
|
||||||
|
) {
|
||||||
|
// All parameters are there
|
||||||
|
res.setHeader("Content-Type", "application/json");
|
||||||
|
try {
|
||||||
|
const lan = parseFloat(req.query.lan);
|
||||||
|
const lat = parseFloat(req.query.lat);
|
||||||
|
const radius = parseFloat(req.query.radius);
|
||||||
|
} catch (error) {
|
||||||
|
res.send(
|
||||||
|
JSON.stringify({ state: "Failed", message: "Invalid arguments" })
|
||||||
|
);
|
||||||
|
res.status(400);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const lan = parseFloat(req.query.lan);
|
||||||
|
const lat = parseFloat(req.query.lat);
|
||||||
|
const 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" }));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// returns an object with the cookies' name as keys
|
||||||
|
const getAppCookies = (req) => {
|
||||||
|
// We extract the raw cookies from the request headers
|
||||||
|
const rawCookies = req.headers.cookie.split("; ");
|
||||||
|
// rawCookies = ['myapp=secretcookie, 'analytics_cookie=beacon;']
|
||||||
|
|
||||||
|
const parsedCookies = {};
|
||||||
|
rawCookies.forEach((rawCookie) => {
|
||||||
|
const parsedCookie = rawCookie.split("=");
|
||||||
|
// parsedCookie = ['myapp', 'secretcookie'], ['analytics_cookie', 'beacon']
|
||||||
|
parsedCookies[parsedCookie[0]] = parsedCookie[1];
|
||||||
|
});
|
||||||
|
return parsedCookies;
|
||||||
|
};
|
||||||
|
|
||||||
|
app.post("/api/saveNewElevatorMeta", function (req, res) {
|
||||||
|
const sess = req.session;
|
||||||
|
const tempJs = JSON.parse(decodeURIComponent(getAppCookies(req)["tempStore"]));
|
||||||
|
const sql =
|
||||||
|
"INSERT INTO elevators (lat, lng, manufacturer, modell, info, visitabilty, technology, amountOfFloors, maxPassangers, maxWeight, images, creator) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, '{ \"images\": []}', ?)";
|
||||||
|
con.query(
|
||||||
|
sql,
|
||||||
|
[
|
||||||
|
tempJs.lat,
|
||||||
|
tempJs.lng,
|
||||||
|
tempJs.manuf,
|
||||||
|
tempJs.model,
|
||||||
|
tempJs.description,
|
||||||
|
tempJs.visit,
|
||||||
|
tempJs.type,
|
||||||
|
tempJs.flor,
|
||||||
|
tempJs.pepl,
|
||||||
|
tempJs.weig,
|
||||||
|
sess.uid
|
||||||
|
],
|
||||||
|
function (err, result) {
|
||||||
|
if (err) throw err;
|
||||||
|
console.log("1 record inserted with id " + result.insertId);
|
||||||
|
res.setHeader("Content-Type", "application/json");
|
||||||
|
|
||||||
|
res.send(
|
||||||
|
JSON.stringify({ state: "Okay", message: "Ok. No fault!", id: result.insertId })
|
||||||
|
);
|
||||||
|
res.status(200);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
app.post("/api/uploadImage", upload.any(), function (req, res) {
|
||||||
|
console.log(req.query.id)
|
||||||
|
let i = 0;
|
||||||
|
const sql = 'SELECT id, images FROM elevators WHERE id=?';
|
||||||
|
const allImages = []
|
||||||
|
while (i < req.files.length) {
|
||||||
|
const fObj = req.files[i];
|
||||||
|
const currentPath = path.join(fObj["path"]);
|
||||||
|
const destinationPath =
|
||||||
|
currentPath +
|
||||||
|
"." +
|
||||||
|
fObj["originalname"].split(".")[
|
||||||
|
fObj["originalname"].split(".").length - 1
|
||||||
|
]; // Add the file end
|
||||||
|
|
||||||
|
fs.rename(currentPath, destinationPath, function (err) {
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
} else {
|
||||||
|
console.log("Successfully moved the file!");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
allImages.push({ "path": destinationPath, "alt": "No alt was provided." })
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
con.query(
|
||||||
|
sql, [req.query.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");
|
||||||
|
mysqlIsUpAndOkay = false;
|
||||||
|
} else {
|
||||||
|
const jData = JSON.parse(result[0].images)
|
||||||
|
console.log(jData)
|
||||||
|
jData.images.push.spread(jData.images, allImages)
|
||||||
|
console.log(jData);
|
||||||
|
console.log(result);
|
||||||
|
const sql = "UPDATE elevators SET images = ? WHERE id = ?";
|
||||||
|
con.query(sql, [JSON.stringify(jData), req.query.id], function (err) {
|
||||||
|
if (err) {
|
||||||
|
console.log("Update failure")
|
||||||
|
} else {
|
||||||
|
console.log("Okay")
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Save Image End
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
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 {
|
||||||
|
const lan = parseFloat(req.query.lan);
|
||||||
|
const lat = parseFloat(req.query.lat);
|
||||||
|
const radius = parseFloat(req.query.radius);
|
||||||
|
} catch (error) {
|
||||||
|
res.send(
|
||||||
|
JSON.stringify({ state: "Failed", message: "Invalid arguments" })
|
||||||
|
);
|
||||||
|
res.status(400);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const lan = parseFloat(req.query.lan);
|
||||||
|
const lat = parseFloat(req.query.lat);
|
||||||
|
const radius = parseFloat(req.query.radius);
|
||||||
|
|
||||||
|
// TODO: Return just the elevators in the viewers area
|
||||||
|
|
||||||
|
con.query("SELECT * FROM elevators", function (err, result) {
|
||||||
|
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" }));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
443
routes/auth.route.ts
Normal file
443
routes/auth.route.ts
Normal file
@@ -0,0 +1,443 @@
|
|||||||
|
module.exports = function (app, con, logger, metainfo, jsonConfig) {
|
||||||
|
const greetingTime = require("greeting-time");
|
||||||
|
const fs = require("fs");
|
||||||
|
const Eta = require("eta");
|
||||||
|
const { verify } = require("hcaptcha");
|
||||||
|
const bcrypt = require("bcrypt");
|
||||||
|
const cryptoF = require("crypto");
|
||||||
|
const saltRounds = 10;
|
||||||
|
|
||||||
|
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])+)\])/;
|
||||||
|
|
||||||
|
app.get("/logout", function (req, res) {
|
||||||
|
req.session.destroy();
|
||||||
|
const data = fs.readFileSync("templates/redirect.html", "utf8");
|
||||||
|
res.send(
|
||||||
|
Eta.render(data, {
|
||||||
|
author: metainfo.author,
|
||||||
|
desc: metainfo.desc,
|
||||||
|
siteTitel: metainfo.sitePrefix + "Logout",
|
||||||
|
fontawesomeKey: jsonConfig.fontAwesome,
|
||||||
|
url: "/",
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
app.get("/verify*", function (req, res) {
|
||||||
|
console.log(req.url.split("/")[2]);
|
||||||
|
const stmt = "SELECT * FROM mailverification WHERE token = ?;";
|
||||||
|
|
||||||
|
con.query(stmt, [req.url.split("/")[2]], function (err, result) {
|
||||||
|
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);
|
||||||
|
const 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)
|
||||||
|
});
|
||||||
|
const 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.post("/register", function (req, res) {
|
||||||
|
const sess = req.session;
|
||||||
|
let resu;
|
||||||
|
verify(jsonConfig.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: metainfo.author,
|
||||||
|
desc: metainfo.desc,
|
||||||
|
siteTitel: metainfo.sitePrefix + "Error",
|
||||||
|
fontawesomeKey: jsonConfig.fontAwesome,
|
||||||
|
displayText: "There was an issue with the Captcha",
|
||||||
|
})
|
||||||
|
);
|
||||||
|
//}
|
||||||
|
|
||||||
|
}, 0)
|
||||||
|
);*/
|
||||||
|
|
||||||
|
if (req.body.pass == req.body.pass2) {
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
const stmt =
|
||||||
|
"INSERT INTO users(email, username, passwordHash) VALUES(?, ?, ?)";
|
||||||
|
const stmt2 =
|
||||||
|
"INSERT INTO mailverification(targetMail, userID, token) VALUES(?, ?, ?)";
|
||||||
|
cryptoF.randomBytes(48, function (err, buffer) {
|
||||||
|
const token = buffer.toString("hex");
|
||||||
|
con.query(
|
||||||
|
stmt,
|
||||||
|
[req.body.email, req.body.username, hash],
|
||||||
|
(err, results1) => {
|
||||||
|
if (err) {
|
||||||
|
res.send(
|
||||||
|
Eta.render(data, {
|
||||||
|
author: metainfo.author,
|
||||||
|
desc: metainfo.desc,
|
||||||
|
siteTitel: metainfo.sitePrefix + "Error",
|
||||||
|
fontawesomeKey: jsonConfig.fontAwesome,
|
||||||
|
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, token],
|
||||||
|
(err, results) => {
|
||||||
|
if (err) {
|
||||||
|
res.send(
|
||||||
|
Eta.render(data, {
|
||||||
|
author: metainfo.author,
|
||||||
|
desc: metainfo.desc,
|
||||||
|
siteTitel: metainfo.sitePrefix + "Error",
|
||||||
|
fontawesomeKey: jsonConfig.fontAwesome,
|
||||||
|
displayText:
|
||||||
|
"An error occured while creating your account.",
|
||||||
|
})
|
||||||
|
);
|
||||||
|
return console.error(err.message);
|
||||||
|
} else {
|
||||||
|
sess.username = req.body.username;
|
||||||
|
sess.uid = String(results1.insertId);
|
||||||
|
sess.mail = req.body.email;
|
||||||
|
// get inserted id
|
||||||
|
logger.info("Inserted Id:" + results.insertId);
|
||||||
|
res.send(
|
||||||
|
Eta.render(data, {
|
||||||
|
author: metainfo.author,
|
||||||
|
desc: metainfo.desc,
|
||||||
|
siteTitel: metainfo.sitePrefix + "Error",
|
||||||
|
fontawesomeKey: jsonConfig.fontAwesome,
|
||||||
|
displayText: "OK " + hash,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
sendVerificationMail(results.insertId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const data = fs.readFileSync("templates/register.html", "utf8");
|
||||||
|
res.send(
|
||||||
|
Eta.render(data, {
|
||||||
|
author: metainfo.author,
|
||||||
|
desc: metainfo.desc,
|
||||||
|
siteTitel: metainfo.sitePrefix + "Register",
|
||||||
|
fontawesomeKey: jsonConfig.fontAwesome,
|
||||||
|
sitekey: jsonConfig.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: metainfo.author,
|
||||||
|
desc: metainfo.desc,
|
||||||
|
siteTitel: metainfo.sitePrefix + "Register",
|
||||||
|
fontawesomeKey: jsonConfig.fontAwesome,
|
||||||
|
sitekey: jsonConfig.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: metainfo.author,
|
||||||
|
desc: metainfo.desc,
|
||||||
|
siteTitel: metainfo.sitePrefix + "Register",
|
||||||
|
fontawesomeKey: jsonConfig.fontAwesome,
|
||||||
|
sitekey: jsonConfig.hCaptcha.sitekey,
|
||||||
|
error: true,
|
||||||
|
errorMessage: "The password have to match up.",
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
app.get("/register", function (req, res) {
|
||||||
|
const data = fs.readFileSync("templates/register.html", "utf8");
|
||||||
|
res.send(
|
||||||
|
Eta.render(data, {
|
||||||
|
author: metainfo.author,
|
||||||
|
desc: metainfo.desc,
|
||||||
|
siteTitel: metainfo.sitePrefix + "Register",
|
||||||
|
fontawesomeKey: jsonConfig.fontAwesome,
|
||||||
|
sitekey: jsonConfig.hCaptcha.sitekey,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
app.get("/profile", function (req, res) {
|
||||||
|
if (req.session.username != undefined) {
|
||||||
|
let greeting = greetingTime(new Date());
|
||||||
|
greeting += " " + req.session.username;
|
||||||
|
const hash = cryptoF
|
||||||
|
.createHash("md5")
|
||||||
|
.update(req.session.mail.replace(" ", "").toLowerCase())
|
||||||
|
.digest("hex");
|
||||||
|
const gravatarURL = "https://www.gravatar.com/avatar/" + hash;
|
||||||
|
const data = fs.readFileSync("templates/profile.html", "utf8");
|
||||||
|
res.send(
|
||||||
|
Eta.render(data, {
|
||||||
|
author: metainfo.author,
|
||||||
|
desc: metainfo.desc,
|
||||||
|
siteTitel: metainfo.sitePrefix + "Profile",
|
||||||
|
fontawesomeKey: jsonConfig.fontAwesome,
|
||||||
|
greeting: greeting,
|
||||||
|
gravatarURL: gravatarURL,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const data = fs.readFileSync("templates/redirect.html", "utf8");
|
||||||
|
res.send(
|
||||||
|
Eta.render(data, {
|
||||||
|
author: metainfo.author,
|
||||||
|
desc: metainfo.desc,
|
||||||
|
siteTitel: metainfo.sitePrefix + "Profile",
|
||||||
|
fontawesomeKey: jsonConfig.fontAwesome,
|
||||||
|
url: "/login",
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/login", function (req, res) {
|
||||||
|
|
||||||
|
const data = fs.readFileSync("templates/login.html", "utf8");
|
||||||
|
res.send(
|
||||||
|
Eta.render(data, {
|
||||||
|
author: metainfo.author,
|
||||||
|
desc: metainfo.desc,
|
||||||
|
siteTitel: metainfo.sitePrefix + "Login",
|
||||||
|
fontawesomeKey: jsonConfig.fontAwesome,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
app.post("/login", function (req, res) {
|
||||||
|
const password = req.body.pass;
|
||||||
|
const mail = req.body.email;
|
||||||
|
const sess = req.session;
|
||||||
|
console.log(req.body.pass);
|
||||||
|
|
||||||
|
// Check if okay
|
||||||
|
if (
|
||||||
|
mail != undefined &&
|
||||||
|
mail != "" &&
|
||||||
|
password != undefined &&
|
||||||
|
password != ""
|
||||||
|
) {
|
||||||
|
if (mailRegex.test(mail)) {
|
||||||
|
const stmt = "SELECT * FROM users WHERE email=?;";
|
||||||
|
con.query(stmt, [mail], function (err, result) {
|
||||||
|
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: metainfo.author,
|
||||||
|
desc: metainfo.desc,
|
||||||
|
siteTitel: metainfo.sitePrefix + "Ok",
|
||||||
|
fontawesomeKey: jsonConfig.fontAwesome,
|
||||||
|
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.uid = String(result[0].id);
|
||||||
|
sess.mail = result[0].email;
|
||||||
|
|
||||||
|
const data = fs.readFileSync("templates/redirect.html", "utf8");
|
||||||
|
if (req.query.r != undefined && req.query.r != "") {
|
||||||
|
res.send(
|
||||||
|
Eta.render(data, {
|
||||||
|
author: metainfo.author,
|
||||||
|
desc: metainfo.desc,
|
||||||
|
siteTitel: metainfo.sitePrefix + "Ok",
|
||||||
|
fontawesomeKey: jsonConfig.fontAwesome,
|
||||||
|
url: req.query.r,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
res.send(
|
||||||
|
Eta.render(data, {
|
||||||
|
author: metainfo.author,
|
||||||
|
desc: metainfo.desc,
|
||||||
|
siteTitel: metainfo.sitePrefix + "Ok",
|
||||||
|
fontawesomeKey: jsonConfig.fontAwesome,
|
||||||
|
url: "/profile",
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Password falsch
|
||||||
|
const data = fs.readFileSync("templates/login.html", "utf8");
|
||||||
|
res.send(
|
||||||
|
Eta.render(data, {
|
||||||
|
author: metainfo.author,
|
||||||
|
desc: metainfo.desc,
|
||||||
|
siteTitel: metainfo.sitePrefix + "Ok",
|
||||||
|
fontawesomeKey: jsonConfig.fontAwesome,
|
||||||
|
error: true,
|
||||||
|
errorMessage: "The given password is wrong.",
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const data = fs.readFileSync("templates/login.html", "utf8");
|
||||||
|
res.send(
|
||||||
|
Eta.render(data, {
|
||||||
|
author: metainfo.author,
|
||||||
|
desc: metainfo.desc,
|
||||||
|
siteTitel: metainfo.sitePrefix + "Ok",
|
||||||
|
fontawesomeKey: jsonConfig.fontAwesome,
|
||||||
|
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");
|
||||||
|
const displayText = "The form did not sent all the information needed.";
|
||||||
|
res.send(
|
||||||
|
Eta.render(data, {
|
||||||
|
author: metainfo.author,
|
||||||
|
desc: metainfo.desc,
|
||||||
|
siteTitel: metainfo.sitePrefix + "Error",
|
||||||
|
fontawesomeKey: jsonConfig.fontAwesome,
|
||||||
|
displayText: displayText,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// sendVerificationMail(2);
|
||||||
|
function sendVerificationMail(userId) {
|
||||||
|
// Query for the mail
|
||||||
|
const stmt = "SELECT * FROM mailverification WHERE id=?";// + userId;
|
||||||
|
con.query(stmt, [userId], 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://" +
|
||||||
|
jsonConfig.serverAdress +
|
||||||
|
"/verify/" +
|
||||||
|
result[0].token;
|
||||||
|
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", "<br>"), // 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: "<b>Hello world?</b>", // html body
|
||||||
|
});*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
6
routes/debug.route.ts
Normal file
6
routes/debug.route.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
module.exports = function (app) {
|
||||||
|
app.get("/debug/showSessionInfo", function (req, res) {
|
||||||
|
res.send(JSON.stringify(req.session));
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
margin: 5px;
|
margin: 5px;
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
|
overflow-y: scroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
.map {
|
.map {
|
||||||
@@ -36,7 +37,6 @@ aside h2 {
|
|||||||
line-height: 1.05em;
|
line-height: 1.05em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.lds-ripple {
|
.lds-ripple {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
position: relative;
|
position: relative;
|
||||||
@@ -70,10 +70,6 @@ aside h2 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Slideshow container */
|
/* Slideshow container */
|
||||||
.slideshow-container {
|
.slideshow-container {
|
||||||
max-width: 1000px;
|
max-width: 1000px;
|
||||||
@@ -90,7 +86,8 @@ aside h2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Next & previous buttons */
|
/* Next & previous buttons */
|
||||||
.prev, .next {
|
.prev,
|
||||||
|
.next {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
/*position: absolute;*/
|
/*position: absolute;*/
|
||||||
margin: 20px;
|
margin: 20px;
|
||||||
@@ -110,11 +107,11 @@ aside h2 {
|
|||||||
.next {
|
.next {
|
||||||
right: 0;
|
right: 0;
|
||||||
border-radius: 3px 0 0 3px;
|
border-radius: 3px 0 0 3px;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* On hover, add a black background color with a little bit see-through */
|
/* On hover, add a black background color with a little bit see-through */
|
||||||
.prev:hover, .next:hover {
|
.prev:hover,
|
||||||
|
.next:hover {
|
||||||
background-color: #000;
|
background-color: #000;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,7 +147,8 @@ aside h2 {
|
|||||||
transition: background-color 0.6s ease;
|
transition: background-color 0.6s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.active, .dot:hover {
|
.active,
|
||||||
|
.dot:hover {
|
||||||
background-color: #717171;
|
background-color: #717171;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,13 +161,21 @@ aside h2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@-webkit-keyframes fade {
|
@-webkit-keyframes fade {
|
||||||
from {opacity: .4}
|
from {
|
||||||
to {opacity: 1}
|
opacity: 0.4;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes fade {
|
@keyframes fade {
|
||||||
from {opacity: .4}
|
from {
|
||||||
to {opacity: 1}
|
opacity: 0.4;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.elevatorPhoto {
|
.elevatorPhoto {
|
||||||
|
|||||||
BIN
static/images/elevatormapLogo.png
Normal file
BIN
static/images/elevatormapLogo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 198 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 867 B After Width: | Height: | Size: 9.2 KiB |
267
static/js/createElevator.js
Normal file
267
static/js/createElevator.js
Normal file
@@ -0,0 +1,267 @@
|
|||||||
|
|
||||||
|
var lockMap = false;
|
||||||
|
|
||||||
|
function noRestore() {
|
||||||
|
off();
|
||||||
|
Cookies.remove("tempStore")
|
||||||
|
}
|
||||||
|
|
||||||
|
function restoreFunc() {
|
||||||
|
try {
|
||||||
|
dataBlock = JSON.parse(dataBlock)
|
||||||
|
document.getElementById("lat").value = dataBlock["lat"]
|
||||||
|
document.getElementById("lng").value = dataBlock["lng"]
|
||||||
|
document.getElementById("type").value = dataBlock["type"]
|
||||||
|
document.getElementById("visit").value = dataBlock["visit"]
|
||||||
|
document.getElementById("pepl").value = dataBlock["pepl"]
|
||||||
|
document.getElementById("weig").value = dataBlock["weig"]
|
||||||
|
document.getElementById("manuf").value = dataBlock["manuf"]
|
||||||
|
document.getElementById("model").value = dataBlock["model"]
|
||||||
|
document.getElementById("flor").value = dataBlock["flor"]
|
||||||
|
document.getElementById("description").value = dataBlock["description"]
|
||||||
|
} catch (ex) {
|
||||||
|
dataBlock = {}
|
||||||
|
}
|
||||||
|
off()
|
||||||
|
}
|
||||||
|
|
||||||
|
dataBlock = Cookies.get("tempStore");
|
||||||
|
if (dataBlock == undefined) {
|
||||||
|
dataBlock = {};
|
||||||
|
} else {
|
||||||
|
on()
|
||||||
|
}
|
||||||
|
|
||||||
|
var currentPage = 0;
|
||||||
|
function saveValues() {
|
||||||
|
dataBlock["lat"] = document.getElementById("lat").value
|
||||||
|
dataBlock["lng"] = document.getElementById("lng").value
|
||||||
|
dataBlock["type"] = document.getElementById("type").value
|
||||||
|
dataBlock["visit"] = document.getElementById("visit").value
|
||||||
|
dataBlock["pepl"] = document.getElementById("pepl").value
|
||||||
|
dataBlock["weig"] = document.getElementById("weig").value
|
||||||
|
dataBlock["manuf"] = document.getElementById("manuf").value
|
||||||
|
dataBlock["model"] = document.getElementById("model").value
|
||||||
|
dataBlock["flor"] = document.getElementById("flor").value
|
||||||
|
dataBlock["description"] = document.getElementById("description").value
|
||||||
|
Cookies.set('tempStore', JSON.stringify(dataBlock))
|
||||||
|
}
|
||||||
|
|
||||||
|
function submit() {
|
||||||
|
currentPage = 6;
|
||||||
|
updateDialog()
|
||||||
|
saveValues()
|
||||||
|
const options = {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({})
|
||||||
|
};
|
||||||
|
|
||||||
|
fetch('/api/saveNewElevatorMeta', options)
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(response => {
|
||||||
|
console.warn("!!!!!!!!!!!!", response)
|
||||||
|
document.getElementById("imageUploadInfo").style.display = 'block';
|
||||||
|
var filesToSend = $('#myFile').prop('files').length;
|
||||||
|
var i = 0;
|
||||||
|
while (i < filesToSend) {
|
||||||
|
document.getElementById("imageUploadInfo").innerHTML = "Uploading image " + String(i) + "/" + String(filesToSend)
|
||||||
|
console.log("Files left to send: ", filesToSend - i)
|
||||||
|
var file_data = $('#myFile').prop('files')[i];
|
||||||
|
var form_data = new FormData();
|
||||||
|
form_data.append('file', file_data);
|
||||||
|
|
||||||
|
console.log(file_data)
|
||||||
|
if (String(file_data.type).includes("image/")) {
|
||||||
|
$.ajax({
|
||||||
|
url: '/api/uploadImage?id=' + response.id,
|
||||||
|
dataType: 'json',
|
||||||
|
cache: false,
|
||||||
|
contentType: false,
|
||||||
|
processData: false,
|
||||||
|
data: form_data,
|
||||||
|
type: 'post',
|
||||||
|
success: function (data) {
|
||||||
|
alert(data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.log("Skipping nonimage file")
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
console.log("DONE!")
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
function updateDialog() {
|
||||||
|
if (currentPage == 0) {
|
||||||
|
document.getElementById("step1").style.display = 'block';
|
||||||
|
document.getElementById("step2").style.display = 'none';
|
||||||
|
document.getElementById("step3").style.display = 'none';
|
||||||
|
document.getElementById("step4").style.display = 'none';
|
||||||
|
}
|
||||||
|
if (currentPage == 1) {
|
||||||
|
document.getElementById("step1").style.display = 'none';
|
||||||
|
document.getElementById("step2").style.display = 'block';
|
||||||
|
document.getElementById("step3").style.display = 'none';
|
||||||
|
document.getElementById("step4").style.display = 'none';
|
||||||
|
}
|
||||||
|
if (currentPage == 2) {
|
||||||
|
document.getElementById("step1").style.display = 'none';
|
||||||
|
document.getElementById("step2").style.display = 'none';
|
||||||
|
document.getElementById("step3").style.display = 'block';
|
||||||
|
document.getElementById("step4").style.display = 'none';
|
||||||
|
lockMap = false;
|
||||||
|
}
|
||||||
|
if (currentPage == 3) {
|
||||||
|
document.getElementById("step1").style.display = 'none';
|
||||||
|
document.getElementById("step2").style.display = 'none';
|
||||||
|
document.getElementById("step3").style.display = 'none';
|
||||||
|
document.getElementById("step4").style.display = 'block';
|
||||||
|
document.getElementById("step5").style.display = 'none';
|
||||||
|
document.getElementById("missingAlert").style.display = 'none';
|
||||||
|
lockMap = true;
|
||||||
|
}
|
||||||
|
if (currentPage == 4) {
|
||||||
|
document.getElementById("step1").style.display = 'none';
|
||||||
|
document.getElementById("step2").style.display = 'none';
|
||||||
|
document.getElementById("step3").style.display = 'none';
|
||||||
|
document.getElementById("step4").style.display = 'none';
|
||||||
|
|
||||||
|
containsEmpt = false;
|
||||||
|
for (const [key, value] of Object.entries(dataBlock)) {
|
||||||
|
if (value == "" || value == undefined) {
|
||||||
|
console.log("hi")
|
||||||
|
console.log(key, value)
|
||||||
|
containsEmpt = true;
|
||||||
|
document.getElementById("missingAlert").style.display = 'block';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (containsEmpt == false) {
|
||||||
|
document.getElementById("missingAlert").style.display = 'none';
|
||||||
|
currentPage = 5;
|
||||||
|
}
|
||||||
|
console.log(containsEmpt);
|
||||||
|
}
|
||||||
|
if (currentPage == 5) {
|
||||||
|
document.getElementById("step1").style.display = 'none';
|
||||||
|
document.getElementById("step2").style.display = 'none';
|
||||||
|
document.getElementById("step3").style.display = 'none';
|
||||||
|
document.getElementById("step4").style.display = 'none';
|
||||||
|
document.getElementById("step5").style.display = 'block';
|
||||||
|
document.getElementById("missingAlert").style.display = 'none';
|
||||||
|
}
|
||||||
|
if (currentPage == 6) {
|
||||||
|
document.getElementById("step1").style.display = 'none';
|
||||||
|
document.getElementById("step2").style.display = 'none';
|
||||||
|
document.getElementById("step3").style.display = 'none';
|
||||||
|
document.getElementById("step4").style.display = 'none';
|
||||||
|
document.getElementById("step5").style.display = 'none';
|
||||||
|
document.getElementById("step6").style.display = 'block';
|
||||||
|
document.getElementById("missingAlert").style.display = 'none';
|
||||||
|
}
|
||||||
|
saveValues();
|
||||||
|
console.log(dataBlock)
|
||||||
|
|
||||||
|
}
|
||||||
|
function nextDialogePage() {
|
||||||
|
currentPage++;
|
||||||
|
updateDialog();
|
||||||
|
}
|
||||||
|
function prevPage() {
|
||||||
|
currentPage--;
|
||||||
|
updateDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var latElm = document.getElementById("lat");
|
||||||
|
var lngElm = document.getElementById("lng");
|
||||||
|
|
||||||
|
latElm.addEventListener('input', function (evt) {
|
||||||
|
if(!lockMap){
|
||||||
|
markers.clearLayers();
|
||||||
|
console.log(evt.target.value)
|
||||||
|
const lat = evt.target.value;
|
||||||
|
const lng = lngElm.value;
|
||||||
|
var marker = new theMarker([lat, lng])
|
||||||
|
//marker.addTo(mymap)
|
||||||
|
markers.addLayer(marker);
|
||||||
|
markers.addTo(mymap);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
lngElm.addEventListener('input', function (evt) {
|
||||||
|
if(!lockMap){
|
||||||
|
markers.clearLayers();
|
||||||
|
console.log(evt.target.value)
|
||||||
|
const lat = latElm.value;
|
||||||
|
const lng = evt.target.value;
|
||||||
|
var marker = new theMarker([lat, lng])
|
||||||
|
//marker.addTo(mymap)
|
||||||
|
markers.addLayer(marker);
|
||||||
|
markers.addTo(mymap);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var amountOfImages = 0;
|
||||||
|
var markers = L.markerClusterGroup();
|
||||||
|
slideIndex = 1;
|
||||||
|
|
||||||
|
var mymap = L.map("map").setView([51.505, -0.09], 50);
|
||||||
|
|
||||||
|
theMarker = L.Marker.extend({
|
||||||
|
options: {
|
||||||
|
id: "-1",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
function showPosition(position) {
|
||||||
|
console.log(position.coords);
|
||||||
|
|
||||||
|
mymap.setView(
|
||||||
|
new L.LatLng(position.coords.latitude, position.coords.longitude),
|
||||||
|
10
|
||||||
|
);
|
||||||
|
// mymap.setView(new L.LatLng(10.737, -73.923), 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
home()
|
||||||
|
|
||||||
|
mymap.on('click', function (e) {
|
||||||
|
if(!lockMap){
|
||||||
|
markers.clearLayers();
|
||||||
|
var coord = e.latlng;
|
||||||
|
var lat = coord.lat;
|
||||||
|
var lng = coord.lng;
|
||||||
|
var marker = new theMarker([lat, lng])
|
||||||
|
//marker.addTo(mymap)
|
||||||
|
markers.addLayer(marker);
|
||||||
|
markers.addTo(mymap);
|
||||||
|
document.getElementById("lat").value = lat
|
||||||
|
document.getElementById("lng").value = lng
|
||||||
|
console.log("You clicked the map at latitude: " + lat + " and longitude: " + lng);
|
||||||
|
}else{
|
||||||
|
console.log("The map is locked.")
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function addPin(item, index) {
|
||||||
|
var marker = new theMarker([item.lat, item.lng], {
|
||||||
|
id: item.id,
|
||||||
|
}).on("click", onClick);
|
||||||
|
// var marker = new L.Marker()
|
||||||
|
//marker.addTo(mymap).on('click', onClick);
|
||||||
|
markers.on("clusterclick", function (a) {
|
||||||
|
//alert('cluster ' + a.layer.getAllChildMarkers().length);
|
||||||
|
});
|
||||||
|
markers.addLayer(marker);
|
||||||
|
}
|
||||||
|
|
||||||
192
static/js/map.js
Normal file
192
static/js/map.js
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
function createNewElev() {
|
||||||
|
window.location.href = "/createElevator";
|
||||||
|
}
|
||||||
|
|
||||||
|
var amountOfImages = 0;
|
||||||
|
var markers = L.markerClusterGroup();
|
||||||
|
slideIndex = 1;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
theMarker = L.Marker.extend({
|
||||||
|
options: {
|
||||||
|
id: "-1",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
function showPosition(position) {
|
||||||
|
console.log(position.coords);
|
||||||
|
|
||||||
|
mymap.setView(
|
||||||
|
new L.LatLng(position.coords.latitude, position.coords.longitude),
|
||||||
|
10
|
||||||
|
);
|
||||||
|
// mymap.setView(new L.LatLng(10.737, -73.923), 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onClick(e) {
|
||||||
|
slideIndex = 1;
|
||||||
|
document.getElementById("inspector").innerHTML =
|
||||||
|
'<br><br><center><div class="lds-ripple"><div></div><div></div></div></center>';
|
||||||
|
res = JSON.parse(httpGet("/api/getElevatorById?id=" + this.options.id));
|
||||||
|
if (res.state == "Ok") {
|
||||||
|
visitStates = [
|
||||||
|
"Test elevator",
|
||||||
|
"Public",
|
||||||
|
"On private property",
|
||||||
|
"Public but locked",
|
||||||
|
];
|
||||||
|
typeStates = [
|
||||||
|
"Hydraulic",
|
||||||
|
"Wiredriven, motor in shaft",
|
||||||
|
"Wiredriven, motor in motorroom",
|
||||||
|
];
|
||||||
|
|
||||||
|
// Prepare the template
|
||||||
|
inspector = httpGet("/templates/inspectorContent.html");
|
||||||
|
inspector = inspector.replace("#MODELL", res.results[0].modell);
|
||||||
|
inspector = inspector.replace("#MANUF", res.results[0].manufacturer);
|
||||||
|
inspector = inspector.replace("#DESC", res.results[0].info);
|
||||||
|
inspector = inspector.replace(
|
||||||
|
"#TYPE",
|
||||||
|
typeStates[res.results[0].technology]
|
||||||
|
);
|
||||||
|
inspector = inspector.replace("#MAXPASS", res.results[0].maxPassangers);
|
||||||
|
inspector = inspector.replace("#MASSWEIGH", res.results[0].maxWeight);
|
||||||
|
inspector = inspector.replace(
|
||||||
|
"#VISIT",
|
||||||
|
visitStates[res.results[0].visitabilty]
|
||||||
|
);
|
||||||
|
try {
|
||||||
|
var username = JSON.parse(
|
||||||
|
httpGet("/api/resolveNameById?id=" + res.results[0].creator)
|
||||||
|
).results[0].username;
|
||||||
|
} catch {
|
||||||
|
username = "Unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
inspector = inspector.replace("#CREATOR", username);
|
||||||
|
document.getElementById("inspector").innerHTML = inspector;
|
||||||
|
|
||||||
|
// Make gallery
|
||||||
|
document.getElementById("imageGallery").innerHTML =
|
||||||
|
"<div class='slideshow-container'>";
|
||||||
|
imgs = JSON.parse(res.results[0].images);
|
||||||
|
amountOfImages = imgs.images.length;
|
||||||
|
console.log(imgs);
|
||||||
|
var iH = 0;
|
||||||
|
|
||||||
|
while (amountOfImages > iH) {
|
||||||
|
newBox = "<center><div class='mySlides fade'><div class='numbertext'>";
|
||||||
|
newBox += iH + 1;
|
||||||
|
newBox += "/";
|
||||||
|
newBox += amountOfImages;
|
||||||
|
newBox += "</div><img src='";
|
||||||
|
newBox += imgs.images[iH].path;
|
||||||
|
newBox +=
|
||||||
|
"' alt='" +
|
||||||
|
imgs.images[iH].alt +
|
||||||
|
"' class=\"elevatorPhoto\"><div class='text'> </div></div></center>";
|
||||||
|
document.getElementById("imageGallery").innerHTML += newBox;
|
||||||
|
iH++;
|
||||||
|
}
|
||||||
|
document.getElementById("imageGallery").innerHTML +=
|
||||||
|
"<br><a class='prev' onclick='plusSlides(-1)''>❮</a><a class='next' onclick='plusSlides(1)'>❯</a></div><br><div style='text-align:center'></div><br><br><br>";
|
||||||
|
showSlides(1);
|
||||||
|
} else {
|
||||||
|
document.getElementById("inspector").innerHTML =
|
||||||
|
' \
|
||||||
|
<center> \
|
||||||
|
<h1><i style="color: red;" class="fas fa-exclamation-triangle"></i></h1> \
|
||||||
|
<h1>Oh no!</h1> \
|
||||||
|
The website failed to fetch the information about this elevator. It responded with the error code: \
|
||||||
|
<br><code> \
|
||||||
|
' +
|
||||||
|
res.message +
|
||||||
|
"</code><center>";
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
function httpGet(theUrl) {
|
||||||
|
var xmlHttp = new XMLHttpRequest();
|
||||||
|
xmlHttp.open("GET", theUrl, false); // false for synchronous request
|
||||||
|
xmlHttp.send(null);
|
||||||
|
return xmlHttp.responseText;
|
||||||
|
}
|
||||||
|
|
||||||
|
function home() {
|
||||||
|
if (navigator.geolocation) {
|
||||||
|
setTimeout(function () {
|
||||||
|
navigator.geolocation.getCurrentPosition(showPosition);
|
||||||
|
}, 200);
|
||||||
|
} else {
|
||||||
|
console.warn("Geolocation of user could not be fetched");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
home();
|
||||||
|
|
||||||
|
function addPin(item, index) {
|
||||||
|
var marker = new theMarker([item.lat, item.lng], {
|
||||||
|
id: item.id,
|
||||||
|
}).on("click", onClick);
|
||||||
|
// var marker = new L.Marker()
|
||||||
|
//marker.addTo(mymap).on('click', onClick);
|
||||||
|
markers.on("clusterclick", function (a) {
|
||||||
|
//alert('cluster ' + a.layer.getAllChildMarkers().length);
|
||||||
|
});
|
||||||
|
markers.addLayer(marker);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start getting the elevators
|
||||||
|
response = httpGet(
|
||||||
|
"/api/getElevatorLocation?lan=" +
|
||||||
|
mymap.getCenter.lng +
|
||||||
|
"&lat=" +
|
||||||
|
mymap.getCenter.lat +
|
||||||
|
"&radius=" +
|
||||||
|
mymap.getZoom()
|
||||||
|
);
|
||||||
|
response = JSON.parse(response);
|
||||||
|
|
||||||
|
if (response.state == "Ok") {
|
||||||
|
response.results.forEach(addPin);
|
||||||
|
mymap.addLayer(markers);
|
||||||
|
} else {
|
||||||
|
// DONT FORGET TO SHOW POPUP OR SOMETHING
|
||||||
|
console.log("Request failed with " + response.message);
|
||||||
|
console.log(response);
|
||||||
|
alert("Loading of the map pins failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next/previous controls
|
||||||
|
function plusSlides(n) {
|
||||||
|
showSlides((slideIndex += n));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Thumbnail image controls
|
||||||
|
function currentSlide(n) {
|
||||||
|
showSlides((slideIndex = n));
|
||||||
|
}
|
||||||
|
|
||||||
|
function showSlides(n) {
|
||||||
|
var i;
|
||||||
|
var slides = document.getElementsByClassName("mySlides");
|
||||||
|
var dots = document.getElementsByClassName("dot");
|
||||||
|
if (n > slides.length) {
|
||||||
|
slideIndex = 1;
|
||||||
|
}
|
||||||
|
if (n < 1) {
|
||||||
|
slideIndex = slides.length;
|
||||||
|
}
|
||||||
|
for (i = 0; i < slides.length; i++) {
|
||||||
|
slides[i].style.display = "none";
|
||||||
|
}
|
||||||
|
for (i = 0; i < dots.length; i++) {
|
||||||
|
dots[i].className = dots[i].className.replace(" active", "");
|
||||||
|
}
|
||||||
|
slides[slideIndex - 1].style.display = "block";
|
||||||
|
dots[slideIndex - 1].className += " active";
|
||||||
|
}
|
||||||
60
static/leafletCluster/dist/MarkerCluster.Default.css
vendored
Normal file
60
static/leafletCluster/dist/MarkerCluster.Default.css
vendored
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
.marker-cluster-small {
|
||||||
|
background-color: rgba(181, 226, 140, 0.6);
|
||||||
|
}
|
||||||
|
.marker-cluster-small div {
|
||||||
|
background-color: rgba(110, 204, 57, 0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.marker-cluster-medium {
|
||||||
|
background-color: rgba(241, 211, 87, 0.6);
|
||||||
|
}
|
||||||
|
.marker-cluster-medium div {
|
||||||
|
background-color: rgba(240, 194, 12, 0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.marker-cluster-large {
|
||||||
|
background-color: rgba(253, 156, 115, 0.6);
|
||||||
|
}
|
||||||
|
.marker-cluster-large div {
|
||||||
|
background-color: rgba(241, 128, 23, 0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* IE 6-8 fallback colors */
|
||||||
|
.leaflet-oldie .marker-cluster-small {
|
||||||
|
background-color: rgb(181, 226, 140);
|
||||||
|
}
|
||||||
|
.leaflet-oldie .marker-cluster-small div {
|
||||||
|
background-color: rgb(110, 204, 57);
|
||||||
|
}
|
||||||
|
|
||||||
|
.leaflet-oldie .marker-cluster-medium {
|
||||||
|
background-color: rgb(241, 211, 87);
|
||||||
|
}
|
||||||
|
.leaflet-oldie .marker-cluster-medium div {
|
||||||
|
background-color: rgb(240, 194, 12);
|
||||||
|
}
|
||||||
|
|
||||||
|
.leaflet-oldie .marker-cluster-large {
|
||||||
|
background-color: rgb(253, 156, 115);
|
||||||
|
}
|
||||||
|
.leaflet-oldie .marker-cluster-large div {
|
||||||
|
background-color: rgb(241, 128, 23);
|
||||||
|
}
|
||||||
|
|
||||||
|
.marker-cluster {
|
||||||
|
background-clip: padding-box;
|
||||||
|
border-radius: 20px;
|
||||||
|
}
|
||||||
|
.marker-cluster div {
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
margin-left: 5px;
|
||||||
|
margin-top: 5px;
|
||||||
|
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 15px;
|
||||||
|
font: 12px "Helvetica Neue", Arial, Helvetica, sans-serif;
|
||||||
|
}
|
||||||
|
.marker-cluster span {
|
||||||
|
line-height: 30px;
|
||||||
|
}
|
||||||
14
static/leafletCluster/dist/MarkerCluster.css
vendored
Normal file
14
static/leafletCluster/dist/MarkerCluster.css
vendored
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
.leaflet-cluster-anim .leaflet-marker-icon, .leaflet-cluster-anim .leaflet-marker-shadow {
|
||||||
|
-webkit-transition: -webkit-transform 0.3s ease-out, opacity 0.3s ease-in;
|
||||||
|
-moz-transition: -moz-transform 0.3s ease-out, opacity 0.3s ease-in;
|
||||||
|
-o-transition: -o-transform 0.3s ease-out, opacity 0.3s ease-in;
|
||||||
|
transition: transform 0.3s ease-out, opacity 0.3s ease-in;
|
||||||
|
}
|
||||||
|
|
||||||
|
.leaflet-cluster-spider-leg {
|
||||||
|
/* stroke-dashoffset (duration and function) should match with leaflet-marker-icon transform in order to track it exactly */
|
||||||
|
-webkit-transition: -webkit-stroke-dashoffset 0.3s ease-out, -webkit-stroke-opacity 0.3s ease-in;
|
||||||
|
-moz-transition: -moz-stroke-dashoffset 0.3s ease-out, -moz-stroke-opacity 0.3s ease-in;
|
||||||
|
-o-transition: -o-stroke-dashoffset 0.3s ease-out, -o-stroke-opacity 0.3s ease-in;
|
||||||
|
transition: stroke-dashoffset 0.3s ease-out, stroke-opacity 0.3s ease-in;
|
||||||
|
}
|
||||||
5
static/leafletCluster/dist/WhereAreTheJavascriptFiles.txt
vendored
Normal file
5
static/leafletCluster/dist/WhereAreTheJavascriptFiles.txt
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
We don't ship the .js files in the git master branch.
|
||||||
|
They are only present in version tags and in npm.
|
||||||
|
|
||||||
|
See how to get the JS files here: https://github.com/Leaflet/Leaflet.markercluster#using-the-plugin
|
||||||
|
Or how to build them: https://github.com/Leaflet/Leaflet.markercluster#building-testing-and-linting-scripts
|
||||||
2677
static/leafletCluster/dist/leaflet.markercluster-src.js
vendored
Normal file
2677
static/leafletCluster/dist/leaflet.markercluster-src.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
7
static/leafletCluster/dist/leaflet.markercluster.js
vendored
Normal file
7
static/leafletCluster/dist/leaflet.markercluster.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -12,5 +12,7 @@
|
|||||||
|
|
||||||
<b>Type:</b> #TYPE <br>
|
<b>Type:</b> #TYPE <br>
|
||||||
<b>Max. Passerngers:</b> #MAXPASS / #MASSWEIGH (kg) <br>
|
<b>Max. Passerngers:</b> #MAXPASS / #MASSWEIGH (kg) <br>
|
||||||
<b>Visitable:</b> #VISIT
|
<b>Visitable:</b> #VISIT <br>
|
||||||
|
|
||||||
|
<i>Created by: #CREATOR</i>
|
||||||
</center>
|
</center>
|
||||||
@@ -38,6 +38,8 @@
|
|||||||
integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA=="
|
integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA=="
|
||||||
crossorigin=""></script>
|
crossorigin=""></script>
|
||||||
|
|
||||||
|
<script src="vendor/jquery/jquery-3.2.1.min.js"></script>
|
||||||
|
|
||||||
<link rel="stylesheet" href="./leafletCluster/dist/MarkerCluster.css" />
|
<link rel="stylesheet" href="./leafletCluster/dist/MarkerCluster.css" />
|
||||||
<link rel="stylesheet" href="./leafletCluster/dist/MarkerCluster.Default.css" />
|
<link rel="stylesheet" href="./leafletCluster/dist/MarkerCluster.Default.css" />
|
||||||
|
|
||||||
@@ -50,8 +52,12 @@
|
|||||||
<body>
|
<body>
|
||||||
<!-- Primary Page Layout
|
<!-- Primary Page Layout
|
||||||
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
|
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
|
||||||
<div id="overlay" onclick="off()">
|
<div id="overlay">
|
||||||
<div id="text"><TODO>Add this dialoge</TODO></div>
|
<div id="text">
|
||||||
|
We've detected that there is a draft in your current session. Do you want to restore it?<br>
|
||||||
|
<button class="button-primary" onclick="restoreFunc()">Yes, restore it</button>
|
||||||
|
<button onclick="noRestore()">No, don't restore it</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style="margin: 0px">
|
<div style="margin: 0px">
|
||||||
<div class="map" id="map"></div>
|
<div class="map" id="map"></div>
|
||||||
@@ -91,6 +97,9 @@
|
|||||||
<input type="number" step="1" min="1" id="pepl" name="pepl" value=4>
|
<input type="number" step="1" min="1" id="pepl" name="pepl" value=4>
|
||||||
<label for="weig">Max. Weight (kg):</label>
|
<label for="weig">Max. Weight (kg):</label>
|
||||||
<input type="number" step="1" min="1" id="weig" name="weig" value=0>
|
<input type="number" step="1" min="1" id="weig" name="weig" value=0>
|
||||||
|
<label for="flor">Amount of Floors:</label>
|
||||||
|
<input type="number" step="1" min="1" id="flor" name="flor" value=0>
|
||||||
|
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
<button onclick="prevPage()">Go back one step <i class="fas fa-arrow-left"></i></button>
|
<button onclick="prevPage()">Go back one step <i class="fas fa-arrow-left"></i></button>
|
||||||
@@ -100,130 +109,60 @@
|
|||||||
<h5>3. Add a description</h5>
|
<h5>3. Add a description</h5>
|
||||||
<p>Add a description to the elevator. You may not use this field for advertisment.</p>
|
<p>Add a description to the elevator. You may not use this field for advertisment.</p>
|
||||||
<textarea id="description"></textarea>
|
<textarea id="description"></textarea>
|
||||||
|
<label for="manuf">Manufacturer: </label>
|
||||||
|
<input type="text" id="manuf" name="manuf">
|
||||||
|
<label for="model">Modell: </label>
|
||||||
|
<input type="text" id="model" name="model">
|
||||||
<br>
|
<br>
|
||||||
<button onclick="prevPage()">Go back one step <i class="fas fa-arrow-left"></i></button>
|
<button onclick="prevPage()">Go back one step <i class="fas fa-arrow-left"></i></button>
|
||||||
<button onclick="nextDialogePage()" class="button-primary">Next step <i class="fas fa-arrow-right"></i></button>
|
<button onclick="nextDialogePage()" class="button-primary">Next step <i class="fas fa-arrow-right"></i></button>
|
||||||
</step>
|
</step>
|
||||||
<step id="step4" style="display: none;">
|
<step id="step4" style="display: none;">
|
||||||
<h5>4. Add images</h5>
|
<h5>4. Add images</h5>
|
||||||
<p>This is the last step. You can now add images. <b>Make sure no personal information is visibel in the image.</b></p>
|
<p>This is the last step. You can now add images. <b>Make sure no personal information is visibel in the
|
||||||
<input type="file" id="myFile" name="files" multiple>
|
image.</b></p>
|
||||||
|
<input type="file" id="myFile" name="myFile" multiple>
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
<button onclick="prevPage()">Go back one step <i class="fas fa-arrow-left"></i></button>
|
<button onclick="prevPage()">Go back one step <i class="fas fa-arrow-left"></i></button>
|
||||||
<button onclick="nextDialogePage()" class="button-primary">Next step <i class="fas fa-arrow-right"></i></button>
|
<button onclick="nextDialogePage()" class="button-primary">Next step <i class="fas fa-arrow-right"></i></button>
|
||||||
</step>
|
</step>
|
||||||
|
<step class="missingAlert" id="missingAlert" style="display: none;">
|
||||||
|
<i class="fas fa-exclamation-triangle"></i> There are some empty fields. Please check the previous pages for
|
||||||
|
empty fields!<br>
|
||||||
|
<button onclick="prevPage()">Go back one step <i class="fas fa-arrow-left"></i></button>
|
||||||
|
</step>
|
||||||
|
<step id="step5" style="display: none;">
|
||||||
|
<h5>5. Ready</h5>
|
||||||
|
<p>Are you sure you want to submit this elevator?</p>
|
||||||
|
<button style="background-color: greenyellow;" onclick="submit()"><i class="fas fa-check"></i></button>
|
||||||
|
|
||||||
|
<button onclick="currentPage = 3; updateDialog()">Go back one step <i class="fas fa-arrow-left"></i></button>
|
||||||
|
</step>
|
||||||
|
<step id="step6" style="display: none;">
|
||||||
|
<h5>6. Saving</h5>
|
||||||
|
<br><br>
|
||||||
|
<center>
|
||||||
|
<div class="lds-ripple">
|
||||||
|
<div></div>
|
||||||
|
<div></div>
|
||||||
|
</div>
|
||||||
|
<div style="display: none; color: grey;" id="imageUploadInfo">
|
||||||
|
Uploading image -/-
|
||||||
|
</div>
|
||||||
|
</center>
|
||||||
|
</step>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<aside>
|
<aside>
|
||||||
<i style="color: black; cursor: pointer" class="fas fa-map-marker-alt" onclick="home()"></i>
|
<i style="color: black; cursor: pointer" class="fas fa-map-marker-alt" onclick="home()"></i>
|
||||||
</aside>
|
</aside>
|
||||||
<script type="text/javascript">
|
|
||||||
dataBlock = Cookies.get("tempStore");
|
|
||||||
if(dataBlock == undefined){
|
|
||||||
dataBlock = {};
|
|
||||||
}else{
|
|
||||||
try{
|
|
||||||
dataBlock = JSON.parse(dataBlock)
|
|
||||||
document.getElementById("lat").value = dataBlock["lat"]
|
|
||||||
document.getElementById("lng").value = dataBlock["lng"]
|
|
||||||
document.getElementById("type").value = dataBlock["type"]
|
|
||||||
document.getElementById("visit").value = dataBlock["visit"]
|
|
||||||
document.getElementById("pepl").value = dataBlock["pepl"]
|
|
||||||
document.getElementById("weig").value = dataBlock["weig"]
|
|
||||||
document.getElementById("description").value = dataBlock["description"]
|
|
||||||
on()
|
|
||||||
}catch(ex){
|
|
||||||
dataBlock = {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var currentPage = 0;
|
|
||||||
function saveValues(){
|
|
||||||
dataBlock["lat"] = document.getElementById("lat").value
|
|
||||||
dataBlock["lng"] = document.getElementById("lng").value
|
|
||||||
dataBlock["type"] = document.getElementById("type").value
|
|
||||||
dataBlock["visit"] = document.getElementById("visit").value
|
|
||||||
dataBlock["pepl"] = document.getElementById("pepl").value
|
|
||||||
dataBlock["weig"] = document.getElementById("weig").value
|
|
||||||
dataBlock["description"] = document.getElementById("description").value
|
|
||||||
Cookies.set('tempStore', JSON.stringify(dataBlock))
|
|
||||||
}
|
|
||||||
function updateDialog() {
|
|
||||||
if (currentPage == 0) {
|
|
||||||
document.getElementById("step1").style.display = 'block';
|
|
||||||
document.getElementById("step2").style.display = 'none';
|
|
||||||
document.getElementById("step3").style.display = 'none';
|
|
||||||
document.getElementById("step4").style.display = 'none';
|
|
||||||
}
|
|
||||||
if (currentPage == 1) {
|
|
||||||
document.getElementById("step1").style.display = 'none';
|
|
||||||
document.getElementById("step2").style.display = 'block';
|
|
||||||
document.getElementById("step3").style.display = 'none';
|
|
||||||
document.getElementById("step4").style.display = 'none';
|
|
||||||
}
|
|
||||||
if (currentPage == 2) {
|
|
||||||
document.getElementById("step1").style.display = 'none';
|
|
||||||
document.getElementById("step2").style.display = 'none';
|
|
||||||
document.getElementById("step3").style.display = 'block';
|
|
||||||
document.getElementById("step4").style.display = 'none';
|
|
||||||
}
|
|
||||||
if (currentPage == 3) {
|
|
||||||
document.getElementById("step1").style.display = 'none';
|
|
||||||
document.getElementById("step2").style.display = 'none';
|
|
||||||
document.getElementById("step3").style.display = 'none';
|
|
||||||
document.getElementById("step4").style.display = 'block';
|
|
||||||
}
|
|
||||||
saveValues();
|
|
||||||
console.log(dataBlock)
|
|
||||||
|
|
||||||
}
|
|
||||||
function nextDialogePage() {
|
|
||||||
currentPage++;
|
|
||||||
updateDialog();
|
|
||||||
}
|
|
||||||
function prevPage() {
|
|
||||||
currentPage--;
|
|
||||||
updateDialog();
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<!-- End Document
|
<!-- End Document
|
||||||
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
|
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
|
||||||
|
<script src="./js/createElevator.js"></script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
|
||||||
var latElm = document.getElementById("lat");
|
|
||||||
var lngElm = document.getElementById("lng");
|
|
||||||
|
|
||||||
latElm.addEventListener('input', function (evt) {
|
|
||||||
markers.clearLayers();
|
|
||||||
console.log(evt.target.value)
|
|
||||||
const lat = evt.target.value;
|
|
||||||
const lng = lngElm.value;
|
|
||||||
var marker = new theMarker([lat, lng])
|
|
||||||
//marker.addTo(mymap)
|
|
||||||
markers.addLayer(marker);
|
|
||||||
markers.addTo(mymap);
|
|
||||||
});
|
|
||||||
|
|
||||||
lngElm.addEventListener('input', function (evt) {
|
|
||||||
markers.clearLayers();
|
|
||||||
console.log(evt.target.value)
|
|
||||||
const lat = latElm.value;
|
|
||||||
const lng = evt.target.value;
|
|
||||||
var marker = new theMarker([lat, lng])
|
|
||||||
//marker.addTo(mymap)
|
|
||||||
markers.addLayer(marker);
|
|
||||||
markers.addTo(mymap);
|
|
||||||
});
|
|
||||||
|
|
||||||
var amountOfImages = 0;
|
|
||||||
var markers = L.markerClusterGroup();
|
|
||||||
slideIndex = 1;
|
|
||||||
|
|
||||||
var mymap = L.map("map").setView([51.505, -0.09], 50);
|
|
||||||
|
|
||||||
L.tileLayer(
|
L.tileLayer(
|
||||||
"https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=<%= it.mapboxAccessToken %>",
|
"https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=<%= it.mapboxAccessToken %>",
|
||||||
{
|
{
|
||||||
@@ -236,51 +175,6 @@
|
|||||||
accessToken: "<%= it.mapboxAccessToken %>",
|
accessToken: "<%= it.mapboxAccessToken %>",
|
||||||
}
|
}
|
||||||
).addTo(mymap);
|
).addTo(mymap);
|
||||||
|
|
||||||
theMarker = L.Marker.extend({
|
|
||||||
options: {
|
|
||||||
id: "-1",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
function showPosition(position) {
|
|
||||||
console.log(position.coords);
|
|
||||||
|
|
||||||
mymap.setView(
|
|
||||||
new L.LatLng(position.coords.latitude, position.coords.longitude),
|
|
||||||
10
|
|
||||||
);
|
|
||||||
// mymap.setView(new L.LatLng(10.737, -73.923), 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
home()
|
|
||||||
|
|
||||||
mymap.on('click', function (e) {
|
|
||||||
markers.clearLayers();
|
|
||||||
var coord = e.latlng;
|
|
||||||
var lat = coord.lat;
|
|
||||||
var lng = coord.lng;
|
|
||||||
var marker = new theMarker([lat, lng])
|
|
||||||
//marker.addTo(mymap)
|
|
||||||
markers.addLayer(marker);
|
|
||||||
markers.addTo(mymap);
|
|
||||||
document.getElementById("lat").value = lat
|
|
||||||
document.getElementById("lng").value = lng
|
|
||||||
console.log("You clicked the map at latitude: " + lat + " and longitude: " + lng);
|
|
||||||
});
|
|
||||||
|
|
||||||
function addPin(item, index) {
|
|
||||||
var marker = new theMarker([item.lat, item.lng], {
|
|
||||||
id: item.id,
|
|
||||||
}).on("click", onClick);
|
|
||||||
// var marker = new L.Marker()
|
|
||||||
//marker.addTo(mymap).on('click', onClick);
|
|
||||||
markers.on("clusterclick", function (a) {
|
|
||||||
//alert('cluster ' + a.layer.getAllChildMarkers().length);
|
|
||||||
});
|
|
||||||
markers.addLayer(marker);
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
|||||||
@@ -50,6 +50,7 @@
|
|||||||
<h5>
|
<h5>
|
||||||
Check it out now <br>
|
Check it out now <br>
|
||||||
<a href= "/map" ><button class="button-primary">Visit the map <i class="fas fa-arrow-right"></i> </button></a>
|
<a href= "/map" ><button class="button-primary">Visit the map <i class="fas fa-arrow-right"></i> </button></a>
|
||||||
|
<a href= "/createElevator" ><button class="button-primary">Create a new elevator <i class="fas fa-arrow-right"></i> </button></a>
|
||||||
</h5>
|
</h5>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -88,7 +88,7 @@
|
|||||||
Don’t have an account?
|
Don’t have an account?
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<a class="txt2" href="#">
|
<a class="txt2" href="/register">
|
||||||
Sign Up
|
Sign Up
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -72,15 +72,12 @@
|
|||||||
class="fas fa-map-marker-alt"
|
class="fas fa-map-marker-alt"
|
||||||
onclick="home()"
|
onclick="home()"
|
||||||
></i>
|
></i>
|
||||||
|
<i style="color: black; cursor: pointer" class="fas fas fa-plus" onclick="createNewElev()"></i>
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
<!-- End Document
|
<!-- End Document
|
||||||
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
|
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
|
||||||
<script type="text/javascript">
|
<script>
|
||||||
var amountOfImages = 0;
|
|
||||||
var markers = L.markerClusterGroup();
|
|
||||||
slideIndex = 1;
|
|
||||||
|
|
||||||
var mymap = L.map("map").setView([51.505, -0.09], 50);
|
var mymap = L.map("map").setView([51.505, -0.09], 50);
|
||||||
|
|
||||||
L.tileLayer(
|
L.tileLayer(
|
||||||
@@ -88,191 +85,14 @@
|
|||||||
{
|
{
|
||||||
attribution:
|
attribution:
|
||||||
'Map data © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
|
'Map data © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
|
||||||
maxZoom: 18,
|
maxZoom: 3,
|
||||||
id: "mapbox/streets-v11",
|
id: "mapbox/streets-v11",
|
||||||
tileSize: 512,
|
tileSize: 512,
|
||||||
zoomOffset: -1,
|
zoomOffset: -1,
|
||||||
accessToken: "<%= it.mapboxAccessToken %>",
|
accessToken: "<%= it.mapboxAccessToken %>",
|
||||||
}
|
}
|
||||||
).addTo(mymap);
|
).addTo(mymap);
|
||||||
|
|
||||||
theMarker = L.Marker.extend({
|
|
||||||
options: {
|
|
||||||
id: "-1",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
function showPosition(position) {
|
|
||||||
console.log(position.coords);
|
|
||||||
|
|
||||||
mymap.setView(
|
|
||||||
new L.LatLng(position.coords.latitude, position.coords.longitude),
|
|
||||||
10
|
|
||||||
);
|
|
||||||
// mymap.setView(new L.LatLng(10.737, -73.923), 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onClick(e) {
|
|
||||||
slideIndex = 1;
|
|
||||||
document.getElementById("inspector").innerHTML =
|
|
||||||
'<br><br><center><div class="lds-ripple"><div></div><div></div></div></center>';
|
|
||||||
res = JSON.parse(httpGet("/api/getElevatorById?id=" + this.options.id));
|
|
||||||
if (res.state == "Ok") {
|
|
||||||
visitStates = [
|
|
||||||
"Test elevator",
|
|
||||||
"Public",
|
|
||||||
"On private property",
|
|
||||||
"Public but locked",
|
|
||||||
];
|
|
||||||
typeStates = [
|
|
||||||
"Hydraulic",
|
|
||||||
"Wiredriven, motor in shaft",
|
|
||||||
"Wiredriven, motor in motorroom",
|
|
||||||
];
|
|
||||||
|
|
||||||
// Prepare the template
|
|
||||||
inspector = httpGet("/templates/inspectorContent.html");
|
|
||||||
inspector = inspector.replace("#MODELL", res.results[0].modell);
|
|
||||||
inspector = inspector.replace("#MANUF", res.results[0].manufacturer);
|
|
||||||
inspector = inspector.replace("#DESC", res.results[0].info);
|
|
||||||
inspector = inspector.replace(
|
|
||||||
"#TYPE",
|
|
||||||
typeStates[res.results[0].technology]
|
|
||||||
);
|
|
||||||
inspector = inspector.replace(
|
|
||||||
"#MAXPASS",
|
|
||||||
res.results[0].maxPassangers
|
|
||||||
);
|
|
||||||
inspector = inspector.replace("#MASSWEIGH", res.results[0].maxWeight);
|
|
||||||
inspector = inspector.replace(
|
|
||||||
"#VISIT",
|
|
||||||
visitStates[res.results[0].visitabilty]
|
|
||||||
);
|
|
||||||
document.getElementById("inspector").innerHTML = inspector;
|
|
||||||
|
|
||||||
// Make gallery
|
|
||||||
document.getElementById("imageGallery").innerHTML =
|
|
||||||
"<div class='slideshow-container'>";
|
|
||||||
imgs = JSON.parse(res.results[0].images);
|
|
||||||
amountOfImages = imgs.images.length;
|
|
||||||
console.log(imgs);
|
|
||||||
var iH = 0;
|
|
||||||
|
|
||||||
while (amountOfImages > iH) {
|
|
||||||
newBox =
|
|
||||||
"<center><div class='mySlides fade'><div class='numbertext'>";
|
|
||||||
newBox += iH + 1;
|
|
||||||
newBox += "/";
|
|
||||||
newBox += amountOfImages;
|
|
||||||
newBox += "</div><img src='";
|
|
||||||
newBox += imgs.images[iH].path;
|
|
||||||
newBox +=
|
|
||||||
"' alt='" +
|
|
||||||
imgs.images[iH].alt +
|
|
||||||
"' class=\"elevatorPhoto\"><div class='text'> </div></div></center>";
|
|
||||||
document.getElementById("imageGallery").innerHTML += newBox;
|
|
||||||
iH++;
|
|
||||||
}
|
|
||||||
document.getElementById("imageGallery").innerHTML +=
|
|
||||||
"<br><a class='prev' onclick='plusSlides(-1)''>❮</a><a class='next' onclick='plusSlides(1)'>❯</a></div><br><div style='text-align:center'></div><br><br><br>";
|
|
||||||
showSlides(1);
|
|
||||||
} else {
|
|
||||||
document.getElementById("inspector").innerHTML =
|
|
||||||
' \
|
|
||||||
<center> \
|
|
||||||
<h1><i style="color: red;" class="fas fa-exclamation-triangle"></i></h1> \
|
|
||||||
<h1>Oh no!</h1> \
|
|
||||||
The website failed to fetch the information about this elevator. It responded with the error code: \
|
|
||||||
<br><code> \
|
|
||||||
' +
|
|
||||||
res.message +
|
|
||||||
"</code><center>";
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(res);
|
|
||||||
}
|
|
||||||
|
|
||||||
function httpGet(theUrl) {
|
|
||||||
var xmlHttp = new XMLHttpRequest();
|
|
||||||
xmlHttp.open("GET", theUrl, false); // false for synchronous request
|
|
||||||
xmlHttp.send(null);
|
|
||||||
return xmlHttp.responseText;
|
|
||||||
}
|
|
||||||
|
|
||||||
function home() {
|
|
||||||
if (navigator.geolocation) {
|
|
||||||
setTimeout(function () {
|
|
||||||
navigator.geolocation.getCurrentPosition(showPosition);
|
|
||||||
}, 200);
|
|
||||||
} else {
|
|
||||||
console.warn("Geolocation of user could not be fetched");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
home();
|
|
||||||
|
|
||||||
function addPin(item, index) {
|
|
||||||
var marker = new theMarker([item.lat, item.lng], {
|
|
||||||
id: item.id,
|
|
||||||
}).on("click", onClick);
|
|
||||||
// var marker = new L.Marker()
|
|
||||||
//marker.addTo(mymap).on('click', onClick);
|
|
||||||
markers.on("clusterclick", function (a) {
|
|
||||||
//alert('cluster ' + a.layer.getAllChildMarkers().length);
|
|
||||||
});
|
|
||||||
markers.addLayer(marker);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start getting the elevators
|
|
||||||
response = httpGet(
|
|
||||||
"/api/getElevatorLocation?lan=" +
|
|
||||||
mymap.getCenter.lng +
|
|
||||||
"&lat=" +
|
|
||||||
mymap.getCenter.lat +
|
|
||||||
"&radius=" +
|
|
||||||
mymap.getZoom()
|
|
||||||
);
|
|
||||||
response = JSON.parse(response);
|
|
||||||
|
|
||||||
if (response.state == "Ok") {
|
|
||||||
response.results.forEach(addPin);
|
|
||||||
mymap.addLayer(markers);
|
|
||||||
} else {
|
|
||||||
// DONT FORGET TO SHOW POPUP OR SOMETHING
|
|
||||||
console.log("Request failed with " + response.message);
|
|
||||||
console.log(response);
|
|
||||||
alert("Loading of the map pins failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Next/previous controls
|
|
||||||
function plusSlides(n) {
|
|
||||||
showSlides((slideIndex += n));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Thumbnail image controls
|
|
||||||
function currentSlide(n) {
|
|
||||||
showSlides((slideIndex = n));
|
|
||||||
}
|
|
||||||
|
|
||||||
function showSlides(n) {
|
|
||||||
var i;
|
|
||||||
var slides = document.getElementsByClassName("mySlides");
|
|
||||||
var dots = document.getElementsByClassName("dot");
|
|
||||||
if (n > slides.length) {
|
|
||||||
slideIndex = 1;
|
|
||||||
}
|
|
||||||
if (n < 1) {
|
|
||||||
slideIndex = slides.length;
|
|
||||||
}
|
|
||||||
for (i = 0; i < slides.length; i++) {
|
|
||||||
slides[i].style.display = "none";
|
|
||||||
}
|
|
||||||
for (i = 0; i < dots.length; i++) {
|
|
||||||
dots[i].className = dots[i].className.replace(" active", "");
|
|
||||||
}
|
|
||||||
slides[slideIndex - 1].style.display = "block";
|
|
||||||
dots[slideIndex - 1].className += " active";
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
<script src="./js/map.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user