setup account based on directory config

part of #704
This commit is contained in:
Girish Ramakrishnan
2020-07-09 16:39:29 -07:00
parent 0f5b7278b8
commit 3adeed381b
2 changed files with 56 additions and 27 deletions
+7 -21
View File
@@ -124,34 +124,20 @@ function setupAccount(req, res, next) {
if (!req.body.resetToken || typeof req.body.resetToken !== 'string') return next(new HttpError(400, 'resetToken must be a non-empty string'));
if (!req.body.password || typeof req.body.password !== 'string') return next(new HttpError(400, 'password must be a non-empty string'));
if (!req.body.username || typeof req.body.username !== 'string') return next(new HttpError(400, 'username must be a non-empty string'));
if (!req.body.displayName || typeof req.body.displayName !== 'string') return next(new HttpError(400, 'displayName must be a non-empty string'));
// only sent if profile is not locked
if ('username' in req.body && typeof req.body.username !== 'string') return next(new HttpError(400, 'username must be a non-empty string'));
if ('displayName' in req.body && typeof req.body.displayName !== 'string') return next(new HttpError(400, 'displayName must be a non-empty string'));
users.getByResetToken(req.body.resetToken, function (error, userObject) {
if (error) return next(new HttpError(401, 'Invalid Reset Token'));
if (Date.now() - userObject.resetTokenCreationTime > 24 * 60 * 60 * 1000) return next(new HttpError(401, 'Token expired'));
users.update(userObject, { username: req.body.username, displayName: req.body.displayName }, auditSource.fromRequest(req), function (error) {
if (error && error.reason === BoxError.ALREADY_EXISTS) return next(new HttpError(409, 'Username already used'));
if (error && error.reason === BoxError.BAD_FIELD) return next(new HttpError(400, error.message));
if (error && error.reason === BoxError.NOT_FOUND) return next(new HttpError(404, 'No such user'));
if (error) return next(new HttpError(500, error));
users.setupAccount(userObject, req.body, auditSource.fromRequest(req), function (error, accessToken) {
if (error) return next(BoxError.toHttpError(error));
userObject.username = req.body.username;
userObject.displayName = req.body.displayName;
// setPassword clears the resetToken
users.setPassword(userObject, req.body.password, function (error) {
if (error && error.reason === BoxError.BAD_FIELD) return next(new HttpError(400, error.message));
if (error) return next(new HttpError(500, error));
tokens.add(tokens.ID_WEBADMIN, userObject.id, Date.now() + constants.DEFAULT_TOKEN_EXPIRATION, {}, function (error, result) {
if (error) return next(new HttpError(500, error));
next(new HttpSuccess(201, { accessToken: result.accessToken }));
});
});
next(new HttpSuccess(201, { accessToken }));
});
});
}
+49 -6
View File
@@ -29,6 +29,8 @@ exports = module.exports = {
sendPasswordResetByIdentifier: sendPasswordResetByIdentifier,
setupAccount,
count: count,
AP_MAIL: 'mail',
@@ -63,6 +65,7 @@ let assert = require('assert'),
safe = require('safetydance'),
settings = require('./settings.js'),
speakeasy = require('speakeasy'),
tokens = require('./tokens.js'),
userdb = require('./userdb.js'),
uuid = require('uuid'),
validator = require('validator'),
@@ -566,11 +569,12 @@ function getOwner(callback) {
});
}
function inviteLink(user) {
function inviteLink(user, directoryConfig) {
let link = `${settings.adminOrigin()}/setupaccount.html?resetToken=${user.resetToken}&email=${encodeURIComponent(user.email)}`;
if (user.username) link += `&username=${encodeURIComponent(user.username)}`;
if (user.displayName) link += `&displayName=${encodeURIComponent(user.displayName)}`;
if (directoryConfig.lockUserProfiles) link += '&profileLocked=true';
return link;
}
@@ -583,11 +587,16 @@ function createInvite(user, callback) {
const resetToken = hat(256), resetTokenCreationTime = new Date();
userdb.update(user.id, { resetToken, resetTokenCreationTime }, function (error) {
settings.getDirectoryConfig(function (error, directoryConfig) {
if (error) return callback(error);
user.resetToken = resetToken;
callback(null, { resetToken, inviteLink: inviteLink(user) });
userdb.update(user.id, { resetToken, resetTokenCreationTime }, function (error) {
if (error) return callback(error);
user.resetToken = resetToken;
callback(null, { resetToken, inviteLink: inviteLink(user, directoryConfig) });
});
});
}
@@ -599,9 +608,43 @@ function sendInvite(user, options, callback) {
if (user.source) return callback(new BoxError(BoxError.CONFLICT, 'User is from an external directory'));
if (!user.resetToken) return callback(new BoxError(BoxError.CONFLICT, 'Must generate resetToken to send invitation'));
mailer.sendInvite(user, options.invitor || null, inviteLink(user));
settings.getDirectoryConfig(function (error, directoryConfig) {
if (error) return callback(error);
callback(null);
mailer.sendInvite(user, options.invitor || null, inviteLink(user, directoryConfig));
callback(null);
});
}
function setupAccount(user, data, auditSource, callback) {
assert.strictEqual(typeof user, 'object');
assert.strictEqual(typeof data, 'object');
assert(auditSource && typeof auditSource === 'object');
assert.strictEqual(typeof callback, 'function');
settings.getDirectoryConfig(function (error, directoryConfig) {
if (error) return callback(error);
const updateFunc = (done) => {
if (directoryConfig.lockUserProfiles) return done();
update(user, _.pick(data, 'username', 'displayName'), auditSource, done);
};
updateFunc(function (error) {
if (error) return callback(error);
setPassword(user, data.password, function (error) { // setPassword clears the resetToken
if (error) return callback(error);
tokens.add(tokens.ID_WEBADMIN, user.id, Date.now() + constants.DEFAULT_TOKEN_EXPIRATION, {}, function (error, result) {
if (error) return callback(error);
callback(null, result.accessToken);
});
});
});
});
}
function setTwoFactorAuthenticationSecret(userId, callback) {