[FIX] REST endpoint `users.setPreferences` to not override all user's preferences (#15288)

pull/15400/head^2
Marcos Spessatto Defendi 6 years ago committed by Diego Sampaio
parent 2c756207bd
commit ea6a944c77
  1. 19
      app/api/server/v1/users.js
  2. 2
      tests/data/user.js
  3. 67
      tests/end-to-end/api/01-users.js

@ -529,28 +529,21 @@ API.v1.addRoute('users.setPreferences', { authRequired: true }, {
muteFocusedConversations: Match.Optional(Boolean),
}),
});
if (this.bodyParams.userId && this.bodyParams.userId !== this.userId && !hasPermission(this.userId, 'edit-other-user-info')) {
throw new Meteor.Error('error-action-not-allowed', 'Editing user is not allowed');
}
const userId = this.bodyParams.userId ? this.bodyParams.userId : this.userId;
const userData = {
_id: userId,
settings: {
preferences: this.bodyParams.data,
},
};
if (this.bodyParams.data.language) {
const { language } = this.bodyParams.data;
delete this.bodyParams.data.language;
userData.language = language;
if (!Users.findOneById(userId)) {
throw new Meteor.Error('error-invalid-user', 'The optional "userId" param provided does not match any users');
}
Meteor.runAsUser(this.userId, () => saveUser(this.userId, userData));
Meteor.runAsUser(userId, () => Meteor.call('saveUserPreferences', this.bodyParams.data));
const user = Users.findOneById(userId, {
fields: {
'settings.preferences': 1,
language: 1,
},
});
return API.v1.success({
user: {
_id: user._id,

@ -10,7 +10,7 @@ export const preferences = {
newRoomNotification: 'door',
newMessageNotification: 'chime',
muteFocusedConversations: true,
clockMode: 0,
clockMode: 1,
useEmojis: true,
convertAsciiEmoji: true,
saveMobileBandwidth: true,

@ -1129,6 +1129,70 @@ describe('[Users]', function() {
});
describe('[/users.setPreferences]', () => {
it('should return an error when the user try to update info of another user and does not have the necessary permission', (done) => {
const userPreferences = {
userId: 'rocket.cat',
data: {
...preferences.data,
},
};
updatePermission('edit-other-user-info', []).then(() => {
request.post(api('users.setPreferences'))
.set(credentials)
.send(userPreferences)
.expect(400)
.expect('Content-Type', 'application/json')
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body).to.have.property('error', 'Editing user is not allowed [error-action-not-allowed]');
expect(res.body).to.have.property('errorType', 'error-action-not-allowed');
})
.end(done);
});
});
it('should return an error when the user try to update info of an inexistent user', (done) => {
const userPreferences = {
userId: 'invalid-id',
data: {
...preferences.data,
},
};
updatePermission('edit-other-user-info', ['admin', 'user']).then(() => {
request.post(api('users.setPreferences'))
.set(credentials)
.send(userPreferences)
.expect(400)
.expect('Content-Type', 'application/json')
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body).to.have.property('error', 'The optional \"userId\" param provided does not match any users [error-invalid-user]');
expect(res.body).to.have.property('errorType', 'error-invalid-user');
})
.end(done);
});
});
it('should set some preferences of another user successfully', (done) => {
const userPreferences = {
userId: 'rocket.cat',
data: {
...preferences.data,
},
};
updatePermission('edit-other-user-info', ['admin', 'user']).then(() => {
request.post(api('users.setPreferences'))
.set(credentials)
.send(userPreferences)
.expect(200)
.expect('Content-Type', 'application/json')
.expect((res) => {
expect(res.body.user).to.have.property('settings');
expect(res.body.user.settings).to.have.property('preferences');
expect(res.body.user._id).to.be.equal('rocket.cat');
expect(res.body).to.have.property('success', true);
})
.end(done);
});
});
it('should set some preferences by user when execute successfully', (done) => {
const userPreferences = {
userId: credentials['X-User-Id'],
@ -1142,7 +1206,8 @@ describe('[Users]', function() {
.expect(200)
.expect('Content-Type', 'application/json')
.expect((res) => {
expect(Object.keys(res.body.user.settings.preferences)).to.include.members(Object.keys(userPreferences.data));
expect(res.body.user).to.have.property('settings');
expect(res.body.user.settings).to.have.property('preferences');
expect(res.body).to.have.property('success', true);
})
.end(done);

Loading…
Cancel
Save