rodauth 2.12.0 → 2.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +8 -0
  3. data/doc/base.rdoc +1 -0
  4. data/doc/error_reasons.rdoc +73 -0
  5. data/doc/release_notes/2.13.0.txt +19 -0
  6. data/lib/rodauth/features/active_sessions.rb +1 -1
  7. data/lib/rodauth/features/base.rb +15 -0
  8. data/lib/rodauth/features/change_login.rb +4 -4
  9. data/lib/rodauth/features/change_password.rb +3 -3
  10. data/lib/rodauth/features/close_account.rb +1 -1
  11. data/lib/rodauth/features/confirm_password.rb +2 -2
  12. data/lib/rodauth/features/create_account.rb +4 -4
  13. data/lib/rodauth/features/disallow_common_passwords.rb +1 -1
  14. data/lib/rodauth/features/disallow_password_reuse.rb +1 -1
  15. data/lib/rodauth/features/email_auth.rb +2 -0
  16. data/lib/rodauth/features/jwt_refresh.rb +3 -1
  17. data/lib/rodauth/features/lockout.rb +4 -2
  18. data/lib/rodauth/features/login.rb +3 -3
  19. data/lib/rodauth/features/login_password_requirements_base.rb +15 -6
  20. data/lib/rodauth/features/otp.rb +7 -6
  21. data/lib/rodauth/features/password_complexity.rb +4 -4
  22. data/lib/rodauth/features/recovery_codes.rb +2 -2
  23. data/lib/rodauth/features/remember.rb +1 -1
  24. data/lib/rodauth/features/reset_password.rb +5 -4
  25. data/lib/rodauth/features/session_expiration.rb +1 -0
  26. data/lib/rodauth/features/single_session.rb +1 -0
  27. data/lib/rodauth/features/sms_codes.rb +10 -5
  28. data/lib/rodauth/features/two_factor_base.rb +4 -1
  29. data/lib/rodauth/features/verify_account.rb +5 -1
  30. data/lib/rodauth/features/verify_login_change.rb +3 -2
  31. data/lib/rodauth/features/webauthn.rb +15 -14
  32. data/lib/rodauth/features/webauthn_login.rb +1 -1
  33. data/lib/rodauth/version.rb +1 -1
  34. data/templates/button.str +1 -1
  35. data/templates/change-password.str +2 -2
  36. data/templates/global-logout-field.str +1 -1
  37. data/templates/login-confirm-field.str +2 -2
  38. data/templates/login-display.str +2 -2
  39. data/templates/login-field.str +2 -2
  40. data/templates/otp-auth-code-field.str +2 -2
  41. data/templates/otp-setup.str +2 -2
  42. data/templates/password-confirm-field.str +2 -2
  43. data/templates/password-field.str +2 -2
  44. data/templates/recovery-auth.str +2 -2
  45. data/templates/remember.str +1 -1
  46. data/templates/sms-code-field.str +2 -2
  47. data/templates/sms-setup.str +2 -2
  48. data/templates/webauthn-remove.str +1 -1
  49. metadata +6 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 453992f6df1e1a41e30923334f53146ddd575015f57960dcdadb2b3d4bc496e9
4
- data.tar.gz: 29172b14c9a5c6d88e36c827c4fbc9e4f61fbadadf6b656734ef7058e9dd4a13
3
+ metadata.gz: f01d42c90dd22a88566f17b3e77b9495dc1431f004f2f54865cff45a3874ce43
4
+ data.tar.gz: b09c0a44b2b4f6ab1eb795b11a69ec7acd1d4ed5ac4abbe45d8bb4072cb61e0f
5
5
  SHA512:
6
- metadata.gz: 956d8809e6ba87044e5aeba7712cc4e907604a632d7113084cda074bf675952fb4e3081cca5adf19a191df6d073e2b9068a313d8d26e81534b70f9eaba20688e
7
- data.tar.gz: aaa0cde299ba115ea281bc18dfe5f02a0d2b35dd95231d9e69662ec340194569a288be916abb2fe0e258c50599c6ea6ef42791824f986d6dc2e295f5db67645a
6
+ metadata.gz: 2934f2824b7c805f6400fab52aad9c4aaca2f3bbfb4584688619b0b24b9e052a3cecc4b36b6eb7379e13f2a9bf2bc64e0efac077d932e390270401966223e2ae
7
+ data.tar.gz: c1dcf6d140117743baa62ba0715c99584bb80b8aa933f596424f242c2ffb6a31c7d25f0fdba65fed4b1bd93d63692502c7c63b36a1f2b793083b1972c5313304
data/CHANGELOG CHANGED
@@ -1,3 +1,11 @@
1
+ === 2.13.0 (2021-05-22)
2
+
3
+ * Make jwt_refresh expired access token support work when using rodauth.check_active_sessions before calling r.rodauth (renchap) (#165)
4
+
5
+ * Update default templates to add classes for Bootstrap 5 compatibility (janko) (#164)
6
+
7
+ * Add set_error_reason configuration method to allow applications more finer grained error handling (renchap, jeremyevans) (#162)
8
+
1
9
  === 2.12.0 (2021-04-22)
2
10
 
3
11
  * Add configuration methods to active_sessions plugin to control the inserting and updating of rows (janko) (#159)
data/doc/base.rdoc CHANGED
@@ -105,6 +105,7 @@ random_key :: A randomly generated string, used for creating tokens.
105
105
  redirect(path) :: Redirect the request to the given path.
106
106
  session_value :: The value for session_key in the current session.
107
107
  set_error_flash(message) :: Set the current error flash to the given message.
108
+ set_error_reason(reason) :: You can override this method to customize handling of specific error types (does nothing by default). Each separate error type has a separate reason symbol, you can see the {list of error reason symbols}[rdoc-ref:doc/error_reasons.rdoc].
108
109
  set_notice_flash(message) :: Set the next notice flash to the given message.
109
110
  set_notice_now_flash(message) :: Set the current notice flash to the given message.
110
111
  set_redirect_error_flash(message) :: Set the next error flash to the given message.
@@ -0,0 +1,73 @@
1
+ = Error Reasons
2
+
3
+ Rodauth allows for customizing response status codes and error
4
+ messages for each type of error. However, in some cases, the
5
+ response status code is too coarse for desired error handling
6
+ by the application (since many error types use the same status
7
+ code), and using the error message is too fragile since it may
8
+ be translated.
9
+
10
+ For this reason, Rodauth associates a fine grained reason for
11
+ each type of error. If an error occurs in Rodauth, it will
12
+ call the +set_error_reason+ method with a symbol for the
13
+ specific type of error. By default, this method does not do
14
+ anything, but you can use the +set_error_reason+ configuration
15
+ method to customize the error handling.
16
+
17
+ These are the currently supported error type symbols that
18
+ Rodauth will call +set_error_reason+ with:
19
+
20
+ * :account_locked_out
21
+ * :already_an_account_with_this_login
22
+ * :already_an_unverified_account_with_this_login
23
+ * :duplicate_webauthn_id
24
+ * :inactive_session
25
+ * :invalid_email_auth_key
26
+ * :invalid_otp_auth_code
27
+ * :invalid_otp_secret
28
+ * :invalid_password
29
+ * :invalid_password_pattern
30
+ * :invalid_phone_number
31
+ * :invalid_previous_password
32
+ * :invalid_recovery_code
33
+ * :invalid_remember_param
34
+ * :invalid_reset_password_key
35
+ * :invalid_sms_code
36
+ * :invalid_sms_confirmation_code
37
+ * :invalid_unlock_account_key
38
+ * :invalid_verify_account_key
39
+ * :invalid_verify_login_change_key
40
+ * :invalid_webauthn_auth_param
41
+ * :invalid_webauthn_remove_param
42
+ * :invalid_webauthn_setup_param
43
+ * :invalid_webauthn_sign_count
44
+ * :login_not_valid_email
45
+ * :login_required
46
+ * :login_too_long
47
+ * :login_too_short
48
+ * :logins_do_not_match
49
+ * :no_current_sms_code
50
+ * :no_matching_login
51
+ * :not_enough_character_groups_in_password
52
+ * :otp_locked_out
53
+ * :password_authentication_required
54
+ * :password_contains_null_byte
55
+ * :password_does_not_meet_requirements
56
+ * :password_in_dictionary
57
+ * :password_is_one_of_the_most_common
58
+ * :password_same_as_previous_password
59
+ * :password_too_short
60
+ * :passwords_do_not_match
61
+ * :same_as_current_login
62
+ * :same_as_existing_password
63
+ * :session_expired
64
+ * :sms_already_setup
65
+ * :sms_locked_out
66
+ * :sms_needs_confirmation
67
+ * :sms_not_setup
68
+ * :too_many_repeating_characters_in_password
69
+ * :two_factor_already_authenticated
70
+ * :two_factor_need_authentication
71
+ * :two_factor_not_setup
72
+ * :unverified_account
73
+ * :webauthn_not_setup
@@ -0,0 +1,19 @@
1
+ = New Features
2
+
3
+ * A set_error_reason configuration method has been added. This method
4
+ is called whenever a error occurs in Rodauth, with a symbol
5
+ describing the error. The default implementation of this method does
6
+ nothing, it has been added to make it easier for Rodauth users to
7
+ implement custom handling for specific error types. See the Rodauth
8
+ documentation for this method to see the list of symbols this method
9
+ can be called with.
10
+
11
+ = Other Improvements
12
+
13
+ * When using active_sessions and jwt_refresh together, and allowing for
14
+ expired JWTs when refreshing, you can now call
15
+ rodauth.check_active_session before r.rodauth. Previously, this
16
+ did not work, and you had to call rodauth.check_active_session
17
+ after r.rodauth.
18
+
19
+ * The default templates now also support Bootstrap 5.
@@ -57,6 +57,7 @@ module Rodauth
57
57
  def no_longer_active_session
58
58
  clear_session
59
59
  set_redirect_error_status inactive_session_error_status
60
+ set_error_reason :inactive_session
60
61
  set_redirect_error_flash active_sessions_error_flash
61
62
  redirect active_sessions_redirect
62
63
  end
@@ -176,4 +177,3 @@ module Rodauth
176
177
  end
177
178
  end
178
179
  end
179
-
@@ -100,6 +100,7 @@ module Rodauth
100
100
  :set_notice_flash,
101
101
  :set_notice_now_flash,
102
102
  :set_redirect_error_flash,
103
+ :set_error_reason,
103
104
  :set_title,
104
105
  :translate,
105
106
  :update_session
@@ -294,6 +295,7 @@ module Rodauth
294
295
 
295
296
  def login_required
296
297
  set_redirect_error_status(login_required_error_status)
298
+ set_error_reason :login_required
297
299
  set_redirect_error_flash require_login_error_flash
298
300
  redirect require_login_redirect
299
301
  end
@@ -539,6 +541,11 @@ module Rodauth
539
541
  def set_response_error_status(status)
540
542
  response.status = status
541
543
  end
544
+
545
+ def set_response_error_reason_status(reason, status)
546
+ set_error_reason(reason)
547
+ set_response_error_status(status)
548
+ end
542
549
 
543
550
  def throw_error(field, error)
544
551
  set_field_error(field, error)
@@ -550,6 +557,14 @@ module Rodauth
550
557
  throw_error(field, error)
551
558
  end
552
559
 
560
+ def set_error_reason(reason)
561
+ end
562
+
563
+ def throw_error_reason(reason, status, field, message)
564
+ set_error_reason(reason)
565
+ throw_error_status(status, field, message)
566
+ end
567
+
553
568
  def use_date_arithmetic?
554
569
  set_deadline_values?
555
570
  end
@@ -30,7 +30,7 @@ module Rodauth
30
30
  r.post do
31
31
  catch_error do
32
32
  if change_login_requires_password? && !password_match?(param(password_param))
33
- throw_error_status(invalid_password_error_status, password_param, invalid_password_message)
33
+ throw_error_reason(:invalid_password, invalid_password_error_status, password_param, invalid_password_message)
34
34
  end
35
35
 
36
36
  login = param(login_param)
@@ -39,7 +39,7 @@ module Rodauth
39
39
  end
40
40
 
41
41
  if require_login_confirmation? && login != param(login_confirm_param)
42
- throw_error_status(unmatched_field_error_status, login_param, logins_do_not_match_message)
42
+ throw_error_reason(:logins_do_not_match, unmatched_field_error_status, login_param, logins_do_not_match_message)
43
43
  end
44
44
 
45
45
  transaction do
@@ -65,7 +65,7 @@ module Rodauth
65
65
 
66
66
  def change_login(login)
67
67
  if account_ds.get(login_column).downcase == login.downcase
68
- @login_requirement_message = same_as_current_login_message
68
+ set_login_requirement_error_message(:same_as_current_login, same_as_current_login_message)
69
69
  return false
70
70
  end
71
71
 
@@ -82,7 +82,7 @@ module Rodauth
82
82
  updated = nil
83
83
  raised = raises_uniqueness_violation?{updated = update_account({login_column=>login}, account_ds.exclude(login_column=>login)) == 1}
84
84
  if raised
85
- @login_requirement_message = already_an_account_with_this_login_message
85
+ set_login_requirement_error_message(:already_an_account_with_this_login, already_an_account_with_this_login_message)
86
86
  end
87
87
  updated && !raised
88
88
  end
@@ -33,16 +33,16 @@ module Rodauth
33
33
  r.post do
34
34
  catch_error do
35
35
  if change_password_requires_password? && !password_match?(param(password_param))
36
- throw_error_status(invalid_password_error_status, password_param, invalid_previous_password_message)
36
+ throw_error_reason(:invalid_previous_password, invalid_password_error_status, password_param, invalid_previous_password_message)
37
37
  end
38
38
 
39
39
  password = param(new_password_param)
40
40
  if require_password_confirmation? && password != param(password_confirm_param)
41
- throw_error_status(unmatched_field_error_status, new_password_param, passwords_do_not_match_message)
41
+ throw_error_reason(:passwords_do_not_match, unmatched_field_error_status, new_password_param, passwords_do_not_match_message)
42
42
  end
43
43
 
44
44
  if password_match?(password)
45
- throw_error_status(invalid_field_error_status, new_password_param, same_as_existing_password_message)
45
+ throw_error_reason(:same_as_existing_password, invalid_field_error_status, new_password_param, same_as_existing_password_message)
46
46
  end
47
47
 
48
48
  unless password_meets_requirements?(password)
@@ -35,7 +35,7 @@ module Rodauth
35
35
  r.post do
36
36
  catch_error do
37
37
  if close_account_requires_password? && !password_match?(param(password_param))
38
- throw_error_status(invalid_password_error_status, password_param, invalid_password_message)
38
+ throw_error_reason(:invalid_password, invalid_password_error_status, password_param, invalid_password_message)
39
39
  end
40
40
 
41
41
  transaction do
@@ -40,7 +40,7 @@ module Rodauth
40
40
  set_notice_flash confirm_password_notice_flash
41
41
  redirect confirm_password_redirect
42
42
  else
43
- set_response_error_status(invalid_password_error_status)
43
+ set_response_error_reason_status(:invalid_password, invalid_password_error_status)
44
44
  set_field_error(password_param, invalid_password_message)
45
45
  set_error_flash confirm_password_error_flash
46
46
  confirm_password_view
@@ -53,6 +53,7 @@ module Rodauth
53
53
 
54
54
  if require_password_authentication? && has_password?
55
55
  set_redirect_error_status(password_authentication_required_error_status)
56
+ set_error_reason :password_authentication_required
56
57
  set_redirect_error_flash password_authentication_required_error_flash
57
58
  set_session_value(confirm_password_redirect_session_key, request.fullpath)
58
59
  redirect password_authentication_required_redirect
@@ -89,4 +90,3 @@ module Rodauth
89
90
  end
90
91
  end
91
92
  end
92
-
@@ -43,7 +43,7 @@ module Rodauth
43
43
 
44
44
  catch_error do
45
45
  if require_login_confirmation? && login != param(login_confirm_param)
46
- throw_error_status(unmatched_field_error_status, login_param, logins_do_not_match_message)
46
+ throw_error_reason(:logins_do_not_match, unmatched_field_error_status, login_param, logins_do_not_match_message)
47
47
  end
48
48
 
49
49
  unless login_meets_requirements?(login)
@@ -52,11 +52,11 @@ module Rodauth
52
52
 
53
53
  if create_account_set_password?
54
54
  if require_password_confirmation? && password != param(password_confirm_param)
55
- throw_error_status(unmatched_field_error_status, password_param, passwords_do_not_match_message)
55
+ throw_error_reason(:passwords_do_not_match, unmatched_field_error_status, password_param, passwords_do_not_match_message)
56
56
  end
57
57
 
58
58
  unless password_meets_requirements?(password)
59
- throw_error_status(invalid_field_error_status, password_param, password_does_not_meet_requirements_message)
59
+ throw_error_reason(:password_does_not_meet_requirements, invalid_field_error_status, password_param, password_does_not_meet_requirements_message)
60
60
  end
61
61
 
62
62
  if account_password_hash_column
@@ -100,7 +100,7 @@ module Rodauth
100
100
  raised = raises_uniqueness_violation?{id = db[accounts_table].insert(account)}
101
101
 
102
102
  if raised
103
- @login_requirement_message = already_an_account_with_this_login_message
103
+ set_login_requirement_error_message(:already_an_account_with_this_login, already_an_account_with_this_login_message)
104
104
  end
105
105
 
106
106
  if id
@@ -32,7 +32,7 @@ module Rodauth
32
32
 
33
33
  def password_not_one_of_the_most_common?(password)
34
34
  return true unless password_one_of_most_common?(password)
35
- @password_requirement_message = password_is_one_of_the_most_common_message
35
+ set_password_requirement_error_message(:password_is_one_of_the_most_common, password_is_one_of_the_most_common_message)
36
36
  false
37
37
  end
38
38
  end
@@ -65,7 +65,7 @@ module Rodauth
65
65
  end
66
66
 
67
67
  return true unless match
68
- @password_requirement_message = password_same_as_previous_password_message
68
+ set_password_requirement_error_message(:password_same_as_previous_password, password_same_as_previous_password_message)
69
69
  false
70
70
  end
71
71
 
@@ -58,6 +58,7 @@ module Rodauth
58
58
  _email_auth_request
59
59
  else
60
60
  set_redirect_error_status(no_matching_login_error_status)
61
+ set_error_reason :no_matching_login
61
62
  set_redirect_error_flash email_auth_request_error_flash
62
63
  end
63
64
 
@@ -90,6 +91,7 @@ module Rodauth
90
91
  key = session[email_auth_session_key] || param(email_auth_key_param)
91
92
  unless account_from_email_auth_key(key)
92
93
  set_redirect_error_status(invalid_key_error_status)
94
+ set_error_reason :invalid_email_auth_key
93
95
  set_redirect_error_flash email_auth_error_flash
94
96
  redirect email_auth_email_sent_redirect
95
97
  end
@@ -32,6 +32,8 @@ module Rodauth
32
32
  )
33
33
 
34
34
  route do |r|
35
+ # For backward compatibility, unused in core Rodauth
36
+ # RODAUTH3: Remove
35
37
  @jwt_refresh_route = true
36
38
  before_jwt_refresh_route
37
39
 
@@ -135,7 +137,7 @@ module Rodauth
135
137
  end
136
138
 
137
139
  def _jwt_decode_opts
138
- if allow_refresh_with_expired_jwt_access_token? && @jwt_refresh_route
140
+ if allow_refresh_with_expired_jwt_access_token? && request.path == jwt_refresh_path
139
141
  Hash[super].merge!(:verify_expiration=>false)
140
142
  else
141
143
  super
@@ -84,6 +84,7 @@ module Rodauth
84
84
  set_notice_flash unlock_account_request_notice_flash
85
85
  else
86
86
  set_redirect_error_status(no_matching_login_error_status)
87
+ set_error_reason :no_matching_login
87
88
  set_redirect_error_flash no_matching_login_message.to_s.capitalize
88
89
  end
89
90
 
@@ -116,6 +117,7 @@ module Rodauth
116
117
  key = session[unlock_account_session_key] || param(unlock_account_key_param)
117
118
  unless account_from_unlock_key(key)
118
119
  set_redirect_error_status invalid_key_error_status
120
+ set_error_reason :invalid_unlock_account_key
119
121
  set_redirect_error_flash no_matching_unlock_account_key_error_flash
120
122
  redirect unlock_account_request_redirect
121
123
  end
@@ -134,7 +136,7 @@ module Rodauth
134
136
  set_notice_flash unlock_account_notice_flash
135
137
  redirect unlock_account_redirect
136
138
  else
137
- set_response_error_status(invalid_password_error_status)
139
+ set_response_error_reason_status(:invalid_password, invalid_password_error_status)
138
140
  set_field_error(password_param, invalid_password_message)
139
141
  set_error_flash unlock_account_error_flash
140
142
  unlock_account_view
@@ -271,7 +273,7 @@ module Rodauth
271
273
  end
272
274
 
273
275
  def show_lockout_page
274
- set_response_error_status lockout_error_status
276
+ set_response_error_reason_status(:account_locked_out, lockout_error_status)
275
277
  set_error_flash login_lockout_error_flash
276
278
  response.write unlock_account_request_view
277
279
  request.halt
@@ -39,13 +39,13 @@ module Rodauth
39
39
 
40
40
  catch_error do
41
41
  unless account_from_login(param(login_param))
42
- throw_error_status(no_matching_login_error_status, login_param, no_matching_login_message)
42
+ throw_error_reason(:no_matching_login, no_matching_login_error_status, login_param, no_matching_login_message)
43
43
  end
44
44
 
45
45
  before_login_attempt
46
46
 
47
47
  unless open_account?
48
- throw_error_status(unopen_account_error_status, login_param, unverified_account_message)
48
+ throw_error_reason(:unverified_account, unopen_account_error_status, login_param, unverified_account_message)
49
49
  end
50
50
 
51
51
  if use_multi_phase_login?
@@ -61,7 +61,7 @@ module Rodauth
61
61
 
62
62
  unless password_match?(param(password_param))
63
63
  after_login_failure
64
- throw_error_status(login_error_status, password_param, invalid_password_message)
64
+ throw_error_reason(:invalid_password, login_error_status, password_param, invalid_password_message)
65
65
  end
66
66
 
67
67
  login('password')
@@ -81,6 +81,11 @@ module Rodauth
81
81
  def password_too_short_message
82
82
  "minimum #{password_minimum_length} characters"
83
83
  end
84
+
85
+ def set_password_requirement_error_message(reason, message)
86
+ set_error_reason(reason)
87
+ @password_requirement_message = message
88
+ end
84
89
 
85
90
  def login_does_not_meet_requirements_message
86
91
  "invalid login#{", #{login_requirement_message}" if login_requirement_message}"
@@ -93,13 +98,18 @@ module Rodauth
93
98
  def login_too_short_message
94
99
  "minimum #{login_minimum_length} characters"
95
100
  end
101
+
102
+ def set_login_requirement_error_message(reason, message)
103
+ set_error_reason(reason)
104
+ @login_requirement_message = message
105
+ end
96
106
 
97
107
  def login_meets_length_requirements?(login)
98
108
  if login_minimum_length > login.length
99
- @login_requirement_message = login_too_short_message
109
+ set_login_requirement_error_message(:login_too_short, login_too_short_message)
100
110
  false
101
111
  elsif login_maximum_length < login.length
102
- @login_requirement_message = login_too_long_message
112
+ set_login_requirement_error_message(:login_too_long, login_too_long_message)
103
113
  false
104
114
  else
105
115
  true
@@ -109,7 +119,7 @@ module Rodauth
109
119
  def login_meets_email_requirements?(login)
110
120
  return true unless require_email_address_logins?
111
121
  return true if login_valid_email?(login)
112
- @login_requirement_message = login_not_valid_email_message
122
+ set_login_requirement_error_message(:login_not_valid_email, login_not_valid_email_message)
113
123
  return false
114
124
  end
115
125
 
@@ -119,13 +129,13 @@ module Rodauth
119
129
 
120
130
  def password_meets_length_requirements?(password)
121
131
  return true if password_minimum_length <= password.length
122
- @password_requirement_message = password_too_short_message
132
+ set_password_requirement_error_message(:password_too_short, password_too_short_message)
123
133
  false
124
134
  end
125
135
 
126
136
  def password_does_not_contain_null_byte?(password)
127
137
  return true unless password.include?("\0")
128
- @password_requirement_message = contains_null_byte_message
138
+ set_password_requirement_error_message(:password_contains_null_byte, contains_null_byte_message)
129
139
  false
130
140
  end
131
141
 
@@ -150,4 +160,3 @@ module Rodauth
150
160
  end
151
161
  end
152
162
  end
153
-
@@ -103,7 +103,7 @@ module Rodauth
103
103
  require_otp_setup
104
104
 
105
105
  if otp_locked_out?
106
- set_response_error_status(lockout_error_status)
106
+ set_response_error_reason_status(:otp_locked_out, lockout_error_status)
107
107
  set_redirect_error_flash otp_lockout_error_flash
108
108
  redirect otp_lockout_redirect
109
109
  end
@@ -122,7 +122,7 @@ module Rodauth
122
122
 
123
123
  otp_record_authentication_failure
124
124
  after_otp_authentication_failure
125
- set_response_error_status(invalid_key_error_status)
125
+ set_response_error_reason_status(:invalid_otp_auth_code, invalid_key_error_status)
126
126
  set_field_error(otp_auth_param, otp_invalid_auth_code_message)
127
127
  set_error_flash otp_auth_error_flash
128
128
  otp_auth_view
@@ -149,7 +149,7 @@ module Rodauth
149
149
  catch_error do
150
150
  unless otp_valid_key?(secret)
151
151
  otp_tmp_key(otp_new_secret)
152
- throw_error_status(invalid_field_error_status, otp_setup_param, otp_invalid_secret_message)
152
+ throw_error_reason(:invalid_otp_secret, invalid_field_error_status, otp_setup_param, otp_invalid_secret_message)
153
153
  end
154
154
 
155
155
  if otp_keys_use_hmac?
@@ -159,11 +159,11 @@ module Rodauth
159
159
  end
160
160
 
161
161
  unless two_factor_password_match?(param(password_param))
162
- throw_error_status(invalid_password_error_status, password_param, invalid_password_message)
162
+ throw_error_reason(:invalid_password, invalid_password_error_status, password_param, invalid_password_message)
163
163
  end
164
164
 
165
165
  unless otp_valid_code?(param(otp_auth_param))
166
- throw_error_status(invalid_key_error_status, otp_auth_param, otp_invalid_auth_code_message)
166
+ throw_error_reason(:invalid_otp_auth_code, invalid_key_error_status, otp_auth_param, otp_invalid_auth_code_message)
167
167
  end
168
168
 
169
169
  transaction do
@@ -206,7 +206,7 @@ module Rodauth
206
206
  redirect otp_disable_redirect
207
207
  end
208
208
 
209
- set_response_error_status(invalid_password_error_status)
209
+ set_response_error_reason_status(:invalid_password, invalid_password_error_status)
210
210
  set_field_error(password_param, invalid_password_message)
211
211
  set_error_flash otp_disable_error_flash
212
212
  otp_disable_view
@@ -226,6 +226,7 @@ module Rodauth
226
226
  def require_otp_setup
227
227
  unless otp_exists?
228
228
  set_redirect_error_status(two_factor_not_setup_error_status)
229
+ set_error_reason :two_factor_not_setup
229
230
  set_redirect_error_flash two_factor_not_setup_error_flash
230
231
  redirect two_factor_need_setup_redirect
231
232
  end
@@ -54,21 +54,21 @@ module Rodauth
54
54
  def password_has_enough_character_groups?(password)
55
55
  return true if password.length > password_max_length_for_groups_check
56
56
  return true if password_character_groups.select{|re| password =~ re}.length >= password_min_groups
57
- @password_requirement_message = password_not_enough_character_groups_message
57
+ set_password_requirement_error_message(:not_enough_character_groups_in_password, password_not_enough_character_groups_message)
58
58
  false
59
59
  end
60
60
 
61
61
  def password_has_no_invalid_pattern?(password)
62
62
  return true unless password_invalid_pattern
63
63
  return true if password !~ password_invalid_pattern
64
- @password_requirement_message = password_invalid_pattern_message
64
+ set_password_requirement_error_message(:invalid_password_pattern, password_invalid_pattern_message)
65
65
  false
66
66
  end
67
67
 
68
68
  def password_not_too_many_repeating_characters?(password)
69
69
  return true if password_max_repeating_characters < 2
70
70
  return true if password !~ /(.)(\1){#{password_max_repeating_characters-1}}/
71
- @password_requirement_message = password_too_many_repeating_characters_message
71
+ set_password_requirement_error_message(:too_many_repeating_characters_in_password, password_too_many_repeating_characters_message)
72
72
  false
73
73
  end
74
74
 
@@ -77,7 +77,7 @@ module Rodauth
77
77
  return true unless password =~ /\A(?:\d*)([A-Za-z!@$+|][A-Za-z!@$+|0134578]+[A-Za-z!@$+|])(?:\d*)\z/
78
78
  word = $1.downcase.tr('!@$+|0134578', 'iastloleastb')
79
79
  return true if !dict.include?(word)
80
- @password_requirement_message = password_in_dictionary_message
80
+ set_password_requirement_error_message(:password_in_dictionary, password_in_dictionary_message)
81
81
  false
82
82
  end
83
83
  end
@@ -76,7 +76,7 @@ module Rodauth
76
76
  two_factor_authenticate('recovery_code')
77
77
  end
78
78
 
79
- set_response_error_status(invalid_key_error_status)
79
+ set_response_error_reason_status(:invalid_recovery_code, invalid_key_error_status)
80
80
  set_field_error(recovery_codes_param, invalid_recovery_code_message)
81
81
  set_error_flash invalid_recovery_code_error_flash
82
82
  recovery_auth_view
@@ -119,7 +119,7 @@ module Rodauth
119
119
  set_error_flash view_recovery_codes_error_flash
120
120
  end
121
121
 
122
- set_response_error_status(invalid_password_error_status)
122
+ set_response_error_reason_status(:invalid_password, invalid_password_error_status)
123
123
  set_field_error(password_param, invalid_password_message)
124
124
  recovery_codes_view
125
125
  end
@@ -74,7 +74,7 @@ module Rodauth
74
74
  set_notice_flash remember_notice_flash
75
75
  redirect remember_redirect
76
76
  else
77
- set_response_error_status(invalid_field_error_status)
77
+ set_response_error_reason_status(:invalid_remember_param, invalid_field_error_status)
78
78
  set_error_flash remember_error_flash
79
79
  remember_view
80
80
  end
@@ -68,11 +68,11 @@ module Rodauth
68
68
  r.post do
69
69
  catch_error do
70
70
  unless account_from_login(param(login_param))
71
- throw_error_status(no_matching_login_error_status, login_param, no_matching_login_message)
71
+ throw_error_reason(:no_matching_login, no_matching_login_error_status, login_param, no_matching_login_message)
72
72
  end
73
73
 
74
74
  unless open_account?
75
- throw_error_status(unopen_account_error_status, login_param, unverified_account_message)
75
+ throw_error_reason(:unverified_account, unopen_account_error_status, login_param, unverified_account_message)
76
76
  end
77
77
 
78
78
  if reset_password_email_recently_sent?
@@ -123,6 +123,7 @@ module Rodauth
123
123
  key = session[reset_password_session_key] || param(reset_password_key_param)
124
124
  unless account_from_reset_password_key(key)
125
125
  set_redirect_error_status(invalid_key_error_status)
126
+ set_error_reason :invalid_reset_password_key
126
127
  set_redirect_error_flash reset_password_error_flash
127
128
  redirect reset_password_email_sent_redirect
128
129
  end
@@ -130,11 +131,11 @@ module Rodauth
130
131
  password = param(password_param)
131
132
  catch_error do
132
133
  if password_match?(password)
133
- throw_error_status(invalid_field_error_status, password_param, same_as_existing_password_message)
134
+ throw_error_reason(:same_as_existing_password, invalid_field_error_status, password_param, same_as_existing_password_message)
134
135
  end
135
136
 
136
137
  if require_password_confirmation? && password != param(password_confirm_param)
137
- throw_error_status(unmatched_field_error_status, password_param, passwords_do_not_match_message)
138
+ throw_error_reason(:passwords_do_not_match, unmatched_field_error_status, password_param, passwords_do_not_match_message)
138
139
  end
139
140
 
140
141
  unless password_meets_requirements?(password)
@@ -38,6 +38,7 @@ module Rodauth
38
38
  def expire_session
39
39
  clear_session
40
40
  set_redirect_error_status session_expiration_error_status
41
+ set_error_reason :session_expired
41
42
  set_redirect_error_flash session_expiration_error_flash
42
43
  redirect session_expiration_redirect
43
44
  end
@@ -57,6 +57,7 @@ module Rodauth
57
57
  def no_longer_active_session
58
58
  clear_session
59
59
  set_redirect_error_status inactive_session_error_status
60
+ set_error_reason :inactive_session
60
61
  set_redirect_error_flash single_session_error_flash
61
62
  redirect single_session_redirect
62
63
  end
@@ -146,7 +146,7 @@ module Rodauth
146
146
  sms_set_code(nil)
147
147
  end
148
148
 
149
- set_response_error_status(invalid_key_error_status)
149
+ set_response_error_reason_status(:no_current_sms_code, invalid_key_error_status)
150
150
  set_redirect_error_flash no_current_sms_code_error_flash
151
151
  redirect sms_request_redirect
152
152
  end
@@ -169,7 +169,7 @@ module Rodauth
169
169
  end
170
170
  end
171
171
 
172
- set_response_error_status(invalid_key_error_status)
172
+ set_response_error_reason_status(:invalid_sms_code, invalid_key_error_status)
173
173
  set_field_error(sms_code_param, sms_invalid_code_message)
174
174
  set_error_flash sms_invalid_code_error_flash
175
175
  sms_auth_view
@@ -186,6 +186,7 @@ module Rodauth
186
186
 
187
187
  if sms_needs_confirmation?
188
188
  set_redirect_error_status(sms_needs_confirmation_error_status)
189
+ set_error_reason :sms_needs_confirmation
189
190
  set_redirect_error_flash sms_needs_confirmation_error_flash
190
191
  redirect sms_needs_confirmation_redirect
191
192
  end
@@ -199,13 +200,13 @@ module Rodauth
199
200
  r.post do
200
201
  catch_error do
201
202
  unless two_factor_password_match?(param(password_param))
202
- throw_error_status(invalid_password_error_status, password_param, invalid_password_message)
203
+ throw_error_reason(:invalid_password, invalid_password_error_status, password_param, invalid_password_message)
203
204
  end
204
205
 
205
206
  phone = sms_normalize_phone(param(sms_phone_param))
206
207
 
207
208
  unless sms_valid_phone?(phone)
208
- throw_error_status(invalid_field_error_status, sms_phone_param, sms_invalid_phone_message)
209
+ throw_error_reason(:invalid_phone_number, invalid_field_error_status, sms_phone_param, sms_invalid_phone_message)
209
210
  end
210
211
 
211
212
  transaction do
@@ -254,6 +255,7 @@ module Rodauth
254
255
 
255
256
  sms_confirm_failure
256
257
  set_redirect_error_status(invalid_key_error_status)
258
+ set_error_reason :invalid_sms_confirmation_code
257
259
  set_redirect_error_flash sms_invalid_confirmation_code_error_flash
258
260
  redirect sms_needs_setup_redirect
259
261
  end
@@ -282,7 +284,7 @@ module Rodauth
282
284
  redirect sms_disable_redirect
283
285
  end
284
286
 
285
- set_response_error_status(invalid_password_error_status)
287
+ set_response_error_reason_status(:invalid_password, invalid_password_error_status)
286
288
  set_field_error(password_param, invalid_password_message)
287
289
  set_error_flash sms_disable_error_flash
288
290
  sms_disable_view
@@ -302,6 +304,7 @@ module Rodauth
302
304
  def require_sms_setup
303
305
  unless sms_setup?
304
306
  set_redirect_error_status(two_factor_not_setup_error_status)
307
+ set_error_reason :sms_not_setup
305
308
  set_redirect_error_flash sms_not_setup_error_flash
306
309
  redirect sms_needs_setup_redirect
307
310
  end
@@ -310,6 +313,7 @@ module Rodauth
310
313
  def require_sms_not_setup
311
314
  if sms_setup?
312
315
  set_redirect_error_status(sms_already_setup_error_status)
316
+ set_error_reason :sms_already_setup
313
317
  set_redirect_error_flash sms_already_setup_error_flash
314
318
  redirect sms_already_setup_redirect
315
319
  end
@@ -320,6 +324,7 @@ module Rodauth
320
324
 
321
325
  if sms_locked_out?
322
326
  set_redirect_error_status(lockout_error_status)
327
+ set_error_reason :sms_locked_out
323
328
  set_redirect_error_flash sms_lockout_error_flash
324
329
  redirect sms_lockout_redirect
325
330
  end
@@ -106,7 +106,7 @@ module Rodauth
106
106
  redirect two_factor_disable_redirect
107
107
  end
108
108
 
109
- set_response_error_status(invalid_password_error_status)
109
+ set_response_error_reason_status(:invalid_password, invalid_password_error_status)
110
110
  set_field_error(password_param, invalid_password_message)
111
111
  set_error_flash two_factor_disable_error_flash
112
112
  two_factor_disable_view
@@ -144,6 +144,7 @@ module Rodauth
144
144
  return if uses_two_factor_authentication?
145
145
 
146
146
  set_redirect_error_status(two_factor_not_setup_error_status)
147
+ set_error_reason :two_factor_not_setup
147
148
  set_redirect_error_flash two_factor_not_setup_error_flash
148
149
  redirect two_factor_need_setup_redirect
149
150
  end
@@ -151,6 +152,7 @@ module Rodauth
151
152
  def require_two_factor_not_authenticated(auth_type = nil)
152
153
  if two_factor_authenticated? || (auth_type && two_factor_login_type_match?(auth_type))
153
154
  set_redirect_error_status(two_factor_already_authenticated_error_status)
155
+ set_error_reason :two_factor_already_authenticated
154
156
  set_redirect_error_flash two_factor_already_authenticated_error_flash
155
157
  redirect two_factor_already_authenticated_redirect
156
158
  end
@@ -162,6 +164,7 @@ module Rodauth
162
164
  set_session_value(two_factor_auth_redirect_session_key, request.fullpath)
163
165
  end
164
166
  set_redirect_error_status(two_factor_need_authentication_error_status)
167
+ set_error_reason :two_factor_need_authentication
165
168
  set_redirect_error_flash two_factor_need_authentication_error_flash
166
169
  redirect two_factor_auth_required_redirect
167
170
  end
@@ -87,6 +87,7 @@ module Rodauth
87
87
  set_notice_flash verify_account_email_sent_notice_flash
88
88
  else
89
89
  set_redirect_error_status(no_matching_login_error_status)
90
+ set_error_reason :no_matching_login
90
91
  set_redirect_error_flash verify_account_resend_error_flash
91
92
  end
92
93
 
@@ -120,6 +121,7 @@ module Rodauth
120
121
  key = session[verify_account_session_key] || param(verify_account_key_param)
121
122
  unless account_from_verify_account_key(key)
122
123
  set_redirect_error_status(invalid_key_error_status)
124
+ set_error_reason :invalid_verify_account_key
123
125
  set_redirect_error_flash verify_account_error_flash
124
126
  redirect verify_account_redirect
125
127
  end
@@ -129,7 +131,7 @@ module Rodauth
129
131
  password = param(password_param)
130
132
 
131
133
  if require_password_confirmation? && password != param(password_confirm_param)
132
- throw_error_status(unmatched_field_error_status, password_param, passwords_do_not_match_message)
134
+ throw_error_reason(:passwords_do_not_match, unmatched_field_error_status, password_param, passwords_do_not_match_message)
133
135
  end
134
136
 
135
137
  unless password_meets_requirements?(password)
@@ -192,6 +194,7 @@ module Rodauth
192
194
  def new_account(login)
193
195
  if account_from_login(login) && allow_resending_verify_account_email?
194
196
  set_redirect_error_status(unopen_account_error_status)
197
+ set_error_reason :already_an_unverified_account_with_this_login
195
198
  set_error_flash attempt_to_create_unverified_account_error_flash
196
199
  response.write resend_verify_account_view
197
200
  request.halt
@@ -269,6 +272,7 @@ module Rodauth
269
272
  def before_login_attempt
270
273
  unless open_account?
271
274
  set_redirect_error_status(unopen_account_error_status)
275
+ set_error_reason :unverified_account
272
276
  set_error_flash attempt_to_login_to_unverified_account_error_flash
273
277
  response.write resend_verify_account_view
274
278
  request.halt
@@ -74,6 +74,7 @@ module Rodauth
74
74
  key = session[verify_login_change_session_key] || param(verify_login_change_key_param)
75
75
  unless account_from_verify_login_change_key(key)
76
76
  set_redirect_error_status(invalid_key_error_status)
77
+ set_error_reason :invalid_verify_login_change_key
77
78
  set_redirect_error_flash verify_login_change_error_flash
78
79
  redirect verify_login_change_redirect
79
80
  end
@@ -82,6 +83,7 @@ module Rodauth
82
83
  before_verify_login_change
83
84
  unless verify_login_change
84
85
  set_redirect_error_status(invalid_key_error_status)
86
+ set_error_reason :already_an_account_with_this_login
85
87
  set_redirect_error_flash verify_login_change_duplicate_account_error_flash
86
88
  redirect verify_login_change_duplicate_account_redirect
87
89
  end
@@ -151,7 +153,7 @@ module Rodauth
151
153
 
152
154
  def update_login(login)
153
155
  if _account_from_login(login)
154
- @login_requirement_message = already_an_account_with_this_login_message
156
+ set_login_requirement_error_message(:already_an_account_with_this_login, already_an_account_with_this_login_message)
155
157
  return false
156
158
  end
157
159
 
@@ -213,4 +215,3 @@ module Rodauth
213
215
  end
214
216
  end
215
217
  end
216
-
@@ -182,7 +182,7 @@ module Rodauth
182
182
  end
183
183
 
184
184
  if throw_error
185
- throw_error_status(invalid_field_error_status, webauthn_setup_param, webauthn_duplicate_webauthn_id_message)
185
+ throw_error_reason(:duplicate_webauthn_id, invalid_field_error_status, webauthn_setup_param, webauthn_duplicate_webauthn_id_message)
186
186
  end
187
187
 
188
188
  set_notice_flash webauthn_setup_notice_flash
@@ -207,17 +207,17 @@ module Rodauth
207
207
  r.post do
208
208
  catch_error do
209
209
  unless webauthn_id = param_or_nil(webauthn_remove_param)
210
- throw_error_status(invalid_field_error_status, webauthn_remove_param, webauthn_invalid_remove_param_message)
210
+ throw_error_reason(:invalid_webauthn_remove_param, invalid_field_error_status, webauthn_remove_param, webauthn_invalid_remove_param_message)
211
211
  end
212
212
 
213
213
  unless two_factor_password_match?(param(password_param))
214
- throw_error_status(invalid_password_error_status, password_param, invalid_password_message)
214
+ throw_error_reason(:invalid_password, invalid_password_error_status, password_param, invalid_password_message)
215
215
  end
216
216
 
217
217
  transaction do
218
218
  before_webauthn_remove
219
219
  unless remove_webauthn_key(webauthn_id)
220
- throw_error_status(invalid_field_error_status, webauthn_remove_param, webauthn_invalid_remove_param_message)
220
+ throw_error_reason(:invalid_webauthn_remove_param, invalid_field_error_status, webauthn_remove_param, webauthn_invalid_remove_param_message)
221
221
  end
222
222
  if authenticated_webauthn_id == webauthn_id && two_factor_login_type_match?('webauthn')
223
223
  webauthn_remove_authenticated_session
@@ -342,7 +342,7 @@ module Rodauth
342
342
  end
343
343
 
344
344
  def handle_webauthn_sign_count_verification_error
345
- throw_error_status(invalid_field_error_status, webauthn_auth_param, webauthn_invalid_sign_count_message)
345
+ throw_error_reason(:invalid_webauthn_sign_count, invalid_field_error_status, webauthn_auth_param, webauthn_invalid_sign_count_message)
346
346
  end
347
347
 
348
348
  def add_webauthn_credential(webauthn_credential)
@@ -392,6 +392,7 @@ module Rodauth
392
392
  def require_webauthn_setup
393
393
  unless webauthn_setup?
394
394
  set_redirect_error_status(webauthn_not_setup_error_status)
395
+ set_error_reason :webauthn_not_setup
395
396
  set_redirect_error_flash webauthn_not_setup_error_flash
396
397
  redirect two_factor_need_setup_redirect
397
398
  end
@@ -450,23 +451,23 @@ module Rodauth
450
451
  begin
451
452
  auth_data = JSON.parse(auth_data)
452
453
  rescue
453
- throw_error_status(invalid_field_error_status, webauthn_auth_param, webauthn_invalid_auth_param_message)
454
+ throw_error_reason(:invalid_webauthn_auth_param, invalid_field_error_status, webauthn_auth_param, webauthn_invalid_auth_param_message)
454
455
  end
455
456
  when Hash
456
457
  # nothing
457
458
  else
458
- throw_error_status(invalid_field_error_status, webauthn_auth_param, webauthn_invalid_auth_param_message)
459
+ throw_error_reason(:invalid_webauthn_auth_param, invalid_field_error_status, webauthn_auth_param, webauthn_invalid_auth_param_message)
459
460
  end
460
461
 
461
462
  begin
462
463
  webauthn_credential = WebAuthn::Credential.from_get(auth_data)
463
464
  unless valid_webauthn_credential_auth?(webauthn_credential)
464
- throw_error_status(invalid_key_error_status, webauthn_auth_param, webauthn_invalid_auth_param_message)
465
+ throw_error_reason(:invalid_webauthn_auth_param, invalid_key_error_status, webauthn_auth_param, webauthn_invalid_auth_param_message)
465
466
  end
466
467
  rescue WebAuthn::SignCountVerificationError
467
468
  handle_webauthn_sign_count_verification_error
468
469
  rescue WebAuthn::Error, RuntimeError, NoMethodError
469
- throw_error_status(invalid_field_error_status, webauthn_auth_param, webauthn_invalid_auth_param_message)
470
+ throw_error_reason(:invalid_webauthn_auth_param, invalid_field_error_status, webauthn_auth_param, webauthn_invalid_auth_param_message)
470
471
  end
471
472
 
472
473
  webauthn_credential
@@ -478,25 +479,25 @@ module Rodauth
478
479
  begin
479
480
  setup_data = JSON.parse(setup_data)
480
481
  rescue
481
- throw_error_status(invalid_field_error_status, webauthn_setup_param, webauthn_invalid_setup_param_message)
482
+ throw_error_reason(:invalid_webauthn_setup_param, invalid_field_error_status, webauthn_setup_param, webauthn_invalid_setup_param_message)
482
483
  end
483
484
  when Hash
484
485
  # nothing
485
486
  else
486
- throw_error_status(invalid_field_error_status, webauthn_setup_param, webauthn_invalid_setup_param_message)
487
+ throw_error_reason(:invalid_webauthn_setup_param, invalid_field_error_status, webauthn_setup_param, webauthn_invalid_setup_param_message)
487
488
  end
488
489
 
489
490
  unless two_factor_password_match?(param(password_param))
490
- throw_error_status(invalid_password_error_status, password_param, invalid_password_message)
491
+ throw_error_reason(:invalid_password, invalid_password_error_status, password_param, invalid_password_message)
491
492
  end
492
493
 
493
494
  begin
494
495
  webauthn_credential = WebAuthn::Credential.from_create(setup_data)
495
496
  unless valid_new_webauthn_credential?(webauthn_credential)
496
- throw_error_status(invalid_field_error_status, webauthn_setup_param, webauthn_invalid_setup_param_message)
497
+ throw_error_reason(:invalid_webauthn_setup_param, invalid_field_error_status, webauthn_setup_param, webauthn_invalid_setup_param_message)
497
498
  end
498
499
  rescue WebAuthn::Error, RuntimeError, NoMethodError
499
- throw_error_status(invalid_field_error_status, webauthn_setup_param, webauthn_invalid_setup_param_message)
500
+ throw_error_reason(:invalid_webauthn_setup_param, invalid_field_error_status, webauthn_setup_param, webauthn_invalid_setup_param_message)
500
501
  end
501
502
 
502
503
  webauthn_credential
@@ -17,7 +17,7 @@ module Rodauth
17
17
  r.post do
18
18
  catch_error do
19
19
  unless account_from_login(param(login_param)) && open_account?
20
- throw_error_status(no_matching_login_error_status, login_param, no_matching_login_message)
20
+ throw_error_reason(:no_matching_login, no_matching_login_error_status, login_param, no_matching_login_message)
21
21
  end
22
22
 
23
23
  webauthn_credential = webauthn_auth_credential_from_form_submission
@@ -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 = 12
9
+ MINOR = 13
10
10
 
11
11
  # The patch version of Rodauth, updated only for bug fixes from the last
12
12
  # feature release.
data/templates/button.str CHANGED
@@ -1,3 +1,3 @@
1
- <div class="form-group">
1
+ <div class="form-group mb-3">
2
2
  <input type="submit" #{"name=\"#{h opts[:name]}\"" if opts[:name]} class="#{h(opts[:class] || 'btn btn-primary')}" value="#{h value}"/>
3
3
  </div>
@@ -2,8 +2,8 @@
2
2
  #{rodauth.change_password_additional_form_tags}
3
3
  #{rodauth.csrf_tag}
4
4
  #{rodauth.render('password-field') if rodauth.change_password_requires_password?}
5
- <div class="form-group">
6
- <label for="new-password">#{rodauth.new_password_label}#{rodauth.input_field_label_suffix}</label>
5
+ <div class="form-group mb-3">
6
+ <label for="new-password" class="form-label">#{rodauth.new_password_label}#{rodauth.input_field_label_suffix}</label>
7
7
  #{rodauth.input_field_string(rodauth.new_password_param, 'new-password', :type => 'password', :autocomplete=>"new-password")}
8
8
  </div>
9
9
  #{rodauth.render('password-confirm-field') if rodauth.require_password_confirmation?}
@@ -1,4 +1,4 @@
1
- <div class="form-group">
1
+ <div class="form-group mb-3">
2
2
  <div class="form-check checkbox">
3
3
  <input type="checkbox" name="#{rodauth.global_logout_param}" class="form-check-input" id="global-logout" value="t"/>
4
4
  <label class="rodauth-global-logout-label form-check-label" for="global-logout">#{rodauth.global_logout_label}</label>
@@ -1,4 +1,4 @@
1
- <div class="form-group">
2
- <label for="login-confirm">#{rodauth.login_confirm_label}#{rodauth.input_field_label_suffix}</label>
1
+ <div class="form-group mb-3">
2
+ <label for="login-confirm" class="form-label">#{rodauth.login_confirm_label}#{rodauth.input_field_label_suffix}</label>
3
3
  #{rodauth.input_field_string(rodauth.login_confirm_param, 'login-confirm', :type=>rodauth.login_input_type, :autocomplete=>rodauth.login_uses_email? ? "email" : "on")}
4
4
  </div>
@@ -1,5 +1,5 @@
1
- <div class="form-group">
1
+ <div class="form-group mb-3">
2
2
  #{rodauth.login_hidden_field}
3
- <label for="login">#{rodauth.login_label}</label>
3
+ <label for="login" class="form-label">#{rodauth.login_label}</label>
4
4
  <div class="form-control-plaintext form-control-static">#{h rodauth.param(rodauth.login_param)}</div>
5
5
  </div>
@@ -1,4 +1,4 @@
1
- <div class="form-group">
2
- <label for="login">#{rodauth.login_label}#{rodauth.input_field_label_suffix}</label>
1
+ <div class="form-group mb-3">
2
+ <label for="login" class="form-label">#{rodauth.login_label}#{rodauth.input_field_label_suffix}</label>
3
3
  #{rodauth.input_field_string(rodauth.login_param, 'login', :type=>rodauth.login_input_type, :autocomplete=>rodauth.login_uses_email? ? "email" : "on")}
4
4
  </div>
@@ -1,5 +1,5 @@
1
- <div class="form-group">
2
- <label for="otp-auth-code">#{rodauth.otp_auth_label}#{rodauth.input_field_label_suffix}</label>
1
+ <div class="form-group mb-3">
2
+ <label for="otp-auth-code" class="form-label">#{rodauth.otp_auth_label}#{rodauth.input_field_label_suffix}</label>
3
3
  <div class="row">
4
4
  <div class="col-sm-3">
5
5
  #{rodauth.input_field_string(rodauth.otp_auth_param, 'otp-auth-code', :value=>'', :autocomplete=>"off", :inputmode=>'numeric')}
@@ -3,14 +3,14 @@
3
3
  <input type="hidden" id="otp-key" name="#{rodauth.otp_setup_param}" value="#{rodauth.otp_user_key}" />
4
4
  #{"<input type=\"hidden\" id=\"otp-hmac-secret\" name=\"#{rodauth.otp_setup_raw_param}\" value=\"#{rodauth.otp_key}\" />" if rodauth.otp_keys_use_hmac?}
5
5
  #{rodauth.csrf_tag}
6
- <div class="form-group">
6
+ <div class="form-group mb-3">
7
7
  <p>#{rodauth.otp_secret_label}: #{rodauth.otp_user_key}</p>
8
8
  <p>#{rodauth.otp_provisioning_uri_label}: #{rodauth.otp_provisioning_uri}</p>
9
9
  </div>
10
10
 
11
11
  <div class="row">
12
12
  <div class="col-lg-6 col-lg">
13
- <div class="form-group">
13
+ <div class="form-group mb-3">
14
14
  <p>#{rodauth.otp_qr_code}</p>
15
15
  </div>
16
16
  </div>
@@ -1,4 +1,4 @@
1
- <div class="form-group">
2
- <label for="password-confirm">#{rodauth.password_confirm_label}#{rodauth.input_field_label_suffix}</label>
1
+ <div class="form-group mb-3">
2
+ <label for="password-confirm" class="form-label">#{rodauth.password_confirm_label}#{rodauth.input_field_label_suffix}</label>
3
3
  #{rodauth.input_field_string(rodauth.password_confirm_param, 'password-confirm', :type => 'password', :autocomplete=>'new-password')}
4
4
  </div>
@@ -1,4 +1,4 @@
1
- <div class="form-group">
2
- <label for="password">#{rodauth.password_label}#{rodauth.input_field_label_suffix}</label>
1
+ <div class="form-group mb-3">
2
+ <label for="password" class="form-label">#{rodauth.password_label}#{rodauth.input_field_label_suffix}</label>
3
3
  #{rodauth.input_field_string(rodauth.password_param, 'password', :type => 'password', :autocomplete=>rodauth.password_field_autocomplete_value)}
4
4
  </div>
@@ -1,8 +1,8 @@
1
1
  <form method="post" class="rodauth" role="form" id="recovery-auth-form">
2
2
  #{rodauth.recovery_auth_additional_form_tags}
3
3
  #{rodauth.csrf_tag}
4
- <div class="form-group">
5
- <label for="recovery-code">#{rodauth.recovery_codes_label}#{rodauth.input_field_label_suffix}</label>
4
+ <div class="form-group mb-3">
5
+ <label for="recovery-code" class="form-label">#{rodauth.recovery_codes_label}#{rodauth.input_field_label_suffix}</label>
6
6
  #{rodauth.input_field_string(rodauth.recovery_codes_param, 'recovery-code', :value => '', :autocomplete=>'off')}
7
7
  </div>
8
8
  #{rodauth.button(rodauth.recovery_auth_button)}
@@ -1,7 +1,7 @@
1
1
  <form method="post" class="rodauth" role="form" id="remember-form">
2
2
  #{rodauth.remember_additional_form_tags}
3
3
  #{rodauth.csrf_tag}
4
- <fieldset class="form-group">
4
+ <fieldset class="form-group mb-3">
5
5
  <div class="form-check radio">
6
6
  <input type="radio" name="#{rodauth.remember_param}" id="remember-remember" value="#{h rodauth.remember_remember_param_value}" class="form-check-input"/>
7
7
  <label class="form-check-label" for="remember-remember">#{rodauth.remember_remember_label}</label>
@@ -1,5 +1,5 @@
1
- <div class="form-group">
2
- <label for="sms-code">#{rodauth.sms_code_label}#{rodauth.input_field_label_suffix}</label>
1
+ <div class="form-group mb-3">
2
+ <label for="sms-code" class="form-label">#{rodauth.sms_code_label}#{rodauth.input_field_label_suffix}</label>
3
3
  <div class="row">
4
4
  <div class="col-sm-3">
5
5
  #{rodauth.input_field_string(rodauth.sms_code_param, 'sms-code', :value => '', :autocomplete=>'one-time-code', :inputmode=>'numeric')}
@@ -2,8 +2,8 @@
2
2
  #{rodauth.sms_setup_additional_form_tags}
3
3
  #{rodauth.csrf_tag}
4
4
  #{rodauth.render('password-field') if rodauth.two_factor_modifications_require_password?}
5
- <div class="form-group">
6
- <label for="sms-phone">#{rodauth.sms_phone_label}#{rodauth.input_field_label_suffix}</label>
5
+ <div class="form-group mb-3">
6
+ <label for="sms-phone" class="form-label">#{rodauth.sms_phone_label}#{rodauth.input_field_label_suffix}</label>
7
7
  <div class="row">
8
8
  <div class="col-sm-3">
9
9
  #{rodauth.input_field_string(rodauth.sms_phone_param, 'sms-phone', :type=>rodauth.sms_phone_input_type, :autocomplete=>'tel')}
@@ -2,7 +2,7 @@
2
2
  #{rodauth.webauthn_remove_additional_form_tags}
3
3
  #{rodauth.csrf_tag}
4
4
  #{rodauth.render('password-field') if rodauth.two_factor_modifications_require_password?}
5
- <fieldset class="form-group">
5
+ <fieldset class="form-group mb-3">
6
6
  #{(usage = rodauth.account_webauthn_usage; last_id = usage.keys.last; usage;).map do |id, last_use|
7
7
  input = rodauth.input_field_string(rodauth.webauthn_remove_param, "webauthn-remove-#{h id}", :type=>'radio', :class=>"form-check-input", :skip_error_message=>true, :value=>id, :required=>false)
8
8
  label = "<label class=\"rodauth-webauthn-id form-check-label\" for=\"webauthn-remove-#{h id}\">Last Use: #{last_use}</label>"
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.12.0
4
+ version: 2.13.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: 2021-04-22 00:00:00.000000000 Z
11
+ date: 2021-05-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sequel
@@ -266,6 +266,7 @@ extra_rdoc_files:
266
266
  - doc/disallow_password_reuse.rdoc
267
267
  - doc/email_auth.rdoc
268
268
  - doc/email_base.rdoc
269
+ - doc/error_reasons.rdoc
269
270
  - doc/http_basic_auth.rdoc
270
271
  - doc/json.rdoc
271
272
  - doc/jwt.rdoc
@@ -323,6 +324,7 @@ extra_rdoc_files:
323
324
  - doc/release_notes/2.10.0.txt
324
325
  - doc/release_notes/2.11.0.txt
325
326
  - doc/release_notes/2.12.0.txt
327
+ - doc/release_notes/2.13.0.txt
326
328
  - doc/release_notes/2.2.0.txt
327
329
  - doc/release_notes/2.3.0.txt
328
330
  - doc/release_notes/2.4.0.txt
@@ -351,6 +353,7 @@ files:
351
353
  - doc/disallow_password_reuse.rdoc
352
354
  - doc/email_auth.rdoc
353
355
  - doc/email_base.rdoc
356
+ - doc/error_reasons.rdoc
354
357
  - doc/guides/admin_activation.rdoc
355
358
  - doc/guides/already_authenticated.rdoc
356
359
  - doc/guides/alternative_login.rdoc
@@ -417,6 +420,7 @@ files:
417
420
  - doc/release_notes/2.10.0.txt
418
421
  - doc/release_notes/2.11.0.txt
419
422
  - doc/release_notes/2.12.0.txt
423
+ - doc/release_notes/2.13.0.txt
420
424
  - doc/release_notes/2.2.0.txt
421
425
  - doc/release_notes/2.3.0.txt
422
426
  - doc/release_notes/2.4.0.txt