omniauth-apple 1.2.1 → 1.3.0.alpha

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 31e8e9835b469abca7611926aaa4da9b1f3e35804ea9c4e9fa5b06a1791dcdd1
4
- data.tar.gz: c916fa50a22971da3f2f71a72566e43771531945b7d9e83bbaf0914a04a6253a
3
+ metadata.gz: dfa80b37505eab851337bde06806ca93b16a36d0bba69c25a379842107a53672
4
+ data.tar.gz: 001a183e434b6bca8096c78b6dd78d4eb44519bef7a063c0774ac0b269a8b261
5
5
  SHA512:
6
- metadata.gz: 02bde67e85651dc85bacdb548248d240d9a3c501f24a204ad572253af8cd6468914fe3de86ee30bbc7a174bb6249d77ee6ae82222573beb829dc9b4f7f690099
7
- data.tar.gz: 57a0b49a53f55a77470ad280c27acdb11bccfa93e43170ed0c34730b3fdb9918bb0d43a1ac20ae30f10eb101ef161bac5a79a90e54bee7186c8c813e7923f733
6
+ metadata.gz: 95c48a4e63f6d8a92655ad3537061cd3877f68114954645cce888e0e1456986164166e28b3c7adffff50bc650dce217a29b34f8004190ddcf346d33c657b1987
7
+ data.tar.gz: fde578a7e24aabdf416b46a622753ba86121581898313a367bdbee09495adca1b039c272101a521839294763381c8cb5514bcfc4f81cb469a576857231f46ac4
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [1.2.2] - 2022-10-31
4
+
5
+ ### Fixed
6
+
7
+ - [#94](https://github.com/nhosoya/omniauth-apple/pull/98) handle fail! in correct way
8
+
3
9
  ## [1.2.1] - 2022-10-25
4
10
 
5
11
  ### Fixed
@@ -1,5 +1,5 @@
1
1
  module OmniAuth
2
2
  module Apple
3
- VERSION = "1.2.1"
3
+ VERSION = '1.3.0.alpha'
4
4
  end
5
5
  end
@@ -1,15 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'omniauth-oauth2'
4
- require 'net/https'
4
+ require 'json/jwt'
5
5
 
6
6
  module OmniAuth
7
7
  module Strategies
8
8
  class Apple < OmniAuth::Strategies::OAuth2
9
+ ISSUER = 'https://appleid.apple.com'
10
+
9
11
  option :name, 'apple'
10
12
 
11
13
  option :client_options,
12
- site: 'https://appleid.apple.com',
14
+ site: ISSUER,
13
15
  authorize_url: '/auth/authorize',
14
16
  token_url: '/auth/token',
15
17
  auth_scheme: :request_body
@@ -18,13 +20,13 @@ module OmniAuth
18
20
  scope: 'email name'
19
21
  option :authorized_client_ids, []
20
22
 
21
- uid { id_info['sub'] }
23
+ uid { id_info[:sub] }
22
24
 
23
25
  # Documentation on parameters
24
26
  # https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_rest_api/authenticating_users_with_sign_in_with_apple
25
27
  info do
26
28
  prune!(
27
- sub: id_info['sub'],
29
+ sub: id_info[:sub],
28
30
  email: email,
29
31
  first_name: first_name,
30
32
  last_name: last_name,
@@ -35,8 +37,8 @@ module OmniAuth
35
37
  end
36
38
 
37
39
  extra do
38
- id_token = request.params['id_token'] || access_token&.params&.dig('id_token')
39
- prune!(raw_info: {id_info: id_info, user_info: user_info, id_token: id_token})
40
+ id_token_str = request.params['id_token'] || access_token&.params&.dig('id_token')
41
+ prune!(raw_info: {id_info: id_info, user_info: user_info, id_token: id_token_str})
40
42
  end
41
43
 
42
44
  def client
@@ -44,12 +46,12 @@ module OmniAuth
44
46
  end
45
47
 
46
48
  def email_verified
47
- value = id_info['email_verified']
49
+ value = id_info[:email_verified]
48
50
  value == true || value == "true"
49
51
  end
50
52
 
51
53
  def is_private_email
52
- value = id_info['is_private_email']
54
+ value = id_info[:is_private_email]
53
55
  value == true || value == "true"
54
56
  end
55
57
 
@@ -73,54 +75,63 @@ module OmniAuth
73
75
 
74
76
  def id_info
75
77
  @id_info ||= if request.params&.key?('id_token') || access_token&.params&.key?('id_token')
76
- id_token = request.params['id_token'] || access_token.params['id_token']
77
- if (verification_key = fetch_jwks)
78
- jwt_options = {
79
- verify_iss: true,
80
- iss: 'https://appleid.apple.com',
81
- verify_iat: true,
82
- verify_aud: true,
83
- aud: [options.client_id].concat(options.authorized_client_ids),
84
- algorithms: ['RS256'],
85
- jwks: verification_key
86
- }
87
- payload, _header = ::JWT.decode(id_token, nil, true, jwt_options)
88
- verify_nonce!(payload)
89
- payload
78
+ id_token_str = request.params['id_token'] || access_token.params['id_token']
79
+ id_token = JSON::JWT.decode(id_token_str, :skip_verification)
80
+ if (jwk = fetch_jwk(id_token.kid))
81
+ id_token.verify! jwk
82
+ verify_claims!(id_token)
83
+ id_token
90
84
  else
91
85
  {}
92
86
  end
93
87
  end
94
88
  end
95
89
 
96
- def fetch_jwks
97
- conn = Faraday.new(headers: {user_agent: 'ruby/omniauth-apple'}) do |c|
98
- c.response :json, parser_options: { symbolize_names: true }
99
- c.adapter Faraday.default_adapter
100
- end
101
- res = conn.get 'https://appleid.apple.com/auth/keys'
102
- if res.success?
103
- res.body
104
- else
105
- fail!(:jwks_fetching_failed, CallbackError.new(:jwks_fetching_failed, 'HTTP Error when fetching JWKs'))
106
- end
107
- rescue Faraday::Error => e
108
- fail!(:jwks_fetching_failed, e)
90
+ def fetch_jwk(kid)
91
+ JSON::JWK::Set::Fetcher.fetch File.join(ISSUER, 'auth/keys'), kid: kid
92
+ rescue JSON::ParserError, JSON::JWT::Exception, Faraday::Error => e
93
+ fail!(:jwks_fetching_failed, e) and nil
94
+ end
95
+
96
+ def verify_claims!(id_token)
97
+ verify_iss!(id_token)
98
+ verify_aud!(id_token)
99
+ verify_iat!(id_token)
100
+ verify_exp!(id_token)
101
+ verify_nonce!(id_token) if id_token[:nonce_supported]
109
102
  end
110
103
 
111
- def verify_nonce!(payload)
112
- return unless payload['nonce_supported']
104
+ def verify_iss!(id_token)
105
+ invalid_claim! :iss unless id_token[:iss] == ISSUER
106
+ end
113
107
 
114
- return if payload['nonce'] && payload['nonce'] == stored_nonce
108
+ def verify_aud!(id_token)
109
+ invalid_claim! :aud unless [options.client_id].concat(options.authorized_client_ids).include?(id_token[:aud])
110
+ end
115
111
 
116
- fail!(:nonce_mismatch, CallbackError.new(:nonce_mismatch, 'nonce mismatch'))
112
+ def verify_iat!(id_token)
113
+ invalid_claim! :iat unless id_token[:iat] <= Time.now.to_i
114
+ end
115
+
116
+ def verify_exp!(id_token)
117
+ invalid_claim! :exp unless id_token[:exp] >= Time.now.to_i
118
+ end
119
+
120
+ def verify_nonce!(id_token)
121
+ invalid_claim! :nonce unless id_token[:nonce] && id_token[:nonce] == stored_nonce
122
+ end
123
+
124
+ def invalid_claim!(claim)
125
+ key = :"#{claim}_invalid"
126
+ message = "#{claim} invalid"
127
+ fail! key, CallbackError.new(key, message)
117
128
  end
118
129
 
119
130
  def client_id
120
131
  @client_id ||= if id_info.nil?
121
132
  options.client_id
122
133
  else
123
- id_info['aud'] if options.authorized_client_ids.include? id_info['aud']
134
+ id_info[:aud] if options.authorized_client_ids.include? id_info[:aud]
124
135
  end
125
136
  end
126
137
 
@@ -132,7 +143,7 @@ module OmniAuth
132
143
  end
133
144
 
134
145
  def email
135
- id_info['email']
146
+ id_info[:email]
136
147
  end
137
148
 
138
149
  def first_name
@@ -151,16 +162,15 @@ module OmniAuth
151
162
  end
152
163
 
153
164
  def client_secret
154
- payload = {
165
+ jwt = JSON::JWT.new(
155
166
  iss: options.team_id,
156
- aud: 'https://appleid.apple.com',
167
+ aud: ISSUER,
157
168
  sub: client_id,
158
- iat: Time.now.to_i,
159
- exp: Time.now.to_i + 60
160
- }
161
- headers = { kid: options.key_id }
162
-
163
- ::JWT.encode(payload, private_key, 'ES256', headers)
169
+ iat: Time.now,
170
+ exp: Time.now + 60
171
+ )
172
+ jwt.kid = options.key_id
173
+ jwt.sign(private_key).to_s
164
174
  end
165
175
 
166
176
  def private_key
@@ -37,7 +37,7 @@ Gem::Specification.new do |spec|
37
37
  spec.require_paths = ["lib"]
38
38
 
39
39
  spec.add_dependency 'omniauth-oauth2'
40
- spec.add_dependency 'jwt'
40
+ spec.add_dependency 'json-jwt'
41
41
  spec.add_development_dependency "bundler", "~> 2.0"
42
42
  spec.add_development_dependency "rake", "~> 13.0"
43
43
  spec.add_development_dependency "rspec", "~> 3.9"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: omniauth-apple
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1
4
+ version: 1.3.0.alpha
5
5
  platform: ruby
6
6
  authors:
7
7
  - nhosoya
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2022-10-25 00:00:00.000000000 Z
12
+ date: 2022-12-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: omniauth-oauth2
@@ -26,7 +26,7 @@ dependencies:
26
26
  - !ruby/object:Gem::Version
27
27
  version: '0'
28
28
  - !ruby/object:Gem::Dependency
29
- name: jwt
29
+ name: json-jwt
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
32
  - - ">="
@@ -146,11 +146,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
146
146
  version: '0'
147
147
  required_rubygems_version: !ruby/object:Gem::Requirement
148
148
  requirements:
149
- - - ">="
149
+ - - ">"
150
150
  - !ruby/object:Gem::Version
151
- version: '0'
151
+ version: 1.3.1
152
152
  requirements: []
153
- rubygems_version: 3.3.7
153
+ rubygems_version: 3.3.26
154
154
  signing_key:
155
155
  specification_version: 4
156
156
  summary: OmniAuth strategy for Sign In with Apple