rodauth 2.6.0 → 2.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +12 -0
- data/doc/jwt_refresh.rdoc +2 -0
- data/doc/recovery_codes.rdoc +2 -1
- data/doc/release_notes/2.7.0.txt +33 -0
- data/doc/remember.rdoc +1 -1
- data/lib/rodauth.rb +5 -1
- data/lib/rodauth/features/base.rb +1 -1
- data/lib/rodauth/features/jwt.rb +6 -2
- data/lib/rodauth/features/jwt_refresh.rb +19 -0
- data/lib/rodauth/features/otp.rb +0 -2
- data/lib/rodauth/features/recovery_codes.rb +22 -1
- data/lib/rodauth/features/remember.rb +4 -1
- data/lib/rodauth/features/verify_account.rb +0 -1
- data/lib/rodauth/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ce2af7161a7aaba17ebb25beda65f8598306b2d040986db0be215b89fb683149
|
4
|
+
data.tar.gz: cf69c788c9401485610599f0b6996f340ab315fcbceb359bccf01a78dceaadc8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8b2d72d0f9338a359653e90829618f2579afc30095bb0dd1bd0c627730c91117158ef5ebbca9a4a32bb78bd312ebbac308a68efb761cf93c4dfc707d7bdcea24
|
7
|
+
data.tar.gz: d5eb1fc01df26b8305edec707642d3192e7a5dc3507416d0e60aaf6ffd1b079ac4ddced72a85d61c4623c70df2d784307cfba60b8759741b2991f591c623b0b0
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
=== 2.7.0 (2020-12-22)
|
2
|
+
|
3
|
+
* Avoid method redefinition warnings in verbose warning mode (jeremyevans)
|
4
|
+
|
5
|
+
* Return expired access token error message in the JWT refresh feature when using an expired token when it isn't allowed (AlexyMatskevich) (#133)
|
6
|
+
|
7
|
+
* Allow Rodauth features to be preloaded, instead of always trying to require them (janko) (#136)
|
8
|
+
|
9
|
+
* Use a default remember cookie path of '/', though this may cause problem with multiple Rodauth configurations on the same domain (janko) (#134)
|
10
|
+
|
11
|
+
* Add auto_remove_recovery_codes? to the recovery_codes feature, for automatically removing the codes when disabling multifactor authentication (SilasSpet, jeremyevans) (#135)
|
12
|
+
|
1
13
|
=== 2.6.0 (2020-11-20)
|
2
14
|
|
3
15
|
* Avoid loading features multiple times (janko) (#131)
|
data/doc/jwt_refresh.rdoc
CHANGED
@@ -30,6 +30,8 @@ This feature depends on the jwt feature.
|
|
30
30
|
== Auth Value Methods
|
31
31
|
|
32
32
|
allow_refresh_with_expired_jwt_access_token? :: Whether refreshing should be allowed with an expired access token. Default is +false+. You must set an +hmac_secret+ if setting this value to +true+.
|
33
|
+
expired_jwt_access_token_status :: The HTTP status code to use when a access token (JWT) is expired is submitted in the Authorization header. Default is 400 for backwards compatibility, and it is recommended to set it to 401.
|
34
|
+
expired_jwt_access_token_message :: The error message to use when a access token (JWT) is expired is submitted in the Authorization header.
|
33
35
|
jwt_access_token_key :: Name of the key in the response json holding the access token. Default is +access_token+.
|
34
36
|
jwt_access_token_not_before_period :: How many seconds before the current time will the jwt be considered valid (to account for inaccurate clocks). Default is 5.
|
35
37
|
jwt_access_token_period :: Validity of an access token in seconds, default is 1800 (30 minutes).
|
data/doc/recovery_codes.rdoc
CHANGED
@@ -17,7 +17,8 @@ add_recovery_codes_error_flash :: The flash error to show when adding recovery c
|
|
17
17
|
add_recovery_codes_heading :: Text to use for heading above the form to add recovery codes.
|
18
18
|
add_recovery_codes_page_title :: The page title to use on the add recovery codes form.
|
19
19
|
add_recovery_codes_param :: The parameter name to use for adding recovery codes.
|
20
|
-
auto_add_recovery_codes? :: Whether to automatically add recovery codes (or any missing recovery codes) when
|
20
|
+
auto_add_recovery_codes? :: Whether to automatically add recovery codes (or any missing recovery codes) when enabling otp, webauthn, or sms authentication (false by default).
|
21
|
+
auto_remove_recovery_codes? :: Whether to automatically remove recovery codes when disabling otp, webauthn, or sms authentication and not having one of the other two authentication methods enabled (false by default).
|
21
22
|
invalid_recovery_code_error_flash :: The flash error to show when an invalid recovery code is used.
|
22
23
|
invalid_recovery_code_message :: The error message to show when an invalid recovery code is used.
|
23
24
|
recovery_auth_additional_form_tags :: HTML fragment containing additional form tags when authenticating via a recovery code.
|
@@ -0,0 +1,33 @@
|
|
1
|
+
= New Features
|
2
|
+
|
3
|
+
* An auto_remove_recovery_codes? configuration method has been added
|
4
|
+
to the recovery_codes feature. This will automatically remove
|
5
|
+
recovery codes when the last multifactor authentication type other
|
6
|
+
than the recovery codes has been removed.
|
7
|
+
|
8
|
+
* The jwt_access_expired_status and expired_jwt_access_token_message
|
9
|
+
configuration methods have been added to the jwt_refresh feature,
|
10
|
+
for supporting custom statuses and messages for expired tokens.
|
11
|
+
|
12
|
+
= Other Improvements
|
13
|
+
|
14
|
+
* Rodauth will no longer attempt to require a feature that has
|
15
|
+
already been required. Related to this is you can now use a
|
16
|
+
a custom Rodauth feature without a rodauth/features/*.rb file
|
17
|
+
in the Ruby library path, as long as you load the feature
|
18
|
+
manually.
|
19
|
+
|
20
|
+
* Rodauth now avoids method redefinition warnings in verbose
|
21
|
+
warning mode. As Ruby 3 is dropping uninitialized instance
|
22
|
+
variable warnings, Rodauth will be verbose warning free in
|
23
|
+
Ruby 3.
|
24
|
+
|
25
|
+
= Backwards Compatibility
|
26
|
+
|
27
|
+
* The default remember cookie path is now set to '/'. This fixes
|
28
|
+
usage in the case where rodauth is loaded under a subpath of the
|
29
|
+
application (which is not the default behavior). Unfortunately,
|
30
|
+
this change can negatively affect cases where multiple rodauth
|
31
|
+
configurations are used in separate paths on the same domain.
|
32
|
+
In these cases, you should now use remember_cookie_options and
|
33
|
+
include a :path option.
|
data/doc/remember.rdoc
CHANGED
@@ -35,7 +35,7 @@ raw_remember_token_deadline :: A deadline before which to allow a raw remember t
|
|
35
35
|
remember_additional_form_tags :: HTML fragment containing additional form tags to use on the change remember setting form.
|
36
36
|
remember_button :: The text to use for the change remember settings button.
|
37
37
|
remember_cookie_key :: The cookie name to use for the remember token.
|
38
|
-
remember_cookie_options :: Any options to set for the remember cookie.
|
38
|
+
remember_cookie_options :: Any options to set for the remember cookie. By default, the `:path` cookie option is set to `/`.
|
39
39
|
remember_deadline_column :: The column name in the +remember_table+ storing the deadline after which the token will be ignored.
|
40
40
|
remember_deadline_interval :: The amount of time for which to remember accounts, 14 days by default. Only used if +set_deadline_values?+ is true.
|
41
41
|
remember_disable_label :: The label for disabling remembering.
|
data/lib/rodauth.rb
CHANGED
@@ -66,6 +66,7 @@ module Rodauth
|
|
66
66
|
define_method(meth) do |&block|
|
67
67
|
@auth.send(:define_method, meth, &block)
|
68
68
|
@auth.send(:private, meth) if priv
|
69
|
+
@auth.send(:alias_method, meth, meth)
|
69
70
|
end
|
70
71
|
end
|
71
72
|
|
@@ -74,6 +75,7 @@ module Rodauth
|
|
74
75
|
define_method(meth) do |&block|
|
75
76
|
@auth.send(:define_method, umeth, &block)
|
76
77
|
@auth.send(:private, umeth)
|
78
|
+
@auth.send(:alias_method, umeth, umeth)
|
77
79
|
end
|
78
80
|
end
|
79
81
|
|
@@ -82,6 +84,7 @@ module Rodauth
|
|
82
84
|
block ||= proc{v}
|
83
85
|
@auth.send(:define_method, meth, &block)
|
84
86
|
@auth.send(:private, meth) if priv
|
87
|
+
@auth.send(:alias_method, meth, meth)
|
85
88
|
end
|
86
89
|
end
|
87
90
|
end
|
@@ -240,6 +243,7 @@ module Rodauth
|
|
240
243
|
instance_variable_set(iv, send(umeth))
|
241
244
|
end
|
242
245
|
end
|
246
|
+
alias_method(meth, meth)
|
243
247
|
auth_private_methods(meth)
|
244
248
|
end
|
245
249
|
|
@@ -300,7 +304,7 @@ module Rodauth
|
|
300
304
|
private
|
301
305
|
|
302
306
|
def load_feature(feature_name)
|
303
|
-
require "rodauth/features/#{feature_name}"
|
307
|
+
require "rodauth/features/#{feature_name}" unless FEATURES[feature_name]
|
304
308
|
feature = FEATURES[feature_name]
|
305
309
|
enable(*feature.dependencies)
|
306
310
|
extend feature.configuration
|
@@ -102,7 +102,6 @@ module Rodauth
|
|
102
102
|
:set_redirect_error_flash,
|
103
103
|
:set_title,
|
104
104
|
:translate,
|
105
|
-
:unverified_account_message,
|
106
105
|
:update_session
|
107
106
|
)
|
108
107
|
|
@@ -261,6 +260,7 @@ module Rodauth
|
|
261
260
|
@password_field_autocomplete_value || 'current-password'
|
262
261
|
end
|
263
262
|
|
263
|
+
alias account_password_hash_column account_password_hash_column
|
264
264
|
# If the account_password_hash_column is set, the password hash is verified in
|
265
265
|
# ruby, it will not use a database function to do so, it will check the password
|
266
266
|
# hash using bcrypt.
|
data/lib/rodauth/features/jwt.rb
CHANGED
@@ -47,7 +47,7 @@ module Rodauth
|
|
47
47
|
s = {}
|
48
48
|
if jwt_token
|
49
49
|
unless session_data = jwt_payload
|
50
|
-
json_response[json_response_error_key]
|
50
|
+
json_response[json_response_error_key] ||= invalid_jwt_format_error_message
|
51
51
|
response.status ||= json_response_error_status
|
52
52
|
response['Content-Type'] ||= json_response_content_type
|
53
53
|
response.write(_json_response_body(json_response))
|
@@ -236,7 +236,11 @@ module Rodauth
|
|
236
236
|
def jwt_payload
|
237
237
|
return @jwt_payload if defined?(@jwt_payload)
|
238
238
|
@jwt_payload = JWT.decode(jwt_token, jwt_secret, true, _jwt_decode_opts.merge(:algorithm=>jwt_algorithm))[0]
|
239
|
-
rescue JWT::DecodeError
|
239
|
+
rescue JWT::DecodeError => e
|
240
|
+
rescue_jwt_payload(e)
|
241
|
+
end
|
242
|
+
|
243
|
+
def rescue_jwt_payload(_)
|
240
244
|
@jwt_payload = false
|
241
245
|
end
|
242
246
|
|
@@ -24,6 +24,8 @@ module Rodauth
|
|
24
24
|
auth_value_method :jwt_refresh_token_table, :account_jwt_refresh_keys
|
25
25
|
translatable_method :jwt_refresh_without_access_token_message, 'no JWT access token provided during refresh'
|
26
26
|
auth_value_method :jwt_refresh_without_access_token_status, 401
|
27
|
+
translatable_method :expired_jwt_access_token_message, "expired JWT access token"
|
28
|
+
auth_value_method :expired_jwt_access_token_status, 400
|
27
29
|
|
28
30
|
auth_private_methods(
|
29
31
|
:account_from_refresh_token
|
@@ -92,6 +94,23 @@ module Rodauth
|
|
92
94
|
|
93
95
|
private
|
94
96
|
|
97
|
+
def rescue_jwt_payload(e)
|
98
|
+
if e.instance_of?(JWT::ExpiredSignature)
|
99
|
+
begin
|
100
|
+
# Some versions of jwt will raise JWT::ExpiredSignature even when the
|
101
|
+
# JWT is invalid for other reasons. Make sure the expiration is the
|
102
|
+
# only reason the JWT isn't valid before treating this as an expired token.
|
103
|
+
JWT.decode(jwt_token, jwt_secret, true, Hash[jwt_decode_opts].merge!(:verify_expiration=>false, :algorithm=>jwt_algorithm))[0]
|
104
|
+
rescue => e
|
105
|
+
else
|
106
|
+
json_response[json_response_error_key] = expired_jwt_access_token_message
|
107
|
+
response.status ||= expired_jwt_access_token_status
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
super
|
112
|
+
end
|
113
|
+
|
95
114
|
def _account_from_refresh_token(token)
|
96
115
|
id, token_id, key = _account_refresh_token_split(token)
|
97
116
|
|
data/lib/rodauth/features/otp.rb
CHANGED
@@ -34,6 +34,7 @@ module Rodauth
|
|
34
34
|
auth_value_method :add_recovery_codes_param, 'add'
|
35
35
|
translatable_method :add_recovery_codes_heading, '<h2>Add Additional Recovery Codes</h2>'
|
36
36
|
auth_value_method :auto_add_recovery_codes?, false
|
37
|
+
auth_value_method :auto_remove_recovery_codes?, false
|
37
38
|
translatable_method :invalid_recovery_code_message, "Invalid recovery code"
|
38
39
|
auth_value_method :recovery_codes_limit, 16
|
39
40
|
auth_value_method :recovery_codes_column, :code
|
@@ -56,7 +57,6 @@ module Rodauth
|
|
56
57
|
:can_add_recovery_codes?,
|
57
58
|
:new_recovery_code,
|
58
59
|
:recovery_code_match?,
|
59
|
-
:recovery_codes
|
60
60
|
)
|
61
61
|
|
62
62
|
route(:recovery_auth) do |r|
|
@@ -213,6 +213,21 @@ module Rodauth
|
|
213
213
|
super
|
214
214
|
end
|
215
215
|
|
216
|
+
def after_otp_disable
|
217
|
+
super if defined?(super)
|
218
|
+
auto_remove_recovery_codes
|
219
|
+
end
|
220
|
+
|
221
|
+
def after_sms_disable
|
222
|
+
super if defined?(super)
|
223
|
+
auto_remove_recovery_codes
|
224
|
+
end
|
225
|
+
|
226
|
+
def after_webauthn_remove
|
227
|
+
super if defined?(super)
|
228
|
+
auto_remove_recovery_codes
|
229
|
+
end
|
230
|
+
|
216
231
|
def new_recovery_code
|
217
232
|
random_key
|
218
233
|
end
|
@@ -227,6 +242,12 @@ module Rodauth
|
|
227
242
|
end
|
228
243
|
end
|
229
244
|
|
245
|
+
def auto_remove_recovery_codes
|
246
|
+
if auto_remove_recovery_codes? && (%w'totp webauthn sms_code' & possible_authentication_methods).empty?
|
247
|
+
recovery_codes_remove
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
230
251
|
def _recovery_codes
|
231
252
|
recovery_codes_ds.select_map(recovery_codes_column)
|
232
253
|
end
|
@@ -132,11 +132,14 @@ module Rodauth
|
|
132
132
|
opts = Hash[remember_cookie_options]
|
133
133
|
opts[:value] = "#{account_id}_#{convert_token_key(remember_key_value)}"
|
134
134
|
opts[:expires] = convert_timestamp(active_remember_key_ds.get(remember_deadline_column))
|
135
|
+
opts[:path] = "/" unless opts.key?(:path)
|
135
136
|
::Rack::Utils.set_cookie_header!(response.headers, remember_cookie_key, opts)
|
136
137
|
end
|
137
138
|
|
138
139
|
def forget_login
|
139
|
-
|
140
|
+
opts = Hash[remember_cookie_options]
|
141
|
+
opts[:path] = "/" unless opts.key?(:path)
|
142
|
+
::Rack::Utils.delete_cookie_header!(response.headers, remember_cookie_key, opts)
|
140
143
|
end
|
141
144
|
|
142
145
|
def get_remember_key
|
data/lib/rodauth/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rodauth
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeremy Evans
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-12-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sequel
|
@@ -309,6 +309,7 @@ extra_rdoc_files:
|
|
309
309
|
- doc/release_notes/2.4.0.txt
|
310
310
|
- doc/release_notes/2.5.0.txt
|
311
311
|
- doc/release_notes/2.6.0.txt
|
312
|
+
- doc/release_notes/2.7.0.txt
|
312
313
|
files:
|
313
314
|
- CHANGELOG
|
314
315
|
- MIT-LICENSE
|
@@ -394,6 +395,7 @@ files:
|
|
394
395
|
- doc/release_notes/2.4.0.txt
|
395
396
|
- doc/release_notes/2.5.0.txt
|
396
397
|
- doc/release_notes/2.6.0.txt
|
398
|
+
- doc/release_notes/2.7.0.txt
|
397
399
|
- doc/remember.rdoc
|
398
400
|
- doc/reset_password.rdoc
|
399
401
|
- doc/session_expiration.rdoc
|