rodauth 1.22.0 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (198) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +190 -0
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +210 -80
  5. data/doc/account_expiration.rdoc +12 -26
  6. data/doc/active_sessions.rdoc +49 -0
  7. data/doc/audit_logging.rdoc +44 -0
  8. data/doc/base.rdoc +75 -128
  9. data/doc/change_login.rdoc +7 -14
  10. data/doc/change_password.rdoc +9 -13
  11. data/doc/change_password_notify.rdoc +2 -2
  12. data/doc/close_account.rdoc +9 -16
  13. data/doc/confirm_password.rdoc +12 -5
  14. data/doc/create_account.rdoc +11 -22
  15. data/doc/disallow_password_reuse.rdoc +6 -13
  16. data/doc/email_auth.rdoc +15 -14
  17. data/doc/email_base.rdoc +6 -15
  18. data/doc/guides/admin_activation.rdoc +46 -0
  19. data/doc/guides/already_authenticated.rdoc +10 -0
  20. data/doc/guides/alternative_login.rdoc +46 -0
  21. data/doc/guides/create_account_programmatically.rdoc +38 -0
  22. data/doc/guides/delay_password.rdoc +25 -0
  23. data/doc/guides/email_only.rdoc +16 -0
  24. data/doc/guides/i18n.rdoc +26 -0
  25. data/doc/{internals.rdoc → guides/internals.rdoc} +0 -0
  26. data/doc/guides/links.rdoc +12 -0
  27. data/doc/guides/login_return.rdoc +37 -0
  28. data/doc/guides/password_column.rdoc +25 -0
  29. data/doc/guides/password_confirmation.rdoc +37 -0
  30. data/doc/guides/password_requirements.rdoc +30 -0
  31. data/doc/guides/paths.rdoc +36 -0
  32. data/doc/guides/query_params.rdoc +9 -0
  33. data/doc/guides/redirects.rdoc +17 -0
  34. data/doc/guides/registration_field.rdoc +68 -0
  35. data/doc/guides/require_mfa.rdoc +30 -0
  36. data/doc/guides/reset_password_autologin.rdoc +21 -0
  37. data/doc/guides/status_column.rdoc +28 -0
  38. data/doc/guides/totp_or_recovery.rdoc +16 -0
  39. data/doc/http_basic_auth.rdoc +10 -1
  40. data/doc/jwt.rdoc +22 -22
  41. data/doc/jwt_cors.rdoc +2 -3
  42. data/doc/jwt_refresh.rdoc +23 -8
  43. data/doc/lockout.rdoc +17 -15
  44. data/doc/login.rdoc +17 -2
  45. data/doc/login_password_requirements_base.rdoc +18 -37
  46. data/doc/logout.rdoc +2 -2
  47. data/doc/otp.rdoc +25 -19
  48. data/doc/password_complexity.rdoc +10 -26
  49. data/doc/password_expiration.rdoc +11 -25
  50. data/doc/password_grace_period.rdoc +16 -2
  51. data/doc/recovery_codes.rdoc +18 -12
  52. data/doc/release_notes/1.23.0.txt +32 -0
  53. data/doc/release_notes/2.0.0.txt +361 -0
  54. data/doc/release_notes/2.1.0.txt +31 -0
  55. data/doc/release_notes/2.2.0.txt +39 -0
  56. data/doc/release_notes/2.3.0.txt +37 -0
  57. data/doc/remember.rdoc +40 -64
  58. data/doc/reset_password.rdoc +12 -9
  59. data/doc/session_expiration.rdoc +1 -0
  60. data/doc/single_session.rdoc +16 -25
  61. data/doc/sms_codes.rdoc +24 -14
  62. data/doc/two_factor_base.rdoc +60 -22
  63. data/doc/verify_account.rdoc +14 -12
  64. data/doc/verify_account_grace_period.rdoc +6 -2
  65. data/doc/verify_login_change.rdoc +9 -8
  66. data/doc/webauthn.rdoc +115 -0
  67. data/doc/webauthn_login.rdoc +15 -0
  68. data/doc/webauthn_verify_account.rdoc +9 -0
  69. data/javascript/webauthn_auth.js +45 -0
  70. data/javascript/webauthn_setup.js +35 -0
  71. data/lib/roda/plugins/rodauth.rb +1 -1
  72. data/lib/rodauth.rb +36 -28
  73. data/lib/rodauth/features/account_expiration.rb +5 -5
  74. data/lib/rodauth/features/active_sessions.rb +158 -0
  75. data/lib/rodauth/features/audit_logging.rb +98 -0
  76. data/lib/rodauth/features/base.rb +144 -43
  77. data/lib/rodauth/features/change_password_notify.rb +2 -2
  78. data/lib/rodauth/features/close_account.rb +8 -6
  79. data/lib/rodauth/features/confirm_password.rb +40 -2
  80. data/lib/rodauth/features/create_account.rb +8 -13
  81. data/lib/rodauth/features/disallow_common_passwords.rb +1 -1
  82. data/lib/rodauth/features/disallow_password_reuse.rb +1 -1
  83. data/lib/rodauth/features/email_auth.rb +31 -30
  84. data/lib/rodauth/features/email_base.rb +9 -4
  85. data/lib/rodauth/features/http_basic_auth.rb +55 -35
  86. data/lib/rodauth/features/jwt.rb +63 -16
  87. data/lib/rodauth/features/jwt_cors.rb +15 -15
  88. data/lib/rodauth/features/jwt_refresh.rb +42 -13
  89. data/lib/rodauth/features/lockout.rb +12 -14
  90. data/lib/rodauth/features/login.rb +64 -15
  91. data/lib/rodauth/features/login_password_requirements_base.rb +13 -8
  92. data/lib/rodauth/features/otp.rb +77 -80
  93. data/lib/rodauth/features/password_complexity.rb +8 -13
  94. data/lib/rodauth/features/password_expiration.rb +2 -2
  95. data/lib/rodauth/features/password_grace_period.rb +17 -10
  96. data/lib/rodauth/features/recovery_codes.rb +49 -53
  97. data/lib/rodauth/features/remember.rb +11 -27
  98. data/lib/rodauth/features/reset_password.rb +26 -26
  99. data/lib/rodauth/features/session_expiration.rb +7 -10
  100. data/lib/rodauth/features/single_session.rb +8 -6
  101. data/lib/rodauth/features/sms_codes.rb +62 -72
  102. data/lib/rodauth/features/two_factor_base.rb +134 -30
  103. data/lib/rodauth/features/verify_account.rb +29 -21
  104. data/lib/rodauth/features/verify_account_grace_period.rb +18 -9
  105. data/lib/rodauth/features/verify_login_change.rb +12 -11
  106. data/lib/rodauth/features/webauthn.rb +505 -0
  107. data/lib/rodauth/features/webauthn_login.rb +70 -0
  108. data/lib/rodauth/features/webauthn_verify_account.rb +46 -0
  109. data/lib/rodauth/migrations.rb +16 -5
  110. data/lib/rodauth/version.rb +2 -2
  111. data/templates/button.str +1 -3
  112. data/templates/change-login.str +1 -2
  113. data/templates/change-password.str +3 -5
  114. data/templates/close-account.str +2 -2
  115. data/templates/confirm-password.str +1 -1
  116. data/templates/create-account.str +1 -1
  117. data/templates/email-auth-request-form.str +2 -3
  118. data/templates/email-auth.str +1 -1
  119. data/templates/global-logout-field.str +6 -0
  120. data/templates/login-confirm-field.str +2 -4
  121. data/templates/login-display.str +3 -2
  122. data/templates/login-field.str +2 -4
  123. data/templates/login-form-footer.str +6 -0
  124. data/templates/login-form.str +7 -0
  125. data/templates/login.str +1 -9
  126. data/templates/logout.str +1 -1
  127. data/templates/multi-phase-login.str +3 -0
  128. data/templates/otp-auth-code-field.str +5 -3
  129. data/templates/otp-auth.str +1 -1
  130. data/templates/otp-disable.str +1 -1
  131. data/templates/otp-setup.str +3 -3
  132. data/templates/password-confirm-field.str +2 -4
  133. data/templates/password-field.str +2 -4
  134. data/templates/recovery-auth.str +3 -6
  135. data/templates/recovery-codes.str +1 -1
  136. data/templates/remember.str +15 -20
  137. data/templates/reset-password-request.str +3 -3
  138. data/templates/reset-password.str +1 -2
  139. data/templates/sms-auth.str +1 -1
  140. data/templates/sms-code-field.str +5 -3
  141. data/templates/sms-confirm.str +1 -2
  142. data/templates/sms-disable.str +1 -2
  143. data/templates/sms-request.str +1 -1
  144. data/templates/sms-setup.str +6 -4
  145. data/templates/two-factor-auth.str +5 -0
  146. data/templates/two-factor-disable.str +6 -0
  147. data/templates/two-factor-manage.str +16 -0
  148. data/templates/unlock-account-request.str +4 -4
  149. data/templates/unlock-account.str +1 -1
  150. data/templates/verify-account-resend.str +3 -3
  151. data/templates/verify-account.str +1 -2
  152. data/templates/verify-login-change.str +1 -1
  153. data/templates/webauthn-auth.str +11 -0
  154. data/templates/webauthn-remove.str +14 -0
  155. data/templates/webauthn-setup.str +12 -0
  156. metadata +94 -54
  157. data/Rakefile +0 -179
  158. data/doc/verify_change_login.rdoc +0 -11
  159. data/lib/rodauth/features/verify_change_login.rb +0 -20
  160. data/spec/account_expiration_spec.rb +0 -225
  161. data/spec/all.rb +0 -1
  162. data/spec/change_login_spec.rb +0 -156
  163. data/spec/change_password_notify_spec.rb +0 -33
  164. data/spec/change_password_spec.rb +0 -202
  165. data/spec/close_account_spec.rb +0 -162
  166. data/spec/confirm_password_spec.rb +0 -70
  167. data/spec/create_account_spec.rb +0 -127
  168. data/spec/disallow_common_passwords_spec.rb +0 -93
  169. data/spec/disallow_password_reuse_spec.rb +0 -179
  170. data/spec/email_auth_spec.rb +0 -285
  171. data/spec/http_basic_auth_spec.rb +0 -143
  172. data/spec/jwt_cors_spec.rb +0 -57
  173. data/spec/jwt_refresh_spec.rb +0 -256
  174. data/spec/jwt_spec.rb +0 -235
  175. data/spec/lockout_spec.rb +0 -250
  176. data/spec/login_spec.rb +0 -328
  177. data/spec/migrate/001_tables.rb +0 -184
  178. data/spec/migrate/002_account_password_hash_column.rb +0 -11
  179. data/spec/migrate_password/001_tables.rb +0 -73
  180. data/spec/migrate_travis/001_tables.rb +0 -141
  181. data/spec/password_complexity_spec.rb +0 -109
  182. data/spec/password_expiration_spec.rb +0 -244
  183. data/spec/password_grace_period_spec.rb +0 -93
  184. data/spec/remember_spec.rb +0 -451
  185. data/spec/reset_password_spec.rb +0 -229
  186. data/spec/rodauth_spec.rb +0 -343
  187. data/spec/session_expiration_spec.rb +0 -58
  188. data/spec/single_session_spec.rb +0 -127
  189. data/spec/spec_helper.rb +0 -327
  190. data/spec/two_factor_spec.rb +0 -1462
  191. data/spec/update_password_hash_spec.rb +0 -40
  192. data/spec/verify_account_grace_period_spec.rb +0 -171
  193. data/spec/verify_account_spec.rb +0 -240
  194. data/spec/verify_change_login_spec.rb +0 -46
  195. data/spec/verify_login_change_spec.rb +0 -232
  196. data/spec/views/layout-other.str +0 -11
  197. data/spec/views/layout.str +0 -11
  198. data/spec/views/login.str +0 -21
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3379479fde31b70cd341f7d862088a1c29f850a4293bbf08a4ddced9f152a026
4
- data.tar.gz: 3ec8abcd54a4da0a230d8d5a064d75febc247ee6ed35e3282b9b3ab2e1dde21d
3
+ metadata.gz: 4ea58deac2998a11cd0cd4b17545eab5fce6fb0acd7751416fd521cbd77d6add
4
+ data.tar.gz: c113c1131f5d756fd3aa5c1dbf083f40506b8822fb1c9b67537069c9e8695fba
5
5
  SHA512:
6
- metadata.gz: 6617d309568f8292c01d00343fdea602692fc6ca0be38d9846f0e8415a6da13cee10007e3286e03e2eb9170f693d4b2420861167225aab35ebea87b111627819
7
- data.tar.gz: 30efd30667ccb724c0796aa58123beb4d2711ac92a032be21d900ae74391901521d60b6b4806463494fc748461ecac3adb28ce3bf7c1956e6dcd4b72b0fea963
6
+ metadata.gz: 1fa2ce1d08a9f09e21d2fb1fe5b71ea3c6fc55181452302a35929229f0fad8c3c5d3d3324d73bee9c69daf0ff7a2d14ddbb731ef994bd3317512627233a69d28
7
+ data.tar.gz: 7a188457006390730f00bc4a2ea5159c002dba66b300fd993929a5b5a491f2f4be0191c7e7c8e4b9e82b2e709b1a4e8ea8f5d335613f262671e1d68507cc2e26
data/CHANGELOG CHANGED
@@ -1,3 +1,193 @@
1
+ === 2.3.0 (2020-08-21)
2
+
3
+ * Return an error status instead of an invalid access token when trying to refresh JWT without an access token in the jwt_refresh feature (jeremyevans)
4
+
5
+ * Allow {create,drop}_database_authentication_functions to work with UUID keys (monorkin, janko) (#117)
6
+
7
+ * Add rodauth.login('login_type') for logging in after setting a valid account (janko) (#114)
8
+
9
+ * Make new refresh token available to the after_refresh_token hook by setting it in the response first (jeremyevans)
10
+
11
+ * Make the jwt_refresh plugin call before_jwt_refresh_route hook (previously the configuration method was ignored) (AlexeyMatskevich) (#110)
12
+
13
+ * Add login_email_regexp, login_not_valid_email_message, and log_valid_email? configuration methods (janko) (#107)
14
+
15
+ === 2.2.0 (2020-07-20)
16
+
17
+ * Allow removing all jwt_refresh tokens when logging out by providing a value of "all" as the token to remove (jeremyevans)
18
+
19
+ * Allow removing specific jwt_refresh token when logging out by providing the token to remove (jeremyevans)
20
+
21
+ * Avoid NoMethodError when checking if session is authenticated when using two factor auth, verify_account_grace_period, and email_auth (jeremyevans) (#105)
22
+
23
+ * Reduce queries in #authenticated? and #require_authentication when using two factor authentication (janko) (#106)
24
+
25
+ * Treat verify_account_email_resend returning false as an error in the verify_account feature (jeremyevans)
26
+
27
+ * Fix use of password_dictionary configuration method in password_complexity feature (jeremyevans)
28
+
29
+ * Remove unnecessary conditionals (jeremyevans)
30
+
31
+ * Add otp_last_use to the otp feature, returning the time of last successful OTP use (jeremyevans) (#103)
32
+
33
+ === 2.1.0 (2020-06-09)
34
+
35
+ * Do not check CSRF tokens by default for requests using JWT (janko, jeremyevans) (#99)
36
+
37
+ * Use new-password autocomplete value for password field when creating accounts (jeremyevans) (#98)
38
+
39
+ * Consistently use json_response_body for all JSON responses in jwt feature (arthurmmoreira) (#97)
40
+
41
+ * Add check_csrf configuration method to customize CSRF checking (janko) (#96)
42
+
43
+ * Have logged_in? when using http_basic_auth feature check for basic authentication (jeremyevans) (#94)
44
+
45
+ * Don't consider account open if in unverified grace period without password (janko) (#92)
46
+
47
+ === 2.0.0 (2020-05-06)
48
+
49
+ * Do not show email auth as an option for unverified accounts if using the verify_account_grace_period feature (jeremyevans) (#88)
50
+
51
+ * Generate unlock account key outside of send_unlock_account_email, similar to other email methods (janko) (#89)
52
+
53
+ * Default otp_drift to 30 in the otp feature (jeremyevans)
54
+
55
+ * Add rodauth.require_http_basic_auth to http_basic_auth feature, similar to require_login (janko) (#86)
56
+
57
+ * Rename require_http_basic_auth to require_http_basic_auth? in http_basic_auth feature (janko) (#86)
58
+
59
+ * Change http_basic_auth feature to use rodauth.http_basic_auth for handling basic authentication, similar to rodauth.load_memory (janko) (#86)
60
+
61
+ * Do not call already_logged_in if logged in when accessing verify_login_change page (janko) (#87)
62
+
63
+ * HTML id attributes now use - instead of _ in recovery_codes and remember features (jeremyevans)
64
+
65
+ * Allow *_path and *_url methods to accept a hash of query parameters (janko) (#84)
66
+
67
+ * Use a danger button when closing accounts (janko) (#83)
68
+
69
+ * Handle invalid form inputs in a more bootstrap compatible manner (janko) (#83)
70
+
71
+ * Use standard vertical Bootstrap forms instead of horizontal forms in templates (janko) (#83)
72
+
73
+ * Make templates compatible with Bootstrap 4, and still display correctly with Bootstrap 3 (janko) (#83)
74
+
75
+ * Add check_csrf_opts and check_csrf_block for arguments to the check_csrf! call before Rodauth route dispatching (jeremyevans)
76
+
77
+ * Add audit_logging feature, logging changes to a database table (jeremyevans)
78
+
79
+ * Add hook_action configuration method, called after all before/after hooks (jeremyevans)
80
+
81
+ * Enable email rate limiting by default in lockout, reset_password, and verify_account features (jeremyevans)
82
+
83
+ * Add session_expiration_error_status method to the session_expiration feature, used for JSON requests where session has expired (jeremyevans)
84
+
85
+ * Add domain configuration method to set an explicit domain, instead of relying on the host of the request (jeremyevans)
86
+
87
+ * Add inactive_session_error_status to single_session feature, used for JSON requests where session is no longer active (jeremyevans)
88
+
89
+ * Prevent use of previous JWT access tokens after refresh when using jwt_refresh and active_sessions features (jeremyevans)
90
+
91
+ * Change default setting of jwt_check_accept? from false to true in the jwt feature (jeremyevans)
92
+
93
+ * Automatically check CSRF tokens before calling any Rodauth route by default, allow disabling using check_csrf? false (jeremyevans)
94
+
95
+ * Add translate(key, default_value) configuration method and have it affect all translatable content (jeremyevans)
96
+
97
+ * Add *_page_title configuration methods for all *_view configuration methods (jeremyevans)
98
+
99
+ * Default to using Roda's route_csrf plugin for CSRF support, with :csrf=>:rack_csrf available for using rack_csrf (jeremyevans)
100
+
101
+ * Allow ability for user to fix an incorrect login when requesting a password reset (janko, jeremyevans) (#76)
102
+
103
+ * Add two_factor_auth_return_to_requested_location? to support returning to original page after successful second factor authentication (janko) (#69)
104
+
105
+ * Add login_return_to_requested_location? to support returning to original page after successful login (janko) (#69)
106
+
107
+ * Add rodauth.require_password_authentication method to confirm_password feature (janko, jeremyevans) (#75)
108
+
109
+ * Make remember feature no longer depend on confirm_password (janko) (#79)
110
+
111
+ * Replace {create_account,reset_password_request,verify_account_resend}_link configuration methods with *_link_text (janko) (#77)
112
+
113
+ * Remove remembered_session_key configuration method, no longer needed (janko) (#80)
114
+
115
+ * Add rodauth.possible_authentication_methods for the available authentication methods for the account (jeremyevans)
116
+
117
+ * Add active_sessions feature for disabling session reuse after logout, and allowing global logout of all sessions (jeremyevans)
118
+
119
+ * Add webauthn_verify_account feature for passwordless WebAuthn setup during account verification (jeremyevans)
120
+
121
+ * Allow confirm_password feature to operate as second factor authentication if using webauthn login (jeremyevans)
122
+
123
+ * Add webauthn_login feature for passwordless login via WebAuthn (jeremyevans)
124
+
125
+ * Do not allow two factor authentication using same type as primary authentication (jeremyevans)
126
+
127
+ * Do not require passwords by default if the account does not have a password (jeremyevans)
128
+
129
+ * Remove clear_remembered_session_key and two_factor_session_key configuration methods, no longer needed (jeremyevans)
130
+
131
+ * Store authentication methods used in the session, available via rodauth.authenticated_by (jeremyevans)
132
+
133
+ * Do not require login confirmation by default if verifying accounts or login changes (jeremyevans)
134
+
135
+ * Add mark_input_fields_with_inputmode? and inputmode_for_field? configuration methods for controlling inputmode (jeremyevans)
136
+
137
+ * Support and enable inputmode=numeric attributes by default for otp auth code and sms code fields (jeremyevans)
138
+
139
+ * Add sms_phone_input_type and default to tel instead of using text for SMS phone input (jeremyevans)
140
+
141
+ * Add mark_input_fields_with_autocomplete? and autocomplete_for_field? configuration methods for controlling autocomplete (jeremyevans)
142
+
143
+ * Support and enable autocomplete attributes by default for fields (jeremyevans)
144
+
145
+ * Add login_uses_email? configuration method for whether to treat logins as email addresses (jeremyevans)
146
+
147
+ * Remove the verify change login feature, users should switch to the verify login change feature (jeremyevans)
148
+
149
+ * Change default setting of json_response_success_key to success in the jwt feature (jeremyevans)
150
+
151
+ * Remove deprecated account_model configuration method (jeremyevans)
152
+
153
+ * Remove all deprecated configuration and runtime method aliases in the lockout, verify_account, email_auth, reset_password, and verify_login_change features (jeremyevans)
154
+
155
+ * Remove deprecated before_otp_authentication_route configuration method (jeremyevans)
156
+
157
+ * Change default setting of login_input_type to email if login_column is :email (jeremyevans)
158
+
159
+ * Change default setting of mark_input_fields_as_required? to true (jeremyevans)
160
+
161
+ * Change default setting of verify_account_set_password? in verify_account feature to true (jeremyevans)
162
+
163
+ * Change default setting of json_response_custom_error_status? in jwt feature to true (jeremyevans)
164
+
165
+ * Add auto_add_recovery_codes? configuration method to recovery codes feature, and default to false (jeremyevans)
166
+
167
+ * Add base_url configuration method to set an explicit base for URLs, instead of relying on the base_url of the request (jeremyevans)
168
+
169
+ * Add webauthn feature to handle WebAuthn authentication (jeremyevans)
170
+
171
+ * Fix corner cases when disabling a second factor when multiple second factors have been setup (jeremyevans)
172
+
173
+ * Don't override second factor used to authenticate when setting up additional second factor authentication (jeremyevans)
174
+
175
+ * Add two factor auth, manage, and disable pages (jeremyevans)
176
+
177
+ * Drop support for Ruby 1.8 (jeremyevans)
178
+
179
+ === 1.23.0 (2020-03-06)
180
+
181
+ * Remove specs from the gem to reduce gem size by over 20% (jeremyevans)
182
+
183
+ * Make rodauth.authenticated? return true on OTP setup page (jeremyevans) (#68)
184
+
185
+ * Display link to email auth request form when user has entered login and incorrect password if using email_auth feature (janko) (#65)
186
+
187
+ * Add *_path and *_url methods for all *_route methods (janko) (#64)
188
+
189
+ * Add send_email configuration method for configuring how email is sent (janko) (#63)
190
+
1
191
  === 1.22.0 (2019-10-29)
2
192
 
3
193
  * Add jwt_cors feature to handle Cross-Origin Resource Sharing when using the jwt feature (jeremyevans)
@@ -1,4 +1,4 @@
1
- Copyright (c) 2015-2019 Jeremy Evans
1
+ Copyright (c) 2015-2020 Jeremy Evans
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  of this software and associated documentation files (the "Software"), to
@@ -1,12 +1,18 @@
1
1
  = Rodauth
2
2
 
3
- Rodauth is an authentication and account management framework for
4
- rack applications. It's built using Roda and Sequel, but it can
5
- be used with other web frameworks, database libraries, and databases.
3
+ Rodauth is Ruby's most advanced authentication framework, designed
4
+ to work in any rack application. It's built using Roda and Sequel,
5
+ but it can be used with other web frameworks, database libraries,
6
+ and databases.
7
+
6
8
  When used with PostgreSQL, MySQL, and Microsoft SQL Server in the
7
9
  default configuration, it offers additional security for password
8
10
  hashes by protecting access via database functions.
9
11
 
12
+ Rodauth supports multiple multifactor authentication methods,
13
+ multiple passwordless authentication methods, and offers both an
14
+ HTML and JSON API for all supported features.
15
+
10
16
  == Design Goals
11
17
 
12
18
  * Security: Ship in a maximum security by default configuration
@@ -26,10 +32,14 @@ hashes by protecting access via database functions.
26
32
  * Confirm Password
27
33
  * Remember (Autologin via token)
28
34
  * Lockout (Bruteforce protection)
29
- * Email Authentication (Login via email link)
30
- * OTP (2 factor authentication via TOTP)
31
- * Recovery Codes (2 factor authentication via backup codes)
32
- * SMS Codes (2 factor authentication via SMS)
35
+ * Audit Logging
36
+ * Email Authentication (Passwordless login via email link)
37
+ * WebAuthn (Multifactor authentication via WebAuthn)
38
+ * WebAuthn Login (Passwordless login via WebAuthn)
39
+ * WebAuthn Verify Account (Passwordless WebAuthn Setup)
40
+ * OTP (Multifactor authentication via TOTP)
41
+ * Recovery Codes (Multifactor authentication via backup codes)
42
+ * SMS Codes (Multifactor authentication via SMS)
33
43
  * Verify Login Change (Verify new login before changing login)
34
44
  * Verify Account Grace Period (Don't require verification before login)
35
45
  * Password Grace Period (Don't require password entry if recently entered)
@@ -39,6 +49,7 @@ hashes by protecting access via database functions.
39
49
  * Password Expiration
40
50
  * Account Expiration
41
51
  * Session Expiration
52
+ * Active Sessions (Prevent session reuse after logout, allow logout of all sessions)
42
53
  * Single Session (Only one active session per account)
43
54
  * JWT (JSON API support for all other features)
44
55
  * JWT Refresh (Access & Refresh Token)
@@ -58,21 +69,24 @@ IRC :: irc://chat.freenode.net/#rodauth
58
69
 
59
70
  == Dependencies
60
71
 
61
- There are some dependencies that Rodauth uses by default, but are
62
- development dependencies instead of runtime dependencies in the
63
- gem as it is possible to run without them:
72
+ There are some dependencies that Rodauth uses depending on the
73
+ features in use. These are development dependencies instead of
74
+ runtime dependencies in the gem as it is possible to run without them:
64
75
 
65
76
  tilt :: Used by all features unless in JSON API only mode.
66
- rack_csrf :: Used by all features unless in JSON API only mode
67
- or the :csrf=>false|:route_csrf option is used when
68
- loading the Rodauth plugin.
77
+ rack_csrf :: Used for CSRF support if the :csrf=>:rack_csrf plugin
78
+ option is given (the default is to use Roda's route_csrf
79
+ plugin, as that allows for more secure request-specific
80
+ tokens).
69
81
  bcrypt :: Used by default for password matching, can be skipped
70
82
  if password_match? is overridden for custom authentication.
71
83
  mail :: Used by default for mailing in the reset password, verify
72
- account, verify_login_change, change_password_notify, and
73
- lockout features.
74
- rotp, rqrcode :: Used by the otp feature
84
+ account, verify_login_change, change_password_notify,
85
+ lockout, and email_auth features.
86
+ rotp :: Used by the otp feature
87
+ rqrcode :: Used by the otp feature
75
88
  jwt :: Used by the jwt feature
89
+ webauthn :: Used by the webauthn feature
76
90
 
77
91
  == Security
78
92
 
@@ -143,10 +157,10 @@ function to reduce the risk of timing attacks.
143
157
 
144
158
  == HMAC
145
159
 
146
- By default, Rodauth does not use HMACs, but you are encouraged to use
147
- the +hmac_secret+ configuration method to set an HMAC secret. Setting
148
- an HMAC secret will enable HMACs for additional security, as described
149
- below.
160
+ By default, for backwards compatibility, Rodauth does not use HMACs,
161
+ but you are strongly encouraged to use the +hmac_secret+ configuration
162
+ method to set an HMAC secret. Setting an HMAC secret will enable HMACs
163
+ for additional security, as described below.
150
164
 
151
165
  === email_base feature
152
166
 
@@ -213,6 +227,17 @@ to the OTP setup route. This will return an error with the +otp_secret+ and
213
227
  in the POST request to setup OTP, along with a valid OTP auth code for the
214
228
  +otp_secret+.
215
229
 
230
+ === webauthn feature
231
+
232
+ Setting +hmac_secret+ is required to use the webauthn feature, as it is
233
+ used for checking that the provided authentication challenges have not
234
+ been modified.
235
+
236
+ === active_sessions feature
237
+
238
+ Setting +hmac_secret+ is required to use the active_sessions feature,
239
+ as the database stores an HMAC of the active session ID.
240
+
216
241
  === single_session feature
217
242
 
218
243
  Setting +hmac_secret+ will ensure the single session secret set in the
@@ -406,6 +431,25 @@ Note that these migrations require Sequel 4.35.0+.
406
431
  end
407
432
  end
408
433
 
434
+ # Used by the audit logging feature
435
+ json_type = case database_type
436
+ when :postgres
437
+ :jsonb
438
+ when :sqlite, :mysql
439
+ :json
440
+ else
441
+ String
442
+ end
443
+ create_table(:account_authentication_audit_logs) do
444
+ primary_key :id, :type=>:Bignum
445
+ foreign_key :account_id, :accounts, :null=>false, :type=>:Bignum
446
+ DateTime :at, :null=>false, :default=>Sequel::CURRENT_TIMESTAMP
447
+ String :message, :null=>false
448
+ column :metadata, json_type
449
+ index [:account_id, :at], :name=>:audit_account_at_idx
450
+ index :at, :name=>:audit_at_idx
451
+ end
452
+
409
453
  # Used by the password reset feature
410
454
  create_table(:account_password_reset_keys) do
411
455
  foreign_key :id, :accounts, :primary_key=>true, :type=>:Bignum
@@ -417,9 +461,10 @@ Note that these migrations require Sequel 4.35.0+.
417
461
  # Used by the jwt refresh feature
418
462
  create_table(:account_jwt_refresh_keys) do
419
463
  primary_key :id, :type=>:Bignum
420
- foreign_key :account_id, :accounts, :type=>:Bignum
464
+ foreign_key :account_id, :accounts, :null=>false, :type=>:Bignum
421
465
  String :key, :null=>false
422
466
  DateTime :deadline, deadline_opts[1]
467
+ index :account_id, :name=>:account_jwt_rk_account_id_idx
423
468
  end
424
469
 
425
470
  # Used by the account verification feature
@@ -485,6 +530,29 @@ Note that these migrations require Sequel 4.35.0+.
485
530
  String :key, :null=>false
486
531
  end
487
532
 
533
+ # Used by the active sessions feature
534
+ create_table(:account_active_session_keys) do
535
+ foreign_key :account_id, :accounts, :type=>:Bignum
536
+ String :session_id
537
+ Time :created_at, :null=>false, :default=>Sequel::CURRENT_TIMESTAMP
538
+ Time :last_use, :null=>false, :default=>Sequel::CURRENT_TIMESTAMP
539
+ primary_key [:account_id, :session_id]
540
+ end
541
+
542
+ # Used by the webauthn feature
543
+ create_table(:account_webauthn_user_ids) do
544
+ foreign_key :id, :accounts, :primary_key=>true, :type=>:Bignum
545
+ String :webauthn_id, :null=>false
546
+ end
547
+ create_table(:account_webauthn_keys) do
548
+ foreign_key :account_id, :accounts, :type=>:Bignum
549
+ String :webauthn_id
550
+ String :public_key, :null=>false
551
+ Integer :sign_count, :null=>false
552
+ Time :last_use, :null=>false, :default=>Sequel::CURRENT_TIMESTAMP
553
+ primary_key [:account_id, :webauthn_id]
554
+ end
555
+
488
556
  # Used by the otp feature
489
557
  create_table(:account_otp_keys) do
490
558
  foreign_key :id, :accounts, :primary_key=>true, :type=>:Bignum
@@ -519,22 +587,26 @@ Note that these migrations require Sequel 4.35.0+.
519
587
  else
520
588
  get(Sequel.function(:DB_NAME))
521
589
  end
522
- run "GRANT ALL ON account_statuses TO #{user}"
523
- run "GRANT ALL ON accounts TO #{user}"
524
- run "GRANT ALL ON account_password_reset_keys TO #{user}"
525
- run "GRANT ALL ON account_jwt_refresh_keys TO #{user}"
526
- run "GRANT ALL ON account_verification_keys TO #{user}"
527
- run "GRANT ALL ON account_login_change_keys TO #{user}"
528
- run "GRANT ALL ON account_remember_keys TO #{user}"
529
- run "GRANT ALL ON account_login_failures TO #{user}"
530
- run "GRANT ALL ON account_lockouts TO #{user}"
531
- run "GRANT ALL ON account_email_auth_keys TO #{user}"
532
- run "GRANT ALL ON account_password_change_times TO #{user}"
533
- run "GRANT ALL ON account_activity_times TO #{user}"
534
- run "GRANT ALL ON account_session_keys TO #{user}"
535
- run "GRANT ALL ON account_otp_keys TO #{user}"
536
- run "GRANT ALL ON account_recovery_codes TO #{user}"
537
- run "GRANT ALL ON account_sms_codes TO #{user}"
590
+ run "GRANT SELECT, INSERT, UPDATE, DELETE ON account_statuses TO #{user}"
591
+ run "GRANT SELECT, INSERT, UPDATE, DELETE ON accounts TO #{user}"
592
+ run "GRANT SELECT, INSERT, UPDATE, DELETE ON account_authentication_audit_logs TO #{user}"
593
+ run "GRANT SELECT, INSERT, UPDATE, DELETE ON account_password_reset_keys TO #{user}"
594
+ run "GRANT SELECT, INSERT, UPDATE, DELETE ON account_jwt_refresh_keys TO #{user}"
595
+ run "GRANT SELECT, INSERT, UPDATE, DELETE ON account_verification_keys TO #{user}"
596
+ run "GRANT SELECT, INSERT, UPDATE, DELETE ON account_login_change_keys TO #{user}"
597
+ run "GRANT SELECT, INSERT, UPDATE, DELETE ON account_remember_keys TO #{user}"
598
+ run "GRANT SELECT, INSERT, UPDATE, DELETE ON account_login_failures TO #{user}"
599
+ run "GRANT SELECT, INSERT, UPDATE, DELETE ON account_email_auth_keys TO #{user}"
600
+ run "GRANT SELECT, INSERT, UPDATE, DELETE ON account_lockouts TO #{user}"
601
+ run "GRANT SELECT, INSERT, UPDATE, DELETE ON account_password_change_times TO #{user}"
602
+ run "GRANT SELECT, INSERT, UPDATE, DELETE ON account_activity_times TO #{user}"
603
+ run "GRANT SELECT, INSERT, UPDATE, DELETE ON account_session_keys TO #{user}"
604
+ run "GRANT SELECT, INSERT, UPDATE, DELETE ON account_active_session_keys TO #{user}"
605
+ run "GRANT SELECT, INSERT, UPDATE, DELETE ON account_webauthn_user_ids TO #{user}"
606
+ run "GRANT SELECT, INSERT, UPDATE, DELETE ON account_webauthn_keys TO #{user}"
607
+ run "GRANT SELECT, INSERT, UPDATE, DELETE ON account_otp_keys TO #{user}"
608
+ run "GRANT SELECT, INSERT, UPDATE, DELETE ON account_recovery_codes TO #{user}"
609
+ run "GRANT SELECT, INSERT, UPDATE, DELETE ON account_sms_codes TO #{user}"
538
610
  end
539
611
  end
540
612
 
@@ -542,7 +614,10 @@ Note that these migrations require Sequel 4.35.0+.
542
614
  drop_table(:account_sms_codes,
543
615
  :account_recovery_codes,
544
616
  :account_otp_keys,
617
+ :account_webauthn_keys,
618
+ :account_webauthn_user_ids,
545
619
  :account_session_keys,
620
+ :account_active_session_keys,
546
621
  :account_activity_times,
547
622
  :account_password_change_times,
548
623
  :account_email_auth_keys,
@@ -553,6 +628,7 @@ Note that these migrations require Sequel 4.35.0+.
553
628
  :account_verification_keys,
554
629
  :account_jwt_refresh_keys,
555
630
  :account_password_reset_keys,
631
+ :account_authentication_audit_logs,
556
632
  :accounts,
557
633
  :account_statuses)
558
634
  end
@@ -644,7 +720,8 @@ for the password user using Sequel's migration API:
644
720
 
645
721
  If the database is not PostgreSQL, MySQL, or Microsoft SQL Server, or you
646
722
  cannot use multiple user accounts, just combine the two migrations into a
647
- single migration.
723
+ single migration, removing all the code related to database permissions
724
+ and database functions.
648
725
 
649
726
  One thing to notice in the above migrations is that Rodauth uses additional
650
727
  tables for additional features, instead of additional columns in a single
@@ -761,10 +838,8 @@ should be flexible enough to integrate into most legacy systems.
761
838
  When loading the rodauth plugin, you can also pass an options hash,
762
839
  which configures which dependent plugins should be loaded. Options:
763
840
 
764
- :csrf :: Set to +false+ to not load a csrf plugin. Set to +:route_csrf+
765
- to use the route_csrf plugin instead of the csrf plugin. It is
766
- recommended to set the +:route_csrf+ option as that allows
767
- for more secure request-specific CSRF tokens.
841
+ :csrf :: Set to +false+ to not load a csrf plugin. Set to +:rack_csrf+
842
+ to use the csrf plugin instead of the route_csrf plugin.
768
843
  :flash :: Set to +false+ to not load the flash plugin
769
844
  :json :: Set to +true+ to load the json and json_parser plugins. Set
770
845
  to +:only+ to only load those plugins and not any other plugins.
@@ -783,42 +858,46 @@ view the appropriate file in the doc directory.
783
858
  * {Login Password Requirements Base}[rdoc-ref:doc/login_password_requirements_base.rdoc] (this feature is autoloaded by features that set logins/passwords)
784
859
  * {Email Base}[rdoc-ref:doc/email_base.rdoc] (this feature is autoloaded by features that send email)
785
860
  * {Two Factor Base}[rdoc-ref:doc/two_factor_base.rdoc] (this feature is autoloaded by 2 factor authentication features)
786
- * {Login}[rdoc-ref:doc/login.rdoc]
787
- * {Logout}[rdoc-ref:doc/logout.rdoc]
861
+ * {Account Expiration}[rdoc-ref:doc/account_expiration.rdoc]
862
+ * {Active Sessions}[rdoc-ref:doc/active_sessions.rdoc]
863
+ * {Audit Logging}[rdoc-ref:doc/audit_logging.rdoc]
864
+ * {Change Login}[rdoc-ref:doc/change_login.rdoc]
788
865
  * {Change Password}[rdoc-ref:doc/change_password.rdoc]
789
866
  * {Change Password Notify}[rdoc-ref:doc/change_password_notify.rdoc]
790
- * {Change Login}[rdoc-ref:doc/change_login.rdoc]
791
- * {Reset Password}[rdoc-ref:doc/reset_password.rdoc]
792
- * {Create Account}[rdoc-ref:doc/create_account.rdoc]
793
867
  * {Close Account}[rdoc-ref:doc/close_account.rdoc]
794
- * {Verify Account}[rdoc-ref:doc/verify_account.rdoc]
795
868
  * {Confirm Password}[rdoc-ref:doc/confirm_password.rdoc]
796
- * {Remember}[rdoc-ref:doc/remember.rdoc]
797
- * {Lockout}[rdoc-ref:doc/lockout.rdoc]
869
+ * {Create Account}[rdoc-ref:doc/create_account.rdoc]
870
+ * {Disallow Common Passwords}[rdoc-ref:doc/disallow_common_passwords.rdoc]
871
+ * {Disallow Password Reuse}[rdoc-ref:doc/disallow_password_reuse.rdoc]
798
872
  * {Email Authentication}[rdoc-ref:doc/email_auth.rdoc]
873
+ * {HTTP Basic Auth}[rdoc-ref:doc/http_basic_auth.rdoc]
874
+ * {JWT CORS}[rdoc-ref:doc/jwt_cors.rdoc]
875
+ * {JWT Refresh}[rdoc-ref:doc/jwt_refresh.rdoc]
876
+ * {JWT}[rdoc-ref:doc/jwt.rdoc]
877
+ * {Lockout}[rdoc-ref:doc/lockout.rdoc]
878
+ * {Login}[rdoc-ref:doc/login.rdoc]
879
+ * {Logout}[rdoc-ref:doc/logout.rdoc]
799
880
  * {OTP}[rdoc-ref:doc/otp.rdoc]
800
- * {Recovery Codes}[rdoc-ref:doc/recovery_codes.rdoc]
801
- * {SMS Codes}[rdoc-ref:doc/sms_codes.rdoc]
802
- * {Verify Login Change}[rdoc-ref:doc/verify_login_change.rdoc]
803
- * {Verify Change Login}[rdoc-ref:doc/verify_change_login.rdoc]
804
- * {Verify Account Grace Period}[rdoc-ref:doc/verify_account_grace_period.rdoc]
805
- * {Password Grace Period}[rdoc-ref:doc/password_grace_period.rdoc]
806
881
  * {Password Complexity}[rdoc-ref:doc/password_complexity.rdoc]
807
- * {Disallow Password Reuse}[rdoc-ref:doc/disallow_password_reuse.rdoc]
808
- * {Disallow Common Passwords}[rdoc-ref:doc/disallow_common_passwords.rdoc]
809
- * {Update Password Hash}[rdoc-ref:doc/update_password_hash.rdoc]
810
882
  * {Password Expiration}[rdoc-ref:doc/password_expiration.rdoc]
811
- * {Account Expiration}[rdoc-ref:doc/account_expiration.rdoc]
883
+ * {Password Grace Period}[rdoc-ref:doc/password_grace_period.rdoc]
884
+ * {Recovery Codes}[rdoc-ref:doc/recovery_codes.rdoc]
885
+ * {Remember}[rdoc-ref:doc/remember.rdoc]
886
+ * {Reset Password}[rdoc-ref:doc/reset_password.rdoc]
812
887
  * {Session Expiration}[rdoc-ref:doc/session_expiration.rdoc]
813
888
  * {Single Session}[rdoc-ref:doc/single_session.rdoc]
814
- * {JWT}[rdoc-ref:doc/jwt.rdoc]
815
- * {JWT Refresh}[rdoc-ref:doc/jwt_refresh.rdoc]
816
- * {JWT CORS}[rdoc-ref:doc/jwt_cors.rdoc]
817
- * {HTTP Basic Auth}[rdoc-ref:doc/http_basic_auth.rdoc]
889
+ * {SMS Codes}[rdoc-ref:doc/sms_codes.rdoc]
890
+ * {Update Password Hash}[rdoc-ref:doc/update_password_hash.rdoc]
891
+ * {Verify Account}[rdoc-ref:doc/verify_account.rdoc]
892
+ * {Verify Account Grace Period}[rdoc-ref:doc/verify_account_grace_period.rdoc]
893
+ * {Verify Login Change}[rdoc-ref:doc/verify_login_change.rdoc]
894
+ * {WebAuthn}[rdoc-ref:doc/webauthn.rdoc]
895
+ * {WebAuthn Login}[rdoc-ref:doc/webauthn_login.rdoc]
896
+ * {WebAuthn Verify Account}[rdoc-ref:doc/webauthn_verify_account.rdoc]
818
897
 
819
898
  === Calling Rodauth in the Routing Tree
820
899
 
821
- In general, you will usually want to call rodauth early in your
900
+ In general, you will usually want to call +r.rodauth+ early in your
822
901
  route block:
823
902
 
824
903
  route do |r|
@@ -897,6 +976,12 @@ logged_in? :: Whether the session has been logged in.
897
976
  authenticated? :: Similar to +logged_in?+, but if the account has setup two
898
977
  factor authentication, whether the session has authenticated
899
978
  via two factors.
979
+ authenticated_by :: An array of strings for successful authentication methods for
980
+ the current session (e.g. password/remember/webauthn).
981
+ possible_authentication_methods :: An array of strings for possible authentication
982
+ types that can be used for the account.
983
+ autologin_type :: If the current session was authenticated via autologin, the
984
+ type of autologin used.
900
985
  require_two_factor_setup :: (two_factor_base feature) Require the session to have
901
986
  setup two factor authentication, redirecting the
902
987
  request to the two factor authentication setup page
@@ -911,6 +996,14 @@ require_current_password :: (password_expiration feature) Require a current
911
996
  password, redirecting the request to the change
912
997
  password page if the password for the account has
913
998
  expired.
999
+ require_password_authentication :: (confirm_password feature) If not authenticated
1000
+ via password and the account has a password,
1001
+ redirect to the password confirmation page,
1002
+ saving the current location to redirect back
1003
+ to after password has been successfully
1004
+ confirmed. If the password_grace_period feature
1005
+ is used, also redirect if the password has not
1006
+ been recently entered.
914
1007
  load_memory :: (remember feature) If the session has not been authenticated, look
915
1008
  for the remember cookie. If present and valid, automatically
916
1009
  log the session in, but mark that it was logged in via a remember
@@ -920,9 +1013,15 @@ logged_in_via_remember_key? :: (remember feature) Whether the current session ha
920
1013
  sensitive actions where you want to require the user
921
1014
  to reenter the password, you can use the
922
1015
  confirm_password feature.
1016
+ http_basic_auth :: (http_basic_auth feature) Use HTTP Basic Authentication information
1017
+ to login the user if provided.
1018
+ require_http_basic_auth :: (http_basic_auth feature) Require that HTTP Basic
1019
+ Authentication be provided in the request.
923
1020
  check_session_expiration :: (session_expiration feature) Check whether the current
924
1021
  session has expired, automatically logging the session
925
1022
  out if so.
1023
+ check_active_session :: (active_sessions feature) Check whether the current session
1024
+ is still active, automatically logging the session out if not.
926
1025
  check_single_session :: (single_session feature) Check whether the current
927
1026
  session is still the only valid session, automatically logging
928
1027
  the session out if not.
@@ -931,6 +1030,15 @@ verified_account? :: (verify_grace_period feature) Whether the account is curren
931
1030
  login as they are in the grace period.
932
1031
  locked_out? :: (lockout feature) Whether the account for the current session has been
933
1032
  locked out.
1033
+ authenticated_webauthn_id :: (webauthn feature) If the current session was
1034
+ authenticated via webauthn, the webauthn id of the
1035
+ credential used.
1036
+ *_path :: One of these is added for each of the routes added by Rodauth, giving the
1037
+ relative path to the route. Any options passed to this method will be
1038
+ converted into query parameters.
1039
+ *_url :: One of these is added for each of the routes added by Rodauth, giving the
1040
+ URL to the route. Any options passed to this method will be converted
1041
+ into query parameters.
934
1042
 
935
1043
  === With Multiple Configurations
936
1044
 
@@ -1062,6 +1170,20 @@ Facebook OAuth access token.
1062
1170
  end
1063
1171
  end
1064
1172
 
1173
+ === With Rails
1174
+
1175
+ If you're using Rails, you can use the
1176
+ {rodauth-rails}[https://github.com/janko/rodauth-rails] gem which provides
1177
+ Rails integration for Rodauth. Some of its features include:
1178
+
1179
+ * generators for Rodauth & Sequel configuration, as well as views and mailers
1180
+ * uses Rails' flash messages and CSRF protection
1181
+ * automatically sets HMAC secret to Rails' secret key base
1182
+ * uses Action Controller & Action View for rendering templates
1183
+ * uses Action Mailer for sending emails
1184
+
1185
+ Follow the instructions in the rodauth-rails README to get started.
1186
+
1065
1187
  === With Other Web Frameworks
1066
1188
 
1067
1189
  You can use Rodauth even if your application does not use the Roda web
@@ -1100,25 +1222,26 @@ Here are some examples of integrating Rodauth into applications that
1100
1222
  don't use Roda:
1101
1223
 
1102
1224
  * {Ginatra, a Sinatra-based git repository viewer}[https://github.com/jeremyevans/ginatra/commit/28108ebec96e8d42596ee55b01c3f7b50c155dd1]
1103
- * {Rodauth's demo site as a Rails application}[https://github.com/jeremyevans/rodauth-demo-rails] (
1104
- This uses the {roda-rails gem}[https://github.com/jeremyevans/roda-rails]
1105
- so that Rodauth uses Rails' CSRF and flash support)
1225
+ * {Rodauth's demo site as a Rails 6 application}[https://github.com/janko/rodauth-demo-rails]
1106
1226
  * {Grape application}[https://github.com/davydovanton/grape-rodauth]
1107
1227
  * {Hanami application}[https://github.com/davydovanton/rodauth_hanami]
1108
1228
 
1109
1229
  === Using 2 Factor Authentication
1110
1230
 
1111
- Rodauth ships with 2 factor authentication support via TOTP (Time-Based
1112
- One-Time Passwords, RFC 6238). There are a wide variety of ways in
1113
- which to integrate 2 factor authentication into your site with Rodauth,
1114
- based on the needs of the application.
1231
+ Rodauth ships with 2 factor authentication support via the following
1232
+ methods:
1233
+
1234
+ * WebAuthn
1235
+ * TOTP (Time-Based One-Time Passwords, RFC 6238).
1236
+ * SMS Codes
1237
+ * Recovery Codes
1115
1238
 
1116
- The 2 factor authentication support is part of the OTP feature, which
1117
- needs to be enabled in addition to the login feature. In addition,
1118
- when implementing 2 factor authentication, you should generally
1119
- provide a backup 2nd factor if the primary second factor is not
1120
- available. Rodauth supports SMS codes and recovery codes as other
1121
- 2nd factors.
1239
+ There are multiple ways to integrate 2 factor authentication with
1240
+ Rodauth, based on the needs of the application. By default, SMS
1241
+ codes and recovery codes are treated only as backup 2nd factors,
1242
+ a user cannot enable them without first enabling another 2nd factor
1243
+ authentication method. However, you can change this by using
1244
+ a configuration method.
1122
1245
 
1123
1246
  If you want to support but not require 2 factor authentication:
1124
1247
 
@@ -1132,7 +1255,7 @@ If you want to support but not require 2 factor authentication:
1132
1255
  # ...
1133
1256
  end
1134
1257
 
1135
- If you want to force all users to use OTP authentication, requiring users
1258
+ If you want to force all users to use 2 factor authentication, requiring users
1136
1259
  that don't currently have two authentication to set it up:
1137
1260
 
1138
1261
  route do |r|
@@ -1249,7 +1372,7 @@ use the following basic structure
1249
1372
  end
1250
1373
  end
1251
1374
 
1252
- See the source code for the features that ship with Rodauth for an
1375
+ See the {internals guide}[rdoc-ref:doc/internals.rdoc] for a more complete
1253
1376
  example of how to construct features.
1254
1377
 
1255
1378
  === Overriding Route-Level Behavior
@@ -1279,6 +1402,13 @@ benefit from precompiling your rodauth templates:
1279
1402
  end
1280
1403
  precompile_rodauth_templates
1281
1404
 
1405
+ == Ruby Support Policy
1406
+
1407
+ Rodauth fully supports the currently supported versions of Ruby (MRI) and JRuby. It may
1408
+ support unsupported versions of Ruby or JRuby, but such support may be dropped in any
1409
+ minor version if keeping it becomes a support issue. The minimum Ruby version
1410
+ required to run the current version of Rodauth is 1.9.2.
1411
+
1282
1412
  == Similar Projects
1283
1413
 
1284
1414
  All of these are Rails-specific: