diff --git a/app.js b/app.js index 9340404..b17ceaa 100644 --- a/app.js +++ b/app.js @@ -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); diff --git a/classes/Account.class.js b/classes/Account.class.js new file mode 100644 index 0000000..9facedf --- /dev/null +++ b/classes/Account.class.js @@ -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. + */ + + diff --git a/classes/Controllers/Accounts.class.js b/classes/Controllers/Accounts.class.js new file mode 100644 index 0000000..e69de29 diff --git a/classes/Controllers/Categories.class.js b/classes/Controllers/Categories.class.js index cd2c01a..8a72929 100644 --- a/classes/Controllers/Categories.class.js +++ b/classes/Controllers/Categories.class.js @@ -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){ diff --git a/classes/JWTHandler.class.js b/classes/JWTHandler.class.js new file mode 100644 index 0000000..b077d8d --- /dev/null +++ b/classes/JWTHandler.class.js @@ -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; \ No newline at end of file diff --git a/config.json b/config.json index e026adf..a2b9811 100644 --- a/config.json +++ b/config.json @@ -3,5 +3,7 @@ "siteTitle": "Dryusdan", "siteHomeTitle": "Dryusdan.fr, blog d'un passionné d'informatique", "db": "rethinkdb", - "webroot" : "/" + "webroot" : "/", + "login": "root", + "password": "root" } diff --git a/lib/router.js b/lib/router.js index cd92408..996894f 100644 --- a/lib/router.js +++ b/lib/router.js @@ -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; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index f90faaf..5f5ba44 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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=", diff --git a/package.json b/package.json index 53dde35..5e8b0c6 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/views/admin/login.hbs b/views/admin/login.hbs new file mode 100644 index 0000000..8ef8df3 --- /dev/null +++ b/views/admin/login.hbs @@ -0,0 +1,21 @@ +
+

Espace admin

+ +
+
+
+
+ +
+
+ + + +
+
+
+
+
\ No newline at end of file diff --git a/views/templateAdmin.hbs b/views/templateAdmin.hbs new file mode 100644 index 0000000..daba184 --- /dev/null +++ b/views/templateAdmin.hbs @@ -0,0 +1,28 @@ + + + + + Administration è {{title}} + + + + +
+ + {{{nav}}} +
+ +{{{content}}} + + + + + + \ No newline at end of file