From cf81b3f86db8edc1256266b15462509969c406ab Mon Sep 17 00:00:00 2001 From: Neil Lalonde Date: Wed, 25 Feb 2015 11:59:57 -0500 Subject: [PATCH] FEATURE: don't allow username and password to be the same --- .../controllers/create-account.js.es6 | 7 ++++++ config/locales/client.en.yml | 1 + config/locales/server.en.yml | 1 + lib/validators/password_validator.rb | 2 ++ .../validators/password_validator_spec.rb | 7 ++++++ .../controllers/create-account-test.js.es6 | 24 +++++++++++++++++++ 6 files changed, 42 insertions(+) diff --git a/app/assets/javascripts/discourse/controllers/create-account.js.es6 b/app/assets/javascripts/discourse/controllers/create-account.js.es6 index eb15fa02626..6f0c04ce00c 100644 --- a/app/assets/javascripts/discourse/controllers/create-account.js.es6 +++ b/app/assets/javascripts/discourse/controllers/create-account.js.es6 @@ -310,6 +310,13 @@ export default DiscourseController.extend(ModalFunctionality, { }); } + if (!this.blank('accountUsername') && this.get('accountPassword') === this.get('accountUsername')) { + return Discourse.InputValidation.create({ + failed: true, + reason: I18n.t('user.password.same_as_username') + }); + } + // Looks good! return Discourse.InputValidation.create({ ok: true, diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 41c824d70c5..f4a78849c07 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -514,6 +514,7 @@ en: title: "Password" too_short: "Your password is too short." common: "That password is too common." + same_as_username: "Your password is the same as your username." ok: "Your password looks good." instructions: "At least %{count} characters." diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index 4eac30036a8..fe859f71128 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -292,6 +292,7 @@ en: attributes: password: common: "is one of the 10000 most common passwords. Please use a more secure password." + same_as_username: "is the same as your username. Please use a more secure password." ip_address: signup_not_allowed: "Signup is not allowed from this account." color_scheme_color: diff --git a/lib/validators/password_validator.rb b/lib/validators/password_validator.rb index 68fdd9de2b8..5bfa2e810d6 100644 --- a/lib/validators/password_validator.rb +++ b/lib/validators/password_validator.rb @@ -8,6 +8,8 @@ class PasswordValidator < ActiveModel::EachValidator record.errors.add(attribute, :blank) elsif value.length < SiteSetting.min_password_length record.errors.add(attribute, :too_short, count: SiteSetting.min_password_length) + elsif record.username.present? && value == record.username + record.errors.add(attribute, :same_as_username) elsif SiteSetting.block_common_passwords && CommonPasswords.common_password?(value) record.errors.add(attribute, :common) end diff --git a/spec/components/validators/password_validator_spec.rb b/spec/components/validators/password_validator_spec.rb index fe14bfdd4be..484db278211 100644 --- a/spec/components/validators/password_validator_spec.rb +++ b/spec/components/validators/password_validator_spec.rb @@ -72,6 +72,13 @@ describe PasswordValidator do expect(record.errors[:password]).not_to be_present end end + + it "adds an error when password is the same as the username" do + @password = "porkchops1" + record.username = @password + validate + expect(record.errors[:password]).to be_present + end end context "password not required" do diff --git a/test/javascripts/controllers/create-account-test.js.es6 b/test/javascripts/controllers/create-account-test.js.es6 index 160dd92e8de..8aca55f68f7 100644 --- a/test/javascripts/controllers/create-account-test.js.es6 +++ b/test/javascripts/controllers/create-account-test.js.es6 @@ -22,3 +22,27 @@ test('basicUsernameValidation', function() { equal(controller.get('basicUsernameValidation.ok'), true, 'Prefilled username is valid'); equal(controller.get('basicUsernameValidation.reason'), I18n.t('user.username.prefilled'), 'Prefilled username is valid'); }); + +test('passwordValidation', function() { + var subject = this.subject; + + var controller = subject(); + controller.set('passwordRequired', true); + controller.set('accountUsername', 'porkchops'); + controller.set('prefilledUsername', 'porkchops'); + + controller.set('accountPassword', 'b4fcdae11f9167'); + equal(controller.get('passwordValidation.ok'), true, 'Password is ok'); + equal(controller.get('passwordValidation.reason'), I18n.t('user.password.ok'), 'Password is valid'); + + var testInvalidPassword = function(password, expectedReason) { + var controller = subject(); + controller.set('accountPassword', password); + equal(controller.get('passwordValidation.failed'), true, 'password should be invalid: ' + password); + equal(controller.get('passwordValidation.reason'), expectedReason, 'password validation reason: ' + password + ', ' + expectedReason); + }; + + testInvalidPassword('', undefined); + testInvalidPassword('x', I18n.t('user.password.too_short')); + testInvalidPassword('porkchops', I18n.t('user.password.same_as_username')); +});