Fix SSO login not using existing account when e-mail is verified (#11862)
Fix #11472
This commit is contained in:
		@@ -4,7 +4,7 @@ module Omniauthable
 | 
			
		||||
  extend ActiveSupport::Concern
 | 
			
		||||
 | 
			
		||||
  TEMP_EMAIL_PREFIX = 'change@me'
 | 
			
		||||
  TEMP_EMAIL_REGEX = /\Achange@me/
 | 
			
		||||
  TEMP_EMAIL_REGEX  = /\A#{TEMP_EMAIL_PREFIX}/.freeze
 | 
			
		||||
 | 
			
		||||
  included do
 | 
			
		||||
    devise :omniauthable
 | 
			
		||||
@@ -29,7 +29,7 @@ module Omniauthable
 | 
			
		||||
      # Note that this may leave zombie accounts (with no associated identity) which
 | 
			
		||||
      # can be cleaned up at a later date.
 | 
			
		||||
      user   = signed_in_resource || identity.user
 | 
			
		||||
      user = create_for_oauth(auth) if user.nil?
 | 
			
		||||
      user ||= create_for_oauth(auth)
 | 
			
		||||
 | 
			
		||||
      if identity.user.nil?
 | 
			
		||||
        identity.user = user
 | 
			
		||||
@@ -45,7 +45,18 @@ module Omniauthable
 | 
			
		||||
      # exists, we assign a temporary email and ask the user to verify it on
 | 
			
		||||
      # the next step via Auth::SetupController.show
 | 
			
		||||
 | 
			
		||||
      user = User.new(user_params_from_auth(auth))
 | 
			
		||||
      strategy          = Devise.omniauth_configs[auth.provider.to_sym].strategy
 | 
			
		||||
      assume_verified   = strategy&.security&.assume_email_is_verified
 | 
			
		||||
      email_is_verified = auth.info.verified || auth.info.verified_email || assume_verified
 | 
			
		||||
      email             = auth.info.verified_email || auth.info.email
 | 
			
		||||
      email             = nil unless email_is_verified
 | 
			
		||||
 | 
			
		||||
      user = User.find_by(email: email) if email_is_verified
 | 
			
		||||
 | 
			
		||||
      return user unless user.nil?
 | 
			
		||||
 | 
			
		||||
      user = User.new(user_params_from_auth(email, auth))
 | 
			
		||||
 | 
			
		||||
      user.account.avatar_remote_url = auth.info.image if auth.info.image =~ /\A#{URI.regexp(%w(http https))}\z/
 | 
			
		||||
      user.skip_confirmation!
 | 
			
		||||
      user.save!
 | 
			
		||||
@@ -54,14 +65,7 @@ module Omniauthable
 | 
			
		||||
 | 
			
		||||
    private
 | 
			
		||||
 | 
			
		||||
    def user_params_from_auth(auth)
 | 
			
		||||
      strategy          = Devise.omniauth_configs[auth.provider.to_sym].strategy
 | 
			
		||||
      assume_verified   = strategy.try(:security).try(:assume_email_is_verified)
 | 
			
		||||
      email_is_verified = auth.info.verified || auth.info.verified_email || assume_verified
 | 
			
		||||
      email             = auth.info.verified_email || auth.info.email
 | 
			
		||||
      email             = email_is_verified && !User.exists?(email: auth.info.email) && email
 | 
			
		||||
      display_name      = auth.info.full_name || [auth.info.first_name, auth.info.last_name].join(' ')
 | 
			
		||||
 | 
			
		||||
    def user_params_from_auth(email, auth)
 | 
			
		||||
      {
 | 
			
		||||
        email: email || "#{TEMP_EMAIL_PREFIX}-#{auth.uid}-#{auth.provider}.com",
 | 
			
		||||
        password: Devise.friendly_token[0, 20],
 | 
			
		||||
@@ -69,7 +73,7 @@ module Omniauthable
 | 
			
		||||
        external: true,
 | 
			
		||||
        account_attributes: {
 | 
			
		||||
          username: ensure_unique_username(auth.uid),
 | 
			
		||||
          display_name: display_name,
 | 
			
		||||
          display_name: auth.info.full_name || [auth.info.first_name, auth.info.last_name].join(' '),
 | 
			
		||||
        },
 | 
			
		||||
      }
 | 
			
		||||
    end
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user