rodauth 2.27.0 → 2.29.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/CHANGELOG +22 -0
- data/README.rdoc +6 -1
- data/doc/active_sessions.rdoc +1 -0
- data/doc/guides/password_requirements.rdoc +15 -2
- data/doc/json.rdoc +8 -0
- data/doc/release_notes/2.28.0.txt +16 -0
- data/doc/release_notes/2.29.0.txt +27 -0
- data/doc/remember.rdoc +3 -1
- data/doc/webauthn.rdoc +2 -1
- data/lib/rodauth/features/active_sessions.rb +7 -1
- data/lib/rodauth/features/argon2.rb +12 -12
- data/lib/rodauth/features/base.rb +5 -1
- data/lib/rodauth/features/login_password_requirements_base.rb +4 -4
- data/lib/rodauth/features/password_pepper.rb +2 -2
- data/lib/rodauth/features/remember.rb +61 -32
- data/lib/rodauth/features/reset_password.rb +1 -1
- data/lib/rodauth/features/verify_account_grace_period.rb +5 -1
- data/lib/rodauth/features/webauthn.rb +12 -7
- data/lib/rodauth/version.rb +1 -1
- data/lib/rodauth.rb +4 -2
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c1714e5a3a0a5bbae56f2905dd528611de3b958d505d312071148b56fdfb3d6f
|
4
|
+
data.tar.gz: 8bb57c30ced05b0825a5d1fd74efe9f6523202f1b151b591c0bbdf10ad9f12af
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4dfc0639aaebdeacf6961122265720c992fb0d1af5d7864f5984fa902eef0ae49aea30db63681b1bdd1c598458f8ce5b035fdb3192249f3983afba15442bf990
|
7
|
+
data.tar.gz: d044a6934b3d06bee1e260de68ca5a88016b6f611da1e59dabf1e16afc63e7a82c6d16d196ed57a23558c14a0d6aecba4030ece7830a4f0a6211260b1e619b50
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,25 @@
|
|
1
|
+
=== 2.29.0 (2023-03-22)
|
2
|
+
|
3
|
+
* Support :render=>false plugin options (davekaro) (#319)
|
4
|
+
|
5
|
+
* Add remove_active_session method for removing the active session for a given session id (janko) (#317)
|
6
|
+
|
7
|
+
* Remove current active session when adding new active session (janko) (#314)
|
8
|
+
|
9
|
+
* Extend the remember cookie deadline once an hour by default while logged in (janko, jeremyevans) (#313)
|
10
|
+
|
11
|
+
* Add account! method for returning associated account or loading account based on the session value (janko) (#309)
|
12
|
+
|
13
|
+
=== 2.28.0 (2023-02-22)
|
14
|
+
|
15
|
+
* Skip rendering reset password request form on invalid internal request logins (janko) (#303)
|
16
|
+
|
17
|
+
* Make logged_in? return false if using verify_account_grace_period feature and grace_period has expired (janko) (#300)
|
18
|
+
|
19
|
+
* Make password_hash method public (janko) (#299)
|
20
|
+
|
21
|
+
* Add webauthn_key_insert_hash auth method to webauthn feature to control inserts into webauthn keys table (janko) (#298)
|
22
|
+
|
1
23
|
=== 2.27.0 (2023-01-24)
|
2
24
|
|
3
25
|
* Rename webauth_credentials_for_get to webauthn_credentials_for_get for consistency (janko) (#295)
|
data/README.rdoc
CHANGED
@@ -79,7 +79,8 @@ There are some dependencies that Rodauth uses depending on the
|
|
79
79
|
features in use. These are development dependencies instead of
|
80
80
|
runtime dependencies in the gem as it is possible to run without them:
|
81
81
|
|
82
|
-
tilt :: Used by all features unless in JSON API only mode
|
82
|
+
tilt :: Used by all features unless in JSON API only mode or using
|
83
|
+
:render=>false plugin option.
|
83
84
|
rack_csrf :: Used for CSRF support if the <tt>csrf: :rack_csrf</tt> plugin
|
84
85
|
option is given (the default is to use Roda's route_csrf
|
85
86
|
plugin, as that allows for more secure request-specific
|
@@ -852,6 +853,8 @@ which configures which dependent plugins should be loaded. Options:
|
|
852
853
|
:csrf :: Set to +false+ to not load a csrf plugin. Set to +:rack_csrf+
|
853
854
|
to use the csrf plugin instead of the route_csrf plugin.
|
854
855
|
:flash :: Set to +false+ to not load the flash plugin
|
856
|
+
:render :: Set to +false+ to not load the render plugin. This is useful
|
857
|
+
to avoid the dependency on tilt when using alternative view libaries.
|
855
858
|
:json :: Set to +true+ to load the json and json_parser plugins. Set
|
856
859
|
to +:only+ to only load those plugins and not any other plugins.
|
857
860
|
Note that if you are enabling features that send email, you
|
@@ -1000,6 +1003,8 @@ logged_in? :: Whether the session has been logged in.
|
|
1000
1003
|
authenticated? :: Similar to +logged_in?+, but if the account has setup two
|
1001
1004
|
factor authentication, whether the session has authenticated
|
1002
1005
|
via two factors.
|
1006
|
+
account! :: Returns the current account record if it has already been loaded,
|
1007
|
+
otherwise retrieves the account from session if logged in.
|
1003
1008
|
authenticated_by :: An array of strings for successful authentication methods for
|
1004
1009
|
the current session (e.g. password/remember/webauthn).
|
1005
1010
|
possible_authentication_methods :: An array of strings for possible authentication
|
data/doc/active_sessions.rdoc
CHANGED
@@ -48,6 +48,7 @@ add_active_session :: Create a session id for the session and populate the sessi
|
|
48
48
|
currently_active_session? :: Whether the session is currently active, by checking the database table.
|
49
49
|
handle_duplicate_active_session_id(exception) :: How to handle the case where a duplicate session id for the account is inserted into the table. Does nothing by default. This should only be called if the random number generator is broken.
|
50
50
|
no_longer_active_session :: What action to take if +rodauth.check_active_session+ is called and the session is no longer active.
|
51
|
+
remove_active_session(session_id) :: Removes the active session matching the given session ID from the database. Useful for implementing session revoking.
|
51
52
|
remove_all_active_sessions :: Remove all active session from the database, used for global logouts and when closing accounts.
|
52
53
|
remove_current_session :: Remove current session from the database, used for regular logouts.
|
53
54
|
remove_inactive_sessions :: Remove inactive sessions from the database, run before checking for whether the current session is active.
|
@@ -1,13 +1,16 @@
|
|
1
1
|
= Customize password requirements
|
2
2
|
|
3
3
|
By default, Rodauth requires passwords to have at least 6 characters. You can
|
4
|
-
modify the minimum length:
|
4
|
+
modify the minimum and maximum length:
|
5
5
|
|
6
6
|
plugin :rodauth do
|
7
7
|
enable :login, :logout, :create_account
|
8
8
|
|
9
9
|
# Require passwords to have at least 8 characters
|
10
10
|
password_minimum_length 8
|
11
|
+
|
12
|
+
# Don't allow passwords to be too long, to prevent long password DoS attacks
|
13
|
+
password_maximum_length 64
|
11
14
|
end
|
12
15
|
|
13
16
|
You can use the {disallow common passwords feature}[rdoc-ref:doc/disallow_common_passwords.rdoc]
|
@@ -25,6 +28,16 @@ can use the <tt>password_meets_requirements?</tt> configuration method.
|
|
25
28
|
enable :login, :logout, :create_account
|
26
29
|
|
27
30
|
password_meets_requirements? do |password|
|
28
|
-
|
31
|
+
super(password) && password_complex_enough?(password)
|
32
|
+
end
|
33
|
+
|
34
|
+
auth_class_eval do
|
35
|
+
# If password doesn't pass custom validation, add field error with error
|
36
|
+
# reason, and return false.
|
37
|
+
def password_complex_enough?(password)
|
38
|
+
return true if password.match?(/\d/) && password.match?(/[^a-zA-Z\d]/)
|
39
|
+
set_password_requirement_error_message(:password_simple, "requires one number and one special character")
|
40
|
+
false
|
41
|
+
end
|
29
42
|
end
|
30
43
|
end
|
data/doc/json.rdoc
CHANGED
@@ -15,6 +15,14 @@ an array containing the field name and the error message for that field.
|
|
15
15
|
Successful requests by default store a +success+ entry with a success
|
16
16
|
message, though that can be disabled.
|
17
17
|
|
18
|
+
The JSON response can be modified at any point by modifying the +json_response+
|
19
|
+
hash. The following example adds an {error reason}[rdoc-ref:doc/error_reasons.rdoc]
|
20
|
+
to the JSON response:
|
21
|
+
|
22
|
+
set_error_reason do |reason|
|
23
|
+
json_response[:error_reason] = reason
|
24
|
+
end
|
25
|
+
|
18
26
|
The session state is managed in the rack session, so make sure that
|
19
27
|
CSRF protection is enabled. This will be the case when passing the
|
20
28
|
<tt>json: true</tt> option when loading the rodauth plugin. If you
|
@@ -0,0 +1,16 @@
|
|
1
|
+
= New Features
|
2
|
+
|
3
|
+
* A webauthn_key_insert_hash configuration method has been added when
|
4
|
+
using the webauthn feature, making it easier to add new columns to
|
5
|
+
the webauthn key data, such as a custom name for the authenticator.
|
6
|
+
|
7
|
+
= Other Improvements
|
8
|
+
|
9
|
+
* When using the verify_account_grace_period feature, logged_in? now
|
10
|
+
returns false for sessions where the grace period has expired.
|
11
|
+
|
12
|
+
* When using the internal_request and reset_password features,
|
13
|
+
submitting an internal request for an invalid login no longer tries
|
14
|
+
to render a reset password request form.
|
15
|
+
|
16
|
+
* The password_hash method is now public.
|
@@ -0,0 +1,27 @@
|
|
1
|
+
= New Features
|
2
|
+
|
3
|
+
* When using the remember feature, by default, the remember deadline
|
4
|
+
is extended while logged in, if it hasn't been extended in the last
|
5
|
+
hour
|
6
|
+
|
7
|
+
* An account! method has been added, which will return the hash for
|
8
|
+
the account if already retrieved, or attempt to retrieve the
|
9
|
+
account hash using the currently logged in session if not.
|
10
|
+
Because of the ambiguity in the provenance of the returned account
|
11
|
+
hash, callers should be careful when using this method.
|
12
|
+
|
13
|
+
* A remove_active_session method has been added. You can call this
|
14
|
+
method with a specific session id, and it will remove the related
|
15
|
+
active session.
|
16
|
+
|
17
|
+
* A render: false plugin option is now support, which will disable
|
18
|
+
the automatic loading of the render plugin. This should only be
|
19
|
+
used if you are completely replacing Rodauth's view rendering with
|
20
|
+
your own.
|
21
|
+
|
22
|
+
= Other Improvements
|
23
|
+
|
24
|
+
* When logging in when using the active_sessions feature, if there is
|
25
|
+
a current active session, it is removed before a new active session
|
26
|
+
is created. This prevents some stale active sessions from remaining
|
27
|
+
in the database (which would eventually be cleaned up later).
|
data/doc/remember.rdoc
CHANGED
@@ -30,13 +30,15 @@ for sessions autologged in via a remember token:
|
|
30
30
|
|
31
31
|
== Auth Value Methods
|
32
32
|
|
33
|
-
extend_remember_deadline? :: Whether to extend the remember token deadline when the user is autologged in via remember token.
|
33
|
+
extend_remember_deadline? :: Whether to extend the remember token deadline when the user is autologged in via remember token and every +extend_remember_deadline_period+ seconds while logged in.
|
34
|
+
extend_remember_deadline_period :: The amount of seconds to wait before extending remember token deadline when +extend_remember_deadline?+ is true (3600 by default).
|
34
35
|
raw_remember_token_deadline :: A deadline before which to allow a raw remember token to be used. Allows for graceful transition for when +hmac_secret+ is first set.
|
35
36
|
remember_additional_form_tags :: HTML fragment containing additional form tags to use on the change remember setting form.
|
36
37
|
remember_button :: The text to use for the change remember settings button.
|
37
38
|
remember_cookie_key :: The cookie name to use for the remember token.
|
38
39
|
remember_cookie_options :: Any options to set for the remember cookie. By default, the `:path` cookie option is set to `/` and `:httponly` is set to `true`. Also, `:secure` is set to `true` by default if the current request is an HTTPS request.
|
39
40
|
remember_deadline_column :: The column name in the +remember_table+ storing the deadline after which the token will be ignored.
|
41
|
+
remember_deadline_extended_session_key :: The session key set if the remember deadline token is being extended.
|
40
42
|
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
43
|
remember_disable_label :: The label for disabling remembering.
|
42
44
|
remember_disable_param_value :: The parameter value for disabling remembering.
|
data/doc/webauthn.rdoc
CHANGED
@@ -104,9 +104,10 @@ remove_all_webauthn_keys_and_user_ids :: Remove all WebAuthn credentials and the
|
|
104
104
|
remove_webauthn_key(webauthn_id) :: Remove the WebAuthn credential with the given WebAuthn ID from the current account.
|
105
105
|
valid_new_webauthn_credential?(webauthn_credential) :: Check wheck the WebAuthn credential provided by the client during registration is valid.
|
106
106
|
valid_webauthn_credential_auth?(webauthn_credential) :: Check wheck the WebAuthn credential provided by the client during authentication is valid.
|
107
|
-
webauthn_credential_options_for_get :: WebAuthn credential options to provide to the client during WebAuthn authentication.
|
108
107
|
webauthn_auth_js_path :: The path to the WebAuthn authentication javascript.
|
109
108
|
webauthn_auth_view :: The HTML to use for the page for authenticating via WebAuthn.
|
109
|
+
webauthn_credential_options_for_get :: WebAuthn credential options to provide to the client during WebAuthn authentication.
|
110
|
+
webauthn_key_insert_hash(webauthn_credential) :: The hash to insert into the +webauthn_keys_table+.
|
110
111
|
webauthn_remove_authenticated_session :: Remove the authenticated WebAuthn ID, used when removing the WebAuthn credential with the ID after authenticating with it.
|
111
112
|
webauthn_remove_view :: The HTML to use for the page for removing an existing WebAuthn authenticator.
|
112
113
|
webauthn_setup_js_path :: The path to the WebAuthn registration javascript.
|
@@ -29,6 +29,7 @@ module Rodauth
|
|
29
29
|
:currently_active_session?,
|
30
30
|
:handle_duplicate_active_session_id,
|
31
31
|
:no_longer_active_session,
|
32
|
+
:remove_active_session,
|
32
33
|
:remove_all_active_sessions,
|
33
34
|
:remove_current_session,
|
34
35
|
:remove_inactive_sessions,
|
@@ -82,10 +83,14 @@ module Rodauth
|
|
82
83
|
|
83
84
|
def remove_current_session
|
84
85
|
if session_id = session[session_id_session_key]
|
85
|
-
|
86
|
+
remove_active_session(compute_hmac(session_id))
|
86
87
|
end
|
87
88
|
end
|
88
89
|
|
90
|
+
def remove_active_session(session_id)
|
91
|
+
active_sessions_ds.where(active_sessions_session_id_column=>session_id).delete
|
92
|
+
end
|
93
|
+
|
89
94
|
def remove_all_active_sessions
|
90
95
|
active_sessions_ds.delete
|
91
96
|
end
|
@@ -101,6 +106,7 @@ module Rodauth
|
|
101
106
|
end
|
102
107
|
|
103
108
|
def update_session
|
109
|
+
remove_current_session
|
104
110
|
super
|
105
111
|
add_active_session
|
106
112
|
end
|
@@ -15,6 +15,18 @@ module Rodauth
|
|
15
15
|
auth_value_method :argon2_secret, nil
|
16
16
|
auth_value_method :use_argon2?, true
|
17
17
|
|
18
|
+
def password_hash(password)
|
19
|
+
return super unless use_argon2?
|
20
|
+
|
21
|
+
if secret = argon2_secret
|
22
|
+
argon2_params = Hash[password_hash_cost]
|
23
|
+
argon2_params[:secret] = secret
|
24
|
+
else
|
25
|
+
argon2_params = password_hash_cost
|
26
|
+
end
|
27
|
+
::Argon2::Password.new(argon2_params).create(password)
|
28
|
+
end
|
29
|
+
|
18
30
|
private
|
19
31
|
|
20
32
|
if Argon2::VERSION != '2.1.0'
|
@@ -34,18 +46,6 @@ module Rodauth
|
|
34
46
|
argon2_hash_cost
|
35
47
|
end
|
36
48
|
|
37
|
-
def password_hash(password)
|
38
|
-
return super unless use_argon2?
|
39
|
-
|
40
|
-
if secret = argon2_secret
|
41
|
-
argon2_params = Hash[password_hash_cost]
|
42
|
-
argon2_params[:secret] = secret
|
43
|
-
else
|
44
|
-
argon2_params = password_hash_cost
|
45
|
-
end
|
46
|
-
::Argon2::Password.new(argon2_params).create(password)
|
47
|
-
end
|
48
|
-
|
49
49
|
def password_hash_match?(hash, password)
|
50
50
|
return super unless argon2_hash_algorithm?(hash)
|
51
51
|
argon2_password_hash_match?(hash, password)
|
@@ -355,6 +355,10 @@ module Rodauth
|
|
355
355
|
account_open_status_value
|
356
356
|
end
|
357
357
|
|
358
|
+
def account!
|
359
|
+
account || (session_value && account_from_session)
|
360
|
+
end
|
361
|
+
|
358
362
|
def account_from_session
|
359
363
|
@account = _account_from_session
|
360
364
|
end
|
@@ -680,7 +684,7 @@ module Rodauth
|
|
680
684
|
# note that only the salt is returned.
|
681
685
|
def get_password_hash
|
682
686
|
if account_password_hash_column
|
683
|
-
|
687
|
+
account![account_password_hash_column]
|
684
688
|
elsif use_database_authentication_functions?
|
685
689
|
db.get(Sequel.function(function_name(:rodauth_get_salt), account ? account_id : session_value))
|
686
690
|
else
|
@@ -75,6 +75,10 @@ module Rodauth
|
|
75
75
|
hash
|
76
76
|
end
|
77
77
|
|
78
|
+
def password_hash(password)
|
79
|
+
BCrypt::Password.create(password, :cost=>password_hash_cost)
|
80
|
+
end
|
81
|
+
|
78
82
|
private
|
79
83
|
|
80
84
|
attr_reader :login_requirement_message
|
@@ -184,9 +188,5 @@ module Rodauth
|
|
184
188
|
def extract_password_hash_cost(hash)
|
185
189
|
hash[4, 2].to_i
|
186
190
|
end
|
187
|
-
|
188
|
-
def password_hash(password)
|
189
|
-
BCrypt::Password.create(password, :cost=>password_hash_cost)
|
190
|
-
end
|
191
191
|
end
|
192
192
|
end
|
@@ -17,6 +17,7 @@ module Rodauth
|
|
17
17
|
auth_value_method :raw_remember_token_deadline, nil
|
18
18
|
auth_value_method :remember_cookie_options, {}.freeze
|
19
19
|
auth_value_method :extend_remember_deadline?, false
|
20
|
+
auth_value_method :extend_remember_deadline_period, 3600
|
20
21
|
auth_value_method :remember_period, {:days=>14}.freeze
|
21
22
|
auth_value_method :remember_deadline_interval, {:days=>14}.freeze
|
22
23
|
auth_value_method :remember_id_column, :id
|
@@ -28,6 +29,7 @@ module Rodauth
|
|
28
29
|
auth_value_method :remember_remember_param_value, 'remember'
|
29
30
|
auth_value_method :remember_forget_param_value, 'forget'
|
30
31
|
auth_value_method :remember_disable_param_value, 'disable'
|
32
|
+
session_key :remember_deadline_extended_session_key, :remember_deadline_extended_at
|
31
33
|
translatable_method :remember_remember_label, 'Remember Me'
|
32
34
|
translatable_method :remember_forget_label, 'Forget Me'
|
33
35
|
translatable_method :remember_disable_label, 'Disable Remember Me'
|
@@ -110,43 +112,23 @@ module Rodauth
|
|
110
112
|
end
|
111
113
|
|
112
114
|
def load_memory
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
remove_session_value(session_key)
|
124
|
-
|
125
|
-
unless account
|
126
|
-
remove_remember_key(id)
|
127
|
-
forget_login
|
128
|
-
return
|
129
|
-
end
|
130
|
-
|
131
|
-
before_load_memory
|
132
|
-
login_session('remember')
|
133
|
-
|
134
|
-
if extend_remember_deadline?
|
135
|
-
active_remember_key_ds(id).update(remember_deadline_column=>Sequel.date_add(Sequel::CURRENT_TIMESTAMP, remember_period))
|
136
|
-
remember_login
|
115
|
+
if logged_in?
|
116
|
+
if extend_remember_deadline_while_logged_in?
|
117
|
+
account_from_session
|
118
|
+
extend_remember_deadline
|
119
|
+
end
|
120
|
+
elsif account_from_remember_cookie
|
121
|
+
before_load_memory
|
122
|
+
login_session('remember')
|
123
|
+
extend_remember_deadline if extend_remember_deadline?
|
124
|
+
after_load_memory
|
137
125
|
end
|
138
|
-
after_load_memory
|
139
126
|
end
|
140
127
|
|
141
128
|
def remember_login
|
142
129
|
get_remember_key
|
143
|
-
|
144
|
-
|
145
|
-
opts[:expires] = convert_timestamp(active_remember_key_ds.get(remember_deadline_column))
|
146
|
-
opts[:path] = "/" unless opts.key?(:path)
|
147
|
-
opts[:httponly] = true unless opts.key?(:httponly) || opts.key?(:http_only)
|
148
|
-
opts[:secure] = true unless opts.key?(:secure) || !request.ssl?
|
149
|
-
::Rack::Utils.set_cookie_header!(response.headers, remember_cookie_key, opts)
|
130
|
+
set_remember_cookie
|
131
|
+
set_session_value(remember_deadline_extended_session_key, Time.now.to_i) if extend_remember_deadline?
|
150
132
|
end
|
151
133
|
|
152
134
|
def forget_login
|
@@ -191,6 +173,53 @@ module Rodauth
|
|
191
173
|
|
192
174
|
private
|
193
175
|
|
176
|
+
def set_remember_cookie
|
177
|
+
opts = Hash[remember_cookie_options]
|
178
|
+
opts[:value] = "#{account_id}_#{convert_token_key(remember_key_value)}"
|
179
|
+
opts[:expires] = convert_timestamp(active_remember_key_ds.get(remember_deadline_column))
|
180
|
+
opts[:path] = "/" unless opts.key?(:path)
|
181
|
+
opts[:httponly] = true unless opts.key?(:httponly) || opts.key?(:http_only)
|
182
|
+
opts[:secure] = true unless opts.key?(:secure) || !request.ssl?
|
183
|
+
::Rack::Utils.set_cookie_header!(response.headers, remember_cookie_key, opts)
|
184
|
+
end
|
185
|
+
|
186
|
+
def extend_remember_deadline_while_logged_in?
|
187
|
+
return false unless extend_remember_deadline?
|
188
|
+
|
189
|
+
if extended_at = session[remember_deadline_extended_session_key]
|
190
|
+
extended_at + extend_remember_deadline_period < Time.now.to_i
|
191
|
+
elsif logged_in_via_remember_key?
|
192
|
+
# Handle existing sessions before the change to extend remember deadline
|
193
|
+
# while logged in.
|
194
|
+
true
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
def extend_remember_deadline
|
199
|
+
active_remember_key_ds.update(remember_deadline_column=>Sequel.date_add(Sequel::CURRENT_TIMESTAMP, remember_period))
|
200
|
+
remember_login
|
201
|
+
end
|
202
|
+
|
203
|
+
def account_from_remember_cookie
|
204
|
+
unless id = remembered_session_id
|
205
|
+
# Only set expired cookie if there is already a cookie set.
|
206
|
+
forget_login if _get_remember_cookie
|
207
|
+
return
|
208
|
+
end
|
209
|
+
|
210
|
+
set_session_value(session_key, id)
|
211
|
+
account_from_session
|
212
|
+
remove_session_value(session_key)
|
213
|
+
|
214
|
+
unless account
|
215
|
+
remove_remember_key(id)
|
216
|
+
forget_login
|
217
|
+
return
|
218
|
+
end
|
219
|
+
|
220
|
+
account
|
221
|
+
end
|
222
|
+
|
194
223
|
def _get_remember_cookie
|
195
224
|
request.cookies[remember_cookie_key]
|
196
225
|
end
|
@@ -30,6 +30,10 @@ module Rodauth
|
|
30
30
|
false
|
31
31
|
end
|
32
32
|
|
33
|
+
def logged_in?
|
34
|
+
super && !unverified_grace_period_expired?
|
35
|
+
end
|
36
|
+
|
33
37
|
def require_login
|
34
38
|
if unverified_grace_period_expired?
|
35
39
|
clear_session
|
@@ -79,7 +83,7 @@ module Rodauth
|
|
79
83
|
end
|
80
84
|
|
81
85
|
def account_in_unverified_grace_period?
|
82
|
-
return false unless account
|
86
|
+
return false unless account!
|
83
87
|
account[account_status_column] == account_unverified_status_value &&
|
84
88
|
verify_account_grace_period &&
|
85
89
|
!verify_account_ds.where(Sequel.date_add(verification_requested_at_column, :seconds=>verify_account_grace_period) > Sequel::CURRENT_TIMESTAMP).empty?
|
@@ -103,6 +103,7 @@ module Rodauth
|
|
103
103
|
:valid_webauthn_credential_auth?,
|
104
104
|
:webauthn_auth_js_path,
|
105
105
|
:webauthn_credential_options_for_get,
|
106
|
+
:webauthn_key_insert_hash,
|
106
107
|
:webauthn_remove_authenticated_session,
|
107
108
|
:webauthn_setup_js_path,
|
108
109
|
:webauthn_update_session,
|
@@ -328,7 +329,7 @@ module Rodauth
|
|
328
329
|
end
|
329
330
|
|
330
331
|
def webauthn_user_name
|
331
|
-
|
332
|
+
account![login_column]
|
332
333
|
end
|
333
334
|
|
334
335
|
def webauthn_origin
|
@@ -348,12 +349,7 @@ module Rodauth
|
|
348
349
|
end
|
349
350
|
|
350
351
|
def add_webauthn_credential(webauthn_credential)
|
351
|
-
webauthn_keys_ds.insert(
|
352
|
-
webauthn_keys_account_id_column => webauthn_account_id,
|
353
|
-
webauthn_keys_webauthn_id_column => webauthn_credential.id,
|
354
|
-
webauthn_keys_public_key_column => webauthn_credential.public_key,
|
355
|
-
webauthn_keys_sign_count_column => Integer(webauthn_credential.sign_count)
|
356
|
-
)
|
352
|
+
webauthn_keys_ds.insert(webauthn_key_insert_hash(webauthn_credential))
|
357
353
|
super if defined?(super)
|
358
354
|
nil
|
359
355
|
end
|
@@ -435,6 +431,15 @@ module Rodauth
|
|
435
431
|
super
|
436
432
|
end
|
437
433
|
|
434
|
+
def webauthn_key_insert_hash(webauthn_credential)
|
435
|
+
{
|
436
|
+
webauthn_keys_account_id_column => webauthn_account_id,
|
437
|
+
webauthn_keys_webauthn_id_column => webauthn_credential.id,
|
438
|
+
webauthn_keys_public_key_column => webauthn_credential.public_key,
|
439
|
+
webauthn_keys_sign_count_column => Integer(webauthn_credential.sign_count)
|
440
|
+
}
|
441
|
+
end
|
442
|
+
|
438
443
|
def webauthn_account_id
|
439
444
|
session_value
|
440
445
|
end
|
data/lib/rodauth/version.rb
CHANGED
data/lib/rodauth.rb
CHANGED
@@ -22,8 +22,10 @@ module Rodauth
|
|
22
22
|
end
|
23
23
|
|
24
24
|
unless json_opt == :only
|
25
|
-
|
26
|
-
|
25
|
+
unless opts[:render] == false
|
26
|
+
require 'tilt/string'
|
27
|
+
app.plugin :render
|
28
|
+
end
|
27
29
|
|
28
30
|
case opts.fetch(:csrf, app.opts[:rodauth_csrf])
|
29
31
|
when false
|
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.29.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: 2023-
|
11
|
+
date: 2023-03-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sequel
|
@@ -343,6 +343,8 @@ extra_rdoc_files:
|
|
343
343
|
- doc/release_notes/2.25.0.txt
|
344
344
|
- doc/release_notes/2.26.0.txt
|
345
345
|
- doc/release_notes/2.27.0.txt
|
346
|
+
- doc/release_notes/2.28.0.txt
|
347
|
+
- doc/release_notes/2.29.0.txt
|
346
348
|
- doc/release_notes/2.3.0.txt
|
347
349
|
- doc/release_notes/2.4.0.txt
|
348
350
|
- doc/release_notes/2.5.0.txt
|
@@ -457,6 +459,8 @@ files:
|
|
457
459
|
- doc/release_notes/2.25.0.txt
|
458
460
|
- doc/release_notes/2.26.0.txt
|
459
461
|
- doc/release_notes/2.27.0.txt
|
462
|
+
- doc/release_notes/2.28.0.txt
|
463
|
+
- doc/release_notes/2.29.0.txt
|
460
464
|
- doc/release_notes/2.3.0.txt
|
461
465
|
- doc/release_notes/2.4.0.txt
|
462
466
|
- doc/release_notes/2.5.0.txt
|
@@ -614,7 +618,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
614
618
|
- !ruby/object:Gem::Version
|
615
619
|
version: '0'
|
616
620
|
requirements: []
|
617
|
-
rubygems_version: 3.4.
|
621
|
+
rubygems_version: 3.4.6
|
618
622
|
signing_key:
|
619
623
|
specification_version: 4
|
620
624
|
summary: Authentication and Account Management Framework for Rack Applications
|