async'ify avatar and apppassword code

This commit is contained in:
Girish Ramakrishnan
2021-06-25 22:11:17 -07:00
parent 31d742fa67
commit 147c8df6e3
11 changed files with 385 additions and 354 deletions

View File

@@ -47,19 +47,16 @@ exports = module.exports = {
ROLE_USER_MANAGER: 'usermanager',
ROLE_OWNER: 'owner',
compareRoles,
getAppPasswords,
getAppPassword,
addAppPassword,
delAppPassword
};
const ORDERED_ROLES = [ exports.ROLE_USER, exports.ROLE_USER_MANAGER, exports.ROLE_ADMIN, exports.ROLE_OWNER ];
const assert = require('assert'),
const appPasswords = require('./apppasswords.js'),
assert = require('assert'),
BoxError = require('./boxerror.js'),
crypto = require('crypto'),
constants = require('./constants.js'),
database = require('./database.js'),
debug = require('debug')('box:user'),
eventlog = require('./eventlog.js'),
externalLdap = require('./externalldap.js'),
@@ -79,10 +76,10 @@ const assert = require('assert'),
validator = require('validator'),
_ = require('underscore');
var CRYPTO_SALT_SIZE = 64; // 512-bit salt
var CRYPTO_ITERATIONS = 10000; // iterations
var CRYPTO_KEY_LENGTH = 512; // bits
var CRYPTO_DIGEST = 'sha1'; // used to be the default in node 4.1.1 cannot change since it will affect existing db records
const CRYPTO_SALT_SIZE = 64; // 512-bit salt
const CRYPTO_ITERATIONS = 10000; // iterations
const CRYPTO_KEY_LENGTH = 512; // bits
const CRYPTO_DIGEST = 'sha1'; // used to be the default in node 4.1.1 cannot change since it will affect existing db records
// keep this in sync with validateGroupname and validateAlias
function validateUsername(username) {
@@ -230,22 +227,21 @@ function verifyGhost(username, password) {
return false;
}
function verifyAppPassword(userId, password, identifier, callback) {
async function verifyAppPassword(userId, password, identifier, callback) {
assert.strictEqual(typeof userId, 'string');
assert.strictEqual(typeof password, 'string');
assert.strictEqual(typeof identifier, 'string');
assert.strictEqual(typeof callback, 'function');
userdb.getAppPasswords(userId, function (error, results) {
if (error) return callback(error);
const [error, results] = await safe(appPasswords.list(userId));
if (error) return callback(error);
const hashedPasswords = results.filter(r => r.identifier === identifier).map(r => r.hashedPassword);
let hash = crypto.createHash('sha256').update(password).digest('base64');
const hashedPasswords = results.filter(r => r.identifier === identifier).map(r => r.hashedPassword);
let hash = crypto.createHash('sha256').update(password).digest('base64');
if (hashedPasswords.includes(hash)) return callback(null);
if (hashedPasswords.includes(hash)) return callback(null);
return callback(new BoxError(BoxError.INVALID_CREDENTIALS));
});
return callback(new BoxError(BoxError.INVALID_CREDENTIALS));
}
function verify(userId, password, identifier, callback) {
@@ -784,108 +780,29 @@ function compareRoles(role1, role2) {
return roleInt1 - roleInt2;
}
function validateAppPasswordName(name) {
assert.strictEqual(typeof name, 'string');
if (name.length < 1) return new BoxError(BoxError.BAD_FIELD, 'name must be atleast 1 char');
if (name.length >= 200) return new BoxError(BoxError.BAD_FIELD, 'name too long');
return null;
}
function getAppPassword(id, callback) {
assert.strictEqual(typeof id, 'string');
assert.strictEqual(typeof callback, 'function');
userdb.getAppPassword(id, function (error, result) {
if (error) return callback(error);
callback(null, _.omit(result, 'hashedPassword'));
});
}
function addAppPassword(userId, identifier, name, callback) {
assert.strictEqual(typeof userId, 'string');
assert.strictEqual(typeof identifier, 'string');
assert.strictEqual(typeof name, 'string');
assert.strictEqual(typeof callback, 'function');
let error = validateAppPasswordName(name);
if (error) return callback(error);
if (identifier.length < 1) return callback(new BoxError(BoxError.BAD_FIELD, 'identifier must be atleast 1 char'));
const password = hat(16 * 4);
const hashedPassword = crypto.createHash('sha256').update(password).digest('base64');
var appPassword = {
id: 'uid-' + uuid.v4(),
name,
userId,
identifier,
password,
hashedPassword
};
userdb.addAppPassword(appPassword.id, appPassword, function (error) {
if (error) return callback(error);
callback(null, _.omit(appPassword, 'hashedPassword'));
});
}
function getAppPasswords(userId, callback) {
assert.strictEqual(typeof userId, 'string');
assert.strictEqual(typeof callback, 'function');
userdb.getAppPasswords(userId, function (error, results) {
if (error) return callback(error);
results.map(r => delete r.hashedPassword);
callback(null, results);
});
}
function delAppPassword(id, callback) {
assert.strictEqual(typeof id, 'string');
assert.strictEqual(typeof callback, 'function');
userdb.delAppPassword(id, function (error) {
if (error) return callback(error);
callback(null);
});
}
function getAvatarUrl(user, callback) {
async function getAvatarUrl(user) {
assert.strictEqual(typeof user, 'object');
assert.strictEqual(typeof callback, 'function');
userdb.getAvatar(user.id, function (error, avatar) {
if (error) return callback(error);
if (avatar) return callback(null, `${settings.dashboardOrigin()}/api/v1/profile/avatar/${user.id}`);
const result = await database.query('SELECT avatar FROM users WHERE id = ?', [ user.id ]);
if (result.length === 0) return null;
if (result[0].avatar) return `${settings.dashboardOrigin()}/api/v1/profile/avatar/${user.id}`;
const emailHash = require('crypto').createHash('md5').update(user.email).digest('hex');
return callback(null, `https://www.gravatar.com/avatar/${emailHash}.jpg`);
});
const emailHash = require('crypto').createHash('md5').update(user.email).digest('hex');
return `https://www.gravatar.com/avatar/${emailHash}.jpg`;
}
function getAvatar(id, callback) {
async function getAvatar(id) {
assert.strictEqual(typeof id, 'string');
assert.strictEqual(typeof callback, 'function');
userdb.getAvatar(id, function (error, avatar) {
if (error) return callback(error);
return callback(null, avatar);
});
const result = await database.query('SELECT avatar FROM users WHERE id = ?', [ id ]);
if (result.length === 0) return null;
return result[0].avatar;
}
function setAvatar(id, avatar, callback) {
async function setAvatar(id, avatar) {
assert.strictEqual(typeof id, 'string');
assert(avatar === null || Buffer.isBuffer(avatar));
assert.strictEqual(typeof callback, 'function');
userdb.setAvatar(id, avatar, callback);
const result = await database.query('UPDATE users SET avatar=? WHERE id = ?', [ avatar, id ]);
if (result.length === 0) throw new BoxError(BoxError.NOT_FOUND, 'User not found');
}