omniauth-apple 1.2.1 → 1.3.0.alpha

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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