Created examples of logging
This commit is contained in:
Generated
+148
-6
@@ -294,6 +294,14 @@
|
||||
"integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
|
||||
"dev": true
|
||||
},
|
||||
"async": {
|
||||
"version": "2.6.1",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz",
|
||||
"integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==",
|
||||
"requires": {
|
||||
"lodash": "4.17.10"
|
||||
}
|
||||
},
|
||||
"async-each": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz",
|
||||
@@ -1463,6 +1471,22 @@
|
||||
"object-visit": "1.0.1"
|
||||
}
|
||||
},
|
||||
"color": {
|
||||
"version": "0.8.0",
|
||||
"resolved": "https://registry.npmjs.org/color/-/color-0.8.0.tgz",
|
||||
"integrity": "sha1-iQwHw/1OZJU3Y4kRz2keVFi2/KU=",
|
||||
"requires": {
|
||||
"color-convert": "0.5.3",
|
||||
"color-string": "0.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"color-convert": {
|
||||
"version": "0.5.3",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-0.5.3.tgz",
|
||||
"integrity": "sha1-vbbGnOZg+t/+CwAHzER+G59ygr0="
|
||||
}
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "1.9.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz",
|
||||
@@ -1475,8 +1499,20 @@
|
||||
"color-name": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
|
||||
"dev": true
|
||||
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
|
||||
},
|
||||
"color-string": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/color-string/-/color-string-0.3.0.tgz",
|
||||
"integrity": "sha1-J9RvtnAlxcL6JZk7+/V55HhBuZE=",
|
||||
"requires": {
|
||||
"color-name": "1.1.3"
|
||||
}
|
||||
},
|
||||
"colornames": {
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/colornames/-/colornames-0.0.2.tgz",
|
||||
"integrity": "sha1-2BH9bIT1kClJmorEQ2ICk1uSvjE="
|
||||
},
|
||||
"colors": {
|
||||
"version": "0.6.2",
|
||||
@@ -1484,6 +1520,15 @@
|
||||
"integrity": "sha1-JCP+ZnisDF2uiFLl0OW+CMmXq8w=",
|
||||
"dev": true
|
||||
},
|
||||
"colorspace": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.0.1.tgz",
|
||||
"integrity": "sha1-yZx5btMRKLmHalLh7l7gOkpxl0k=",
|
||||
"requires": {
|
||||
"color": "0.8.0",
|
||||
"text-hex": "0.0.0"
|
||||
}
|
||||
},
|
||||
"component-emitter": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
|
||||
@@ -1752,6 +1797,16 @@
|
||||
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
|
||||
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
|
||||
},
|
||||
"diagnostics": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/diagnostics/-/diagnostics-1.1.0.tgz",
|
||||
"integrity": "sha1-4QkJALSVI+hSe+IPCBJ1IF8q42o=",
|
||||
"requires": {
|
||||
"colorspace": "1.0.1",
|
||||
"enabled": "1.0.2",
|
||||
"kuler": "0.0.0"
|
||||
}
|
||||
},
|
||||
"dns-prefetch-control": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/dns-prefetch-control/-/dns-prefetch-control-0.1.0.tgz",
|
||||
@@ -1832,6 +1887,14 @@
|
||||
"integrity": "sha1-dk6IfKkQTQGgrI6r7n38DizhQQQ=",
|
||||
"dev": true
|
||||
},
|
||||
"enabled": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/enabled/-/enabled-1.0.2.tgz",
|
||||
"integrity": "sha1-ll9lE9LC0cX0ZStkouM5ZGf8L5M=",
|
||||
"requires": {
|
||||
"env-variable": "0.0.4"
|
||||
}
|
||||
},
|
||||
"encodeurl": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
||||
@@ -1846,6 +1909,11 @@
|
||||
"iconv-lite": "0.4.21"
|
||||
}
|
||||
},
|
||||
"env-variable": {
|
||||
"version": "0.0.4",
|
||||
"resolved": "https://registry.npmjs.org/env-variable/-/env-variable-0.0.4.tgz",
|
||||
"integrity": "sha512-+jpGxSWG4vr6gVxUHOc4p+ilPnql7NzZxOZBxNldsKGjCF+97df3CbuX7XMaDa5oAVkKQj4rKp38rYdC4VcpDg=="
|
||||
},
|
||||
"error-ex": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz",
|
||||
@@ -2448,6 +2516,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"fecha": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/fecha/-/fecha-2.3.3.tgz",
|
||||
"integrity": "sha512-lUGBnIamTAwk4znq5BcqsDaxSmZ9nDVJaij6NvRt/Tg4R69gERA+otPKbS86ROw9nxVMw2/mp1fnaiWqbs6Sdg=="
|
||||
},
|
||||
"figures": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
|
||||
@@ -4123,8 +4196,7 @@
|
||||
"is-stream": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
|
||||
"integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
|
||||
"dev": true
|
||||
"integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
|
||||
},
|
||||
"is-symbol": {
|
||||
"version": "1.0.1",
|
||||
@@ -4283,6 +4355,14 @@
|
||||
"integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
|
||||
"dev": true
|
||||
},
|
||||
"kuler": {
|
||||
"version": "0.0.0",
|
||||
"resolved": "https://registry.npmjs.org/kuler/-/kuler-0.0.0.tgz",
|
||||
"integrity": "sha1-tmu0a5NOVQ9Z2BiEjgq7pPf1VTw=",
|
||||
"requires": {
|
||||
"colornames": "0.0.2"
|
||||
}
|
||||
},
|
||||
"latest-version": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz",
|
||||
@@ -4359,8 +4439,7 @@
|
||||
"lodash": {
|
||||
"version": "4.17.10",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz",
|
||||
"integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg=="
|
||||
},
|
||||
"lodash.assign": {
|
||||
"version": "4.2.0",
|
||||
@@ -4408,6 +4487,29 @@
|
||||
"resolved": "https://registry.npmjs.org/lodash.reduce/-/lodash.reduce-4.6.0.tgz",
|
||||
"integrity": "sha1-8atrg5KZrUj3hKu/R2WW8DuRTTs="
|
||||
},
|
||||
"logform": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/logform/-/logform-1.7.0.tgz",
|
||||
"integrity": "sha512-IyyAkQiA0I3LEar69J0bR5kg7204883jsWW4os9ypXiEsHueuPwfEClC3aSelhG+pIbMD0l23nAkz5VRXZYMWA==",
|
||||
"requires": {
|
||||
"colors": "1.3.0",
|
||||
"fecha": "2.3.3",
|
||||
"ms": "2.1.1",
|
||||
"triple-beam": "1.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"colors": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/colors/-/colors-1.3.0.tgz",
|
||||
"integrity": "sha512-EDpX3a7wHMWFA7PUHWPHNWqOxIIRSJetuwl0AS5Oi/5FMV8kWm69RTlgm00GKjBO1xFHMtBbL49yRtMMdticBw=="
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
|
||||
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"loose-envify": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz",
|
||||
@@ -4817,6 +4919,11 @@
|
||||
"wrappy": "1.0.2"
|
||||
}
|
||||
},
|
||||
"one-time": {
|
||||
"version": "0.0.4",
|
||||
"resolved": "https://registry.npmjs.org/one-time/-/one-time-0.0.4.tgz",
|
||||
"integrity": "sha1-+M33eISCb+Tf+T46nMN7HkSAdC4="
|
||||
},
|
||||
"onetime": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
|
||||
@@ -5912,6 +6019,11 @@
|
||||
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
|
||||
"dev": true
|
||||
},
|
||||
"stack-trace": {
|
||||
"version": "0.0.10",
|
||||
"resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
|
||||
"integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA="
|
||||
},
|
||||
"static-extend": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
|
||||
@@ -6119,6 +6231,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"text-hex": {
|
||||
"version": "0.0.0",
|
||||
"resolved": "https://registry.npmjs.org/text-hex/-/text-hex-0.0.0.tgz",
|
||||
"integrity": "sha1-V4+8haapJjbkLdF7QdAhjM6esrM="
|
||||
},
|
||||
"text-table": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
|
||||
@@ -6215,6 +6332,11 @@
|
||||
"integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=",
|
||||
"dev": true
|
||||
},
|
||||
"triple-beam": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz",
|
||||
"integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw=="
|
||||
},
|
||||
"type-check": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
|
||||
@@ -6552,6 +6674,26 @@
|
||||
"integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU=",
|
||||
"dev": true
|
||||
},
|
||||
"winston": {
|
||||
"version": "3.0.0-rc5",
|
||||
"resolved": "https://registry.npmjs.org/winston/-/winston-3.0.0-rc5.tgz",
|
||||
"integrity": "sha512-BRYS7jsNkfLAqGu4dZW3kp6CmqiWKrComvfsIMYdsnpPre7g8BIw63nWRyX69vxyLYvZdszcEyxJkJmILXd/pA==",
|
||||
"requires": {
|
||||
"async": "2.6.1",
|
||||
"diagnostics": "1.1.0",
|
||||
"is-stream": "1.1.0",
|
||||
"logform": "1.7.0",
|
||||
"one-time": "0.0.4",
|
||||
"stack-trace": "0.0.10",
|
||||
"triple-beam": "1.3.0",
|
||||
"winston-transport": "3.2.1"
|
||||
}
|
||||
},
|
||||
"winston-transport": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-3.2.1.tgz",
|
||||
"integrity": "sha512-WPqbdAmMK/kfWCWKM2bA1o997wWPZ0jg5NpO8JPqoaDZgCiZnFpIEddcf7Ur4UZV2sYRUdySVBWKx0+gQQ/jrg=="
|
||||
},
|
||||
"wordwrap": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
|
||||
|
||||
@@ -78,7 +78,8 @@
|
||||
"express": "^4.16.3",
|
||||
"helmet": "^3.12.1",
|
||||
"jsonwebtoken": "^8.2.1",
|
||||
"mariasql": "^0.2.6"
|
||||
"mariasql": "^0.2.6",
|
||||
"winston": "^3.0.0-rc5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-eslint": "^8.2.2",
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
/* @flow */
|
||||
"use strict";
|
||||
|
||||
const express = require("express");
|
||||
const cors = require("cors");
|
||||
|
||||
const app = express();
|
||||
|
||||
app.use(cors());
|
||||
|
||||
app.get("/", (req, res) => res.send("Server alive, with CORS!"));
|
||||
|
||||
app.listen(8080, () =>
|
||||
console.log("CORS server ready at http://localhost:8080/!")
|
||||
);
|
||||
@@ -1,18 +0,0 @@
|
||||
/* @flow */
|
||||
"use strict";
|
||||
|
||||
const express = require("express");
|
||||
const app = express();
|
||||
const http = require("http");
|
||||
|
||||
http.createServer(app).listen(8080);
|
||||
|
||||
app.use((req, res, next) => {
|
||||
if (req.secure) {
|
||||
next();
|
||||
} else {
|
||||
res.redirect(
|
||||
`https://${req.headers.host.replace(/8080/, "8443")}${req.url}`
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -1,17 +0,0 @@
|
||||
/* @flow */
|
||||
"use strict";
|
||||
|
||||
const express = require("express");
|
||||
const app = express();
|
||||
const https = require("https");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
|
||||
const keysPath = path.join(__dirname, "../../certificates");
|
||||
const ca = fs.readFileSync(`${keysPath}/modernjsbook.csr`);
|
||||
const cert = fs.readFileSync(`${keysPath}/modernjsbook.crt`);
|
||||
const key = fs.readFileSync(`${keysPath}/modernjsbook.key`);
|
||||
|
||||
https.createServer({ ca, cert, key }, app).listen(8443);
|
||||
|
||||
app.get("/", (req, res) => res.send("Secure server!"));
|
||||
@@ -1,69 +0,0 @@
|
||||
/* @flow */
|
||||
"use strict";
|
||||
|
||||
const express = require("express");
|
||||
const app = express();
|
||||
const jwt = require("jsonwebtoken");
|
||||
const bodyParser = require("body-parser");
|
||||
|
||||
const validateUser = require("./validate_user.js");
|
||||
|
||||
const SECRET_JWT_KEY = "modernJSbook";
|
||||
|
||||
app.use(bodyParser.urlencoded({ extended: false }));
|
||||
|
||||
app.get("/public", (req, res) => {
|
||||
res.send("the /public endpoint needs no token!");
|
||||
});
|
||||
|
||||
app.post("/gettoken", (req, res) => {
|
||||
validateUser(req.body.user, req.body.password, (idErr, userid) => {
|
||||
if (idErr !== null) {
|
||||
res.status(401).send(idErr);
|
||||
} else {
|
||||
jwt.sign(
|
||||
{ userid },
|
||||
SECRET_JWT_KEY,
|
||||
{ algorithm: "HS256", expiresIn: "1h" },
|
||||
(err, token) => res.status(200).send(token)
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
app.use((req, res, next) => {
|
||||
// First check for the Authorization header
|
||||
const authHeader = req.headers.authorization;
|
||||
if (!authHeader || !authHeader.startsWith("Bearer ")) {
|
||||
return res.status(401).send("No token specified");
|
||||
}
|
||||
|
||||
// Now validate the token itself
|
||||
const token = authHeader.split(" ")[1];
|
||||
|
||||
jwt.verify(token, SECRET_JWT_KEY, (err, decoded) => {
|
||||
if (err) {
|
||||
// Token bad formed, or expired, or other problem
|
||||
return res.status(403).send("Token expired or not valid");
|
||||
} else {
|
||||
// Token OK; get the user id from it
|
||||
req.userid = decoded.userid;
|
||||
// Keep processing the request
|
||||
next();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
app.get("/private", (req, res) => {
|
||||
res.send("the /private endpoint needs JWT, but it was provided: OK!");
|
||||
});
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
app.use((err, req, res, next) => {
|
||||
console.error("Error....", err.message);
|
||||
res.status(500).send("INTERNAL SERVER ERROR");
|
||||
});
|
||||
|
||||
app.listen(8080, () =>
|
||||
console.log("Mini JWT server ready, at http://localhost:8080/!")
|
||||
);
|
||||
@@ -1,30 +0,0 @@
|
||||
/* @flow */
|
||||
"use strict";
|
||||
|
||||
const express = require("express");
|
||||
const app = express();
|
||||
|
||||
app.use((req, res, next) => {
|
||||
console.log("Logger... ", new Date(), req.method, req.path);
|
||||
next();
|
||||
});
|
||||
|
||||
app.use((req, res, next) => {
|
||||
if (req.method === "DELETE") {
|
||||
next(new Error("DELETEs are not accepted!"));
|
||||
} else {
|
||||
res.send("Server alive, with Express!");
|
||||
}
|
||||
});
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
app.use((err, req, res, next) => {
|
||||
console.error("Error....", err.message);
|
||||
res.status(500).send("INTERNAL SERVER ERROR");
|
||||
});
|
||||
|
||||
app.listen(8080, () =>
|
||||
console.log(
|
||||
"Mini server (with Express) ready at http://localhost:8080/!"
|
||||
)
|
||||
);
|
||||
@@ -1,20 +0,0 @@
|
||||
/* @flow */
|
||||
"use strict";
|
||||
|
||||
const mariaSQL = require("mariasql");
|
||||
const { promisify } = require("util");
|
||||
|
||||
const DB_HOST = "127.0.0.1";
|
||||
const DB_USER = "fkereki";
|
||||
const DB_PASS = "modernJS!!";
|
||||
const DB_SCHEMA = "world";
|
||||
|
||||
const getDbConnection = (host, user, password, db) => {
|
||||
const dbConn = new mariaSQL({ host, user, password, db });
|
||||
dbConn.query = promisify(dbConn.query);
|
||||
return dbConn;
|
||||
};
|
||||
|
||||
const dbConn = getDbConnection(DB_HOST, DB_USER, DB_PASS, DB_SCHEMA);
|
||||
|
||||
module.exports = dbConn;
|
||||
@@ -1,182 +0,0 @@
|
||||
/* @flow */
|
||||
"use strict";
|
||||
|
||||
const getRegion = async (
|
||||
res: any,
|
||||
dbConn: any,
|
||||
country: ?string,
|
||||
region: ?string
|
||||
) => {
|
||||
try {
|
||||
let sqlQuery = "";
|
||||
if (country == null) {
|
||||
sqlQuery = `
|
||||
SELECT rr.*
|
||||
FROM regions rr
|
||||
JOIN countries cc
|
||||
ON cc.countryCode=rr.countryCode
|
||||
ORDER BY cc.countryCode, rr.regionCode
|
||||
`;
|
||||
} else if (region == null) {
|
||||
sqlQuery = `
|
||||
SELECT 1
|
||||
FROM countries
|
||||
WHERE countryCode="${country}"
|
||||
`;
|
||||
|
||||
const countries = await dbConn.query(sqlQuery);
|
||||
if (countries.length === 0) {
|
||||
return res.status(404).send("Country not found");
|
||||
}
|
||||
|
||||
sqlQuery = `
|
||||
SELECT rr.*
|
||||
FROM regions rr
|
||||
JOIN countries cc
|
||||
ON cc.countryCode=rr.countryCode
|
||||
WHERE rr.countryCode="${country}"
|
||||
ORDER BY rr.regionCode
|
||||
`;
|
||||
} else {
|
||||
sqlQuery = `
|
||||
SELECT rr.*
|
||||
FROM regions rr
|
||||
JOIN countries cc
|
||||
ON cc.countryCode=rr.countryCode
|
||||
WHERE rr.countryCode="${country}"
|
||||
AND rr.regionCode="${region}"
|
||||
`;
|
||||
}
|
||||
|
||||
const regions = await dbConn.query(sqlQuery);
|
||||
if (regions.length > 0 || region === null) {
|
||||
res
|
||||
.status(200)
|
||||
.set("Content-Type", "application/json")
|
||||
.send(JSON.stringify(regions));
|
||||
} else {
|
||||
res.status(404).send("Not found");
|
||||
}
|
||||
} catch (e) {
|
||||
res.status(500).send("Server error");
|
||||
}
|
||||
};
|
||||
|
||||
const deleteRegion = async (
|
||||
res: any,
|
||||
dbConn: any,
|
||||
country: string,
|
||||
region: string
|
||||
) => {
|
||||
try {
|
||||
const sqlCities = `
|
||||
SELECT 1 FROM cities
|
||||
WHERE countryCode="${country}"
|
||||
AND regionCode="${region}"
|
||||
LIMIT 1
|
||||
`;
|
||||
const cities = await dbConn.query(sqlCities);
|
||||
if (cities.length > 0) {
|
||||
res.status(405).send("Cannot delete a region with cities");
|
||||
} else {
|
||||
const deleteRegion = `
|
||||
DELETE FROM regions
|
||||
WHERE countryCode="${country}"
|
||||
AND regionCode="${region}"
|
||||
`;
|
||||
|
||||
const result = await dbConn.query(deleteRegion);
|
||||
if (result.info.affectedRows > 0) {
|
||||
res.status(204).send();
|
||||
} else {
|
||||
res.status(404).send("Region not found");
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
res.status(500).send("Server error");
|
||||
}
|
||||
};
|
||||
|
||||
const postRegion = async (
|
||||
res: any,
|
||||
dbConn: any,
|
||||
country: string,
|
||||
name: string
|
||||
) => {
|
||||
if (!name) {
|
||||
return res.status(400).send("Missing name");
|
||||
}
|
||||
|
||||
try {
|
||||
const sqlCountry = `
|
||||
SELECT 1
|
||||
FROM countries
|
||||
WHERE countryCode="${country}"
|
||||
`;
|
||||
const countries = await dbConn.query(sqlCountry);
|
||||
if (countries.length === 0) {
|
||||
res.status(403).send("Country must exist");
|
||||
}
|
||||
|
||||
const sqlGetId = `
|
||||
SELECT MAX(CAST(regionCode AS INTEGER)) AS maxr
|
||||
FROM regions
|
||||
WHERE countryCode="${country}"
|
||||
`;
|
||||
const regions = await dbConn.query(sqlGetId);
|
||||
const newId =
|
||||
regions.length === 0 ? 1 : 1 + Number(regions[0].maxr);
|
||||
|
||||
const sqlAddRegion = `
|
||||
INSERT INTO regions SET
|
||||
countryCode="${country}",
|
||||
regionCode="${newId}",
|
||||
regionName="${name}"
|
||||
`;
|
||||
|
||||
const result = await dbConn.query(sqlAddRegion);
|
||||
if (result.info.affectedRows > 0) {
|
||||
res
|
||||
.status(201)
|
||||
.header("Location", `/regions/${country}/${newId}`)
|
||||
.send("Region created");
|
||||
} else {
|
||||
res.status(409).send("Region not created");
|
||||
}
|
||||
} catch (e) {
|
||||
res.status(500).send("Server error");
|
||||
}
|
||||
};
|
||||
|
||||
const putRegion = async (
|
||||
res: any,
|
||||
dbConn: any,
|
||||
country: string,
|
||||
region: string,
|
||||
name: string
|
||||
) => {
|
||||
if (!name) {
|
||||
return res.status(400).send("Missing name");
|
||||
}
|
||||
|
||||
try {
|
||||
const sqlUpdateRegion = `
|
||||
UPDATE regions
|
||||
SET regionName="${name}"
|
||||
WHERE countryCode="${country}"
|
||||
AND regionCode="${region}"
|
||||
`;
|
||||
|
||||
const result = await dbConn.query(sqlUpdateRegion);
|
||||
|
||||
if (result.info.affectedRows > 0) {
|
||||
res.status(204).send();
|
||||
} else {
|
||||
res.status(409).send("Region not updated");
|
||||
}
|
||||
} catch (e) {
|
||||
res.status(500).send("Server error");
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = { getRegion, deleteRegion, postRegion, putRegion };
|
||||
@@ -1,87 +0,0 @@
|
||||
/* @flow */
|
||||
"use strict";
|
||||
|
||||
const express = require("express");
|
||||
const app = express();
|
||||
const bodyParser = require("body-parser");
|
||||
|
||||
const dbConn = require("./restful_db.js");
|
||||
|
||||
app.get("/", (req, res) => res.send("Secure server!"));
|
||||
|
||||
/*
|
||||
Add here the logic for CORS
|
||||
|
||||
const cors = require("cors");
|
||||
app.use(cors());
|
||||
*/
|
||||
|
||||
app.use(bodyParser.urlencoded({ extended: false }));
|
||||
|
||||
/*
|
||||
Add here the logic for providing a JWT at /gettoken
|
||||
and the logic for validating a JWT, as shown earlier
|
||||
*/
|
||||
|
||||
const {
|
||||
getRegion,
|
||||
deleteRegion,
|
||||
postRegion,
|
||||
putRegion
|
||||
} = require("./restful_regions.js");
|
||||
|
||||
app.get("/regions/", (req, res) => getRegion(res, dbConn));
|
||||
|
||||
app.get(
|
||||
"/regions/:country/",
|
||||
(req, res) => (
|
||||
console.log(req), getRegion(res, dbConn, req.params.country)
|
||||
)
|
||||
);
|
||||
|
||||
app.get("/regions/:country/:region/", (req, res) =>
|
||||
getRegion(res, dbConn, req.params.country, req.params.region)
|
||||
);
|
||||
|
||||
app.delete("/regions/:country/:region", (req, res) =>
|
||||
deleteRegion(res, dbConn, req.params.country, req.params.region)
|
||||
);
|
||||
|
||||
app.post("/regions/:country", (req, res) =>
|
||||
postRegion(res, dbConn, req.params.country, req.body.name)
|
||||
);
|
||||
|
||||
app.put("/regions/:country/:region", (req, res) =>
|
||||
putRegion(
|
||||
res,
|
||||
dbConn,
|
||||
req.params.country,
|
||||
req.params.region,
|
||||
req.body.name
|
||||
)
|
||||
);
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
app.use((err, req, res, next) => {
|
||||
console.error("Error....", err.message);
|
||||
res.status(500).send("INTERNAL SERVER ERROR");
|
||||
});
|
||||
|
||||
/*
|
||||
Add here the logic for HTTPS
|
||||
|
||||
const https = require("https");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const keysPath = path.join(__dirname, "../../certificates");
|
||||
const ca = fs.readFileSync(`${keysPath}/modernjsbook.csr`);
|
||||
const cert = fs.readFileSync(`${keysPath}/modernjsbook.crt`);
|
||||
const key = fs.readFileSync(`${keysPath}/modernjsbook.key`);
|
||||
|
||||
https.createServer({ ca, cert, key }, app).listen(8443);
|
||||
|
||||
and remove the following line if HTTPS is used
|
||||
*/
|
||||
app.listen(8080, () =>
|
||||
console.log("Routing ready at http://localhost:8080")
|
||||
);
|
||||
@@ -1,23 +0,0 @@
|
||||
/* @flow */
|
||||
"use strict";
|
||||
|
||||
/*
|
||||
In real life, validateUser could check a database,
|
||||
look into an Active Directory, call another service,
|
||||
etc. -- but for this demo, let's keep it quite
|
||||
simple and only accept a single hardcoded user.
|
||||
*/
|
||||
|
||||
const validateUser = (
|
||||
userName: string,
|
||||
password: string,
|
||||
callback: (?string, ?string) => void
|
||||
) => {
|
||||
if (userName === "fkereki" && password === "modernjsbook") {
|
||||
callback(null, "fkereki"); // OK, send userName back
|
||||
} else {
|
||||
callback("Not valid user", null);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = validateUser;
|
||||
@@ -0,0 +1,66 @@
|
||||
/* @flow */
|
||||
"use strict";
|
||||
|
||||
const express = require("express");
|
||||
const app = express();
|
||||
|
||||
const winston = require("winston");
|
||||
|
||||
const logger = winston.createLogger({
|
||||
level: "info",
|
||||
|
||||
transports: [
|
||||
new winston.transports.Console({
|
||||
format: winston.format.combine(
|
||||
winston.format.colorize({ all: true }),
|
||||
winston.format.label({ label: "w_s" }),
|
||||
winston.format.timestamp(),
|
||||
winston.format.printf(
|
||||
msg =>
|
||||
`${msg.timestamp} [${msg.label}] ${msg.level} ${
|
||||
msg.message
|
||||
}`
|
||||
)
|
||||
)
|
||||
}),
|
||||
new winston.transports.File({
|
||||
filename: "w_s_error.txt.log",
|
||||
level: "error",
|
||||
format: winston.format.combine(
|
||||
winston.format.timestamp(),
|
||||
winston.format.printf(
|
||||
msg => `${msg.timestamp} ${msg.level} ${msg.message}`
|
||||
)
|
||||
)
|
||||
}),
|
||||
new winston.transports.File({
|
||||
filename: "w_s_error.json.log",
|
||||
level: "error"
|
||||
})
|
||||
]
|
||||
});
|
||||
|
||||
logger.level = "debug";
|
||||
|
||||
logger.error("This is an error");
|
||||
logger.info("This is an info");
|
||||
logger.warn("This is a warning");
|
||||
logger.debug("This is debugging info");
|
||||
|
||||
app.get("/", (req, res) => {
|
||||
logger.info("Request for root /");
|
||||
res.send("Winston server!");
|
||||
});
|
||||
|
||||
app.get("*", (req, res) => {
|
||||
logger.error(`UNKNOWN ROUTE ${req.originalUrl}`);
|
||||
res.status(404).send("NOT FOUND");
|
||||
});
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
app.use((err, req, res, next) => {
|
||||
logger.error(`GENERAL ERROR ${err.message}`);
|
||||
res.status(500).send("INTERNAL SERVER ERROR");
|
||||
});
|
||||
|
||||
app.listen(8081, () => logger.info("Ready at http://localhost:8080"));
|
||||
Reference in New Issue
Block a user