jwt_sessions 2.4.2 → 2.6.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 +5 -5
- data/CHANGELOG.md +49 -0
- data/README.md +43 -6
- data/lib/jwt_sessions.rb +2 -2
- data/lib/jwt_sessions/errors.rb +1 -0
- data/lib/jwt_sessions/session.rb +7 -7
- data/lib/jwt_sessions/store_adapters.rb +1 -1
- data/lib/jwt_sessions/store_adapters/abstract_store_adapter.rb +2 -1
- data/lib/jwt_sessions/store_adapters/memory_store_adapter.rb +11 -3
- data/lib/jwt_sessions/store_adapters/redis_store_adapter.rb +19 -5
- data/lib/jwt_sessions/token.rb +8 -4
- data/lib/jwt_sessions/version.rb +1 -1
- data/test/units/jwt_sessions/store_adapters/test_redis_store_adapter.rb +12 -7
- data/test/units/jwt_sessions/test_session.rb +12 -0
- data/test/units/jwt_sessions/test_token.rb +4 -4
- metadata +15 -39
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 8a485796c7aa19c00c79992111ed0135c0ec93af6e88aff80b233be779bb2301
|
4
|
+
data.tar.gz: d0b89a924589aa8450cfcaefb2061674db4d61cb32ed5ace92f1cab021db1fb1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e0bef3934719502d51f1299b210fad2df87360ef91cc3471384c3840870f3d548f43c5c5c1ff89a33e9e8847b706f9b7e1d2c240f288a21a16533369d8b0fce5
|
7
|
+
data.tar.gz: cd8b450b1a09e13290e3ac6ec5bcd17cf52c7314f01044ca1c2888321816585ff27eb7ae7b3935f5aa388fec3c11d9b8ebb0fe2c5fdde5a99cbc390932c4a646
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
## 2.6.0 (June 01, 2021)
|
2
|
+
|
3
|
+
Features:
|
4
|
+
|
5
|
+
- added support for all Redis settings
|
6
|
+
|
7
|
+
Support:
|
8
|
+
|
9
|
+
- updated jwt to '>= 2.2.3'
|
10
|
+
- switched to redis scan when looking for keys
|
11
|
+
- removed extra gems from gemspec deps
|
12
|
+
- updated gems in dummy apps
|
13
|
+
|
14
|
+
## 2.5.2 (July 06, 2020)
|
15
|
+
|
16
|
+
Bugfixes:
|
17
|
+
|
18
|
+
- fixed `Using the last argument as keyword parameters is deprecated;` warnings
|
19
|
+
|
20
|
+
## 2.5.1 (April 20, 2020)
|
21
|
+
|
22
|
+
Features:
|
23
|
+
|
24
|
+
- added changelog
|
25
|
+
|
26
|
+
Bugfixes:
|
27
|
+
|
28
|
+
- fixed double exp key in payload
|
29
|
+
|
30
|
+
Support:
|
31
|
+
|
32
|
+
- moved decode error text to a constant within token class
|
33
|
+
|
34
|
+
## 2.5.0 (April 12, 2020)
|
35
|
+
|
36
|
+
Features:
|
37
|
+
|
38
|
+
- added new error class `JWTSessions::Errors::Expired`
|
39
|
+
|
40
|
+
## 2.4.3 (September 19, 2019)
|
41
|
+
|
42
|
+
Bugfixes:
|
43
|
+
|
44
|
+
- fixed lookup for refresh token for namespaced sessions
|
45
|
+
|
46
|
+
Support:
|
47
|
+
|
48
|
+
- updated sqlite to ~> 1.4 in `dummy_api`
|
49
|
+
- added 2.6.3 Ruby to CI
|
data/README.md
CHANGED
@@ -15,10 +15,11 @@ XSS/CSRF safe JWT auth designed for SPA
|
|
15
15
|
- [Rails integration](#rails-integration)
|
16
16
|
- [Non-Rails usage](#non-rails-usage)
|
17
17
|
- [Configuration](#configuration)
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
18
|
+
- [Token store](#token-store)
|
19
|
+
- [JWT signature](#jwt-signature)
|
20
|
+
- [Request headers and cookies names](#request-headers-and-cookies-names)
|
21
|
+
- [Expiration time](#expiration-time)
|
22
|
+
- [Exceptions](#exceptions)
|
22
23
|
- [CSRF and cookies](#csrf-and-cookies)
|
23
24
|
- [Refresh with access token](#refresh-with-access-token)
|
24
25
|
- [Refresh token hijack protection](#refresh-token-hijack-protection)
|
@@ -368,6 +369,15 @@ JWTSessions.token_store = :redis, { redis_url: "redis://localhost:6397" }
|
|
368
369
|
|
369
370
|
**NOTE:** if `REDIS_URL` environment variable is set it is used automatically.
|
370
371
|
|
372
|
+
SSL, timeout, reconnect, etc. redis settings are supported:
|
373
|
+
```ruby
|
374
|
+
JWTSessions.token_store = :redis, {
|
375
|
+
read_timeout: 1.5,
|
376
|
+
reconnect_attempts: 10,
|
377
|
+
ssl_params: { verify_mode: OpenSSL::SSL::VERIFY_NONE }
|
378
|
+
}
|
379
|
+
```
|
380
|
+
|
371
381
|
##### JWT signature
|
372
382
|
|
373
383
|
```ruby
|
@@ -441,6 +451,15 @@ JWTSessions.refresh_exp_time = 604800 # 1 week in seconds
|
|
441
451
|
|
442
452
|
It is defined globally, but can be overridden on a session level. See `JWTSessions::Session.new` options for more info.
|
443
453
|
|
454
|
+
##### Exceptions
|
455
|
+
|
456
|
+
`JWTSessions::Errors::Error` - base class, all possible exceptions are inhereted from it. \
|
457
|
+
`JWTSessions::Errors::Malconfigured` - some required gem settings are empty, or methods are not implemented. \
|
458
|
+
`JWTSessions::Errors::InvalidPayload` - token's payload doesn't contain required keys or they are invalid. \
|
459
|
+
`JWTSessions::Errors::Unauthorized` - token can't be decoded or JWT claims are invalid. \
|
460
|
+
`JWTSessions::Errors::ClaimsVerification` - JWT claims are invalid (inherited from `JWTSessions::Errors::Unauthorized`). \
|
461
|
+
`JWTSessions::Errors::Expired` - token is expired (inherited from `JWTSessions::Errors::ClaimsVerification`).
|
462
|
+
|
444
463
|
#### CSRF and cookies
|
445
464
|
|
446
465
|
When you use cookies as your tokens transport it becomes vulnerable to CSRF. That is why both the login and refresh methods of the `Session` class produce CSRF tokens for you. `Authorization` mixin expects that this token is sent with all requests except GET and HEAD in a header specified among this gem's settings (`X-CSRF-Token` by default). Verification will be done automatically and the `Authorization` exception will be raised in case of a mismatch between the token from the header and the one stored in the session. \
|
@@ -455,7 +474,7 @@ session.masked_csrf(access_token)
|
|
455
474
|
|
456
475
|
Sometimes it is not secure enough to store the refresh tokens in web / JS clients. \
|
457
476
|
This is why you have the option to only use an access token and to not pass the refresh token to the client at all. \
|
458
|
-
Session accepts `refresh_by_access_allowed: true` setting, which links the access token to the corresponding refresh token.
|
477
|
+
Session accepts `refresh_by_access_allowed: true` setting, which links the access token to the corresponding refresh token.
|
459
478
|
|
460
479
|
Example Rails login controller, which passes an access token token via cookies and renders CSRF:
|
461
480
|
|
@@ -490,7 +509,18 @@ tokens = session.refresh_by_access_payload
|
|
490
509
|
|
491
510
|
In case of token forgery and successful refresh performed by an attacker the original user will have to logout. \
|
492
511
|
To protect the endpoint use the before_action `authorize_refresh_by_access_request!`. \
|
493
|
-
Refresh should be performed once the access token is already expired and we need to use the `claimless_payload` method in order to skip JWT expiration validation (and other claims) in order to proceed.
|
512
|
+
Refresh should be performed once the access token is already expired and we need to use the `claimless_payload` method in order to skip JWT expiration validation (and other claims) in order to proceed.
|
513
|
+
|
514
|
+
Optionally `refresh_by_access_payload` accepts a block argument (the same way `refresh` method does).
|
515
|
+
The block will be called if the refresh action is performed before the access token is expired.
|
516
|
+
Thereby it's possible to prohibit users from making refresh calls while their access token is still active.
|
517
|
+
|
518
|
+
```ruby
|
519
|
+
tokens = session.refresh_by_access_payload do
|
520
|
+
# here goes malicious activity alert
|
521
|
+
raise JWTSessions::Errors::Unauthorized, "Refresh action is performed before the expiration of the access token."
|
522
|
+
end
|
523
|
+
```
|
494
524
|
|
495
525
|
Example Rails refresh by access controller with cookies as token transport:
|
496
526
|
|
@@ -571,6 +601,13 @@ session = JWTSessions::Session.new(namespace: "ie-sessions")
|
|
571
601
|
session.flush_namespaced # will flush all sessions which belong to the same namespace
|
572
602
|
```
|
573
603
|
|
604
|
+
Selectively flush one single session inside a namespace by its access token:
|
605
|
+
|
606
|
+
```ruby
|
607
|
+
session = JWTSessions::Session.new(namespace: "ie-sessions", payload: payload)
|
608
|
+
session.flush_by_access_payload # will flush a specific session which belongs to an existing namespace
|
609
|
+
```
|
610
|
+
|
574
611
|
Flush access tokens only:
|
575
612
|
|
576
613
|
```ruby
|
data/lib/jwt_sessions.rb
CHANGED
@@ -155,7 +155,7 @@ module JWTSessions
|
|
155
155
|
private
|
156
156
|
|
157
157
|
def supported_algos
|
158
|
-
algos = JWT::Algos
|
159
|
-
algos.map { |algo|
|
158
|
+
algos = JWT::Algos::ALGOS - [JWT::Algos::Unsupported]
|
159
|
+
algos.map { |algo| algo::SUPPORTED }.flatten + [NONE]
|
160
160
|
end
|
161
161
|
end
|
data/lib/jwt_sessions/errors.rb
CHANGED
data/lib/jwt_sessions/session.rb
CHANGED
@@ -37,7 +37,7 @@ module JWTSessions
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def session_exists?(token, token_type = :access)
|
40
|
-
send(:"#{token_type}_token_data", token)
|
40
|
+
send(:"#{token_type}_token_data", token, true)
|
41
41
|
true
|
42
42
|
rescue Errors::Unauthorized
|
43
43
|
false
|
@@ -142,20 +142,20 @@ module JWTSessions
|
|
142
142
|
end
|
143
143
|
|
144
144
|
def refresh_csrf(refresh_token)
|
145
|
-
refresh_token_instance = refresh_token_data(refresh_token)
|
145
|
+
refresh_token_instance = refresh_token_data(refresh_token, true)
|
146
146
|
CSRFToken.new(refresh_token_instance.csrf)
|
147
147
|
end
|
148
148
|
|
149
|
-
def access_token_data(token)
|
149
|
+
def access_token_data(token, _first_match = false)
|
150
150
|
uid = token_uid(token, :access, @access_claims)
|
151
151
|
data = store.fetch_access(uid)
|
152
152
|
raise Errors::Unauthorized, "Access token not found" if data.empty?
|
153
153
|
data
|
154
154
|
end
|
155
155
|
|
156
|
-
def refresh_token_data(token)
|
156
|
+
def refresh_token_data(token, first_match = false)
|
157
157
|
uid = token_uid(token, :refresh, @refresh_claims)
|
158
|
-
retrieve_refresh_token(uid)
|
158
|
+
retrieve_refresh_token(uid, first_match: first_match)
|
159
159
|
end
|
160
160
|
|
161
161
|
def token_uid(token, type, claims)
|
@@ -177,8 +177,8 @@ module JWTSessions
|
|
177
177
|
val
|
178
178
|
end
|
179
179
|
|
180
|
-
def retrieve_refresh_token(uid)
|
181
|
-
@_refresh = RefreshToken.find(uid, store, namespace)
|
180
|
+
def retrieve_refresh_token(uid, first_match: false)
|
181
|
+
@_refresh = RefreshToken.find(uid, store, namespace, first_match: first_match)
|
182
182
|
end
|
183
183
|
|
184
184
|
def tokens_hash
|
@@ -9,7 +9,7 @@ module JWTSessions
|
|
9
9
|
def self.build_by_name(adapter, options = nil)
|
10
10
|
camelized_adapter = adapter.to_s.split('_').map(&:capitalize).join
|
11
11
|
adapter_class_name = "#{camelized_adapter}StoreAdapter"
|
12
|
-
StoreAdapters.const_get(adapter_class_name).new(options || {})
|
12
|
+
StoreAdapters.const_get(adapter_class_name).new(**(options || {}))
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
@@ -5,7 +5,7 @@ module JWTSessions
|
|
5
5
|
class MemoryStoreAdapter < AbstractStoreAdapter
|
6
6
|
attr_reader :storage
|
7
7
|
|
8
|
-
def initialize(options)
|
8
|
+
def initialize(**options)
|
9
9
|
raise ArgumentError, "Memory store doesn't support any options" if options.any?
|
10
10
|
@storage = Hash.new do |h, k|
|
11
11
|
h[k] = Hash.new { |hh, kk| hh[kk] = {} }
|
@@ -22,8 +22,16 @@ module JWTSessions
|
|
22
22
|
storage[""]["access"].store(uid, access_token)
|
23
23
|
end
|
24
24
|
|
25
|
-
def fetch_refresh(uid, namespace,
|
26
|
-
|
25
|
+
def fetch_refresh(uid, namespace, first_match = false)
|
26
|
+
if first_match
|
27
|
+
storage.keys.each do |namespace_key|
|
28
|
+
val = value_if_not_expired(uid, "refresh", namespace_key)
|
29
|
+
return val unless val.empty?
|
30
|
+
end
|
31
|
+
{}
|
32
|
+
else
|
33
|
+
value_if_not_expired(uid, "refresh", namespace.to_s)
|
34
|
+
end
|
27
35
|
end
|
28
36
|
|
29
37
|
def persist_refresh(uid:, access_expiration:, access_uid:, csrf:, expiration:, namespace: "")
|
@@ -12,7 +12,7 @@ module JWTSessions
|
|
12
12
|
|
13
13
|
begin
|
14
14
|
require "redis"
|
15
|
-
@storage = configure_redis_client(options)
|
15
|
+
@storage = configure_redis_client(**options)
|
16
16
|
rescue LoadError => e
|
17
17
|
msg = "Could not load the 'redis' gem, please add it to your gemfile or " \
|
18
18
|
"configure a different adapter (e.g. JWTSessions.store_adapter = :memory)"
|
@@ -62,7 +62,7 @@ module JWTSessions
|
|
62
62
|
end
|
63
63
|
|
64
64
|
def all_refresh_tokens(namespace)
|
65
|
-
keys_in_namespace =
|
65
|
+
keys_in_namespace = scan_keys(refresh_key("*", namespace))
|
66
66
|
(keys_in_namespace || []).each_with_object({}) do |key, acc|
|
67
67
|
uid = uid_from_key(key)
|
68
68
|
acc[uid] = fetch_refresh(uid, namespace)
|
@@ -80,7 +80,7 @@ module JWTSessions
|
|
80
80
|
|
81
81
|
private
|
82
82
|
|
83
|
-
def configure_redis_client(redis_url: nil, redis_host: nil, redis_port: nil, redis_db_name: nil)
|
83
|
+
def configure_redis_client(redis_url: nil, redis_host: nil, redis_port: nil, redis_db_name: nil, **options)
|
84
84
|
if redis_url && (redis_host || redis_port || redis_db_name)
|
85
85
|
raise ArgumentError, "redis_url cannot be passed along with redis_host, redis_port or redis_db_name options"
|
86
86
|
end
|
@@ -91,7 +91,7 @@ module JWTSessions
|
|
91
91
|
redis_db_name: redis_db_name
|
92
92
|
)
|
93
93
|
|
94
|
-
Redis.new(url: redis_url)
|
94
|
+
Redis.new(options.merge(url: redis_url))
|
95
95
|
end
|
96
96
|
|
97
97
|
def build_redis_url(redis_host: nil, redis_port: nil, redis_db_name: nil)
|
@@ -111,7 +111,7 @@ module JWTSessions
|
|
111
111
|
|
112
112
|
def first_refresh_key(uid)
|
113
113
|
key = full_refresh_key(uid, "*")
|
114
|
-
(
|
114
|
+
(scan_keys(key) || []).first
|
115
115
|
end
|
116
116
|
|
117
117
|
def refresh_key(uid, namespace)
|
@@ -126,6 +126,20 @@ module JWTSessions
|
|
126
126
|
def uid_from_key(key)
|
127
127
|
key.split("_").last
|
128
128
|
end
|
129
|
+
|
130
|
+
def scan_keys(key_pattern)
|
131
|
+
cursor = 0
|
132
|
+
all_keys = []
|
133
|
+
|
134
|
+
loop do
|
135
|
+
cursor, keys = storage.scan(cursor, match: key_pattern, count: 1000)
|
136
|
+
all_keys |= keys
|
137
|
+
|
138
|
+
break if cursor == "0"
|
139
|
+
end
|
140
|
+
|
141
|
+
all_keys
|
142
|
+
end
|
129
143
|
end
|
130
144
|
end
|
131
145
|
end
|
data/lib/jwt_sessions/token.rb
CHANGED
@@ -4,6 +4,8 @@ require "jwt"
|
|
4
4
|
|
5
5
|
module JWTSessions
|
6
6
|
class Token
|
7
|
+
DECODE_ERROR = "cannot decode the token"
|
8
|
+
|
7
9
|
class << self
|
8
10
|
def encode(payload)
|
9
11
|
exp_payload = meta.merge(payload)
|
@@ -13,23 +15,25 @@ module JWTSessions
|
|
13
15
|
def decode(token, claims = {})
|
14
16
|
decode_options = { algorithm: JWTSessions.algorithm }.merge(JWTSessions.jwt_options.to_h).merge(claims)
|
15
17
|
JWT.decode(token, JWTSessions.public_key, JWTSessions.validate?, decode_options)
|
16
|
-
rescue JWT::
|
18
|
+
rescue JWT::ExpiredSignature => e
|
19
|
+
raise Errors::Expired, e.message
|
20
|
+
rescue JWT::InvalidIssuerError, JWT::InvalidIatError, JWT::InvalidAudError, JWT::InvalidSubError, JWT::InvalidJtiError => e
|
17
21
|
raise Errors::ClaimsVerification, e.message
|
18
22
|
rescue JWT::DecodeError => e
|
19
23
|
raise Errors::Unauthorized, e.message
|
20
24
|
rescue StandardError
|
21
|
-
raise Errors::Unauthorized,
|
25
|
+
raise Errors::Unauthorized, DECODE_ERROR
|
22
26
|
end
|
23
27
|
|
24
28
|
def decode!(token)
|
25
29
|
decode_options = { algorithm: JWTSessions.algorithm }
|
26
30
|
JWT.decode(token, JWTSessions.public_key, false, decode_options)
|
27
31
|
rescue StandardError
|
28
|
-
raise Errors::Unauthorized,
|
32
|
+
raise Errors::Unauthorized, DECODE_ERROR
|
29
33
|
end
|
30
34
|
|
31
35
|
def meta
|
32
|
-
{ exp
|
36
|
+
{ "exp" => JWTSessions.access_expiration }
|
33
37
|
end
|
34
38
|
end
|
35
39
|
end
|
data/lib/jwt_sessions/version.rb
CHANGED
@@ -20,13 +20,18 @@ class TestRedisStoreAdapter < Minitest::Test
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
def
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
23
|
+
def test_support_of_extra_options
|
24
|
+
adapter = JWTSessions::StoreAdapters::RedisStoreAdapter.new(
|
25
|
+
redis_url: "redis://127.0.0.1:6379",
|
26
|
+
ssl_params: { verify_mode: OpenSSL::SSL::VERIFY_NONE },
|
27
|
+
reconnect_delay: 2,
|
28
|
+
timeout: 8
|
29
|
+
)
|
30
|
+
options = adapter.storage.instance_variable_get(:@options)
|
31
|
+
|
32
|
+
assert_equal 8, options[:timeout]
|
33
|
+
assert_equal 2, options[:reconnect_delay]
|
34
|
+
assert_equal 0, options[:ssl_params][:verify_mode]
|
30
35
|
end
|
31
36
|
|
32
37
|
def test_default_url
|
@@ -69,6 +69,18 @@ class TestSession < Minitest::Test
|
|
69
69
|
end
|
70
70
|
end
|
71
71
|
|
72
|
+
def test_refresh_with_namespace
|
73
|
+
@new_session = JWTSessions::Session.new(
|
74
|
+
payload: payload,
|
75
|
+
namespace: "custom-namespace"
|
76
|
+
)
|
77
|
+
new_tokens = @new_session.login
|
78
|
+
refreshed_tokens = @new_session.refresh(new_tokens[:refresh])
|
79
|
+
decoded_access = JWTSessions::Token.decode(refreshed_tokens[:access]).first
|
80
|
+
assert_equal REFRESH_KEYS, refreshed_tokens.keys.sort
|
81
|
+
assert_equal payload[:test], decoded_access["test"]
|
82
|
+
end
|
83
|
+
|
72
84
|
def test_refresh_by_access_payload
|
73
85
|
session = JWTSessions::Session.new(payload: payload, refresh_by_access_allowed: true)
|
74
86
|
session.login
|
@@ -110,11 +110,11 @@ class TestToken < Minitest::Test
|
|
110
110
|
def test_token_leeway_decode
|
111
111
|
JWTSessions.encryption_key = "abcdefghijklmnopqrstuvwxyzABCDEF"
|
112
112
|
JWTSessions.jwt_options.leeway = 50
|
113
|
-
token = JWTSessions::Token.encode(payload.merge(exp
|
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"]
|
116
116
|
assert_equal payload["secret"], decoded["secret"]
|
117
|
-
token = JWTSessions::Token.encode(payload.merge(exp
|
117
|
+
token = JWTSessions::Token.encode(payload.merge("exp" => Time.now.to_i - 100))
|
118
118
|
assert_raises JWTSessions::Errors::Unauthorized do
|
119
119
|
JWTSessions::Token.decode(token)
|
120
120
|
end
|
@@ -141,8 +141,8 @@ class TestToken < Minitest::Test
|
|
141
141
|
end
|
142
142
|
|
143
143
|
def test_payload_exp_time
|
144
|
-
token = JWTSessions::Token.encode(payload.merge(exp
|
145
|
-
assert_raises JWTSessions::Errors::
|
144
|
+
token = JWTSessions::Token.encode(payload.merge("exp" => Time.now.to_i - (3600 * 24)))
|
145
|
+
assert_raises JWTSessions::Errors::Expired do
|
146
146
|
JWTSessions::Token.decode(token)
|
147
147
|
end
|
148
148
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jwt_sessions
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yulia Oletskaya
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-06-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: jwt
|
@@ -16,7 +16,7 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 2.
|
19
|
+
version: 2.2.3
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
22
|
version: '3'
|
@@ -26,7 +26,7 @@ dependencies:
|
|
26
26
|
requirements:
|
27
27
|
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: 2.
|
29
|
+
version: 2.2.3
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: '3'
|
@@ -44,34 +44,6 @@ dependencies:
|
|
44
44
|
- - ">="
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: '1.16'
|
47
|
-
- !ruby/object:Gem::Dependency
|
48
|
-
name: minitest
|
49
|
-
requirement: !ruby/object:Gem::Requirement
|
50
|
-
requirements:
|
51
|
-
- - "~>"
|
52
|
-
- !ruby/object:Gem::Version
|
53
|
-
version: '5.11'
|
54
|
-
type: :development
|
55
|
-
prerelease: false
|
56
|
-
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
requirements:
|
58
|
-
- - "~>"
|
59
|
-
- !ruby/object:Gem::Version
|
60
|
-
version: '5.11'
|
61
|
-
- !ruby/object:Gem::Dependency
|
62
|
-
name: pry
|
63
|
-
requirement: !ruby/object:Gem::Requirement
|
64
|
-
requirements:
|
65
|
-
- - "~>"
|
66
|
-
- !ruby/object:Gem::Version
|
67
|
-
version: '0.11'
|
68
|
-
type: :development
|
69
|
-
prerelease: false
|
70
|
-
version_requirements: !ruby/object:Gem::Requirement
|
71
|
-
requirements:
|
72
|
-
- - "~>"
|
73
|
-
- !ruby/object:Gem::Version
|
74
|
-
version: '0.11'
|
75
47
|
- !ruby/object:Gem::Dependency
|
76
48
|
name: rake
|
77
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -92,6 +64,7 @@ executables: []
|
|
92
64
|
extensions: []
|
93
65
|
extra_rdoc_files: []
|
94
66
|
files:
|
67
|
+
- CHANGELOG.md
|
95
68
|
- LICENSE
|
96
69
|
- README.md
|
97
70
|
- lib/jwt_sessions.rb
|
@@ -120,7 +93,11 @@ files:
|
|
120
93
|
homepage: http://rubygems.org/gems/jwt_sessions
|
121
94
|
licenses:
|
122
95
|
- MIT
|
123
|
-
metadata:
|
96
|
+
metadata:
|
97
|
+
homepage_uri: https://github.com/tuwukee/jwt_sessions
|
98
|
+
changelog_uri: https://github.com/tuwukee/jwt_sessions/blob/master/CHANGELOG.md
|
99
|
+
source_code_uri: https://github.com/tuwukee/jwt_sessions
|
100
|
+
bug_tracker_uri: https://github.com/tuwukee/jwt_sessions/issues
|
124
101
|
post_install_message:
|
125
102
|
rdoc_options: []
|
126
103
|
require_paths:
|
@@ -136,18 +113,17 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
136
113
|
- !ruby/object:Gem::Version
|
137
114
|
version: '0'
|
138
115
|
requirements: []
|
139
|
-
|
140
|
-
rubygems_version: 2.6.13
|
116
|
+
rubygems_version: 3.0.3
|
141
117
|
signing_key:
|
142
118
|
specification_version: 4
|
143
119
|
summary: JWT Sessions
|
144
120
|
test_files:
|
145
121
|
- test/units/test_jwt_sessions.rb
|
146
122
|
- test/units/test_token_store.rb
|
147
|
-
- test/units/jwt_sessions/store_adapters/test_memory_store_adapter.rb
|
148
|
-
- test/units/jwt_sessions/store_adapters/test_redis_store_adapter.rb
|
149
|
-
- test/units/jwt_sessions/test_access_token.rb
|
150
123
|
- test/units/jwt_sessions/test_csrf_token.rb
|
124
|
+
- test/units/jwt_sessions/test_access_token.rb
|
125
|
+
- test/units/jwt_sessions/store_adapters/test_redis_store_adapter.rb
|
126
|
+
- test/units/jwt_sessions/store_adapters/test_memory_store_adapter.rb
|
127
|
+
- test/units/jwt_sessions/test_token.rb
|
151
128
|
- test/units/jwt_sessions/test_refresh_token.rb
|
152
129
|
- test/units/jwt_sessions/test_session.rb
|
153
|
-
- test/units/jwt_sessions/test_token.rb
|