jwt_sessions 2.7.0 → 2.7.4

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
  SHA256:
3
- metadata.gz: ad42d33af309b3295e9aa6402179df2a9a0ac5e17618d133427e27edafca9578
4
- data.tar.gz: e67b97b9bf3a2aec4bba3f66cc517d4dad03bcb4ce73269147cce31bcd9d85d4
3
+ metadata.gz: 8d8719e8f8b113faf2af6b40f1912d2cf4819527634411ec946a909c67833d31
4
+ data.tar.gz: f4e46db88c68b110dc78034925fce8193deab286d5703ea81ccfd2740bca9225
5
5
  SHA512:
6
- metadata.gz: fe6bc8a993388688a85d6b86ea139ab8d3123b628db77181fa4db6ba68d92c0080ca16fdfcaeb3567be9f2a07896df711cb9edb9c7845d6a226408e6fda00de9
7
- data.tar.gz: 712ea681644f82710f5d561a96e78df86c1c3e4c225b8535a9d1cd2e03bcb363d93e4b42764847b786461e26f6f9440a3f85b026e02fa557c647a5866eef70dc
6
+ metadata.gz: 6edb6fb526941fda66abcf0cea4a69904e08f4ca0be03ff7514d8c73e9b9f94cb86cb74a948612d62f3a20a2f91c123bce8c5e342b2600c959f0da90f4e0a918
7
+ data.tar.gz: b49c7a27800f9b7621565c9e9206a30f547e837668fb0fd683073ff75b062479bb0d51630f28cd165a70ecd767fc44f736795d4d12b480183fe7395b239696ac
data/CHANGELOG.md CHANGED
@@ -1,3 +1,28 @@
1
+ ## 2.7.4 (August 31, 2022)
2
+
3
+ Support:
4
+
5
+ - compatibility with redis 5.0
6
+
7
+ ## 2.7.3 (August 26, 2022)
8
+
9
+ Support:
10
+
11
+ - compatibility with jwt 2.5
12
+ - add rspec to development deps
13
+
14
+ ## 2.7.2 (January 24, 2022)
15
+
16
+ Bugfixes:
17
+
18
+ - 2.7.1 version didn't include the correct patch
19
+
20
+ ## 2.7.1 (January 22, 2022)
21
+
22
+ Bugfixes:
23
+
24
+ - Correctly init namespaced refresh tokens when fetching all tokens from Redis
25
+
1
26
  ## 2.7.0 (October 05, 2021)
2
27
 
3
28
  Features:
data/README.md CHANGED
@@ -409,11 +409,11 @@ jwt_sessions only uses `exp` claim by default when it decodes tokens and you can
409
409
  setting `jwt_options`. You can also specify leeway to account for clock skew.
410
410
 
411
411
  ```ruby
412
- JWTSessions.jwt_options.verify_iss = true
413
- JWTSessions.jwt_options.verify_sub = true
414
- JWTSessions.jwt_options.verify_iat = true
415
- JWTSessions.jwt_options.verify_aud = true
416
- JWTSessions.jwt_options.leeway = 30 # seconds
412
+ JWTSessions.jwt_options[:verify_iss] = true
413
+ JWTSessions.jwt_options[:verify_sub] = true
414
+ JWTSessions.jwt_options[:verify_iat] = true
415
+ JWTSessions.jwt_options[:verify_aud] = true
416
+ JWTSessions.jwt_options[:leeway] = 30 # seconds
417
417
  ```
418
418
 
419
419
  To pass options like `sub`, `aud`, `iss`, or leeways you should specify a method called `token_claims` in your controller.
@@ -61,7 +61,7 @@ module JWTSessions
61
61
  token_attrs[:access_uid],
62
62
  token_attrs[:access_expiration],
63
63
  store,
64
- namespace: namespace,
64
+ namespace: token_attrs[:namespace] || namespace,
65
65
  payload: {},
66
66
  uid: uid,
67
67
  expiration: token_attrs[:expiration]
@@ -89,7 +89,7 @@ module JWTSessions
89
89
  tokens.each do |token|
90
90
  AccessToken.destroy(token.access_uid, store)
91
91
  # unlink refresh token from the current access token
92
- token.update(nil, nil, token.csrf)
92
+ token.update(0, 0, token.csrf)
93
93
  end.count
94
94
  end
95
95
 
@@ -208,7 +208,7 @@ module JWTSessions
208
208
  def check_access_uid_within_refresh_token
209
209
  uid = retrieve_val_from(payload, :access, "uid", "access uid")
210
210
  access_uid = @_refresh.access_uid
211
- return if access_uid.size.zero?
211
+ return if access_uid == "0"
212
212
  yield @_refresh.uid, @_refresh.access_expiration if access_uid != uid
213
213
  end
214
214
 
@@ -37,10 +37,15 @@ module JWTSessions
37
37
 
38
38
  def fetch_refresh(uid, namespace, first_match = false)
39
39
  key = first_match ? first_refresh_key(uid) : full_refresh_key(uid, namespace)
40
- values = storage.hmget(key, *REFRESH_KEYS).compact
40
+ return {} if key.nil?
41
41
 
42
+ values = storage.hmget(key, *REFRESH_KEYS).compact
42
43
  return {} if values.length != REFRESH_KEYS.length
43
- REFRESH_KEYS.each_with_index.each_with_object({}) { |(key, index), acc| acc[key] = values[index] }
44
+
45
+ REFRESH_KEYS
46
+ .each_with_index
47
+ .each_with_object({}) { |(key, index), acc| acc[key] = values[index] }
48
+ .merge({ namespace: namespace })
44
49
  end
45
50
 
46
51
  def persist_refresh(uid:, access_expiration:, access_uid:, csrf:, expiration:, namespace: nil)
@@ -69,7 +74,10 @@ module JWTSessions
69
74
  keys_in_namespace = scan_keys(refresh_key("*", namespace))
70
75
  (keys_in_namespace || []).each_with_object({}) do |key, acc|
71
76
  uid = uid_from_key(key)
72
- acc[uid] = fetch_refresh(uid, namespace)
77
+ # to be able to properly initialize namespaced tokens extract their namespaces
78
+ # and pass down to fetch_refresh
79
+ token_namespace = namespace.to_s.empty? ? namespace_from_key(key) : namespace
80
+ acc[uid] = fetch_refresh(uid, token_namespace)
73
81
  end
74
82
  end
75
83
 
@@ -131,6 +139,14 @@ module JWTSessions
131
139
  key.split("_").last
132
140
  end
133
141
 
142
+ def namespace_from_key(key)
143
+ ns_regexp.match(key)&.[](:namespace)
144
+ end
145
+
146
+ def ns_regexp
147
+ @ns_regexp ||= Regexp.new("#{prefix}_(?<namespace>.+)_refresh")
148
+ end
149
+
134
150
  def scan_keys(key_pattern)
135
151
  cursor = 0
136
152
  all_keys = []
@@ -13,7 +13,7 @@ module JWTSessions
13
13
  end
14
14
 
15
15
  def decode(token, claims = {})
16
- decode_options = { algorithm: JWTSessions.algorithm }.merge(JWTSessions.jwt_options.to_h).merge(claims)
16
+ decode_options = { algorithm: JWTSessions.algorithm }.merge(JWTSessions.jwt_options).merge(claims)
17
17
  JWT.decode(token, JWTSessions.public_key, JWTSessions.validate?, decode_options)
18
18
  rescue JWT::ExpiredSignature => e
19
19
  raise Errors::Expired, e.message
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JWTSessions
4
- VERSION = "2.7.0"
4
+ VERSION = "2.7.4"
5
5
  end
data/lib/jwt_sessions.rb CHANGED
@@ -21,8 +21,6 @@ module JWTSessions
21
21
 
22
22
  NONE = "none"
23
23
 
24
- JWTOptions = Struct.new(*JWT::DefaultOptions::DEFAULT_OPTIONS.keys)
25
-
26
24
  DEFAULT_SETTINGS_KEYS = %i[access_cookie
27
25
  access_exp_time
28
26
  access_header
@@ -66,7 +64,7 @@ module JWTSessions
66
64
  end
67
65
 
68
66
  def jwt_options
69
- @jwt_options ||= JWTOptions.new(*JWT::DefaultOptions::DEFAULT_OPTIONS.values)
67
+ @jwt_options ||= JWT::Configuration::Container.new.decode.to_h
70
68
  end
71
69
 
72
70
  def algorithm=(algo)
@@ -24,13 +24,11 @@ class TestRedisStoreAdapter < Minitest::Test
24
24
  adapter = JWTSessions::StoreAdapters::RedisStoreAdapter.new(
25
25
  redis_url: "redis://127.0.0.1:6379",
26
26
  ssl_params: { verify_mode: OpenSSL::SSL::VERIFY_NONE },
27
- reconnect_delay: 2,
28
27
  timeout: 8
29
28
  )
30
29
  options = adapter.storage.instance_variable_get(:@options)
31
30
 
32
31
  assert_equal 8, options[:timeout]
33
- assert_equal 2, options[:reconnect_delay]
34
32
  assert_equal 0, options[:ssl_params][:verify_mode]
35
33
  end
36
34
 
@@ -309,8 +309,8 @@ class TestSession < Minitest::Test
309
309
  session.flush_namespaced_access_tokens
310
310
  ruid = session.instance_variable_get(:"@_refresh").uid
311
311
  refresh_token = JWTSessions::RefreshToken.find(ruid, JWTSessions.token_store, namespace)
312
- assert_equal "", refresh_token.access_uid
313
- assert_equal "", refresh_token.access_expiration
312
+ assert_equal "0", refresh_token.access_uid
313
+ assert_equal "0", refresh_token.access_expiration
314
314
 
315
315
  # allows to refresh with un-expired but flushed access token payload
316
316
  session.refresh_by_access_payload do
@@ -320,8 +320,8 @@ class TestSession < Minitest::Test
320
320
  access_token = JWTSessions::AccessToken.find(auid, JWTSessions.token_store)
321
321
  refresh_token = JWTSessions::RefreshToken.find(ruid, JWTSessions.token_store, namespace)
322
322
 
323
- assert_equal false, access_token.uid.size.zero?
324
- assert_equal false, access_token.expiration.size.zero?
323
+ assert "0" != access_token.uid
324
+ assert "0" != access_token.expiration
325
325
  assert_equal access_token.uid.to_s, refresh_token.access_uid
326
326
  assert_equal access_token.expiration.to_s, refresh_token.access_expiration
327
327
  end
@@ -24,7 +24,7 @@ class TestToken < Minitest::Test
24
24
 
25
25
  def teardown
26
26
  JWTSessions.algorithm = JWTSessions::DEFAULT_ALGORITHM
27
- JWTSessions.instance_variable_set(:"@jwt_options", JWTSessions::JWTOptions.new(*JWT::DefaultOptions::DEFAULT_OPTIONS.values))
27
+ JWTSessions.instance_variable_set(:"@jwt_options", JWT::Configuration::Container.new.decode.to_h)
28
28
  end
29
29
 
30
30
  def test_rsa_token_decode
@@ -73,7 +73,7 @@ class TestToken < Minitest::Test
73
73
 
74
74
  def test_token_sub_claim
75
75
  JWTSessions.encryption_key = "abcdefghijklmnopqrstuvwxyzABCDEF"
76
- JWTSessions.jwt_options.verify_sub = true
76
+ JWTSessions.jwt_options[:verify_sub] = true
77
77
  token = JWTSessions::Token.encode(payload.merge(sub: "subject"))
78
78
  decoded = JWTSessions::Token.decode(token, { sub: "subject" }).first
79
79
  assert_equal payload["user_id"], decoded["user_id"]
@@ -85,7 +85,7 @@ class TestToken < Minitest::Test
85
85
 
86
86
  def test_token_iss_claim
87
87
  JWTSessions.encryption_key = "abcdefghijklmnopqrstuvwxyzABCDEF"
88
- JWTSessions.jwt_options.verify_iss = true
88
+ JWTSessions.jwt_options[:verify_iss] = true
89
89
  token = JWTSessions::Token.encode(payload.merge(iss: "Me"))
90
90
  decoded = JWTSessions::Token.decode(token, { iss: "Me" }).first
91
91
  assert_equal payload["user_id"], decoded["user_id"]
@@ -97,7 +97,7 @@ class TestToken < Minitest::Test
97
97
 
98
98
  def test_token_aud_claim
99
99
  JWTSessions.encryption_key = "abcdefghijklmnopqrstuvwxyzABCDEF"
100
- JWTSessions.jwt_options.verify_aud = true
100
+ JWTSessions.jwt_options[:verify_aud] = true
101
101
  token = JWTSessions::Token.encode(payload.merge(aud: ["young", "old"]))
102
102
  decoded = JWTSessions::Token.decode(token, { aud: ["young"] }).first
103
103
  assert_equal payload["user_id"], decoded["user_id"]
@@ -109,7 +109,7 @@ class TestToken < Minitest::Test
109
109
 
110
110
  def test_token_leeway_decode
111
111
  JWTSessions.encryption_key = "abcdefghijklmnopqrstuvwxyzABCDEF"
112
- JWTSessions.jwt_options.leeway = 50
112
+ JWTSessions.jwt_options[:leeway] = 50
113
113
  token = JWTSessions::Token.encode(payload.merge("exp" => Time.now.to_i - 20))
114
114
  decoded = JWTSessions::Token.decode(token).first
115
115
  assert_equal payload["user_id"], decoded["user_id"]
metadata CHANGED
@@ -1,22 +1,22 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jwt_sessions
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.7.0
4
+ version: 2.7.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yulia Oletskaya
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-10-05 00:00:00.000000000 Z
11
+ date: 2022-08-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jwt
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 2.2.3
19
+ version: '2.5'
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
22
  version: '3'
@@ -24,9 +24,9 @@ dependencies:
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
- - - ">="
27
+ - - "~>"
28
28
  - !ruby/object:Gem::Version
29
- version: 2.2.3
29
+ version: '2.5'
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
32
  version: '3'
@@ -58,6 +58,20 @@ dependencies:
58
58
  - - "~>"
59
59
  - !ruby/object:Gem::Version
60
60
  version: '12.3'
61
+ - !ruby/object:Gem::Dependency
62
+ name: rspec
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '3.11'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '3.11'
61
75
  description: XSS/CSRF safe JWT auth designed for SPA
62
76
  email: yulia.oletskaya@gmail.com
63
77
  executables: []
@@ -98,7 +112,7 @@ metadata:
98
112
  changelog_uri: https://github.com/tuwukee/jwt_sessions/blob/master/CHANGELOG.md
99
113
  source_code_uri: https://github.com/tuwukee/jwt_sessions
100
114
  bug_tracker_uri: https://github.com/tuwukee/jwt_sessions/issues
101
- post_install_message:
115
+ post_install_message:
102
116
  rdoc_options: []
103
117
  require_paths:
104
118
  - lib
@@ -113,8 +127,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
113
127
  - !ruby/object:Gem::Version
114
128
  version: '0'
115
129
  requirements: []
116
- rubygems_version: 3.2.5
117
- signing_key:
130
+ rubygems_version: 3.0.3.1
131
+ signing_key:
118
132
  specification_version: 4
119
133
  summary: JWT Sessions
120
134
  test_files: