diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml
index b6e5af9b2ea..72d07f22752 100644
--- a/config/locales/server.en.yml
+++ b/config/locales/server.en.yml
@@ -139,6 +139,7 @@ en:
max_username_length_range: "You cannot set the maximum below the minimum."
default_categories_already_selected: "You cannot select a category used in another list."
s3_upload_bucket_is_required: "You cannot enable uploads to S3 unless you've provided the 's3_upload_bucket'."
+ conflicting_google_user_id: 'The Google Account ID for this account has changed, for protection this requires manual intervention. Please contact the site administrator with the following reference:
https://meta.discourse.org/t/76575'
activemodel:
errors:
diff --git a/lib/auth/google_oauth2_authenticator.rb b/lib/auth/google_oauth2_authenticator.rb
index 310f2ab9e93..dcee38d217f 100644
--- a/lib/auth/google_oauth2_authenticator.rb
+++ b/lib/auth/google_oauth2_authenticator.rb
@@ -21,6 +21,19 @@ class Auth::GoogleOAuth2Authenticator < Auth::Authenticator
if !result.user && !result.email.blank? && result.email_valid
result.user = User.find_by_email(result.email)
if result.user
+ # we've matched an existing user to this login attempt...
+ if result.user.google_user_info && result.user.google_user_info.google_user_id != google_hash[:google_user_id]
+ # but the user has changed the google account used to log in...
+ if result.user.google_user_info.email != google_hash[:email]
+ # the user changed their email, go ahead and scrub the old record
+ result.user.google_user_info.destroy!
+ else
+ # same email address but different account? likely a takeover scenario
+ result.failed = true
+ result.failed_reason = I18n.t('errors.conflicting_google_user_id')
+ return result
+ end
+ end
::GoogleUserInfo.create({ user_id: result.user.id }.merge(google_hash))
end
end