rodauth 1.22.0 → 2.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/CHANGELOG +190 -0
- data/MIT-LICENSE +1 -1
- data/README.rdoc +210 -80
- data/doc/account_expiration.rdoc +12 -26
- data/doc/active_sessions.rdoc +49 -0
- data/doc/audit_logging.rdoc +44 -0
- data/doc/base.rdoc +75 -128
- data/doc/change_login.rdoc +7 -14
- data/doc/change_password.rdoc +9 -13
- data/doc/change_password_notify.rdoc +2 -2
- data/doc/close_account.rdoc +9 -16
- data/doc/confirm_password.rdoc +12 -5
- data/doc/create_account.rdoc +11 -22
- data/doc/disallow_password_reuse.rdoc +6 -13
- data/doc/email_auth.rdoc +15 -14
- data/doc/email_base.rdoc +6 -15
- data/doc/guides/admin_activation.rdoc +46 -0
- data/doc/guides/already_authenticated.rdoc +10 -0
- data/doc/guides/alternative_login.rdoc +46 -0
- data/doc/guides/create_account_programmatically.rdoc +38 -0
- data/doc/guides/delay_password.rdoc +25 -0
- data/doc/guides/email_only.rdoc +16 -0
- data/doc/guides/i18n.rdoc +26 -0
- data/doc/{internals.rdoc → guides/internals.rdoc} +0 -0
- data/doc/guides/links.rdoc +12 -0
- data/doc/guides/login_return.rdoc +37 -0
- data/doc/guides/password_column.rdoc +25 -0
- data/doc/guides/password_confirmation.rdoc +37 -0
- data/doc/guides/password_requirements.rdoc +30 -0
- data/doc/guides/paths.rdoc +36 -0
- data/doc/guides/query_params.rdoc +9 -0
- data/doc/guides/redirects.rdoc +17 -0
- data/doc/guides/registration_field.rdoc +68 -0
- data/doc/guides/require_mfa.rdoc +30 -0
- data/doc/guides/reset_password_autologin.rdoc +21 -0
- data/doc/guides/status_column.rdoc +28 -0
- data/doc/guides/totp_or_recovery.rdoc +16 -0
- data/doc/http_basic_auth.rdoc +10 -1
- data/doc/jwt.rdoc +22 -22
- data/doc/jwt_cors.rdoc +2 -3
- data/doc/jwt_refresh.rdoc +23 -8
- data/doc/lockout.rdoc +17 -15
- data/doc/login.rdoc +17 -2
- data/doc/login_password_requirements_base.rdoc +18 -37
- data/doc/logout.rdoc +2 -2
- data/doc/otp.rdoc +25 -19
- data/doc/password_complexity.rdoc +10 -26
- data/doc/password_expiration.rdoc +11 -25
- data/doc/password_grace_period.rdoc +16 -2
- data/doc/recovery_codes.rdoc +18 -12
- data/doc/release_notes/1.23.0.txt +32 -0
- data/doc/release_notes/2.0.0.txt +361 -0
- data/doc/release_notes/2.1.0.txt +31 -0
- data/doc/release_notes/2.2.0.txt +39 -0
- data/doc/release_notes/2.3.0.txt +37 -0
- data/doc/remember.rdoc +40 -64
- data/doc/reset_password.rdoc +12 -9
- data/doc/session_expiration.rdoc +1 -0
- data/doc/single_session.rdoc +16 -25
- data/doc/sms_codes.rdoc +24 -14
- data/doc/two_factor_base.rdoc +60 -22
- data/doc/verify_account.rdoc +14 -12
- data/doc/verify_account_grace_period.rdoc +6 -2
- data/doc/verify_login_change.rdoc +9 -8
- data/doc/webauthn.rdoc +115 -0
- data/doc/webauthn_login.rdoc +15 -0
- data/doc/webauthn_verify_account.rdoc +9 -0
- data/javascript/webauthn_auth.js +45 -0
- data/javascript/webauthn_setup.js +35 -0
- data/lib/roda/plugins/rodauth.rb +1 -1
- data/lib/rodauth.rb +36 -28
- data/lib/rodauth/features/account_expiration.rb +5 -5
- data/lib/rodauth/features/active_sessions.rb +158 -0
- data/lib/rodauth/features/audit_logging.rb +98 -0
- data/lib/rodauth/features/base.rb +144 -43
- data/lib/rodauth/features/change_password_notify.rb +2 -2
- data/lib/rodauth/features/close_account.rb +8 -6
- data/lib/rodauth/features/confirm_password.rb +40 -2
- data/lib/rodauth/features/create_account.rb +8 -13
- data/lib/rodauth/features/disallow_common_passwords.rb +1 -1
- data/lib/rodauth/features/disallow_password_reuse.rb +1 -1
- data/lib/rodauth/features/email_auth.rb +31 -30
- data/lib/rodauth/features/email_base.rb +9 -4
- data/lib/rodauth/features/http_basic_auth.rb +55 -35
- data/lib/rodauth/features/jwt.rb +63 -16
- data/lib/rodauth/features/jwt_cors.rb +15 -15
- data/lib/rodauth/features/jwt_refresh.rb +42 -13
- data/lib/rodauth/features/lockout.rb +12 -14
- data/lib/rodauth/features/login.rb +64 -15
- data/lib/rodauth/features/login_password_requirements_base.rb +13 -8
- data/lib/rodauth/features/otp.rb +77 -80
- data/lib/rodauth/features/password_complexity.rb +8 -13
- data/lib/rodauth/features/password_expiration.rb +2 -2
- data/lib/rodauth/features/password_grace_period.rb +17 -10
- data/lib/rodauth/features/recovery_codes.rb +49 -53
- data/lib/rodauth/features/remember.rb +11 -27
- data/lib/rodauth/features/reset_password.rb +26 -26
- data/lib/rodauth/features/session_expiration.rb +7 -10
- data/lib/rodauth/features/single_session.rb +8 -6
- data/lib/rodauth/features/sms_codes.rb +62 -72
- data/lib/rodauth/features/two_factor_base.rb +134 -30
- data/lib/rodauth/features/verify_account.rb +29 -21
- data/lib/rodauth/features/verify_account_grace_period.rb +18 -9
- data/lib/rodauth/features/verify_login_change.rb +12 -11
- data/lib/rodauth/features/webauthn.rb +505 -0
- data/lib/rodauth/features/webauthn_login.rb +70 -0
- data/lib/rodauth/features/webauthn_verify_account.rb +46 -0
- data/lib/rodauth/migrations.rb +16 -5
- data/lib/rodauth/version.rb +2 -2
- data/templates/button.str +1 -3
- data/templates/change-login.str +1 -2
- data/templates/change-password.str +3 -5
- data/templates/close-account.str +2 -2
- data/templates/confirm-password.str +1 -1
- data/templates/create-account.str +1 -1
- data/templates/email-auth-request-form.str +2 -3
- data/templates/email-auth.str +1 -1
- data/templates/global-logout-field.str +6 -0
- data/templates/login-confirm-field.str +2 -4
- data/templates/login-display.str +3 -2
- data/templates/login-field.str +2 -4
- data/templates/login-form-footer.str +6 -0
- data/templates/login-form.str +7 -0
- data/templates/login.str +1 -9
- data/templates/logout.str +1 -1
- data/templates/multi-phase-login.str +3 -0
- data/templates/otp-auth-code-field.str +5 -3
- data/templates/otp-auth.str +1 -1
- data/templates/otp-disable.str +1 -1
- data/templates/otp-setup.str +3 -3
- data/templates/password-confirm-field.str +2 -4
- data/templates/password-field.str +2 -4
- data/templates/recovery-auth.str +3 -6
- data/templates/recovery-codes.str +1 -1
- data/templates/remember.str +15 -20
- data/templates/reset-password-request.str +3 -3
- data/templates/reset-password.str +1 -2
- data/templates/sms-auth.str +1 -1
- data/templates/sms-code-field.str +5 -3
- data/templates/sms-confirm.str +1 -2
- data/templates/sms-disable.str +1 -2
- data/templates/sms-request.str +1 -1
- data/templates/sms-setup.str +6 -4
- data/templates/two-factor-auth.str +5 -0
- data/templates/two-factor-disable.str +6 -0
- data/templates/two-factor-manage.str +16 -0
- data/templates/unlock-account-request.str +4 -4
- data/templates/unlock-account.str +1 -1
- data/templates/verify-account-resend.str +3 -3
- data/templates/verify-account.str +1 -2
- data/templates/verify-login-change.str +1 -1
- data/templates/webauthn-auth.str +11 -0
- data/templates/webauthn-remove.str +14 -0
- data/templates/webauthn-setup.str +12 -0
- metadata +94 -54
- data/Rakefile +0 -179
- data/doc/verify_change_login.rdoc +0 -11
- data/lib/rodauth/features/verify_change_login.rb +0 -20
- data/spec/account_expiration_spec.rb +0 -225
- data/spec/all.rb +0 -1
- data/spec/change_login_spec.rb +0 -156
- data/spec/change_password_notify_spec.rb +0 -33
- data/spec/change_password_spec.rb +0 -202
- data/spec/close_account_spec.rb +0 -162
- data/spec/confirm_password_spec.rb +0 -70
- data/spec/create_account_spec.rb +0 -127
- data/spec/disallow_common_passwords_spec.rb +0 -93
- data/spec/disallow_password_reuse_spec.rb +0 -179
- data/spec/email_auth_spec.rb +0 -285
- data/spec/http_basic_auth_spec.rb +0 -143
- data/spec/jwt_cors_spec.rb +0 -57
- data/spec/jwt_refresh_spec.rb +0 -256
- data/spec/jwt_spec.rb +0 -235
- data/spec/lockout_spec.rb +0 -250
- data/spec/login_spec.rb +0 -328
- data/spec/migrate/001_tables.rb +0 -184
- data/spec/migrate/002_account_password_hash_column.rb +0 -11
- data/spec/migrate_password/001_tables.rb +0 -73
- data/spec/migrate_travis/001_tables.rb +0 -141
- data/spec/password_complexity_spec.rb +0 -109
- data/spec/password_expiration_spec.rb +0 -244
- data/spec/password_grace_period_spec.rb +0 -93
- data/spec/remember_spec.rb +0 -451
- data/spec/reset_password_spec.rb +0 -229
- data/spec/rodauth_spec.rb +0 -343
- data/spec/session_expiration_spec.rb +0 -58
- data/spec/single_session_spec.rb +0 -127
- data/spec/spec_helper.rb +0 -327
- data/spec/two_factor_spec.rb +0 -1462
- data/spec/update_password_hash_spec.rb +0 -40
- data/spec/verify_account_grace_period_spec.rb +0 -171
- data/spec/verify_account_spec.rb +0 -240
- data/spec/verify_change_login_spec.rb +0 -46
- data/spec/verify_login_change_spec.rb +0 -232
- data/spec/views/layout-other.str +0 -11
- data/spec/views/layout.str +0 -11
- data/spec/views/login.str +0 -21
|
@@ -17,14 +17,14 @@ module Rodauth
|
|
|
17
17
|
button 'Authenticate via Recovery Code', 'recovery_auth'
|
|
18
18
|
button 'View Authentication Recovery Codes', 'view_recovery_codes'
|
|
19
19
|
|
|
20
|
-
error_flash "Error authenticating via recovery code
|
|
21
|
-
error_flash "Unable to add recovery codes
|
|
22
|
-
error_flash "Unable to view recovery codes
|
|
20
|
+
error_flash "Error authenticating via recovery code", 'invalid_recovery_code'
|
|
21
|
+
error_flash "Unable to add recovery codes", 'add_recovery_codes'
|
|
22
|
+
error_flash "Unable to view recovery codes", 'view_recovery_codes'
|
|
23
23
|
|
|
24
|
-
notice_flash "Additional authentication recovery codes have been added
|
|
24
|
+
notice_flash "Additional authentication recovery codes have been added", 'recovery_codes_added'
|
|
25
25
|
|
|
26
|
-
redirect(:recovery_auth){
|
|
27
|
-
redirect(:add_recovery_codes){
|
|
26
|
+
redirect(:recovery_auth){recovery_auth_path}
|
|
27
|
+
redirect(:add_recovery_codes){recovery_codes_path}
|
|
28
28
|
|
|
29
29
|
loaded_templates %w'add-recovery-codes recovery-auth recovery-codes password-field'
|
|
30
30
|
view 'add-recovery-codes', 'Authentication Recovery Codes', 'add_recovery_codes'
|
|
@@ -32,15 +32,19 @@ module Rodauth
|
|
|
32
32
|
view 'recovery-codes', 'View Authentication Recovery Codes', 'recovery_codes'
|
|
33
33
|
|
|
34
34
|
auth_value_method :add_recovery_codes_param, 'add'
|
|
35
|
-
|
|
36
|
-
auth_value_method :
|
|
35
|
+
translatable_method :add_recovery_codes_heading, '<h2>Add Additional Recovery Codes</h2>'
|
|
36
|
+
auth_value_method :auto_add_recovery_codes?, false
|
|
37
|
+
translatable_method :invalid_recovery_code_message, "Invalid recovery code"
|
|
37
38
|
auth_value_method :recovery_codes_limit, 16
|
|
38
39
|
auth_value_method :recovery_codes_column, :code
|
|
39
40
|
auth_value_method :recovery_codes_id_column, :id
|
|
40
|
-
|
|
41
|
+
translatable_method :recovery_codes_label, 'Recovery Code'
|
|
41
42
|
auth_value_method :recovery_codes_param, 'recovery-code'
|
|
42
43
|
auth_value_method :recovery_codes_table, :account_recovery_codes
|
|
43
44
|
|
|
45
|
+
translatable_method :recovery_auth_link_text, "Authenticate Using Recovery Code"
|
|
46
|
+
translatable_method :recovery_codes_link_text, "View Authentication Recovery Codes"
|
|
47
|
+
|
|
44
48
|
auth_cached_method :recovery_codes
|
|
45
49
|
|
|
46
50
|
auth_value_methods(
|
|
@@ -59,7 +63,7 @@ module Rodauth
|
|
|
59
63
|
require_login
|
|
60
64
|
require_account_session
|
|
61
65
|
require_two_factor_setup
|
|
62
|
-
require_two_factor_not_authenticated
|
|
66
|
+
require_two_factor_not_authenticated('recovery_code')
|
|
63
67
|
before_recovery_auth_route
|
|
64
68
|
|
|
65
69
|
r.get do
|
|
@@ -69,7 +73,7 @@ module Rodauth
|
|
|
69
73
|
r.post do
|
|
70
74
|
if recovery_code_match?(param(recovery_codes_param))
|
|
71
75
|
before_recovery_auth
|
|
72
|
-
two_factor_authenticate(
|
|
76
|
+
two_factor_authenticate('recovery_code')
|
|
73
77
|
end
|
|
74
78
|
|
|
75
79
|
set_response_error_status(invalid_key_error_status)
|
|
@@ -124,61 +128,24 @@ module Rodauth
|
|
|
124
128
|
|
|
125
129
|
attr_accessor :recovery_codes_button
|
|
126
130
|
|
|
127
|
-
def two_factor_need_setup_redirect
|
|
128
|
-
super || (add_recovery_codes_redirect if recovery_codes_primary?)
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
def two_factor_auth_required_redirect
|
|
132
|
-
super || (recovery_auth_redirect if recovery_codes_primary?)
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
def two_factor_auth_fallback_redirect
|
|
136
|
-
recovery_auth_redirect
|
|
137
|
-
end
|
|
138
|
-
|
|
139
131
|
def two_factor_remove
|
|
140
132
|
super
|
|
141
133
|
recovery_codes_remove
|
|
142
134
|
end
|
|
143
135
|
|
|
144
|
-
def two_factor_authentication_setup?
|
|
145
|
-
super || (recovery_codes_primary? && !recovery_codes.empty?)
|
|
146
|
-
end
|
|
147
|
-
|
|
148
|
-
def otp_auth_form_footer
|
|
149
|
-
"#{super if defined?(super)}<p><a href=\"#{recovery_auth_route}\">Authenticate using recovery code</a></p>"
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
def otp_lockout_redirect
|
|
153
|
-
recovery_auth_redirect
|
|
154
|
-
end
|
|
155
|
-
|
|
156
|
-
def otp_lockout_error_flash
|
|
157
|
-
"#{super if defined?(super)} Can use recovery code to unlock."
|
|
158
|
-
end
|
|
159
|
-
|
|
160
136
|
def otp_add_key
|
|
161
137
|
super if defined?(super)
|
|
162
|
-
|
|
138
|
+
auto_add_missing_recovery_codes
|
|
163
139
|
end
|
|
164
140
|
|
|
165
141
|
def sms_confirm
|
|
166
142
|
super if defined?(super)
|
|
167
|
-
|
|
168
|
-
end
|
|
169
|
-
|
|
170
|
-
def otp_remove
|
|
171
|
-
super if defined?(super)
|
|
172
|
-
unless recovery_codes_primary?
|
|
173
|
-
recovery_codes_remove
|
|
174
|
-
end
|
|
143
|
+
auto_add_missing_recovery_codes
|
|
175
144
|
end
|
|
176
145
|
|
|
177
|
-
def
|
|
146
|
+
def add_webauthn_credential(_)
|
|
178
147
|
super if defined?(super)
|
|
179
|
-
|
|
180
|
-
recovery_codes_remove
|
|
181
|
-
end
|
|
148
|
+
auto_add_missing_recovery_codes
|
|
182
149
|
end
|
|
183
150
|
|
|
184
151
|
def recovery_codes_remove
|
|
@@ -221,14 +188,43 @@ module Rodauth
|
|
|
221
188
|
end
|
|
222
189
|
end
|
|
223
190
|
|
|
191
|
+
def possible_authentication_methods
|
|
192
|
+
methods = super
|
|
193
|
+
methods << 'recovery_code' unless recovery_codes_ds.empty?
|
|
194
|
+
methods
|
|
195
|
+
end
|
|
196
|
+
|
|
224
197
|
private
|
|
225
198
|
|
|
199
|
+
def _two_factor_auth_links
|
|
200
|
+
links = super
|
|
201
|
+
links << [40, recovery_auth_path, recovery_auth_link_text] unless recovery_codes_ds.empty?
|
|
202
|
+
links
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def _two_factor_setup_links
|
|
206
|
+
links = super
|
|
207
|
+
links << [40, recovery_codes_path, recovery_codes_link_text] if (recovery_codes_primary? || uses_two_factor_authentication?)
|
|
208
|
+
links
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def _two_factor_remove_all_from_session
|
|
212
|
+
two_factor_remove_session('recovery_code')
|
|
213
|
+
super
|
|
214
|
+
end
|
|
215
|
+
|
|
226
216
|
def new_recovery_code
|
|
227
217
|
random_key
|
|
228
218
|
end
|
|
229
219
|
|
|
230
220
|
def recovery_codes_primary?
|
|
231
|
-
(features & [:otp, :sms_codes]).empty?
|
|
221
|
+
(features & [:otp, :sms_codes, :webauthn]).empty?
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
def auto_add_missing_recovery_codes
|
|
225
|
+
if auto_add_recovery_codes?
|
|
226
|
+
add_recovery_codes(recovery_codes_limit - recovery_codes.length)
|
|
227
|
+
end
|
|
232
228
|
end
|
|
233
229
|
|
|
234
230
|
def _recovery_codes
|
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
module Rodauth
|
|
4
4
|
Feature.define(:remember, :Remember) do
|
|
5
|
-
depends :confirm_password
|
|
6
|
-
|
|
7
5
|
notice_flash "Your remember setting has been updated"
|
|
8
6
|
error_flash "There was an error updating your remember setting"
|
|
9
7
|
loaded_templates %w'remember'
|
|
@@ -17,11 +15,10 @@ module Rodauth
|
|
|
17
15
|
redirect
|
|
18
16
|
|
|
19
17
|
auth_value_method :raw_remember_token_deadline, nil
|
|
20
|
-
auth_value_method :remember_cookie_options, {}
|
|
18
|
+
auth_value_method :remember_cookie_options, {}.freeze
|
|
21
19
|
auth_value_method :extend_remember_deadline?, false
|
|
22
|
-
auth_value_method :remember_period, {:days=>14}
|
|
23
|
-
|
|
24
|
-
auth_value_method :remember_deadline_interval, {:days=>14}
|
|
20
|
+
auth_value_method :remember_period, {:days=>14}.freeze
|
|
21
|
+
auth_value_method :remember_deadline_interval, {:days=>14}.freeze
|
|
25
22
|
auth_value_method :remember_id_column, :id
|
|
26
23
|
auth_value_method :remember_key_column, :key
|
|
27
24
|
auth_value_method :remember_deadline_column, :deadline
|
|
@@ -31,13 +28,12 @@ module Rodauth
|
|
|
31
28
|
auth_value_method :remember_remember_param_value, 'remember'
|
|
32
29
|
auth_value_method :remember_forget_param_value, 'forget'
|
|
33
30
|
auth_value_method :remember_disable_param_value, 'disable'
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
31
|
+
translatable_method :remember_remember_label, 'Remember Me'
|
|
32
|
+
translatable_method :remember_forget_label, 'Forget Me'
|
|
33
|
+
translatable_method :remember_disable_label, 'Disable Remember Me'
|
|
37
34
|
|
|
38
35
|
auth_methods(
|
|
39
36
|
:add_remember_key,
|
|
40
|
-
:clear_remembered_session_key,
|
|
41
37
|
:disable_remember_login,
|
|
42
38
|
:forget_login,
|
|
43
39
|
:generate_remember_key_value,
|
|
@@ -109,9 +105,9 @@ module Rodauth
|
|
|
109
105
|
return
|
|
110
106
|
end
|
|
111
107
|
|
|
112
|
-
|
|
108
|
+
set_session_value(session_key, id)
|
|
113
109
|
account = account_from_session
|
|
114
|
-
|
|
110
|
+
remove_session_value(session_key)
|
|
115
111
|
|
|
116
112
|
unless account
|
|
117
113
|
remove_remember_key(id)
|
|
@@ -120,9 +116,8 @@ module Rodauth
|
|
|
120
116
|
end
|
|
121
117
|
|
|
122
118
|
before_load_memory
|
|
123
|
-
|
|
119
|
+
login_session('remember')
|
|
124
120
|
|
|
125
|
-
set_session_value(remembered_session_key, true)
|
|
126
121
|
if extend_remember_deadline?
|
|
127
122
|
active_remember_key_ds(id).update(remember_deadline_column=>Sequel.date_add(Sequel::CURRENT_TIMESTAMP, remember_period))
|
|
128
123
|
remember_login
|
|
@@ -133,9 +128,7 @@ module Rodauth
|
|
|
133
128
|
def remember_login
|
|
134
129
|
get_remember_key
|
|
135
130
|
opts = Hash[remember_cookie_options]
|
|
136
|
-
|
|
137
|
-
key = compute_hmac(key) if hmac_secret
|
|
138
|
-
opts[:value] = "#{account_id}_#{key}"
|
|
131
|
+
opts[:value] = "#{account_id}_#{convert_token_key(remember_key_value)}"
|
|
139
132
|
opts[:expires] = convert_timestamp(active_remember_key_ds.get(remember_deadline_column))
|
|
140
133
|
::Rack::Utils.set_cookie_header!(response.headers, remember_cookie_key, opts)
|
|
141
134
|
end
|
|
@@ -174,12 +167,8 @@ module Rodauth
|
|
|
174
167
|
remember_key_ds(id).delete
|
|
175
168
|
end
|
|
176
169
|
|
|
177
|
-
def clear_remembered_session_key
|
|
178
|
-
session.delete(remembered_session_key)
|
|
179
|
-
end
|
|
180
|
-
|
|
181
170
|
def logged_in_via_remember_key?
|
|
182
|
-
|
|
171
|
+
authenticated_by.include?('remember')
|
|
183
172
|
end
|
|
184
173
|
|
|
185
174
|
private
|
|
@@ -194,11 +183,6 @@ module Rodauth
|
|
|
194
183
|
super if defined?(super)
|
|
195
184
|
end
|
|
196
185
|
|
|
197
|
-
def after_confirm_password
|
|
198
|
-
super
|
|
199
|
-
clear_remembered_session_key
|
|
200
|
-
end
|
|
201
|
-
|
|
202
186
|
attr_reader :remember_key_value
|
|
203
187
|
|
|
204
188
|
def generate_remember_key_value
|
|
@@ -4,8 +4,6 @@ module Rodauth
|
|
|
4
4
|
Feature.define(:reset_password, :ResetPassword) do
|
|
5
5
|
depends :login, :email_base, :login_password_requirements_base
|
|
6
6
|
|
|
7
|
-
def_deprecated_alias :no_matching_reset_password_key_error_flash, :no_matching_reset_password_key_message
|
|
8
|
-
|
|
9
7
|
notice_flash "Your password has been reset"
|
|
10
8
|
notice_flash "An email has been sent to you with a link to reset the password for your account", 'reset_password_email_sent'
|
|
11
9
|
error_flash "There was an error resetting your password"
|
|
@@ -28,20 +26,19 @@ module Rodauth
|
|
|
28
26
|
redirect(:reset_password_email_recently_sent){default_post_email_redirect}
|
|
29
27
|
|
|
30
28
|
auth_value_method :reset_password_deadline_column, :deadline
|
|
31
|
-
auth_value_method :reset_password_deadline_interval, {:days=>1}
|
|
32
|
-
|
|
29
|
+
auth_value_method :reset_password_deadline_interval, {:days=>1}.freeze
|
|
30
|
+
translatable_method :reset_password_email_subject, 'Reset Password'
|
|
33
31
|
auth_value_method :reset_password_key_param, 'key'
|
|
34
32
|
auth_value_method :reset_password_autologin?, false
|
|
35
33
|
auth_value_method :reset_password_table, :account_password_reset_keys
|
|
36
34
|
auth_value_method :reset_password_id_column, :id
|
|
37
35
|
auth_value_method :reset_password_key_column, :key
|
|
38
|
-
auth_value_method :reset_password_email_last_sent_column,
|
|
39
|
-
|
|
36
|
+
auth_value_method :reset_password_email_last_sent_column, :email_last_sent
|
|
37
|
+
translatable_method :reset_password_explanatory_text, "<p>If you have forgotten your password, you can request a password reset:</p>"
|
|
40
38
|
auth_value_method :reset_password_skip_resend_email_within, 300
|
|
39
|
+
translatable_method :reset_password_request_link_text, "Forgot Password?"
|
|
41
40
|
session_key :reset_password_session_key, :reset_password_key
|
|
42
41
|
|
|
43
|
-
auth_value_methods :reset_password_request_link
|
|
44
|
-
|
|
45
42
|
auth_methods(
|
|
46
43
|
:create_reset_password_key,
|
|
47
44
|
:create_reset_password_email,
|
|
@@ -69,7 +66,15 @@ module Rodauth
|
|
|
69
66
|
end
|
|
70
67
|
|
|
71
68
|
r.post do
|
|
72
|
-
|
|
69
|
+
catch_error do
|
|
70
|
+
unless account_from_login(param(login_param))
|
|
71
|
+
throw_error_status(no_matching_login_error_status, login_param, no_matching_login_message)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
unless open_account?
|
|
75
|
+
throw_error_status(unopen_account_error_status, login_param, unverified_account_message)
|
|
76
|
+
end
|
|
77
|
+
|
|
73
78
|
if reset_password_email_recently_sent?
|
|
74
79
|
set_redirect_error_flash reset_password_email_recently_sent_error_flash
|
|
75
80
|
redirect reset_password_email_recently_sent_redirect
|
|
@@ -84,12 +89,11 @@ module Rodauth
|
|
|
84
89
|
end
|
|
85
90
|
|
|
86
91
|
set_notice_flash reset_password_email_sent_notice_flash
|
|
87
|
-
|
|
88
|
-
set_redirect_error_status(no_matching_login_error_status)
|
|
89
|
-
set_redirect_error_flash reset_password_request_error_flash
|
|
92
|
+
redirect reset_password_email_sent_redirect
|
|
90
93
|
end
|
|
91
94
|
|
|
92
|
-
|
|
95
|
+
set_error_flash reset_password_request_error_flash
|
|
96
|
+
reset_password_request_view
|
|
93
97
|
end
|
|
94
98
|
end
|
|
95
99
|
|
|
@@ -99,7 +103,7 @@ module Rodauth
|
|
|
99
103
|
|
|
100
104
|
r.get do
|
|
101
105
|
if key = param_or_nil(reset_password_key_param)
|
|
102
|
-
|
|
106
|
+
set_session_value(reset_password_session_key, key)
|
|
103
107
|
redirect(r.path)
|
|
104
108
|
end
|
|
105
109
|
|
|
@@ -107,7 +111,7 @@ module Rodauth
|
|
|
107
111
|
if account_from_reset_password_key(key)
|
|
108
112
|
reset_password_view
|
|
109
113
|
else
|
|
110
|
-
|
|
114
|
+
remove_session_value(reset_password_session_key)
|
|
111
115
|
set_redirect_error_flash no_matching_reset_password_key_error_flash
|
|
112
116
|
redirect require_login_redirect
|
|
113
117
|
end
|
|
@@ -144,10 +148,10 @@ module Rodauth
|
|
|
144
148
|
end
|
|
145
149
|
|
|
146
150
|
if reset_password_autologin?
|
|
147
|
-
|
|
151
|
+
autologin_session('reset_password')
|
|
148
152
|
end
|
|
149
153
|
|
|
150
|
-
|
|
154
|
+
remove_session_value(reset_password_session_key)
|
|
151
155
|
set_notice_flash reset_password_notice_flash
|
|
152
156
|
redirect reset_password_redirect
|
|
153
157
|
end
|
|
@@ -179,7 +183,7 @@ module Rodauth
|
|
|
179
183
|
end
|
|
180
184
|
|
|
181
185
|
def send_reset_password_email
|
|
182
|
-
create_reset_password_email
|
|
186
|
+
send_email(create_reset_password_email)
|
|
183
187
|
end
|
|
184
188
|
|
|
185
189
|
def reset_password_email_link
|
|
@@ -192,14 +196,6 @@ module Rodauth
|
|
|
192
196
|
ds.get(reset_password_key_column)
|
|
193
197
|
end
|
|
194
198
|
|
|
195
|
-
def login_form_footer
|
|
196
|
-
super + reset_password_request_link
|
|
197
|
-
end
|
|
198
|
-
|
|
199
|
-
def reset_password_request_link
|
|
200
|
-
"<p><a href=\"#{prefix}/#{reset_password_request_route}\">Forgot Password?</a></p>"
|
|
201
|
-
end
|
|
202
|
-
|
|
203
199
|
def set_reset_password_email_last_sent
|
|
204
200
|
password_reset_ds.update(reset_password_email_last_sent_column=>Sequel::CURRENT_TIMESTAMP) if reset_password_email_last_sent_column
|
|
205
201
|
end
|
|
@@ -214,6 +210,10 @@ module Rodauth
|
|
|
214
210
|
|
|
215
211
|
private
|
|
216
212
|
|
|
213
|
+
def _login_form_footer_links
|
|
214
|
+
super << [20, reset_password_request_path, reset_password_request_link_text]
|
|
215
|
+
end
|
|
216
|
+
|
|
217
217
|
def reset_password_email_recently_sent?
|
|
218
218
|
(email_last_sent = get_reset_password_email_last_sent) && (Time.now - email_last_sent < reset_password_skip_resend_email_within)
|
|
219
219
|
end
|
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
module Rodauth
|
|
4
4
|
Feature.define(:session_expiration, :SessionExpiration) do
|
|
5
|
-
error_flash "This session has expired, please login again
|
|
5
|
+
error_flash "This session has expired, please login again"
|
|
6
|
+
redirect{require_login_redirect}
|
|
6
7
|
|
|
7
8
|
auth_value_method :max_session_lifetime, 86400
|
|
8
9
|
session_key :session_created_session_key, :session_created_at
|
|
10
|
+
auth_value_method :session_expiration_error_status, 401
|
|
9
11
|
auth_value_method :session_expiration_default, true
|
|
10
12
|
auth_value_method :session_inactivity_timeout, 1800
|
|
11
13
|
session_key :session_last_activity_session_key, :last_session_activity_at
|
|
12
14
|
|
|
13
|
-
auth_value_methods :session_expiration_redirect
|
|
14
|
-
|
|
15
15
|
def check_session_expiration
|
|
16
16
|
return unless logged_in?
|
|
17
17
|
|
|
@@ -37,19 +37,16 @@ module Rodauth
|
|
|
37
37
|
|
|
38
38
|
def expire_session
|
|
39
39
|
clear_session
|
|
40
|
+
set_redirect_error_status session_expiration_error_status
|
|
40
41
|
set_redirect_error_flash session_expiration_error_flash
|
|
41
42
|
redirect session_expiration_redirect
|
|
42
43
|
end
|
|
43
44
|
|
|
44
|
-
def session_expiration_redirect
|
|
45
|
-
require_login_redirect
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
private
|
|
49
|
-
|
|
50
45
|
def update_session
|
|
51
46
|
super
|
|
52
|
-
|
|
47
|
+
t = Time.now.to_i
|
|
48
|
+
set_session_value(session_last_activity_session_key, t)
|
|
49
|
+
set_session_value(session_created_session_key, t)
|
|
53
50
|
end
|
|
54
51
|
end
|
|
55
52
|
end
|
|
@@ -6,6 +6,7 @@ module Rodauth
|
|
|
6
6
|
redirect
|
|
7
7
|
|
|
8
8
|
auth_value_method :allow_raw_single_session_key?, false
|
|
9
|
+
auth_value_method :inactive_session_error_status, 401
|
|
9
10
|
auth_value_method :single_session_id_column, :id
|
|
10
11
|
auth_value_method :single_session_key_column, :key
|
|
11
12
|
session_key :single_session_session_key, :single_session_key
|
|
@@ -55,6 +56,7 @@ module Rodauth
|
|
|
55
56
|
|
|
56
57
|
def no_longer_active_session
|
|
57
58
|
clear_session
|
|
59
|
+
set_redirect_error_status inactive_session_error_status
|
|
58
60
|
set_redirect_error_flash single_session_error_flash
|
|
59
61
|
redirect single_session_redirect
|
|
60
62
|
end
|
|
@@ -70,6 +72,11 @@ module Rodauth
|
|
|
70
72
|
end
|
|
71
73
|
end
|
|
72
74
|
|
|
75
|
+
def update_session
|
|
76
|
+
super
|
|
77
|
+
update_single_session_key
|
|
78
|
+
end
|
|
79
|
+
|
|
73
80
|
private
|
|
74
81
|
|
|
75
82
|
def after_close_account
|
|
@@ -78,7 +85,7 @@ module Rodauth
|
|
|
78
85
|
end
|
|
79
86
|
|
|
80
87
|
def before_logout
|
|
81
|
-
reset_single_session_key
|
|
88
|
+
reset_single_session_key
|
|
82
89
|
super if defined?(super)
|
|
83
90
|
end
|
|
84
91
|
|
|
@@ -87,11 +94,6 @@ module Rodauth
|
|
|
87
94
|
set_session_value(single_session_session_key, data)
|
|
88
95
|
end
|
|
89
96
|
|
|
90
|
-
def update_session
|
|
91
|
-
super
|
|
92
|
-
update_single_session_key
|
|
93
|
-
end
|
|
94
|
-
|
|
95
97
|
def single_session_ds
|
|
96
98
|
db[single_session_table].
|
|
97
99
|
where(single_session_id_column=>session_value)
|