rodauth 2.21.0 → 2.24.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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.
@@ -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 emails.
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
- active_sessions_ds.where(active_sessions_session_id_column=>compute_hmac(session[session_id_session_key])).delete
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
- value.to_s unless value.nil?
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
- account[k] = Sequel::CURRENT_TIMESTAMP == v ? Time.now : v
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
- translatable_method :password_changed_email_subject, 'Password Changed'
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
@@ -27,7 +27,7 @@ module Rodauth
27
27
  def require_http_basic_auth
28
28
  unless http_basic_auth
29
29
  set_http_basic_auth_error_response
30
- request.halt
30
+ return_response
31
31
  end
32
32
  end
33
33
 
@@ -40,7 +40,7 @@ module Rodauth
40
40
 
41
41
  def domain
42
42
  d = super
43
- if d == INVALID_DOMAIN
43
+ if d.nil? || d == INVALID_DOMAIN
44
44
  raise InternalRequestError, "must set domain in configuration, as it cannot be determined from internal request"
45
45
  end
46
46
  d
@@ -156,8 +156,7 @@ module Rodauth
156
156
  end
157
157
  elsif only_json?
158
158
  response.status = json_response_error_status
159
- response.write non_json_request_error_message
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
- response.write(_json_response_body(json_response))
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
- request.halt(response.finish)
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
- response.write unlock_account_request_view
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?
@@ -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 otp_exists? && !otp_locked_out?
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] unless recovery_codes_ds.empty?
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
- sms && !sms_needs_confirmation? && !sms_locked_out?
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('sms_codes')
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
- response.write resend_verify_account_view
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
- response.write resend_verify_account_view
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
@@ -6,7 +6,7 @@ module Rodauth
6
6
  MAJOR = 2
7
7
 
8
8
  # The minor version of Rodauth, updated for new feature releases of Rodauth.
9
- MINOR = 21
9
+ MINOR = 24
10
10
 
11
11
  # The patch version of Rodauth, updated only for bug fixes from the last
12
12
  # feature release.