diff --git a/app/models/user.rb b/app/models/user.rb index 3da8bd059ab..a2db3a8e428 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -166,9 +166,12 @@ class User < ActiveRecord::Base SiteSetting.min_username_length.to_i..SiteSetting.max_username_length.to_i end - def self.username_available?(username) + def self.username_available?(username, email=nil) lower = username.downcase - !reserved_username?(lower) && !User.where(username_lower: lower).exists? + return false if reserved_username?(lower) + return true if !User.exists?(username_lower: lower) + # staged users can use the same username since they will take over the account + email.present? && User.joins(:user_emails).exists?(staged: true, username_lower: lower, user_emails: { primary: true, email: email }) end def self.reserved_username?(username) diff --git a/app/services/username_checker_service.rb b/app/services/username_checker_service.rb index 0f8d7a62510..539e07e39cf 100644 --- a/app/services/username_checker_service.rb +++ b/app/services/username_checker_service.rb @@ -12,7 +12,7 @@ class UsernameCheckerService end def check_username_availability(username, email) - if User.username_available?(username) + if User.username_available?(username, email) { available: true, is_developer: is_developer?(email) } else { available: false, suggestion: UserNameSuggester.suggest(username) } diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index f9917959a73..d057e042c33 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -484,9 +484,16 @@ describe User do it 'returns false when a username is reserved' do SiteSetting.reserved_usernames = 'test|donkey' - expect(User.username_available?('tESt')).to eq(false) end + + it "returns true when username is associated to a staged user of the same email" do + staged = Fabricate(:user, staged: true, email: "foo@bar.com") + expect(User.username_available?(staged.username, staged.primary_email.email)).to eq(true) + + user = Fabricate(:user, email: "bar@foo.com") + expect(User.username_available?(user.username, user.primary_email.email)).to eq(false) + end end describe '.reserved_username?' do