Inital commit
This commit is contained in:
320
routes/api.route.ts
Normal file
320
routes/api.route.ts
Normal file
@ -0,0 +1,320 @@
|
||||
module.exports = function (app, enabMods, con, otherContext) {
|
||||
const wc = require('pp-which-country');
|
||||
const _ = require("underscore");
|
||||
const libs = require("../libs/metaHandler.lib");
|
||||
const jLib = require("../libs/jsonHand.lib");
|
||||
const stringify = require('safe-stable-stringify')
|
||||
const mailValidator = require("deep-email-validator")
|
||||
const tools = require("../functions");
|
||||
|
||||
// Returns all installed and non-limited modules
|
||||
app.get("/api/allModules", function (req, res) {
|
||||
res.setHeader("Content-Type", "application/json");
|
||||
|
||||
const allModules = [];
|
||||
// Loop though all modules and sort all interesting ones into `allModules`
|
||||
for (let i = 0; i < enabMods.length; i++) {
|
||||
if (enabMods[i].getModuleMeta().limited == false) {
|
||||
allModules.push(enabMods[i].getModuleMeta());
|
||||
}
|
||||
}
|
||||
// Return all modules
|
||||
res.send(allModules);
|
||||
});
|
||||
|
||||
// Returns all tags with usages amounts
|
||||
app.get("/api/allTags", function (req, res) {
|
||||
res.setHeader("Content-Type", "application/json");
|
||||
|
||||
|
||||
// Return all tags
|
||||
const allTags = otherContext.tags
|
||||
//allTags = allTags.sort(function(a,b) { return parseInt(a.z) - parseInt(b.z) } );
|
||||
const response = []
|
||||
for (const key in allTags) {
|
||||
if (allTags.hasOwnProperty(key)) {
|
||||
console.log(`${key}: ${allTags[key]}`);
|
||||
response.push({key: key, amount: allTags[key]})
|
||||
}
|
||||
}
|
||||
|
||||
res.send(response);
|
||||
});
|
||||
|
||||
// The report API endpoint
|
||||
app.get("/api/internal/report", function (req, res) {
|
||||
res.setHeader("Content-Type", "application/json");
|
||||
// First check if all needed parameters are set
|
||||
const point_id = req.query.point_id;
|
||||
const mail = req.query.mail;
|
||||
const reason = req.query.reason;
|
||||
if (!point_id || !mail || !reason) {
|
||||
res.send(JSON.stringify({
|
||||
"status": "error",
|
||||
"message": "Missing parameters"
|
||||
}));
|
||||
} else {
|
||||
// Check if the point_id is valid
|
||||
const splited = point_id.split("_");
|
||||
if (splited.length != 2) {
|
||||
res.send(JSON.stringify({
|
||||
"status": "error",
|
||||
"message": "Invalid point_id"
|
||||
}));
|
||||
} else {
|
||||
let isValid = false;
|
||||
for (let i = 0; i < enabMods.length; i++) {
|
||||
if (enabMods[i].getModuleMeta().exactName == splited[0] && enabMods[i].getModuleMeta().limited == false) {
|
||||
isValid = true;
|
||||
}
|
||||
}
|
||||
if (isValid) {
|
||||
// Check if the mail is valid
|
||||
const mailValidationRes = mailValidator.validate({ email: mail, validateSMTP: false, validateTypo: false });
|
||||
mailValidationRes.then(function (resp) {
|
||||
if (resp.valid) {
|
||||
const sqlQuery = "INSERT INTO `reports` (`point_id`, `mail`, `comment`) VALUES (?, ? , ?);";
|
||||
con.query(sqlQuery, [point_id, mail, reason], function (err, rows, fields) {
|
||||
tools.handleMysqlErrors(err, "API");
|
||||
res.send(JSON.stringify({
|
||||
"status": "success",
|
||||
"message": "Report sent"
|
||||
}));
|
||||
});
|
||||
|
||||
} else {
|
||||
res.send(JSON.stringify({
|
||||
"status": "error",
|
||||
"message": "Invalid mail",
|
||||
"cause": resp
|
||||
}));
|
||||
}
|
||||
})
|
||||
|
||||
} else {
|
||||
res.send(JSON.stringify({
|
||||
"status": "error",
|
||||
"message": "Invalid point_id"
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
app.get("/api/retrieve", function (req, res) {
|
||||
// Make sure all parameters are there
|
||||
if (
|
||||
req.query.uid != undefined
|
||||
) {
|
||||
// All parameters are there
|
||||
res.setHeader("Content-Type", "application/json");
|
||||
|
||||
const uid = req.query.uid;
|
||||
let result = undefined;
|
||||
console.warn("Retrieving data for UID: " + uid);
|
||||
// Go thorugh all modules and find the one which should handle the request
|
||||
for (let i = 0; i < enabMods.length; i++) {
|
||||
if (enabMods[i].getModuleMeta().exactName == uid.split("_")[0] && enabMods[i].getModuleMeta().limited == false) {
|
||||
|
||||
result = enabMods[i].queryItem(uid);
|
||||
console.warn("Found module: " + enabMods[i].getModuleMeta().exactName + " with result: " + result);
|
||||
}
|
||||
}
|
||||
// Because DBs are slow the module only returns a Promise and we have to wait for it
|
||||
Promise.all([result]).then(function (results) { res.send(results) });
|
||||
} else {
|
||||
// A parameter is missing
|
||||
res.status(400);
|
||||
res.setHeader("Content-Type", "application/json");
|
||||
res.send(JSON.stringify({ state: "Failed", message: "Missing arguments" }));
|
||||
}
|
||||
});
|
||||
|
||||
app.get("/api/getPOI", function (req, res) {
|
||||
// All parameters are there
|
||||
res.setHeader("Content-Type", "application/json");
|
||||
// Check if the bounds are valid so `lat;lng` is present
|
||||
// First check if the `;` is present and .split() returns an array with 2 elements
|
||||
const boundNorthEast = req.query.boundingEast.split(";");
|
||||
const boundSouthWest = req.query.boundingWest.split(";");
|
||||
let filterdModules = [];
|
||||
if (boundNorthEast.length == 2 && boundSouthWest.length == 2) {
|
||||
// Length is valid. Now check if the values are numbers and they are not infinte
|
||||
if (_.isFinite(boundNorthEast[0]) && _.isFinite(boundNorthEast[1]) && _.isFinite(boundSouthWest[0]) && _.isFinite(boundSouthWest[1])) {
|
||||
// Values are valid
|
||||
const boundNorthEastLat = parseFloat(boundNorthEast[0]);
|
||||
const boundNorthEastLng = parseFloat(boundNorthEast[1]);
|
||||
const boundNorthEastLatLng = { lat: boundNorthEastLat, lng: boundNorthEastLng };
|
||||
const boundSouthWestLat = parseFloat(boundSouthWest[0]);
|
||||
const boundSouthWestLng = parseFloat(boundSouthWest[1]);
|
||||
const boundSouthWestLatLng = { lat: boundSouthWestLat, lng: boundSouthWestLng };
|
||||
// Get the country of both edges
|
||||
// If the country is diffrent, set the country to *
|
||||
const countryNorthEast = wc([boundNorthEastLng, boundNorthEastLat]);
|
||||
let countrySouthWest = wc([boundSouthWestLng, boundSouthWestLat]);
|
||||
if (countryNorthEast != countrySouthWest) {
|
||||
// Country is the same
|
||||
countrySouthWest = "*";
|
||||
}
|
||||
|
||||
// Get all POIs in the given bounds
|
||||
const usefullMods = []
|
||||
for (let i = 0; i < enabMods.length; i++) {
|
||||
const meta = enabMods[i].getModuleMeta()
|
||||
// Is the country in the module's country list? Or is it "*"? Or did the system decide is doesnt matter
|
||||
if ((meta.country.indexOf(countrySouthWest) > -1 || meta.country[0] == "*" || countrySouthWest == "*") && meta.limited == false) {
|
||||
usefullMods.push(enabMods[i])
|
||||
}
|
||||
}
|
||||
|
||||
// JSON filter
|
||||
if (jLib.IsJsonString(req.query.filter)) {
|
||||
const jsonData = JSON.parse(req.query.filter);
|
||||
filterdModules = usefullMods.filter(function (elm) {
|
||||
// Loops through all elements in a list and lets you decide if weather to keep 'em or not
|
||||
let amount = 0;
|
||||
for (const fId in jsonData.filters) {
|
||||
// Do this is each provided filter
|
||||
const fi = jsonData.filters[fId]; // Gets the current filters name
|
||||
switch (fi[0]) {
|
||||
case "tag":
|
||||
if (jsonData.conjunction == "OR") {
|
||||
if (libs.returnTags(elm).includes(fi[1])) {
|
||||
return elm;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (libs.returnTags(elm).includes(fi[1])) {
|
||||
amount++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "country":
|
||||
if (jsonData.conjunction == "OR") {
|
||||
if (libs.returnCountries(elm).includes(fi[1])) {
|
||||
return elm;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (libs.returnCountries(elm).includes(fi[1])) {
|
||||
amount++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "source":
|
||||
if (jsonData.conjunction == "OR") {
|
||||
if (elm.getModuleMeta().exactName == fi[1]) {
|
||||
return elm;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (elm.getModuleMeta().exactName == fi[1]) {
|
||||
amount++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (jsonData.conjunction == "AND") {
|
||||
if (amount == jsonData.filters.length) {
|
||||
return elm;
|
||||
}
|
||||
}
|
||||
});
|
||||
} else { // No filtering
|
||||
filterdModules = enabMods;
|
||||
}
|
||||
|
||||
|
||||
// Create all promises
|
||||
const allProms = []; // A list for all promises
|
||||
for (let i = 0; i < filterdModules.length; i++) {
|
||||
const module = filterdModules[i];
|
||||
const temp = module.queryData(boundNorthEastLatLng, boundSouthWestLatLng, true); // Returns a promise of the results, because DBs are slowwwww
|
||||
allProms.push(temp); // Put the promises into a list
|
||||
}
|
||||
|
||||
// Wait for all promises and return them
|
||||
Promise.all(allProms).then(function (result) {
|
||||
const allResultsInOne = []
|
||||
for (let i = 0; i < result.length; i++) {
|
||||
for (let d = 0; d < result[i].length; d++) {
|
||||
allResultsInOne.push(result[i][d])
|
||||
}
|
||||
}
|
||||
res.send(stringify(allResultsInOne));
|
||||
}).catch(function (error) {
|
||||
console.error(error)
|
||||
res.status(500).send(error); // We should probably not do this in a PROD env but FIXME: Only in DEV env
|
||||
});
|
||||
} else {
|
||||
// Values are not valid
|
||||
res.status(400);
|
||||
res.send(JSON.stringify({ state: "Failed", message: "Bounding box is not valid" }));
|
||||
return (0);
|
||||
}
|
||||
} else {
|
||||
res.send(
|
||||
JSON.stringify({ state: "Failed", message: "Invalid arguments" })
|
||||
);
|
||||
res.status(400);
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
app.get("/api/getPOILocations", function (req, res) {
|
||||
// Make sure all parameters are there
|
||||
|
||||
// All parameters are there
|
||||
res.setHeader("Content-Type", "application/json");
|
||||
if (_.isFinite(req.query.lat) && _.isFinite(req.query.lng) && _.isFinite(req.query.radius)) {
|
||||
const lng = parseFloat(req.query.lng);
|
||||
const lat = parseFloat(req.query.lat);
|
||||
const radius = parseFloat(req.query.radius);
|
||||
|
||||
// Filter by usefull modules
|
||||
const country = wc([lng, lat]); // Find out which country is at this location
|
||||
const usefullMods = [];
|
||||
// Go through all modules and find all fiting ones
|
||||
for (let i = 0; i < enabMods.length; i++) {
|
||||
const meta = enabMods[i].getModuleMeta()
|
||||
if ((meta.country.indexOf(country) > -1 || meta.country[0] == "*") && meta.limited == false) {
|
||||
usefullMods.push(enabMods[i])
|
||||
}
|
||||
}
|
||||
|
||||
const allProms = [];
|
||||
for (let i = 0; i < usefullMods.length; i++) {
|
||||
const module = usefullMods[i]
|
||||
const temp = module.queryData(lat, lng, radius) // Returns a promise of the results
|
||||
allProms.push(temp)
|
||||
}
|
||||
|
||||
// Wait for all promises to be resolved
|
||||
Promise.all(allProms).then(function (result) {
|
||||
const allResultsInOne = []
|
||||
for (let i = 0; i < result.length; i++) {
|
||||
for (let d = 0; d < result[i].length; d++) {
|
||||
allResultsInOne.push(result[i][d])
|
||||
}
|
||||
}
|
||||
res.send(allResultsInOne);
|
||||
}).catch(function (error) {
|
||||
console.error(error)
|
||||
res.status(500).send(error); // TODO: again only do it in DEV envs
|
||||
});
|
||||
} else {
|
||||
res.send(
|
||||
JSON.stringify({ state: "Failed", message: "Invalid arguments" })
|
||||
);
|
||||
res.status(400);
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
58
routes/error.route.js
Normal file
58
routes/error.route.js
Normal file
@ -0,0 +1,58 @@
|
||||
module.exports = function (app, jsonConfigGlobal, metaGlobals) {
|
||||
const fs = require("fs");
|
||||
const Eta = require("eta");
|
||||
const util = require('util');
|
||||
|
||||
// Machine readable 404
|
||||
app.get("/api/*", function (req, res) {
|
||||
res.status(404);
|
||||
res.setHeader("Content-Type", "application/json");
|
||||
res.send(JSON.stringify({ state: "failed", message: "404-Unknown path" }));
|
||||
});
|
||||
|
||||
// Users 404
|
||||
app.get("*", function (req, res) {
|
||||
res.status(404);
|
||||
const data = fs.readFileSync("templates/error/404.eta", "utf8");
|
||||
let debugData;
|
||||
debugData = {
|
||||
code: 404,
|
||||
message: "Unknown path",
|
||||
"Original url": req.originalUrl,
|
||||
};
|
||||
if (jsonConfigGlobal.env != "DEV") {
|
||||
debugData = {};
|
||||
}
|
||||
res.send(
|
||||
Eta.render(data, {
|
||||
desc: metaGlobals.desc,
|
||||
siteTitel: metaGlobals.titlePrefx + "404",
|
||||
debug: debugData,
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
app.use(function (err, req, res, next) {
|
||||
console.error(err.stack)
|
||||
const data = fs.readFileSync("templates/error/serverError.eta", "utf8");
|
||||
debugData = {trace: err.stack, avail: true}
|
||||
if (jsonConfigGlobal.env != "DEV") {
|
||||
debugData = {avail: false};
|
||||
}
|
||||
res.status(500)
|
||||
res.send(
|
||||
Eta.render(data, {
|
||||
desc: metaGlobals.desc,
|
||||
siteTitel: metaGlobals.titlePrefx + "500",
|
||||
debug: debugData,
|
||||
debugText: String(debugData.trace).replaceAll("\n", "<br>")
|
||||
})
|
||||
);
|
||||
})
|
||||
app.use(function (err, req, res, next) {
|
||||
console.error(err.stack)
|
||||
res.status(500)
|
||||
res.send("Something went very wrong.")
|
||||
})
|
||||
};
|
36
routes/index.route.js
Normal file
36
routes/index.route.js
Normal file
@ -0,0 +1,36 @@
|
||||
module.exports = function (app, metaGlobals, fontawesomeKey, mapboxAccessToken, config) {
|
||||
const fs = require("fs");
|
||||
const Eta = require("eta");
|
||||
app.get("/", (req, res) => {
|
||||
const data = fs.readFileSync("templates/index.eta.html", "utf8");
|
||||
let indev = false;
|
||||
if(config.ENV == "dev"){
|
||||
indev = true
|
||||
}
|
||||
const errorPageContents = fs.readFileSync("templates/error/jserror.eta.html", "utf8").replace(new RegExp('\r?\n','g'), '<br />');
|
||||
res.send(
|
||||
Eta.render(data, {
|
||||
desc: metaGlobals.desc,
|
||||
siteTitel: metaGlobals.titlePrefx + "Map",
|
||||
fontawesomeKey: fontawesomeKey,
|
||||
mapboxAccessToken: mapboxAccessToken,
|
||||
hereKey: config.here,
|
||||
isInDev: indev,
|
||||
errorPageContent: errorPageContents,
|
||||
dsn: config.sentryDsn,
|
||||
})
|
||||
);
|
||||
|
||||
});
|
||||
|
||||
app.get("/about", (req, res) => {
|
||||
const data = fs.readFileSync("templates/credits.eta.html", "utf8");
|
||||
res.send(
|
||||
Eta.render(data, {
|
||||
desc: metaGlobals.desc,
|
||||
siteTitel: metaGlobals.titlePrefx + "About",
|
||||
fontawesomeKey: fontawesomeKey,
|
||||
})
|
||||
);
|
||||
});
|
||||
};
|
Reference in New Issue
Block a user