jwt 2.4.1 → 2.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +33 -2
  3. data/CONTRIBUTING.md +7 -7
  4. data/README.md +135 -31
  5. data/lib/jwt/algos/algo_wrapper.rb +30 -0
  6. data/lib/jwt/algos/ecdsa.rb +2 -4
  7. data/lib/jwt/algos/eddsa.rb +4 -4
  8. data/lib/jwt/algos/hmac.rb +54 -17
  9. data/lib/jwt/algos/hmac_rbnacl.rb +53 -0
  10. data/lib/jwt/algos/hmac_rbnacl_fixed.rb +52 -0
  11. data/lib/jwt/algos/none.rb +3 -1
  12. data/lib/jwt/algos/ps.rb +3 -5
  13. data/lib/jwt/algos/rsa.rb +3 -4
  14. data/lib/jwt/algos.rb +38 -15
  15. data/lib/jwt/base64.rb +19 -0
  16. data/lib/jwt/configuration/container.rb +21 -0
  17. data/lib/jwt/configuration/decode_configuration.rb +46 -0
  18. data/lib/jwt/configuration/jwk_configuration.rb +27 -0
  19. data/lib/jwt/configuration.rb +15 -0
  20. data/lib/jwt/decode.rb +48 -27
  21. data/lib/jwt/encode.rb +30 -20
  22. data/lib/jwt/jwk/ec.rb +131 -62
  23. data/lib/jwt/jwk/hmac.rb +59 -24
  24. data/lib/jwt/jwk/key_base.rb +43 -7
  25. data/lib/jwt/jwk/key_finder.rb +14 -34
  26. data/lib/jwt/jwk/kid_as_key_digest.rb +15 -0
  27. data/lib/jwt/jwk/rsa.rb +128 -53
  28. data/lib/jwt/jwk/set.rb +80 -0
  29. data/lib/jwt/jwk/thumbprint.rb +26 -0
  30. data/lib/jwt/jwk.rb +13 -11
  31. data/lib/jwt/security_utils.rb +0 -27
  32. data/lib/jwt/version.rb +23 -2
  33. data/lib/jwt/x5c_key_finder.rb +1 -1
  34. data/lib/jwt.rb +5 -4
  35. data/ruby-jwt.gemspec +8 -4
  36. metadata +15 -30
  37. data/.codeclimate.yml +0 -8
  38. data/.github/workflows/coverage.yml +0 -27
  39. data/.github/workflows/test.yml +0 -66
  40. data/.gitignore +0 -13
  41. data/.reek.yml +0 -22
  42. data/.rspec +0 -2
  43. data/.rubocop.yml +0 -67
  44. data/.sourcelevel.yml +0 -17
  45. data/Appraisals +0 -13
  46. data/Gemfile +0 -7
  47. data/Rakefile +0 -16
  48. data/lib/jwt/default_options.rb +0 -18
  49. data/lib/jwt/signature.rb +0 -35
data/lib/jwt/jwk/rsa.rb CHANGED
@@ -2,16 +2,33 @@
2
2
 
3
3
  module JWT
4
4
  module JWK
5
- class RSA < KeyBase
5
+ class RSA < KeyBase # rubocop:disable Metrics/ClassLength
6
6
  BINARY = 2
7
7
  KTY = 'RSA'
8
- KTYS = [KTY, OpenSSL::PKey::RSA].freeze
9
- RSA_KEY_ELEMENTS = %i[n e d p q dp dq qi].freeze
8
+ KTYS = [KTY, OpenSSL::PKey::RSA, JWT::JWK::RSA].freeze
9
+ RSA_PUBLIC_KEY_ELEMENTS = %i[kty n e].freeze
10
+ RSA_PRIVATE_KEY_ELEMENTS = %i[d p q dp dq qi].freeze
11
+ RSA_KEY_ELEMENTS = (RSA_PRIVATE_KEY_ELEMENTS + RSA_PUBLIC_KEY_ELEMENTS).freeze
10
12
 
11
- def initialize(keypair, kid = nil)
12
- raise ArgumentError, 'keypair must be of type OpenSSL::PKey::RSA' unless keypair.is_a?(OpenSSL::PKey::RSA)
13
+ RSA_OPT_PARAMS = %i[p q dp dq qi].freeze
14
+ RSA_ASN1_SEQUENCE = (%i[n e d] + RSA_OPT_PARAMS).freeze # https://www.rfc-editor.org/rfc/rfc3447#appendix-A.1.2
13
15
 
14
- super(keypair, kid || generate_kid(keypair.public_key))
16
+ def initialize(key, params = nil, options = {})
17
+ params ||= {}
18
+
19
+ # For backwards compatibility when kid was a String
20
+ params = { kid: params } if params.is_a?(String)
21
+
22
+ key_params = extract_key_params(key)
23
+
24
+ params = params.transform_keys(&:to_sym)
25
+ check_jwk(key_params, params)
26
+
27
+ super(options, key_params.merge(params))
28
+ end
29
+
30
+ def keypair
31
+ @keypair ||= self.class.create_rsa_key(jwk_attributes(*(RSA_KEY_ELEMENTS - [:kty])))
15
32
  end
16
33
 
17
34
  def private?
@@ -23,75 +40,124 @@ module JWT
23
40
  end
24
41
 
25
42
  def export(options = {})
26
- exported_hash = {
27
- kty: KTY,
28
- n: encode_open_ssl_bn(public_key.n),
29
- e: encode_open_ssl_bn(public_key.e),
30
- kid: kid
31
- }
32
-
33
- return exported_hash unless private? && options[:include_private] == true
34
-
35
- append_private_parts(exported_hash)
43
+ exported = parameters.clone
44
+ exported.reject! { |k, _| RSA_PRIVATE_KEY_ELEMENTS.include? k } unless private? && options[:include_private] == true
45
+ exported
36
46
  end
37
47
 
38
- private
48
+ def members
49
+ RSA_PUBLIC_KEY_ELEMENTS.each_with_object({}) { |i, h| h[i] = self[i] }
50
+ end
39
51
 
40
- def generate_kid(public_key)
52
+ def key_digest
41
53
  sequence = OpenSSL::ASN1::Sequence([OpenSSL::ASN1::Integer.new(public_key.n),
42
54
  OpenSSL::ASN1::Integer.new(public_key.e)])
43
55
  OpenSSL::Digest::SHA256.hexdigest(sequence.to_der)
44
56
  end
45
57
 
46
- def append_private_parts(the_hash)
47
- the_hash.merge(
48
- d: encode_open_ssl_bn(keypair.d),
49
- p: encode_open_ssl_bn(keypair.p),
50
- q: encode_open_ssl_bn(keypair.q),
51
- dp: encode_open_ssl_bn(keypair.dmp1),
52
- dq: encode_open_ssl_bn(keypair.dmq1),
53
- qi: encode_open_ssl_bn(keypair.iqmp)
54
- )
58
+ def []=(key, value)
59
+ if RSA_KEY_ELEMENTS.include?(key.to_sym)
60
+ raise ArgumentError, 'cannot overwrite cryptographic key attributes'
61
+ end
62
+
63
+ super(key, value)
64
+ end
65
+
66
+ private
67
+
68
+ def extract_key_params(key)
69
+ case key
70
+ when JWT::JWK::RSA
71
+ key.export(include_private: true)
72
+ when OpenSSL::PKey::RSA # Accept OpenSSL key as input
73
+ @keypair = key # Preserve the object to avoid recreation
74
+ parse_rsa_key(key)
75
+ when Hash
76
+ key.transform_keys(&:to_sym)
77
+ else
78
+ raise ArgumentError, 'key must be of type OpenSSL::PKey::RSA or Hash with key parameters'
79
+ end
80
+ end
81
+
82
+ def check_jwk(keypair, params)
83
+ raise ArgumentError, 'cannot overwrite cryptographic key attributes' unless (RSA_KEY_ELEMENTS & params.keys).empty?
84
+ raise JWT::JWKError, "Incorrect 'kty' value: #{keypair[:kty]}, expected #{KTY}" unless keypair[:kty] == KTY
85
+ raise JWT::JWKError, 'Key format is invalid for RSA' unless keypair[:n] && keypair[:e]
86
+ end
87
+
88
+ def parse_rsa_key(key)
89
+ {
90
+ kty: KTY,
91
+ n: encode_open_ssl_bn(key.n),
92
+ e: encode_open_ssl_bn(key.e),
93
+ d: encode_open_ssl_bn(key.d),
94
+ p: encode_open_ssl_bn(key.p),
95
+ q: encode_open_ssl_bn(key.q),
96
+ dp: encode_open_ssl_bn(key.dmp1),
97
+ dq: encode_open_ssl_bn(key.dmq1),
98
+ qi: encode_open_ssl_bn(key.iqmp)
99
+ }.compact
100
+ end
101
+
102
+ def jwk_attributes(*attributes)
103
+ attributes.each_with_object({}) do |attribute, hash|
104
+ hash[attribute] = decode_open_ssl_bn(self[attribute])
105
+ end
55
106
  end
56
107
 
57
108
  def encode_open_ssl_bn(key_part)
58
- Base64.urlsafe_encode64(key_part.to_s(BINARY), padding: false)
109
+ return unless key_part
110
+
111
+ ::JWT::Base64.url_encode(key_part.to_s(BINARY))
112
+ end
113
+
114
+ def decode_open_ssl_bn(jwk_data)
115
+ self.class.decode_open_ssl_bn(jwk_data)
59
116
  end
60
117
 
61
118
  class << self
62
119
  def import(jwk_data)
63
- pkey_params = jwk_attributes(jwk_data, *RSA_KEY_ELEMENTS) do |value|
64
- decode_open_ssl_bn(value)
65
- end
66
- kid = jwk_attributes(jwk_data, :kid)[:kid]
67
- new(rsa_pkey(pkey_params), kid)
120
+ new(jwk_data)
68
121
  end
69
122
 
70
- private
123
+ def decode_open_ssl_bn(jwk_data)
124
+ return nil unless jwk_data
71
125
 
72
- def jwk_attributes(jwk_data, *attributes)
73
- attributes.each_with_object({}) do |attribute, hash|
74
- value = jwk_data[attribute] || jwk_data[attribute.to_s]
75
- value = yield(value) if block_given?
76
- hash[attribute] = value
77
- end
126
+ OpenSSL::BN.new(::JWT::Base64.url_decode(jwk_data), BINARY)
78
127
  end
79
128
 
80
- def rsa_pkey(rsa_parameters)
81
- raise JWT::JWKError, 'Key format is invalid for RSA' unless rsa_parameters[:n] && rsa_parameters[:e]
129
+ def create_rsa_key_using_der(rsa_parameters)
130
+ validate_rsa_parameters!(rsa_parameters)
131
+
132
+ sequence = RSA_ASN1_SEQUENCE.each_with_object([]) do |key, arr|
133
+ next if rsa_parameters[key].nil?
134
+
135
+ arr << OpenSSL::ASN1::Integer.new(rsa_parameters[key])
136
+ end
137
+
138
+ if sequence.size > 2 # Append "two-prime" version for private key
139
+ sequence.unshift(OpenSSL::ASN1::Integer.new(0))
140
+
141
+ raise JWT::JWKError, 'Creating a RSA key with a private key requires the CRT parameters to be defined' if sequence.size < RSA_ASN1_SEQUENCE.size
142
+ end
82
143
 
83
- populate_key(OpenSSL::PKey::RSA.new, rsa_parameters)
144
+ OpenSSL::PKey::RSA.new(OpenSSL::ASN1::Sequence(sequence).to_der)
84
145
  end
85
146
 
86
- if OpenSSL::PKey::RSA.new.respond_to?(:set_key)
87
- def populate_key(rsa_key, rsa_parameters)
147
+ def create_rsa_key_using_sets(rsa_parameters)
148
+ validate_rsa_parameters!(rsa_parameters)
149
+
150
+ OpenSSL::PKey::RSA.new.tap do |rsa_key|
88
151
  rsa_key.set_key(rsa_parameters[:n], rsa_parameters[:e], rsa_parameters[:d])
89
152
  rsa_key.set_factors(rsa_parameters[:p], rsa_parameters[:q]) if rsa_parameters[:p] && rsa_parameters[:q]
90
153
  rsa_key.set_crt_params(rsa_parameters[:dp], rsa_parameters[:dq], rsa_parameters[:qi]) if rsa_parameters[:dp] && rsa_parameters[:dq] && rsa_parameters[:qi]
91
- rsa_key
92
154
  end
93
- else
94
- def populate_key(rsa_key, rsa_parameters)
155
+ end
156
+
157
+ def create_rsa_key_using_accessors(rsa_parameters) # rubocop:disable Metrics/AbcSize
158
+ validate_rsa_parameters!(rsa_parameters)
159
+
160
+ OpenSSL::PKey::RSA.new.tap do |rsa_key|
95
161
  rsa_key.n = rsa_parameters[:n]
96
162
  rsa_key.e = rsa_parameters[:e]
97
163
  rsa_key.d = rsa_parameters[:d] if rsa_parameters[:d]
@@ -100,15 +166,24 @@ module JWT
100
166
  rsa_key.dmp1 = rsa_parameters[:dp] if rsa_parameters[:dp]
101
167
  rsa_key.dmq1 = rsa_parameters[:dq] if rsa_parameters[:dq]
102
168
  rsa_key.iqmp = rsa_parameters[:qi] if rsa_parameters[:qi]
103
-
104
- rsa_key
105
169
  end
106
170
  end
107
171
 
108
- def decode_open_ssl_bn(jwk_data)
109
- return nil unless jwk_data
172
+ def validate_rsa_parameters!(rsa_parameters)
173
+ return unless rsa_parameters.key?(:d)
174
+
175
+ parameters = RSA_OPT_PARAMS - rsa_parameters.keys
176
+ return if parameters.empty? || parameters.size == RSA_OPT_PARAMS.size
110
177
 
111
- OpenSSL::BN.new(Base64.urlsafe_decode64(jwk_data), BINARY)
178
+ raise JWT::JWKError, 'When one of p, q, dp, dq or qi is given all the other optimization parameters also needs to be defined' # https://www.rfc-editor.org/rfc/rfc7518.html#section-6.3.2
179
+ end
180
+
181
+ if ::JWT.openssl_3?
182
+ alias create_rsa_key create_rsa_key_using_der
183
+ elsif OpenSSL::PKey::RSA.new.respond_to?(:set_key)
184
+ alias create_rsa_key create_rsa_key_using_sets
185
+ else
186
+ alias create_rsa_key create_rsa_key_using_accessors
112
187
  end
113
188
  end
114
189
  end
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'forwardable'
4
+
5
+ module JWT
6
+ module JWK
7
+ class Set
8
+ include Enumerable
9
+ extend Forwardable
10
+
11
+ attr_reader :keys
12
+
13
+ def initialize(jwks = nil, options = {}) # rubocop:disable Metrics/CyclomaticComplexity
14
+ jwks ||= {}
15
+
16
+ @keys = case jwks
17
+ when JWT::JWK::Set # Simple duplication
18
+ jwks.keys
19
+ when JWT::JWK::KeyBase # Singleton
20
+ [jwks]
21
+ when Hash
22
+ jwks = jwks.transform_keys(&:to_sym)
23
+ [*jwks[:keys]].map { |k| JWT::JWK.new(k, nil, options) }
24
+ when Array
25
+ jwks.map { |k| JWT::JWK.new(k, nil, options) }
26
+ else
27
+ raise ArgumentError, 'Can only create new JWKS from Hash, Array and JWK'
28
+ end
29
+ end
30
+
31
+ def export(options = {})
32
+ { keys: @keys.map { |k| k.export(options) } }
33
+ end
34
+
35
+ def_delegators :@keys, :each, :size, :delete, :dig
36
+
37
+ def select!(&block)
38
+ return @keys.select! unless block
39
+
40
+ self if @keys.select!(&block)
41
+ end
42
+
43
+ def reject!(&block)
44
+ return @keys.reject! unless block
45
+
46
+ self if @keys.reject!(&block)
47
+ end
48
+
49
+ def uniq!(&block)
50
+ self if @keys.uniq!(&block)
51
+ end
52
+
53
+ def merge(enum)
54
+ @keys += JWT::JWK::Set.new(enum.to_a).keys
55
+ self
56
+ end
57
+
58
+ def union(enum)
59
+ dup.merge(enum)
60
+ end
61
+
62
+ def add(key)
63
+ @keys << JWT::JWK.new(key)
64
+ self
65
+ end
66
+
67
+ def ==(other)
68
+ other.is_a?(JWT::JWK::Set) && keys.sort == other.keys.sort
69
+ end
70
+
71
+ alias eql? ==
72
+ alias filter! select!
73
+ alias length size
74
+ # For symbolic manipulation
75
+ alias | union
76
+ alias + union
77
+ alias << add
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JWT
4
+ module JWK
5
+ # https://tools.ietf.org/html/rfc7638
6
+ class Thumbprint
7
+ attr_reader :jwk
8
+
9
+ def initialize(jwk)
10
+ @jwk = jwk
11
+ end
12
+
13
+ def generate
14
+ ::Base64.urlsafe_encode64(
15
+ Digest::SHA256.digest(
16
+ JWT::JSON.generate(
17
+ jwk.members.sort.to_h
18
+ )
19
+ ), padding: false
20
+ )
21
+ end
22
+
23
+ alias to_s generate
24
+ end
25
+ end
26
+ end
data/lib/jwt/jwk.rb CHANGED
@@ -1,23 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'jwk/key_finder'
4
+ require_relative 'jwk/set'
4
5
 
5
6
  module JWT
6
7
  module JWK
7
8
  class << self
8
- def import(jwk_data)
9
- jwk_kty = jwk_data[:kty] || jwk_data['kty']
10
- raise JWT::JWKError, 'Key type (kty) not provided' unless jwk_kty
11
-
12
- mappings.fetch(jwk_kty.to_s) do |kty|
13
- raise JWT::JWKError, "Key type #{kty} not supported"
14
- end.import(jwk_data)
15
- end
9
+ def create_from(key, params = nil, options = {})
10
+ if key.is_a?(Hash)
11
+ jwk_kty = key[:kty] || key['kty']
12
+ raise JWT::JWKError, 'Key type (kty) not provided' unless jwk_kty
13
+
14
+ return mappings.fetch(jwk_kty.to_s) do |kty|
15
+ raise JWT::JWKError, "Key type #{kty} not supported"
16
+ end.new(key, params, options)
17
+ end
16
18
 
17
- def create_from(keypair, kid = nil)
18
- mappings.fetch(keypair.class) do |klass|
19
+ mappings.fetch(key.class) do |klass|
19
20
  raise JWT::JWKError, "Cannot create JWK from a #{klass.name}"
20
- end.new(keypair, kid)
21
+ end.new(key, params, options)
21
22
  end
22
23
 
23
24
  def classes
@@ -26,6 +27,7 @@ module JWT
26
27
  end
27
28
 
28
29
  alias new create_from
30
+ alias import create_from
29
31
 
30
32
  private
31
33
 
@@ -7,17 +7,6 @@ module JWT
7
7
  module SecurityUtils
8
8
  module_function
9
9
 
10
- def secure_compare(left, right)
11
- left_bytesize = left.bytesize
12
-
13
- return false unless left_bytesize == right.bytesize
14
-
15
- unpacked_left = left.unpack "C#{left_bytesize}"
16
- result = 0
17
- right.each_byte { |byte| result |= byte ^ unpacked_left.shift }
18
- result.zero?
19
- end
20
-
21
10
  def verify_rsa(algorithm, public_key, signing_input, signature)
22
11
  public_key.verify(OpenSSL::Digest.new(algorithm.sub('RS', 'sha')), signature, signing_input)
23
12
  end
@@ -39,21 +28,5 @@ module JWT
39
28
  sig_char = signature[byte_size..-1] || ''
40
29
  OpenSSL::ASN1::Sequence.new([sig_bytes, sig_char].map { |int| OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(int, 2)) }).to_der
41
30
  end
42
-
43
- def rbnacl_fixup(algorithm, key)
44
- algorithm = algorithm.sub('HS', 'SHA').to_sym
45
-
46
- return [] unless defined?(RbNaCl) && RbNaCl::HMAC.constants(false).include?(algorithm)
47
-
48
- authenticator = RbNaCl::HMAC.const_get(algorithm)
49
-
50
- # Fall back to OpenSSL for keys larger than 32 bytes.
51
- return [] if key.bytesize > authenticator.key_bytes
52
-
53
- [
54
- authenticator,
55
- key.bytes.fill(0, key.bytesize...authenticator.key_bytes).pack('C*')
56
- ]
57
- end
58
31
  end
59
32
  end
data/lib/jwt/version.rb CHANGED
@@ -11,13 +11,34 @@ module JWT
11
11
  # major version
12
12
  MAJOR = 2
13
13
  # minor version
14
- MINOR = 4
14
+ MINOR = 6
15
15
  # tiny version
16
- TINY = 1
16
+ TINY = 0
17
17
  # alpha, beta, etc. tag
18
18
  PRE = nil
19
19
 
20
20
  # Build version string
21
21
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
22
22
  end
23
+
24
+ def self.openssl_3?
25
+ return false if OpenSSL::OPENSSL_VERSION.include?('LibreSSL')
26
+ return true if OpenSSL::OPENSSL_VERSION_NUMBER >= 3 * 0x10000000
27
+ end
28
+
29
+ def self.rbnacl?
30
+ defined?(::RbNaCl)
31
+ end
32
+
33
+ def self.rbnacl_6_or_greater?
34
+ rbnacl? && ::Gem::Version.new(::RbNaCl::VERSION) >= ::Gem::Version.new('6.0.0')
35
+ end
36
+
37
+ def self.openssl_3_hmac_empty_key_regression?
38
+ openssl_3? && openssl_version <= ::Gem::Version.new('3.0.0')
39
+ end
40
+
41
+ def self.openssl_version
42
+ @openssl_version ||= ::Gem::Version.new(OpenSSL::VERSION)
43
+ end
23
44
  end
@@ -47,7 +47,7 @@ module JWT
47
47
  x5c_header_or_certificates
48
48
  else
49
49
  x5c_header_or_certificates.map do |encoded|
50
- OpenSSL::X509::Certificate.new(::Base64.strict_decode64(encoded))
50
+ OpenSSL::X509::Certificate.new(::JWT::Base64.url_decode(encoded))
51
51
  end
52
52
  end
53
53
  end
data/lib/jwt.rb CHANGED
@@ -1,9 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'base64'
3
+ require 'jwt/version'
4
+ require 'jwt/base64'
4
5
  require 'jwt/json'
5
6
  require 'jwt/decode'
6
- require 'jwt/default_options'
7
+ require 'jwt/configuration'
7
8
  require 'jwt/encode'
8
9
  require 'jwt/error'
9
10
  require 'jwt/jwk'
@@ -13,7 +14,7 @@ require 'jwt/jwk'
13
14
  # Should be up to date with the latest spec:
14
15
  # https://tools.ietf.org/html/rfc7519
15
16
  module JWT
16
- include JWT::DefaultOptions
17
+ extend ::JWT::Configuration
17
18
 
18
19
  module_function
19
20
 
@@ -25,6 +26,6 @@ module JWT
25
26
  end
26
27
 
27
28
  def decode(jwt, key = nil, verify = true, options = {}, &keyfinder) # rubocop:disable Style/OptionalBooleanParameter
28
- Decode.new(jwt, key, verify, DEFAULT_OPTIONS.merge(options), &keyfinder).decode_segments
29
+ Decode.new(jwt, key, verify, configuration.decode.to_h.merge(options), &keyfinder).decode_segments
29
30
  end
30
31
  end
data/ruby-jwt.gemspec CHANGED
@@ -18,18 +18,22 @@ Gem::Specification.new do |spec|
18
18
  spec.required_ruby_version = '>= 2.5'
19
19
  spec.metadata = {
20
20
  'bug_tracker_uri' => 'https://github.com/jwt/ruby-jwt/issues',
21
- 'changelog_uri' => "https://github.com/jwt/ruby-jwt/blob/v#{JWT.gem_version}/CHANGELOG.md"
21
+ 'changelog_uri' => "https://github.com/jwt/ruby-jwt/blob/v#{JWT.gem_version}/CHANGELOG.md",
22
+ 'rubygems_mfa_required' => 'true'
22
23
  }
23
24
 
24
- spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(spec|gemfiles|coverage|bin)/}) }
25
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
26
+ f.match(%r{^(spec|gemfiles|coverage|bin)/}) || # Irrelevant folders
27
+ f.match(/^\.+/) || # Files and folders starting with .
28
+ f.match(/^(Appraisals|Gemfile|Rakefile)$/) # Irrelevant files
29
+ end
30
+
25
31
  spec.executables = []
26
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
27
32
  spec.require_paths = %w[lib]
28
33
 
29
34
  spec.add_development_dependency 'appraisal'
30
35
  spec.add_development_dependency 'bundler'
31
36
  spec.add_development_dependency 'rake'
32
- spec.add_development_dependency 'reek'
33
37
  spec.add_development_dependency 'rspec'
34
38
  spec.add_development_dependency 'simplecov'
35
39
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jwt
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.1
4
+ version: 2.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Rudat
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-06-07 00:00:00.000000000 Z
11
+ date: 2022-12-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: appraisal
@@ -52,20 +52,6 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
- - !ruby/object:Gem::Dependency
56
- name: reek
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
55
  - !ruby/object:Gem::Dependency
70
56
  name: rspec
71
57
  requirement: !ruby/object:Gem::Requirement
@@ -101,35 +87,31 @@ executables: []
101
87
  extensions: []
102
88
  extra_rdoc_files: []
103
89
  files:
104
- - ".codeclimate.yml"
105
- - ".github/workflows/coverage.yml"
106
- - ".github/workflows/test.yml"
107
- - ".gitignore"
108
- - ".reek.yml"
109
- - ".rspec"
110
- - ".rubocop.yml"
111
- - ".sourcelevel.yml"
112
90
  - AUTHORS
113
- - Appraisals
114
91
  - CHANGELOG.md
115
92
  - CODE_OF_CONDUCT.md
116
93
  - CONTRIBUTING.md
117
- - Gemfile
118
94
  - LICENSE
119
95
  - README.md
120
- - Rakefile
121
96
  - lib/jwt.rb
122
97
  - lib/jwt/algos.rb
98
+ - lib/jwt/algos/algo_wrapper.rb
123
99
  - lib/jwt/algos/ecdsa.rb
124
100
  - lib/jwt/algos/eddsa.rb
125
101
  - lib/jwt/algos/hmac.rb
102
+ - lib/jwt/algos/hmac_rbnacl.rb
103
+ - lib/jwt/algos/hmac_rbnacl_fixed.rb
126
104
  - lib/jwt/algos/none.rb
127
105
  - lib/jwt/algos/ps.rb
128
106
  - lib/jwt/algos/rsa.rb
129
107
  - lib/jwt/algos/unsupported.rb
108
+ - lib/jwt/base64.rb
130
109
  - lib/jwt/claims_validator.rb
110
+ - lib/jwt/configuration.rb
111
+ - lib/jwt/configuration/container.rb
112
+ - lib/jwt/configuration/decode_configuration.rb
113
+ - lib/jwt/configuration/jwk_configuration.rb
131
114
  - lib/jwt/decode.rb
132
- - lib/jwt/default_options.rb
133
115
  - lib/jwt/encode.rb
134
116
  - lib/jwt/error.rb
135
117
  - lib/jwt/json.rb
@@ -138,9 +120,11 @@ files:
138
120
  - lib/jwt/jwk/hmac.rb
139
121
  - lib/jwt/jwk/key_base.rb
140
122
  - lib/jwt/jwk/key_finder.rb
123
+ - lib/jwt/jwk/kid_as_key_digest.rb
141
124
  - lib/jwt/jwk/rsa.rb
125
+ - lib/jwt/jwk/set.rb
126
+ - lib/jwt/jwk/thumbprint.rb
142
127
  - lib/jwt/security_utils.rb
143
- - lib/jwt/signature.rb
144
128
  - lib/jwt/verify.rb
145
129
  - lib/jwt/version.rb
146
130
  - lib/jwt/x5c_key_finder.rb
@@ -150,7 +134,8 @@ licenses:
150
134
  - MIT
151
135
  metadata:
152
136
  bug_tracker_uri: https://github.com/jwt/ruby-jwt/issues
153
- changelog_uri: https://github.com/jwt/ruby-jwt/blob/v2.4.1/CHANGELOG.md
137
+ changelog_uri: https://github.com/jwt/ruby-jwt/blob/v2.6.0/CHANGELOG.md
138
+ rubygems_mfa_required: 'true'
154
139
  post_install_message:
155
140
  rdoc_options: []
156
141
  require_paths:
data/.codeclimate.yml DELETED
@@ -1,8 +0,0 @@
1
- plugins:
2
- fixme:
3
- enabled: true
4
- shellcheck:
5
- enabled: true
6
- rubocop:
7
- enabled: true
8
- channel: rubocop-1-23-0
@@ -1,27 +0,0 @@
1
- ---
2
- name: coverage
3
- on:
4
- push:
5
- branches:
6
- - "master"
7
- jobs:
8
- coverage:
9
- name: coverage
10
- runs-on: ubuntu-20.04
11
- env:
12
- BUNDLE_GEMFILE: 'gemfiles/rbnacl.gemfile'
13
- CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
14
- steps:
15
- - uses: actions/checkout@v2
16
- - name: Install libsodium
17
- run: |
18
- sudo apt-get update -q
19
- sudo apt-get install libsodium-dev -y
20
- - name: Set up Ruby
21
- uses: ruby/setup-ruby@v1
22
- with:
23
- ruby-version: "2.7"
24
- bundler-cache: true
25
- - uses: paambaati/codeclimate-action@v3.0.0
26
- with:
27
- coverageCommand: bundle exec rspec