diff --git a/app/assets/javascripts/discourse/controllers/preferences.js.es6 b/app/assets/javascripts/discourse/controllers/preferences.js.es6 index 1e40e4ba1..b7a3bb54d 100644 --- a/app/assets/javascripts/discourse/controllers/preferences.js.es6 +++ b/app/assets/javascripts/discourse/controllers/preferences.js.es6 @@ -19,12 +19,17 @@ export default ObjectController.extend(CanCheckEmails, { newNameInput: null, userFields: function() { - var siteUserFields = this.site.get('user_fields'); + let siteUserFields = this.site.get('user_fields'); if (!Ember.isEmpty(siteUserFields)) { - var userFields = this.get('user_fields'); - return siteUserFields.filterProperty('editable', true).sortBy('field_type').map(function(uf) { - var val = userFields ? userFields[uf.get('id').toString()] : null; - return Ember.Object.create({value: val, field: uf}); + const userFields = this.get('user_fields'); + + // Staff can edit fields that are not `editable` + if (!this.get('currentUser.staff')) { + siteUserFields = siteUserFields.filterProperty('editable', true); + } + return siteUserFields.sortBy('field_type').map(function(field) { + const value = userFields ? userFields[field.get('id').toString()] : null; + return Ember.Object.create({ value, field }); }); } }.property('user_fields.@each.value'), @@ -82,16 +87,16 @@ export default ObjectController.extend(CanCheckEmails, { actions: { - save: function() { - var self = this; + save() { + const self = this; this.setProperties({ saving: true, saved: false }); - var model = this.get('model'), + const model = this.get('model'), userFields = this.get('userFields'); // Update the user fields if (!Ember.isEmpty(userFields)) { - var modelFields = model.get('user_fields'); + const modelFields = model.get('user_fields'); if (!Ember.isEmpty(modelFields)) { userFields.forEach(function(uf) { modelFields[uf.get('field.id').toString()] = uf.get('value'); @@ -120,8 +125,8 @@ export default ObjectController.extend(CanCheckEmails, { }); }, - changePassword: function() { - var self = this; + changePassword() { + const self = this; if (!this.get('passwordProgress')) { this.set('passwordProgress', I18n.t("user.change_password.in_progress")); return this.get('model').changePassword().then(function() { @@ -140,32 +145,31 @@ export default ObjectController.extend(CanCheckEmails, { } }, - delete: function() { + delete() { this.set('deleting', true); - var self = this, + const self = this, message = I18n.t('user.delete_account_confirm'), model = this.get('model'), - buttons = [{ - "label": I18n.t("cancel"), - "class": "cancel-inline", - "link": true, - "callback": function() { - self.set('deleting', false); - } - }, { - "label": ' ' + I18n.t("user.delete_account"), - "class": "btn btn-danger", - "callback": function() { - model.delete().then(function() { - bootbox.alert(I18n.t('user.deleted_yourself'), function() { - window.location.pathname = Discourse.getURL('/'); - }); - }, function() { - bootbox.alert(I18n.t('user.delete_yourself_not_allowed')); - self.set('deleting', false); - }); - } - }]; + buttons = [ + { label: I18n.t("cancel"), + class: "cancel-inline", + link: true, + callback: () => { this.set('deleting', false); } + }, + { label: ' ' + I18n.t("user.delete_account"), + class: "btn btn-danger", + callback() { + model.delete().then(function() { + bootbox.alert(I18n.t('user.deleted_yourself'), function() { + window.location.pathname = Discourse.getURL('/'); + }); + }, function() { + bootbox.alert(I18n.t('user.delete_yourself_not_allowed')); + self.set('deleting', false); + }); + } + } + ]; bootbox.dialog(message, buttons, {"classes": "delete-account"}); } } diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 4642bef89..5f9277d12 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -73,7 +73,10 @@ class UsersController < ApplicationController if params[:user_fields].present? params[:custom_fields] = {} unless params[:custom_fields].present? - UserField.where(editable: true).each do |f| + + fields = UserField.all + fields = fields.where(editable: true) unless current_user.staff? + fields.each do |f| val = params[:user_fields][f.id.to_s] val = nil if val === "false" val = val[0...UserField.max_length] if val diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb index 92b2d3fc6..8fe685e90 100644 --- a/spec/controllers/users_controller_spec.rb +++ b/spec/controllers/users_controller_spec.rb @@ -963,6 +963,21 @@ describe UsersController do end end + context "as a staff user" do + let!(:user) { log_in(:admin) } + + context "uneditable field" do + let!(:user_field) { Fabricate(:user_field, editable: false) } + + it "allows staff to edit the field" do + put :update, username: user.username, name: 'Jim Tom', user_fields: { user_field.id.to_s => 'happy' } + expect(response).to be_success + expect(user.user_fields[user_field.id.to_s]).to eq('happy') + end + end + + end + context 'with authenticated user' do context 'with permission to update' do let!(:user) { log_in(:user) }