jwt 1.3.0 → 1.4.0

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
  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