rodauth-rails 0.9.1 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +54 -0
  3. data/README.md +467 -249
  4. data/lib/generators/rodauth/install_generator.rb +17 -0
  5. data/lib/generators/rodauth/templates/app/lib/rodauth_app.rb +41 -30
  6. data/lib/generators/rodauth/templates/app/mailers/rodauth_mailer.rb +3 -3
  7. data/lib/generators/rodauth/templates/app/views/rodauth/_email_auth_request_form.html.erb +1 -1
  8. data/lib/generators/rodauth/templates/app/views/rodauth/_field.html.erb +2 -2
  9. data/lib/generators/rodauth/templates/app/views/rodauth/_field_error.html.erb +2 -2
  10. data/lib/generators/rodauth/templates/app/views/rodauth/_global_logout_field.html.erb +2 -2
  11. data/lib/generators/rodauth/templates/app/views/rodauth/_login_confirm_field.html.erb +3 -3
  12. data/lib/generators/rodauth/templates/app/views/rodauth/_login_display.html.erb +3 -3
  13. data/lib/generators/rodauth/templates/app/views/rodauth/_login_field.html.erb +3 -3
  14. data/lib/generators/rodauth/templates/app/views/rodauth/_login_form.html.erb +3 -3
  15. data/lib/generators/rodauth/templates/app/views/rodauth/_login_form_footer.html.erb +2 -2
  16. data/lib/generators/rodauth/templates/app/views/rodauth/_login_form_header.html.erb +2 -2
  17. data/lib/generators/rodauth/templates/app/views/rodauth/_login_hidden_field.html.erb +1 -1
  18. data/lib/generators/rodauth/templates/app/views/rodauth/_new_password_field.html.erb +3 -3
  19. data/lib/generators/rodauth/templates/app/views/rodauth/_otp_auth_code_field.html.erb +3 -3
  20. data/lib/generators/rodauth/templates/app/views/rodauth/_password_confirm_field.html.erb +3 -3
  21. data/lib/generators/rodauth/templates/app/views/rodauth/_password_field.html.erb +3 -3
  22. data/lib/generators/rodauth/templates/app/views/rodauth/_recovery_code_field.html.erb +3 -3
  23. data/lib/generators/rodauth/templates/app/views/rodauth/_recovery_codes_form.html.erb +4 -4
  24. data/lib/generators/rodauth/templates/app/views/rodauth/_sms_code_field.html.erb +3 -3
  25. data/lib/generators/rodauth/templates/app/views/rodauth/_sms_phone_field.html.erb +3 -3
  26. data/lib/generators/rodauth/templates/app/views/rodauth/_submit.html.erb +1 -1
  27. data/lib/generators/rodauth/templates/app/views/rodauth/add_recovery_codes.html.erb +2 -2
  28. data/lib/generators/rodauth/templates/app/views/rodauth/change_login.html.erb +3 -3
  29. data/lib/generators/rodauth/templates/app/views/rodauth/change_password.html.erb +3 -3
  30. data/lib/generators/rodauth/templates/app/views/rodauth/close_account.html.erb +2 -2
  31. data/lib/generators/rodauth/templates/app/views/rodauth/confirm_password.html.erb +1 -1
  32. data/lib/generators/rodauth/templates/app/views/rodauth/create_account.html.erb +4 -4
  33. data/lib/generators/rodauth/templates/app/views/rodauth/email_auth.html.erb +1 -1
  34. data/lib/generators/rodauth/templates/app/views/rodauth/logout.html.erb +2 -2
  35. data/lib/generators/rodauth/templates/app/views/rodauth/multi_phase_login.html.erb +1 -1
  36. data/lib/generators/rodauth/templates/app/views/rodauth/otp_auth.html.erb +1 -1
  37. data/lib/generators/rodauth/templates/app/views/rodauth/otp_disable.html.erb +2 -2
  38. data/lib/generators/rodauth/templates/app/views/rodauth/otp_setup.html.erb +9 -9
  39. data/lib/generators/rodauth/templates/app/views/rodauth/recovery_auth.html.erb +1 -1
  40. data/lib/generators/rodauth/templates/app/views/rodauth/remember.html.erb +5 -5
  41. data/lib/generators/rodauth/templates/app/views/rodauth/reset_password.html.erb +2 -2
  42. data/lib/generators/rodauth/templates/app/views/rodauth/reset_password_request.html.erb +2 -2
  43. data/lib/generators/rodauth/templates/app/views/rodauth/sms_auth.html.erb +1 -1
  44. data/lib/generators/rodauth/templates/app/views/rodauth/sms_confirm.html.erb +1 -1
  45. data/lib/generators/rodauth/templates/app/views/rodauth/sms_disable.html.erb +2 -2
  46. data/lib/generators/rodauth/templates/app/views/rodauth/sms_request.html.erb +1 -1
  47. data/lib/generators/rodauth/templates/app/views/rodauth/sms_setup.html.erb +2 -2
  48. data/lib/generators/rodauth/templates/app/views/rodauth/two_factor_auth.html.erb +1 -1
  49. data/lib/generators/rodauth/templates/app/views/rodauth/two_factor_disable.html.erb +2 -2
  50. data/lib/generators/rodauth/templates/app/views/rodauth/two_factor_manage.html.erb +6 -6
  51. data/lib/generators/rodauth/templates/app/views/rodauth/unlock_account.html.erb +2 -2
  52. data/lib/generators/rodauth/templates/app/views/rodauth/unlock_account_request.html.erb +1 -1
  53. data/lib/generators/rodauth/templates/app/views/rodauth/verify_account.html.erb +3 -3
  54. data/lib/generators/rodauth/templates/app/views/rodauth/verify_account_resend.html.erb +2 -2
  55. data/lib/generators/rodauth/templates/app/views/rodauth/verify_login_change.html.erb +1 -1
  56. data/lib/generators/rodauth/templates/app/views/rodauth/webauthn_auth.html.erb +7 -7
  57. data/lib/generators/rodauth/templates/app/views/rodauth/webauthn_remove.html.erb +6 -6
  58. data/lib/generators/rodauth/templates/app/views/rodauth/webauthn_setup.html.erb +7 -7
  59. data/lib/generators/rodauth/templates/app/views/rodauth_mailer/unlock_account.text.erb +1 -1
  60. data/lib/generators/rodauth/views_generator.rb +25 -4
  61. data/lib/rodauth/rails.rb +36 -4
  62. data/lib/rodauth/rails/app.rb +19 -21
  63. data/lib/rodauth/rails/app/flash.rb +2 -8
  64. data/lib/rodauth/rails/app/middleware.rb +20 -10
  65. data/lib/rodauth/rails/auth.rb +37 -0
  66. data/lib/rodauth/rails/controller_methods.rb +1 -5
  67. data/lib/rodauth/rails/feature.rb +17 -210
  68. data/lib/rodauth/rails/feature/base.rb +62 -0
  69. data/lib/rodauth/rails/feature/callbacks.rb +61 -0
  70. data/lib/rodauth/rails/feature/csrf.rb +65 -0
  71. data/lib/rodauth/rails/feature/email.rb +30 -0
  72. data/lib/rodauth/rails/feature/instrumentation.rb +71 -0
  73. data/lib/rodauth/rails/feature/render.rb +48 -0
  74. data/lib/rodauth/rails/version.rb +1 -1
  75. data/rodauth-rails.gemspec +1 -1
  76. metadata +12 -6
  77. data/lib/generators/rodauth/mailer_generator.rb +0 -37
@@ -1,4 +1,4 @@
1
- <%%= form_tag rodauth.otp_auth_path, method: :post do %>
1
+ <%%= form_tag <%= rodauth %>.otp_auth_path, method: :post do %>
2
2
  <%%= render "otp_auth_code_field" %>
3
3
  <%%= render "submit", value: "Authenticate Using TOTP" %>
4
4
  <%% end %>
@@ -1,4 +1,4 @@
1
- <%%= form_tag rodauth.otp_disable_path, method: :post do %>
2
- <%%= render "password_field" if rodauth.two_factor_modifications_require_password? %>
1
+ <%%= form_tag <%= rodauth %>.otp_disable_path, method: :post do %>
2
+ <%%= render "password_field" if <%= rodauth %>.two_factor_modifications_require_password? %>
3
3
  <%%= render "submit", value: "Disable TOTP Authentication", class: "btn btn-warning" %>
4
4
  <%% end %>
@@ -1,21 +1,21 @@
1
- <%%= form_tag rodauth.otp_setup_path, method: :post do %>
2
- <%%= hidden_field_tag rodauth.otp_setup_param, rodauth.otp_user_key, id: "otp-key" %>
3
- <%%= hidden_field_tag rodauth.otp_setup_raw_param, rodauth.otp_key, id: "otp-hmac-secret" if rodauth.otp_keys_use_hmac? %>
1
+ <%%= form_tag <%= rodauth %>.otp_setup_path, method: :post do %>
2
+ <%%= hidden_field_tag <%= rodauth %>.otp_setup_param, <%= rodauth %>.otp_user_key, id: "otp-key" %>
3
+ <%%= hidden_field_tag <%= rodauth %>.otp_setup_raw_param, <%= rodauth %>.otp_key, id: "otp-hmac-secret" if <%= rodauth %>.otp_keys_use_hmac? %>
4
4
 
5
- <div class="form-group">
6
- <p>Secret: <%%= rodauth.otp_user_key %></p>
7
- <p>Provisioning URL: <%%= rodauth.otp_provisioning_uri %></p>
5
+ <div class="form-group mb-3">
6
+ <p>Secret: <%%= <%= rodauth %>.otp_user_key %></p>
7
+ <p>Provisioning URL: <%%= <%= rodauth %>.otp_provisioning_uri %></p>
8
8
  </div>
9
9
 
10
10
  <div class="row">
11
11
  <div class="col-lg-6 col-lg">
12
- <div class="form-group">
13
- <p><%%= rodauth.otp_qr_code.html_safe %></p>
12
+ <div class="form-group mb-3">
13
+ <p><%%= <%= rodauth %>.otp_qr_code.html_safe %></p>
14
14
  </div>
15
15
  </div>
16
16
 
17
17
  <div class="col-lg-6 col-lg">
18
- <%%= render "password_field" if rodauth.two_factor_modifications_require_password? %>
18
+ <%%= render "password_field" if <%= rodauth %>.two_factor_modifications_require_password? %>
19
19
  <%%= render "otp_auth_code_field" %>
20
20
  <%%= render "submit", value: "Setup TOTP Authentication" %>
21
21
  </div>
@@ -1,4 +1,4 @@
1
- <%%= form_tag rodauth.recovery_auth_path, method: :post do %>
1
+ <%%= form_tag <%= rodauth %>.recovery_auth_path, method: :post do %>
2
2
  <%%= render "recovery_code_field" %>
3
3
  <%%= render "submit", value: "Authenticate via Recovery Code" %>
4
4
  <%% end %>
@@ -1,17 +1,17 @@
1
- <%%= form_tag rodauth.remember_path, method: :post do %>
2
- <fieldset class="form-group">
1
+ <%%= form_tag <%= rodauth %>.remember_path, method: :post do %>
2
+ <fieldset class="form-group mb-3">
3
3
  <div class="form-check">
4
- <%%= radio_button_tag rodauth.remember_param, rodauth.remember_remember_param_value, false, id: "remember-remember", class: "form-check-input" %>
4
+ <%%= radio_button_tag <%= rodauth %>.remember_param, <%= rodauth %>.remember_remember_param_value, false, id: "remember-remember", class: "form-check-input" %>
5
5
  <%%= label_tag "remember-remember", "Remember Me", class: "form-check-label" %>
6
6
  </div>
7
7
 
8
8
  <div class="form-check">
9
- <%%= radio_button_tag rodauth.remember_param, rodauth.remember_forget_param_value, false, id: "remember-forget", class: "form-check-input" %>
9
+ <%%= radio_button_tag <%= rodauth %>.remember_param, <%= rodauth %>.remember_forget_param_value, false, id: "remember-forget", class: "form-check-input" %>
10
10
  <%%= label_tag "remember-forget", "Forget Me", class: "form-check-label" %>
11
11
  </div>
12
12
 
13
13
  <div class="form-check">
14
- <%%= radio_button_tag rodauth.remember_param, rodauth.remember_disable_param_value, false, id: "remember-disable", class: "form-check-input" %>
14
+ <%%= radio_button_tag <%= rodauth %>.remember_param, <%= rodauth %>.remember_disable_param_value, false, id: "remember-disable", class: "form-check-input" %>
15
15
  <%%= label_tag "remember-disable", "Disable Remember Me", class: "form-check-label" %>
16
16
  </div>
17
17
  </fieldset>
@@ -1,5 +1,5 @@
1
- <%%= form_tag rodauth.reset_password_path, method: :post do %>
1
+ <%%= form_tag <%= rodauth %>.reset_password_path, method: :post do %>
2
2
  <%%= render "password_field" %>
3
- <%%= render "password_confirm_field" if rodauth.require_password_confirmation? %>
3
+ <%%= render "password_confirm_field" if <%= rodauth %>.require_password_confirmation? %>
4
4
  <%%= render "submit", value: "Reset Password" %>
5
5
  <%% end %>
@@ -1,6 +1,6 @@
1
- <%%= form_tag rodauth.reset_password_request_path, method: :post do %>
1
+ <%%= form_tag <%= rodauth %>.reset_password_request_path, method: :post do %>
2
2
  <p>If you have forgotten your password, you can request a password reset:</p>
3
- <%% if params[rodauth.login_param] && !rodauth.field_error(rodauth.login_param) %>
3
+ <%% if params[<%= rodauth %>.login_param] && !<%= rodauth %>.field_error(<%= rodauth %>.login_param) %>
4
4
  <%%= render "login_hidden_field" %>
5
5
  <%% else %>
6
6
  <%%= render "login_field" %>
@@ -1,4 +1,4 @@
1
- <%%= form_tag rodauth.sms_auth_path, method: :post do %>
1
+ <%%= form_tag <%= rodauth %>.sms_auth_path, method: :post do %>
2
2
  <%%= render "sms_code_field" %>
3
3
  <%%= render "submit", value: "Authenticate via SMS Code" %>
4
4
  <%% end %>
@@ -1,4 +1,4 @@
1
- <%%= form_tag rodauth.sms_confirm_path, method: :post do %>
1
+ <%%= form_tag <%= rodauth %>.sms_confirm_path, method: :post do %>
2
2
  <%%= render "sms_code_field" %>
3
3
  <%%= render "submit", value: "Confirm SMS Backup Number" %>
4
4
  <%% end %>
@@ -1,4 +1,4 @@
1
- <%%= form_tag rodauth.sms_disable_path, method: :post do %>
2
- <%%= render "password_field" if rodauth.two_factor_modifications_require_password? %>
1
+ <%%= form_tag <%= rodauth %>.sms_disable_path, method: :post do %>
2
+ <%%= render "password_field" if <%= rodauth %>.two_factor_modifications_require_password? %>
3
3
  <%%= render "submit", value: "Disable Backup SMS Authentication" %>
4
4
  <%% end %>
@@ -1,3 +1,3 @@
1
- <%%= form_tag rodauth.sms_request_path, method: :post do %>
1
+ <%%= form_tag <%= rodauth %>.sms_request_path, method: :post do %>
2
2
  <%%= render "submit", value: "Send SMS Code" %>
3
3
  <%% end %>
@@ -1,5 +1,5 @@
1
- <%%= form_tag rodauth.sms_setup_path, method: :post do %>
2
- <%%= render "password_field" if rodauth.two_factor_modifications_require_password? %>
1
+ <%%= form_tag <%= rodauth %>.sms_setup_path, method: :post do %>
2
+ <%%= render "password_field" if <%= rodauth %>.two_factor_modifications_require_password? %>
3
3
  <%%= render "sms_phone_field" %>
4
4
  <%%= render "submit", value: "Setup SMS Backup Number" %>
5
5
  <%% end %>
@@ -1,5 +1,5 @@
1
1
  <ul>
2
- <%% rodauth.two_factor_auth_links.sort.each do |_, link, text| %>
2
+ <%% <%= rodauth %>.two_factor_auth_links.sort.each do |_, link, text| %>
3
3
  <li><%%= link_to text, link %></li>
4
4
  <%% end %>
5
5
  </ul>
@@ -1,4 +1,4 @@
1
- <%%= form_tag rodauth.two_factor_disable_path, method: :post do %>
2
- <%%= render "password_field" if rodauth.two_factor_modifications_require_password? %>
1
+ <%%= form_tag <%= rodauth %>.two_factor_disable_path, method: :post do %>
2
+ <%%= render "password_field" if <%= rodauth %>.two_factor_modifications_require_password? %>
3
3
  <%%= render "submit", value: "Remove All Multifactor Authentication Methods" %>
4
4
  <%% end %>
@@ -1,22 +1,22 @@
1
- <%% if rodauth.two_factor_setup_links.any? %>
1
+ <%% if <%= rodauth %>.two_factor_setup_links.any? %>
2
2
  <h2>Setup Multifactor Authentication</h2>
3
3
 
4
4
  <ul>
5
- <%% rodauth.two_factor_setup_links.sort.each do |_, link, text| %>
5
+ <%% <%= rodauth %>.two_factor_setup_links.sort.each do |_, link, text| %>
6
6
  <li><%%= link_to text, link %></li>
7
7
  <%% end %>
8
8
  </ul>
9
9
  <%% end %>
10
10
 
11
- <%% if rodauth.two_factor_remove_links.any? %>
11
+ <%% if <%= rodauth %>.two_factor_remove_links.any? %>
12
12
  <h2>Remove Multifactor Authentication</h2>
13
13
 
14
14
  <ul>
15
- <%% rodauth.two_factor_remove_links.sort.each do |_, link, text| %>
15
+ <%% <%= rodauth %>.two_factor_remove_links.sort.each do |_, link, text| %>
16
16
  <li><%%= link_to text, link %></li>
17
17
  <%% end %>
18
- <%% if rodauth.two_factor_remove_links.length > 1 %>
19
- <li><%%= link_to "Remove All Multifactor Authentication Methods", rodauth.two_factor_disable_path %></li>
18
+ <%% if <%= rodauth %>.two_factor_remove_links.length > 1 %>
19
+ <li><%%= link_to "Remove All Multifactor Authentication Methods", <%= rodauth %>.two_factor_disable_path %></li>
20
20
  <%% end %>
21
21
  </ul>
22
22
  <%% end %>
@@ -1,5 +1,5 @@
1
- <%%= form_tag rodauth.unlock_account_path, method: :post do %>
1
+ <%%= form_tag <%= rodauth %>.unlock_account_path, method: :post do %>
2
2
  <p>This account is currently locked out. You can unlock the account:</p>
3
- <%%= render "password_field" if rodauth.unlock_account_requires_password? %>
3
+ <%%= render "password_field" if <%= rodauth %>.unlock_account_requires_password? %>
4
4
  <%%= render "submit", value: "Unlock Account" %>
5
5
  <%% end %>
@@ -1,4 +1,4 @@
1
- <%%= form_tag rodauth.unlock_account_request_path, method: :post do %>
1
+ <%%= form_tag <%= rodauth %>.unlock_account_request_path, method: :post do %>
2
2
  <p>This account is currently locked out. You can request that the account be unlocked:</p>
3
3
  <%%= render "login_hidden_field" %>
4
4
  <%%= render "submit", value: "Request Account Unlock" %>
@@ -1,5 +1,5 @@
1
- <%%= form_tag rodauth.verify_account_path, method: :post do %>
2
- <%%= render "password_field" if rodauth.verify_account_set_password? %>
3
- <%%= render "password_confirm_field" if rodauth.verify_account_set_password? && rodauth.require_password_confirmation? %>
1
+ <%%= form_tag <%= rodauth %>.verify_account_path, method: :post do %>
2
+ <%%= render "password_field" if <%= rodauth %>.verify_account_set_password? %>
3
+ <%%= render "password_confirm_field" if <%= rodauth %>.verify_account_set_password? && <%= rodauth %>.require_password_confirmation? %>
4
4
  <%%= render "submit", value: "Verify Account" %>
5
5
  <%% end %>
@@ -1,6 +1,6 @@
1
- <%%= form_tag rodauth.verify_account_resend_path, method: :post do %>
1
+ <%%= form_tag <%= rodauth %>.verify_account_resend_path, method: :post do %>
2
2
  <p>If you no longer have the email to verify the account, you can request that it be resent to you:</p>
3
- <%% if params[rodauth.login_param] %>
3
+ <%% if params[<%= rodauth %>.login_param] %>
4
4
  <%%= render "login_hidden_field" %>
5
5
  <%% else %>
6
6
  <%%= render "login_field" %>
@@ -1,3 +1,3 @@
1
- <%%= form_tag rodauth.verify_login_change_path, method: :post do %>
1
+ <%%= form_tag <%= rodauth %>.verify_login_change_path, method: :post do %>
2
2
  <%%= render "submit", value: "Verify Login Change" %>
3
3
  <%% end %>
@@ -1,13 +1,13 @@
1
- <%% cred = rodauth.webauth_credential_options_for_get %>
1
+ <%% cred = <%= rodauth %>.webauth_credential_options_for_get %>
2
2
 
3
- <%%= form_tag rodauth.webauthn_auth_form_path, method: :post, id: "webauthn-auth-form", data: { credential_options: cred.as_json.to_json } do %>
4
- <%%= render "login_hidden_field" if params[rodauth.login_param] %>
5
- <%%= hidden_field_tag rodauth.webauthn_auth_challenge_param, cred.challenge %>
6
- <%%= hidden_field_tag rodauth.webauthn_auth_challenge_hmac_param, rodauth.compute_hmac(cred.challenge) %>
7
- <%%= text_field_tag rodauth.webauthn_auth_param, "", id: "webauthn-auth", aria: { hidden: "true" } %>
3
+ <%%= form_tag <%= rodauth %>.webauthn_auth_form_path, method: :post, id: "webauthn-auth-form", data: { credential_options: cred.as_json.to_json } do %>
4
+ <%%= render "login_hidden_field" if params[<%= rodauth %>.login_param] %>
5
+ <%%= hidden_field_tag <%= rodauth %>.webauthn_auth_challenge_param, cred.challenge %>
6
+ <%%= hidden_field_tag <%= rodauth %>.webauthn_auth_challenge_hmac_param, <%= rodauth %>.compute_hmac(cred.challenge) %>
7
+ <%%= text_field_tag <%= rodauth %>.webauthn_auth_param, "", id: "webauthn-auth", aria: { hidden: "true" } %>
8
8
  <div id="webauthn-auth-button">
9
9
  <%%= render "submit", value: "Authenticate Using WebAuthn" %>
10
10
  </div>
11
11
  <%% end %>
12
12
 
13
- <%%= javascript_include_tag rodauth.webauthn_auth_js_path %>
13
+ <%%= javascript_include_tag <%= rodauth %>.webauthn_auth_js_path %>
@@ -1,11 +1,11 @@
1
- <%%= form_tag rodauth.webauthn_remove_path, method: :post, id: "webauthn-remove-form" do %>
2
- <%%= render "password_field" if rodauth.two_factor_modifications_require_password? %>
3
- <fieldset class="form-group">
4
- <%% (usage = rodauth.account_webauthn_usage).each do |id, last_use| %>
1
+ <%%= form_tag <%= rodauth %>.webauthn_remove_path, method: :post, id: "webauthn-remove-form" do %>
2
+ <%%= render "password_field" if <%= rodauth %>.two_factor_modifications_require_password? %>
3
+ <fieldset class="form-group mb-3">
4
+ <%% (usage = <%= rodauth %>.account_webauthn_usage).each do |id, last_use| %>
5
5
  <div class="form-check">
6
- <%%= render "field", name: rodauth.webauthn_remove_param, id: "webauthn-remove-#{id}", type: :radio, class: "form-check-input", skip_error_message: true, value: id, required: false %>
6
+ <%%= render "field", name: <%= rodauth %>.webauthn_remove_param, id: "webauthn-remove-#{id}", type: :radio, class: "form-check-input", skip_error_message: true, value: id, required: false %>
7
7
  <%%= label_tag "webauthn-remove-#{id}", "Last use: #{last_use}", class: "form-check-label" %>
8
- <%%= render "field_error", name: rodauth.webauthn_remove_param if id == usage.keys.last %>
8
+ <%%= render "field_error", name: <%= rodauth %>.webauthn_remove_param if id == usage.keys.last %>
9
9
  </div>
10
10
  <%% end %>
11
11
  </fieldset>
@@ -1,13 +1,13 @@
1
- <%% cred = rodauth.new_webauthn_credential %>
1
+ <%% cred = <%= rodauth %>.new_webauthn_credential %>
2
2
 
3
- <%%= form_tag rodauth.webauthn_setup_path, method: :post, id: "webauthn-setup-form", data: { credential_options: cred.as_json.to_json } do %>
4
- <%%= hidden_field_tag rodauth.webauthn_setup_challenge_param, cred.challenge %>
5
- <%%= hidden_field_tag rodauth.webauthn_setup_challenge_hmac_param, rodauth.compute_hmac(cred.challenge) %>
6
- <%%= text_field_tag rodauth.webauthn_setup_param, "", id: "webauthn-setup", aria: { hidden: "true" } %>
7
- <%%= render "password_field" if rodauth.two_factor_modifications_require_password? %>
3
+ <%%= form_tag <%= rodauth %>.webauthn_setup_path, method: :post, id: "webauthn-setup-form", data: { credential_options: cred.as_json.to_json } do %>
4
+ <%%= hidden_field_tag <%= rodauth %>.webauthn_setup_challenge_param, cred.challenge %>
5
+ <%%= hidden_field_tag <%= rodauth %>.webauthn_setup_challenge_hmac_param, <%= rodauth %>.compute_hmac(cred.challenge) %>
6
+ <%%= text_field_tag <%= rodauth %>.webauthn_setup_param, "", id: "webauthn-setup", aria: { hidden: "true" } %>
7
+ <%%= render "password_field" if <%= rodauth %>.two_factor_modifications_require_password? %>
8
8
  <div id="webauthn-setup-button">
9
9
  <%%= render "submit", value: "Setup WebAuthn Authentication" %>
10
10
  </div>
11
11
  <%% end %>
12
12
 
13
- <%%= javascript_include_tag rodauth.webauthn_setup_js_path %>
13
+ <%%= javascript_include_tag <%= rodauth %>.webauthn_setup_js_path %>
@@ -1,4 +1,4 @@
1
- Someone has requested a that the account with this email be unlocked.
1
+ Someone has requested 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
4
  <%%= @email_link %>
@@ -18,9 +18,9 @@ module Rodauth
18
18
  desc: "Generates views for all Rodauth features",
19
19
  default: false
20
20
 
21
- class_option :directory, aliases: "-d", type: :string,
22
- desc: "The directory under app/views/* into which to create views",
23
- default: "rodauth"
21
+ class_option :name, aliases: "-n", type: :string,
22
+ desc: "The configuration name for which to generate views",
23
+ default: nil
24
24
 
25
25
  VIEWS = {
26
26
  login: %w[
@@ -112,9 +112,30 @@ module Rodauth
112
112
 
113
113
  views.each do |view|
114
114
  template "app/views/rodauth/#{view}.html.erb",
115
- "app/views/#{options[:directory].underscore}/#{view}.html.erb"
115
+ "app/views/#{directory}/#{view}.html.erb"
116
116
  end
117
117
  end
118
+
119
+ def directory
120
+ if controller.abstract?
121
+ fail Error, "no controller configured for configuration: #{configuration_name.inspect}"
122
+ end
123
+
124
+ controller.controller_path
125
+ end
126
+
127
+ def rodauth
128
+ "rodauth#{"(:#{configuration_name})" if configuration_name}"
129
+ end
130
+
131
+ def controller
132
+ rodauth = Rodauth::Rails.rodauth(configuration_name)
133
+ rodauth.rails_controller
134
+ end
135
+
136
+ def configuration_name
137
+ options[:name]&.to_sym
138
+ end
118
139
  end
119
140
  end
120
141
  end
data/lib/rodauth/rails.rb CHANGED
@@ -1,6 +1,9 @@
1
1
  require "rodauth/rails/version"
2
2
  require "rodauth/rails/railtie"
3
3
 
4
+ require "rack/utils"
5
+ require "stringio"
6
+
4
7
  module Rodauth
5
8
  module Rails
6
9
  class Error < StandardError
@@ -8,12 +11,17 @@ module Rodauth
8
11
 
9
12
  # This allows the developer to avoid loading Rodauth at boot time.
10
13
  autoload :App, "rodauth/rails/app"
14
+ autoload :Auth, "rodauth/rails/auth"
11
15
 
12
16
  @app = nil
13
17
  @middleware = true
14
18
 
15
19
  class << self
16
- def rodauth(name = nil)
20
+ def rodauth(name = nil, query: {}, form: {}, session: {}, account: nil, env: {})
21
+ unless app.rodauth(name)
22
+ fail ArgumentError, "undefined rodauth configuration: #{name.inspect}"
23
+ end
24
+
17
25
  url_options = ActionMailer::Base.default_url_options
18
26
 
19
27
  scheme = url_options[:protocol] || "http"
@@ -22,14 +30,38 @@ module Rodauth
22
30
  host = url_options[:host]
23
31
  host += ":#{port}" if port
24
32
 
33
+ content_type = "application/x-www-form-urlencoded" if form.any?
34
+
25
35
  rack_env = {
36
+ "QUERY_STRING" => Rack::Utils.build_nested_query(query),
37
+ "rack.input" => StringIO.new(Rack::Utils.build_nested_query(form)),
38
+ "CONTENT_TYPE" => content_type,
39
+ "rack.session" => {},
26
40
  "HTTP_HOST" => host,
27
41
  "rack.url_scheme" => scheme,
28
- }
42
+ }.merge(env)
43
+
44
+ scope = app.new(rack_env)
45
+ instance = scope.rodauth(name)
29
46
 
30
- scope = app.new(rack_env)
47
+ # update session hash here to make it work with JWT session
48
+ instance.session.merge!(session)
31
49
 
32
- scope.rodauth(name)
50
+ if account
51
+ instance.instance_variable_set(:@account, account.attributes.symbolize_keys)
52
+ instance.session[instance.session_key] = instance.account_session_value
53
+ end
54
+
55
+ instance
56
+ end
57
+
58
+ # routing constraint that requires authentication
59
+ def authenticated(name = nil, &condition)
60
+ lambda do |request|
61
+ rodauth = request.env.fetch ["rodauth", *name].join(".")
62
+ rodauth.require_authentication
63
+ rodauth.authenticated? && (condition.nil? || condition.call(rodauth))
64
+ end
33
65
  end
34
66
 
35
67
  if ::Rails.gem_version >= Gem::Version.new("5.2")
@@ -1,6 +1,5 @@
1
1
  require "roda"
2
- require "rodauth"
3
- require "rodauth/rails/feature"
2
+ require "rodauth/rails/auth"
4
3
 
5
4
  module Rodauth
6
5
  module Rails
@@ -11,40 +10,39 @@ module Rodauth
11
10
 
12
11
  plugin :hooks
13
12
  plugin :render, layout: false
13
+ plugin :pass
14
14
 
15
15
  unless Rodauth::Rails.api_only?
16
16
  require "rodauth/rails/app/flash"
17
17
  plugin Flash
18
18
  end
19
19
 
20
- def self.configure(name = nil, **options, &block)
21
- plugin :rodauth, name: name, csrf: false, flash: false, json: true, **options do
22
- # load the Rails integration
23
- enable :rails
20
+ def self.configure(*args, **options, &block)
21
+ auth_class = args.shift if args[0].is_a?(Class)
22
+ name = args.shift if args[0].is_a?(Symbol)
24
23
 
25
- # database functions are more complex to set up, so disable them by default
26
- use_database_authentication_functions? false
24
+ fail ArgumentError, "need to pass optional Rodauth::Auth subclass and optional configuration name" if args.any?
27
25
 
28
- # avoid having to set deadline values in column default values
29
- set_deadline_values? true
26
+ auth_class ||= Class.new(Rodauth::Rails::Auth)
30
27
 
31
- # use HMACs for additional security
32
- hmac_secret { Rodauth::Rails.secret_key_base }
33
-
34
- # evaluate user configuration
35
- instance_exec(&block)
28
+ plugin :rodauth, auth_class: auth_class, name: name, csrf: false, flash: false, json: true, **options do
29
+ instance_exec(&block) if block
36
30
  end
37
31
  end
38
32
 
39
33
  before do
40
- (opts[:rodauths] || {}).each do |name, _|
41
- if name
42
- env["rodauth.#{name}"] = rodauth(name)
43
- else
44
- env["rodauth"] = rodauth
45
- end
34
+ opts[:rodauths]&.each_key do |name|
35
+ env[["rodauth", *name].join(".")] = rodauth(name)
46
36
  end
47
37
  end
38
+
39
+ def rails_routes
40
+ ::Rails.application.routes.url_helpers
41
+ end
42
+
43
+ def rails_request
44
+ ActionDispatch::Request.new(env)
45
+ end
48
46
  end
49
47
  end
50
48
  end