jwt 1.3.0 → 1.4.0

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
  SHA1:
3
- metadata.gz: 8f9090c3c5618d2e844c93a71d27b0fc09761f3b
4
- data.tar.gz: c9207a0a342a524526ca808643717da32a369fd6
3
+ metadata.gz: 22e5c1eafdf6a7e80397bbca142c3bff69524b21
4
+ data.tar.gz: e7acda6c7609412c393a5ebb29e575cb82618f9f
5
5
  SHA512:
6
- metadata.gz: 94d6c47e835ba56c48afcac43912caa94c30ed83e4ba09a8cf0e94036f8c14d54c097931d732b5777f1fa45c09eca85735b9982c0ba8606f1d2da551d9d9fe90
7
- data.tar.gz: 547492a234aa3f61299117ea2a770601710c9e36ed6d6df1f3e83b85d6e6693efa7da5c25ebb132ceff50998762229ae17649fd410df67f1d2ec92c8f63de28a
6
+ metadata.gz: f897824dd5f6ccc196f16c9944914c14ca0d476d9bc030bc8872ad7e2c5234a3db907ee35b780715689549fe397a4e76521b0e3d06d37f2b06d890cbcf855633
7
+ data.tar.gz: aec0e48a68cee3b5694d97f47aa0b3721ac2eee8a82b038c172c884d3ccfc1ade1728a4d4bf92d7cedd2d8bca9273cb180a14fb4ee306b01e981b2e752341515
data/Rakefile CHANGED
@@ -2,7 +2,7 @@ require 'rubygems'
2
2
  require 'rake'
3
3
  require 'echoe'
4
4
 
5
- Echoe.new('jwt', '1.3.0') do |p|
5
+ Echoe.new('jwt', '1.4.0') do |p|
6
6
  p.description = "JSON Web Token implementation in Ruby"
7
7
  p.url = "http://github.com/progrium/ruby-jwt"
8
8
  p.author = "Jeff Lindsay"
@@ -1,14 +1,14 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # stub: jwt 1.3.0 ruby lib
2
+ # stub: jwt 1.4.0 ruby lib
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "jwt"
6
- s.version = "1.3.0"
6
+ s.version = "1.4.0"
7
7
 
8
8
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
9
9
  s.require_paths = ["lib"]
10
10
  s.authors = ["Jeff Lindsay"]
11
- s.date = "2015-02-24"
11
+ s.date = "2015-03-10"
12
12
  s.description = "JSON Web Token implementation in Ruby"
13
13
  s.email = "progrium@gmail.com"
14
14
  s.extra_rdoc_files = ["lib/jwt.rb", "lib/jwt/json.rb"]
data/lib/jwt.rb CHANGED
@@ -11,8 +11,13 @@ require "jwt/json"
11
11
  module JWT
12
12
  class DecodeError < StandardError; end
13
13
  class VerificationError < DecodeError; end
14
- class ExpiredSignature < StandardError; end
15
- class ImmatureSignature < StandardError; end
14
+ class ExpiredSignature < DecodeError; end
15
+ class ImmatureSignature < DecodeError; end
16
+ class InvalidIssuerError < DecodeError; end
17
+ class InvalidIatError < DecodeError; end
18
+ class InvalidAudError < DecodeError; end
19
+ class InvalidSubError < DecodeError; end
20
+ class InvalidJtiError < DecodeError; end
16
21
  extend JWT::Json
17
22
 
18
23
  module_function
@@ -105,8 +110,14 @@ module JWT
105
110
  default_options = {
106
111
  :verify_expiration => true,
107
112
  :verify_not_before => true,
113
+ :verify_iss => true,
114
+ :verify_iat => true,
115
+ :verify_jti => true,
116
+ :verify_aud => true,
117
+ :verify_sub => true,
108
118
  :leeway => 0
109
119
  }
120
+
110
121
  options = default_options.merge(options)
111
122
 
112
123
  if verify
@@ -120,6 +131,27 @@ module JWT
120
131
  if options[:verify_not_before] && payload.include?('nbf')
121
132
  raise JWT::ImmatureSignature.new("Signature nbf has not been reached") unless payload['nbf'].to_i < (Time.now.to_i + options[:leeway])
122
133
  end
134
+ if options[:verify_iss] && payload.include?('iss')
135
+ raise JWT::InvalidIssuerError.new("Invalid issuer") unless payload['iss'].to_s == options['iss'].to_s
136
+ end
137
+ if options[:verify_iat] && payload.include?('iat')
138
+ raise JWT::InvalidIatError.new("Invalid iat") unless (payload['iat'].is_a?(Integer) and payload['iat'].to_i <= Time.now.to_i)
139
+ end
140
+ if options[:verify_aud] && payload.include?('aud')
141
+ if payload['aud'].is_a?(Array)
142
+ raise JWT::InvalidAudError.new("Invalid audience") unless payload['aud'].include?(options['aud'])
143
+ else
144
+ raise JWT::InvalidAudError.new("Invalid audience") unless payload['aud'].to_s == options['aud'].to_s
145
+ end
146
+ end
147
+ if options[:verify_sub] && payload.include?('sub')
148
+ raise JWT::InvalidSubError.new("Invalid subject") unless payload['sub'].to_s == options['sub'].to_s
149
+ end
150
+ if options[:verify_jti] && payload.include?('jti')
151
+ raise JWT::InvalidJtiError.new("need iat for verify jwt id") unless payload.include?('iat')
152
+ raise JWT::InvalidJtiError.new("Not a uniq jwt id") unless options['jti'].to_s == Digest::MD5.hexdigest("#{key}:#{payload['iat']}")
153
+ end
154
+
123
155
  return payload,header
124
156
  end
125
157
 
@@ -1,5 +1,2 @@
1
1
  require 'rspec'
2
2
  require "#{File.dirname(__FILE__)}/../lib/jwt.rb"
3
-
4
- RSpec.configure do |c|
5
- end
@@ -2,81 +2,175 @@ require 'helper'
2
2
 
3
3
  describe JWT do
4
4
  before do
5
- @payload = {"foo" => "bar", "exp" => Time.now.to_i + 1, "nbf" => Time.now.to_i - 1 }
5
+ @payload = {'foo' => 'bar', 'exp' => Time.now.to_i + 1, 'nbf' => Time.now.to_i - 1 }
6
6
  end
7
7
 
8
- it "encodes and decodes JWTs" do
9
- secret = "secret"
8
+ it 'encodes and decodes JWTs' do
9
+ secret = 'secret'
10
10
  jwt = JWT.encode(@payload, secret)
11
11
  decoded_payload = JWT.decode(jwt, secret)
12
12
  expect(decoded_payload).to include(@payload)
13
13
  end
14
14
 
15
- it "encodes and decodes JWTs for RSA signatures" do
15
+ it 'encodes and decodes JWTs for RSA signatures' do
16
16
  private_key = OpenSSL::PKey::RSA.generate(512)
17
- jwt = JWT.encode(@payload, private_key, "RS256")
17
+ jwt = JWT.encode(@payload, private_key, 'RS256')
18
18
  decoded_payload = JWT.decode(jwt, private_key.public_key)
19
19
  expect(decoded_payload).to include(@payload)
20
20
  end
21
21
 
22
- it "encodes and decodes JWTs with custom header fields" do
22
+ it 'encodes and decodes JWTs with custom header fields' do
23
23
  private_key = OpenSSL::PKey::RSA.generate(512)
24
- jwt = JWT.encode(@payload, private_key, "RS256", {"kid" => 'default'})
24
+ jwt = JWT.encode(@payload, private_key, 'RS256', {'kid' => 'default'})
25
25
  decoded_payload = JWT.decode(jwt) do |header|
26
- expect(header["kid"]).to eq('default')
26
+ expect(header['kid']).to eq('default')
27
27
  private_key.public_key
28
28
  end
29
29
  expect(decoded_payload).to include(@payload)
30
30
  end
31
31
 
32
- it "decodes valid JWTs" do
33
- example_payload = {"hello" => "world"}
32
+ it 'decodes valid JWTs' do
33
+ example_payload = {'hello' => 'world'}
34
34
  example_secret = 'secret'
35
35
  example_jwt = 'eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJoZWxsbyI6ICJ3b3JsZCJ9.tvagLDLoaiJKxOKqpBXSEGy7SYSifZhjntgm9ctpyj8'
36
36
  decoded_payload = JWT.decode(example_jwt, example_secret)
37
37
  expect(decoded_payload).to include(example_payload)
38
38
  end
39
39
 
40
- it "raises decode exception when the token is invalid" do
40
+ it 'decodes valid JWTs with iss' do
41
+ example_payload = {'hello' => 'world', 'iss' => 'jwtiss'}
42
+ example_secret = 'secret'
43
+ example_jwt = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJoZWxsbyI6IndvcmxkIiwiaXNzIjoiand0aXNzIn0.nTZkyYfpGUyKULaj45lXw_1gXXjHvGW4h5V7okHdUqQ'
44
+ decoded_payload = JWT.decode(example_jwt, example_secret, true, {'iss' => 'jwtiss'})
45
+ expect(decoded_payload).to include(example_payload)
46
+ end
47
+
48
+ it 'raises invalid issuer' do
49
+ # example_payload = {'hello' => 'world', 'iss' => 'jwtiss'}
50
+ example_payload2 = {'hello' => 'world'}
51
+
52
+ example_secret = 'secret'
53
+
54
+ example_jwt = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJoZWxsbyI6IndvcmxkIiwiaXNzIjoiand0aXNzIn0.nTZkyYfpGUyKULaj45lXw_1gXXjHvGW4h5V7okHdUqQ'
55
+ expect{ JWT.decode(example_jwt, example_secret, true, {'iss' => 'jwt_iss'}) }.to raise_error(JWT::InvalidIssuerError)
56
+
57
+ example_jwt2 = 'eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJoZWxsbyI6ICJ3b3JsZCJ9.tvagLDLoaiJKxOKqpBXSEGy7SYSifZhjntgm9ctpyj8'
58
+ decode_payload2 = JWT.decode(example_jwt2, example_secret, true, {'iss' => 'jwt_iss'})
59
+ expect(decode_payload2).to include(example_payload2)
60
+ end
61
+
62
+ it 'decodes valid JWTs with iat' do
63
+ example_payload = {'hello' => 'world', 'iat' => 1425917209}
64
+ example_secret = 'secret'
65
+ example_jwt = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJoZWxsbyI6IndvcmxkIiwiaWF0IjoxNDI1OTE3MjA5fQ.m4F-Ugo7aLnLunBBO3BeDidyWMx8T9eoJz6FW2rgQhU'
66
+ decoded_payload = JWT.decode(example_jwt, example_secret, true, {'iat' => true})
67
+ expect(decoded_payload).to include(example_payload)
68
+ end
69
+
70
+ it 'raises decode exception when iat is invalid' do
71
+ # example_payload = {'hello' => 'world', 'iat' => 'abc'}
72
+ example_secret = 'secret'
73
+ example_jwt = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJoZWxsbyI6IndvcmxkIiwiaWF0IjoiMTQyNTkxNzIwOSJ9.Mn_vk61xWjIhbXFqAB0nFmNkDiCmfzUgl_LaCKRT6S8'
74
+ expect{ JWT.decode(example_jwt, example_secret, true, {'iat' => 1425917209}) }.to raise_error(JWT::InvalidIatError)
75
+ end
76
+
77
+ it 'decodes valid JWTs with jti' do
78
+ example_payload = {'hello' => 'world', 'iat' => 1425917209, 'jti' => Digest::MD5.hexdigest('secret:1425917209')}
79
+ example_secret = 'secret'
80
+ example_jwt = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJoZWxsbyI6IndvcmxkIiwiaWF0IjoxNDI1OTE3MjA5LCJqdGkiOiI1NWM3NzZlMjFmN2NiZDg3OWMwNmZhYzAxOGRhYzQwMiJ9.ET0hb-VTUOL3M22oG13ofzvGPLMAncbF8rdNDIqo8tg'
81
+ decoded_payload = JWT.decode(example_jwt, example_secret, true, {'jti' => Digest::MD5.hexdigest('secret:1425917209')})
82
+ expect(decoded_payload).to include(example_payload)
83
+ end
84
+
85
+ it 'raises decode exception when jti is invalid' do
86
+ # example_payload = {'hello' => 'world', 'iat' => 1425917209, 'jti' => Digest::MD5.hexdigest('secret:1425917209')}
87
+ example_secret = 'secret'
88
+ example_jwt = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJoZWxsbyI6IndvcmxkIiwiaWF0IjoxNDI1OTE3MjA5LCJqdGkiOiI1NWM3NzZlMjFmN2NiZDg3OWMwNmZhYzAxOGRhYzQwMiJ9.ET0hb-VTUOL3M22oG13ofzvGPLMAncbF8rdNDIqo8tg'
89
+ expect{ JWT.decode(example_jwt, example_secret, true, {'jti' => Digest::MD5.hexdigest('secret:1425922032')}) }.to raise_error(JWT::InvalidJtiError)
90
+ expect{ JWT.decode(example_jwt, example_secret) }.to raise_error(JWT::InvalidJtiError)
91
+ end
92
+
93
+ it 'raises decode exception when jti without iat' do
94
+ # example_payload = {'hello' => 'world', 'jti' => Digest::MD5.hexdigest('secret:1425917209')}
95
+ example_secret = 'secret'
96
+ example_jwt = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJoZWxsbyI6IndvcmxkIiwianRpIjoiNTVjNzc2ZTIxZjdjYmQ4NzljMDZmYWMwMThkYWM0MDIifQ.n0foJCnCM_-_xUvG_TOmR9mYpL2y0UqZOD_gv33djeE'
97
+ expect{ JWT.decode(example_jwt, example_secret, true, {'jti' => Digest::MD5.hexdigest('secret:1425922032')}) }.to raise_error(JWT::InvalidJtiError)
98
+ end
99
+
100
+ it 'decodes valid JWTs with aud' do
101
+ example_payload = {'hello' => 'world', 'aud' => 'url:pnd'}
102
+ example_payload2 = {'hello' => 'world', 'aud' => ['url:pnd', 'aud:yes']}
103
+ example_secret = 'secret'
104
+ example_jwt = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJoZWxsbyI6IndvcmxkIiwiYXVkIjoidXJsOnBuZCJ9._gT5veUtNiZD7wLEC6Gd0-nkQV3cl1z8G0zXq8qcd-8'
105
+ example_jwt2 = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJoZWxsbyI6IndvcmxkIiwiYXVkIjpbInVybDpwbmQiLCJhdWQ6eWVzIl19.qNPNcT4X9B5uI91rIwbW2bIPTsp8wbRYW3jkZkrmqbQ'
106
+ decoded_payload = JWT.decode(example_jwt, example_secret, true, {'aud' => 'url:pnd'})
107
+ decoded_payload2 = JWT.decode(example_jwt2, example_secret, true, {'aud' => 'url:pnd'})
108
+ expect(decoded_payload).to include(example_payload)
109
+ expect(decoded_payload2).to include(example_payload2)
110
+ end
111
+
112
+ it 'raises deode exception when aud is invalid' do
113
+ # example_payload = {'hello' => 'world', 'aud' => 'url:pnd'}
114
+ example_secret = 'secret'
115
+ example_jwt = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJoZWxsbyI6IndvcmxkIiwiYXVkIjoidXJsOnBuZCJ9._gT5veUtNiZD7wLEC6Gd0-nkQV3cl1z8G0zXq8qcd-8'
116
+ expect{ JWT.decode(example_jwt, example_secret, true, {'aud' => 'wrong:aud'}) }.to raise_error(JWT::InvalidAudError)
117
+ end
118
+
119
+ it 'decodes valid JWTs with sub' do
120
+ example_payload = {'hello' => 'world', 'sub' => 'subject'}
121
+ example_secret = 'secret'
122
+ example_jwt = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJoZWxsbyI6IndvcmxkIiwic3ViIjoic3ViamVjdCJ9.QUnNVZm4SPB4vP2zY9m1LoUSOx-5oGXBhj7R89D_UtA'
123
+ decoded_payload = JWT.decode(example_jwt, example_secret, true, {'sub' => 'subject'})
124
+ expect(decoded_payload).to include(example_payload)
125
+ end
126
+
127
+ it 'raise decode exception when the sub is invalid' do
128
+ # example_payload = {'hello' => 'world', 'sub' => 'subject'}
129
+ example_secret = 'secret'
130
+ example_jwt = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJoZWxsbyI6IndvcmxkIiwic3ViIjoic3ViamVjdCJ9.QUnNVZm4SPB4vP2zY9m1LoUSOx-5oGXBhj7R89D_UtA'
131
+ expect{ JWT.decode(example_jwt, example_secret, true, {'iss' => 'subject'}) }.to raise_error(JWT::InvalidSubError)
132
+ end
133
+
134
+ it 'raises decode exception when the token is invalid' do
41
135
  example_secret = 'secret'
42
136
  # Same as above exmaple with some random bytes replaced
43
137
  example_jwt = 'eyJhbGciOiAiSFMyNTYiLCAidHiMomlwIjogIkJ9.eyJoZWxsbyI6ICJ3b3JsZCJ9.tvagLDLoaiJKxOKqpBXSEGy7SYSifZhjntgm9ctpyj8'
44
138
  expect { JWT.decode(example_jwt, example_secret) }.to raise_error(JWT::DecodeError)
45
139
  end
46
140
 
47
- it "raises verification exception with wrong hmac key" do
141
+ it 'raises verification exception with wrong hmac key' do
48
142
  right_secret = 'foo'
49
143
  bad_secret = 'bar'
50
- jwt_message = JWT.encode(@payload, right_secret, "HS256")
144
+ jwt_message = JWT.encode(@payload, right_secret, 'HS256')
51
145
  expect { JWT.decode(jwt_message, bad_secret) }.to raise_error(JWT::VerificationError)
52
146
  end
53
147
 
54
- it "raises verification exception with wrong rsa key" do
148
+ it 'raises verification exception with wrong rsa key' do
55
149
  right_private_key = OpenSSL::PKey::RSA.generate(512)
56
150
  bad_private_key = OpenSSL::PKey::RSA.generate(512)
57
- jwt = JWT.encode(@payload, right_private_key, "RS256")
151
+ jwt = JWT.encode(@payload, right_private_key, 'RS256')
58
152
  expect { JWT.decode(jwt, bad_private_key.public_key) }.to raise_error(JWT::VerificationError)
59
153
  end
60
154
 
61
- it "raises decode exception with invalid signature" do
155
+ it 'raises decode exception with invalid signature' do
62
156
  example_secret = 'secret'
63
157
  example_jwt = 'eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJoZWxsbyI6ICJ3b3JsZCJ9.'
64
158
  expect { JWT.decode(example_jwt, example_secret) }.to raise_error(JWT::DecodeError)
65
159
  end
66
160
 
67
- it "raises decode exception with nonexistent header" do
68
- expect { JWT.decode("..stuff") }.to raise_error(JWT::DecodeError)
161
+ it 'raises decode exception with nonexistent header' do
162
+ expect { JWT.decode('..stuff') }.to raise_error(JWT::DecodeError)
69
163
  end
70
164
 
71
- it "raises decode exception with nonexistent payload" do
72
- expect { JWT.decode("eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9..stuff") }.to raise_error(JWT::DecodeError)
165
+ it 'raises decode exception with nonexistent payload' do
166
+ expect { JWT.decode('eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9..stuff') }.to raise_error(JWT::DecodeError)
73
167
  end
74
168
 
75
- it "raises decode exception with nil jwt" do
169
+ it 'raises decode exception with nil jwt' do
76
170
  expect { JWT.decode(nil) }.to raise_error(JWT::DecodeError)
77
171
  end
78
172
 
79
- it "allows decoding without key" do
173
+ it 'allows decoding without key' do
80
174
  right_secret = 'foo'
81
175
  bad_secret = 'bar'
82
176
  jwt = JWT.encode(@payload, right_secret)
@@ -84,35 +178,35 @@ describe JWT do
84
178
  expect(decoded_payload).to include(@payload)
85
179
  end
86
180
 
87
- it "checks the key when verify is truthy" do
181
+ it 'checks the key when verify is truthy' do
88
182
  right_secret = 'foo'
89
183
  bad_secret = 'bar'
90
184
  jwt = JWT.encode(@payload, right_secret)
91
- verify = "yes" =~ /^y/i
185
+ verify = 'yes' =~ /^y/i
92
186
  expect { JWT.decode(jwt, bad_secret, verify) }.to raise_error(JWT::DecodeError)
93
187
  end
94
188
 
95
- it "raises exception on unsupported crypto algorithm" do
96
- expect { JWT.encode(@payload, "secret", 'HS1024') }.to raise_error(NotImplementedError)
189
+ it 'raises exception on unsupported crypto algorithm' do
190
+ expect { JWT.encode(@payload, 'secret', 'HS1024') }.to raise_error(NotImplementedError)
97
191
  end
98
192
 
99
- it "encodes and decodes plaintext JWTs" do
193
+ it 'encodes and decodes plaintext JWTs' do
100
194
  jwt = JWT.encode(@payload, nil, nil)
101
195
  expect(jwt.split('.').length).to eq(2)
102
196
  decoded_payload = JWT.decode(jwt, nil, nil)
103
197
  expect(decoded_payload).to include(@payload)
104
198
  end
105
199
 
106
- it "requires a signature segment when verify is truthy" do
200
+ it 'requires a signature segment when verify is truthy' do
107
201
  jwt = JWT.encode(@payload, nil, nil)
108
202
  expect(jwt.split('.').length).to eq(2)
109
203
  expect { JWT.decode(jwt, nil, true) }.to raise_error(JWT::DecodeError)
110
204
  end
111
205
 
112
- it "does not use == to compare digests" do
113
- secret = "secret"
206
+ it 'does not use == to compare digests' do
207
+ secret = 'secret'
114
208
  jwt = JWT.encode(@payload, secret)
115
- crypto_segment = jwt.split(".").last
209
+ crypto_segment = jwt.split('.').last
116
210
 
117
211
  signature = JWT.base64url_decode(crypto_segment)
118
212
  expect(signature).not_to receive('==')
@@ -122,96 +216,96 @@ describe JWT do
122
216
  JWT.decode(jwt, secret)
123
217
  end
124
218
 
125
- it "raises error when expired" do
219
+ it 'raises error when expired' do
126
220
  expired_payload = @payload.clone
127
221
  expired_payload['exp'] = Time.now.to_i - 1
128
- secret = "secret"
222
+ secret = 'secret'
129
223
  jwt = JWT.encode(expired_payload, secret)
130
224
  expect { JWT.decode(jwt, secret) }.to raise_error(JWT::ExpiredSignature)
131
225
  end
132
226
 
133
- it "raise ExpiredSignature even when exp claims is a string" do
227
+ it 'raise ExpiredSignature even when exp claims is a string' do
134
228
  expired_payload = @payload.clone
135
229
  expired_payload['exp'] = (Time.now.to_i).to_s
136
- secret = "secret"
230
+ secret = 'secret'
137
231
  jwt = JWT.encode(expired_payload, secret)
138
232
  expect { JWT.decode(jwt, secret) }.to raise_error(JWT::ExpiredSignature)
139
233
  end
140
234
 
141
- it "performs normal decode with skipped expiration check" do
235
+ it 'performs normal decode with skipped expiration check' do
142
236
  expired_payload = @payload.clone
143
237
  expired_payload['exp'] = Time.now.to_i - 1
144
- secret = "secret"
238
+ secret = 'secret'
145
239
  jwt = JWT.encode(expired_payload, secret)
146
240
  decoded_payload = JWT.decode(jwt, secret, true, {:verify_expiration => false})
147
241
  expect(decoded_payload).to include(expired_payload)
148
242
  end
149
243
 
150
- it "performs normal decode using leeway" do
244
+ it 'performs normal decode using leeway' do
151
245
  expired_payload = @payload.clone
152
246
  expired_payload['exp'] = Time.now.to_i - 2
153
- secret = "secret"
247
+ secret = 'secret'
154
248
  jwt = JWT.encode(expired_payload, secret)
155
249
  decoded_payload = JWT.decode(jwt, secret, true, {:leeway => 3})
156
250
  expect(decoded_payload).to include(expired_payload)
157
251
  end
158
252
 
159
- it "raises error when before nbf" do
253
+ it 'raises error when before nbf' do
160
254
  immature_payload = @payload.clone
161
255
  immature_payload['nbf'] = Time.now.to_i + 1
162
- secret = "secret"
256
+ secret = 'secret'
163
257
  jwt = JWT.encode(immature_payload, secret)
164
258
  expect { JWT.decode(jwt, secret) }.to raise_error(JWT::ImmatureSignature)
165
259
  end
166
260
 
167
- it "doesnt raise error when after nbf" do
261
+ it 'doesnt raise error when after nbf' do
168
262
  mature_payload = @payload.clone
169
- secret = "secret"
263
+ secret = 'secret'
170
264
  jwt = JWT.encode(mature_payload, secret)
171
265
  decoded_payload = JWT.decode(jwt, secret, true, {:verify_expiration => false})
172
266
  expect(decoded_payload).to include(mature_payload)
173
267
  end
174
268
 
175
- it "raise ImmatureSignature even when nbf claim is a string" do
269
+ it 'raise ImmatureSignature even when nbf claim is a string' do
176
270
  immature_payload = @payload.clone
177
271
  immature_payload['nbf'] = (Time.now.to_i).to_s
178
- secret = "secret"
272
+ secret = 'secret'
179
273
  jwt = JWT.encode(immature_payload, secret)
180
274
  expect { JWT.decode(jwt, secret) }.to raise_error(JWT::ImmatureSignature)
181
275
  end
182
276
 
183
- it "performs normal decode with skipped not before check" do
277
+ it 'performs normal decode with skipped not before check' do
184
278
  immature_payload = @payload.clone
185
279
  immature_payload['nbf'] = Time.now.to_i + 2
186
- secret = "secret"
280
+ secret = 'secret'
187
281
  jwt = JWT.encode(immature_payload, secret)
188
282
  decoded_payload = JWT.decode(jwt, secret, true, {:verify_not_before => false})
189
283
  expect(decoded_payload).to include(immature_payload)
190
284
  end
191
285
 
192
- it "performs normal decode using leeway" do
286
+ it 'performs normal decode using leeway' do
193
287
  immature_payload = @payload.clone
194
288
  immature_payload['nbf'] = Time.now.to_i - 2
195
- secret = "secret"
289
+ secret = 'secret'
196
290
  jwt = JWT.encode(immature_payload, secret)
197
291
  decoded_payload = JWT.decode(jwt, secret, true, {:leeway => 3})
198
292
  expect(decoded_payload).to include(immature_payload)
199
293
  end
200
294
 
201
- describe "secure comparison" do
202
- it "returns true if strings are equal" do
203
- expect(JWT.secure_compare("Foo", "Foo")).to be true
295
+ describe 'secure comparison' do
296
+ it 'returns true if strings are equal' do
297
+ expect(JWT.secure_compare('Foo', 'Foo')).to be true
204
298
  end
205
299
 
206
- it "returns false if either input is nil or empty" do
207
- [nil, ""].each do |bad|
208
- expect(JWT.secure_compare(bad, "Foo")).to be false
209
- expect(JWT.secure_compare("Foo", bad)).to be false
300
+ it 'returns false if either input is nil or empty' do
301
+ [nil, ''].each do |bad|
302
+ expect(JWT.secure_compare(bad, 'Foo')).to be false
303
+ expect(JWT.secure_compare('Foo', bad)).to be false
210
304
  end
211
305
  end
212
306
 
213
- it "retuns false if the strings are different" do
214
- expect(JWT.secure_compare("Foo", "Bar")).to be false
307
+ it 'retuns false if the strings are different' do
308
+ expect(JWT.secure_compare('Foo', 'Bar')).to be false
215
309
  end
216
310
  end
217
311
 
@@ -220,7 +314,7 @@ describe JWT do
220
314
  expect(OpenSSL.errors).to be_empty
221
315
  end
222
316
 
223
- it "raise exception on invalid signature" do
317
+ it 'raise exception on invalid signature' do
224
318
  pubkey = OpenSSL::PKey::RSA.new(<<-PUBKEY)
225
319
  -----BEGIN PUBLIC KEY-----
226
320
  MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxCaY7425h964bjaoLeUm
@@ -245,20 +339,20 @@ PUBKEY
245
339
  expect { JWT.decode(jwt, pubkey, true) }.to raise_error(JWT::DecodeError)
246
340
  end
247
341
 
248
- describe "urlsafe base64 encoding" do
249
- it "replaces + and / with - and _" do
250
- allow(Base64).to receive(:encode64) { "string+with/non+url-safe/characters_" }
251
- expect(JWT.base64url_encode("foo")).to eq("string-with_non-url-safe_characters_")
342
+ describe 'urlsafe base64 encoding' do
343
+ it 'replaces + and / with - and _' do
344
+ allow(Base64).to receive(:encode64) { 'string+with/non+url-safe/characters_' }
345
+ expect(JWT.base64url_encode('foo')).to eq('string-with_non-url-safe_characters_')
252
346
  end
253
347
  end
254
348
 
255
349
  describe 'decoded_segments' do
256
- it "allows access to the decoded header and payload" do
257
- secret = "secret"
350
+ it 'allows access to the decoded header and payload' do
351
+ secret = 'secret'
258
352
  jwt = JWT.encode(@payload, secret)
259
353
  decoded_segments = JWT.decoded_segments(jwt)
260
354
  expect(decoded_segments.size).to eq(4)
261
- expect(decoded_segments[0]).to eq({"typ" => "JWT", "alg" => "HS256"})
355
+ expect(decoded_segments[0]).to eq({'typ' => 'JWT', 'alg' => 'HS256'})
262
356
  expect(decoded_segments[1]).to eq(@payload)
263
357
  end
264
358
  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: 1.3.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeff Lindsay
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-24 00:00:00.000000000 Z
11
+ date: 2015-03-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: echoe