class OmniAuth::Strategies::Apple

Public Instance Methods

authorize_params() click to toggle source
Calls superclass method
# File lib/omniauth/strategies/apple.rb, line 41
def authorize_params
  super.merge(nonce: new_nonce)
end
callback_url() click to toggle source
# File lib/omniauth/strategies/apple.rb, line 45
def callback_url
  options[:redirect_uri] || (full_host + script_name + callback_path)
end
client() click to toggle source
# File lib/omniauth/strategies/apple.rb, line 37
def client
  ::OAuth2::Client.new(client_id, client_secret, deep_symbolize(options.client_options))
end

Private Instance Methods

client_id() click to toggle source
# File lib/omniauth/strategies/apple.rb, line 93
def client_id
  @client_id ||= if id_info.nil?
                   options.client_id
                 else
                   id_info['aud'] if options.authorized_client_ids.include? id_info['aud']
                 end
end
client_secret() click to toggle source
# File lib/omniauth/strategies/apple.rb, line 127
def client_secret
  payload = {
    iss: options.team_id,
    aud: 'https://appleid.apple.com',
    sub: client_id,
    iat: Time.now.to_i,
    exp: Time.now.to_i + 60
  }
  headers = { kid: options.key_id }

  ::JWT.encode(payload, private_key, 'ES256', headers)
end
email() click to toggle source
# File lib/omniauth/strategies/apple.rb, line 108
def email
  id_info['email']
end
fetch_jwks() click to toggle source
# File lib/omniauth/strategies/apple.rb, line 77
def fetch_jwks
  http = Net::HTTP.new('appleid.apple.com', 443)
  http.use_ssl = true
  request = Net::HTTP::Get.new('/auth/keys', 'User-Agent' => 'ruby/omniauth-apple')
  response = http.request(request)
  JSON.parse(response.body, symbolize_names: true)
end
first_name() click to toggle source
# File lib/omniauth/strategies/apple.rb, line 112
def first_name
  user_info.dig('name', 'firstName')
end
id_info() click to toggle source
# File lib/omniauth/strategies/apple.rb, line 59
def id_info
  @id_info ||= if request.params&.key?('id_token') || access_token&.params&.key?('id_token')
                 id_token = request.params['id_token'] || access_token.params['id_token']
                 jwt_options = {
                   verify_iss: true,
                   iss: 'https://appleid.apple.com',
                   verify_iat: true,
                   verify_aud: true,
                   aud: [options.client_id].concat(options.authorized_client_ids),
                   algorithms: ['RS256'],
                   jwks: fetch_jwks
                 }
                 payload, _header = ::JWT.decode(id_token, nil, true, jwt_options)
                 verify_nonce!(payload)
                 payload
               end
end
last_name() click to toggle source
# File lib/omniauth/strategies/apple.rb, line 116
def last_name
  user_info.dig('name', 'lastName')
end
new_nonce() click to toggle source
# File lib/omniauth/strategies/apple.rb, line 51
def new_nonce
  session['omniauth.nonce'] = SecureRandom.urlsafe_base64(16)
end
private_key() click to toggle source
# File lib/omniauth/strategies/apple.rb, line 140
def private_key
  ::OpenSSL::PKey::EC.new(options.pem)
end
prune!(hash) click to toggle source
# File lib/omniauth/strategies/apple.rb, line 120
def prune!(hash)
  hash.delete_if do |_, v|
    prune!(v) if v.is_a?(Hash)
    v.nil? || (v.respond_to?(:empty?) && v.empty?)
  end
end
stored_nonce() click to toggle source
# File lib/omniauth/strategies/apple.rb, line 55
def stored_nonce
  session.delete('omniauth.nonce')
end
user_info() click to toggle source
# File lib/omniauth/strategies/apple.rb, line 101
def user_info
  user = request.params['user']
  return {} if user.nil?

  @user_info ||= JSON.parse(user)
end
verify_nonce!(payload) click to toggle source
# File lib/omniauth/strategies/apple.rb, line 85
def verify_nonce!(payload)
  return unless payload['nonce_supported']

  return if payload['nonce'] && payload['nonce'] == stored_nonce

  fail!(:nonce_mismatch, CallbackError.new(:nonce_mismatch, 'nonce mismatch'))
end