docbrown/app/services/authentication/providers/apple.rb
Duke Greene 9a6f04bd37
api v1 endpoint for creating an organization (#19778)
* api v1 endpoint for creating an organization

* address failing specs, regenerate swagger docs

* remove old comment in destroy now that woreker call takes third argument

* refactor our services for profile images into images folder
2023-07-21 07:43:56 -04:00

84 lines
2.9 KiB
Ruby

module Authentication
module Providers
# Apple authentication provider, uses omniauth-apple as backend
class Apple < Provider
OFFICIAL_NAME = "Apple".freeze
SETTINGS_URL = "https://appleid.apple.com/account/manage".freeze
TRUSTED_CALLBACK_ORIGIN = "https://appleid.apple.com".freeze
CALLBACK_PATH = "/users/auth/apple/callback".freeze
def self.official_name
OFFICIAL_NAME
end
def self.settings_url
SETTINGS_URL
end
def self.sign_in_path(**kwargs)
::Authentication::Paths.sign_in_path(
provider_name,
**kwargs,
)
end
def new_user_data
# Apple sends `first_name` and `last_name` as separate fields
name = I18n.t("services.authentication.providers.apple.name", first: info.first_name, last: info.last_name)
user_data = {
email: info.email,
apple_username: user_nickname,
name: name
}
user_data[:profile_image] = if Rails.env.test?
Settings::General.mascot_image_url
else
Images::ProfileImageGenerator.call
end
user_data
end
def existing_user_data
# Apple by default will send nil `first_name` and `last_name` after
# the first login. To cover the case where a user disconnects their
# Apple authorization, signs in again and then changes their name,
# we update the username only if the name is not nil
apple_username = info.first_name&.downcase
return {} unless apple_username
{ apple_username: apple_username }
end
# For Apple we override this method because the `info` payload doesn't
# include `nickname`. On top of not having a username, Apple allows users
# to 'choose' the first_name & last_name sent our way so they are
# definitely not assured to be unique. We still need `user_nickname` to
# always be the same on each login so we use the email hash as suffix to
# avoid collisions with other registrations with the same first_name
def user_nickname
if info.first_name.present? || info.last_name.present?
# We sometimes get `info.first_name` and `info.last_name`
[
info.first_name&.downcase,
info.last_name&.downcase,
Digest::SHA512.hexdigest(info.email),
].join("_")[0...25]
else
# This covers an edge case where the Apple Id has already given
# permissions to the forem auth and we don't have anything else
# to work with other than the email
["user", Digest::SHA512.hexdigest(info.email)].join("_")[0...15]
end
end
protected
def cleanup_payload(auth_payload)
auth_payload
end
end
end
end