jwt 2.8.2 → 3.1.1

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.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +149 -31
  3. data/CODE_OF_CONDUCT.md +14 -14
  4. data/CONTRIBUTING.md +9 -10
  5. data/README.md +299 -234
  6. data/UPGRADING.md +47 -0
  7. data/lib/jwt/base64.rb +4 -10
  8. data/lib/jwt/claims/audience.rb +30 -0
  9. data/lib/jwt/claims/crit.rb +35 -0
  10. data/lib/jwt/claims/decode_verifier.rb +40 -0
  11. data/lib/jwt/claims/expiration.rb +32 -0
  12. data/lib/jwt/claims/issued_at.rb +22 -0
  13. data/lib/jwt/claims/issuer.rb +34 -0
  14. data/lib/jwt/claims/jwt_id.rb +35 -0
  15. data/lib/jwt/claims/not_before.rb +32 -0
  16. data/lib/jwt/claims/numeric.rb +45 -0
  17. data/lib/jwt/claims/required.rb +33 -0
  18. data/lib/jwt/claims/subject.rb +30 -0
  19. data/lib/jwt/claims/verifier.rb +61 -0
  20. data/lib/jwt/claims.rb +67 -0
  21. data/lib/jwt/configuration/container.rb +20 -1
  22. data/lib/jwt/configuration/decode_configuration.rb +24 -0
  23. data/lib/jwt/configuration/jwk_configuration.rb +1 -0
  24. data/lib/jwt/configuration.rb +8 -0
  25. data/lib/jwt/decode.rb +42 -81
  26. data/lib/jwt/encode.rb +17 -60
  27. data/lib/jwt/encoded_token.rb +236 -0
  28. data/lib/jwt/error.rb +32 -1
  29. data/lib/jwt/json.rb +1 -1
  30. data/lib/jwt/jwa/ecdsa.rb +59 -24
  31. data/lib/jwt/jwa/hmac.rb +22 -19
  32. data/lib/jwt/jwa/none.rb +8 -3
  33. data/lib/jwt/jwa/ps.rb +21 -15
  34. data/lib/jwt/jwa/rsa.rb +21 -10
  35. data/lib/jwt/jwa/signing_algorithm.rb +62 -0
  36. data/lib/jwt/jwa/unsupported.rb +9 -8
  37. data/lib/jwt/jwa.rb +76 -35
  38. data/lib/jwt/jwk/ec.rb +54 -65
  39. data/lib/jwt/jwk/hmac.rb +5 -6
  40. data/lib/jwt/jwk/key_base.rb +16 -1
  41. data/lib/jwt/jwk/key_finder.rb +35 -8
  42. data/lib/jwt/jwk/kid_as_key_digest.rb +1 -0
  43. data/lib/jwt/jwk/rsa.rb +7 -4
  44. data/lib/jwt/jwk/set.rb +2 -0
  45. data/lib/jwt/jwk.rb +1 -1
  46. data/lib/jwt/token.rb +131 -0
  47. data/lib/jwt/version.rb +24 -19
  48. data/lib/jwt.rb +18 -4
  49. data/ruby-jwt.gemspec +2 -0
  50. metadata +49 -15
  51. data/lib/jwt/claims_validator.rb +0 -37
  52. data/lib/jwt/deprecations.rb +0 -48
  53. data/lib/jwt/jwa/eddsa.rb +0 -42
  54. data/lib/jwt/jwa/hmac_rbnacl.rb +0 -50
  55. data/lib/jwt/jwa/hmac_rbnacl_fixed.rb +0 -46
  56. data/lib/jwt/jwa/wrapper.rb +0 -26
  57. data/lib/jwt/jwk/okp_rbnacl.rb +0 -110
  58. data/lib/jwt/verify.rb +0 -117
data/lib/jwt/jwk/hmac.rb CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  module JWT
4
4
  module JWK
5
+ # JWK for HMAC keys
5
6
  class HMAC < KeyBase
6
7
  KTY = 'oct'
7
8
  KTYS = [KTY, String, JWT::JWK::HMAC].freeze
@@ -61,17 +62,15 @@ module JWT
61
62
  end
62
63
 
63
64
  def []=(key, value)
64
- if HMAC_KEY_ELEMENTS.include?(key.to_sym)
65
- raise ArgumentError, 'cannot overwrite cryptographic key attributes'
66
- end
65
+ raise ArgumentError, 'cannot overwrite cryptographic key attributes' if HMAC_KEY_ELEMENTS.include?(key.to_sym)
67
66
 
68
- super(key, value)
67
+ super
69
68
  end
70
69
 
71
70
  private
72
71
 
73
72
  def secret
74
- self[:k]
73
+ @secret ||= ::JWT::Base64.url_decode(self[:k])
75
74
  end
76
75
 
77
76
  def extract_key_params(key)
@@ -79,7 +78,7 @@ module JWT
79
78
  when JWT::JWK::HMAC
80
79
  key.export(include_private: true)
81
80
  when String # Accept String key as input
82
- { kty: KTY, k: key }
81
+ { kty: KTY, k: ::JWT::Base64.url_encode(key) }
83
82
  when Hash
84
83
  key.transform_keys(&:to_sym)
85
84
  else
@@ -2,6 +2,7 @@
2
2
 
3
3
  module JWT
4
4
  module JWK
5
+ # Base for JWK implementations
5
6
  class KeyBase
6
7
  def self.inherited(klass)
7
8
  super
@@ -41,6 +42,14 @@ module JWT
41
42
  other.is_a?(::JWT::JWK::KeyBase) && self[:kid] == other[:kid]
42
43
  end
43
44
 
45
+ def verify(**kwargs)
46
+ jwa.verify(**kwargs, verification_key: verify_key)
47
+ end
48
+
49
+ def sign(**kwargs)
50
+ jwa.sign(**kwargs, signing_key: signing_key)
51
+ end
52
+
44
53
  alias eql? ==
45
54
 
46
55
  def <=>(other)
@@ -49,7 +58,13 @@ module JWT
49
58
  self[:kid] <=> other[:kid]
50
59
  end
51
60
 
52
- private
61
+ def jwa
62
+ raise JWT::JWKError, 'Could not resolve the JWA, the "alg" parameter is missing' unless self[:alg]
63
+
64
+ JWA.resolve(self[:alg]).tap do |jwa|
65
+ raise JWT::JWKError, 'none algorithm usage not supported via JWK' if jwa.is_a?(JWA::None)
66
+ end
67
+ end
53
68
 
54
69
  attr_reader :parameters
55
70
  end
@@ -2,7 +2,16 @@
2
2
 
3
3
  module JWT
4
4
  module JWK
5
+ # JSON Web Key keyfinder
6
+ # To find the key for a given kid
5
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
12
+ # @option options [Array] :key_fields the fields to use for key matching,
13
+ # the order of the fields are used to determine
14
+ # the priority of the keys.
6
15
  def initialize(options)
7
16
  @allow_nil_kid = options[:allow_nil_kid]
8
17
  jwks_or_loader = options[:jwks]
@@ -12,13 +21,16 @@ module JWT
12
21
  else
13
22
  ->(_options) { jwks_or_loader }
14
23
  end
24
+
25
+ @key_fields = options[:key_fields] || %i[kid]
15
26
  end
16
27
 
17
- def key_for(kid)
18
- raise ::JWT::DecodeError, 'No key id (kid) found from token headers' unless kid || @allow_nil_kid
19
- raise ::JWT::DecodeError, 'Invalid type for kid header parameter' unless kid.nil? || kid.is_a?(String)
28
+ # Returns the verification key for the given kid
29
+ # @param [String] kid the key id
30
+ def key_for(kid, key_field = :kid)
31
+ raise ::JWT::DecodeError, "Invalid type for #{key_field} header parameter" unless kid.nil? || kid.is_a?(String)
20
32
 
21
- jwk = resolve_key(kid)
33
+ jwk = resolve_key(kid, key_field)
22
34
 
23
35
  raise ::JWT::DecodeError, 'No keys found in jwks' unless @jwks.any?
24
36
  raise ::JWT::DecodeError, "Could not find public key for kid #{kid}" unless jwk
@@ -26,19 +38,34 @@ module JWT
26
38
  jwk.verify_key
27
39
  end
28
40
 
41
+ # Returns the key for the given token
42
+ # @param [JWT::EncodedToken] token the token
43
+ def call(token)
44
+ @key_fields.each do |key_field|
45
+ field_value = token.header[key_field.to_s]
46
+
47
+ return key_for(field_value, key_field) if field_value
48
+ end
49
+
50
+ raise ::JWT::DecodeError, 'No key id (kid) or x5t found from token headers' unless @allow_nil_kid
51
+
52
+ kid = token.header['kid']
53
+ key_for(kid)
54
+ end
55
+
29
56
  private
30
57
 
31
- def resolve_key(kid)
32
- key_matcher = ->(key) { (kid.nil? && @allow_nil_kid) || key[:kid] == kid }
58
+ def resolve_key(kid, key_field)
59
+ key_matcher = ->(key) { (kid.nil? && @allow_nil_kid) || key[key_field] == kid }
33
60
 
34
61
  # First try without invalidation to facilitate application caching
35
- @jwks ||= JWT::JWK::Set.new(@jwks_loader.call(kid: kid))
62
+ @jwks ||= JWT::JWK::Set.new(@jwks_loader.call(key_field => kid))
36
63
  jwk = @jwks.find { |key| key_matcher.call(key) }
37
64
 
38
65
  return jwk if jwk
39
66
 
40
67
  # Second try, invalidate for backwards compatibility
41
- @jwks = JWT::JWK::Set.new(@jwks_loader.call(invalidate: true, kid_not_found: true, kid: kid))
68
+ @jwks = JWT::JWK::Set.new(@jwks_loader.call(invalidate: true, kid_not_found: true, key_field => kid))
42
69
  @jwks.find { |key| key_matcher.call(key) }
43
70
  end
44
71
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  module JWT
4
4
  module JWK
5
+ # @api private
5
6
  class KidAsKeyDigest
6
7
  def initialize(jwk)
7
8
  @jwk = jwk
data/lib/jwt/jwk/rsa.rb CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  module JWT
4
4
  module JWK
5
+ # JSON Web Key (JWK) representation of a RSA key
5
6
  class RSA < KeyBase # rubocop:disable Metrics/ClassLength
6
7
  BINARY = 2
7
8
  KTY = 'RSA'
@@ -50,6 +51,7 @@ module JWT
50
51
  def export(options = {})
51
52
  exported = parameters.clone
52
53
  exported.reject! { |k, _| RSA_PRIVATE_KEY_ELEMENTS.include? k } unless private? && options[:include_private] == true
54
+
53
55
  exported
54
56
  end
55
57
 
@@ -64,11 +66,9 @@ module JWT
64
66
  end
65
67
 
66
68
  def []=(key, value)
67
- if RSA_KEY_ELEMENTS.include?(key.to_sym)
68
- raise ArgumentError, 'cannot overwrite cryptographic key attributes'
69
- end
69
+ raise ArgumentError, 'cannot overwrite cryptographic key attributes' if RSA_KEY_ELEMENTS.include?(key.to_sym)
70
70
 
71
- super(key, value)
71
+ super
72
72
  end
73
73
 
74
74
  private
@@ -166,6 +166,8 @@ module JWT
166
166
  end
167
167
  end
168
168
 
169
+ # :nocov:
170
+ # Before openssl 2.0, we need to use the accessors to set the key
169
171
  def create_rsa_key_using_accessors(rsa_parameters) # rubocop:disable Metrics/AbcSize
170
172
  validate_rsa_parameters!(rsa_parameters)
171
173
 
@@ -180,6 +182,7 @@ module JWT
180
182
  rsa_key.iqmp = rsa_parameters[:qi] if rsa_parameters[:qi]
181
183
  end
182
184
  end
185
+ # :nocov:
183
186
 
184
187
  def validate_rsa_parameters!(rsa_parameters)
185
188
  return unless rsa_parameters.key?(:d)
data/lib/jwt/jwk/set.rb CHANGED
@@ -4,6 +4,8 @@ require 'forwardable'
4
4
 
5
5
  module JWT
6
6
  module JWK
7
+ # JSON Web Key Set (JWKS) representation
8
+ # https://tools.ietf.org/html/rfc7517
7
9
  class Set
8
10
  include Enumerable
9
11
  extend Forwardable
data/lib/jwt/jwk.rb CHANGED
@@ -4,6 +4,7 @@ require_relative 'jwk/key_finder'
4
4
  require_relative 'jwk/set'
5
5
 
6
6
  module JWT
7
+ # JSON Web Key (JWK)
7
8
  module JWK
8
9
  class << self
9
10
  def create_from(key, params = nil, options = {})
@@ -52,4 +53,3 @@ require_relative 'jwk/key_base'
52
53
  require_relative 'jwk/ec'
53
54
  require_relative 'jwk/rsa'
54
55
  require_relative 'jwk/hmac'
55
- require_relative 'jwk/okp_rbnacl' if JWT.rbnacl?
data/lib/jwt/token.rb ADDED
@@ -0,0 +1,131 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JWT
4
+ # Represents a JWT token
5
+ #
6
+ # Basic token signed using the HS256 algorithm:
7
+ #
8
+ # token = JWT::Token.new(payload: {pay: 'load'})
9
+ # token.sign!(algorithm: 'HS256', key: 'secret')
10
+ # token.jwt # => eyJhb....
11
+ #
12
+ # Custom headers will be combined with generated headers:
13
+ # token = JWT::Token.new(payload: {pay: 'load'}, header: {custom: "value"})
14
+ # token.sign!(algorithm: 'HS256', key: 'secret')
15
+ # token.header # => {"custom"=>"value", "alg"=>"HS256"}
16
+ #
17
+ class Token
18
+ # Initializes a new Token instance.
19
+ #
20
+ # @param header [Hash] the header of the JWT token.
21
+ # @param payload [Hash] the payload of the JWT token.
22
+ def initialize(payload:, header: {})
23
+ @header = header&.transform_keys(&:to_s)
24
+ @payload = payload
25
+ end
26
+
27
+ # Returns the decoded signature of the JWT token.
28
+ #
29
+ # @return [String] the decoded signature of the JWT token.
30
+ def signature
31
+ @signature ||= ::JWT::Base64.url_decode(encoded_signature || '')
32
+ end
33
+
34
+ # Returns the encoded signature of the JWT token.
35
+ #
36
+ # @return [String] the encoded signature of the JWT token.
37
+ def encoded_signature
38
+ @encoded_signature ||= ::JWT::Base64.url_encode(signature)
39
+ end
40
+
41
+ # Returns the decoded header of the JWT token.
42
+ #
43
+ # @return [Hash] the header of the JWT token.
44
+ attr_reader :header
45
+
46
+ # Returns the encoded header of the JWT token.
47
+ #
48
+ # @return [String] the encoded header of the JWT token.
49
+ def encoded_header
50
+ @encoded_header ||= ::JWT::Base64.url_encode(JWT::JSON.generate(header))
51
+ end
52
+
53
+ # Returns the payload of the JWT token.
54
+ #
55
+ # @return [Hash] the payload of the JWT token.
56
+ attr_reader :payload
57
+
58
+ # Returns the encoded payload of the JWT token.
59
+ #
60
+ # @return [String] the encoded payload of the JWT token.
61
+ def encoded_payload
62
+ @encoded_payload ||= ::JWT::Base64.url_encode(JWT::JSON.generate(payload))
63
+ end
64
+
65
+ # Returns the signing input of the JWT token.
66
+ #
67
+ # @return [String] the signing input of the JWT token.
68
+ def signing_input
69
+ @signing_input ||= [encoded_header, encoded_payload].join('.')
70
+ end
71
+
72
+ # Returns the JWT token as a string.
73
+ #
74
+ # @return [String] the JWT token as a string.
75
+ # @raise [JWT::EncodeError] if the token is not signed or other encoding issues
76
+ def jwt
77
+ @jwt ||= (@signature && [encoded_header, @detached_payload ? '' : encoded_payload, encoded_signature].join('.')) || raise(::JWT::EncodeError, 'Token is not signed')
78
+ end
79
+
80
+ # Detaches the payload according to https://datatracker.ietf.org/doc/html/rfc7515#appendix-F
81
+ #
82
+ def detach_payload!
83
+ @detached_payload = true
84
+
85
+ nil
86
+ end
87
+
88
+ # Signs the JWT token.
89
+ #
90
+ # @param key [String, JWT::JWK::KeyBase] the key to use for signing.
91
+ # @param algorithm [String, Object] the algorithm to use for signing.
92
+ # @return [void]
93
+ # @raise [JWT::EncodeError] if the token is already signed or other problems when signing
94
+ def sign!(key:, algorithm:)
95
+ raise ::JWT::EncodeError, 'Token already signed' if @signature
96
+
97
+ JWA.create_signer(algorithm: algorithm, key: key).tap do |signer|
98
+ header.merge!(signer.jwa.header) { |_key, old, _new| old }
99
+ @signature = signer.sign(data: signing_input)
100
+ end
101
+
102
+ nil
103
+ end
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
+
126
+ # Returns the JWT token as a string.
127
+ #
128
+ # @return [String] the JWT token as a string.
129
+ alias to_s jwt
130
+ end
131
+ end
data/lib/jwt/version.rb CHANGED
@@ -1,44 +1,49 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Moments version builder module
3
+ # JSON Web Token implementation
4
+ #
5
+ # Should be up to date with the latest spec:
6
+ # https://tools.ietf.org/html/rfc7519
4
7
  module JWT
8
+ # Returns the gem version of the JWT library.
9
+ #
10
+ # @return [Gem::Version] the gem version.
5
11
  def self.gem_version
6
- Gem::Version.new VERSION::STRING
12
+ Gem::Version.new(VERSION::STRING)
7
13
  end
8
14
 
9
- # Moments version builder module
15
+ # Version constants
10
16
  module VERSION
11
- # major version
12
- MAJOR = 2
13
- # minor version
14
- MINOR = 8
15
- # tiny version
16
- TINY = 2
17
- # alpha, beta, etc. tag
17
+ MAJOR = 3
18
+ MINOR = 1
19
+ TINY = 1
18
20
  PRE = nil
19
21
 
20
- # Build version string
21
22
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
22
23
  end
23
24
 
25
+ # Checks if the OpenSSL version is 3 or greater.
26
+ #
27
+ # @return [Boolean] true if OpenSSL version is 3 or greater, false otherwise.
28
+ # @api private
24
29
  def self.openssl_3?
25
30
  return false if OpenSSL::OPENSSL_VERSION.include?('LibreSSL')
26
31
 
27
32
  true if 3 * 0x10000000 <= OpenSSL::OPENSSL_VERSION_NUMBER
28
33
  end
29
34
 
30
- def self.rbnacl?
31
- defined?(::RbNaCl)
32
- end
33
-
34
- def self.rbnacl_6_or_greater?
35
- rbnacl? && ::Gem::Version.new(::RbNaCl::VERSION) >= ::Gem::Version.new('6.0.0')
36
- end
37
-
35
+ # Checks if there is an OpenSSL 3 HMAC empty key regression.
36
+ #
37
+ # @return [Boolean] true if there is an OpenSSL 3 HMAC empty key regression, false otherwise.
38
+ # @api private
38
39
  def self.openssl_3_hmac_empty_key_regression?
39
40
  openssl_3? && openssl_version <= ::Gem::Version.new('3.0.0')
40
41
  end
41
42
 
43
+ # Returns the OpenSSL version.
44
+ #
45
+ # @return [Gem::Version] the OpenSSL version.
46
+ # @api private
42
47
  def self.openssl_version
43
48
  @openssl_version ||= ::Gem::Version.new(OpenSSL::VERSION)
44
49
  end
data/lib/jwt.rb CHANGED
@@ -5,10 +5,12 @@ 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'
11
+ require 'jwt/claims'
12
+ require 'jwt/encoded_token'
13
+ require 'jwt/token'
12
14
 
13
15
  # JSON Web Token implementation
14
16
  #
@@ -19,6 +21,13 @@ module JWT
19
21
 
20
22
  module_function
21
23
 
24
+ # Encodes a payload into a JWT.
25
+ #
26
+ # @param payload [Hash] the payload to encode.
27
+ # @param key [String] the key used to sign the JWT.
28
+ # @param algorithm [String] the algorithm used to sign the JWT.
29
+ # @param header_fields [Hash] additional headers to include in the JWT.
30
+ # @return [String] the encoded JWT.
22
31
  def encode(payload, key, algorithm = 'HS256', header_fields = {})
23
32
  Encode.new(payload: payload,
24
33
  key: key,
@@ -26,9 +35,14 @@ module JWT
26
35
  headers: header_fields).segments
27
36
  end
28
37
 
38
+ # Decodes a JWT to extract the payload and header
39
+ #
40
+ # @param jwt [String] the JWT to decode.
41
+ # @param key [String] the key used to verify the JWT.
42
+ # @param verify [Boolean] whether to verify the JWT signature.
43
+ # @param options [Hash] additional options for decoding.
44
+ # @return [Array<Hash>] the decoded payload and headers.
29
45
  def decode(jwt, key = nil, verify = true, options = {}, &keyfinder) # rubocop:disable Style/OptionalBooleanParameter
30
- Deprecations.context do
31
- Decode.new(jwt, key, verify, configuration.decode.to_h.merge(options), &keyfinder).decode_segments
32
- end
46
+ Decode.new(jwt, key, verify, configuration.decode.to_h.merge(options), &keyfinder).decode_segments
33
47
  end
34
48
  end
data/ruby-jwt.gemspec CHANGED
@@ -35,6 +35,8 @@ 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 'irb'
39
+ spec.add_development_dependency 'logger'
38
40
  spec.add_development_dependency 'rake'
39
41
  spec.add_development_dependency 'rspec'
40
42
  spec.add_development_dependency 'rubocop'
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jwt
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.8.2
4
+ version: 3.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Rudat
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-06-18 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: base64
@@ -52,6 +51,34 @@ dependencies:
52
51
  - - ">="
53
52
  - !ruby/object:Gem::Version
54
53
  version: '0'
54
+ - !ruby/object:Gem::Dependency
55
+ name: irb
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
+ - !ruby/object:Gem::Dependency
69
+ name: logger
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ type: :development
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
55
82
  - !ruby/object:Gem::Dependency
56
83
  name: rake
57
84
  requirement: !ruby/object:Gem::Requirement
@@ -121,40 +148,49 @@ files:
121
148
  - CONTRIBUTING.md
122
149
  - LICENSE
123
150
  - README.md
151
+ - UPGRADING.md
124
152
  - lib/jwt.rb
125
153
  - lib/jwt/base64.rb
126
- - lib/jwt/claims_validator.rb
154
+ - lib/jwt/claims.rb
155
+ - lib/jwt/claims/audience.rb
156
+ - lib/jwt/claims/crit.rb
157
+ - lib/jwt/claims/decode_verifier.rb
158
+ - lib/jwt/claims/expiration.rb
159
+ - lib/jwt/claims/issued_at.rb
160
+ - lib/jwt/claims/issuer.rb
161
+ - lib/jwt/claims/jwt_id.rb
162
+ - lib/jwt/claims/not_before.rb
163
+ - lib/jwt/claims/numeric.rb
164
+ - lib/jwt/claims/required.rb
165
+ - lib/jwt/claims/subject.rb
166
+ - lib/jwt/claims/verifier.rb
127
167
  - lib/jwt/configuration.rb
128
168
  - lib/jwt/configuration/container.rb
129
169
  - lib/jwt/configuration/decode_configuration.rb
130
170
  - lib/jwt/configuration/jwk_configuration.rb
131
171
  - lib/jwt/decode.rb
132
- - lib/jwt/deprecations.rb
133
172
  - lib/jwt/encode.rb
173
+ - lib/jwt/encoded_token.rb
134
174
  - lib/jwt/error.rb
135
175
  - lib/jwt/json.rb
136
176
  - lib/jwt/jwa.rb
137
177
  - lib/jwt/jwa/ecdsa.rb
138
- - lib/jwt/jwa/eddsa.rb
139
178
  - lib/jwt/jwa/hmac.rb
140
- - lib/jwt/jwa/hmac_rbnacl.rb
141
- - lib/jwt/jwa/hmac_rbnacl_fixed.rb
142
179
  - lib/jwt/jwa/none.rb
143
180
  - lib/jwt/jwa/ps.rb
144
181
  - lib/jwt/jwa/rsa.rb
182
+ - lib/jwt/jwa/signing_algorithm.rb
145
183
  - lib/jwt/jwa/unsupported.rb
146
- - lib/jwt/jwa/wrapper.rb
147
184
  - lib/jwt/jwk.rb
148
185
  - lib/jwt/jwk/ec.rb
149
186
  - lib/jwt/jwk/hmac.rb
150
187
  - lib/jwt/jwk/key_base.rb
151
188
  - lib/jwt/jwk/key_finder.rb
152
189
  - lib/jwt/jwk/kid_as_key_digest.rb
153
- - lib/jwt/jwk/okp_rbnacl.rb
154
190
  - lib/jwt/jwk/rsa.rb
155
191
  - lib/jwt/jwk/set.rb
156
192
  - lib/jwt/jwk/thumbprint.rb
157
- - lib/jwt/verify.rb
193
+ - lib/jwt/token.rb
158
194
  - lib/jwt/version.rb
159
195
  - lib/jwt/x5c_key_finder.rb
160
196
  - ruby-jwt.gemspec
@@ -163,9 +199,8 @@ licenses:
163
199
  - MIT
164
200
  metadata:
165
201
  bug_tracker_uri: https://github.com/jwt/ruby-jwt/issues
166
- changelog_uri: https://github.com/jwt/ruby-jwt/blob/v2.8.2/CHANGELOG.md
202
+ changelog_uri: https://github.com/jwt/ruby-jwt/blob/v3.1.1/CHANGELOG.md
167
203
  rubygems_mfa_required: 'true'
168
- post_install_message:
169
204
  rdoc_options: []
170
205
  require_paths:
171
206
  - lib
@@ -180,8 +215,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
180
215
  - !ruby/object:Gem::Version
181
216
  version: '0'
182
217
  requirements: []
183
- rubygems_version: 3.5.3
184
- signing_key:
218
+ rubygems_version: 3.6.7
185
219
  specification_version: 4
186
220
  summary: JSON Web Token implementation in Ruby
187
221
  test_files: []
@@ -1,37 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'error'
4
-
5
- module JWT
6
- class ClaimsValidator
7
- NUMERIC_CLAIMS = %i[
8
- exp
9
- iat
10
- nbf
11
- ].freeze
12
-
13
- def initialize(payload)
14
- @payload = payload.transform_keys(&:to_sym)
15
- end
16
-
17
- def validate!
18
- validate_numeric_claims
19
-
20
- true
21
- end
22
-
23
- private
24
-
25
- def validate_numeric_claims
26
- NUMERIC_CLAIMS.each do |claim|
27
- validate_is_numeric(claim) if @payload.key?(claim)
28
- end
29
- end
30
-
31
- def validate_is_numeric(claim)
32
- return if @payload[claim].is_a?(Numeric)
33
-
34
- raise InvalidPayload, "#{claim} claim must be a Numeric value but it is a #{@payload[claim].class}"
35
- end
36
- end
37
- end