retropilot-server/controllers/authentication.js

105 lines
3.2 KiB
JavaScript

const jwt = require('jsonwebtoken');
let logger;
const models_orm = require('./../models/index.model')
const crypto = require('crypto');
const config = require('./../config')
async function validateJWT(token, key) {
try {
return jwt.verify(token.replace("JWT ", ""), key, {algorithms: ['RS256'], ignoreNotBefore: true});
} catch (exception) {
console.log(`failed to validate JWT ${exception}`)
}
return null;
}
async function readJWT(token) {
try {
return jwt.decode(token);
} catch (exception) {
logger.warn(`failed to read JWT ${exception}`)
}
return null;
}
async function signIn(email, password) {
let account = await models_orm.models.accounts.findOne({where: {email: email}});
if (account.dataValues) {
account = account.dataValues;
const inputPassword = crypto.createHash('sha256').update(password + config.applicationSalt).digest('hex');
if (account.password === inputPassword) {
const token = jwt.sign({accountId: account.id}, config.applicationSalt)
return {success: true, jwt: token};
} else {
return {success: false, msg: 'BAD PASSWORD', invalidPassword: true}
}
} else {
return {success: false, msg: 'BAD ACCOUNT', badAccount: true}
}
}
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}
}
}
/*
TODO: update rest of the code to support authentication rejection reasons
*/
async function getAuthenticatedAccount(req, res) {
const sessionJWT = (req.signedCookies !== undefined ? req.signedCookies.jwt : null)
if ((!sessionJWT || sessionJWT.expires <= Date.now())) { return null; }
const token = jwt.verify(sessionJWT, config.applicationSalt);
if (token && token.accountId) {
const account = await models_orm.models.accounts.findOne({where: {id: token.accountId}});
if (account.dataValues) {
const update = models_orm.models.accounts.update({ last_ping: Date.now() },
{ where: { id: account.id } }
)
if (!account || account.banned) {
return null; // {success: false, isBanned: true}
}
return account;
} else {
return null; // {success: false, isInvalid: true}
}
} else {
return null; // {success: false, badToken: true}
}
return null;
}
module.exports = {
validateJWT: validateJWT,
getAuthenticatedAccount: getAuthenticatedAccount,
changePassword: changePassword,
signIn: signIn,
readJWT: readJWT
}