omniauth-apple 1.2.2 → 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: 81a5350ae8be48914ee324f8586b5d58f83927467bc87106cab846e028e38beb
4
- data.tar.gz: 42db86865c9120c95e7326359e3ac02dd58dbd28bfe84c7fc0bbb002488b0a1b
3
+ metadata.gz: dfa80b37505eab851337bde06806ca93b16a36d0bba69c25a379842107a53672
4
+ data.tar.gz: 001a183e434b6bca8096c78b6dd78d4eb44519bef7a063c0774ac0b269a8b261
5
5
  SHA512:
6
- metadata.gz: 18a1bf098d7687ed17df039b9b2f4b0a388f0d6858a4a54aa8c94a7233622f7cb1d4485a38d870ae430f873aadaaee8d9d1b42c9f8a91545c0bdb10c4cffbe11
7
- data.tar.gz: f53179d2a247e0fd2559614fece6b3b734579d756be44c1b4c40ab9c6911479e38dc7f74800dcc59b36b09749656bb93aff6c8eeccc422238e95667049064b63
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.2"
3
+ VERSION = '1.3.0.alpha'
4
4
  end
5
5
  end
@@ -1,21 +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
- class JWTFetchingFailed < CallbackError
10
- def initialize(error_reason = nil, error_uri = nil)
11
- super :jwks_fetching_failed, error_reason, error_uri
12
- end
13
- end
9
+ ISSUER = 'https://appleid.apple.com'
14
10
 
15
11
  option :name, 'apple'
16
12
 
17
13
  option :client_options,
18
- site: 'https://appleid.apple.com',
14
+ site: ISSUER,
19
15
  authorize_url: '/auth/authorize',
20
16
  token_url: '/auth/token',
21
17
  auth_scheme: :request_body
@@ -24,13 +20,13 @@ module OmniAuth
24
20
  scope: 'email name'
25
21
  option :authorized_client_ids, []
26
22
 
27
- uid { id_info['sub'] }
23
+ uid { id_info[:sub] }
28
24
 
29
25
  # Documentation on parameters
30
26
  # https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_rest_api/authenticating_users_with_sign_in_with_apple
31
27
  info do
32
28
  prune!(
33
- sub: id_info['sub'],
29
+ sub: id_info[:sub],
34
30
  email: email,
35
31
  first_name: first_name,
36
32
  last_name: last_name,
@@ -41,8 +37,8 @@ module OmniAuth
41
37
  end
42
38
 
43
39
  extra do
44
- id_token = request.params['id_token'] || access_token&.params&.dig('id_token')
45
- 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})
46
42
  end
47
43
 
48
44
  def client
@@ -50,12 +46,12 @@ module OmniAuth
50
46
  end
51
47
 
52
48
  def email_verified
53
- value = id_info['email_verified']
49
+ value = id_info[:email_verified]
54
50
  value == true || value == "true"
55
51
  end
56
52
 
57
53
  def is_private_email
58
- value = id_info['is_private_email']
54
+ value = id_info[:is_private_email]
59
55
  value == true || value == "true"
60
56
  end
61
57
 
@@ -79,54 +75,63 @@ module OmniAuth
79
75
 
80
76
  def id_info
81
77
  @id_info ||= if request.params&.key?('id_token') || access_token&.params&.key?('id_token')
82
- id_token = request.params['id_token'] || access_token.params['id_token']
83
- if (verification_key = fetch_jwks)
84
- jwt_options = {
85
- verify_iss: true,
86
- iss: 'https://appleid.apple.com',
87
- verify_iat: true,
88
- verify_aud: true,
89
- aud: [options.client_id].concat(options.authorized_client_ids),
90
- algorithms: ['RS256'],
91
- jwks: verification_key
92
- }
93
- payload, _header = ::JWT.decode(id_token, nil, true, jwt_options)
94
- verify_nonce!(payload)
95
- 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
96
84
  else
97
85
  {}
98
86
  end
99
87
  end
100
88
  end
101
89
 
102
- def fetch_jwks
103
- conn = Faraday.new(headers: {user_agent: 'ruby/omniauth-apple'}) do |c|
104
- c.response :json, parser_options: { symbolize_names: true }
105
- c.adapter Faraday.default_adapter
106
- end
107
- res = conn.get 'https://appleid.apple.com/auth/keys'
108
- if res.success?
109
- res.body
110
- else
111
- raise JWTFetchingFailed.new('HTTP Error when fetching JWKs')
112
- end
113
- rescue JWTFetchingFailed, Faraday::Error => 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
114
93
  fail!(:jwks_fetching_failed, e) and nil
115
94
  end
116
95
 
117
- def verify_nonce!(payload)
118
- return unless payload['nonce_supported']
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]
102
+ end
103
+
104
+ def verify_iss!(id_token)
105
+ invalid_claim! :iss unless id_token[:iss] == ISSUER
106
+ end
107
+
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
111
+
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
119
 
120
- return if payload['nonce'] && payload['nonce'] == stored_nonce
120
+ def verify_nonce!(id_token)
121
+ invalid_claim! :nonce unless id_token[:nonce] && id_token[:nonce] == stored_nonce
122
+ end
121
123
 
122
- fail!(:nonce_mismatch, CallbackError.new(:nonce_mismatch, 'nonce mismatch'))
124
+ def invalid_claim!(claim)
125
+ key = :"#{claim}_invalid"
126
+ message = "#{claim} invalid"
127
+ fail! key, CallbackError.new(key, message)
123
128
  end
124
129
 
125
130
  def client_id
126
131
  @client_id ||= if id_info.nil?
127
132
  options.client_id
128
133
  else
129
- 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]
130
135
  end
131
136
  end
132
137
 
@@ -138,7 +143,7 @@ module OmniAuth
138
143
  end
139
144
 
140
145
  def email
141
- id_info['email']
146
+ id_info[:email]
142
147
  end
143
148
 
144
149
  def first_name
@@ -157,16 +162,15 @@ module OmniAuth
157
162
  end
158
163
 
159
164
  def client_secret
160
- payload = {
165
+ jwt = JSON::JWT.new(
161
166
  iss: options.team_id,
162
- aud: 'https://appleid.apple.com',
167
+ aud: ISSUER,
163
168
  sub: client_id,
164
- iat: Time.now.to_i,
165
- exp: Time.now.to_i + 60
166
- }
167
- headers = { kid: options.key_id }
168
-
169
- ::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
170
174
  end
171
175
 
172
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.2
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-31 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