jwt_keeper 4.0.1 → 5.0.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 +4 -4
- data/lib/jwt_keeper/controller.rb +1 -1
- data/lib/jwt_keeper/token.rb +25 -16
- data/lib/jwt_keeper/version.rb +1 -1
- data/spec/lib/jwt_keeper/controller_spec.rb +1 -0
- data/spec/lib/jwt_keeper/token_spec.rb +32 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '0781e4deae7439d13aadad57e1c3fa6dd224cd791c90672ee647815af2ebf70a'
|
4
|
+
data.tar.gz: 9be046da200f6d6f6e17c2f747c398e7b5abe13e1fe1517a7b288d9dec468ea8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a58d6573eb512abce406c8726a15eebac3136d5c05b5305c9b5cd8d040f2facd6c050071d86a8bb885523485ea6217b2596f6bc14771d0e5d0c878278b0bdd66
|
7
|
+
data.tar.gz: 6a1086f9933a1daf4fc48e2ea7af4c2fe8c7b26c248a84f096cde00e9e2af3302258a894cdcb88211a281756a2b847713d6a6bd87233b66d1ca10fe64b3b6459
|
data/lib/jwt_keeper/token.rb
CHANGED
@@ -2,14 +2,16 @@ module JWTKeeper
|
|
2
2
|
# This class acts as the main interface to wrap the concerns of JWTs. Handling everything from
|
3
3
|
# encoding to invalidation.
|
4
4
|
class Token
|
5
|
-
attr_accessor :claims, :cookie_secret
|
5
|
+
attr_accessor :claims, :secret, :cookie_secret
|
6
6
|
|
7
7
|
# Initalizes a new web token
|
8
|
-
# @param
|
9
|
-
# @param
|
8
|
+
# @param options [Hash] the custom claims to encode
|
9
|
+
# @param secret the secret to use during encoding, defaults to config
|
10
|
+
# @param cookie_secret the cookie secret to use during encoding
|
10
11
|
# @return [void]
|
11
|
-
def initialize(
|
12
|
-
@
|
12
|
+
def initialize(options = {})
|
13
|
+
@secret = options.delete(:secret) || JWTKeeper.configuration.secret
|
14
|
+
@cookie_secret = options.delete(:cookie_secret)
|
13
15
|
@claims = {
|
14
16
|
nbf: DateTime.now.to_i, # not before
|
15
17
|
iat: DateTime.now.to_i, # issued at
|
@@ -17,27 +19,28 @@ module JWTKeeper
|
|
17
19
|
}
|
18
20
|
|
19
21
|
@claims.merge!(JWTKeeper.configuration.base_claims)
|
20
|
-
@claims.merge!(
|
22
|
+
@claims.merge!(options)
|
21
23
|
@claims[:exp] = @claims[:exp].to_i if @claims[:exp].is_a?(Time)
|
22
24
|
end
|
23
25
|
|
24
26
|
# Creates a new web token
|
25
|
-
# @param
|
27
|
+
# @param options [Hash] the custom claims to encode
|
28
|
+
# @param secret the secret to use during encoding, defaults to config
|
26
29
|
# @return [Token] token object
|
27
|
-
def self.create(
|
30
|
+
def self.create(options)
|
28
31
|
cookie_secret = SecureRandom.hex(16) if JWTKeeper.configuration.cookie_lock
|
29
|
-
new(
|
32
|
+
new(options.merge(cookie_secret: cookie_secret))
|
30
33
|
end
|
31
34
|
|
32
35
|
# Decodes and validates an existing token
|
33
36
|
# @param raw_token [String] the raw token
|
34
37
|
# @param cookie_secret [String] the cookie secret
|
35
38
|
# @return [Token] token object
|
36
|
-
def self.find(raw_token, cookie_secret
|
37
|
-
claims = decode(raw_token, cookie_secret)
|
39
|
+
def self.find(raw_token, secret: nil, cookie_secret: nil)
|
40
|
+
claims = decode(raw_token, secret: secret, cookie_secret: cookie_secret)
|
38
41
|
return nil if claims.nil?
|
39
42
|
|
40
|
-
new_token = new(
|
43
|
+
new_token = new(secret: secret, cookie_secret: cookie_secret)
|
41
44
|
new_token.claims = claims
|
42
45
|
|
43
46
|
return nil if new_token.revoked?
|
@@ -114,7 +117,11 @@ module JWTKeeper
|
|
114
117
|
# Checks if the token invalid?
|
115
118
|
# @return [Boolean]
|
116
119
|
def invalid?
|
117
|
-
self.class.decode(
|
120
|
+
self.class.decode(
|
121
|
+
encode,
|
122
|
+
secret: secret,
|
123
|
+
cookie_secret: cookie_secret
|
124
|
+
).nil? || revoked?
|
118
125
|
end
|
119
126
|
|
120
127
|
# Encodes the jwt
|
@@ -134,8 +141,10 @@ module JWTKeeper
|
|
134
141
|
end
|
135
142
|
|
136
143
|
# @!visibility private
|
137
|
-
def self.decode(raw_token, cookie_secret)
|
138
|
-
|
144
|
+
def self.decode(raw_token, secret: nil, cookie_secret: nil)
|
145
|
+
secret ||= JWTKeeper.configuration.secret
|
146
|
+
|
147
|
+
JWT.decode(raw_token, secret.to_s + cookie_secret.to_s, true,
|
139
148
|
algorithm: JWTKeeper.configuration.algorithm,
|
140
149
|
verify_iss: true,
|
141
150
|
verify_aud: true,
|
@@ -156,7 +165,7 @@ module JWTKeeper
|
|
156
165
|
# @!visibility private
|
157
166
|
def encode
|
158
167
|
JWT.encode(claims.compact,
|
159
|
-
|
168
|
+
secret.to_s + cookie_secret.to_s,
|
160
169
|
JWTKeeper.configuration.algorithm
|
161
170
|
)
|
162
171
|
end
|
data/lib/jwt_keeper/version.rb
CHANGED
@@ -24,6 +24,15 @@ module JWTKeeper
|
|
24
24
|
it { is_expected.to be_instance_of described_class }
|
25
25
|
it { expect(subject.claims[:exp]).to eql private_claims[:exp] }
|
26
26
|
end
|
27
|
+
|
28
|
+
context 'when overriding default secret' do
|
29
|
+
subject { described_class.create(**private_claims, secret: secret) }
|
30
|
+
|
31
|
+
let(:secret) { SecureRandom.uuid }
|
32
|
+
|
33
|
+
it { is_expected.to be_instance_of described_class }
|
34
|
+
it { expect(subject.claims[:claim]).to eql private_claims[:claim] }
|
35
|
+
end
|
27
36
|
end
|
28
37
|
|
29
38
|
describe '.find' do
|
@@ -46,20 +55,30 @@ module JWTKeeper
|
|
46
55
|
before { JWTKeeper.configure(JWTKeeper::Configuration.new(config.merge(cookie_lock: true))) }
|
47
56
|
|
48
57
|
context 'with no cookie' do
|
49
|
-
subject { described_class.find(raw_token, nil) }
|
58
|
+
subject { described_class.find(raw_token, cookie_secret: nil) }
|
50
59
|
it { is_expected.to be nil }
|
51
60
|
end
|
52
61
|
|
53
62
|
context 'with bad cookie' do
|
54
|
-
subject { described_class.find(raw_token, 'BAD_COOKIE') }
|
63
|
+
subject { described_class.find(raw_token, cookie_secret: 'BAD_COOKIE') }
|
55
64
|
it { is_expected.to be nil }
|
56
65
|
end
|
57
66
|
|
58
67
|
context 'with valid cookie' do
|
59
|
-
subject { described_class.find(raw_token, token.cookie_secret) }
|
68
|
+
subject { described_class.find(raw_token, cookie_secret: token.cookie_secret) }
|
60
69
|
it { is_expected.to be_instance_of described_class }
|
61
70
|
end
|
62
71
|
end
|
72
|
+
|
73
|
+
context 'when overriding default secret' do
|
74
|
+
subject { described_class.find(raw_token, secret: secret) }
|
75
|
+
|
76
|
+
let(:token) { described_class.create(**private_claims, secret: secret) }
|
77
|
+
let(:secret) { SecureRandom.uuid }
|
78
|
+
|
79
|
+
it { is_expected.to be_instance_of described_class }
|
80
|
+
it { expect(subject.claims[:claim]).to eql private_claims[:claim] }
|
81
|
+
end
|
63
82
|
end
|
64
83
|
|
65
84
|
describe '.rotate' do
|
@@ -194,6 +213,16 @@ module JWTKeeper
|
|
194
213
|
context 'when valid' do
|
195
214
|
it { is_expected.to be_valid }
|
196
215
|
end
|
216
|
+
|
217
|
+
context 'with overriden secret' do
|
218
|
+
subject { described_class.create(**private_claims, secret: secret) }
|
219
|
+
|
220
|
+
let(:secret) { SecureRandom.uuid }
|
221
|
+
|
222
|
+
context 'when valid' do
|
223
|
+
it { is_expected.to be_valid }
|
224
|
+
end
|
225
|
+
end
|
197
226
|
end
|
198
227
|
|
199
228
|
describe '#invalid?' do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jwt_keeper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 5.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Rivera
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2021-02-
|
12
|
+
date: 2021-02-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|