Skip to content

Commit

Permalink
Merge pull request #9719 from RocketChat/fix-rest-api-verified-email-…
Browse files Browse the repository at this point in the history
…update

[FIX] Verified property of user is always set to false if not supplied
  • Loading branch information
rodrigok authored Mar 9, 2018
2 parents d173ba2 + b7259fc commit e571e76
Show file tree
Hide file tree
Showing 4 changed files with 277 additions and 30 deletions.
29 changes: 28 additions & 1 deletion packages/rocketchat-api/server/v1/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -260,14 +260,41 @@ RocketChat.API.v1.addRoute('users.update', { authRequired: true }, {
}
});

RocketChat.API.v1.addRoute('users.updateOwnBasicInfo', { authRequired: true }, {
post() {
check(this.bodyParams, {
data: Match.ObjectIncluding({
email: Match.Maybe(String),
name: Match.Maybe(String),
username: Match.Maybe(String),
currentPassword: Match.Maybe(String),
newPassword: Match.Maybe(String)
}),
customFields: Match.Maybe(Object)
});

const userData = {
email: this.bodyParams.data.email,
realname: this.bodyParams.data.name,
username: this.bodyParams.data.username,
newPassword: this.bodyParams.data.newPassword,
typedPassword: this.bodyParams.data.currentPassword
};

Meteor.runAsUser(this.userId, () => Meteor.call('saveUserProfile', userData, this.bodyParams.customFields));

return RocketChat.API.v1.success({ user: RocketChat.models.Users.findOneById(this.userId, { fields: RocketChat.API.v1.defaultFieldsToExclude }) });
}
});

RocketChat.API.v1.addRoute('users.createToken', { authRequired: true }, {
post() {
const user = this.getUserFromParams();
let data;
Meteor.runAsUser(this.userId, () => {
data = Meteor.call('createToken', user._id);
});
return data ? RocketChat.API.v1.success({data}) : RocketChat.API.v1.unauthorized();
return data ? RocketChat.API.v1.success({ data }) : RocketChat.API.v1.unauthorized();
}
});

Expand Down
71 changes: 54 additions & 17 deletions packages/rocketchat-lib/server/functions/saveUser.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,45 @@ RocketChat.saveUser = function(userId, userData) {
const existingRoles = _.pluck(RocketChat.authz.getRoles(), '_id');

if (userData._id && userId !== userData._id && !RocketChat.authz.hasPermission(userId, 'edit-other-user-info')) {
throw new Meteor.Error('error-action-not-allowed', 'Editing user is not allowed', { method: 'insertOrUpdateUser', action: 'Editing_user' });
throw new Meteor.Error('error-action-not-allowed', 'Editing user is not allowed', {
method: 'insertOrUpdateUser',
action: 'Editing_user'
});
}

if (!userData._id && !RocketChat.authz.hasPermission(userId, 'create-user')) {
throw new Meteor.Error('error-action-not-allowed', 'Adding user is not allowed', { method: 'insertOrUpdateUser', action: 'Adding_user' });
throw new Meteor.Error('error-action-not-allowed', 'Adding user is not allowed', {
method: 'insertOrUpdateUser',
action: 'Adding_user'
});
}

if (userData.roles && _.difference(userData.roles, existingRoles).length > 0) {
throw new Meteor.Error('error-action-not-allowed', 'The field Roles consist invalid role name', { method: 'insertOrUpdateUser', action: 'Assign_role' });
throw new Meteor.Error('error-action-not-allowed', 'The field Roles consist invalid role name', {
method: 'insertOrUpdateUser',
action: 'Assign_role'
});
}

if (userData.roles && _.indexOf(userData.roles, 'admin') >= 0 && !RocketChat.authz.hasPermission(userId, 'assign-admin-role')) {
throw new Meteor.Error('error-action-not-allowed', 'Assigning admin is not allowed', { method: 'insertOrUpdateUser', action: 'Assign_admin' });
throw new Meteor.Error('error-action-not-allowed', 'Assigning admin is not allowed', {
method: 'insertOrUpdateUser',
action: 'Assign_admin'
});
}

if (!userData._id && !s.trim(userData.name)) {
throw new Meteor.Error('error-the-field-is-required', 'The field Name is required', { method: 'insertOrUpdateUser', field: 'Name' });
throw new Meteor.Error('error-the-field-is-required', 'The field Name is required', {
method: 'insertOrUpdateUser',
field: 'Name'
});
}

if (!userData._id && !s.trim(userData.username)) {
throw new Meteor.Error('error-the-field-is-required', 'The field Username is required', { method: 'insertOrUpdateUser', field: 'Username' });
throw new Meteor.Error('error-the-field-is-required', 'The field Username is required', {
method: 'insertOrUpdateUser',
field: 'Username'
});
}

let nameValidation;
Expand All @@ -39,20 +57,33 @@ RocketChat.saveUser = function(userId, userData) {
}

if (userData.username && !nameValidation.test(userData.username)) {
throw new Meteor.Error('error-input-is-not-a-valid-field', `${ _.escape(userData.username) } is not a valid username`, { method: 'insertOrUpdateUser', input: userData.username, field: 'Username' });
throw new Meteor.Error('error-input-is-not-a-valid-field', `${ _.escape(userData.username) } is not a valid username`, {
method: 'insertOrUpdateUser',
input: userData.username,
field: 'Username'
});
}

if (!userData._id && !userData.password) {
throw new Meteor.Error('error-the-field-is-required', 'The field Password is required', { method: 'insertOrUpdateUser', field: 'Password' });
throw new Meteor.Error('error-the-field-is-required', 'The field Password is required', {
method: 'insertOrUpdateUser',
field: 'Password'
});
}

if (!userData._id) {
if (!RocketChat.checkUsernameAvailability(userData.username)) {
throw new Meteor.Error('error-field-unavailable', `${ _.escape(userData.username) } is already in use :(`, { method: 'insertOrUpdateUser', field: userData.username });
throw new Meteor.Error('error-field-unavailable', `${ _.escape(userData.username) } is already in use :(`, {
method: 'insertOrUpdateUser',
field: userData.username
});
}

if (userData.email && !RocketChat.checkEmailAvailability(userData.email)) {
throw new Meteor.Error('error-field-unavailable', `${ _.escape(userData.email) } is already in use :(`, { method: 'insertOrUpdateUser', field: userData.email });
throw new Meteor.Error('error-field-unavailable', `${ _.escape(userData.email) } is already in use :(`, {
method: 'insertOrUpdateUser',
field: userData.email
});
}

RocketChat.validateEmailDomain(userData.email);
Expand All @@ -73,16 +104,16 @@ RocketChat.saveUser = function(userId, userData) {
$set: {
name: userData.name,
roles: userData.roles || ['user'],
settings: userData.settings
settings: userData.settings || {}
}
};

if (typeof userData.requirePasswordChange !== 'undefined') {
updateUser.$set.requirePasswordChange = userData.requirePasswordChange;
}

if (userData.verified) {
updateUser.$set['emails.0.verified'] = true;
if (typeof userData.verified === 'boolean') {
updateUser.$set['emails.0.verified'] = userData.verified;
}

Meteor.users.update({ _id }, updateUser);
Expand Down Expand Up @@ -120,15 +151,18 @@ RocketChat.saveUser = function(userId, userData) {
try {
Email.send(email);
} catch (error) {
throw new Meteor.Error('error-email-send-failed', `Error trying to send email: ${ error.message }`, { function: 'RocketChat.saveUser', message: error.message });
throw new Meteor.Error('error-email-send-failed', `Error trying to send email: ${ error.message }`, {
function: 'RocketChat.saveUser',
message: error.message
});
}
});
}

userData._id = _id;

if (RocketChat.settings.get('Accounts_SetDefaultAvatar') === true && userData.email) {
const gravatarUrl = Gravatar.imageUrl(userData.email, {default: '404', size: 200, secure: true});
const gravatarUrl = Gravatar.imageUrl(userData.email, { default: '404', size: 200, secure: true });

try {
RocketChat.setUserAvatar(userData, gravatarUrl, '', 'url');
Expand All @@ -149,7 +183,8 @@ RocketChat.saveUser = function(userId, userData) {
}

if (userData.email) {
RocketChat.setEmail(userData._id, userData.email);
const shouldSendVerificationEmailToUser = userData.verified !== true;
RocketChat.setEmail(userData._id, userData.email, shouldSendVerificationEmailToUser);
}

if (userData.password && userData.password.trim() && RocketChat.authz.hasPermission(userId, 'edit-other-user-password')) {
Expand All @@ -172,7 +207,9 @@ RocketChat.saveUser = function(userId, userData) {
updateUser.$set.requirePasswordChange = userData.requirePasswordChange;
}

updateUser.$set['emails.0.verified'] = !!userData.verified;
if (typeof userData.verified === 'boolean') {
updateUser.$set['emails.0.verified'] = userData.verified;
}

Meteor.users.update({ _id: userData._id }, updateUser);

Expand Down
5 changes: 4 additions & 1 deletion packages/rocketchat-lib/server/functions/setEmail.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import s from 'underscore.string';

RocketChat._setEmail = function(userId, email) {
RocketChat._setEmail = function(userId, email, shouldSendVerificationEmail = true) {
email = s.trim(email);
if (!userId) {
throw new Meteor.Error('error-invalid-user', 'Invalid user', { function: '_setEmail' });
Expand All @@ -27,6 +27,9 @@ RocketChat._setEmail = function(userId, email) {
// Set new email
RocketChat.models.Users.setEmail(user._id, email);
user.email = email;
if (shouldSendVerificationEmail === true) {
Meteor.call('sendConfirmationEmail', user.email);
}
return user;
};

Expand Down
Loading

0 comments on commit e571e76

Please sign in to comment.