omniauth-apple 1.2.2 → 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: 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