diff --git a/package.json b/package.json index c7f7e9e..d554c3c 100644 --- a/package.json +++ b/package.json @@ -17,8 +17,10 @@ "codex.editor.header": "^2.0.5", "cookie-parser": "~1.4.3", "debug": "~4.1.0", + "dotenv": "^6.2.0", "express": "~4.16.0", "http-errors": "~1.7.1", + "jsonwebtoken": "^8.4.0", "module-dispatcher": "^1.0.2", "morgan": "~1.9.0", "multer": "^1.3.1", diff --git a/src/routes/auth.js b/src/routes/auth.js new file mode 100644 index 0000000..63a6060 --- /dev/null +++ b/src/routes/auth.js @@ -0,0 +1,29 @@ +const express = require('express'); +const router = express.Router(); +const { password: db } = require('../utils/database/index'); +const jwt = require('jsonwebtoken'); + +/* GET authorization page. */ +router.get('/auth', function (req, res, next) { + res.render('auth', { title: 'Login page ', header: 'Enter password' }); +}); + +router.post('/auth', async (req, res) => { + const passwordDoc = await db.findOne({password: req.body.password}); + + if (passwordDoc !== null) { + const token = jwt.sign({ + 'iss': 'Codex Team', + 'sub': 'auth', + 'iat': Date.now() + }, passwordDoc.password); + + res.cookie('authToken', token); + + res.redirect('/'); + } else { + res.render('auth', { title: 'Login page', header: 'Wrong password!
Try once more' }); + } +}); + +module.exports = router; diff --git a/src/routes/home.js b/src/routes/home.js index 819cc1d..5e78936 100644 --- a/src/routes/home.js +++ b/src/routes/home.js @@ -1,9 +1,21 @@ const express = require('express'); +const verifyToken = require('./middlewares/token'); const router = express.Router(); /* GET home page. */ -router.get('/', function (req, res, next) { - res.render('index', { title: 'Express' }); +router.get('/', async function (req, res, next) { + let isAuthorized = false; + + await verifyToken(req.cookies.authToken).then( + async () => { + console.log('Authorized user entered page'); + isAuthorized = true; + }, + () => { + console.log('Not authorized'); + } + ); + res.render('index', { title: 'Express', isAuthorized: isAuthorized }); }); -module.exports = router; \ No newline at end of file +module.exports = router; diff --git a/src/routes/index.js b/src/routes/index.js index 6ad5d78..9dc3e27 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -3,12 +3,14 @@ const router = express.Router(); const home = require('./home'); const pages = require('./pages'); +const auth = require('./auth'); const api = require('./api'); const pagesMiddleware = require('./middlewares/pages'); router.use('/', pagesMiddleware, home); router.use('/', pagesMiddleware, pages); +router.use('/', pagesMiddleware, auth); router.use('/api', api); module.exports = router; diff --git a/src/routes/middlewares/token.js b/src/routes/middlewares/token.js new file mode 100644 index 0000000..3050f1a --- /dev/null +++ b/src/routes/middlewares/token.js @@ -0,0 +1,14 @@ +require('dotenv').config(); + +const jwt = require('jsonwebtoken'); + +module.exports = function verifyToken(token) { + return new Promise((resolve, reject) => { + jwt.verify(token, process.env.PASSWORD, (err, decodedToken) => { + if (err || !decodedToken) { + return reject(err); + } + resolve(decodedToken); + }); + }); +}; diff --git a/src/routes/pages.js b/src/routes/pages.js index 62a788c..701078e 100644 --- a/src/routes/pages.js +++ b/src/routes/pages.js @@ -1,37 +1,53 @@ const express = require('express'); const router = express.Router(); const Pages = require('../controllers/pages'); +const verifyToken = require('./middlewares/token'); /** * Create new page form */ router.get('/page/new', async (req, res) => { - let pagesAvailable = await Pages.getAll(); + verifyToken(req.cookies.authToken).then( + async () => { + let pagesAvailable = await Pages.getAll(); - res.render('pages/form', { - pagesAvailable, - page: null - }); + res.render('pages/form', { + pagesAvailable, + page: null + }); + }, + () => { + res.render('auth', { title: 'Login page', header: 'Enter password to do this!' }); + } + + ); }); /** * Edit page form */ router.get('/page/edit/:id', async (req, res, next) => { - const pageId = req.params.id; + verifyToken(req.cookies.authToken).then( + async () => { + const pageId = req.params.id; - try { - let page = await Pages.get(pageId); - let pagesAvailable = await Pages.getAll(); + try { + let page = await Pages.get(pageId); + let pagesAvailable = await Pages.getAll(); - res.render('pages/form', { - pagesAvailable, - page - }); - } catch (error) { - res.status(404); - next(error); - } + res.render('pages/form', { + pagesAvailable, + page + }); + } catch (error) { + res.status(404); + next(error); + } + }, + () => { + res.render('auth', { title: 'Login page', header: 'Enter password to do this!' }); + } + ); }); /** @@ -39,6 +55,17 @@ router.get('/page/edit/:id', async (req, res, next) => { */ router.get('/page/:id', async (req, res, next) => { const pageId = req.params.id; + let isAuthorized = false; + + await verifyToken(req.cookies.authToken).then( + async () => { + console.log('Authorized user entered page'); + isAuthorized = true; + }, + () => { + console.log('Not authorized'); + } + ); try { let page = await Pages.get(pageId); @@ -46,7 +73,7 @@ router.get('/page/:id', async (req, res, next) => { let pageParent = await page.parent; res.render('pages/page', { - page, pageParent + page, pageParent, isAuthorized }); } catch (error) { res.status(404); diff --git a/src/utils/database/index.js b/src/utils/database/index.js index 0066c58..3ab0783 100644 --- a/src/utils/database/index.js +++ b/src/utils/database/index.js @@ -1,4 +1,5 @@ const pages = require('./pages'); +const password = require('./password'); /** * @class Database @@ -142,5 +143,6 @@ class Database { module.exports = { class: Database, - pages: new Database(pages) + pages: new Database(pages), + password: new Database(password) }; diff --git a/src/utils/database/password.js b/src/utils/database/password.js new file mode 100644 index 0000000..e97f33c --- /dev/null +++ b/src/utils/database/password.js @@ -0,0 +1,6 @@ +const Datastore = require('nedb'); +const config = require('../../../config'); + +const db = new Datastore({filename: `./${config.database}/password.db`, autoload: true}); + +module.exports = db; diff --git a/src/views/auth.twig b/src/views/auth.twig new file mode 100644 index 0000000..cf9e514 --- /dev/null +++ b/src/views/auth.twig @@ -0,0 +1,10 @@ +{% extends 'layout.twig' %} + +{% block body %} +

{{header}}

+
+ + +
+{% endblock %} + diff --git a/src/views/components/header.twig b/src/views/components/header.twig index fd7d722..7c54e31 100644 --- a/src/views/components/header.twig +++ b/src/views/components/header.twig @@ -4,10 +4,14 @@