jwt 2.10.2 → 3.0.0.beta1

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.
data/lib/jwt/jwk/hmac.rb CHANGED
@@ -70,7 +70,7 @@ module JWT
70
70
  private
71
71
 
72
72
  def secret
73
- self[:k]
73
+ @secret ||= ::JWT::Base64.url_decode(self[:k])
74
74
  end
75
75
 
76
76
  def extract_key_params(key)
@@ -78,7 +78,7 @@ module JWT
78
78
  when JWT::JWK::HMAC
79
79
  key.export(include_private: true)
80
80
  when String # Accept String key as input
81
- { kty: KTY, k: key }
81
+ { kty: KTY, k: ::JWT::Base64.url_encode(key) }
82
82
  when Hash
83
83
  key.transform_keys(&:to_sym)
84
84
  else
@@ -2,8 +2,13 @@
2
2
 
3
3
  module JWT
4
4
  module JWK
5
- # @api private
5
+ # JSON Web Key keyfinder
6
+ # To find the key for a given kid
6
7
  class KeyFinder
8
+ # Initializes a new KeyFinder instance.
9
+ # @param [Hash] options the options to create a KeyFinder with
10
+ # @option options [Proc, JWT::JWK::Set] :jwks the jwks or a loader proc
11
+ # @option options [Boolean] :allow_nil_kid whether to allow nil kid
7
12
  def initialize(options)
8
13
  @allow_nil_kid = options[:allow_nil_kid]
9
14
  jwks_or_loader = options[:jwks]
@@ -15,6 +20,8 @@ module JWT
15
20
  end
16
21
  end
17
22
 
23
+ # Returns the verification key for the given kid
24
+ # @param [String] kid the key id
18
25
  def key_for(kid)
19
26
  raise ::JWT::DecodeError, 'No key id (kid) found from token headers' unless kid || @allow_nil_kid
20
27
  raise ::JWT::DecodeError, 'Invalid type for kid header parameter' unless kid.nil? || kid.is_a?(String)
@@ -27,6 +34,12 @@ module JWT
27
34
  jwk.verify_key
28
35
  end
29
36
 
37
+ # Returns the key for the given token
38
+ # @param [JWT::EncodedToken] token the token
39
+ def call(token)
40
+ key_for(token.header['kid'])
41
+ end
42
+
30
43
  private
31
44
 
32
45
  def resolve_key(kid)
data/lib/jwt/jwk/rsa.rb CHANGED
@@ -165,6 +165,8 @@ module JWT
165
165
  end
166
166
  end
167
167
 
168
+ # :nocov:
169
+ # Before openssl 2.0, we need to use the accessors to set the key
168
170
  def create_rsa_key_using_accessors(rsa_parameters) # rubocop:disable Metrics/AbcSize
169
171
  validate_rsa_parameters!(rsa_parameters)
170
172
 
@@ -179,6 +181,7 @@ module JWT
179
181
  rsa_key.iqmp = rsa_parameters[:qi] if rsa_parameters[:qi]
180
182
  end
181
183
  end
184
+ # :nocov:
182
185
 
183
186
  def validate_rsa_parameters!(rsa_parameters)
184
187
  return unless rsa_parameters.key?(:d)
data/lib/jwt/jwk.rb CHANGED
@@ -53,4 +53,3 @@ require_relative 'jwk/key_base'
53
53
  require_relative 'jwk/ec'
54
54
  require_relative 'jwk/rsa'
55
55
  require_relative 'jwk/hmac'
56
- require_relative 'jwk/okp_rbnacl' if JWT.rbnacl?
data/lib/jwt/token.rb CHANGED
@@ -15,8 +15,6 @@ module JWT
15
15
  # token.header # => {"custom"=>"value", "alg"=>"HS256"}
16
16
  #
17
17
  class Token
18
- include Claims::VerificationMethods
19
-
20
18
  # Initializes a new Token instance.
21
19
  #
22
20
  # @param header [Hash] the header of the JWT token.
@@ -97,13 +95,34 @@ module JWT
97
95
  raise ::JWT::EncodeError, 'Token already signed' if @signature
98
96
 
99
97
  JWA.resolve(algorithm).tap do |algo|
100
- header.merge!(algo.header)
98
+ header.merge!(algo.header) { |_key, old, _new| old }
101
99
  @signature = algo.sign(data: signing_input, signing_key: key)
102
100
  end
103
101
 
104
102
  nil
105
103
  end
106
104
 
105
+ # Verifies the claims of the token.
106
+ # @param options [Array<Symbol>, Hash] the claims to verify.
107
+ # @raise [JWT::DecodeError] if the claims are invalid.
108
+ def verify_claims!(*options)
109
+ Claims::Verifier.verify!(self, *options)
110
+ end
111
+
112
+ # Returns the errors of the claims of the token.
113
+ # @param options [Array<Symbol>, Hash] the claims to verify.
114
+ # @return [Array<Symbol>] the errors of the claims.
115
+ def claim_errors(*options)
116
+ Claims::Verifier.errors(self, *options)
117
+ end
118
+
119
+ # Returns whether the claims of the token are valid.
120
+ # @param options [Array<Symbol>, Hash] the claims to verify.
121
+ # @return [Boolean] whether the claims are valid.
122
+ def valid_claims?(*options)
123
+ claim_errors(*options).empty?
124
+ end
125
+
107
126
  # Returns the JWT token as a string.
108
127
  #
109
128
  # @return [String] the JWT token as a string.
data/lib/jwt/version.rb CHANGED
@@ -12,12 +12,12 @@ module JWT
12
12
  Gem::Version.new(VERSION::STRING)
13
13
  end
14
14
 
15
- # @api private
15
+ # Version constants
16
16
  module VERSION
17
- MAJOR = 2
18
- MINOR = 10
19
- TINY = 2
20
- PRE = nil
17
+ MAJOR = 3
18
+ MINOR = 0
19
+ TINY = 0
20
+ PRE = 'beta1'
21
21
 
22
22
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
23
23
  end
@@ -32,22 +32,6 @@ module JWT
32
32
  true if 3 * 0x10000000 <= OpenSSL::OPENSSL_VERSION_NUMBER
33
33
  end
34
34
 
35
- # Checks if the RbNaCl library is defined.
36
- #
37
- # @return [Boolean] true if RbNaCl is defined, false otherwise.
38
- # @api private
39
- def self.rbnacl?
40
- defined?(::RbNaCl)
41
- end
42
-
43
- # Checks if the RbNaCl library version is 6.0.0 or greater.
44
- #
45
- # @return [Boolean] true if RbNaCl version is 6.0.0 or greater, false otherwise.
46
- # @api private
47
- def self.rbnacl_6_or_greater?
48
- rbnacl? && ::Gem::Version.new(::RbNaCl::VERSION) >= ::Gem::Version.new('6.0.0')
49
- end
50
-
51
35
  # Checks if there is an OpenSSL 3 HMAC empty key regression.
52
36
  #
53
37
  # @return [Boolean] true if there is an OpenSSL 3 HMAC empty key regression, false otherwise.
data/lib/jwt.rb CHANGED
@@ -5,7 +5,6 @@ require 'jwt/base64'
5
5
  require 'jwt/json'
6
6
  require 'jwt/decode'
7
7
  require 'jwt/configuration'
8
- require 'jwt/deprecations'
9
8
  require 'jwt/encode'
10
9
  require 'jwt/error'
11
10
  require 'jwt/jwk'
@@ -13,9 +12,6 @@ require 'jwt/claims'
13
12
  require 'jwt/encoded_token'
14
13
  require 'jwt/token'
15
14
 
16
- require 'jwt/claims_validator'
17
- require 'jwt/verify'
18
-
19
15
  # JSON Web Token implementation
20
16
  #
21
17
  # Should be up to date with the latest spec:
@@ -47,8 +43,6 @@ module JWT
47
43
  # @param options [Hash] additional options for decoding.
48
44
  # @return [Array<Hash>] the decoded payload and headers.
49
45
  def decode(jwt, key = nil, verify = true, options = {}, &keyfinder) # rubocop:disable Style/OptionalBooleanParameter
50
- Deprecations.context do
51
- Decode.new(jwt, key, verify, configuration.decode.to_h.merge(options), &keyfinder).decode_segments
52
- end
46
+ Decode.new(jwt, key, verify, configuration.decode.to_h.merge(options), &keyfinder).decode_segments
53
47
  end
54
48
  end
data/ruby-jwt.gemspec CHANGED
@@ -35,7 +35,6 @@ Gem::Specification.new do |spec|
35
35
 
36
36
  spec.add_development_dependency 'appraisal'
37
37
  spec.add_development_dependency 'bundler'
38
- spec.add_development_dependency 'logger'
39
38
  spec.add_development_dependency 'rake'
40
39
  spec.add_development_dependency 'rspec'
41
40
  spec.add_development_dependency 'rubocop'
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jwt
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.10.2
4
+ version: 3.0.0.beta1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Rudat
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 1980-01-02 00:00:00.000000000 Z
10
+ date: 2025-01-25 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: base64
@@ -51,20 +51,6 @@ dependencies:
51
51
  - - ">="
52
52
  - !ruby/object:Gem::Version
53
53
  version: '0'
54
- - !ruby/object:Gem::Dependency
55
- name: logger
56
- requirement: !ruby/object:Gem::Requirement
57
- requirements:
58
- - - ">="
59
- - !ruby/object:Gem::Version
60
- version: '0'
61
- type: :development
62
- prerelease: false
63
- version_requirements: !ruby/object:Gem::Requirement
64
- requirements:
65
- - - ">="
66
- - !ruby/object:Gem::Version
67
- version: '0'
68
54
  - !ruby/object:Gem::Dependency
69
55
  name: rake
70
56
  requirement: !ruby/object:Gem::Requirement
@@ -134,6 +120,7 @@ files:
134
120
  - CONTRIBUTING.md
135
121
  - LICENSE
136
122
  - README.md
123
+ - UPGRADING.md
137
124
  - lib/jwt.rb
138
125
  - lib/jwt/base64.rb
139
126
  - lib/jwt/claims.rb
@@ -148,44 +135,34 @@ files:
148
135
  - lib/jwt/claims/numeric.rb
149
136
  - lib/jwt/claims/required.rb
150
137
  - lib/jwt/claims/subject.rb
151
- - lib/jwt/claims/verification_methods.rb
152
138
  - lib/jwt/claims/verifier.rb
153
- - lib/jwt/claims_validator.rb
154
139
  - lib/jwt/configuration.rb
155
140
  - lib/jwt/configuration/container.rb
156
141
  - lib/jwt/configuration/decode_configuration.rb
157
142
  - lib/jwt/configuration/jwk_configuration.rb
158
143
  - lib/jwt/decode.rb
159
- - lib/jwt/deprecations.rb
160
144
  - lib/jwt/encode.rb
161
145
  - lib/jwt/encoded_token.rb
162
146
  - lib/jwt/error.rb
163
147
  - lib/jwt/json.rb
164
148
  - lib/jwt/jwa.rb
165
- - lib/jwt/jwa/compat.rb
166
149
  - lib/jwt/jwa/ecdsa.rb
167
- - lib/jwt/jwa/eddsa.rb
168
150
  - lib/jwt/jwa/hmac.rb
169
- - lib/jwt/jwa/hmac_rbnacl.rb
170
- - lib/jwt/jwa/hmac_rbnacl_fixed.rb
171
151
  - lib/jwt/jwa/none.rb
172
152
  - lib/jwt/jwa/ps.rb
173
153
  - lib/jwt/jwa/rsa.rb
174
154
  - lib/jwt/jwa/signing_algorithm.rb
175
155
  - lib/jwt/jwa/unsupported.rb
176
- - lib/jwt/jwa/wrapper.rb
177
156
  - lib/jwt/jwk.rb
178
157
  - lib/jwt/jwk/ec.rb
179
158
  - lib/jwt/jwk/hmac.rb
180
159
  - lib/jwt/jwk/key_base.rb
181
160
  - lib/jwt/jwk/key_finder.rb
182
161
  - lib/jwt/jwk/kid_as_key_digest.rb
183
- - lib/jwt/jwk/okp_rbnacl.rb
184
162
  - lib/jwt/jwk/rsa.rb
185
163
  - lib/jwt/jwk/set.rb
186
164
  - lib/jwt/jwk/thumbprint.rb
187
165
  - lib/jwt/token.rb
188
- - lib/jwt/verify.rb
189
166
  - lib/jwt/version.rb
190
167
  - lib/jwt/x5c_key_finder.rb
191
168
  - ruby-jwt.gemspec
@@ -194,7 +171,7 @@ licenses:
194
171
  - MIT
195
172
  metadata:
196
173
  bug_tracker_uri: https://github.com/jwt/ruby-jwt/issues
197
- changelog_uri: https://github.com/jwt/ruby-jwt/blob/v2.10.2/CHANGELOG.md
174
+ changelog_uri: https://github.com/jwt/ruby-jwt/blob/v3.0.0.beta1/CHANGELOG.md
198
175
  rubygems_mfa_required: 'true'
199
176
  rdoc_options: []
200
177
  require_paths:
@@ -210,7 +187,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
210
187
  - !ruby/object:Gem::Version
211
188
  version: '0'
212
189
  requirements: []
213
- rubygems_version: 3.6.7
190
+ rubygems_version: 3.6.2
214
191
  specification_version: 4
215
192
  summary: JSON Web Token implementation in Ruby
216
193
  test_files: []
@@ -1,20 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module JWT
4
- module Claims
5
- # @api private
6
- module VerificationMethods
7
- def verify_claims!(*options)
8
- Verifier.verify!(self, *options)
9
- end
10
-
11
- def claim_errors(*options)
12
- Verifier.errors(self, *options)
13
- end
14
-
15
- def valid_claims?(*options)
16
- claim_errors(*options).empty?
17
- end
18
- end
19
- end
20
- end
@@ -1,18 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module JWT
4
- # @deprecated Use `Claims.verify_payload!` directly instead.
5
- class ClaimsValidator
6
- # @deprecated Use `Claims.verify_payload!` directly instead.
7
- def initialize(payload)
8
- Deprecations.warning('The ::JWT::ClaimsValidator class is deprecated and will be removed in the next major version of ruby-jwt')
9
- @payload = payload
10
- end
11
-
12
- # @deprecated Use `Claims.verify_payload!` directly instead.
13
- def validate!
14
- Claims.verify_payload!(@payload, :numeric)
15
- true
16
- end
17
- end
18
- end
@@ -1,49 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module JWT
4
- # Deprecations module to handle deprecation warnings in the gem
5
- # @api private
6
- module Deprecations
7
- class << self
8
- def context
9
- yield.tap { emit_warnings }
10
- ensure
11
- Thread.current[:jwt_warning_store] = nil
12
- end
13
-
14
- def warning(message, only_if_valid: false)
15
- method_name = only_if_valid ? :store : :warn
16
- case JWT.configuration.deprecation_warnings
17
- when :once
18
- return if record_warned(message)
19
- when :warn
20
- # noop
21
- else
22
- return
23
- end
24
-
25
- send(method_name, "[DEPRECATION WARNING] #{message}")
26
- end
27
-
28
- def store(message)
29
- (Thread.current[:jwt_warning_store] ||= []) << message
30
- end
31
-
32
- def emit_warnings
33
- return if Thread.current[:jwt_warning_store].nil?
34
-
35
- Thread.current[:jwt_warning_store].each { |warning| warn(warning) }
36
- end
37
-
38
- private
39
-
40
- def record_warned(message)
41
- @warned ||= []
42
- return true if @warned.include?(message)
43
-
44
- @warned << message
45
- false
46
- end
47
- end
48
- end
49
- end
@@ -1,32 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module JWT
4
- module JWA
5
- # Provides backwards compatibility for algorithms
6
- # @api private
7
- module Compat
8
- # @api private
9
- module ClassMethods
10
- def from_algorithm(algorithm)
11
- new(algorithm)
12
- end
13
-
14
- def sign(algorithm, msg, key)
15
- Deprecations.warning('Support for calling sign with positional arguments will be removed in future ruby-jwt versions')
16
-
17
- from_algorithm(algorithm).sign(data: msg, signing_key: key)
18
- end
19
-
20
- def verify(algorithm, key, signing_input, signature)
21
- Deprecations.warning('Support for calling verify with positional arguments will be removed in future ruby-jwt versions')
22
-
23
- from_algorithm(algorithm).verify(data: signing_input, signature: signature, verification_key: key)
24
- end
25
- end
26
-
27
- def self.included(klass)
28
- klass.extend(ClassMethods)
29
- end
30
- end
31
- end
32
- end
data/lib/jwt/jwa/eddsa.rb DELETED
@@ -1,35 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module JWT
4
- module JWA
5
- # Implementation of the EdDSA family of algorithms
6
- class Eddsa
7
- include JWT::JWA::SigningAlgorithm
8
-
9
- def initialize(alg)
10
- @alg = alg
11
- end
12
-
13
- def sign(data:, signing_key:)
14
- raise_sign_error!("Key given is a #{signing_key.class} but has to be an RbNaCl::Signatures::Ed25519::SigningKey") unless signing_key.is_a?(RbNaCl::Signatures::Ed25519::SigningKey)
15
-
16
- Deprecations.warning('Using the EdDSA algorithm is deprecated and will be removed in a future version of ruby-jwt. In the future the algorithm will be provided by the jwt-eddsa gem.')
17
-
18
- signing_key.sign(data)
19
- end
20
-
21
- def verify(data:, signature:, verification_key:)
22
- raise_verify_error!("key given is a #{verification_key.class} but has to be a RbNaCl::Signatures::Ed25519::VerifyKey") unless verification_key.is_a?(RbNaCl::Signatures::Ed25519::VerifyKey)
23
-
24
- Deprecations.warning('Using the EdDSA algorithm is deprecated and will be removed in a future version of ruby-jwt. In the future the algorithm will be provided by the jwt-eddsa gem.')
25
-
26
- verification_key.verify(signature, data)
27
- rescue RbNaCl::CryptoError
28
- false
29
- end
30
-
31
- register_algorithm(new('ED25519'))
32
- register_algorithm(new('EdDSA'))
33
- end
34
- end
35
- end
@@ -1,50 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module JWT
4
- module JWA
5
- # Implementation of the HMAC family of algorithms (using RbNaCl)
6
- class HmacRbNaCl
7
- include JWT::JWA::SigningAlgorithm
8
-
9
- def self.from_algorithm(algorithm)
10
- new(algorithm, ::RbNaCl::HMAC.const_get(algorithm.upcase.gsub('HS', 'SHA')))
11
- end
12
-
13
- def initialize(alg, hmac)
14
- @alg = alg
15
- @hmac = hmac
16
- end
17
-
18
- def sign(data:, signing_key:)
19
- Deprecations.warning("The use of the algorithm #{alg} is deprecated and will be removed in the next major version of ruby-jwt")
20
- hmac.auth(key_for_rbnacl(hmac, signing_key).encode('binary'), data.encode('binary'))
21
- end
22
-
23
- def verify(data:, signature:, verification_key:)
24
- Deprecations.warning("The use of the algorithm #{alg} is deprecated and will be removed in the next major version of ruby-jwt")
25
- hmac.verify(key_for_rbnacl(hmac, verification_key).encode('binary'), signature.encode('binary'), data.encode('binary'))
26
- rescue ::RbNaCl::BadAuthenticatorError, ::RbNaCl::LengthError
27
- false
28
- end
29
-
30
- register_algorithm(new('HS512256', ::RbNaCl::HMAC::SHA512256))
31
-
32
- private
33
-
34
- attr_reader :hmac
35
-
36
- def key_for_rbnacl(hmac, key)
37
- key ||= ''
38
- raise JWT::DecodeError, 'HMAC key expected to be a String' unless key.is_a?(String)
39
-
40
- return padded_empty_key(hmac.key_bytes) if key == ''
41
-
42
- key
43
- end
44
-
45
- def padded_empty_key(length)
46
- Array.new(length, 0x0).pack('C*').encode('binary')
47
- end
48
- end
49
- end
50
- end
@@ -1,47 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module JWT
4
- module JWA
5
- # Implementation of the HMAC family of algorithms (using RbNaCl prior to a certain version)
6
- class HmacRbNaClFixed
7
- include JWT::JWA::SigningAlgorithm
8
-
9
- def self.from_algorithm(algorithm)
10
- new(algorithm, ::RbNaCl::HMAC.const_get(algorithm.upcase.gsub('HS', 'SHA')))
11
- end
12
-
13
- def initialize(alg, hmac)
14
- @alg = alg
15
- @hmac = hmac
16
- end
17
-
18
- def sign(data:, signing_key:)
19
- signing_key ||= ''
20
- Deprecations.warning("The use of the algorithm #{alg} is deprecated and will be removed in the next major version of ruby-jwt")
21
- raise JWT::DecodeError, 'HMAC key expected to be a String' unless signing_key.is_a?(String)
22
-
23
- hmac.auth(padded_key_bytes(signing_key, hmac.key_bytes), data.encode('binary'))
24
- end
25
-
26
- def verify(data:, signature:, verification_key:)
27
- verification_key ||= ''
28
- Deprecations.warning("The use of the algorithm #{alg} is deprecated and will be removed in the next major version of ruby-jwt")
29
- raise JWT::DecodeError, 'HMAC key expected to be a String' unless verification_key.is_a?(String)
30
-
31
- hmac.verify(padded_key_bytes(verification_key, hmac.key_bytes), signature.encode('binary'), data.encode('binary'))
32
- rescue ::RbNaCl::BadAuthenticatorError, ::RbNaCl::LengthError
33
- false
34
- end
35
-
36
- register_algorithm(new('HS512256', ::RbNaCl::HMAC::SHA512256))
37
-
38
- private
39
-
40
- attr_reader :hmac
41
-
42
- def padded_key_bytes(key, bytesize)
43
- key.bytes.fill(0, key.bytesize...bytesize).pack('C*')
44
- end
45
- end
46
- end
47
- end
@@ -1,44 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module JWT
4
- module JWA
5
- # @api private
6
- class Wrapper
7
- include SigningAlgorithm
8
-
9
- def initialize(algorithm)
10
- @algorithm = algorithm
11
- end
12
-
13
- def alg
14
- return @algorithm.alg if @algorithm.respond_to?(:alg)
15
-
16
- super
17
- end
18
-
19
- def valid_alg?(alg_to_check)
20
- return @algorithm.valid_alg?(alg_to_check) if @algorithm.respond_to?(:valid_alg?)
21
-
22
- super
23
- end
24
-
25
- def header(*args, **kwargs)
26
- return @algorithm.header(*args, **kwargs) if @algorithm.respond_to?(:header)
27
-
28
- super
29
- end
30
-
31
- def sign(*args, **kwargs)
32
- return @algorithm.sign(*args, **kwargs) if @algorithm.respond_to?(:sign)
33
-
34
- super
35
- end
36
-
37
- def verify(*args, **kwargs)
38
- return @algorithm.verify(*args, **kwargs) if @algorithm.respond_to?(:verify)
39
-
40
- super
41
- end
42
- end
43
- end
44
- end