mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-03-11 02:12:21 -05:00
User edit & add endpoints cleanup
- edit and add endpoints don't assume role - edit and add endpoints cope with no role, role objects, and strings - resend user invite was failing at one point due to no role being sent, but this shouldn't be required - other random api cleanup
This commit is contained in:
parent
cc995e8ef6
commit
eecbdc1693
6 changed files with 237 additions and 165 deletions
|
@ -46,27 +46,22 @@ authentication = {
|
||||||
return dataProvider.User.generateResetToken(email, expires, dbHash);
|
return dataProvider.User.generateResetToken(email, expires, dbHash);
|
||||||
}).then(function (resetToken) {
|
}).then(function (resetToken) {
|
||||||
var baseUrl = config.forceAdminSSL ? (config.urlSSL || config.url) : config.url,
|
var baseUrl = config.forceAdminSSL ? (config.urlSSL || config.url) : config.url,
|
||||||
resetUrl = baseUrl.replace(/\/$/, '') + '/ghost/reset/' + resetToken + '/',
|
resetUrl = baseUrl.replace(/\/$/, '') + '/ghost/reset/' + resetToken + '/';
|
||||||
emailData = {
|
|
||||||
resetUrl: resetUrl
|
|
||||||
};
|
|
||||||
|
|
||||||
return emailData;
|
return mail.generateContent({data: { resetUrl: resetUrl }, template: 'reset-password'});
|
||||||
}).then(function (emailData) {
|
}).then(function (emailContent) {
|
||||||
return mail.generateContent({data: emailData, template: 'reset-password'}).then(function (emailContent) {
|
var payload = {
|
||||||
var payload = {
|
mail: [{
|
||||||
mail: [{
|
message: {
|
||||||
message: {
|
to: email,
|
||||||
to: email,
|
subject: 'Reset Password',
|
||||||
subject: 'Reset Password',
|
html: emailContent.html,
|
||||||
html: emailContent.html,
|
text: emailContent.text
|
||||||
text: emailContent.text
|
},
|
||||||
},
|
options: {}
|
||||||
options: {}
|
}]
|
||||||
}]
|
};
|
||||||
};
|
return mail.send(payload, {context: {internal: true}});
|
||||||
return mail.send(payload, {context: {internal: true}});
|
|
||||||
});
|
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
return when.resolve({passwordreset: [{message: 'Check your email for further instructions.'}]});
|
return when.resolve({passwordreset: [{message: 'Check your email for further instructions.'}]});
|
||||||
}).otherwise(function (error) {
|
}).otherwise(function (error) {
|
||||||
|
@ -219,29 +214,27 @@ authentication = {
|
||||||
ownerEmail: setupUser.email
|
ownerEmail: setupUser.email
|
||||||
};
|
};
|
||||||
|
|
||||||
return mail.generateContent({data: data, template: 'welcome'}).then(function (emailContent) {
|
return mail.generateContent({data: data, template: 'welcome'});
|
||||||
var message = {
|
}).then(function (emailContent) {
|
||||||
to: setupUser.email,
|
var message = {
|
||||||
subject: 'Your New Ghost Blog',
|
to: setupUser.email,
|
||||||
html: emailContent.html,
|
subject: 'Your New Ghost Blog',
|
||||||
text: emailContent.text
|
html: emailContent.html,
|
||||||
},
|
text: emailContent.text
|
||||||
payload = {
|
},
|
||||||
mail: [{
|
payload = {
|
||||||
message: message,
|
mail: [{
|
||||||
options: {}
|
message: message,
|
||||||
}]
|
options: {}
|
||||||
};
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
return payload;
|
return mail.send(payload, {context: {internal: true}}).otherwise(function (error) {
|
||||||
}).then(function (payload) {
|
errors.logError(
|
||||||
return mail.send(payload, {context: {internal: true}}).otherwise(function (error) {
|
error.message,
|
||||||
errors.logError(
|
"Unable to send welcome email, your blog will continue to function.",
|
||||||
error.message,
|
"Please see http://docs.ghost.org/mail/ for instructions on configuring email."
|
||||||
"Unable to send welcome email, your blog will continue to function.",
|
);
|
||||||
"Please see http://docs.ghost.org/mail/ for instructions on configuring email."
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
|
|
|
@ -195,17 +195,16 @@ settingsResult = function (settings, type) {
|
||||||
populateDefaultSetting = function (key) {
|
populateDefaultSetting = function (key) {
|
||||||
// Call populateDefault and update the settings cache
|
// Call populateDefault and update the settings cache
|
||||||
return dataProvider.Settings.populateDefault(key).then(function (defaultSetting) {
|
return dataProvider.Settings.populateDefault(key).then(function (defaultSetting) {
|
||||||
|
|
||||||
// Process the default result and add to settings cache
|
// Process the default result and add to settings cache
|
||||||
var readResult = readSettingsResult([defaultSetting]);
|
var readResult = readSettingsResult([defaultSetting]);
|
||||||
|
|
||||||
// Add to the settings cache
|
// Add to the settings cache
|
||||||
return updateSettingsCache(readResult).then(function () {
|
return updateSettingsCache(readResult).then(function () {
|
||||||
// Update theme with the new settings
|
// Try to update theme with the new settings
|
||||||
return config.theme.update(settings, config.url);
|
// if we're in the middle of populating, this might not work
|
||||||
|
return config.theme.update(settings, config.url).then(function () { return; }, function () { return; });
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
// Get the result from the cache with permission checks
|
// Get the result from the cache with permission checks
|
||||||
return defaultSetting;
|
|
||||||
});
|
});
|
||||||
}).otherwise(function (err) {
|
}).otherwise(function (err) {
|
||||||
// Pass along NotFoundError
|
// Pass along NotFoundError
|
||||||
|
|
|
@ -14,7 +14,8 @@ var when = require('when'),
|
||||||
docName = 'users',
|
docName = 'users',
|
||||||
// TODO: implement created_by, updated_by
|
// TODO: implement created_by, updated_by
|
||||||
allowedIncludes = ['permissions', 'roles', 'roles.permissions'],
|
allowedIncludes = ['permissions', 'roles', 'roles.permissions'],
|
||||||
users;
|
users,
|
||||||
|
sendInviteEmail;
|
||||||
|
|
||||||
// ## Helpers
|
// ## Helpers
|
||||||
function prepareInclude(include) {
|
function prepareInclude(include) {
|
||||||
|
@ -22,6 +23,48 @@ function prepareInclude(include) {
|
||||||
return include;
|
return include;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sendInviteEmail = function sendInviteEmail(user) {
|
||||||
|
var emailData;
|
||||||
|
|
||||||
|
return when.join(
|
||||||
|
users.read({'id': user.created_by}),
|
||||||
|
settings.read({'key': 'title'}),
|
||||||
|
settings.read({context: {internal: true}, key: 'dbHash'})
|
||||||
|
).then(function (values) {
|
||||||
|
var invitedBy = values[0].users[0],
|
||||||
|
blogTitle = values[1].settings[0].value,
|
||||||
|
expires = Date.now() + (14 * globalUtils.ONE_DAY_MS),
|
||||||
|
dbHash = values[2].settings[0].value;
|
||||||
|
|
||||||
|
emailData = {
|
||||||
|
blogName: blogTitle,
|
||||||
|
invitedByName: invitedBy.name,
|
||||||
|
invitedByEmail: invitedBy.email
|
||||||
|
};
|
||||||
|
|
||||||
|
return dataProvider.User.generateResetToken(user.email, expires, dbHash);
|
||||||
|
}).then(function (resetToken) {
|
||||||
|
var baseUrl = config.forceAdminSSL ? (config.urlSSL || config.url) : config.url;
|
||||||
|
|
||||||
|
emailData.resetLink = baseUrl.replace(/\/$/, '') + '/ghost/signup/' + resetToken + '/';
|
||||||
|
|
||||||
|
return mail.generateContent({data: emailData, template: 'invite-user'});
|
||||||
|
}).then(function (emailContent) {
|
||||||
|
var payload = {
|
||||||
|
mail: [{
|
||||||
|
message: {
|
||||||
|
to: user.email,
|
||||||
|
subject: emailData.invitedByName + ' has invited you to join ' + emailData.blogName,
|
||||||
|
html: emailContent.html,
|
||||||
|
text: emailContent.text
|
||||||
|
},
|
||||||
|
options: {}
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
return mail.send(payload, {context: {internal: true}});
|
||||||
|
});
|
||||||
|
};
|
||||||
/**
|
/**
|
||||||
* ## Posts API Methods
|
* ## Posts API Methods
|
||||||
*
|
*
|
||||||
|
@ -43,7 +86,7 @@ users = {
|
||||||
}
|
}
|
||||||
return dataProvider.User.findPage(options);
|
return dataProvider.User.findPage(options);
|
||||||
}).catch(function (error) {
|
}).catch(function (error) {
|
||||||
return errors.handleAPIError(error);
|
return errors.handleAPIError(error, 'You do not have permission to browse users.');
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -106,20 +149,32 @@ users = {
|
||||||
|
|
||||||
// Check permissions
|
// Check permissions
|
||||||
return canThis(options.context).edit.user(options.id).then(function () {
|
return canThis(options.context).edit.user(options.id).then(function () {
|
||||||
if (data.users[0].roles) {
|
if (data.users[0].roles && data.users[0].roles[0]) {
|
||||||
if (options.id === options.context.user) {
|
var role = data.users[0].roles[0],
|
||||||
return when.reject(new errors.NoPermissionError('You cannot change your own role.'));
|
roleId = parseInt(role.id || role, 10);
|
||||||
}
|
|
||||||
return canThis(options.context).assign.role(data.users[0].roles[0]).then(function () {
|
return dataProvider.User.findOne(
|
||||||
|
{id: options.context.user, include: 'roles'}
|
||||||
|
).then(function (contextUser) {
|
||||||
|
var contextRoleId = contextUser.related('roles').toJSON()[0].id;
|
||||||
|
|
||||||
|
if (roleId !== contextRoleId &&
|
||||||
|
parseInt(options.id, 10) === parseInt(options.context.user, 10)) {
|
||||||
|
return when.reject(new errors.NoPermissionError('You cannot change your own role.'));
|
||||||
|
} else if (roleId !== contextRoleId) {
|
||||||
|
return canThis(options.context).assign.role(role).then(function () {
|
||||||
|
return editOperation();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return editOperation();
|
return editOperation();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return editOperation();
|
return editOperation();
|
||||||
|
|
||||||
});
|
});
|
||||||
}).catch(function (error) {
|
}).catch(function (error) {
|
||||||
return errors.handleAPIError(error);
|
return errors.handleAPIError(error, 'You do not have permission to edit this user');
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -130,119 +185,92 @@ users = {
|
||||||
* @returns {Promise(User}} Newly created user
|
* @returns {Promise(User}} Newly created user
|
||||||
*/
|
*/
|
||||||
add: function add(object, options) {
|
add: function add(object, options) {
|
||||||
var newUser,
|
var addOperation,
|
||||||
user,
|
newUser,
|
||||||
roleId,
|
user;
|
||||||
emailData;
|
|
||||||
|
|
||||||
return canThis(options.context).add.user(object).then(function () {
|
if (options.include) {
|
||||||
return utils.checkObject(object, docName).then(function (checkedUserData) {
|
options.include = prepareInclude(options.include);
|
||||||
if (options.include) {
|
}
|
||||||
options.include = prepareInclude(options.include);
|
|
||||||
}
|
|
||||||
|
|
||||||
newUser = checkedUserData.users[0];
|
return utils.checkObject(object, docName).then(function (data) {
|
||||||
|
newUser = data.users[0];
|
||||||
|
|
||||||
if (_.isEmpty(newUser.roles)) {
|
addOperation = function () {
|
||||||
return when.reject(new errors.BadRequestError('No role provided.'));
|
if (newUser.email) {
|
||||||
}
|
newUser.name = object.users[0].email.substring(0, newUser.email.indexOf('@'));
|
||||||
|
newUser.password = globalUtils.uid(50);
|
||||||
roleId = parseInt(newUser.roles[0].id || newUser.roles[0], 10);
|
newUser.status = 'invited';
|
||||||
|
|
||||||
// Make sure user is allowed to add a user with this role
|
|
||||||
return dataProvider.Role.findOne({id: roleId}).then(function (role) {
|
|
||||||
if (role.get('name') === 'Owner') {
|
|
||||||
return when.reject(new errors.NoPermissionError('Not allowed to create an owner user.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return canThis(options.context).assign.role(role);
|
|
||||||
}).then(function () {
|
|
||||||
if (newUser.email) {
|
|
||||||
newUser.name = object.users[0].email.substring(0, newUser.email.indexOf('@'));
|
|
||||||
newUser.password = globalUtils.uid(50);
|
|
||||||
newUser.status = 'invited';
|
|
||||||
} else {
|
|
||||||
return when.reject(new errors.BadRequestError('No email provided.'));
|
|
||||||
}
|
|
||||||
}).catch(function () {
|
|
||||||
return when.reject(new errors.NoPermissionError('Not allowed to create user with that role.'));
|
|
||||||
});
|
|
||||||
}).then(function () {
|
|
||||||
return dataProvider.User.getByEmail(newUser.email);
|
|
||||||
}).then(function (foundUser) {
|
|
||||||
if (!foundUser) {
|
|
||||||
return dataProvider.User.add(newUser, options);
|
|
||||||
} else {
|
} else {
|
||||||
// only invitations for already invited users are resent
|
return when.reject(new errors.BadRequestError('No email provided.'));
|
||||||
if (foundUser.get('status') === 'invited' || foundUser.get('status') === 'invited-pending') {
|
}
|
||||||
return foundUser;
|
|
||||||
|
return dataProvider.User.getByEmail(
|
||||||
|
newUser.email
|
||||||
|
).then(function (foundUser) {
|
||||||
|
if (!foundUser) {
|
||||||
|
return dataProvider.User.add(newUser, options);
|
||||||
} else {
|
} else {
|
||||||
return when.reject(new errors.BadRequestError('User is already registered.'));
|
// only invitations for already invited users are resent
|
||||||
}
|
if (foundUser.get('status') === 'invited' || foundUser.get('status') === 'invited-pending') {
|
||||||
}
|
return foundUser;
|
||||||
}).then(function (invitedUser) {
|
} else {
|
||||||
user = invitedUser.toJSON();
|
return when.reject(new errors.BadRequestError('User is already registered.'));
|
||||||
return settings.read({context: {internal: true}, key: 'dbHash'});
|
|
||||||
}).then(function (response) {
|
|
||||||
var expires = Date.now() + (14 * globalUtils.ONE_DAY_MS),
|
|
||||||
dbHash = response.settings[0].value;
|
|
||||||
return dataProvider.User.generateResetToken(user.email, expires, dbHash);
|
|
||||||
}).then(function (resetToken) {
|
|
||||||
return when.join(users.read({'id': user.created_by}), settings.read({'key': 'title'})).then(function (values) {
|
|
||||||
var invitedBy = values[0].users[0],
|
|
||||||
blogTitle = values[1].settings[0].value,
|
|
||||||
baseUrl = config.forceAdminSSL ? (config.urlSSL || config.url) : config.url,
|
|
||||||
resetUrl = baseUrl.replace(/\/$/, '') + '/ghost/signup/' + resetToken + '/';
|
|
||||||
|
|
||||||
emailData = {
|
|
||||||
blogName: blogTitle,
|
|
||||||
invitedByName: invitedBy.name,
|
|
||||||
invitedByEmail: invitedBy.email,
|
|
||||||
resetLink: resetUrl
|
|
||||||
};
|
|
||||||
|
|
||||||
return mail.generateContent({data: emailData, template: 'invite-user'});
|
|
||||||
}).then(function (emailContent) {
|
|
||||||
var payload = {
|
|
||||||
mail: [
|
|
||||||
{
|
|
||||||
message: {
|
|
||||||
to: user.email,
|
|
||||||
subject: emailData.invitedByName + ' has invited you to join ' + emailData.blogName,
|
|
||||||
html: emailContent.html,
|
|
||||||
text: emailContent.text
|
|
||||||
},
|
|
||||||
options: {}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
return mail.send(payload, {context: {internal: true}}).then(function () {
|
|
||||||
// If status was invited-pending and sending the invitation succeeded, set status to invited.
|
|
||||||
if (user.status === 'invited-pending') {
|
|
||||||
return dataProvider.User.edit({status: 'invited'}, {id: user.id}).then(function (editedUser) {
|
|
||||||
user = editedUser.toJSON();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
});
|
}).then(function (invitedUser) {
|
||||||
}).then(function () {
|
user = invitedUser.toJSON();
|
||||||
return when.resolve({users: [user]});
|
return sendInviteEmail(user);
|
||||||
}).catch(function (error) {
|
}).then(function () {
|
||||||
if (error && error.type === 'EmailError') {
|
// If status was invited-pending and sending the invitation succeeded, set status to invited.
|
||||||
error.message = 'Error sending email: ' + error.message + ' Please check your email settings and resend the invitation.';
|
if (user.status === 'invited-pending') {
|
||||||
errors.logWarn(error.message);
|
return dataProvider.User.edit(
|
||||||
|
{status: 'invited'}, _.extend({}, options, {id: user.id})
|
||||||
// If sending the invitation failed, set status to invited-pending
|
).then(function (editedUser) {
|
||||||
return dataProvider.User.edit({status: 'invited-pending'}, {id: user.id}).then(function (user) {
|
console.log('user to return 2', user);
|
||||||
return dataProvider.User.findOne({ id: user.id }, options).then(function (user) {
|
user = editedUser.toJSON();
|
||||||
return { users: [user] };
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
}).then(function () {
|
||||||
|
return when.resolve({users: [user]});
|
||||||
|
}).catch(function (error) {
|
||||||
|
if (error && error.type === 'EmailError') {
|
||||||
|
error.message = 'Error sending email: ' + error.message + ' Please check your email settings and resend the invitation.';
|
||||||
|
errors.logWarn(error.message);
|
||||||
|
|
||||||
|
// If sending the invitation failed, set status to invited-pending
|
||||||
|
return dataProvider.User.edit({status: 'invited-pending'}, {id: user.id}).then(function (user) {
|
||||||
|
return dataProvider.User.findOne({ id: user.id }, options).then(function (user) {
|
||||||
|
return { users: [user] };
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return when.reject(error);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check permissions
|
||||||
|
return canThis(options.context).add.user(object).then(function () {
|
||||||
|
if (newUser.roles && newUser.roles[0]) {
|
||||||
|
var roleId = parseInt(newUser.roles[0].id || newUser.roles[0], 10);
|
||||||
|
|
||||||
|
// Make sure user is allowed to add a user with this role
|
||||||
|
return dataProvider.Role.findOne({id: roleId}).then(function (role) {
|
||||||
|
if (role.get('name') === 'Owner') {
|
||||||
|
return when.reject(new errors.NoPermissionError('Not allowed to create an owner user.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return canThis(options.context).assign.role(role);
|
||||||
|
}).then(function () {
|
||||||
|
return addOperation();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return when.reject(error);
|
|
||||||
|
return addOperation();
|
||||||
});
|
});
|
||||||
|
|
||||||
}).catch(function (error) {
|
}).catch(function (error) {
|
||||||
return errors.handleAPIError(error);
|
return errors.handleAPIError(error, 'You do not have permission to add this user');
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -273,7 +301,7 @@ users = {
|
||||||
return errors.handleAPIError(error);
|
return errors.handleAPIError(error);
|
||||||
});
|
});
|
||||||
}).catch(function (error) {
|
}).catch(function (error) {
|
||||||
return errors.handleAPIError(error);
|
return errors.handleAPIError(error, 'You do not have permission to destroy this user');
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -154,9 +154,11 @@ errors = {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
handleAPIError: function (error) {
|
handleAPIError: function (error, permsMessage) {
|
||||||
if (!error) {
|
if (!error) {
|
||||||
return this.rejectError(new this.NoPermissionError('You do not have permission to perform this action'));
|
return this.rejectError(
|
||||||
|
new this.NoPermissionError(permsMessage || 'You do not have permission to perform this action')
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_.isString(error)) {
|
if (_.isString(error)) {
|
||||||
|
|
|
@ -397,7 +397,8 @@ User = ghostBookshelf.Model.extend({
|
||||||
options.withRelated = _.union([ 'roles' ], options.include);
|
options.withRelated = _.union([ 'roles' ], options.include);
|
||||||
return Role.findOne({name: 'Author'}).then(function (authorRole) {
|
return Role.findOne({name: 'Author'}).then(function (authorRole) {
|
||||||
// Get the role we're going to assign to this user, or the author role if there isn't one
|
// Get the role we're going to assign to this user, or the author role if there isn't one
|
||||||
roles = data.roles || authorRole.id;
|
roles = data.roles || [authorRole.get('id')];
|
||||||
|
|
||||||
// check for too many roles
|
// check for too many roles
|
||||||
if (roles.length > 1) {
|
if (roles.length > 1) {
|
||||||
return when.reject(new errors.ValidationError('Only one role per user is supported at the moment.'));
|
return when.reject(new errors.ValidationError('Only one role per user is supported at the moment.'));
|
||||||
|
@ -424,7 +425,9 @@ User = ghostBookshelf.Model.extend({
|
||||||
userData = addedUser;
|
userData = addedUser;
|
||||||
//if we are given a "role" object, only pass in the role ID in place of the full object
|
//if we are given a "role" object, only pass in the role ID in place of the full object
|
||||||
roles = _.map(roles, function (role) {
|
roles = _.map(roles, function (role) {
|
||||||
if (_.isNumber(role)) {
|
if (_.isString(role)) {
|
||||||
|
return parseInt(role, 10);
|
||||||
|
} else if (_.isNumber(role)) {
|
||||||
return role;
|
return role;
|
||||||
} else {
|
} else {
|
||||||
return parseInt(role.id, 10);
|
return parseInt(role.id, 10);
|
||||||
|
@ -781,12 +784,15 @@ User = ghostBookshelf.Model.extend({
|
||||||
// Get the user by email address, enforces case insensitivity rejects if the user is not found
|
// Get the user by email address, enforces case insensitivity rejects if the user is not found
|
||||||
// When multi-user support is added, email addresses must be deduplicated with case insensitivity, so that
|
// When multi-user support is added, email addresses must be deduplicated with case insensitivity, so that
|
||||||
// joe@bloggs.com and JOE@BLOGGS.COM cannot be created as two separate users.
|
// joe@bloggs.com and JOE@BLOGGS.COM cannot be created as two separate users.
|
||||||
getByEmail: function (email) {
|
getByEmail: function (email, options) {
|
||||||
|
options = options || {};
|
||||||
// We fetch all users and process them in JS as there is no easy way to make this query across all DBs
|
// We fetch all users and process them in JS as there is no easy way to make this query across all DBs
|
||||||
// Although they all support `lower()`, sqlite can't case transform unicode characters
|
// Although they all support `lower()`, sqlite can't case transform unicode characters
|
||||||
// This is somewhat mute, as validator.isEmail() also doesn't support unicode, but this is much easier / more
|
// This is somewhat mute, as validator.isEmail() also doesn't support unicode, but this is much easier / more
|
||||||
// likely to be fixed in the near future.
|
// likely to be fixed in the near future.
|
||||||
return Users.forge().fetch({require: true}).then(function (users) {
|
options.require = true;
|
||||||
|
|
||||||
|
return Users.forge(options).fetch(options).then(function (users) {
|
||||||
var userWithEmail = users.find(function (user) {
|
var userWithEmail = users.find(function (user) {
|
||||||
return user.get('email').toLowerCase() === email.toLowerCase();
|
return user.get('email').toLowerCase() === email.toLowerCase();
|
||||||
});
|
});
|
||||||
|
|
|
@ -308,6 +308,26 @@ describe('Users API', function () {
|
||||||
done();
|
done();
|
||||||
}).catch(done);
|
}).catch(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Author can edit self with role set', function (done) {
|
||||||
|
// Next test that author CAN edit self
|
||||||
|
UserAPI.edit(
|
||||||
|
{users: [{name: newName, roles: [roleIdFor.author]}]}, _.extend({}, context.author, {id: userIdFor.author})
|
||||||
|
).then(function (response) {
|
||||||
|
checkEditResponse(response);
|
||||||
|
done();
|
||||||
|
}).catch(done);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Author can edit self with role set as string', function (done) {
|
||||||
|
// Next test that author CAN edit self
|
||||||
|
UserAPI.edit(
|
||||||
|
{users: [{name: newName, roles: [roleIdFor.author.toString()]}]}, _.extend({}, context.author, {id: userIdFor.author})
|
||||||
|
).then(function (response) {
|
||||||
|
checkEditResponse(response);
|
||||||
|
done();
|
||||||
|
}).catch(done);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Add', function () {
|
describe('Add', function () {
|
||||||
|
@ -384,6 +404,30 @@ describe('Users API', function () {
|
||||||
done();
|
done();
|
||||||
}).catch(done);
|
}).catch(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Can add with no role set', function (done) {
|
||||||
|
// Can add author
|
||||||
|
delete newUser.roles;
|
||||||
|
UserAPI.add({users: [newUser]}, _.extend({}, context.owner, {include: 'roles'}))
|
||||||
|
.then(function (response) {
|
||||||
|
checkAddResponse(response);
|
||||||
|
response.users[0].id.should.eql(8);
|
||||||
|
response.users[0].roles[0].name.should.equal('Author');
|
||||||
|
done();
|
||||||
|
}).catch(done);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Can add with role set as string', function (done) {
|
||||||
|
// Can add author
|
||||||
|
newUser.roles = [roleIdFor.author.toString()];
|
||||||
|
UserAPI.add({users: [newUser]}, _.extend({}, context.owner, {include: 'roles'}))
|
||||||
|
.then(function (response) {
|
||||||
|
checkAddResponse(response);
|
||||||
|
response.users[0].id.should.eql(8);
|
||||||
|
response.users[0].roles[0].name.should.equal('Author');
|
||||||
|
done();
|
||||||
|
}).catch(done);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Admin', function () {
|
describe('Admin', function () {
|
||||||
|
@ -485,7 +529,7 @@ describe('Users API', function () {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
describe('Destroy', function () {
|
describe('Destroy', function () {
|
||||||
function checkDestroyResponse(response) {
|
function checkDestroyResponse(response) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue