FIX: Suggest current username for staged users (#13706)

FIX: Suggest current username for staged users (#13706)

If user had a staged account and logged in using a third party service a different username was suggested. This change will try to use the username given by the authentication provider first, then the current staged username and last suggest a new one.

diff --git a/lib/auth/result.rb b/lib/auth/result.rb
index 35ce4ca..1b9c1d8 100644
--- a/lib/auth/result.rb
+++ b/lib/auth/result.rb
@@ -137,9 +137,18 @@ class Auth::Result
       return result
     end
 
+    suggested_username = UserNameSuggester.suggest(username_suggester_attributes)
+    if email_valid && email.present?
+      if username.present? && User.username_available?(username, email)
+        suggested_username = username
+      elsif staged_user = User.where(staged: true).find_by_email(email)
+        suggested_username = staged_user.username
+      end
+    end
+
     result = {
       email: email,
-      username: UserNameSuggester.suggest(username_suggester_attributes),
+      username: suggested_username,
       auth_provider: authenticator_name,
       email_valid: !!email_valid,
       can_edit_username: can_edit_username,
diff --git a/spec/requests/omniauth_callbacks_controller_spec.rb b/spec/requests/omniauth_callbacks_controller_spec.rb
index 8f99c8e..331678d 100644
--- a/spec/requests/omniauth_callbacks_controller_spec.rb
+++ b/spec/requests/omniauth_callbacks_controller_spec.rb
@@ -213,6 +213,29 @@ RSpec.describe Users::OmniauthCallbacksController do
         expect(data["destination_url"]).to eq(destination_url)
       end
 
+      it 'should return the right response for staged users' do
+        Fabricate(:user, username: "Staged_User", email: email, staged: true)
+
+        destination_url = '/somepath'
+        Rails.application.env_config["omniauth.origin"] = destination_url
+
+        events = DiscourseEvent.track_events { get "/auth/google_oauth2/callback.json" }
+        expect(events.any? { |e| e[:event_name] == :before_auth }).to eq(true)
+        expect(events.any? { |e| e[:event_name] === :after_auth && Auth::GoogleOAuth2Authenticator === e[:params][0] && !e[:params][1].failed? }).to eq(true)
+
+        expect(response.status).to eq(302)
+
+        data = JSON.parse(cookies[:authentication_data])
+
+        expect(data["email"]).to eq(email)
+        expect(data["username"]).to eq("Staged_User")
+        expect(data["auth_provider"]).to eq("google_oauth2")
+        expect(data["email_valid"]).to eq(true)
+        expect(data["can_edit_username"]).to eq(true)
+        expect(data["name"]).to eq("Some Name")
+        expect(data["destination_url"]).to eq(destination_url)
+      end
+
       it 'should include destination url in response' do
         destination_url = '/cookiepath'
         cookies[:destination_url] = destination_url

GitHub sha: 49090c3524b37eb9b3757b2cc6e74c1f75431d28

This commit appears in #13706 which was approved by eviltrout and lis2. It was merged by lis2.