devise_token_auth 1.2.6 → 1.3.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/app/models/devise_token_auth/concerns/user.rb +7 -2
- data/lib/devise_token_auth/rails/routes.rb +14 -1
- data/lib/devise_token_auth/version.rb +1 -1
- data/test/controllers/devise_token_auth/confirmations_controller_test.rb +4 -4
- data/test/dummy/config/environments/test.rb +4 -1
- data/test/lib/devise_token_auth/rails/custom_routes_test.rb +5 -4
- data/test/models/user_test.rb +27 -0
- data/test/test_helper.rb +8 -1
- metadata +16 -10
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0d50f68558fe641e4412661bdd4dfc15ce37b047300353cd4736c7e314c9fed9
|
|
4
|
+
data.tar.gz: e73de38339a0d663e78bf8e0abbb416b46078440b922a11cf9e49ff7ec2e6bc5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7b2f6973ffc5ba8b3763f36eeda7581fd698cfe1c6a556e714ec32c94b7f21e9f2da9b5b871c59419c1a3f26249dc1d560cb28b03b228fa9c4e5a81a294c12c4
|
|
7
|
+
data.tar.gz: 6d14031a8a4269655bd4f0d9c03f39fc360112e331f1e1e14f583127d58effbe32d23d1a5852cdf5bb5b07fce6a8ae05f6391863ccbff4c8cf9020e09773496d
|
|
@@ -261,8 +261,13 @@ module DeviseTokenAuth::Concerns::User
|
|
|
261
261
|
return if tokens.blank? || !max_client_tokens_exceeded?
|
|
262
262
|
|
|
263
263
|
# First, remove any tokens with expiry greater than current max allowed lifespan
|
|
264
|
-
# this handles the case where token lifespan was reduced and old tokens exist
|
|
265
|
-
|
|
264
|
+
# this handles the case where token lifespan was reduced and old tokens exist.
|
|
265
|
+
# The threshold MUST be computed the same way TokenFactory.expiry writes
|
|
266
|
+
# expiries — calendar advance (Time.zone.now + lifespan) — otherwise a
|
|
267
|
+
# calendar Duration (e.g. 2.months) and its average-seconds form
|
|
268
|
+
# (token_lifespan.to_i) disagree by hours, and the freshly minted token
|
|
269
|
+
# gets purged out from under the response.
|
|
270
|
+
max_lifespan_expiry = (Time.zone.now + DeviseTokenAuth.token_lifespan).to_i
|
|
266
271
|
tokens_to_keep = tokens.select do |_cid, v|
|
|
267
272
|
expiry = (v[:expiry] || v['expiry']).to_i
|
|
268
273
|
expiry <= max_lifespan_expiry
|
|
@@ -76,7 +76,20 @@ module ActionDispatch::Routing
|
|
|
76
76
|
match "#{full_path}/:provider", to: redirect(status: 307) { |params, request|
|
|
77
77
|
# get the current querystring
|
|
78
78
|
# TODO: deprecate in favor of using params
|
|
79
|
-
|
|
79
|
+
# `CGI.parse` is unavailable as of the cgi gem shipped with Ruby 3.5
|
|
80
|
+
# (pulled in by Rails 8.1). `Rack::Utils.parse_query` returns a bare
|
|
81
|
+
# value for single occurrences, so normalize to arrays to keep the
|
|
82
|
+
# shape `CGI.parse` returned.
|
|
83
|
+
# As of Rails 7.1 the request body may already have been read when
|
|
84
|
+
# this runs, in which case `read` returns "" and every param is
|
|
85
|
+
# silently dropped. Rewind first so POSTed params survive.
|
|
86
|
+
query_string = if request.env['QUERY_STRING'].empty?
|
|
87
|
+
request.body.rewind if request.body.respond_to?(:rewind)
|
|
88
|
+
request.body.read
|
|
89
|
+
else
|
|
90
|
+
request.env['QUERY_STRING']
|
|
91
|
+
end
|
|
92
|
+
qs = Rack::Utils.parse_query(query_string).transform_values { |v| Array(v) }
|
|
80
93
|
|
|
81
94
|
# append name of current resource
|
|
82
95
|
qs['resource_class'] = [resource]
|
|
@@ -62,8 +62,8 @@ class DeviseTokenAuth::ConfirmationsControllerTest < ActionController::TestCase
|
|
|
62
62
|
end
|
|
63
63
|
|
|
64
64
|
test 'redirect url includes token params' do
|
|
65
|
-
assert @token_params.all? { |param| response.
|
|
66
|
-
assert response.
|
|
65
|
+
assert @token_params.all? { |param| response.location.include?(param) }
|
|
66
|
+
assert response.location.include?('account_confirmation_success')
|
|
67
67
|
end
|
|
68
68
|
end
|
|
69
69
|
|
|
@@ -86,8 +86,8 @@ class DeviseTokenAuth::ConfirmationsControllerTest < ActionController::TestCase
|
|
|
86
86
|
end
|
|
87
87
|
|
|
88
88
|
test 'redirect url does not include token params' do
|
|
89
|
-
refute @token_params.any? { |param| response.
|
|
90
|
-
assert response.
|
|
89
|
+
refute @token_params.any? { |param| response.location.include?(param) }
|
|
90
|
+
assert response.location.include?('account_confirmation_success')
|
|
91
91
|
end
|
|
92
92
|
end
|
|
93
93
|
|
|
@@ -32,7 +32,10 @@ Rails.application.configure do
|
|
|
32
32
|
config.action_controller.perform_caching = false
|
|
33
33
|
|
|
34
34
|
# Raise exceptions instead of rendering exception templates.
|
|
35
|
-
|
|
35
|
+
# Rails 7.1 turned this into an enum; `false` is no longer recognised and
|
|
36
|
+
# falls through to the "show everything" default. Note the version check must
|
|
37
|
+
# not be `MAJOR >= 7 && MINOR > 0`, which is false on Rails 8.0.
|
|
38
|
+
if Rails.gem_version >= Gem::Version.new('7.1')
|
|
36
39
|
config.action_dispatch.show_exceptions = :none
|
|
37
40
|
else
|
|
38
41
|
config.action_dispatch.show_exceptions = false
|
|
@@ -7,11 +7,12 @@ class DeviseTokenAuth::CustomRoutesTest < ActiveSupport::TestCase
|
|
|
7
7
|
Rails.application.reload_routes!
|
|
8
8
|
end
|
|
9
9
|
test 'custom controllers' do
|
|
10
|
-
class ActionDispatch::Routing::Mapper
|
|
11
|
-
include Mocha::ParameterMatchers
|
|
12
|
-
end
|
|
13
10
|
Rails.application.routes.draw do
|
|
14
|
-
self
|
|
11
|
+
mapper = self
|
|
12
|
+
mapper.singleton_class.include(Mocha::API)
|
|
13
|
+
mapper.singleton_class.include(Mocha::ParameterMatchers)
|
|
14
|
+
|
|
15
|
+
mapper.expects(:devise_for).with(
|
|
15
16
|
:users,
|
|
16
17
|
has_entries(
|
|
17
18
|
controllers: has_entries(
|
data/test/models/user_test.rb
CHANGED
|
@@ -220,5 +220,32 @@ class UserTest < ActiveSupport::TestCase
|
|
|
220
220
|
# We should have exactly 2 tokens: the new one and client_3
|
|
221
221
|
assert_equal 2, @resource.tokens.length
|
|
222
222
|
end
|
|
223
|
+
|
|
224
|
+
# Regression: with a calendar ActiveSupport::Duration lifespan, the token
|
|
225
|
+
# expiry is advanced by calendar (Time.zone.now + 2.months) while the old
|
|
226
|
+
# eager purge compared against an average-seconds threshold
|
|
227
|
+
# (token_lifespan.to_i). The freshly minted token's expiry sat just past
|
|
228
|
+
# that threshold and was silently dropped, leaving a 200 response whose
|
|
229
|
+
# advertised access-token no longer existed in user.tokens.
|
|
230
|
+
test 'keeps the freshly created token at the device cap with a calendar lifespan' do
|
|
231
|
+
DeviseTokenAuth.max_number_of_devices = 2
|
|
232
|
+
DeviseTokenAuth.token_lifespan = 2.months
|
|
233
|
+
|
|
234
|
+
# Fill the cap with tokens created a few hours ago (calendar expiry).
|
|
235
|
+
old_time = 4.hours.ago
|
|
236
|
+
@resource.tokens = {}
|
|
237
|
+
%w[client_1 client_2].each do |client|
|
|
238
|
+
@resource.tokens[client] = {
|
|
239
|
+
'token' => 'x',
|
|
240
|
+
'expiry' => (old_time + DeviseTokenAuth.token_lifespan).to_i
|
|
241
|
+
}
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
tok = @resource.create_token
|
|
245
|
+
|
|
246
|
+
assert @resource.tokens.key?(tok.client),
|
|
247
|
+
'Freshly created token must survive clean_old_tokens'
|
|
248
|
+
assert_equal DeviseTokenAuth.max_number_of_devices, @resource.tokens.length
|
|
249
|
+
end
|
|
223
250
|
end
|
|
224
251
|
end
|
data/test/test_helper.rb
CHANGED
|
@@ -38,7 +38,14 @@ end
|
|
|
38
38
|
class ActiveSupport::TestCase
|
|
39
39
|
include FactoryBot::Syntax::Methods
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
if DEVISE_TOKEN_AUTH_ORM == :active_record
|
|
42
|
+
# `check_pending!` was deprecated in Rails 7.1 and removed in Rails 8.0
|
|
43
|
+
if ActiveRecord::Migration.respond_to?(:check_all_pending!)
|
|
44
|
+
ActiveRecord::Migration.check_all_pending!
|
|
45
|
+
else
|
|
46
|
+
ActiveRecord::Migration.check_pending!
|
|
47
|
+
end
|
|
48
|
+
end
|
|
42
49
|
|
|
43
50
|
strategies = { active_record: :transaction,
|
|
44
51
|
mongoid: :deletion }
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: devise_token_auth
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Lynn Hurley
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-07-31 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|
|
@@ -19,7 +19,7 @@ dependencies:
|
|
|
19
19
|
version: 4.2.0
|
|
20
20
|
- - "<"
|
|
21
21
|
- !ruby/object:Gem::Version
|
|
22
|
-
version: '8.
|
|
22
|
+
version: '8.3'
|
|
23
23
|
type: :runtime
|
|
24
24
|
prerelease: false
|
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -29,7 +29,7 @@ dependencies:
|
|
|
29
29
|
version: 4.2.0
|
|
30
30
|
- - "<"
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
|
-
version: '8.
|
|
32
|
+
version: '8.3'
|
|
33
33
|
- !ruby/object:Gem::Dependency
|
|
34
34
|
name: devise
|
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -39,7 +39,7 @@ dependencies:
|
|
|
39
39
|
version: 3.5.2
|
|
40
40
|
- - "<"
|
|
41
41
|
- !ruby/object:Gem::Version
|
|
42
|
-
version: '
|
|
42
|
+
version: '6'
|
|
43
43
|
type: :runtime
|
|
44
44
|
prerelease: false
|
|
45
45
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -49,7 +49,7 @@ dependencies:
|
|
|
49
49
|
version: 3.5.2
|
|
50
50
|
- - "<"
|
|
51
51
|
- !ruby/object:Gem::Version
|
|
52
|
-
version: '
|
|
52
|
+
version: '6'
|
|
53
53
|
- !ruby/object:Gem::Dependency
|
|
54
54
|
name: bcrypt
|
|
55
55
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -82,16 +82,22 @@ dependencies:
|
|
|
82
82
|
name: sqlite3
|
|
83
83
|
requirement: !ruby/object:Gem::Requirement
|
|
84
84
|
requirements:
|
|
85
|
-
- - "
|
|
85
|
+
- - ">="
|
|
86
86
|
- !ruby/object:Gem::Version
|
|
87
87
|
version: '1.4'
|
|
88
|
+
- - "<"
|
|
89
|
+
- !ruby/object:Gem::Version
|
|
90
|
+
version: '3.0'
|
|
88
91
|
type: :development
|
|
89
92
|
prerelease: false
|
|
90
93
|
version_requirements: !ruby/object:Gem::Requirement
|
|
91
94
|
requirements:
|
|
92
|
-
- - "
|
|
95
|
+
- - ">="
|
|
93
96
|
- !ruby/object:Gem::Version
|
|
94
97
|
version: '1.4'
|
|
98
|
+
- - "<"
|
|
99
|
+
- !ruby/object:Gem::Version
|
|
100
|
+
version: '3.0'
|
|
95
101
|
- !ruby/object:Gem::Dependency
|
|
96
102
|
name: pg
|
|
97
103
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -129,7 +135,7 @@ dependencies:
|
|
|
129
135
|
version: '4'
|
|
130
136
|
- - "<"
|
|
131
137
|
- !ruby/object:Gem::Version
|
|
132
|
-
version: '
|
|
138
|
+
version: '10'
|
|
133
139
|
type: :development
|
|
134
140
|
prerelease: false
|
|
135
141
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -139,7 +145,7 @@ dependencies:
|
|
|
139
145
|
version: '4'
|
|
140
146
|
- - "<"
|
|
141
147
|
- !ruby/object:Gem::Version
|
|
142
|
-
version: '
|
|
148
|
+
version: '10'
|
|
143
149
|
- !ruby/object:Gem::Dependency
|
|
144
150
|
name: mongoid-locker
|
|
145
151
|
requirement: !ruby/object:Gem::Requirement
|