From 7590e9b64473d8a0e59fdba072262f7e0efee517 Mon Sep 17 00:00:00 2001 From: AdamSBlack Date: Sun, 3 Oct 2021 15:35:44 +0100 Subject: [PATCH] userAdminApi now allows users to change their password --- controllers/authentication.js | 24 ++++++++++--- routes/index.js | 2 +- routes/userAdminApi.js | 64 +++++++++++++++++------------------ server.js | 4 +-- 4 files changed, 55 insertions(+), 39 deletions(-) diff --git a/controllers/authentication.js b/controllers/authentication.js index fc105b4..a83bc37 100644 --- a/controllers/authentication.js +++ b/controllers/authentication.js @@ -2,7 +2,8 @@ const jwt = require('jsonwebtoken'); let models; let logger; const models_orm = require('./../models/index.model') - +const crypto = require('crypto'); +const config = require('./../config') async function validateJWT(token, key) { try { @@ -23,15 +24,29 @@ async function readJWT(token) { } +async function changePassword(account, newPassword, oldPassword) { + if (!account || !newPassword || !oldPassword) { return {success: false, error: 'MISSING_DATA'}} + const oldPasswordHash = crypto.createHash('sha256').update(oldPassword + config.applicationSalt).digest('hex') + if (account.password === oldPasswordHash) { + const newPasswordHash = crypto.createHash('sha256').update(newPassword + config.applicationSalt).digest('hex') + + const update = models_orm.models.accounts.update( + { password: newPasswordHash }, + { where: { id: account.id } } + ) + + return {success: true, msg: 'PASSWORD CHANGED', changed: true} + } else { + return {success: false, msg: 'BAD PASSWORD', passwordCorrect: false} + } +} async function getAuthenticatedAccount(req, res) { const sessionCookie = (req.signedCookies !== undefined ? req.signedCookies.session : null); if (!sessionCookie || sessionCookie.expires <= Date.now()) { return null; } const email = sessionCookie.account.trim().toLowerCase(); - - // TODO stop storing emails in the cookie const account = await models_orm.models.accounts.findOne({where: {email: email}}); @@ -59,6 +74,7 @@ module.exports = (_models, _logger) => { return { validateJWT: validateJWT, - getAuthenticatedAccount: getAuthenticatedAccount + getAuthenticatedAccount: getAuthenticatedAccount, + changePassword: changePassword } } diff --git a/routes/index.js b/routes/index.js index fcb16fa..665427d 100644 --- a/routes/index.js +++ b/routes/index.js @@ -6,7 +6,7 @@ module.exports = (_models, _controllers, _logger) => { return { useradmin: require('./useradmin')(_models, _controllers, _logger), api: require('./api')(_models, _controllers, _logger), - //useradminapi: require('./userAdminApi')(_models, _controllers, _logger) + useradminapi: require('./userAdminApi')(_models, _controllers, _logger) //adminApi: require('./administration/adminApi')(_models, _controllers, _logger) } } \ No newline at end of file diff --git a/routes/userAdminApi.js b/routes/userAdminApi.js index c876035..190e230 100644 --- a/routes/userAdminApi.js +++ b/routes/userAdminApi.js @@ -222,7 +222,7 @@ router.get('/retropilot/0/overview', runAsyncWrapper(async (req, res) => { })) -router.get('/useradmin/unpair_device/:dongleId', runAsyncWrapper(async (req, res) => { +router.get('/retropilot/0/unpair_device/:dongleId', runAsyncWrapper(async (req, res) => { const account = await controllers.authentication.getAuthenticatedAccount(req, res); if (account == null) { return res.json({success: false, data: {session: false}}).status(403) @@ -243,39 +243,39 @@ router.get('/useradmin/unpair_device/:dongleId', runAsyncWrapper(async (req, res res.json({success: true, data: {unlink: true}}) })) +router.post('/retropilot/0/pair_device', bodyParser.urlencoded({extended: true}), runAsyncWrapper(async (req, res) => { + const account = await controllers.authentication.getAuthenticatedAccount(req, res); + if (account == null) { + res.json({success: false, msg: 'UNAUTHORISED', status: 403}) + } + + const pairDevice = await controllers.devices.pairDevice(req.body.qr_string); + + if (pairDevice.success === true) { + res.json({success: true, msg: 'Paired', status: 200, data: pairDevice}) + } else { + res.json({success: false, msg:'error', data: pairDevice}) + } +})) + + +router.post('/retropilot/0/password/change', bodyParser.urlencoded({extended: true}), runAsyncWrapper(async (req, res) => { + const account = await controllers.authentication.getAuthenticatedAccount(req, res); + if (account == null) { + res.json({success: false, msg: 'UNAUTHORISED', status: 403}) + } + + const pwChange = await controllers.authentication.changePassword(account, req.body.newPassword, req.body.oldPassword); + + if (pwChange.success === true) { + res.json({success: true}) + } else { + res.json({success: false, data: pwChange}); + } +})); + /* - router.post('/useradmin/pair_device', bodyParser.urlencoded({extended: true}), runAsyncWrapper(async (req, res) => { - const account = await controllers.authentication.getAuthenticatedAccount(req, res); - if (account == null) { - res.redirect('/useradmin?status=' + encodeURIComponent('Invalid or expired session')); - return; - } - - var qrCodeParts = req.body.qr_string.split("--"); // imei, serial, jwtToken - - const device = await models.__db.get('SELECT * FROM devices WHERE imei = ? AND serial = ?', qrCodeParts[0], qrCodeParts[1]); - if (device == null) { - res.redirect('/useradmin/overview?linkstatus=' + encodeURIComponent('Device not registered on Server')); - } - var decoded = controllers.authentication.validateJWT(qrCodeParts[2], device.public_key); - if (decoded == null || decoded.pair == undefined) { - res.redirect('/useradmin/overview?linkstatus=' + encodeURIComponent('Device QR Token is invalid or has expired')); - } - if (device.account_id != 0) { - res.redirect('/useradmin/overview?linkstatus=' + encodeURIComponent('Device is already paired, unpair in that account first')); - } - - const result = await models.__db.run( - 'UPDATE devices SET account_id = ? WHERE dongle_id = ?', - account.id, - device.dongle_id - ); - - res.redirect('/useradmin/overview'); - })) - - router.get('/useradmin/device/:dongleId', runAsyncWrapper(async (req, res) => { const account = await controllers.authentication.getAuthenticatedAccount(req, res); if (account == null) { diff --git a/server.js b/server.js index fe030f1..8731f0f 100644 --- a/server.js +++ b/server.js @@ -57,8 +57,8 @@ const web = async () => { app.use(routers.api); app.use(routers.useradmin); - if (config.flags.useUserAdminApi) app.use(routers.useradminapi); - //app.use(routers.adminApi) + //if (config.flags.useUserAdminApi) app.use(routers.useradminapi); + app.use(routers.useradminapi) app.use(cors());