Files
jambonz-api-server/lib/routes/api/users.js
T
2020-04-01 16:27:18 -04:00

97 lines
3.3 KiB
JavaScript

const router = require('express').Router();
const crypto = require('crypto');
const {getMysqlConnection} = require('../../db');
const retrieveSql = 'SELECT * from users where user_sid = ?';
const updateSql = 'UPDATE users set hashed_password = ?, salt = ?, force_change = false WHERE user_sid = ?';
const tokenSql = 'SELECT token from api_keys where account_sid IS NULL AND service_provider_sid IS NULL';
const genRandomString = (len) => {
return crypto.randomBytes(Math.ceil(len / 2))
.toString('hex') /** convert to hexadecimal format */
.slice(0, len); /** return required number of characters */
};
const sha512 = function(password, salt) {
const hash = crypto.createHmac('sha512', salt); /** Hashing algorithm sha512 */
hash.update(password);
var value = hash.digest('hex');
return {
salt:salt,
passwordHash:value
};
};
const saltHashPassword = (userpassword) => {
var salt = genRandomString(16); /** Gives us salt of length 16 */
return sha512(userpassword, salt);
};
router.put('/:user_sid', (req, res) => {
const logger = req.app.locals.logger;
const {old_password, new_password} = req.body;
if (!old_password || !new_password) {
logger.info('Bad PUT to /Users is missing old_password or new password');
return res.sendStatus(400);
}
getMysqlConnection((err, conn) => {
if (err) {
logger.error({err}, 'Error getting db connection');
return res.sendStatus(500);
}
conn.query(retrieveSql, [req.params.user_sid], (err, results) => {
conn.release();
if (err) {
logger.error({err}, 'Error getting db connection');
return res.sendStatus(500);
}
if (0 === results.length) {
logger.info(`Failed to find user with sid ${req.params.user_sid}`);
return res.sendStatus(404);
}
logger.info({results}, 'successfully retrieved user');
const old_salt = results[0].salt;
const old_hashed_password = results[0].hashed_password;
const {passwordHash} = sha512(old_password, old_salt);
if (old_hashed_password !== passwordHash) return res.sendStatus(403);
getMysqlConnection((err, conn) => {
if (err) {
logger.error({err}, 'Error getting db connection');
return res.sendStatus(500);
}
const {salt, passwordHash} = saltHashPassword(new_password);
conn.query(updateSql, [passwordHash, salt, req.params.user_sid], (err, r) => {
conn.release();
if (err) {
logger.error({err}, 'Error getting db connection');
return res.sendStatus(500);
}
if (0 === r.changedRows) {
logger.error('Failed updating database with new password');
return res.sendStatus(500);
}
conn.query(tokenSql, (err, tokenResults) => {
conn.release();
if (err) {
logger.error({err}, 'Error getting db connection');
return res.sendStatus(500);
}
if (0 === tokenResults.length) {
logger.error('Database has no admin token provisioned...run reset_admin_password');
return res.sendStatus(500);
}
res.json({user_sid: results[0].user_sid, token: tokenResults[0].token});
});
});
});
});
});
});
module.exports = router;