Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FIX] Verified property of user is always set to false if not supplied #9719

Merged
merged 7 commits into from
Mar 9, 2018
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