Create basic admin area

This commit is contained in:
Dryusdan 2017-07-23 01:17:20 +02:00
parent 15d20073b2
commit ea1b116c17
11 changed files with 361 additions and 10 deletions

26
app.js
View File

@ -1,10 +1,13 @@
const express = require('express'),
cors = require("cors"),
app = express(),
helmet = require('helmet'),
log = require("color-logs")(true, true, "Nodezzarella app"),
fs = require("fs"),
promise = require('promise');
const express = require('express'),
cors = require("cors"),
app = express(),
session = require('express-session'),
bodyParser = require('body-parser'),
cookieParser = require('cookie-parser'),
helmet = require('helmet'),
log = require("color-logs")(true, true, "Nodezzarella app"),
fs = require("fs"),
promise = require('promise');
log.info("Application started and now preparing");
@ -53,6 +56,15 @@ class Nodezzarella {
var routes = require("./lib/router");
log.info("HTTP server listening on port", config.appPort);
log.info("Application ready");
app.use(cookieParser()); // read cookies (needed for auth)
app.use(bodyParser.urlencoded({ extended: false })); // get information from url-encoded data
app.use(bodyParser.json()); // get information from html forms
app.use(session({
secret: 'Nodezzarella',
resave: false,
saveUninitialized: true,
cookie: { secure: true }
}))
app.use(config.webroot || "/", routes);
app.use(function(req, res, next) {
res.status(404);

7
classes/Account.class.js Normal file
View File

@ -0,0 +1,7 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/

View File

View File

@ -179,7 +179,7 @@ class Categories {
//log.debug(data);
var categorie = new Categorie(0, "home", "/", "home");
for(var i in data){
categorie.setArticle(new Article(data[i].left.id,data[i].left.title, data[i].left.author, data[i].left.date, data[i].left.img, data[i].left.slug, data[i].left.categorie_id));
categorie.setArticle(new Article(data[i].left.id,data[i].left.title, data[i].left.author, data[i].left.date, data[i].left.img, "/"+data[i].right.uri+"/"+data[i].left.slug, data[i].left.categorie_id));
categorie.getArticles()[i].setCategorieName(data[i].right.title);
}
switch(returnFormat){

View File

@ -0,0 +1,61 @@
const crypto = require('crypto'),
moment = require("moment"),
jwt = require('jsonwebtoken'),
log = require('color-logs')(true, true, "JWTHandler.class.js");
moment.locale("fr");
class JWTHandler {
constructor() {
this.secret = crypto.createHash('sha256').update("La vie sans gâteau c'est possible, mais c'est sans intérêt", "UTF-8").digest("base64");
log.debug(this.secret);
}
verify(token, secret, cb){
jwt.verify(token, secret, {
issuer: "Nodezzarella",
clockTolerance: 3
}, function(err, decoded) {
if (err) {
cb(err, null);
} else {
cb(false, decoded);
}
});
}
sign(payload, cb){
let baseObject = {
iat: moment().unix(),
exp: moment().add(1, "day").unix(),
iss: "Orbital-Blaze"
};
jwt.sign(Object.assign(baseObject, payload), this.secret, {
algorithm: 'HS256'
}, function(err, token) {
if (err) throw err;
cb(token);
});
}
protect(req, res, next){
var that = this;
return function (req, res, next){
that.verify(req.header("Authorization"), that.secret, function(err, decoded){
if (err) {
res.status(403).json({
status: 403,
message: "Token expired",
expDate: moment(err.expiredAt).unix()
});
}else{
req.token = decoded;
next();
return;
}
})
};
}
}
module.exports = JWTHandler;

View File

@ -3,5 +3,7 @@
"siteTitle": "Dryusdan",
"siteHomeTitle": "Dryusdan.fr, blog d'un passionné d'informatique",
"db": "rethinkdb",
"webroot" : "/"
"webroot" : "/",
"login": "root",
"password": "root"
}

View File

@ -4,6 +4,7 @@ const express = require("express"),
hbs = require('hbs'),
path = require('path'),
log = require("color-logs")(true, true, "Router"),
session = require('express-session'),
Template = require('../classes/Template.class.js'),
Article = require('../classes/Article.class.js'),
Categorie = require('../classes/Categorie.class.js'),
@ -12,7 +13,6 @@ const express = require("express"),
var template = new Template();
router.get("/", function(req, res){
var categories = new Categories();
Promise.all([
categories.getNav(),
@ -34,6 +34,55 @@ router.get("/", function(req, res){
});
});
router.get("/admin/", function(req, res){
var categories = new Categories();
if(req.session.authenticated === true){
res.redirect('/admin/dashboard')
}
else{
categories.getNav().then(data => {
fs.readFile('./views/admin/login.hbs', 'utf-8', (error, source) => {
var template = hbs.compile(source);
res.setHeader("Content-type", "text/html");
var tplData = {
"blogName": config.siteTitle,
"title": config.siteHomeTitle,
"nav": data,
"content": source,
};
res.render('templateAdmin.hbs', tplData);
});
}).catch(err => {
log.debug(err);
res.setHeader("Content-type", "text/plain");
res.end("erreur");
});
}
});
router.post("/admin/", function(req, res){
if(req.body.login && req.body.login === config.login && req.body.password && req.body.password === config.password){
req.session.authenticated = true;
res.redirect('/admin/dashboard');
}
else{
res.redirect('/admin/');
}
});
router.get("/admin/dashboard", function(req, res){
log.debug(req.session);
if(req.session.authenticated === true){
res.setHeader("Content-type", "text/plain");
res.end("erreur");
}
else{
res.redirect('/admin/');
}
});
router.get("/:uri/", function(req, res){
var categories = new Categories();
Promise.all([
@ -83,6 +132,7 @@ router.get("/:categories/:slug", function(req, res){
res.end("erreur");
});
});
router.use(express.static("./public"));
module.exports = router;

166
package-lock.json generated
View File

@ -33,11 +33,43 @@
"version": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
"integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo="
},
"base64url": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/base64url/-/base64url-2.0.0.tgz",
"integrity": "sha1-6sFuA+oUOO/5Qj1puqNiYu0fcLs="
},
"bluebird": {
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz",
"integrity": "sha1-U0uQM8AiyVecVro7Plpcqvu2UOE="
},
"body-parser": {
"version": "1.17.2",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.17.2.tgz",
"integrity": "sha1-+IkqvI+eYn1Crtr7yma/WrmRBO4=",
"dependencies": {
"debug": {
"version": "2.6.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.7.tgz",
"integrity": "sha1-krrR9tBbu2u6Isyoi80OyJTChh4="
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
}
}
},
"buffer-equal-constant-time": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
"integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk="
},
"bytes": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz",
"integrity": "sha1-fZcZb51br39pNeJZhVSe3SpsIzk="
},
"camelcase": {
"version": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz",
"integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=",
@ -112,6 +144,11 @@
"version": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
"integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s="
},
"cookie-parser": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.3.tgz",
"integrity": "sha1-D+MfoZ0AC5X0qt8fU/3CuKIDuqU="
},
"cookie-signature": {
"version": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
@ -125,6 +162,11 @@
"version": "https://registry.npmjs.org/cors/-/cors-2.8.1.tgz",
"integrity": "sha1-YYGqVqu0WiglvjMEcDdHrk6dI4M="
},
"crc": {
"version": "3.4.4",
"resolved": "https://registry.npmjs.org/crc/-/crc-3.4.4.tgz",
"integrity": "sha1-naHpgOO9RPxck79as9ozeNheRms="
},
"dasherize": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/dasherize/-/dasherize-2.0.0.tgz",
@ -162,6 +204,11 @@
"resolved": "https://registry.npmjs.org/dont-sniff-mimetype/-/dont-sniff-mimetype-1.0.0.tgz",
"integrity": "sha1-WTKJDcn04vGeXrAqIAJuXl78j1g="
},
"ecdsa-sig-formatter": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.9.tgz",
"integrity": "sha1-S8kmJ07Dtau1AW5+HWCSGsJisqE="
},
"ee-first": {
"version": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
@ -187,6 +234,33 @@
"version": "https://registry.npmjs.org/express/-/express-4.15.2.tgz",
"integrity": "sha1-rxB/wUhQRFfy3Kmm8lcdcSm5ezU="
},
"express-jwt": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/express-jwt/-/express-jwt-5.3.0.tgz",
"integrity": "sha1-PZDNZYAuYzYlLxnmo98+FJ4MXqA="
},
"express-session": {
"version": "1.15.4",
"resolved": "https://registry.npmjs.org/express-session/-/express-session-1.15.4.tgz",
"integrity": "sha1-Xizc9t7+PB7aTpgPE7mGzFjPuVQ=",
"dependencies": {
"debug": {
"version": "2.6.8",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz",
"integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw="
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
}
}
},
"express-unless": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/express-unless/-/express-unless-0.3.0.tgz",
"integrity": "sha1-XHlec5JXFRLdKPUgs4V6UrISYaI="
},
"finalhandler": {
"version": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.0.1.tgz",
"integrity": "sha1-vNFdFonA5e1ym29/VBpt+YQRfbg=",
@ -243,6 +317,11 @@
"resolved": "https://registry.npmjs.org/hide-powered-by/-/hide-powered-by-1.0.0.tgz",
"integrity": "sha1-SoWtZYgfYoV/xwr3F0oRhNzM4ys="
},
"hoek": {
"version": "2.16.3",
"resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
"integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0="
},
"hpkp": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/hpkp/-/hpkp-2.0.0.tgz",
@ -257,6 +336,11 @@
"version": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.1.tgz",
"integrity": "sha1-X4uO2YrKVFZWv1cplzh/kEpyIlc="
},
"iconv-lite": {
"version": "0.4.15",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz",
"integrity": "sha1-/iZaIYrGpXz+hUkn6dBMGYJe3es="
},
"ienoopen": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/ienoopen/-/ienoopen-1.0.0.tgz",
@ -274,6 +358,38 @@
"version": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz",
"integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw="
},
"isemail": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/isemail/-/isemail-1.2.0.tgz",
"integrity": "sha1-vgPfjMPineTSxd9lASY/H6RZXpo="
},
"joi": {
"version": "6.10.1",
"resolved": "https://registry.npmjs.org/joi/-/joi-6.10.1.tgz",
"integrity": "sha1-TVDDGAeRIgAP5fFq8f+OGRe3fgY="
},
"jsonwebtoken": {
"version": "7.4.1",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-7.4.1.tgz",
"integrity": "sha1-fKMk9SFfi+A5zTWmxFu4y3SkSPs=",
"dependencies": {
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
}
}
},
"jwa": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/jwa/-/jwa-1.1.5.tgz",
"integrity": "sha1-oFUs4CIHQs1S4VN3SjKQXDDnVuU="
},
"jws": {
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/jws/-/jws-3.1.4.tgz",
"integrity": "sha1-+ei5M46KhHJ31kRLFGT2GIDgUKI="
},
"kind-of": {
"version": "https://registry.npmjs.org/kind-of/-/kind-of-3.1.0.tgz",
"integrity": "sha1-R11pil5J/15T0U4+cyQp3Iv0z0c="
@ -283,11 +399,21 @@
"integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=",
"optional": true
},
"lodash.once": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
"integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w="
},
"lodash.reduce": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/lodash.reduce/-/lodash.reduce-4.6.0.tgz",
"integrity": "sha1-8atrg5KZrUj3hKu/R2WW8DuRTTs="
},
"lodash.set": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz",
"integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM="
},
"longest": {
"version": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
"integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc="
@ -325,6 +451,11 @@
"version": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz",
"integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8="
},
"moment": {
"version": "2.18.1",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.18.1.tgz",
"integrity": "sha1-w2GT3Tzhwu7SrbfIAtu8d6gbHA8="
},
"ms": {
"version": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
"integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U="
@ -347,6 +478,11 @@
"version": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
"integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc="
},
"on-headers": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz",
"integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c="
},
"optimist": {
"version": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
"integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY="
@ -377,10 +513,20 @@
"version": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz",
"integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM="
},
"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": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
"integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4="
},
"raw-body": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.2.0.tgz",
"integrity": "sha1-mUl2z2pQlqQRYoQEkvC9xdbn+5Y="
},
"referrer-policy": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/referrer-policy/-/referrer-policy-1.1.0.tgz",
@ -400,6 +546,11 @@
"integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=",
"optional": true
},
"safe-buffer": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
"integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
},
"send": {
"version": "https://registry.npmjs.org/send/-/send-0.15.1.tgz",
"integrity": "sha1-igI1TCbm9cynAAZfXwzeupDse18="
@ -420,6 +571,11 @@
"version": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
"integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4="
},
"topo": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/topo/-/topo-1.1.0.tgz",
"integrity": "sha1-6ddRYV0buH3IZdsYL6HKCl71NtU="
},
"type-is": {
"version": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz",
"integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA="
@ -441,6 +597,11 @@
"integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=",
"optional": true
},
"uid-safe": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.4.tgz",
"integrity": "sha1-Otbzg2jG1MjHXsF2I/t5qh0HHYE="
},
"unpipe": {
"version": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
"integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
@ -471,6 +632,11 @@
"resolved": "https://registry.npmjs.org/x-xss-protection/-/x-xss-protection-1.0.0.tgz",
"integrity": "sha1-iYr7k4abJGYc+cUvnujbjtB2Tdk="
},
"xtend": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
"integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68="
},
"yargs": {
"version": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz",
"integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=",

View File

@ -15,9 +15,13 @@
},
"contributors": [],
"dependencies": {
"body-parser": "^1.17.2",
"color-logs": "0.6.1",
"cookie-parser": "^1.4.3",
"cors": "2.8.1",
"express": "4.15.2",
"express-jwt": "^5.3.0",
"express-session": "^1.15.4",
"handlebars": "4.0.6",
"hbs": "4.0.1",
"helmet": "^3.6.1",

21
views/admin/login.hbs Normal file
View File

@ -0,0 +1,21 @@
<div id="disclaimer">
<h2>Espace admin</h2>
<img class="separator" src="/assets/img/separator.png">
</div>
<main class="transparent">
<section>
<article>
<!-- <div class="articleTitle">
<h1></h1>
<p class="author">Par </p>
</div>-->
<div class="content">
<form action="" method="post">
<input type="input" name="login">
<input type="password" name="password">
<input type="submit" name="connexion">
</form>
</div>
</article>
</section>
</main>

28
views/templateAdmin.hbs Normal file
View File

@ -0,0 +1,28 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Administration è {{title}}</title>
<link rel="stylesheet" href="/assets/css/global.css">
<link href='https://miaou.drycat.fr/favicon.ico' rel='icon' type='image/x-icon'>
</head>
<body>
<header>
<div id="logo"><a href="/">{{blogName}}</a></div>
{{{nav}}}
</header>
<!--<div class="search">
<div class="inputContainer">
<input type="search" placeholder="Rechercher...">
<button> </button>
</div>
</div>-->
{{{content}}}
<footer>
</footer>
<script src="/assets/js/jquery-2.2.0.min.js"></script>
<script src="/assets/js/parallax.js"></script>
<script src="/assets/js/searchInput.js"></script>
</body>
</html>