diff --git a/app/assets/javascripts/discourse/controllers/create-account.js.es6 b/app/assets/javascripts/discourse/controllers/create-account.js.es6 index 03dc3d4f6..4f55d15d4 100644 --- a/app/assets/javascripts/discourse/controllers/create-account.js.es6 +++ b/app/assets/javascripts/discourse/controllers/create-account.js.es6 @@ -69,12 +69,20 @@ export default DiscourseController.extend(ModalFunctionality, { return I18n.t('user.password.instructions', {count: Discourse.SiteSettings.min_password_length}); }.property(), - // Validate the name. It's not required. + nameInstructions: function() { + return I18n.t(Discourse.SiteSettings.full_name_required ? 'user.name.instructions_required' : 'user.name.instructions'); + }.property(), + + // Validate the name. nameValidation: function() { if (this.get('accountPasswordConfirm') === 0) { this.fetchConfirmationValue(); } + if (Discourse.SiteSettings.full_name_required && this.blank('accountName')) { + return Discourse.InputValidation.create({ failed: true }); + } + return Discourse.InputValidation.create({ok: true}); }.property('accountName'), diff --git a/app/assets/javascripts/discourse/controllers/preferences.js.es6 b/app/assets/javascripts/discourse/controllers/preferences.js.es6 index b7a3bb54d..07120a7c8 100644 --- a/app/assets/javascripts/discourse/controllers/preferences.js.es6 +++ b/app/assets/javascripts/discourse/controllers/preferences.js.es6 @@ -39,6 +39,10 @@ export default ObjectController.extend(CanCheckEmails, { canEditName: Discourse.computed.setting('enable_names'), + nameInstructions: function() { + return I18n.t(Discourse.SiteSettings.full_name_required ? 'user.name.instructions_required' : 'user.name.instructions'); + }.property(), + canSelectTitle: function() { return this.siteSettings.enable_badges && this.get('model.has_title_badges'); }.property('model.badge_count'), diff --git a/app/assets/javascripts/discourse/templates/modal/create-account.hbs b/app/assets/javascripts/discourse/templates/modal/create-account.hbs index 1e5934d20..87e472078 100644 --- a/app/assets/javascripts/discourse/templates/modal/create-account.hbs +++ b/app/assets/javascripts/discourse/templates/modal/create-account.hbs @@ -42,7 +42,7 @@ - + {{#if passwordRequired}} diff --git a/app/assets/javascripts/discourse/templates/user/preferences.hbs b/app/assets/javascripts/discourse/templates/user/preferences.hbs index cd6eb59e4..d8e5ff1e2 100644 --- a/app/assets/javascripts/discourse/templates/user/preferences.hbs +++ b/app/assets/javascripts/discourse/templates/user/preferences.hbs @@ -32,7 +32,7 @@ {{/if}}
- {{i18n 'user.name.instructions'}} + {{nameInstructions}}
{{/if}} diff --git a/app/models/user.rb b/app/models/user.rb index af2ab4c71..6a8eea014 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -72,6 +72,7 @@ class User < ActiveRecord::Base validates :email, presence: true, uniqueness: true validates :email, email: true, if: :email_changed? validate :password_validator + validates :name, user_full_name: true, if: :name_changed? validates :ip_address, allowed_ip_address: {on: :create, message: :signup_not_allowed} after_initialize :add_trust_level diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index c6e27bafd..e93fc713b 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -441,6 +441,7 @@ en: name: title: "Name" instructions: "Your full name (optional)" + instructions_required: "Your full name" too_short: "Your name is too short" ok: "Your name looks good" username: diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index 07645605d..45b611185 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -1101,6 +1101,7 @@ en: disable_edit_notifications: "Disables edit notifications by the system user when 'download_remote_images_to_local' is active." + full_name_required: "Full name is a required field of a user's profile." enable_names: "Show the user's full name on their profile, user card, and emails. Disable to hide full name everywhere." display_name_on_posts: "Show a user's full name on their posts in addition to their @username." invites_per_page: "Default invites shown on the user page." diff --git a/config/site_settings.yml b/config/site_settings.yml index d6075f5d8..b3405b37f 100644 --- a/config/site_settings.yml +++ b/config/site_settings.yml @@ -276,6 +276,9 @@ users: logout_redirect: client: true default: '' + full_name_required: + client: true + default: false enable_names: client: true default: true diff --git a/lib/validators/user_full_name_validator.rb b/lib/validators/user_full_name_validator.rb new file mode 100644 index 000000000..ec994c5c3 --- /dev/null +++ b/lib/validators/user_full_name_validator.rb @@ -0,0 +1,8 @@ +class UserFullNameValidator < ActiveModel::EachValidator + + def validate_each(record, attribute, value) + if SiteSetting.full_name_required && !record.name.present? + record.errors.add(attribute, :blank) + end + end +end diff --git a/spec/components/validators/user_full_name_validator_spec.rb b/spec/components/validators/user_full_name_validator_spec.rb new file mode 100644 index 000000000..1b06d00ed --- /dev/null +++ b/spec/components/validators/user_full_name_validator_spec.rb @@ -0,0 +1,45 @@ +require "spec_helper" + +describe UserFullNameValidator do + let(:validator) { described_class.new({attributes: :name}) } + subject(:validate) { validator.validate_each(record,:name,@name) } + let(:record) { Fabricate.build(:user, name: @name) } + + context "name not required" do + before { SiteSetting.stubs(:full_name_required).returns(false) } + + it "allows no name" do + @name = nil + validate + expect(record.errors[:name]).not_to be_present + end + + it "allows name being set" do + @name = "Bigfoot" + validate + expect(record.errors[:name]).not_to be_present + end + end + + context "name required" do + before { SiteSetting.stubs(:full_name_required).returns(true) } + + it "adds error for nil name" do + @name = nil + validate + expect(record.errors[:name]).to be_present + end + + it "adds error for empty string name" do + @name = "" + validate + expect(record.errors[:name]).to be_present + end + + it "allows name being set" do + @name = "Bigfoot" + validate + expect(record.errors[:name]).not_to be_present + end + end +end