jwt_sessions 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +39 -1
- data/lib/jwt_sessions.rb +4 -2
- data/lib/jwt_sessions/authorization.rb +5 -0
- data/lib/jwt_sessions/redis_token_store.rb +38 -13
- data/lib/jwt_sessions/refresh_token.rb +38 -19
- data/lib/jwt_sessions/session.rb +48 -7
- data/lib/jwt_sessions/version.rb +1 -1
- data/test/units/jwt_sessions/test_refresh_token.rb +5 -4
- data/test/units/jwt_sessions/test_session.rb +64 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a82e7a774b3c7707f9766cab5daaa7931c02575b
|
4
|
+
data.tar.gz: b31598139258b52483ccd593feae380c240d1c24
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c34675a2622944e5e715302bea401442b335abbaeede9b3f77829cee3e7a1d0d1ecc22dc6874ec23954a50f1b91e110b5ab681b3bed538f8dedc8384f67a20b6
|
7
|
+
data.tar.gz: 1d7fb0b9052c9a1df4610282b1ab39e63b9a35d0fd5b77a5d35f83417ff8d0cd52d489f470a3feecf9ede8cffa568301801ab7e1262316be0c559dcf0e0296cf
|
data/README.md
CHANGED
@@ -20,6 +20,8 @@ XSS/CSRF safe JWT auth designed for SPA
|
|
20
20
|
+ [Expiration time](#expiration-time)
|
21
21
|
+ [CSRF and cookies](#csrf-and-cookies)
|
22
22
|
+ [Refresh token hijack protection](#refresh-token-hijack-protection)
|
23
|
+
- [Flush Sessions](#flush-sessions)
|
24
|
+
+ [Sessions Namespace](#sessions-namespace)
|
23
25
|
- [Examples](#examples)
|
24
26
|
- [TODO](#todo)
|
25
27
|
- [Contributing](#contributing)
|
@@ -82,7 +84,7 @@ JWTSessions.algorithm = 'HS256'
|
|
82
84
|
JWTSessions.encryption_key = Rails.application.secrets.secret_jwt_encryption_key
|
83
85
|
```
|
84
86
|
|
85
|
-
Most of the encryption algorithms require private and public keys to sign a token, yet HMAC only require a single key, so you can use a shortcat `
|
87
|
+
Most of the encryption algorithms require private and public keys to sign a token, yet HMAC only require a single key, so you can use a shortcat `encryption_key` to sign the token. For other algorithms you must specify a private and public keys separately.
|
86
88
|
|
87
89
|
```ruby
|
88
90
|
JWTSessions.algorithm = 'RS256'
|
@@ -381,6 +383,42 @@ session = JwtSessions::Session.new(payload: payload)
|
|
381
383
|
session.refresh(refresh_token) { |refresh_token_uid, access_token_expiration| ... }
|
382
384
|
```
|
383
385
|
|
386
|
+
## Flush Sessions
|
387
|
+
|
388
|
+
Flush session by refresh token. The method returns number of flushed sessions.
|
389
|
+
|
390
|
+
```ruby
|
391
|
+
session = JWTSessions::Session.new
|
392
|
+
tokens = session.login
|
393
|
+
session.flush_by_token(tokens[:refresh]) # => 1
|
394
|
+
```
|
395
|
+
|
396
|
+
Or by refresh token UID
|
397
|
+
|
398
|
+
```ruby
|
399
|
+
session.flush_by_uid(uid) # => 1
|
400
|
+
```
|
401
|
+
|
402
|
+
##### Sessions namespace
|
403
|
+
|
404
|
+
It's possible to group sessions by custom namespaces
|
405
|
+
|
406
|
+
```ruby
|
407
|
+
session = JWTSessions::Session.new(namespace: 'account-1')
|
408
|
+
```
|
409
|
+
|
410
|
+
and selectively flush sessions by namespace
|
411
|
+
|
412
|
+
```ruby
|
413
|
+
session = JWTSessions::Session.new(namespace: 'ie-sessions')
|
414
|
+
session.flush_namespaced # will flush all sessions that belong to the same namespace
|
415
|
+
```
|
416
|
+
|
417
|
+
To force flush of all app sessions
|
418
|
+
```ruby
|
419
|
+
JWTSessions::Session.flush_all
|
420
|
+
```
|
421
|
+
|
384
422
|
## Examples
|
385
423
|
|
386
424
|
[Rails API](test/support/dummy_api) \
|
data/lib/jwt_sessions.rb
CHANGED
@@ -25,7 +25,6 @@ module JWTSessions
|
|
25
25
|
DEFAULT_SETTINGS_KEYS = %i[access_cookie
|
26
26
|
access_exp_time
|
27
27
|
access_header
|
28
|
-
algorithm
|
29
28
|
csrf_header
|
30
29
|
redis_db_name
|
31
30
|
redis_host
|
@@ -74,6 +73,10 @@ module JWTSessions
|
|
74
73
|
@algorithm = algo
|
75
74
|
end
|
76
75
|
|
76
|
+
def algorithm
|
77
|
+
@algorithm ||= DEFAULT_ALGORITHM
|
78
|
+
end
|
79
|
+
|
77
80
|
def token_store
|
78
81
|
RedisTokenStore.instance(redis_host, redis_port, redis_db_name, token_prefix)
|
79
82
|
end
|
@@ -110,7 +113,6 @@ module JWTSessions
|
|
110
113
|
Time.now.to_i + refresh_exp_time.to_i
|
111
114
|
end
|
112
115
|
|
113
|
-
|
114
116
|
def header_by(token_type)
|
115
117
|
send("#{token_type}_header")
|
116
118
|
end
|
@@ -16,6 +16,7 @@ module JWTSessions
|
|
16
16
|
end
|
17
17
|
# triggers token decode and jwt claim checks
|
18
18
|
payload
|
19
|
+
invalid_authorization unless session_exists?(token_type)
|
19
20
|
check_csrf(token_type)
|
20
21
|
end
|
21
22
|
end
|
@@ -50,6 +51,10 @@ module JWTSessions
|
|
50
51
|
JWTSessions::Session.new.valid_csrf?(found_token, csrf_token, token_type)
|
51
52
|
end
|
52
53
|
|
54
|
+
def session_exists?(token_type)
|
55
|
+
JWTSessions::Session.new.session_exists?(found_token, token_type)
|
56
|
+
end
|
57
|
+
|
53
58
|
def cookieless_auth(token_type)
|
54
59
|
@_csrf_check = false
|
55
60
|
@_raw_token = token_from_headers(token_type)
|
@@ -43,26 +43,38 @@ module JWTSessions
|
|
43
43
|
store.expireat(key, expiration)
|
44
44
|
end
|
45
45
|
|
46
|
-
def fetch_refresh(uid)
|
47
|
-
keys = [
|
48
|
-
values = store.hmget(refresh_key(uid), *keys).compact
|
46
|
+
def fetch_refresh(uid, namespace)
|
47
|
+
keys = %i[csrf access_uid access_expiration expiration]
|
48
|
+
values = store.hmget(refresh_key(uid, namespace), *keys).compact
|
49
49
|
return {} if values.length != keys.length
|
50
|
-
keys.each_with_index.
|
50
|
+
keys.each_with_index.each_with_object({}) { |(key, index), acc| acc[key] = values[index]; }
|
51
51
|
end
|
52
52
|
|
53
|
-
def persist_refresh(uid, access_expiration, access_uid, csrf, expiration)
|
54
|
-
|
55
|
-
|
53
|
+
def persist_refresh(uid, access_expiration, access_uid, csrf, expiration, namespace = nil)
|
54
|
+
ns = namespace || ''
|
55
|
+
key = refresh_key(uid, ns)
|
56
|
+
update_refresh(uid, access_expiration, access_uid, csrf, ns)
|
56
57
|
store.hset(key, :expiration, expiration)
|
57
58
|
store.expireat(key, expiration)
|
58
59
|
end
|
59
60
|
|
60
|
-
def update_refresh(uid, access_expiration, access_uid, csrf)
|
61
|
-
store.hmset(refresh_key(uid
|
61
|
+
def update_refresh(uid, access_expiration, access_uid, csrf, namespace = nil)
|
62
|
+
store.hmset(refresh_key(uid, namespace),
|
63
|
+
:csrf, csrf,
|
64
|
+
:access_expiration, access_expiration,
|
65
|
+
:access_uid, access_uid)
|
62
66
|
end
|
63
67
|
|
64
|
-
def
|
65
|
-
store.
|
68
|
+
def all_in_namespace(namespace)
|
69
|
+
keys = store.keys(refresh_key('*', namespace))
|
70
|
+
(keys || []).each_with_object({}) do |key, acc|
|
71
|
+
uid = uid_from_key(key)
|
72
|
+
acc[uid] = fetch_refresh(uid, namespace)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def destroy_refresh(uid, namespace)
|
77
|
+
store.del(refresh_key(uid, namespace))
|
66
78
|
end
|
67
79
|
|
68
80
|
def destroy_access(uid)
|
@@ -75,8 +87,21 @@ module JWTSessions
|
|
75
87
|
"#{prefix}_access_#{uid}"
|
76
88
|
end
|
77
89
|
|
78
|
-
def refresh_key(uid)
|
79
|
-
|
90
|
+
def refresh_key(uid, namespace = nil)
|
91
|
+
if namespace
|
92
|
+
"#{prefix}_#{namespace}_refresh_#{uid}"
|
93
|
+
else
|
94
|
+
wildcard_refresh_key(uid)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def wildcard_refresh_key(uid)
|
99
|
+
keys = store.keys(refresh_key(uid, '*')) || []
|
100
|
+
keys.first
|
101
|
+
end
|
102
|
+
|
103
|
+
def uid_from_key(key)
|
104
|
+
key.split('_').last
|
80
105
|
end
|
81
106
|
end
|
82
107
|
end
|
@@ -2,39 +2,58 @@
|
|
2
2
|
|
3
3
|
module JWTSessions
|
4
4
|
class RefreshToken
|
5
|
-
attr_reader :expiration, :uid, :token, :csrf, :access_uid, :access_expiration, :store
|
5
|
+
attr_reader :expiration, :uid, :token, :csrf, :access_uid, :access_expiration, :store, :namespace
|
6
6
|
|
7
|
-
def initialize(csrf,
|
7
|
+
def initialize(csrf,
|
8
|
+
access_uid,
|
9
|
+
access_expiration,
|
10
|
+
store,
|
11
|
+
options = {})
|
8
12
|
@csrf = csrf
|
9
13
|
@access_uid = access_uid
|
10
14
|
@access_expiration = access_expiration
|
11
|
-
@uid = uid
|
12
|
-
@expiration = expiration
|
13
15
|
@store = store
|
14
|
-
@
|
16
|
+
@uid = options.fetch(:uid, SecureRandom.uuid)
|
17
|
+
@expiration = options.fetch(:expiration, JWTSessions.refresh_expiration)
|
18
|
+
@namespace = options.fetch(:namespace, nil)
|
19
|
+
@token = Token.encode(options.fetch(:payload, {}).merge(uid: uid, exp: expiration.to_i))
|
15
20
|
end
|
16
21
|
|
17
22
|
class << self
|
18
|
-
def create(csrf, access_uid, access_expiration, store, payload)
|
19
|
-
inst = new(csrf, access_uid, access_expiration, store, payload)
|
23
|
+
def create(csrf, access_uid, access_expiration, store, payload, namespace)
|
24
|
+
inst = new(csrf, access_uid, access_expiration, store, payload: payload, namespace: namespace)
|
20
25
|
inst.send(:persist_in_store)
|
21
26
|
inst
|
22
27
|
end
|
23
28
|
|
24
|
-
def
|
25
|
-
|
29
|
+
def all(namespace, store)
|
30
|
+
tokens = store.all_in_namespace(namespace)
|
31
|
+
tokens.map do |uid, token_attrs|
|
32
|
+
build_with_token_attrs(store, uid, token_attrs, namespace)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def find(uid, store, namespace)
|
37
|
+
token_attrs = store.fetch_refresh(uid, namespace)
|
26
38
|
raise Errors::Unauthorized, 'Refresh token not found' if token_attrs.empty?
|
39
|
+
build_with_token_attrs(store, uid, token_attrs, namespace)
|
40
|
+
end
|
41
|
+
|
42
|
+
def destroy(uid, store, namespace)
|
43
|
+
store.destroy_refresh(uid, namespace)
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def build_with_token_attrs(store, uid, token_attrs, namespace)
|
27
49
|
new(token_attrs[:csrf],
|
28
50
|
token_attrs[:access_uid],
|
29
51
|
token_attrs[:access_expiration],
|
30
52
|
store,
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
def destroy(uid, store)
|
37
|
-
store.destroy_refresh(uid)
|
53
|
+
namespace: namespace,
|
54
|
+
payload: {},
|
55
|
+
uid: uid,
|
56
|
+
expiration: token_attrs[:expiration])
|
38
57
|
end
|
39
58
|
end
|
40
59
|
|
@@ -42,17 +61,17 @@ module JWTSessions
|
|
42
61
|
@csrf = csrf
|
43
62
|
@access_uid = access_uid
|
44
63
|
@access_expiration = access_expiration
|
45
|
-
store.update_refresh(uid, access_uid, access_expiration, csrf)
|
64
|
+
store.update_refresh(uid, access_uid, access_expiration, csrf, namespace)
|
46
65
|
end
|
47
66
|
|
48
67
|
def destroy
|
49
|
-
store.destroy_refresh(uid)
|
68
|
+
store.destroy_refresh(uid, namespace)
|
50
69
|
end
|
51
70
|
|
52
71
|
private
|
53
72
|
|
54
73
|
def persist_in_store
|
55
|
-
store.persist_refresh(uid, access_expiration, access_uid, csrf, expiration)
|
74
|
+
store.persist_refresh(uid, access_expiration, access_uid, csrf, expiration, namespace)
|
56
75
|
end
|
57
76
|
end
|
58
77
|
end
|
data/lib/jwt_sessions/session.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
module JWTSessions
|
4
4
|
class Session
|
5
5
|
attr_reader :access_token, :refresh_token, :csrf_token
|
6
|
-
attr_accessor :payload, :store, :refresh_payload
|
6
|
+
attr_accessor :payload, :store, :refresh_payload, :namespace
|
7
7
|
|
8
8
|
def initialize(options = {})
|
9
9
|
@store = options.fetch(:store, JWTSessions.token_store)
|
@@ -11,6 +11,7 @@ module JWTSessions
|
|
11
11
|
@payload = options.fetch(:payload, {})
|
12
12
|
@access_claims = options.fetch(:access_claims, {})
|
13
13
|
@refresh_claims = options.fetch(:refresh_claims, {})
|
14
|
+
@namespace = options.fetch(:namespace, nil)
|
14
15
|
end
|
15
16
|
|
16
17
|
def login
|
@@ -25,6 +26,13 @@ module JWTSessions
|
|
25
26
|
send(:"valid_#{token_type}_csrf?", token, csrf_token)
|
26
27
|
end
|
27
28
|
|
29
|
+
def session_exists?(token, token_type = :access)
|
30
|
+
send(:"#{token_type}_token_data", token)
|
31
|
+
true
|
32
|
+
rescue Errors::Unauthorized
|
33
|
+
false
|
34
|
+
end
|
35
|
+
|
28
36
|
def masked_csrf(access_token)
|
29
37
|
csrf(access_token).token
|
30
38
|
end
|
@@ -34,6 +42,35 @@ module JWTSessions
|
|
34
42
|
refresh_by_uid(&block)
|
35
43
|
end
|
36
44
|
|
45
|
+
def flush_by_token(token)
|
46
|
+
uid = token_uid(token, :refresh, @refresh_claims)
|
47
|
+
flush_by_uid(uid)
|
48
|
+
end
|
49
|
+
|
50
|
+
def flush_by_uid(uid)
|
51
|
+
token = retrieve_refresh_token(uid)
|
52
|
+
|
53
|
+
AccessToken.destroy(token.access_uid, store)
|
54
|
+
token.destroy
|
55
|
+
end
|
56
|
+
|
57
|
+
def flush_namespaced
|
58
|
+
return 0 unless namespace
|
59
|
+
tokens = RefreshToken.all(namespace, store)
|
60
|
+
tokens.each do |token|
|
61
|
+
AccessToken.destroy(token.access_uid, store)
|
62
|
+
token.destroy
|
63
|
+
end.count
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.flush_all(store = JWTSessions.token_store)
|
67
|
+
tokens = RefreshToken.all(nil, store)
|
68
|
+
tokens.each do |token|
|
69
|
+
AccessToken.destroy(token.access_uid, store)
|
70
|
+
token.destroy
|
71
|
+
end.count
|
72
|
+
end
|
73
|
+
|
37
74
|
private
|
38
75
|
|
39
76
|
def valid_access_csrf?(access_token, csrf_token)
|
@@ -52,7 +89,6 @@ module JWTSessions
|
|
52
89
|
|
53
90
|
def csrf(access_token)
|
54
91
|
token_data = access_token_data(access_token)
|
55
|
-
raise Errors::Unauthorized, 'Access token not found' if token_data.empty?
|
56
92
|
CSRFToken.new(token_data[:csrf])
|
57
93
|
end
|
58
94
|
|
@@ -63,7 +99,9 @@ module JWTSessions
|
|
63
99
|
|
64
100
|
def access_token_data(token)
|
65
101
|
uid = token_uid(token, :access, @access_claims)
|
66
|
-
store.fetch_access(uid)
|
102
|
+
data = store.fetch_access(uid)
|
103
|
+
raise Errors::Unauthorized, 'Access token not found' if data.empty?
|
104
|
+
data
|
67
105
|
end
|
68
106
|
|
69
107
|
def refresh_token_data(token)
|
@@ -82,15 +120,17 @@ module JWTSessions
|
|
82
120
|
end
|
83
121
|
|
84
122
|
def retrieve_refresh_token(uid)
|
85
|
-
@_refresh = RefreshToken.find(uid, store)
|
123
|
+
@_refresh = RefreshToken.find(uid, store, namespace)
|
86
124
|
end
|
87
125
|
|
88
126
|
def tokens_hash
|
89
|
-
{
|
127
|
+
{
|
128
|
+
csrf: csrf_token,
|
90
129
|
access: access_token,
|
91
130
|
access_expires_at: Time.at(@_access.expiration.to_i),
|
92
131
|
refresh: refresh_token,
|
93
|
-
refresh_expires_at: Time.at(@_refresh.expiration.to_i)
|
132
|
+
refresh_expires_at: Time.at(@_refresh.expiration.to_i)
|
133
|
+
}
|
94
134
|
end
|
95
135
|
|
96
136
|
def check_refresh_on_time
|
@@ -121,7 +161,8 @@ module JWTSessions
|
|
121
161
|
@_access.uid,
|
122
162
|
@_access.expiration,
|
123
163
|
store,
|
124
|
-
|
164
|
+
refresh_payload,
|
165
|
+
namespace)
|
125
166
|
@refresh_token = @_refresh.token
|
126
167
|
end
|
127
168
|
|
data/lib/jwt_sessions/version.rb
CHANGED
@@ -14,7 +14,8 @@ class TestRefreshToken < Minitest::Test
|
|
14
14
|
@access_uid,
|
15
15
|
JWTSessions.access_expiration - 5,
|
16
16
|
JWTSessions.token_store,
|
17
|
-
{}
|
17
|
+
{},
|
18
|
+
nil)
|
18
19
|
end
|
19
20
|
|
20
21
|
def test_update
|
@@ -27,15 +28,15 @@ class TestRefreshToken < Minitest::Test
|
|
27
28
|
end
|
28
29
|
|
29
30
|
def test_find
|
30
|
-
found_token = JWTSessions::RefreshToken.find(token.uid, JWTSessions.token_store)
|
31
|
+
found_token = JWTSessions::RefreshToken.find(token.uid, JWTSessions.token_store, nil)
|
31
32
|
assert_equal found_token.access_uid, token.access_uid
|
32
33
|
token.destroy
|
33
34
|
end
|
34
35
|
|
35
36
|
def test_destroy
|
36
|
-
JWTSessions::RefreshToken.destroy(token.uid, JWTSessions.token_store)
|
37
|
+
JWTSessions::RefreshToken.destroy(token.uid, JWTSessions.token_store, nil)
|
37
38
|
assert_raises JWTSessions::Errors::Unauthorized do
|
38
|
-
JWTSessions::RefreshToken.find(token.uid, JWTSessions.token_store)
|
39
|
+
JWTSessions::RefreshToken.find(token.uid, JWTSessions.token_store, nil)
|
39
40
|
end
|
40
41
|
end
|
41
42
|
end
|
@@ -14,6 +14,12 @@ class TestSession < Minitest::Test
|
|
14
14
|
@tokens = session.login
|
15
15
|
end
|
16
16
|
|
17
|
+
def teardown
|
18
|
+
redis = Redis.new
|
19
|
+
keys = redis.keys('jwt_*')
|
20
|
+
keys.each { |k| redis.del(k) }
|
21
|
+
end
|
22
|
+
|
17
23
|
def test_login
|
18
24
|
decoded_access = JWTSessions::Token.decode(tokens[:access]).first
|
19
25
|
assert_equal EXPECTED_KEYS, tokens.keys.sort
|
@@ -47,4 +53,62 @@ class TestSession < Minitest::Test
|
|
47
53
|
assert_equal EXPECTED_KEYS, refreshed_tokens.keys.sort
|
48
54
|
assert_equal payload[:test], decoded_access['test']
|
49
55
|
end
|
56
|
+
|
57
|
+
def test_flush_by_token
|
58
|
+
refresh_token = @session.instance_variable_get(:"@_refresh")
|
59
|
+
uid = refresh_token.uid
|
60
|
+
assert_equal refresh_token.token, JWTSessions::RefreshToken.find(uid, JWTSessions.token_store, nil).token
|
61
|
+
|
62
|
+
@session.flush_by_token(refresh_token.token)
|
63
|
+
|
64
|
+
assert_raises JWTSessions::Errors::Unauthorized do
|
65
|
+
JWTSessions::RefreshToken.find(uid, JWTSessions.token_store, nil)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_flush_by_uid
|
70
|
+
refresh_token = @session.instance_variable_get(:"@_refresh")
|
71
|
+
uid = refresh_token.uid
|
72
|
+
|
73
|
+
@session.flush_by_uid(uid)
|
74
|
+
|
75
|
+
assert_raises JWTSessions::Errors::Unauthorized do
|
76
|
+
JWTSessions::RefreshToken.find(uid, JWTSessions.token_store, nil)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_flush_namespaced
|
81
|
+
namespace = 'test_namespace'
|
82
|
+
@session1 = JWTSessions::Session.new(payload: payload, namespace: namespace)
|
83
|
+
@session2 = JWTSessions::Session.new(payload: payload, namespace: namespace)
|
84
|
+
@session1.login
|
85
|
+
@session2.login
|
86
|
+
|
87
|
+
flushed_count = @session1.flush_namespaced
|
88
|
+
|
89
|
+
assert_equal 2, flushed_count
|
90
|
+
assert_raises JWTSessions::Errors::Unauthorized do
|
91
|
+
refresh_token = @session1.instance_variable_get(:"@_refresh")
|
92
|
+
JWTSessions::RefreshToken.find(refresh_token.uid, JWTSessions.token_store, nil)
|
93
|
+
end
|
94
|
+
|
95
|
+
assert_raises JWTSessions::Errors::Unauthorized do
|
96
|
+
refresh_token = @session2.instance_variable_get(:"@_refresh")
|
97
|
+
JWTSessions::RefreshToken.find(refresh_token.uid, JWTSessions.token_store, nil)
|
98
|
+
end
|
99
|
+
|
100
|
+
refresh_token = @session.instance_variable_get(:"@_refresh")
|
101
|
+
flushed_count = @session.flush_namespaced
|
102
|
+
assert_equal 0, flushed_count
|
103
|
+
assert_equal refresh_token.token, JWTSessions::RefreshToken.find(refresh_token.uid, JWTSessions.token_store, nil).token
|
104
|
+
end
|
105
|
+
|
106
|
+
def test_flush_all
|
107
|
+
refresh_token = @session.instance_variable_get(:"@_refresh")
|
108
|
+
flushed_count = JWTSessions::Session.flush_all
|
109
|
+
assert_equal 1, flushed_count
|
110
|
+
assert_raises JWTSessions::Errors::Unauthorized do
|
111
|
+
JWTSessions::RefreshToken.find(refresh_token.uid, JWTSessions.token_store, nil).token
|
112
|
+
end
|
113
|
+
end
|
50
114
|
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: 1.
|
4
|
+
version: 1.2.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: 2018-04-
|
11
|
+
date: 2018-04-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: jwt
|