rodauth 2.21.0 → 2.24.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 +36 -442
- data/README.rdoc +11 -3
- data/doc/base.rdoc +1 -0
- data/doc/guides/internals.rdoc +11 -0
- data/doc/guides/paths.rdoc +3 -0
- data/doc/login_password_requirements_base.rdoc +1 -1
- data/doc/otp.rdoc +1 -0
- data/doc/recovery_codes.rdoc +1 -0
- data/doc/release_notes/2.22.0.txt +43 -0
- data/doc/release_notes/2.23.0.txt +15 -0
- data/doc/release_notes/2.24.0.txt +15 -0
- data/doc/reset_password.rdoc +16 -16
- data/doc/reset_password_notify.rdoc +17 -0
- data/lib/rodauth/features/active_sessions.rb +3 -1
- data/lib/rodauth/features/base.rb +20 -2
- data/lib/rodauth/features/change_password_notify.rb +2 -22
- data/lib/rodauth/features/email_auth.rb +1 -16
- data/lib/rodauth/features/http_basic_auth.rb +1 -1
- data/lib/rodauth/features/internal_request.rb +1 -1
- data/lib/rodauth/features/json.rb +2 -4
- data/lib/rodauth/features/jwt_cors.rb +1 -1
- data/lib/rodauth/features/lockout.rb +2 -18
- data/lib/rodauth/features/otp.rb +8 -2
- data/lib/rodauth/features/recovery_codes.rb +6 -1
- data/lib/rodauth/features/remember.rb +1 -1
- data/lib/rodauth/features/reset_password.rb +5 -20
- data/lib/rodauth/features/reset_password_notify.rb +16 -0
- data/lib/rodauth/features/sms_codes.rb +2 -2
- data/lib/rodauth/features/verify_account.rb +3 -20
- data/lib/rodauth/version.rb +1 -1
- data/lib/rodauth.rb +27 -0
- data/templates/reset-password-notify-email.str +2 -0
- metadata +15 -5
@@ -0,0 +1,15 @@
|
|
1
|
+
= New Features
|
2
|
+
|
3
|
+
* rodauth.otp_available? has been added for checking whether the
|
4
|
+
account is allowed to authenticate with OTP. It returns true
|
5
|
+
when the account has setup OTP and OTP use is not locked out.
|
6
|
+
|
7
|
+
* rodauth.recovery_codes_available? has been added for checking
|
8
|
+
whether the account is allowed to authenticate using a recovery
|
9
|
+
code. It returns true when there are any available recovery
|
10
|
+
codes for the account to use.
|
11
|
+
|
12
|
+
= Other Improvements
|
13
|
+
|
14
|
+
* The otp feature no longer includes the <?xml> tag for svg images,
|
15
|
+
since that results in invalid HTML.
|
data/doc/reset_password.rdoc
CHANGED
@@ -14,12 +14,12 @@ reset_password_autologin? :: Whether to autologin the user after successfully re
|
|
14
14
|
reset_password_button :: The text to use for the reset password button.
|
15
15
|
reset_password_deadline_column :: The column name in the +reset_password_table+ storing the deadline after which the token will be ignored.
|
16
16
|
reset_password_deadline_interval :: The amount of time for which to allow users to reset their passwords, 1 day by default. Only used if +set_deadline_values?+ is true.
|
17
|
-
reset_password_email_last_sent_column :: The email last sent column in the +reset_password_table+. Set to nil to always send a reset password email when requested.
|
18
|
-
reset_password_email_recently_sent_error_flash :: The flash error to show if not sending reset password email because one has been sent recently.
|
19
|
-
reset_password_email_recently_sent_redirect :: Where to redirect if not sending reset password email because one has been sent recently.
|
20
|
-
reset_password_email_sent_notice_flash :: The flash notice to show after a reset password email has been sent.
|
21
|
-
reset_password_email_sent_redirect :: Where to redirect after sending a reset password email.
|
22
|
-
reset_password_email_subject :: The subject to use for reset password
|
17
|
+
reset_password_email_last_sent_column :: The email last sent column in the +reset_password_table+. Set to nil to always send a reset password request email when requested.
|
18
|
+
reset_password_email_recently_sent_error_flash :: The flash error to show if not sending reset password request email because one has been sent recently.
|
19
|
+
reset_password_email_recently_sent_redirect :: Where to redirect if not sending reset password request email because one has been sent recently.
|
20
|
+
reset_password_email_sent_notice_flash :: The flash notice to show after a reset password request email has been sent.
|
21
|
+
reset_password_email_sent_redirect :: Where to redirect after sending a reset password request email.
|
22
|
+
reset_password_email_subject :: The subject to use for the reset password request email.
|
23
23
|
reset_password_error_flash :: The flash error to show after resetting a password.
|
24
24
|
reset_password_explanatory_text :: The text to display above the button to request a password reset.
|
25
25
|
reset_password_id_column :: The id column in the +reset_password_table+, should be a foreign key referencing the accounts table.
|
@@ -30,35 +30,35 @@ reset_password_page_title :: The page title to use on the reset password form.
|
|
30
30
|
reset_password_redirect :: Where to redirect after resetting a password.
|
31
31
|
reset_password_request_additional_form_tags :: HTML fragment containing additional form tags to use on the reset password request form.
|
32
32
|
reset_password_request_button :: The text to use for the reset password request button.
|
33
|
-
reset_password_request_error_flash :: The flash error to show if not able to send a reset password email.
|
33
|
+
reset_password_request_error_flash :: The flash error to show if not able to send a reset password request email.
|
34
34
|
reset_password_request_link_text :: The text to use for a link to the page to request a password reset.
|
35
35
|
reset_password_request_page_title :: The page title to use on the reset password request form.
|
36
36
|
reset_password_request_route :: The route to the reset password request action. Defaults to +reset-password-request+.
|
37
37
|
reset_password_route :: The route to the reset password action. Defaults to +reset-password+.
|
38
38
|
reset_password_session_key :: The key in the session to hold the reset password key temporarily.
|
39
|
-
reset_password_skip_resend_email_within :: The number of seconds before sending another reset password email, if +reset_password_email_last_sent_column+ is set.
|
39
|
+
reset_password_skip_resend_email_within :: The number of seconds before sending another reset password request email, if +reset_password_email_last_sent_column+ is set.
|
40
40
|
reset_password_table :: The name of the reset password keys table.
|
41
41
|
|
42
42
|
== Auth Methods
|
43
43
|
|
44
44
|
account_from_reset_password_key(key) :: Retrieve the account using the given reset password key, or return nil if no account matches.
|
45
45
|
after_reset_password :: Run arbitrary code after successfully resetting a password.
|
46
|
-
after_reset_password_request :: Run arbitrary code after sending the reset password email.
|
46
|
+
after_reset_password_request :: Run arbitrary code after sending the reset password request email.
|
47
47
|
before_reset_password :: Run arbitrary code before resetting a password.
|
48
|
-
before_reset_password_request :: Run arbitrary code before sending the reset password email.
|
48
|
+
before_reset_password_request :: Run arbitrary code before sending the reset password request email.
|
49
49
|
before_reset_password_request_route :: Run arbitrary code before handling a reset password request route.
|
50
50
|
before_reset_password_route :: Run arbitrary code before handling a reset password route.
|
51
|
-
create_reset_password_email :: A Mail::Message for the reset password email.
|
51
|
+
create_reset_password_email :: A Mail::Message for the reset password request email.
|
52
52
|
create_reset_password_key :: Add the reset password key data to the database.
|
53
|
-
get_reset_password_email_last_sent :: Get the last time a reset password email is sent, or nil if there is no last sent time.
|
53
|
+
get_reset_password_email_last_sent :: Get the last time a reset password request email is sent, or nil if there is no last sent time.
|
54
54
|
get_reset_password_key(id) :: Get the password reset key for the given account id from the database.
|
55
55
|
login_failed_reset_password_request_form :: The HTML to use for a form to request a password reset, shown on the login page after the user tries to login with an invalid password.
|
56
56
|
remove_reset_password_key :: Remove the reset password key for the current account, run after successful password reset.
|
57
|
-
reset_password_email_body :: The body to use for the reset password email.
|
58
|
-
reset_password_email_link :: The link to the reset password form in the reset password email.
|
57
|
+
reset_password_email_body :: The body to use for the reset password request email.
|
58
|
+
reset_password_email_link :: The link to the reset password form in the reset password request email.
|
59
59
|
reset_password_key_insert_hash :: The hash to insert into the +reset_password_table+.
|
60
60
|
reset_password_key_value :: The reset password key for the current account.
|
61
61
|
reset_password_request_view :: The HTML to use for the reset password request form.
|
62
62
|
reset_password_view :: The HTML to use for the reset password form.
|
63
|
-
send_reset_password_email :: Send the reset password email.
|
64
|
-
set_reset_password_email_last_sent :: Set the last time a reset password email is sent.
|
63
|
+
send_reset_password_email :: Send the reset password request email.
|
64
|
+
set_reset_password_email_last_sent :: Set the last time a reset password request email is sent.
|
@@ -0,0 +1,17 @@
|
|
1
|
+
= Documentation for Reset Password Notify Feature
|
2
|
+
|
3
|
+
The reset password notify feature emails the user after the user has
|
4
|
+
reset their password. The user has already been sent a reset password
|
5
|
+
email by this point, so they know a password reset was requested, but
|
6
|
+
this feature allows for confirming that the password reset process
|
7
|
+
was completed. Depends on the reset_password feature.
|
8
|
+
|
9
|
+
== Auth Value Methods
|
10
|
+
|
11
|
+
reset_password_notify_email_subject :: The subject to use for the reset password notify email.
|
12
|
+
reset_password_notify_email_body :: The body to use for the reset password notify email.
|
13
|
+
|
14
|
+
== Auth Methods
|
15
|
+
|
16
|
+
create_reset_password_notify_email :: A Mail::Message for the reset password notify email.
|
17
|
+
send_reset_password_notify_email :: Send the reset password notify email.
|
@@ -81,7 +81,9 @@ module Rodauth
|
|
81
81
|
end
|
82
82
|
|
83
83
|
def remove_current_session
|
84
|
-
|
84
|
+
if session_id = session[session_id_session_key]
|
85
|
+
active_sessions_ds.where(active_sessions_session_id_column=>compute_hmac(session_id)).delete
|
86
|
+
end
|
85
87
|
end
|
86
88
|
|
87
89
|
def remove_all_active_sessions
|
@@ -1,5 +1,8 @@
|
|
1
1
|
# frozen-string-literal: true
|
2
2
|
|
3
|
+
require 'rack/request'
|
4
|
+
require 'rack/utils'
|
5
|
+
|
3
6
|
module Rodauth
|
4
7
|
Feature.define(:base, :Base) do
|
5
8
|
after 'login'
|
@@ -91,6 +94,7 @@ module Rodauth
|
|
91
94
|
:inputmode_for_field?,
|
92
95
|
:logged_in?,
|
93
96
|
:login_required,
|
97
|
+
:null_byte_parameter_value,
|
94
98
|
:open_account?,
|
95
99
|
:password_match?,
|
96
100
|
:random_key,
|
@@ -446,7 +450,16 @@ module Rodauth
|
|
446
450
|
# parameter with that name.
|
447
451
|
def param_or_nil(key)
|
448
452
|
value = raw_param(key)
|
449
|
-
|
453
|
+
unless value.nil?
|
454
|
+
value = value.to_s
|
455
|
+
value = null_byte_parameter_value(key, value) if value.include?("\0")
|
456
|
+
end
|
457
|
+
value
|
458
|
+
end
|
459
|
+
|
460
|
+
# Return nil by default for values with null bytes
|
461
|
+
def null_byte_parameter_value(key, value)
|
462
|
+
nil
|
450
463
|
end
|
451
464
|
|
452
465
|
def raw_param(key)
|
@@ -501,6 +514,11 @@ module Rodauth
|
|
501
514
|
request.redirect(path)
|
502
515
|
end
|
503
516
|
|
517
|
+
def return_response(body=nil)
|
518
|
+
response.write(body) if body
|
519
|
+
request.halt
|
520
|
+
end
|
521
|
+
|
504
522
|
def route_path(route, opts={})
|
505
523
|
path = "#{prefix}/#{route}"
|
506
524
|
path += "?#{Rack::Utils.build_nested_query(opts)}" unless opts.empty?
|
@@ -756,7 +774,7 @@ module Rodauth
|
|
756
774
|
num = ds.update(values)
|
757
775
|
if num == 1
|
758
776
|
values.each do |k, v|
|
759
|
-
|
777
|
+
hash[k] = Sequel::CURRENT_TIMESTAMP == v ? Time.now : v
|
760
778
|
end
|
761
779
|
end
|
762
780
|
num
|
@@ -3,31 +3,11 @@
|
|
3
3
|
module Rodauth
|
4
4
|
Feature.define(:change_password_notify, :ChangePasswordNotify) do
|
5
5
|
depends :change_password, :email_base
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
auth_value_methods(
|
10
|
-
:password_changed_email_body
|
11
|
-
)
|
12
|
-
auth_methods(
|
13
|
-
:create_password_changed_email,
|
14
|
-
:send_password_changed_email
|
15
|
-
)
|
6
|
+
loaded_templates %w'password-changed-email'
|
7
|
+
email :password_changed, 'Password Changed', :translatable=>true
|
16
8
|
|
17
9
|
private
|
18
10
|
|
19
|
-
def send_password_changed_email
|
20
|
-
send_email(create_password_changed_email)
|
21
|
-
end
|
22
|
-
|
23
|
-
def create_password_changed_email
|
24
|
-
create_email(password_changed_email_subject, password_changed_email_body)
|
25
|
-
end
|
26
|
-
|
27
|
-
def password_changed_email_body
|
28
|
-
render('password-changed-email')
|
29
|
-
end
|
30
|
-
|
31
11
|
def after_change_password
|
32
12
|
super
|
33
13
|
send_password_changed_email
|
@@ -19,10 +19,10 @@ module Rodauth
|
|
19
19
|
button 'Send Login Link Via Email', 'email_auth_request'
|
20
20
|
redirect(:email_auth_email_sent){default_post_email_redirect}
|
21
21
|
redirect(:email_auth_email_recently_sent){default_post_email_redirect}
|
22
|
+
email :email_auth, 'Login Link'
|
22
23
|
|
23
24
|
auth_value_method :email_auth_deadline_column, :deadline
|
24
25
|
auth_value_method :email_auth_deadline_interval, {:days=>1}.freeze
|
25
|
-
translatable_method :email_auth_email_subject, 'Login Link'
|
26
26
|
auth_value_method :email_auth_id_column, :id
|
27
27
|
auth_value_method :email_auth_key_column, :key
|
28
28
|
auth_value_method :email_auth_key_param, 'key'
|
@@ -33,9 +33,7 @@ module Rodauth
|
|
33
33
|
session_key :email_auth_session_key, :email_auth_key
|
34
34
|
|
35
35
|
auth_methods(
|
36
|
-
:create_email_auth_email,
|
37
36
|
:create_email_auth_key,
|
38
|
-
:email_auth_email_body,
|
39
37
|
:email_auth_email_link,
|
40
38
|
:email_auth_key_insert_hash,
|
41
39
|
:email_auth_key_value,
|
@@ -43,7 +41,6 @@ module Rodauth
|
|
43
41
|
:get_email_auth_key,
|
44
42
|
:get_email_auth_email_last_sent,
|
45
43
|
:remove_email_auth_key,
|
46
|
-
:send_email_auth_email,
|
47
44
|
:set_email_auth_email_last_sent
|
48
45
|
)
|
49
46
|
|
@@ -137,10 +134,6 @@ module Rodauth
|
|
137
134
|
@account = _account_from_email_auth_key(key)
|
138
135
|
end
|
139
136
|
|
140
|
-
def send_email_auth_email
|
141
|
-
send_email(create_email_auth_email)
|
142
|
-
end
|
143
|
-
|
144
137
|
def email_auth_email_link
|
145
138
|
token_link(email_auth_route, email_auth_key_param, email_auth_key_value)
|
146
139
|
end
|
@@ -233,14 +226,6 @@ module Rodauth
|
|
233
226
|
@email_auth_key_value = random_key
|
234
227
|
end
|
235
228
|
|
236
|
-
def create_email_auth_email
|
237
|
-
create_email(email_auth_email_subject, email_auth_email_body)
|
238
|
-
end
|
239
|
-
|
240
|
-
def email_auth_email_body
|
241
|
-
render('email-auth-email')
|
242
|
-
end
|
243
|
-
|
244
229
|
def use_date_arithmetic?
|
245
230
|
super || db.database_type == :mysql
|
246
231
|
end
|
@@ -156,8 +156,7 @@ module Rodauth
|
|
156
156
|
end
|
157
157
|
elsif only_json?
|
158
158
|
response.status = json_response_error_status
|
159
|
-
|
160
|
-
request.halt
|
159
|
+
return_response non_json_request_error_message
|
161
160
|
end
|
162
161
|
|
163
162
|
super
|
@@ -175,8 +174,7 @@ module Rodauth
|
|
175
174
|
def _return_json_response
|
176
175
|
response.status ||= json_response_error_status if json_response[json_response_error_key]
|
177
176
|
response['Content-Type'] ||= json_response_content_type
|
178
|
-
|
179
|
-
request.halt
|
177
|
+
return_response _json_response_body(json_response)
|
180
178
|
end
|
181
179
|
|
182
180
|
def include_success_messages?
|
@@ -41,7 +41,7 @@ module Rodauth
|
|
41
41
|
response['Access-Control-Allow-Headers'] = jwt_cors_allow_headers
|
42
42
|
response['Access-Control-Max-Age'] = jwt_cors_max_age.to_s
|
43
43
|
response.status = 204
|
44
|
-
|
44
|
+
return_response
|
45
45
|
end
|
46
46
|
|
47
47
|
response['Access-Control-Expose-Headers'] = jwt_cors_expose_headers
|
@@ -25,6 +25,7 @@ module Rodauth
|
|
25
25
|
redirect :unlock_account
|
26
26
|
redirect(:unlock_account_request){default_post_email_redirect}
|
27
27
|
redirect(:unlock_account_email_recently_sent){default_post_email_redirect}
|
28
|
+
email :unlock_account, 'Unlock Account'
|
28
29
|
|
29
30
|
auth_value_method :unlock_account_autologin?, true
|
30
31
|
auth_value_method :max_invalid_logins, 100
|
@@ -37,7 +38,6 @@ module Rodauth
|
|
37
38
|
auth_value_method :account_lockouts_email_last_sent_column, :email_last_sent
|
38
39
|
auth_value_method :account_lockouts_deadline_column, :deadline
|
39
40
|
auth_value_method :account_lockouts_deadline_interval, {:days=>1}.freeze
|
40
|
-
translatable_method :unlock_account_email_subject, 'Unlock Account'
|
41
41
|
translatable_method :unlock_account_explanatory_text, '<p>This account is currently locked out. You can unlock the account:</p>'
|
42
42
|
translatable_method :unlock_account_request_explanatory_text, '<p>This account is currently locked out. You can request that the account be unlocked:</p>'
|
43
43
|
auth_value_method :unlock_account_key_param, 'key'
|
@@ -47,15 +47,12 @@ module Rodauth
|
|
47
47
|
|
48
48
|
auth_methods(
|
49
49
|
:clear_invalid_login_attempts,
|
50
|
-
:create_unlock_account_email,
|
51
50
|
:generate_unlock_account_key,
|
52
51
|
:get_unlock_account_key,
|
53
52
|
:get_unlock_account_email_last_sent,
|
54
53
|
:invalid_login_attempted,
|
55
54
|
:locked_out?,
|
56
|
-
:send_unlock_account_email,
|
57
55
|
:set_unlock_account_email_last_sent,
|
58
|
-
:unlock_account_email_body,
|
59
56
|
:unlock_account_email_link,
|
60
57
|
:unlock_account,
|
61
58
|
:unlock_account_key
|
@@ -226,10 +223,6 @@ module Rodauth
|
|
226
223
|
@account = _account_from_unlock_key(key)
|
227
224
|
end
|
228
225
|
|
229
|
-
def send_unlock_account_email
|
230
|
-
send_email(create_unlock_account_email)
|
231
|
-
end
|
232
|
-
|
233
226
|
def unlock_account_email_link
|
234
227
|
token_link(unlock_account_route, unlock_account_key_param, unlock_account_key_value)
|
235
228
|
end
|
@@ -284,16 +277,7 @@ module Rodauth
|
|
284
277
|
def show_lockout_page
|
285
278
|
set_response_error_reason_status(:account_locked_out, lockout_error_status)
|
286
279
|
set_error_flash login_lockout_error_flash
|
287
|
-
|
288
|
-
request.halt
|
289
|
-
end
|
290
|
-
|
291
|
-
def create_unlock_account_email
|
292
|
-
create_email(unlock_account_email_subject, unlock_account_email_body)
|
293
|
-
end
|
294
|
-
|
295
|
-
def unlock_account_email_body
|
296
|
-
render('unlock-account-email')
|
280
|
+
return_response unlock_account_request_view
|
297
281
|
end
|
298
282
|
|
299
283
|
def unlock_account_email_recently_sent?
|
data/lib/rodauth/features/otp.rb
CHANGED
@@ -76,6 +76,7 @@ module Rodauth
|
|
76
76
|
)
|
77
77
|
|
78
78
|
auth_methods(
|
79
|
+
:otp_available?,
|
79
80
|
:otp_exists?,
|
80
81
|
:otp_last_use,
|
81
82
|
:otp_locked_out?,
|
@@ -238,6 +239,10 @@ module Rodauth
|
|
238
239
|
end
|
239
240
|
end
|
240
241
|
|
242
|
+
def otp_available?
|
243
|
+
otp_exists? && !otp_locked_out?
|
244
|
+
end
|
245
|
+
|
241
246
|
def otp_exists?
|
242
247
|
!otp_key.nil?
|
243
248
|
end
|
@@ -303,7 +308,8 @@ module Rodauth
|
|
303
308
|
end
|
304
309
|
|
305
310
|
def otp_qr_code
|
306
|
-
RQRCode::QRCode.new(otp_provisioning_uri).as_svg(:module_size=>8, :viewbox=>true)
|
311
|
+
svg = RQRCode::QRCode.new(otp_provisioning_uri).as_svg(:module_size=>8, :viewbox=>true, :use_path=>true)
|
312
|
+
svg.sub(/\A<\?xml version="1\.0" standalone="yes"\?>/, '')
|
307
313
|
end
|
308
314
|
|
309
315
|
def otp_user_key
|
@@ -328,7 +334,7 @@ module Rodauth
|
|
328
334
|
|
329
335
|
def _two_factor_auth_links
|
330
336
|
links = super
|
331
|
-
links << [20, otp_auth_path, otp_auth_link_text] if
|
337
|
+
links << [20, otp_auth_path, otp_auth_link_text] if otp_available?
|
332
338
|
links
|
333
339
|
end
|
334
340
|
|
@@ -57,6 +57,7 @@ module Rodauth
|
|
57
57
|
:can_add_recovery_codes?,
|
58
58
|
:new_recovery_code,
|
59
59
|
:recovery_code_match?,
|
60
|
+
:recovery_codes_available?,
|
60
61
|
)
|
61
62
|
|
62
63
|
internal_request_method :recovery_codes
|
@@ -192,6 +193,10 @@ module Rodauth
|
|
192
193
|
end
|
193
194
|
end
|
194
195
|
|
196
|
+
def recovery_codes_available?
|
197
|
+
!recovery_codes_ds.empty?
|
198
|
+
end
|
199
|
+
|
195
200
|
def possible_authentication_methods
|
196
201
|
methods = super
|
197
202
|
methods << 'recovery_code' unless recovery_codes_ds.empty?
|
@@ -202,7 +207,7 @@ module Rodauth
|
|
202
207
|
|
203
208
|
def _two_factor_auth_links
|
204
209
|
links = super
|
205
|
-
links << [40, recovery_auth_path, recovery_auth_link_text]
|
210
|
+
links << [40, recovery_auth_path, recovery_auth_link_text] if recovery_codes_available?
|
206
211
|
links
|
207
212
|
end
|
208
213
|
|
@@ -144,7 +144,7 @@ module Rodauth
|
|
144
144
|
opts[:value] = "#{account_id}_#{convert_token_key(remember_key_value)}"
|
145
145
|
opts[:expires] = convert_timestamp(active_remember_key_ds.get(remember_deadline_column))
|
146
146
|
opts[:path] = "/" unless opts.key?(:path)
|
147
|
-
opts[:httponly] = true unless opts.key?(:httponly)
|
147
|
+
opts[:httponly] = true unless opts.key?(:httponly) || opts.key?(:http_only)
|
148
148
|
opts[:secure] = true unless opts.key?(:secure) || !request.ssl?
|
149
149
|
::Rack::Utils.set_cookie_header!(response.headers, remember_cookie_key, opts)
|
150
150
|
end
|
@@ -24,10 +24,10 @@ module Rodauth
|
|
24
24
|
redirect
|
25
25
|
redirect(:reset_password_email_sent){default_post_email_redirect}
|
26
26
|
redirect(:reset_password_email_recently_sent){default_post_email_redirect}
|
27
|
+
email :reset_password, 'Reset Password'
|
27
28
|
|
28
29
|
auth_value_method :reset_password_deadline_column, :deadline
|
29
30
|
auth_value_method :reset_password_deadline_interval, {:days=>1}.freeze
|
30
|
-
translatable_method :reset_password_email_subject, 'Reset Password'
|
31
31
|
auth_value_method :reset_password_key_param, 'key'
|
32
32
|
auth_value_method :reset_password_autologin?, false
|
33
33
|
auth_value_method :reset_password_table, :account_password_reset_keys
|
@@ -41,16 +41,13 @@ module Rodauth
|
|
41
41
|
|
42
42
|
auth_methods(
|
43
43
|
:create_reset_password_key,
|
44
|
-
:create_reset_password_email,
|
45
44
|
:get_reset_password_key,
|
46
45
|
:get_reset_password_email_last_sent,
|
47
46
|
:login_failed_reset_password_request_form,
|
48
47
|
:remove_reset_password_key,
|
49
|
-
:reset_password_email_body,
|
50
48
|
:reset_password_email_link,
|
51
49
|
:reset_password_key_insert_hash,
|
52
50
|
:reset_password_key_value,
|
53
|
-
:send_reset_password_email,
|
54
51
|
:set_reset_password_email_last_sent
|
55
52
|
)
|
56
53
|
auth_private_methods(
|
@@ -133,6 +130,10 @@ module Rodauth
|
|
133
130
|
|
134
131
|
password = param(password_param)
|
135
132
|
catch_error do
|
133
|
+
unless password_meets_requirements?(password)
|
134
|
+
throw_error_status(invalid_field_error_status, password_param, password_does_not_meet_requirements_message)
|
135
|
+
end
|
136
|
+
|
136
137
|
if password_match?(password)
|
137
138
|
throw_error_reason(:same_as_existing_password, invalid_field_error_status, password_param, same_as_existing_password_message)
|
138
139
|
end
|
@@ -141,10 +142,6 @@ module Rodauth
|
|
141
142
|
throw_error_reason(:passwords_do_not_match, unmatched_field_error_status, password_param, passwords_do_not_match_message)
|
142
143
|
end
|
143
144
|
|
144
|
-
unless password_meets_requirements?(password)
|
145
|
-
throw_error_status(invalid_field_error_status, password_param, password_does_not_meet_requirements_message)
|
146
|
-
end
|
147
|
-
|
148
145
|
transaction do
|
149
146
|
before_reset_password
|
150
147
|
set_password(password)
|
@@ -187,10 +184,6 @@ module Rodauth
|
|
187
184
|
@account = _account_from_reset_password_key(key)
|
188
185
|
end
|
189
186
|
|
190
|
-
def send_reset_password_email
|
191
|
-
send_email(create_reset_password_email)
|
192
|
-
end
|
193
|
-
|
194
187
|
def reset_password_email_link
|
195
188
|
token_link(reset_password_route, reset_password_key_param, reset_password_key_value)
|
196
189
|
end
|
@@ -241,18 +234,10 @@ module Rodauth
|
|
241
234
|
@reset_password_key_value = random_key
|
242
235
|
end
|
243
236
|
|
244
|
-
def create_reset_password_email
|
245
|
-
create_email(reset_password_email_subject, reset_password_email_body)
|
246
|
-
end
|
247
|
-
|
248
237
|
def login_failed_reset_password_request_form
|
249
238
|
render("reset-password-request")
|
250
239
|
end
|
251
240
|
|
252
|
-
def reset_password_email_body
|
253
|
-
render('reset-password-email')
|
254
|
-
end
|
255
|
-
|
256
241
|
def use_date_arithmetic?
|
257
242
|
super || db.database_type == :mysql
|
258
243
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
3
|
+
module Rodauth
|
4
|
+
Feature.define(:reset_password_notify, :ResetPasswordNotify) do
|
5
|
+
depends :reset_password
|
6
|
+
loaded_templates %w'reset-password-notify-email'
|
7
|
+
email :reset_password_notify, 'Password Reset Completed', :translatable=>true
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def after_reset_password
|
12
|
+
super
|
13
|
+
send_reset_password_notify_email
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -430,7 +430,7 @@ module Rodauth
|
|
430
430
|
end
|
431
431
|
|
432
432
|
def sms_available?
|
433
|
-
|
433
|
+
sms_setup? && !sms_locked_out?
|
434
434
|
end
|
435
435
|
|
436
436
|
def sms_locked_out?
|
@@ -468,7 +468,7 @@ module Rodauth
|
|
468
468
|
end
|
469
469
|
|
470
470
|
def _two_factor_remove_all_from_session
|
471
|
-
two_factor_remove_session('
|
471
|
+
two_factor_remove_session('sms_code')
|
472
472
|
super
|
473
473
|
end
|
474
474
|
|
@@ -26,8 +26,8 @@ module Rodauth
|
|
26
26
|
redirect
|
27
27
|
redirect(:verify_account_email_sent){default_post_email_redirect}
|
28
28
|
redirect(:verify_account_email_recently_sent){default_post_email_redirect}
|
29
|
+
email :verify_account, 'Verify Account'
|
29
30
|
|
30
|
-
translatable_method :verify_account_email_subject, 'Verify Account'
|
31
31
|
auth_value_method :verify_account_key_param, 'key'
|
32
32
|
auth_value_method :verify_account_autologin?, true
|
33
33
|
auth_value_method :verify_account_table, :account_verification_keys
|
@@ -43,14 +43,11 @@ module Rodauth
|
|
43
43
|
auth_methods(
|
44
44
|
:allow_resending_verify_account_email?,
|
45
45
|
:create_verify_account_key,
|
46
|
-
:create_verify_account_email,
|
47
46
|
:get_verify_account_key,
|
48
47
|
:get_verify_account_email_last_sent,
|
49
48
|
:remove_verify_account_key,
|
50
|
-
:send_verify_account_email,
|
51
49
|
:set_verify_account_email_last_sent,
|
52
50
|
:verify_account,
|
53
|
-
:verify_account_email_body,
|
54
51
|
:verify_account_email_link,
|
55
52
|
:verify_account_key_insert_hash,
|
56
53
|
:verify_account_key_value
|
@@ -198,8 +195,7 @@ module Rodauth
|
|
198
195
|
if account_from_login(login) && allow_resending_verify_account_email?
|
199
196
|
set_response_error_reason_status(:already_an_unverified_account_with_this_login, unopen_account_error_status)
|
200
197
|
set_error_flash attempt_to_create_unverified_account_error_flash
|
201
|
-
|
202
|
-
request.halt
|
198
|
+
return_response resend_verify_account_view
|
203
199
|
end
|
204
200
|
super
|
205
201
|
end
|
@@ -212,10 +208,6 @@ module Rodauth
|
|
212
208
|
account_unverified_status_value
|
213
209
|
end
|
214
210
|
|
215
|
-
def send_verify_account_email
|
216
|
-
send_email(create_verify_account_email)
|
217
|
-
end
|
218
|
-
|
219
211
|
def verify_account_email_link
|
220
212
|
token_link(verify_account_route, verify_account_key_param, verify_account_key_value)
|
221
213
|
end
|
@@ -275,8 +267,7 @@ module Rodauth
|
|
275
267
|
unless open_account?
|
276
268
|
set_response_error_reason_status(:unverified_account, unopen_account_error_status)
|
277
269
|
set_error_flash attempt_to_login_to_unverified_account_error_flash
|
278
|
-
|
279
|
-
request.halt
|
270
|
+
return_response resend_verify_account_view
|
280
271
|
end
|
281
272
|
super
|
282
273
|
end
|
@@ -311,14 +302,6 @@ module Rodauth
|
|
311
302
|
{verify_account_id_column=>account_id, verify_account_key_column=>verify_account_key_value}
|
312
303
|
end
|
313
304
|
|
314
|
-
def create_verify_account_email
|
315
|
-
create_email(verify_account_email_subject, verify_account_email_body)
|
316
|
-
end
|
317
|
-
|
318
|
-
def verify_account_email_body
|
319
|
-
render('verify-account-email')
|
320
|
-
end
|
321
|
-
|
322
305
|
def verify_account_ds(id=account_id)
|
323
306
|
db[verify_account_table].where(verify_account_id_column=>id)
|
324
307
|
end
|
data/lib/rodauth/version.rb
CHANGED