Archived
1
0
Fork 0

Add user, login & logout, secure sandwiches and orders pages with login and permissions check

This commit is contained in:
Ethanell 2020-08-17 11:33:54 +02:00
parent d4a1864dfb
commit 43851413ea
11 changed files with 173 additions and 4 deletions

16
app.js
View file

@ -1,14 +1,27 @@
let express = require("express");
let path = require("path");
let cookieParser = require("cookie-parser");
let session = require("express-session");
let logger = require("morgan");
let config = require("./config/config.json");
let indexRouter = require("./routes/index");
let loginRouter = require("./routes/login");
let logoutRouter = require("./routes/logout");
let commandRouter = require("./routes/command");
let ordersRouter = require("./routes/orders");
let sandwichesRouter = require("./routes/sandwiches");
let app = express();
let sess = {
secret: config.secret,
cookie: {}
}
if (app.get("env") === "production") {
app.set("trust proxy", 1);
sess.cookie.secure = true;
}
// view engine setup
app.set("views", path.join(__dirname, "views"));
@ -18,9 +31,12 @@ app.use(logger("dev"));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(session(sess));
app.use(express.static(path.join(__dirname, "public")));
app.use("/", indexRouter);
app.use("/login", loginRouter);
app.use("/logout", logoutRouter);
app.use("/command", commandRouter);
app.use("/orders", ordersRouter);
app.use("/sandwiches", sandwichesRouter);

View file

@ -3,5 +3,6 @@
"password": null,
"database": "database_development",
"host": "127.0.0.1",
"dialect": "mysql"
"dialect": "mysql",
"secret": "keyboard cat"
}

View file

@ -0,0 +1,13 @@
function sessionCheck(permission) {
return (req, res, next) => {
if (!req.session.user) {
req.session.lastUrl = req.originalUrl;
req.session.save(() => res.redirect("/login"));
} else if (req.session.user.permissions < permission)
res.render("error", {message: "Permission denied !", "error": {}});
else
next();
}
}
module.exports = sessionCheck;

44
models/user.js Normal file
View file

@ -0,0 +1,44 @@
"use strict";
const {
Model
} = require("sequelize");
module.exports = (sequelize, DataTypes) => {
class User extends Model {
static associate(models) {
}
checkPassword(password) {
return require("crypto")
.createHash("sha256")
.update(this.username + password)
.digest("base64") === this.passwordHash
}
}
User.init({
username: {
type: DataTypes.STRING,
primaryKey: true
},
passwordHash: {
type: DataTypes.STRING,
allowNull: false,
set(value) {
if (value)
this.setDataValue("passwordHash",
require("crypto").
createHash("sha256").
update(this.username + value).
digest("base64"));
}
},
permissions: { // 1 = sandwich page, 2 = order page, 3 = admin
type: DataTypes.INTEGER,
defaultValue: 0,
allowNull: false
}
}, {
sequelize,
modelName: "User",
});
return User;
};

40
package-lock.json generated
View file

@ -495,6 +495,33 @@
}
}
},
"express-session": {
"version": "1.17.1",
"resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.1.tgz",
"integrity": "sha512-UbHwgqjxQZJiWRTMyhvWGvjBQduGCSBDhhZXYenziMFjxst5rMV+aJZ6hKPHZnPyHGsrqRICxtX8jtEbm/z36Q==",
"requires": {
"cookie": "0.4.0",
"cookie-signature": "1.0.6",
"debug": "2.6.9",
"depd": "~2.0.0",
"on-headers": "~1.0.2",
"parseurl": "~1.3.3",
"safe-buffer": "5.2.0",
"uid-safe": "~2.1.5"
},
"dependencies": {
"depd": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
"integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="
},
"safe-buffer": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
"integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg=="
}
}
},
"ext": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz",
@ -1205,6 +1232,11 @@
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
},
"random-bytes": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz",
"integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs="
},
"range-parser": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
@ -1526,6 +1558,14 @@
"integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=",
"optional": true
},
"uid-safe": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz",
"integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==",
"requires": {
"random-bytes": "~1.0.0"
}
},
"umzug": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/umzug/-/umzug-2.3.0.tgz",

View file

@ -9,6 +9,7 @@
"cookie-parser": "~1.4.4",
"debug": "~2.6.9",
"express": "~4.16.1",
"express-session": "^1.17.1",
"http-errors": "~1.6.3",
"morgan": "~1.9.1",
"pg": "^8.3.0",

28
routes/login.js Normal file
View file

@ -0,0 +1,28 @@
const express = require("express");
const router = express.Router();
const models = require("../models");
router.get("/", async (req, res) => {
if (req.session.user)
res.redirect("/")
else
res.render("login", { title: "Kfet - Login" });
})
.post("/", async (req, res) => {
if (!req.body.username || !req.body.password)
res.redirect("/login");
else {
let u = await models.User.findByPk(req.body.username);
if (!u || !u.checkPassword(req.body.password))
res.redirect("/login?err=true");
else {
req.session.user = u;
if (req.session.lastUrl && !req.session.lastUrl.startsWith("/login"))
res.redirect(req.session.lastUrl);
else
res.redirect("/");
}
}
});
module.exports = router;

11
routes/logout.js Normal file
View file

@ -0,0 +1,11 @@
const express = require("express");
const router = express.Router();
router.get("/", (req, res) => {
if (req.session.user) {
req.session.user = null;
}
res.redirect("/");
});
module.exports = router;

View file

@ -1,9 +1,10 @@
let express = require("express");
let router = express.Router();
let sessionCheck = require("../middlewares/sessionCheck");
let models = require("../models");
router.get("/", async (req, res) => {
router.get("/", sessionCheck(2), async (req, res) => {
let date = req.query.date ? req.query.date : (new Date()).toISOString().substring(0,10);
let commands = {};

View file

@ -1,10 +1,11 @@
let express = require("express");
let router = express.Router();
let sessionCheck = require("../middlewares/sessionCheck");
let models = require("../models");
let sequelize = require("sequelize")
let sequelize = require("sequelize");
router.get("/", async (req, res) => {
router.get("/", sessionCheck(1), async (req, res) => {
let date = req.query.date ? req.query.date : (new Date()).toISOString().substring(0,10);
res.render("sandwiches", {

13
views/login.pug Normal file
View file

@ -0,0 +1,13 @@
extends layout
block content
form.card(action="/login" method="POST")
h1 Login
div.field
label(for="username") Username:
input#username(type="text" name="username" required)
dov.field
label(for="password") Username:
input#password(type="password" name="password" required)
div.field
input(type="submit" value="Login")