From d2f94dbb8892dabbf93dc25e37407d7692cbc702 Mon Sep 17 00:00:00 2001 From: "D. Berge" Date: Wed, 1 May 2024 10:05:48 +0200 Subject: [PATCH] Refactor JWT token verification --- lib/www/server/api/middleware/user/login.js | 25 ++++++---------- lib/www/server/lib/jwt.js | 33 +++++++++++++++++++-- 2 files changed, 40 insertions(+), 18 deletions(-) diff --git a/lib/www/server/api/middleware/user/login.js b/lib/www/server/api/middleware/user/login.js index aea9aa5..6da6561 100644 --- a/lib/www/server/api/middleware/user/login.js +++ b/lib/www/server/api/middleware/user/login.js @@ -1,28 +1,21 @@ -const crypto = require('crypto'); const cfg = require('../../../lib/config'); const jwt = require('../../../lib/jwt'); async function login (req, res, next) { if (req.body) { const {user, password} = req.body; - if (user && password) { - const hash = crypto - .pbkdf2Sync(password, 'Dougal'+user, 10712, 48, 'sha512') - .toString('base64'); - for (const credentials of cfg._("global.users.login.user") || []) { - if (credentials.name == user && credentials.hash == hash) { - const payload = Object.assign({}, credentials); - delete payload.hash; - jwt.issue(payload, req, res); - res.status(204).send(); - next(); - return; - } - } + const payload = jwt.checkValidCredentials({user, password}); + if (payload) { + jwt.issue(payload, req, res); + res.status(204).send(); + next(); + return; + } else { next({status: 401, message: "Unauthorised"}); } + } else { + next({status: 400, message: "Bad request"}); } - next({status: 400, message: "Bad request"}); } module.exports = login; diff --git a/lib/www/server/lib/jwt.js b/lib/www/server/lib/jwt.js index 1824507..423cac8 100644 --- a/lib/www/server/lib/jwt.js +++ b/lib/www/server/lib/jwt.js @@ -1,9 +1,37 @@ -const jwt = require('jsonwebtoken'); +const crypto = require('crypto'); +const JWT = require('jsonwebtoken'); const cfg = require('./config'); + +function checkValidCredentials ({user, password, jwt}) { + if (jwt) { + try { + const decoded = JWT.verify(jwt, cfg.jwt.secret, {maxAge: "1d"}); + delete decoded.iat; + delete decoded.exp; + return decoded; + } catch (err) { + console.warn("Failed to verify credentials for", jwt); + console.warn(err); + return; // Invalid JWT + } + } else if (user && password) { + const hash = crypto + .pbkdf2Sync(password, 'Dougal'+user, 10712, 48, 'sha512') + .toString('base64'); + for (const credentials of cfg._("global.users.login.user") || []) { + if (credentials.name == user && credentials.hash == hash) { + const payload = {...credentials}; + delete payload.hash; + return payload; + } + } + } +} + function issue (payload, req, res) { - const token = jwt.sign(payload, cfg.jwt.secret, cfg.jwt.options); + const token = JWT.sign(payload, cfg.jwt.secret, cfg.jwt.options); if (req) { req.user = payload; @@ -17,5 +45,6 @@ function issue (payload, req, res) { } module.exports = { + checkValidCredentials, issue };