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
@@ -1,7 +1,7 @@
1
- <form action="#{rodauth.prefix}/#{rodauth.reset_password_request_route}" method="post" class="rodauth form-horizontal" role="form" id="reset-password-request-form">
1
+ <form action="#{rodauth.reset_password_request_path}" method="post" class="rodauth" role="form" id="reset-password-request-form">
2
2
  #{rodauth.reset_password_request_additional_form_tags}
3
- #{rodauth.csrf_tag("#{rodauth.prefix}/#{rodauth.reset_password_request_route}")}
3
+ #{rodauth.csrf_tag(rodauth.reset_password_request_path)}
4
4
  #{rodauth.reset_password_explanatory_text}
5
- #{(login = rodauth.param_or_nil(rodauth.login_param)) ? "<input type=\"hidden\" name=\"#{rodauth.login_param}\" value=\"#{h login}\"/>" : rodauth.render('login-field')}
5
+ #{rodauth.param_or_nil(rodauth.login_param) && !rodauth.field_error(rodauth.login_param) ? rodauth.login_hidden_field : rodauth.render('login-field')}
6
6
  #{rodauth.button(rodauth.reset_password_request_button)}
7
7
  </form>
@@ -1,8 +1,7 @@
1
- <form method="post" class="rodauth form-horizontal" role="form" id="reset-password-form">
1
+ <form method="post" class="rodauth" role="form" id="reset-password-form">
2
2
  #{rodauth.reset_password_additional_form_tags}
3
3
  #{rodauth.csrf_tag}
4
4
  #{rodauth.render('password-field')}
5
5
  #{rodauth.render('password-confirm-field') if rodauth.require_password_confirmation?}
6
6
  #{rodauth.button(rodauth.reset_password_button)}
7
7
  </form>
8
-
@@ -1,4 +1,4 @@
1
- <form method="post" class="rodauth form-horizontal" role="form" id="sms-auth-form">
1
+ <form method="post" class="rodauth" role="form" id="sms-auth-form">
2
2
  #{rodauth.sms_auth_additional_form_tags}
3
3
  #{rodauth.csrf_tag}
4
4
  #{rodauth.render('sms-code-field')}
@@ -1,6 +1,8 @@
1
1
  <div class="form-group">
2
- <label class="col-sm-3 control-label" for="sms-code">#{rodauth.sms_code_label}#{rodauth.input_field_label_suffix}</label>
3
- <div class="col-sm-3">
4
- #{rodauth.input_field_string(rodauth.sms_code_param, 'sms-code', :value => '')}
2
+ <label for="sms-code">#{rodauth.sms_code_label}#{rodauth.input_field_label_suffix}</label>
3
+ <div class="row">
4
+ <div class="col-sm-3">
5
+ #{rodauth.input_field_string(rodauth.sms_code_param, 'sms-code', :value => '', :autocomplete=>'one-time-code', :inputmode=>'numeric')}
6
+ </div>
5
7
  </div>
6
8
  </div>
@@ -1,7 +1,6 @@
1
- <form method="post" class="rodauth form-horizontal" role="form" id="sms-confirm-form">
1
+ <form method="post" class="rodauth" role="form" id="sms-confirm-form">
2
2
  #{rodauth.sms_confirm_additional_form_tags}
3
3
  #{rodauth.csrf_tag}
4
4
  #{rodauth.render('sms-code-field')}
5
5
  #{rodauth.button(rodauth.sms_confirm_button)}
6
6
  </form>
7
-
@@ -1,7 +1,6 @@
1
- <form method="post" class="rodauth form-horizontal" role="form" id="sms-disable-form">
1
+ <form method="post" class="rodauth" role="form" id="sms-disable-form">
2
2
  #{rodauth.sms_disable_additional_form_tags}
3
3
  #{rodauth.csrf_tag}
4
4
  #{rodauth.render('password-field') if rodauth.two_factor_modifications_require_password?}
5
5
  #{rodauth.button(rodauth.sms_disable_button)}
6
6
  </form>
7
-
@@ -1,4 +1,4 @@
1
- <form method="post" class="rodauth form-horizontal" role="form" id="sms-request-form">
1
+ <form method="post" class="rodauth" role="form" id="sms-request-form">
2
2
  #{rodauth.sms_request_additional_form_tags}
3
3
  #{rodauth.csrf_tag}
4
4
  #{rodauth.button(rodauth.sms_request_button)}
@@ -1,11 +1,13 @@
1
- <form method="post" class="rodauth form-horizontal" role="form" id="sms-setup-form">
1
+ <form method="post" class="rodauth" role="form" id="sms-setup-form">
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
5
  <div class="form-group">
6
- <label class="col-sm-2 control-label" for="sms-phone">#{rodauth.sms_phone_label}#{rodauth.input_field_label_suffix}</label>
7
- <div class="col-sm-3">
8
- #{rodauth.input_field_string(rodauth.sms_phone_param, 'sms-phone')}
6
+ <label for="sms-phone">#{rodauth.sms_phone_label}#{rodauth.input_field_label_suffix}</label>
7
+ <div class="row">
8
+ <div class="col-sm-3">
9
+ #{rodauth.input_field_string(rodauth.sms_phone_param, 'sms-phone', :type=>rodauth.sms_phone_input_type, :autocomplete=>'tel')}
10
+ </div>
9
11
  </div>
10
12
  </div>
11
13
  #{rodauth.button(rodauth.sms_setup_button)}
@@ -0,0 +1,5 @@
1
+ <ul class="rodauth-links rodauth-two-factor-auth-links">
2
+ #{rodauth.two_factor_auth_links.sort.map do |_, link, text|
3
+ "<li><a href=\"#{h link}\">#{h text}</a></li>"
4
+ end.join}
5
+ </ul>
@@ -0,0 +1,6 @@
1
+ <form method="post" class="rodauth" role="form" id="multifactor-disable-form">
2
+ #{rodauth.two_factor_disable_additional_form_tags}
3
+ #{rodauth.csrf_tag}
4
+ #{rodauth.render('password-field') if rodauth.two_factor_modifications_require_password?}
5
+ #{rodauth.button(rodauth.two_factor_disable_button)}
6
+ </form>
@@ -0,0 +1,16 @@
1
+ #{rodauth.two_factor_setup_heading unless rodauth.two_factor_setup_links.empty?}
2
+
3
+ <ul class="rodauth-links rodauth-multifactor-setup-links">
4
+ #{rodauth.two_factor_setup_links.sort.map do |_, link, text|
5
+ "<li><a href=\"#{h link}\">#{h text}</a></li>"
6
+ end.join("\n")}
7
+ </ul>
8
+
9
+ #{rodauth.two_factor_remove_heading unless rodauth.two_factor_remove_links.empty?}
10
+
11
+ <ul class="rodauth-links rodauth-multifactor-remove-links">
12
+ #{rodauth.two_factor_remove_links.sort.map do |_, link, text|
13
+ "<li><a href=\"#{h link}\">#{h text}</a></li>"
14
+ end.join("\n")}
15
+ #{"<li><a href=\"#{h rodauth.two_factor_disable_path}\">#{rodauth.two_factor_disable_link_text}</a></li>" if rodauth.two_factor_remove_links.length > 1}
16
+ </ul>
@@ -1,7 +1,7 @@
1
- <form action="#{rodauth.prefix}/#{rodauth.unlock_account_request_route}" method="post" class="rodauth form-horizontal" role="form" id="unlock-account-request-form">
1
+ <form action="#{rodauth.unlock_account_request_path}" method="post" class="rodauth" role="form" id="unlock-account-request-form">
2
2
  #{rodauth.unlock_account_request_additional_form_tags}
3
- #{rodauth.csrf_tag("#{rodauth.prefix}/#{rodauth.unlock_account_request_route}")}
4
- <input type="hidden" name="#{rodauth.login_param}" value="#{h rodauth.param(rodauth.login_param)}"/>
3
+ #{rodauth.csrf_tag(rodauth.unlock_account_request_path)}
4
+ #{rodauth.login_hidden_field}
5
5
  #{rodauth.unlock_account_request_explanatory_text}
6
- <input type="submit" class="btn btn-primary inline" value="#{rodauth.unlock_account_request_button}"/>
6
+ #{rodauth.button(rodauth.unlock_account_request_button)}
7
7
  </form>
@@ -1,4 +1,4 @@
1
- <form method="post" class="rodauth form-horizontal" role="form" id="unlock-account-form">
1
+ <form method="post" class="rodauth" role="form" id="unlock-account-form">
2
2
  #{rodauth.unlock_account_additional_form_tags}
3
3
  #{rodauth.csrf_tag}
4
4
  #{rodauth.unlock_account_explanatory_text}
@@ -1,7 +1,7 @@
1
- <form action="#{rodauth.prefix}/#{rodauth.verify_account_resend_route}" method="post" class="rodauth form-horizontal" role="form" id="verify-account-resend-form">
1
+ <form action="#{rodauth.verify_account_resend_path}" method="post" class="rodauth" role="form" id="verify-account-resend-form">
2
2
  #{rodauth.verify_account_resend_additional_form_tags}
3
- #{rodauth.csrf_tag("#{rodauth.prefix}/#{rodauth.verify_account_resend_route}")}
3
+ #{rodauth.csrf_tag(rodauth.verify_account_resend_path)}
4
4
  #{rodauth.verify_account_resend_explanatory_text}
5
- #{(login = rodauth.param_or_nil(rodauth.login_param)) ? "<input type=\"hidden\" name=\"#{rodauth.login_param}\" value=\"#{h login}\"/>" : rodauth.render('login-field')}
5
+ #{rodauth.param_or_nil(rodauth.login_param) ? rodauth.login_hidden_field : rodauth.render('login-field')}
6
6
  #{rodauth.button(rodauth.verify_account_resend_button)}
7
7
  </form>
@@ -1,8 +1,7 @@
1
- <form method="post" class="rodauth form-horizontal" role="form" id="verify-account-form">
1
+ <form method="post" class="rodauth" role="form" id="verify-account-form">
2
2
  #{rodauth.verify_account_additional_form_tags}
3
3
  #{rodauth.csrf_tag}
4
4
  #{rodauth.render('password-field') if rodauth.verify_account_set_password?}
5
5
  #{rodauth.render('password-confirm-field') if rodauth.verify_account_set_password? && rodauth.require_password_confirmation?}
6
6
  #{rodauth.button(rodauth.verify_account_button)}
7
7
  </form>
8
-
@@ -1,4 +1,4 @@
1
- <form method="post" class="rodauth form-horizontal" role="form" id="verify-login-change-form">
1
+ <form method="post" class="rodauth" role="form" id="verify-login-change-form">
2
2
  #{rodauth.verify_login_change_additional_form_tags}
3
3
  #{rodauth.csrf_tag}
4
4
  #{rodauth.button(rodauth.verify_login_change_button)}
@@ -0,0 +1,11 @@
1
+ <form method="post" action="#{rodauth.webauthn_auth_form_path}" class="rodauth" role="form" id="webauthn-auth-form" data-credential-options="#{h((cred = rodauth.webauth_credential_options_for_get).as_json.to_json)}">
2
+ #{rodauth.webauthn_auth_additional_form_tags}
3
+ #{rodauth.csrf_tag(rodauth.webauthn_auth_form_path)}
4
+ <input type="hidden" name="#{rodauth.webauthn_auth_challenge_param}" value="#{cred.challenge}" />
5
+ <input type="hidden" name="#{rodauth.webauthn_auth_challenge_hmac_param}" value="#{rodauth.compute_hmac(cred.challenge)}" />
6
+ <input class="rodauth_hidden" aria-hidden="true" type="text" name="#{rodauth.webauthn_auth_param}" id="webauthn-auth" value="" />
7
+ <div id="webauthn-auth-button">
8
+ #{rodauth.button(rodauth.webauthn_auth_button)}
9
+ </div>
10
+ </form>
11
+ <script src="#{rodauth.webauthn_js_host}#{rodauth.webauthn_auth_js_path}"></script>
@@ -0,0 +1,14 @@
1
+ <form method="post" class="rodauth" role="form" id="webauthn-remove-form">
2
+ #{rodauth.webauthn_remove_additional_form_tags}
3
+ #{rodauth.csrf_tag}
4
+ #{rodauth.render('password-field') if rodauth.two_factor_modifications_require_password?}
5
+ <fieldset class="form-group">
6
+ #{(usage = rodauth.account_webauthn_usage; last_id = usage.keys.last; usage;).map do |id, last_use|
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
+ label = "<label class=\"rodauth-webauthn-id form-check-label\" for=\"webauthn-remove-#{h id}\">Last Use: #{last_use}</label>"
9
+ error = rodauth.formatted_field_error(rodauth.webauthn_remove_param) if id == last_id
10
+ "<div class=\"form-check radio\">#{input}#{label}#{error}</div>"
11
+ end.join("\n")}
12
+ </fieldset>
13
+ #{rodauth.button(rodauth.webauthn_remove_button)}
14
+ </form>
@@ -0,0 +1,12 @@
1
+ <form method="post" class="rodauth" role="form" id="webauthn-setup-form" data-credential-options="#{h((cred = rodauth.new_webauthn_credential).as_json.to_json)}">
2
+ #{rodauth.webauthn_setup_additional_form_tags}
3
+ #{rodauth.csrf_tag}
4
+ <input type="hidden" name="#{rodauth.webauthn_setup_challenge_param}" value="#{cred.challenge}" />
5
+ <input type="hidden" name="#{rodauth.webauthn_setup_challenge_hmac_param}" value="#{rodauth.compute_hmac(cred.challenge)}" />
6
+ <input class="rodauth_hidden" aria-hidden="true" type="text" name="#{rodauth.webauthn_setup_param}" id="webauthn-setup" value="" />
7
+ #{rodauth.render('password-field') if rodauth.two_factor_modifications_require_password?}
8
+ <div id="webauthn-setup-button">
9
+ #{rodauth.button(rodauth.webauthn_setup_button)}
10
+ </div>
11
+ </form>
12
+ <script src="#{rodauth.webauthn_js_host}#{rodauth.webauthn_setup_js_path}"></script>
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: 1.22.0
4
+ version: 2.3.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: 2019-10-29 00:00:00.000000000 Z
11
+ date: 2020-08-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sequel
@@ -136,6 +136,20 @@ dependencies:
136
136
  - - ">="
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: webauthn
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">"
144
+ - !ruby/object:Gem::Version
145
+ version: '2'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">"
151
+ - !ruby/object:Gem::Version
152
+ version: '2'
139
153
  - !ruby/object:Gem::Dependency
140
154
  name: minitest
141
155
  requirement: !ruby/object:Gem::Requirement
@@ -193,9 +207,9 @@ dependencies:
193
207
  - !ruby/object:Gem::Version
194
208
  version: 2.1.0
195
209
  description: |
196
- Rodauth is an authentication and account management framework for
197
- rack applications. It's built using Roda and Sequel, but it can
198
- be used as middleware in front of web applications that use
210
+ Rodauth is Ruby's most advanced authentication framework, designed
211
+ to work in all rack applications. It's built using Roda and Sequel,
212
+ but it can be used as middleware in front of web applications that use
199
213
  other web frameworks and database libraries.
200
214
 
201
215
  Rodauth aims to provide strong security for password storage by
@@ -203,6 +217,19 @@ description: |
203
217
  MySQL, and Microsoft SQL Server. Configuration is done via
204
218
  a DSL that makes it easy to override any part of the authentication
205
219
  process.
220
+
221
+ Rodauth supports typical authentication features: such as login and
222
+ logout, changing logins and passwords, and creating, verifying,
223
+ unlocking, and resetting passwords for accounts. Rodauth also
224
+ supports many advanced authentication features:
225
+
226
+ * Secure password storage using security definer database functions
227
+ * Multiple primary multifactor authentication methods (WebAuthn and
228
+ TOTP), as well as backup multifactor authentication methods (SMS
229
+ and recovery codes).
230
+ * Passwordless authentication using email links and WebAuthn
231
+ authenticators.
232
+ * Both standard HTML form and JSON API support for all features.
206
233
  email: code@jeremyevans.net
207
234
  executables: []
208
235
  extensions: []
@@ -220,7 +247,6 @@ extra_rdoc_files:
220
247
  - doc/http_basic_auth.rdoc
221
248
  - doc/create_account.rdoc
222
249
  - doc/email_base.rdoc
223
- - doc/internals.rdoc
224
250
  - doc/disallow_common_passwords.rdoc
225
251
  - doc/disallow_password_reuse.rdoc
226
252
  - doc/password_complexity.rdoc
@@ -230,7 +256,7 @@ extra_rdoc_files:
230
256
  - doc/logout.rdoc
231
257
  - doc/otp.rdoc
232
258
  - doc/login_password_requirements_base.rdoc
233
- - doc/verify_change_login.rdoc
259
+ - doc/jwt_cors.rdoc
234
260
  - doc/password_expiration.rdoc
235
261
  - doc/password_grace_period.rdoc
236
262
  - doc/recovery_codes.rdoc
@@ -246,7 +272,11 @@ extra_rdoc_files:
246
272
  - doc/jwt_refresh.rdoc
247
273
  - doc/verify_account_grace_period.rdoc
248
274
  - doc/verify_login_change.rdoc
249
- - doc/jwt_cors.rdoc
275
+ - doc/webauthn.rdoc
276
+ - doc/webauthn_login.rdoc
277
+ - doc/webauthn_verify_account.rdoc
278
+ - doc/active_sessions.rdoc
279
+ - doc/audit_logging.rdoc
250
280
  - doc/release_notes/1.17.0.txt
251
281
  - doc/release_notes/1.0.0.txt
252
282
  - doc/release_notes/1.1.0.txt
@@ -270,13 +300,19 @@ extra_rdoc_files:
270
300
  - doc/release_notes/1.20.0.txt
271
301
  - doc/release_notes/1.21.0.txt
272
302
  - doc/release_notes/1.22.0.txt
303
+ - doc/release_notes/1.23.0.txt
304
+ - doc/release_notes/2.0.0.txt
305
+ - doc/release_notes/2.1.0.txt
306
+ - doc/release_notes/2.2.0.txt
307
+ - doc/release_notes/2.3.0.txt
273
308
  files:
274
309
  - CHANGELOG
275
310
  - MIT-LICENSE
276
311
  - README.rdoc
277
- - Rakefile
278
312
  - dict/top-10_000-passwords.txt
279
313
  - doc/account_expiration.rdoc
314
+ - doc/active_sessions.rdoc
315
+ - doc/audit_logging.rdoc
280
316
  - doc/base.rdoc
281
317
  - doc/change_login.rdoc
282
318
  - doc/change_password.rdoc
@@ -288,8 +324,28 @@ files:
288
324
  - doc/disallow_password_reuse.rdoc
289
325
  - doc/email_auth.rdoc
290
326
  - doc/email_base.rdoc
327
+ - doc/guides/admin_activation.rdoc
328
+ - doc/guides/already_authenticated.rdoc
329
+ - doc/guides/alternative_login.rdoc
330
+ - doc/guides/create_account_programmatically.rdoc
331
+ - doc/guides/delay_password.rdoc
332
+ - doc/guides/email_only.rdoc
333
+ - doc/guides/i18n.rdoc
334
+ - doc/guides/internals.rdoc
335
+ - doc/guides/links.rdoc
336
+ - doc/guides/login_return.rdoc
337
+ - doc/guides/password_column.rdoc
338
+ - doc/guides/password_confirmation.rdoc
339
+ - doc/guides/password_requirements.rdoc
340
+ - doc/guides/paths.rdoc
341
+ - doc/guides/query_params.rdoc
342
+ - doc/guides/redirects.rdoc
343
+ - doc/guides/registration_field.rdoc
344
+ - doc/guides/require_mfa.rdoc
345
+ - doc/guides/reset_password_autologin.rdoc
346
+ - doc/guides/status_column.rdoc
347
+ - doc/guides/totp_or_recovery.rdoc
291
348
  - doc/http_basic_auth.rdoc
292
- - doc/internals.rdoc
293
349
  - doc/jwt.rdoc
294
350
  - doc/jwt_cors.rdoc
295
351
  - doc/jwt_refresh.rdoc
@@ -318,6 +374,7 @@ files:
318
374
  - doc/release_notes/1.20.0.txt
319
375
  - doc/release_notes/1.21.0.txt
320
376
  - doc/release_notes/1.22.0.txt
377
+ - doc/release_notes/1.23.0.txt
321
378
  - doc/release_notes/1.3.0.txt
322
379
  - doc/release_notes/1.4.0.txt
323
380
  - doc/release_notes/1.5.0.txt
@@ -325,6 +382,10 @@ files:
325
382
  - doc/release_notes/1.7.0.txt
326
383
  - doc/release_notes/1.8.0.txt
327
384
  - doc/release_notes/1.9.0.txt
385
+ - doc/release_notes/2.0.0.txt
386
+ - doc/release_notes/2.1.0.txt
387
+ - doc/release_notes/2.2.0.txt
388
+ - doc/release_notes/2.3.0.txt
328
389
  - doc/remember.rdoc
329
390
  - doc/reset_password.rdoc
330
391
  - doc/session_expiration.rdoc
@@ -334,11 +395,17 @@ files:
334
395
  - doc/update_password_hash.rdoc
335
396
  - doc/verify_account.rdoc
336
397
  - doc/verify_account_grace_period.rdoc
337
- - doc/verify_change_login.rdoc
338
398
  - doc/verify_login_change.rdoc
399
+ - doc/webauthn.rdoc
400
+ - doc/webauthn_login.rdoc
401
+ - doc/webauthn_verify_account.rdoc
402
+ - javascript/webauthn_auth.js
403
+ - javascript/webauthn_setup.js
339
404
  - lib/roda/plugins/rodauth.rb
340
405
  - lib/rodauth.rb
341
406
  - lib/rodauth/features/account_expiration.rb
407
+ - lib/rodauth/features/active_sessions.rb
408
+ - lib/rodauth/features/audit_logging.rb
342
409
  - lib/rodauth/features/base.rb
343
410
  - lib/rodauth/features/change_login.rb
344
411
  - lib/rodauth/features/change_password.rb
@@ -372,49 +439,12 @@ files:
372
439
  - lib/rodauth/features/update_password_hash.rb
373
440
  - lib/rodauth/features/verify_account.rb
374
441
  - lib/rodauth/features/verify_account_grace_period.rb
375
- - lib/rodauth/features/verify_change_login.rb
376
442
  - lib/rodauth/features/verify_login_change.rb
443
+ - lib/rodauth/features/webauthn.rb
444
+ - lib/rodauth/features/webauthn_login.rb
445
+ - lib/rodauth/features/webauthn_verify_account.rb
377
446
  - lib/rodauth/migrations.rb
378
447
  - lib/rodauth/version.rb
379
- - spec/account_expiration_spec.rb
380
- - spec/all.rb
381
- - spec/change_login_spec.rb
382
- - spec/change_password_notify_spec.rb
383
- - spec/change_password_spec.rb
384
- - spec/close_account_spec.rb
385
- - spec/confirm_password_spec.rb
386
- - spec/create_account_spec.rb
387
- - spec/disallow_common_passwords_spec.rb
388
- - spec/disallow_password_reuse_spec.rb
389
- - spec/email_auth_spec.rb
390
- - spec/http_basic_auth_spec.rb
391
- - spec/jwt_cors_spec.rb
392
- - spec/jwt_refresh_spec.rb
393
- - spec/jwt_spec.rb
394
- - spec/lockout_spec.rb
395
- - spec/login_spec.rb
396
- - spec/migrate/001_tables.rb
397
- - spec/migrate/002_account_password_hash_column.rb
398
- - spec/migrate_password/001_tables.rb
399
- - spec/migrate_travis/001_tables.rb
400
- - spec/password_complexity_spec.rb
401
- - spec/password_expiration_spec.rb
402
- - spec/password_grace_period_spec.rb
403
- - spec/remember_spec.rb
404
- - spec/reset_password_spec.rb
405
- - spec/rodauth_spec.rb
406
- - spec/session_expiration_spec.rb
407
- - spec/single_session_spec.rb
408
- - spec/spec_helper.rb
409
- - spec/two_factor_spec.rb
410
- - spec/update_password_hash_spec.rb
411
- - spec/verify_account_grace_period_spec.rb
412
- - spec/verify_account_spec.rb
413
- - spec/verify_change_login_spec.rb
414
- - spec/verify_login_change_spec.rb
415
- - spec/views/layout-other.str
416
- - spec/views/layout.str
417
- - spec/views/login.str
418
448
  - templates/add-recovery-codes.str
419
449
  - templates/button.str
420
450
  - templates/change-login.str
@@ -425,11 +455,15 @@ files:
425
455
  - templates/email-auth-email.str
426
456
  - templates/email-auth-request-form.str
427
457
  - templates/email-auth.str
458
+ - templates/global-logout-field.str
428
459
  - templates/login-confirm-field.str
429
460
  - templates/login-display.str
430
461
  - templates/login-field.str
462
+ - templates/login-form-footer.str
463
+ - templates/login-form.str
431
464
  - templates/login.str
432
465
  - templates/logout.str
466
+ - templates/multi-phase-login.str
433
467
  - templates/otp-auth-code-field.str
434
468
  - templates/otp-auth.str
435
469
  - templates/otp-disable.str
@@ -449,6 +483,9 @@ files:
449
483
  - templates/sms-disable.str
450
484
  - templates/sms-request.str
451
485
  - templates/sms-setup.str
486
+ - templates/two-factor-auth.str
487
+ - templates/two-factor-disable.str
488
+ - templates/two-factor-manage.str
452
489
  - templates/unlock-account-email.str
453
490
  - templates/unlock-account-request.str
454
491
  - templates/unlock-account.str
@@ -457,6 +494,9 @@ files:
457
494
  - templates/verify-account.str
458
495
  - templates/verify-login-change-email.str
459
496
  - templates/verify-login-change.str
497
+ - templates/webauthn-auth.str
498
+ - templates/webauthn-remove.str
499
+ - templates/webauthn-setup.str
460
500
  homepage: https://github.com/jeremyevans/rodauth
461
501
  licenses:
462
502
  - MIT
@@ -472,7 +512,7 @@ rdoc_options:
472
512
  - "--line-numbers"
473
513
  - "--inline-source"
474
514
  - "--title"
475
- - 'Rodauth: Authentication and Account Management Framework for Rack Applications'
515
+ - 'Rodauth: Ruby''s Most Advanced Authentication Framework'
476
516
  - "--main"
477
517
  - README.rdoc
478
518
  require_paths:
@@ -481,14 +521,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
481
521
  requirements:
482
522
  - - ">="
483
523
  - !ruby/object:Gem::Version
484
- version: 1.8.7
524
+ version: 1.9.2
485
525
  required_rubygems_version: !ruby/object:Gem::Requirement
486
526
  requirements:
487
527
  - - ">="
488
528
  - !ruby/object:Gem::Version
489
529
  version: '0'
490
530
  requirements: []
491
- rubygems_version: 3.0.3
531
+ rubygems_version: 3.1.2
492
532
  signing_key:
493
533
  specification_version: 4
494
534
  summary: Authentication and Account Management Framework for Rack Applications