Add user, login & logout, secure sandwiches and orders pages with login and permissions check
This commit is contained in:
parent
d4a1864dfb
commit
43851413ea
11 changed files with 173 additions and 4 deletions
16
app.js
16
app.js
|
@ -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);
|
||||
|
|
|
@ -3,5 +3,6 @@
|
|||
"password": null,
|
||||
"database": "database_development",
|
||||
"host": "127.0.0.1",
|
||||
"dialect": "mysql"
|
||||
"dialect": "mysql",
|
||||
"secret": "keyboard cat"
|
||||
}
|
||||
|
|
13
middlewares/sessionCheck.js
Normal file
13
middlewares/sessionCheck.js
Normal 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
44
models/user.js
Normal 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
40
package-lock.json
generated
|
@ -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",
|
||||
|
|
|
@ -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
28
routes/login.js
Normal 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
11
routes/logout.js
Normal 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;
|
|
@ -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 = {};
|
||||
|
|
|
@ -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
13
views/login.pug
Normal 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")
|
Reference in a new issue