jwt_sessions 3.1.0 → 3.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7740c76d1bba04e91c960b59d8dd248d09adbecbea3359e09e49b9ec82cd4a98
4
- data.tar.gz: 43192bbcb08751f07216e84939a2b025239cb13b641c4563567b551626df79ae
3
+ metadata.gz: f73b9f84080047130ad1d468d79418be979c742de84603a06c9933d8a185d935
4
+ data.tar.gz: 14e06ad9f9262b12a7b05339ed93f0c45cdc9d2ee39f526ff69bef99a0851ff0
5
5
  SHA512:
6
- metadata.gz: c96b79c7ba0a8952766d3d5501a34e5877f0f8bcebb9a3210318b42e86eaf3370c15b0a534e980cbb699493633fe2b7652ec1797f8c467a1838e76fdb246530c
7
- data.tar.gz: aa1d46b6890bf7d5907ad9a190598c91855db0f90e3f6f5522d4b0390ccc92a797d8977162980a072db8fc0fb9553961683eb59896c1cc7881111fe48413f1e6
6
+ metadata.gz: e4a0a9d70804717e8a310c77be865bff624f3e824800a0df35d082be906e79120012dde275d4cbe1d9b18dd51445b570ad081488d7a6df201fefaa154ad71aff
7
+ data.tar.gz: 4964b5277b235c50715f6886965693a9fda64735d7d5b0b90d599929c06d743110a72fc27efcb7d250fc85b141d6fb441adc54bdaddc2daf41e9382a28d563be
data/CHANGELOG.md CHANGED
@@ -1,4 +1,16 @@
1
- ## 3.1.0 (February 18, 20222)
1
+ ## 3.2.0 (June 20, 2023)
2
+
3
+ Features:
4
+
5
+ - payload can be accessed without auth - it's going to be resolved into an empty hash.
6
+
7
+ ## 3.1.1 (May 6, 2023)
8
+
9
+ Bugfixes:
10
+
11
+ - fix bug with flushing empty refresh tokens (Unsupported command argument type: NilClass (TypeError))
12
+
13
+ ## 3.1.0 (February 18, 2023)
2
14
 
3
15
  Features:
4
16
 
data/README.md CHANGED
@@ -119,7 +119,7 @@ Available `JWTSessions::Session.new` options:
119
119
 
120
120
  - **payload**: a hash object with session data which will be included into an access token payload. Default is an empty hash.
121
121
  - **refresh_payload**: a hash object with session data which will be included into a refresh token payload. Default is the value of the access payload.
122
- - **access_claims**: a hash object with [JWT claims](https://github.com/jwt/ruby-jwt#support-for-reserved-claim-names) which will be validated within the access token payload. For example, `{ aud: ["admin"], verify_aud: true }` means that the token can be used only by "admin" audience. Also, the endpoint can automatically validate claims instead. See `token_claims` method.
122
+ - **access_claims**: a hash object with [JWT claims](https://github.com/jwt/ruby-jwt#support-for-reserved-claim-names) which will be validated within the access token payload. For example, `JWTSessions::Session.new(payload: { user_id: 1, aud: ['admin'], verify_aud: true })` means that the token can be used only by "admin" audience. Also, the endpoint can automatically validate claims instead. See `token_claims` method.
123
123
  - **refresh_claims**: a hash object with [JWT claims](https://github.com/jwt/ruby-jwt#support-for-reserved-claim-names) which will be validated within the refresh token payload.
124
124
  - **namespace**: a string object which helps to group sessions by a custom criteria. For example, sessions can be grouped by user ID, making it possible to logout the user from all devices. More info [Sessions Namespace](#sessions-namespace).
125
125
  - **refresh_by_access_allowed**: a boolean value. Default is false. It links access and refresh tokens (adds refresh token ID to access payload), making it possible to perform a session refresh by the last expired access token. See [Refresh with access token](#refresh-with-access-token).
@@ -131,7 +131,7 @@ Helper methods within `Authorization` mixin:
131
131
  - **authorize_access_request!**: validates access token within the request.
132
132
  - **authorize_refresh_request!**: validates refresh token within the request.
133
133
  - **found_token**: a raw token found within the request.
134
- - **payload**: a decoded token's payload.
134
+ - **payload**: a decoded token's payload. Returns an empty hash in case the token is absent in the request headers/cookies.
135
135
  - **claimless_payload**: a decoded token's payload without claims validation (can be used for checking data of an expired token).
136
136
  - **token_claims**: the method should be defined by a developer and is expected to return a hash-like object with claims to be validated within a token's payload.
137
137
 
@@ -102,16 +102,18 @@ module JWTSessions
102
102
  token
103
103
  end
104
104
 
105
- def token_from_headers(token_type)
105
+ def token_from_headers(token_type, required: true)
106
106
  raw_token = request_headers[JWTSessions.header_by(token_type)] || ""
107
107
  token = raw_token.split(" ")[-1]
108
- raise Errors::Unauthorized, "Token is not found" unless token
108
+ raise Errors::Unauthorized, "Token is not found" if !token && required
109
+
109
110
  token
110
111
  end
111
112
 
112
- def token_from_cookies(token_type)
113
+ def token_from_cookies(token_type, required: true)
113
114
  token = request_cookies[JWTSessions.cookie_by(token_type)]
114
- raise Errors::Unauthorized, "Token is not found" unless token
115
+ raise Errors::Unauthorized, "Token is not found" if !token && required
116
+
115
117
  token
116
118
  end
117
119
 
@@ -119,9 +121,21 @@ module JWTSessions
119
121
  @_raw_token
120
122
  end
121
123
 
124
+ def fetch_access_token
125
+ if respond_to?(:request_headers)
126
+ token = token_from_headers(:access, required: false)
127
+ return token if token
128
+ end
129
+
130
+ token_from_cookies(:access, required: false) if respond_to?(:request_cookies)
131
+ end
132
+
122
133
  def payload
134
+ return @_payload if defined? @_payload
135
+
123
136
  claims = respond_to?(:token_claims) ? token_claims : {}
124
- @_payload ||= Token.decode(found_token, claims).first
137
+ token = found_token || fetch_access_token
138
+ @_payload = token ? Token.decode(token, claims).first : {}
125
139
  end
126
140
 
127
141
  # retrieves tokens payload without JWT claims validation
@@ -78,7 +78,8 @@ module JWTSessions
78
78
  # to be able to properly initialize namespaced tokens extract their namespaces
79
79
  # and pass down to fetch_refresh
80
80
  token_namespace = namespace.to_s.empty? ? namespace_from_key(key) : namespace
81
- acc[uid] = fetch_refresh(uid, token_namespace)
81
+ token_attrs = fetch_refresh(uid, token_namespace)
82
+ acc[uid] = token_attrs unless token_attrs.empty?
82
83
  end
83
84
  end
84
85
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JWTSessions
4
- VERSION = "3.1.0"
4
+ VERSION = "3.2.0"
5
5
  end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "minitest/autorun"
4
+ require "jwt_sessions"
5
+
6
+ class TestAuthorization < Minitest::Test
7
+ include JWTSessions::Authorization
8
+
9
+ def setup
10
+ JWTSessions.signing_key = "abcdefghijklmnopqrstuvwxyzABCDEF"
11
+ end
12
+
13
+ def test_payload_when_token_is_nil
14
+ @_raw_token = nil
15
+
16
+ assert_equal payload, {}
17
+ end
18
+
19
+ def test_payload_when_token_is_present
20
+ @_raw_token =
21
+ JWTSessions::Token.encode({ "user_id" => 1, "secret" => "mystery" })
22
+
23
+ assert_equal payload['user_id'], 1
24
+ assert_equal payload['secret'], 'mystery'
25
+ end
26
+ end
@@ -326,6 +326,16 @@ class TestSession < Minitest::Test
326
326
  assert_equal access_token.expiration.to_s, refresh_token.access_expiration
327
327
  end
328
328
 
329
+ def test_flush_namespaced_access_tokens_after_flush_namespaced
330
+ namespace = "test_namespace"
331
+ session = JWTSessions::Session.new(payload: payload, namespace: namespace)
332
+ session.login
333
+
334
+ assert_equal 1, session.flush_namespaced
335
+ # it should not throw an error
336
+ assert_equal 0, session.flush_namespaced_access_tokens
337
+ end
338
+
329
339
  def test_flush_all
330
340
  refresh_token = @session.instance_variable_get(:"@_refresh")
331
341
  flushed_count = JWTSessions::Session.flush_all
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: 3.1.0
4
+ version: 3.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Julija Alieckaja
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-02-18 00:00:00.000000000 Z
11
+ date: 2023-06-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jwt
@@ -98,6 +98,7 @@ files:
98
98
  - test/units/jwt_sessions/store_adapters/test_memory_store_adapter.rb
99
99
  - test/units/jwt_sessions/store_adapters/test_redis_store_adapter.rb
100
100
  - test/units/jwt_sessions/test_access_token.rb
101
+ - test/units/jwt_sessions/test_authorization.rb
101
102
  - test/units/jwt_sessions/test_csrf_token.rb
102
103
  - test/units/jwt_sessions/test_refresh_token.rb
103
104
  - test/units/jwt_sessions/test_session.rb
@@ -127,7 +128,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
127
128
  - !ruby/object:Gem::Version
128
129
  version: '0'
129
130
  requirements: []
130
- rubygems_version: 3.4.6
131
+ rubygems_version: 3.4.12
131
132
  signing_key:
132
133
  specification_version: 4
133
134
  summary: JWT Sessions
@@ -137,6 +138,7 @@ test_files:
137
138
  - test/units/jwt_sessions/store_adapters/test_memory_store_adapter.rb
138
139
  - test/units/jwt_sessions/store_adapters/test_redis_store_adapter.rb
139
140
  - test/units/jwt_sessions/test_access_token.rb
141
+ - test/units/jwt_sessions/test_authorization.rb
140
142
  - test/units/jwt_sessions/test_csrf_token.rb
141
143
  - test/units/jwt_sessions/test_refresh_token.rb
142
144
  - test/units/jwt_sessions/test_session.rb