rodauth 1.21.0 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (200) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +182 -0
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +211 -79
  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 +22 -0
  42. data/doc/jwt_refresh.rdoc +18 -8
  43. data/doc/lockout.rdoc +17 -15
  44. data/doc/login.rdoc +10 -2
  45. data/doc/login_password_requirements_base.rdoc +15 -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.22.0.txt +11 -0
  53. data/doc/release_notes/1.23.0.txt +32 -0
  54. data/doc/release_notes/2.0.0.txt +361 -0
  55. data/doc/release_notes/2.1.0.txt +31 -0
  56. data/doc/release_notes/2.2.0.txt +39 -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/confirm_password.rb +40 -2
  79. data/lib/rodauth/features/create_account.rb +8 -13
  80. data/lib/rodauth/features/disallow_common_passwords.rb +1 -1
  81. data/lib/rodauth/features/disallow_password_reuse.rb +1 -1
  82. data/lib/rodauth/features/email_auth.rb +31 -30
  83. data/lib/rodauth/features/email_base.rb +9 -4
  84. data/lib/rodauth/features/http_basic_auth.rb +55 -35
  85. data/lib/rodauth/features/jwt.rb +63 -16
  86. data/lib/rodauth/features/jwt_cors.rb +53 -0
  87. data/lib/rodauth/features/jwt_refresh.rb +32 -9
  88. data/lib/rodauth/features/lockout.rb +12 -14
  89. data/lib/rodauth/features/login.rb +54 -10
  90. data/lib/rodauth/features/login_password_requirements_base.rb +4 -4
  91. data/lib/rodauth/features/otp.rb +77 -80
  92. data/lib/rodauth/features/password_complexity.rb +8 -13
  93. data/lib/rodauth/features/password_expiration.rb +2 -2
  94. data/lib/rodauth/features/password_grace_period.rb +17 -10
  95. data/lib/rodauth/features/recovery_codes.rb +49 -53
  96. data/lib/rodauth/features/remember.rb +11 -27
  97. data/lib/rodauth/features/reset_password.rb +26 -26
  98. data/lib/rodauth/features/session_expiration.rb +6 -4
  99. data/lib/rodauth/features/single_session.rb +8 -6
  100. data/lib/rodauth/features/sms_codes.rb +62 -72
  101. data/lib/rodauth/features/two_factor_base.rb +134 -30
  102. data/lib/rodauth/features/verify_account.rb +29 -21
  103. data/lib/rodauth/features/verify_account_grace_period.rb +18 -9
  104. data/lib/rodauth/features/verify_login_change.rb +12 -11
  105. data/lib/rodauth/features/webauthn.rb +505 -0
  106. data/lib/rodauth/features/webauthn_login.rb +70 -0
  107. data/lib/rodauth/features/webauthn_verify_account.rb +46 -0
  108. data/lib/rodauth/version.rb +2 -2
  109. data/templates/button.str +1 -3
  110. data/templates/change-login.str +1 -2
  111. data/templates/change-password.str +3 -5
  112. data/templates/close-account.str +2 -2
  113. data/templates/confirm-password.str +1 -1
  114. data/templates/create-account.str +1 -1
  115. data/templates/email-auth-email.str +1 -1
  116. data/templates/email-auth-request-form.str +2 -3
  117. data/templates/email-auth.str +1 -1
  118. data/templates/global-logout-field.str +6 -0
  119. data/templates/login-confirm-field.str +2 -4
  120. data/templates/login-display.str +3 -2
  121. data/templates/login-field.str +2 -4
  122. data/templates/login-form-footer.str +6 -0
  123. data/templates/login-form.str +7 -0
  124. data/templates/login.str +1 -9
  125. data/templates/logout.str +1 -1
  126. data/templates/multi-phase-login.str +3 -0
  127. data/templates/otp-auth-code-field.str +5 -3
  128. data/templates/otp-auth.str +1 -1
  129. data/templates/otp-disable.str +1 -1
  130. data/templates/otp-setup.str +3 -3
  131. data/templates/password-confirm-field.str +2 -4
  132. data/templates/password-field.str +2 -4
  133. data/templates/recovery-auth.str +3 -6
  134. data/templates/recovery-codes.str +1 -1
  135. data/templates/remember.str +15 -20
  136. data/templates/reset-password-email.str +1 -1
  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-email.str +1 -1
  149. data/templates/unlock-account-request.str +4 -4
  150. data/templates/unlock-account.str +1 -1
  151. data/templates/verify-account-email.str +1 -1
  152. data/templates/verify-account-resend.str +3 -3
  153. data/templates/verify-account.str +1 -2
  154. data/templates/verify-login-change-email.str +2 -1
  155. data/templates/verify-login-change.str +1 -1
  156. data/templates/webauthn-auth.str +11 -0
  157. data/templates/webauthn-remove.str +14 -0
  158. data/templates/webauthn-setup.str +12 -0
  159. metadata +110 -52
  160. data/Rakefile +0 -179
  161. data/doc/verify_change_login.rdoc +0 -11
  162. data/lib/rodauth/features/verify_change_login.rb +0 -20
  163. data/spec/account_expiration_spec.rb +0 -225
  164. data/spec/all.rb +0 -1
  165. data/spec/change_login_spec.rb +0 -156
  166. data/spec/change_password_notify_spec.rb +0 -33
  167. data/spec/change_password_spec.rb +0 -202
  168. data/spec/close_account_spec.rb +0 -162
  169. data/spec/confirm_password_spec.rb +0 -70
  170. data/spec/create_account_spec.rb +0 -127
  171. data/spec/disallow_common_passwords_spec.rb +0 -93
  172. data/spec/disallow_password_reuse_spec.rb +0 -179
  173. data/spec/email_auth_spec.rb +0 -285
  174. data/spec/http_basic_auth_spec.rb +0 -143
  175. data/spec/jwt_refresh_spec.rb +0 -256
  176. data/spec/jwt_spec.rb +0 -235
  177. data/spec/lockout_spec.rb +0 -250
  178. data/spec/login_spec.rb +0 -328
  179. data/spec/migrate/001_tables.rb +0 -184
  180. data/spec/migrate/002_account_password_hash_column.rb +0 -11
  181. data/spec/migrate_password/001_tables.rb +0 -73
  182. data/spec/migrate_travis/001_tables.rb +0 -141
  183. data/spec/password_complexity_spec.rb +0 -109
  184. data/spec/password_expiration_spec.rb +0 -244
  185. data/spec/password_grace_period_spec.rb +0 -93
  186. data/spec/remember_spec.rb +0 -451
  187. data/spec/reset_password_spec.rb +0 -229
  188. data/spec/rodauth_spec.rb +0 -343
  189. data/spec/session_expiration_spec.rb +0 -58
  190. data/spec/single_session_spec.rb +0 -127
  191. data/spec/spec_helper.rb +0 -327
  192. data/spec/two_factor_spec.rb +0 -1462
  193. data/spec/update_password_hash_spec.rb +0 -40
  194. data/spec/verify_account_grace_period_spec.rb +0 -171
  195. data/spec/verify_account_spec.rb +0 -240
  196. data/spec/verify_change_login_spec.rb +0 -46
  197. data/spec/verify_login_change_spec.rb +0 -232
  198. data/spec/views/layout-other.str +0 -11
  199. data/spec/views/layout.str +0 -11
  200. data/spec/views/login.str +0 -21
@@ -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,5 +1,5 @@
1
1
  Someone has requested a that the account with this email be unlocked.
2
2
  If you did not request the unlocking of this account, please ignore this
3
3
  message. If you requested the unlocking of this account, please go to
4
- #{rodauth.unlock_account_email_link}
4
+ #{rodauth.unlock_account_email_link}
5
5
  to unlock this account.
@@ -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,4 +1,4 @@
1
1
  Someone has created an account with this email address. If you did not create
2
2
  this account, please ignore this message. If you created this account, please go to
3
- #{rodauth.verify_account_email_link}
3
+ #{rodauth.verify_account_email_link}
4
4
  to verify the account.
@@ -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,9 +1,10 @@
1
1
  Someone with an account has requested their login be changed to this email address:
2
2
 
3
3
  Old Login: #{rodauth.verify_login_change_old_login}
4
+
4
5
  New Login: #{rodauth.verify_login_change_new_login}
5
6
 
6
7
  If you did not request this login change, please ignore this message. If you
7
8
  requested this login change, please go to
8
- #{rodauth.verify_login_change_email_link}
9
+ #{rodauth.verify_login_change_email_link}
9
10
  to verify the login change.
@@ -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.21.0
4
+ version: 2.2.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-07-24 00:00:00.000000000 Z
11
+ date: 2020-07-20 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
@@ -150,6 +164,20 @@ dependencies:
150
164
  - - ">="
151
165
  - !ruby/object:Gem::Version
152
166
  version: 5.0.0
167
+ - !ruby/object:Gem::Dependency
168
+ name: minitest-global_expectations
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
153
181
  - !ruby/object:Gem::Dependency
154
182
  name: minitest-hooks
155
183
  requirement: !ruby/object:Gem::Requirement
@@ -179,9 +207,9 @@ dependencies:
179
207
  - !ruby/object:Gem::Version
180
208
  version: 2.1.0
181
209
  description: |
182
- Rodauth is an authentication and account management framework for
183
- rack applications. It's built using Roda and Sequel, but it can
184
- 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
185
213
  other web frameworks and database libraries.
186
214
 
187
215
  Rodauth aims to provide strong security for password storage by
@@ -189,6 +217,19 @@ description: |
189
217
  MySQL, and Microsoft SQL Server. Configuration is done via
190
218
  a DSL that makes it easy to override any part of the authentication
191
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.
192
233
  email: code@jeremyevans.net
193
234
  executables: []
194
235
  extensions: []
@@ -206,7 +247,6 @@ extra_rdoc_files:
206
247
  - doc/http_basic_auth.rdoc
207
248
  - doc/create_account.rdoc
208
249
  - doc/email_base.rdoc
209
- - doc/internals.rdoc
210
250
  - doc/disallow_common_passwords.rdoc
211
251
  - doc/disallow_password_reuse.rdoc
212
252
  - doc/password_complexity.rdoc
@@ -216,7 +256,7 @@ extra_rdoc_files:
216
256
  - doc/logout.rdoc
217
257
  - doc/otp.rdoc
218
258
  - doc/login_password_requirements_base.rdoc
219
- - doc/verify_change_login.rdoc
259
+ - doc/jwt_cors.rdoc
220
260
  - doc/password_expiration.rdoc
221
261
  - doc/password_grace_period.rdoc
222
262
  - doc/recovery_codes.rdoc
@@ -232,6 +272,11 @@ extra_rdoc_files:
232
272
  - doc/jwt_refresh.rdoc
233
273
  - doc/verify_account_grace_period.rdoc
234
274
  - doc/verify_login_change.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
235
280
  - doc/release_notes/1.17.0.txt
236
281
  - doc/release_notes/1.0.0.txt
237
282
  - doc/release_notes/1.1.0.txt
@@ -254,13 +299,19 @@ extra_rdoc_files:
254
299
  - doc/release_notes/1.19.0.txt
255
300
  - doc/release_notes/1.20.0.txt
256
301
  - doc/release_notes/1.21.0.txt
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
257
307
  files:
258
308
  - CHANGELOG
259
309
  - MIT-LICENSE
260
310
  - README.rdoc
261
- - Rakefile
262
311
  - dict/top-10_000-passwords.txt
263
312
  - doc/account_expiration.rdoc
313
+ - doc/active_sessions.rdoc
314
+ - doc/audit_logging.rdoc
264
315
  - doc/base.rdoc
265
316
  - doc/change_login.rdoc
266
317
  - doc/change_password.rdoc
@@ -272,9 +323,30 @@ files:
272
323
  - doc/disallow_password_reuse.rdoc
273
324
  - doc/email_auth.rdoc
274
325
  - doc/email_base.rdoc
326
+ - doc/guides/admin_activation.rdoc
327
+ - doc/guides/already_authenticated.rdoc
328
+ - doc/guides/alternative_login.rdoc
329
+ - doc/guides/create_account_programmatically.rdoc
330
+ - doc/guides/delay_password.rdoc
331
+ - doc/guides/email_only.rdoc
332
+ - doc/guides/i18n.rdoc
333
+ - doc/guides/internals.rdoc
334
+ - doc/guides/links.rdoc
335
+ - doc/guides/login_return.rdoc
336
+ - doc/guides/password_column.rdoc
337
+ - doc/guides/password_confirmation.rdoc
338
+ - doc/guides/password_requirements.rdoc
339
+ - doc/guides/paths.rdoc
340
+ - doc/guides/query_params.rdoc
341
+ - doc/guides/redirects.rdoc
342
+ - doc/guides/registration_field.rdoc
343
+ - doc/guides/require_mfa.rdoc
344
+ - doc/guides/reset_password_autologin.rdoc
345
+ - doc/guides/status_column.rdoc
346
+ - doc/guides/totp_or_recovery.rdoc
275
347
  - doc/http_basic_auth.rdoc
276
- - doc/internals.rdoc
277
348
  - doc/jwt.rdoc
349
+ - doc/jwt_cors.rdoc
278
350
  - doc/jwt_refresh.rdoc
279
351
  - doc/lockout.rdoc
280
352
  - doc/login.rdoc
@@ -300,6 +372,8 @@ files:
300
372
  - doc/release_notes/1.2.0.txt
301
373
  - doc/release_notes/1.20.0.txt
302
374
  - doc/release_notes/1.21.0.txt
375
+ - doc/release_notes/1.22.0.txt
376
+ - doc/release_notes/1.23.0.txt
303
377
  - doc/release_notes/1.3.0.txt
304
378
  - doc/release_notes/1.4.0.txt
305
379
  - doc/release_notes/1.5.0.txt
@@ -307,6 +381,9 @@ files:
307
381
  - doc/release_notes/1.7.0.txt
308
382
  - doc/release_notes/1.8.0.txt
309
383
  - doc/release_notes/1.9.0.txt
384
+ - doc/release_notes/2.0.0.txt
385
+ - doc/release_notes/2.1.0.txt
386
+ - doc/release_notes/2.2.0.txt
310
387
  - doc/remember.rdoc
311
388
  - doc/reset_password.rdoc
312
389
  - doc/session_expiration.rdoc
@@ -316,11 +393,17 @@ files:
316
393
  - doc/update_password_hash.rdoc
317
394
  - doc/verify_account.rdoc
318
395
  - doc/verify_account_grace_period.rdoc
319
- - doc/verify_change_login.rdoc
320
396
  - doc/verify_login_change.rdoc
397
+ - doc/webauthn.rdoc
398
+ - doc/webauthn_login.rdoc
399
+ - doc/webauthn_verify_account.rdoc
400
+ - javascript/webauthn_auth.js
401
+ - javascript/webauthn_setup.js
321
402
  - lib/roda/plugins/rodauth.rb
322
403
  - lib/rodauth.rb
323
404
  - lib/rodauth/features/account_expiration.rb
405
+ - lib/rodauth/features/active_sessions.rb
406
+ - lib/rodauth/features/audit_logging.rb
324
407
  - lib/rodauth/features/base.rb
325
408
  - lib/rodauth/features/change_login.rb
326
409
  - lib/rodauth/features/change_password.rb
@@ -334,6 +417,7 @@ files:
334
417
  - lib/rodauth/features/email_base.rb
335
418
  - lib/rodauth/features/http_basic_auth.rb
336
419
  - lib/rodauth/features/jwt.rb
420
+ - lib/rodauth/features/jwt_cors.rb
337
421
  - lib/rodauth/features/jwt_refresh.rb
338
422
  - lib/rodauth/features/lockout.rb
339
423
  - lib/rodauth/features/login.rb
@@ -353,48 +437,12 @@ files:
353
437
  - lib/rodauth/features/update_password_hash.rb
354
438
  - lib/rodauth/features/verify_account.rb
355
439
  - lib/rodauth/features/verify_account_grace_period.rb
356
- - lib/rodauth/features/verify_change_login.rb
357
440
  - lib/rodauth/features/verify_login_change.rb
441
+ - lib/rodauth/features/webauthn.rb
442
+ - lib/rodauth/features/webauthn_login.rb
443
+ - lib/rodauth/features/webauthn_verify_account.rb
358
444
  - lib/rodauth/migrations.rb
359
445
  - lib/rodauth/version.rb
360
- - spec/account_expiration_spec.rb
361
- - spec/all.rb
362
- - spec/change_login_spec.rb
363
- - spec/change_password_notify_spec.rb
364
- - spec/change_password_spec.rb
365
- - spec/close_account_spec.rb
366
- - spec/confirm_password_spec.rb
367
- - spec/create_account_spec.rb
368
- - spec/disallow_common_passwords_spec.rb
369
- - spec/disallow_password_reuse_spec.rb
370
- - spec/email_auth_spec.rb
371
- - spec/http_basic_auth_spec.rb
372
- - spec/jwt_refresh_spec.rb
373
- - spec/jwt_spec.rb
374
- - spec/lockout_spec.rb
375
- - spec/login_spec.rb
376
- - spec/migrate/001_tables.rb
377
- - spec/migrate/002_account_password_hash_column.rb
378
- - spec/migrate_password/001_tables.rb
379
- - spec/migrate_travis/001_tables.rb
380
- - spec/password_complexity_spec.rb
381
- - spec/password_expiration_spec.rb
382
- - spec/password_grace_period_spec.rb
383
- - spec/remember_spec.rb
384
- - spec/reset_password_spec.rb
385
- - spec/rodauth_spec.rb
386
- - spec/session_expiration_spec.rb
387
- - spec/single_session_spec.rb
388
- - spec/spec_helper.rb
389
- - spec/two_factor_spec.rb
390
- - spec/update_password_hash_spec.rb
391
- - spec/verify_account_grace_period_spec.rb
392
- - spec/verify_account_spec.rb
393
- - spec/verify_change_login_spec.rb
394
- - spec/verify_login_change_spec.rb
395
- - spec/views/layout-other.str
396
- - spec/views/layout.str
397
- - spec/views/login.str
398
446
  - templates/add-recovery-codes.str
399
447
  - templates/button.str
400
448
  - templates/change-login.str
@@ -405,11 +453,15 @@ files:
405
453
  - templates/email-auth-email.str
406
454
  - templates/email-auth-request-form.str
407
455
  - templates/email-auth.str
456
+ - templates/global-logout-field.str
408
457
  - templates/login-confirm-field.str
409
458
  - templates/login-display.str
410
459
  - templates/login-field.str
460
+ - templates/login-form-footer.str
461
+ - templates/login-form.str
411
462
  - templates/login.str
412
463
  - templates/logout.str
464
+ - templates/multi-phase-login.str
413
465
  - templates/otp-auth-code-field.str
414
466
  - templates/otp-auth.str
415
467
  - templates/otp-disable.str
@@ -429,6 +481,9 @@ files:
429
481
  - templates/sms-disable.str
430
482
  - templates/sms-request.str
431
483
  - templates/sms-setup.str
484
+ - templates/two-factor-auth.str
485
+ - templates/two-factor-disable.str
486
+ - templates/two-factor-manage.str
432
487
  - templates/unlock-account-email.str
433
488
  - templates/unlock-account-request.str
434
489
  - templates/unlock-account.str
@@ -437,6 +492,9 @@ files:
437
492
  - templates/verify-account.str
438
493
  - templates/verify-login-change-email.str
439
494
  - templates/verify-login-change.str
495
+ - templates/webauthn-auth.str
496
+ - templates/webauthn-remove.str
497
+ - templates/webauthn-setup.str
440
498
  homepage: https://github.com/jeremyevans/rodauth
441
499
  licenses:
442
500
  - MIT
@@ -452,7 +510,7 @@ rdoc_options:
452
510
  - "--line-numbers"
453
511
  - "--inline-source"
454
512
  - "--title"
455
- - 'Rodauth: Authentication and Account Management Framework for Rack Applications'
513
+ - 'Rodauth: Ruby''s Most Advanced Authentication Framework'
456
514
  - "--main"
457
515
  - README.rdoc
458
516
  require_paths:
@@ -461,14 +519,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
461
519
  requirements:
462
520
  - - ">="
463
521
  - !ruby/object:Gem::Version
464
- version: 1.8.7
522
+ version: 1.9.2
465
523
  required_rubygems_version: !ruby/object:Gem::Requirement
466
524
  requirements:
467
525
  - - ">="
468
526
  - !ruby/object:Gem::Version
469
527
  version: '0'
470
528
  requirements: []
471
- rubygems_version: 3.0.3
529
+ rubygems_version: 3.1.2
472
530
  signing_key:
473
531
  specification_version: 4
474
532
  summary: Authentication and Account Management Framework for Rack Applications