rodauth-rails 0.16.0 → 0.18.1

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 +97 -36
  4. data/lib/generators/rodauth/install_generator.rb +11 -3
  5. data/lib/generators/rodauth/migration/base.erb +8 -2
  6. data/lib/generators/rodauth/templates/app/views/rodauth/_email_auth_request_form.html.erb +7 -4
  7. data/lib/generators/rodauth/templates/app/views/rodauth/_login_form.html.erb +26 -9
  8. data/lib/generators/rodauth/templates/app/views/rodauth/_login_form_footer.html.erb +7 -6
  9. data/lib/generators/rodauth/templates/app/views/rodauth/_login_form_header.html.erb +3 -3
  10. data/lib/generators/rodauth/templates/app/views/rodauth/add_recovery_codes.html.erb +7 -5
  11. data/lib/generators/rodauth/templates/app/views/rodauth/change_login.html.erb +29 -6
  12. data/lib/generators/rodauth/templates/app/views/rodauth/change_password.html.erb +29 -6
  13. data/lib/generators/rodauth/templates/app/views/rodauth/close_account.html.erb +15 -4
  14. data/lib/generators/rodauth/templates/app/views/rodauth/confirm_password.html.erb +13 -4
  15. data/lib/generators/rodauth/templates/app/views/rodauth/create_account.html.erb +37 -7
  16. data/lib/generators/rodauth/templates/app/views/rodauth/email_auth.html.erb +7 -3
  17. data/lib/generators/rodauth/templates/app/views/rodauth/login.html.erb +5 -3
  18. data/lib/generators/rodauth/templates/app/views/rodauth/logout.html.erb +16 -4
  19. data/lib/generators/rodauth/templates/app/views/rodauth/multi_phase_login.html.erb +5 -3
  20. data/lib/generators/rodauth/templates/app/views/rodauth/otp_auth.html.erb +17 -4
  21. data/lib/generators/rodauth/templates/app/views/rodauth/otp_disable.html.erb +15 -4
  22. data/lib/generators/rodauth/templates/app/views/rodauth/otp_setup.html.erb +30 -10
  23. data/lib/generators/rodauth/templates/app/views/rodauth/recovery_auth.html.erb +13 -4
  24. data/lib/generators/rodauth/templates/app/views/rodauth/recovery_codes.html.erb +15 -1
  25. data/lib/generators/rodauth/templates/app/views/rodauth/remember.html.erb +14 -9
  26. data/lib/generators/rodauth/templates/app/views/rodauth/reset_password.html.erb +21 -5
  27. data/lib/generators/rodauth/templates/app/views/rodauth/reset_password_request.html.erb +19 -9
  28. data/lib/generators/rodauth/templates/app/views/rodauth/sms_auth.html.erb +17 -4
  29. data/lib/generators/rodauth/templates/app/views/rodauth/sms_confirm.html.erb +17 -4
  30. data/lib/generators/rodauth/templates/app/views/rodauth/sms_disable.html.erb +15 -4
  31. data/lib/generators/rodauth/templates/app/views/rodauth/sms_request.html.erb +7 -3
  32. data/lib/generators/rodauth/templates/app/views/rodauth/sms_setup.html.erb +25 -5
  33. data/lib/generators/rodauth/templates/app/views/rodauth/two_factor_auth.html.erb +5 -3
  34. data/lib/generators/rodauth/templates/app/views/rodauth/two_factor_disable.html.erb +15 -4
  35. data/lib/generators/rodauth/templates/app/views/rodauth/two_factor_manage.html.erb +17 -15
  36. data/lib/generators/rodauth/templates/app/views/rodauth/unlock_account.html.erb +17 -5
  37. data/lib/generators/rodauth/templates/app/views/rodauth/unlock_account_request.html.erb +11 -5
  38. data/lib/generators/rodauth/templates/app/views/rodauth/verify_account.html.erb +23 -5
  39. data/lib/generators/rodauth/templates/app/views/rodauth/verify_account_resend.html.erb +19 -9
  40. data/lib/generators/rodauth/templates/app/views/rodauth/verify_login_change.html.erb +7 -3
  41. data/lib/generators/rodauth/templates/app/views/rodauth/webauthn_auth.html.erb +13 -9
  42. data/lib/generators/rodauth/templates/app/views/rodauth/webauthn_remove.html.erb +21 -9
  43. data/lib/generators/rodauth/templates/app/views/rodauth/webauthn_setup.html.erb +21 -9
  44. data/lib/generators/rodauth/templates/app/views/rodauth_mailer/email_auth.text.erb +1 -1
  45. data/lib/generators/rodauth/templates/app/views/rodauth_mailer/reset_password.text.erb +1 -1
  46. data/lib/generators/rodauth/templates/app/views/rodauth_mailer/unlock_account.text.erb +1 -1
  47. data/lib/generators/rodauth/templates/app/views/rodauth_mailer/verify_account.text.erb +1 -1
  48. data/lib/generators/rodauth/templates/app/views/rodauth_mailer/verify_login_change.text.erb +3 -3
  49. data/lib/generators/rodauth/views_generator.rb +55 -93
  50. data/lib/rodauth/rails/app.rb +4 -0
  51. data/lib/rodauth/rails/controller_methods.rb +1 -2
  52. data/lib/rodauth/rails/feature/base.rb +9 -0
  53. data/lib/rodauth/rails/feature/csrf.rb +15 -4
  54. data/lib/rodauth/rails/feature/internal_request.rb +16 -20
  55. data/lib/rodauth/rails/feature/render.rb +1 -1
  56. data/lib/rodauth/rails/model.rb +1 -1
  57. data/lib/rodauth/rails/railtie.rb +4 -2
  58. data/lib/rodauth/rails/version.rb +1 -1
  59. data/lib/rodauth/rails.rb +14 -7
  60. data/rodauth-rails.gemspec +1 -1
  61. metadata +4 -20
  62. data/lib/generators/rodauth/templates/app/views/rodauth/_field.html.erb +0 -10
  63. data/lib/generators/rodauth/templates/app/views/rodauth/_field_error.html.erb +0 -3
  64. data/lib/generators/rodauth/templates/app/views/rodauth/_global_logout_field.html.erb +0 -6
  65. data/lib/generators/rodauth/templates/app/views/rodauth/_login_confirm_field.html.erb +0 -4
  66. data/lib/generators/rodauth/templates/app/views/rodauth/_login_display.html.erb +0 -4
  67. data/lib/generators/rodauth/templates/app/views/rodauth/_login_field.html.erb +0 -4
  68. data/lib/generators/rodauth/templates/app/views/rodauth/_login_hidden_field.html.erb +0 -1
  69. data/lib/generators/rodauth/templates/app/views/rodauth/_new_password_field.html.erb +0 -4
  70. data/lib/generators/rodauth/templates/app/views/rodauth/_otp_auth_code_field.html.erb +0 -8
  71. data/lib/generators/rodauth/templates/app/views/rodauth/_password_confirm_field.html.erb +0 -4
  72. data/lib/generators/rodauth/templates/app/views/rodauth/_password_field.html.erb +0 -4
  73. data/lib/generators/rodauth/templates/app/views/rodauth/_recovery_code_field.html.erb +0 -4
  74. data/lib/generators/rodauth/templates/app/views/rodauth/_recovery_codes_form.html.erb +0 -6
  75. data/lib/generators/rodauth/templates/app/views/rodauth/_sms_code_field.html.erb +0 -8
  76. data/lib/generators/rodauth/templates/app/views/rodauth/_sms_phone_field.html.erb +0 -8
  77. data/lib/generators/rodauth/templates/app/views/rodauth/_submit.html.erb +0 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e46466d584d7579c32e7d7e53335260dd137c04371f4b7c4680caa5c6a4e4147
4
- data.tar.gz: c0be8bdc56f5214c885fc5ad990a0be511251cab6dbf9b0ec7aa3fbd8631d0c9
3
+ metadata.gz: 8eb9b3bee5cf4cd6741d7b05fa1d6869526a583ff3d9712b8a4adcb522c5a8d5
4
+ data.tar.gz: 37cba7e8de2b0c2aa07763ca4da38989692e3cd467a314440f22706380e9e2fe
5
5
  SHA512:
6
- metadata.gz: 8428739e888033efa811819ee8561fa3f2ae342074f6e27bbf257c18bf7029ab87380a82c75c6c08de2a0d4de49482eac74a32bc7aaf0579baf45978fe63811c
7
- data.tar.gz: d626ea202fe8e371e6c77364a9e3c1ef34fdccff0ce7794c54b3fc748b0e1a764e92b99b6b7f06aaa8e2f2f67b155b127c0b1314d4ec7420637013136170141c
6
+ metadata.gz: 8c027c266b03b2be2a68d19e847e31ce04d608e1befbf9785b38ffd94326962db2b01bf72b715311f9a690022fe62232c92a355094d451383330413096c57be5
7
+ data.tar.gz: bc2d33f6d773cc7884c5b655ef93630a6e1f1ec56fe9ce6f75aa8127120005496eecc976aa8f1689cc4ade3e784070b5ce5de1308eda674e8487e9eac5a5599e
data/CHANGELOG.md CHANGED
@@ -1,3 +1,57 @@
1
+ ## 0.18.0 (2021-11-05)
2
+
3
+ * Disable Turbo on the generated login form (@janko)
4
+
5
+ * Generate controller views with `form_with` helper on Rails 5.1+ (@janko)
6
+
7
+ * Fix missing layout error when rendering Rodauth's built-in templates when using Turbo on Rails 6.0+ (@janko)
8
+
9
+ * Fix `Rodauth::Rails.middleware` config not actually affecting middleware insertion (@janko)
10
+
11
+ * Set page titles in generated view templates (@janko)
12
+
13
+ * Merge field and button partials into view templates (@janko)
14
+
15
+ * Raise error for unknown configuration in `Rodauth::Rails.model` (@janko)
16
+
17
+ * Generate views for all enabled features by default in `rodauth:views` generator (@janko)
18
+
19
+ * Add `Rodauth::Rails::App.rodauth!` which raises an error for unknown configuration (@janko)
20
+
21
+ * Remove deprecated `--features` option from `rodauth:views` generator (@janko)
22
+
23
+ * Inline `_recovery_codes_form.html.erb` partial into `recovery_codes.html.erb` (@janko)
24
+
25
+ * Use Rodauth helper methods for texts in generated views, for easier i18n (@janko)
26
+
27
+ * Allow setting passing a `Sequel::Model` to `:account` in `Rodauth::Rails.rodauth` (@janko)
28
+
29
+ ## 0.17.1 (2021-10-20)
30
+
31
+ * Skip checking CSRF when request forgery protection wasn't loaded on the controller (@janko)
32
+
33
+ * Create partial unique index for `accounts.email` column when using `sqlite3` adapter (@janko)
34
+
35
+ * Revert setting `delete_account_on_close?` to `true` in generated `rodauth_app.rb` (@janko)
36
+
37
+ * Disable Turbo in `_recovery_codes_form.html.erb`, since viewing recovery codes isn't Turbo-compatible (@janko)
38
+
39
+ * Generate JSON configuration on `rodauth:install` for API-only with sessions enabled (@janko)
40
+
41
+ * Generate JWT configuration on `rodauth:install` only for API-only apps without sessions enabled (@janko)
42
+
43
+ * Don't generate JWT configuration when `rodauth:install --json` was run in API-only app (@janko)
44
+
45
+ * Use `config.action_mailer.default_url_options` in path_class_methods feature (@janko)
46
+
47
+ ## 0.17.0 (2021-10-05)
48
+
49
+ * Set `delete_account_on_close?` to `true` in generated `rodauth_app.rb` (@janko)
50
+
51
+ * Change default `:dependent` option for associations to `:delete`/`:delete_all` (@janko)
52
+
53
+ * Add `rails_account_model` configuration method for when the account model cannot be inferred (@janko)
54
+
1
55
  ## 0.16.0 (2021-09-26)
2
56
 
3
57
  * Add `#current_account` to methods defined on `ActionController::Base` (@janko)
data/README.md CHANGED
@@ -49,7 +49,7 @@ For instructions on upgrading from previous rodauth-rails versions, see
49
49
  Add the gem to your Gemfile:
50
50
 
51
51
  ```rb
52
- gem "rodauth-rails", "~> 0.16"
52
+ gem "rodauth-rails", "~> 0.18"
53
53
 
54
54
  # gem "jwt", require: false # for JWT feature
55
55
  # gem "rotp", require: false # for OTP feature
@@ -150,6 +150,9 @@ current_account #=> #<Account id=123 email="user@example.com">
150
150
  current_account.email #=> "user@example.com"
151
151
  ```
152
152
 
153
+ If the account doesn't exist in the database, the session will be cleared and
154
+ login required.
155
+
153
156
  Pass the configuration name to retrieve accounts belonging to other Rodauth
154
157
  configurations:
155
158
 
@@ -157,8 +160,19 @@ configurations:
157
160
  current_account(:admin)
158
161
  ```
159
162
 
160
- If the account doesn't exist in the database, the session will be cleared and
161
- login required.
163
+ The `#current_account` method will try to infer the account model class from
164
+ the configured table name. If that fails, you can set the account model
165
+ manually:
166
+
167
+ ```rb
168
+ # app/lib/rodauth_app.rb
169
+ class RodauthApp < Rodauth::Rails::App
170
+ configure do
171
+ # ...
172
+ rails_account_model Authentication::Account # custom model name
173
+ end
174
+ end
175
+ ```
162
176
 
163
177
  ### Requiring authentication
164
178
 
@@ -268,12 +282,12 @@ copy Rodauth templates into your Rails app:
268
282
  $ rails generate rodauth:views
269
283
  ```
270
284
 
271
- This will generate views for the default set of Rodauth features into the
272
- `app/views/rodauth` directory, provided that `RodauthController` is set for the
273
- main configuration.
285
+ This will generate views for Rodauth features you have currently enabled into
286
+ the `app/views/rodauth` directory, provided that `RodauthController` is set for
287
+ the main configuration.
274
288
 
275
289
  You can pass a list of Rodauth features to the generator to create views for
276
- these features (this will not remove or overwrite any existing views):
290
+ these features (this will not remove any existing views):
277
291
 
278
292
  ```sh
279
293
  $ rails generate rodauth:views login create_account lockout otp
@@ -288,7 +302,7 @@ $ rails generate rodauth:views --all
288
302
  Use `--name` to generate views for a different Rodauth configuration:
289
303
 
290
304
  ```sh
291
- $ rails generate rodauth:views --name admin
305
+ $ rails generate rodauth:views webauthn --name admin
292
306
  ```
293
307
 
294
308
  #### Layout
@@ -777,11 +791,52 @@ end
777
791
 
778
792
  ### Outside of a request
779
793
 
780
- In some cases you might need to use Rodauth more programmatically. If you would
781
- like to perform Rodauth operations outside of request context, Rodauth ships
782
- with the [internal_request] feature just for that. The rodauth-rails gem
783
- additionally updates the internal rack env hash with your
784
- `config.action_mailer.default_url_options`, which is used for generating URLs.
794
+ In some cases you might need to use Rodauth more programmatically. If you want
795
+ to perform authentication operations outside of request context, Rodauth ships
796
+ with the [internal_request] feature just for that.
797
+
798
+ ```rb
799
+ # app/lib/rodauth_app.rb
800
+ class RodauthApp < Rodauth::Rails::App
801
+ configure do
802
+ enable :internal_request
803
+ end
804
+ end
805
+ ```
806
+ ```rb
807
+ # main configuration
808
+ RodauthApp.rodauth.create_account(login: "user@example.com", password: "secret")
809
+ RodauthApp.rodauth.verify_account(account_login: "user@example.com")
810
+
811
+ # secondary configuration
812
+ RodauthApp.rodauth(:admin).close_account(account_login: "admin@example.com")
813
+ ```
814
+
815
+ The rodauth-rails gem additionally updates the internal rack env hash with your
816
+ `config.action_mailer.default_url_options`, which is used for generating email
817
+ links.
818
+
819
+ For generating authentication URLs outside of a request use the
820
+ [path_class_methods] plugin:
821
+
822
+ ```rb
823
+ # app/lib/rodauth_app.rb
824
+ class RodauthApp < Rodauth::Rails::App
825
+ configure do
826
+ enable :path_class_methods
827
+ end
828
+ end
829
+ ```
830
+ ```rb
831
+ # main configuration
832
+ RodauthApp.rodauth.create_account_path
833
+ RodauthApp.rodauth.verify_account_url(key: "abc123")
834
+
835
+ # secondary configuration
836
+ RodauthApp.rodauth(:admin).close_account_path
837
+ ```
838
+
839
+ #### Calling instance methods
785
840
 
786
841
  If you need to access Rodauth methods not exposed as internal requests, you can
787
842
  use `Rodauth::Rails.rodauth` to retrieve the Rodauth instance used by the
@@ -810,19 +865,12 @@ In addition to the `:account` option, the `Rodauth::Rails.rodauth`
810
865
  method accepts any options supported by the internal_request feature.
811
866
 
812
867
  ```rb
813
- Rodauth::Rails.rodauth(
814
- env: { "HTTP_USER_AGENT" => "programmatic" },
815
- session: { two_factor_auth_setup: true },
816
- params: { "param" => "value" },
817
- # ...
818
- )
819
- ```
868
+ # main configuration
869
+ Rodauth::Rails.rodauth(env: { "HTTP_USER_AGENT" => "programmatic" })
870
+ Rodauth::Rails.rodauth(session: { two_factor_auth_setup: true })
820
871
 
821
- Secondary Rodauth configurations are specified by passing the configuration
822
- name:
823
-
824
- ```rb
825
- Rodauth::Rails.rodauth(:admin)
872
+ # secondary configuration
873
+ Rodauth::Rails.rodauth(:admin, params: { "param" => "value" })
826
874
  ```
827
875
 
828
876
  ## How it works
@@ -986,7 +1034,24 @@ end
986
1034
  While Rodauth doesn't yet come with [OmniAuth] integration, we can build one
987
1035
  ourselves using the existing Rodauth API.
988
1036
 
989
- In order to allow the user to login via multiple external providers, let's
1037
+ Let's assume we're building Facebook login. We'll start by installing the
1038
+ necessary gems, and loading the Facebook OmniAuth strategy:
1039
+
1040
+ ```rb
1041
+ # Gemfile
1042
+ gem "omniauth", "~> 2.0"
1043
+ gem "omniauth-rails_csrf_protection" # https://github.com/omniauth/omniauth/wiki/Resolving-CVE-2015-9284
1044
+ gem "omniauth-facebook"
1045
+ ```
1046
+ ```rb
1047
+ # config/initializers/omniauth.rb
1048
+ Rails.application.config.middleware.use OmniAuth::Builder do
1049
+ provider :facebook, ENV["FACEBOOK_APP_ID"], ENV["FACEBOOK_APP_SECRET"],
1050
+ scope: "email", callback_path: "/auth/facebook/callback"
1051
+ end
1052
+ ```
1053
+
1054
+ Since users might potentially want to login with multiple external providers, let's
990
1055
  create an `account_identities` table that will have a many-to-one relationship
991
1056
  with the `accounts` table:
992
1057
 
@@ -1023,18 +1088,11 @@ class Account < ApplicationRecord
1023
1088
  end
1024
1089
  ```
1025
1090
 
1026
- Let's assume we want to implement Facebook login, and have added the
1027
- corresponding OmniAuth strategy to the middleware stack, together with an
1028
- authorization link on the login form:
1091
+ Next, let's add a POST button pointing to the request URL to our login form:
1029
1092
 
1030
- ```rb
1031
- Rails.application.config.middleware.use OmniAuth::Builder do
1032
- provider :facebook, ENV["FACEBOOK_APP_ID"], ENV["FACEBOOK_APP_SECRET"],
1033
- scope: "email", callback_path: "/auth/facebook/callback"
1034
- end
1035
- ```
1036
1093
  ```erb
1037
- <%= link_to "Login via Facebook", "/auth/facebook" %>
1094
+ <%= button_to "Login via Facebook", "/auth/facebook",
1095
+ method: :post, data: { turbo: false }, class: "btn btn-link p-0" %>
1038
1096
  ```
1039
1097
 
1040
1098
  Finally, let's implement the OmniAuth callback endpoint on our Rodauth
@@ -1107,6 +1165,7 @@ methods:
1107
1165
  | `rails_check_csrf!` | Verifies the authenticity token for the current request. |
1108
1166
  | `rails_controller_instance` | Instance of the controller with the request env context. |
1109
1167
  | `rails_controller` | Controller class to use for rendering and CSRF protection. |
1168
+ | `rails_account_model` | Model class connected with the accounts table. |
1110
1169
 
1111
1170
  The `Rodauth::Rails` module has a few config settings available as well:
1112
1171
 
@@ -1423,3 +1482,5 @@ conduct](https://github.com/janko/rodauth-rails/blob/master/CODE_OF_CONDUCT.md).
1423
1482
  [account_expiration]: http://rodauth.jeremyevans.net/rdoc/files/doc/account_expiration_rdoc.html
1424
1483
  [simple_ldap_authenticator]: https://github.com/jeremyevans/simple_ldap_authenticator
1425
1484
  [internal_request]: http://rodauth.jeremyevans.net/rdoc/files/doc/internal_request_rdoc.html
1485
+ [composite_primary_keys]: https://github.com/composite-primary-keys/composite_primary_keys
1486
+ [path_class_methods]: https://rodauth.jeremyevans.net/rdoc/files/doc/path_class_methods_rdoc.html
@@ -60,7 +60,7 @@ module Rodauth
60
60
  template "app/mailers/rodauth_mailer.rb"
61
61
 
62
62
  MAILER_VIEWS.each do |view|
63
- template "app/views/rodauth_mailer/#{view}.text.erb"
63
+ copy_file "app/views/rodauth_mailer/#{view}.text.erb"
64
64
  end
65
65
  end
66
66
 
@@ -95,11 +95,11 @@ module Rodauth
95
95
  end
96
96
 
97
97
  def json?
98
- options[:json]
98
+ options[:json] || api_only? && session_store? && !options[:jwt]
99
99
  end
100
100
 
101
101
  def jwt?
102
- options[:jwt] || Rodauth::Rails.api_only?
102
+ options[:jwt] || api_only? && !session_store? && !options[:json]
103
103
  end
104
104
 
105
105
  def migration_features
@@ -107,6 +107,14 @@ module Rodauth
107
107
  features << :remember unless jwt?
108
108
  features
109
109
  end
110
+
111
+ def session_store?
112
+ !!::Rails.application.config.session_store
113
+ end
114
+
115
+ def api_only?
116
+ Rodauth::Rails.api_only?
117
+ end
110
118
  end
111
119
  end
112
120
  end
@@ -5,11 +5,17 @@ enable_extension "citext"
5
5
  create_table :accounts<%= primary_key_type %> do |t|
6
6
  <% case activerecord_adapter -%>
7
7
  <% when "postgresql" -%>
8
- t.citext :email, null: false, index: { unique: true, where: "status IN ('unverified', 'verified')" }
8
+ t.citext :email, null: false
9
9
  <% else -%>
10
- t.string :email, null: false, index: { unique: true }
10
+ t.string :email, null: false
11
11
  <% end -%>
12
12
  t.string :status, null: false, default: "unverified"
13
+ <% case activerecord_adapter -%>
14
+ <% when "postgresql", "sqlite3" -%>
15
+ t.index :email, unique: true, where: "status IN ('unverified', 'verified')"
16
+ <% else -%>
17
+ t.index :email, unique: true
18
+ <% end -%>
13
19
  end
14
20
 
15
21
  # Used if storing password hashes in a separate table (default)
@@ -1,4 +1,7 @@
1
- <%%= form_tag <%= rodauth %>.email_auth_request_path, method: :post do %>
2
- <%%= render "login_hidden_field" %>
3
- <%%= render "submit", value: "Send Login Link Via Email" %>
4
- <%% end %>
1
+ <%= form_with url: rodauth.email_auth_request_path, method: :post do |form| %>
2
+ <%= form.hidden_field rodauth.login_param, value: params[rodauth.login_param] %>
3
+
4
+ <div class="form-group mb-3">
5
+ <%= form.submit rodauth.email_auth_request_button, class: "btn btn-primary" %>
6
+ </div>
7
+ <% end %>
@@ -1,9 +1,26 @@
1
- <%%= form_tag <%= rodauth %>.login_path, method: :post do %>
2
- <%% if <%= rodauth %>.skip_login_field_on_login? %>
3
- <%%= render "login_display" %>
4
- <%% else %>
5
- <%%= render "login_field" %>
6
- <%% end %>
7
- <%%= render "password_field" unless <%= rodauth %>.skip_password_field_on_login? %>
8
- <%%= render "submit", value: "Login" %>
9
- <%% end %>
1
+ <%= form_with url: rodauth.login_path, method: :post, data: { turbo: false } do |form| %>
2
+ <% if rodauth.skip_login_field_on_login? %>
3
+ <div class="form-group mb-3">
4
+ <%= form.label "login", rodauth.login_label, class: "form-label" %>
5
+ <%= form.email_field rodauth.login_param, value: params[rodauth.login_param], id: "login", readonly: true, class: "form-control-plaintext" %>
6
+ </div>
7
+ <% else %>
8
+ <div class="form-group mb-3">
9
+ <%= form.label "login", rodauth.login_label, class: "form-label" %>
10
+ <%= form.email_field rodauth.login_param, value: params[rodauth.login_param], id: "login", autocomplete: "email", required: true, class: "form-control #{"is-invalid" if rodauth.field_error(rodauth.login_param)}", aria: ({ invalid: true, describedby: "login_error_message" } if rodauth.field_error(rodauth.login_param)) %>
11
+ <%= content_tag(:span, rodauth.field_error(rodauth.login_param), class: "invalid-feedback", id: "login_error_message") if rodauth.field_error(rodauth.login_param) %>
12
+ </div>
13
+ <% end %>
14
+
15
+ <% unless rodauth.skip_password_field_on_login? %>
16
+ <div class="form-group mb-3">
17
+ <%= form.label "password", rodauth.password_label, class: "form-label" %>
18
+ <%= form.password_field rodauth.password_param, value: "", id: "password", autocomplete: rodauth.password_field_autocomplete_value, required: true, class: "form-control #{"is-invalid" if rodauth.field_error(rodauth.password_param)}", aria: ({ invalid: true, describedby: "password_error_message" } if rodauth.field_error(rodauth.password_param)) %>
19
+ <%= content_tag(:span, rodauth.field_error(rodauth.password_param), class: "invalid-feedback", id: "password_error_message") if rodauth.field_error(rodauth.password_param) %>
20
+ </div>
21
+ <% end %>
22
+
23
+ <div class="form-group mb-3">
24
+ <%= form.submit rodauth.login_button, class: "btn btn-primary" %>
25
+ </div>
26
+ <% end %>
@@ -1,8 +1,9 @@
1
- <%% unless <%= rodauth %>.login_form_footer_links.empty? %>
2
- <h2>Other Options</h2>
1
+ <% unless rodauth.login_form_footer_links.empty? %>
2
+ <%== rodauth.login_form_footer_links_heading %>
3
+
3
4
  <ul>
4
- <%% <%= rodauth %>.login_form_footer_links.sort.each do |_, link, text| %>
5
- <li><%%= link_to text, link %></li>
6
- <%% end %>
5
+ <% rodauth.login_form_footer_links.sort.each do |_, link, text| %>
6
+ <li><%= link_to text, link %></li>
7
+ <% end %>
7
8
  </ul>
8
- <%% end %>
9
+ <% end %>
@@ -1,3 +1,3 @@
1
- <%% if <%= rodauth %>.field_error("password") && <%= rodauth %>.features.include?(:reset_password) %>
2
- <%%= render template: "<%= directory %>/reset_password_request", layout: false %>
3
- <%% end %>
1
+ <% if rodauth.field_error(rodauth.password_param) && rodauth.features.include?(:reset_password) %>
2
+ <%= render template: "rodauth/reset_password_request", layout: false %>
3
+ <% end %>
@@ -1,6 +1,8 @@
1
- <pre id="recovery-codes"><%%= <%= rodauth %>.recovery_codes.map { |s| h(s) }.join("\n\n") %></pre>
1
+ <% content_for :title, rodauth.add_recovery_codes_page_title %>
2
2
 
3
- <%% if <%= rodauth %>.can_add_recovery_codes? %>
4
- <h2>Add Additional Recovery Codes</h2>
5
- <%%= render "recovery_codes_form" %>
6
- <%% end %>
3
+ <pre id="recovery-codes"><%= rodauth.recovery_codes.map { |s| h(s) }.join("\n\n") %></pre>
4
+
5
+ <% if rodauth.can_add_recovery_codes? %>
6
+ <%== rodauth.add_recovery_codes_heading %>
7
+ <%= render template: "rodauth/recovery_codes", layout: false %>
8
+ <% end %>
@@ -1,6 +1,29 @@
1
- <%%= form_tag <%= rodauth %>.change_login_path, method: :post do %>
2
- <%%= render "login_field" %>
3
- <%%= render "login_confirm_field" if <%= rodauth %>.require_login_confirmation? %>
4
- <%%= render "password_field" if <%= rodauth %>.change_login_requires_password? %>
5
- <%%= render "submit", value: "Change Login" %>
6
- <%% end %>
1
+ <% content_for :title, rodauth.change_login_page_title %>
2
+
3
+ <%= form_with url: rodauth.change_login_path, method: :post do |form| %>
4
+ <div class="form-group mb-3">
5
+ <%= form.label "login", rodauth.login_label, class: "form-label" %>
6
+ <%= form.email_field rodauth.login_param, value: params[rodauth.login_param], id: "login", autocomplete: "email", required: true, class: "form-control #{"is-invalid" if rodauth.field_error(rodauth.login_param)}", aria: ({ invalid: true, describedby: "login_error_message" } if rodauth.field_error(rodauth.login_param)) %>
7
+ <%= content_tag(:span, rodauth.field_error(rodauth.login_param), class: "invalid-feedback", id: "login_error_message") if rodauth.field_error(rodauth.login_param) %>
8
+ </div>
9
+
10
+ <% if rodauth.require_login_confirmation? %>
11
+ <div class="form-group mb-3">
12
+ <%= form.label "login-confirm", rodauth.login_confirm_label, class: "form-label" %>
13
+ <%= form.email_field rodauth.login_confirm_param, value: params[rodauth.login_confirm_param], id: "login-confirm", autocomplete: "email", required: true, class: "form-control #{"is-invalid" if rodauth.field_error(rodauth.login_confirm_param)}", aria: ({ invalid: true, describedby: "login-confirm_error_message" } if rodauth.field_error(rodauth.login_confirm_param)) %>
14
+ <%= content_tag(:span, rodauth.field_error(rodauth.login_confirm_param), class: "invalid-feedback", id: "login-confirm_error_message") if rodauth.field_error(rodauth.login_confirm_param) %>
15
+ </div>
16
+ <% end %>
17
+
18
+ <% if rodauth.change_login_requires_password? %>
19
+ <div class="form-group mb-3">
20
+ <%= form.label "password", rodauth.password_label, class: "form-label" %>
21
+ <%= form.password_field rodauth.password_param, value: "", id: "password", autocomplete: rodauth.password_field_autocomplete_value, required: true, class: "form-control #{"is-invalid" if rodauth.field_error(rodauth.password_param)}", aria: ({ invalid: true, describedby: "password_error_message" } if rodauth.field_error(rodauth.password_param)) %>
22
+ <%= content_tag(:span, rodauth.field_error(rodauth.password_param), class: "invalid-feedback", id: "password_error_message") if rodauth.field_error(rodauth.password_param) %>
23
+ </div>
24
+ <% end %>
25
+
26
+ <div class="form-group mb-3">
27
+ <%= form.submit rodauth.change_login_button, class: "btn btn-primary" %>
28
+ </div>
29
+ <% end %>
@@ -1,6 +1,29 @@
1
- <%%= form_tag <%= rodauth %>.change_password_path, method: :post do %>
2
- <%%= render "password_field" if <%= rodauth %>.change_password_requires_password? %>
3
- <%%= render "new_password_field" %>
4
- <%%= render "password_confirm_field" if <%= rodauth %>.require_password_confirmation? %>
5
- <%%= render "submit", value: "Change Password" %>
6
- <%% end %>
1
+ <% content_for :title, rodauth.change_password_page_title %>
2
+
3
+ <%= form_with url: rodauth.change_password_path, method: :post do |form| %>
4
+ <% if rodauth.change_password_requires_password? %>
5
+ <div class="form-group mb-3">
6
+ <%= form.label "password", rodauth.password_label, class: "form-label" %>
7
+ <%= form.password_field rodauth.password_param, value: "", id: "password", autocomplete: rodauth.password_field_autocomplete_value, required: true, class: "form-control #{"is-invalid" if rodauth.field_error(rodauth.password_param)}", aria: ({ invalid: true, describedby: "password_error_message" } if rodauth.field_error(rodauth.password_param)) %>
8
+ <%= content_tag(:span, rodauth.field_error(rodauth.password_param), class: "invalid-feedback", id: "password_error_message") if rodauth.field_error(rodauth.password_param) %>
9
+ </div>
10
+ <% end %>
11
+
12
+ <div class="form-group mb-3">
13
+ <%= form.label "new-password", rodauth.new_password_label, class: "form-label" %>
14
+ <%= form.password_field rodauth.new_password_param, value: "", id: "new-password", autocomplete: "new-password", required: true, class: "form-control #{"is-invalid" if rodauth.field_error(rodauth.new_password_param)}", aria: ({ invalid: true, describedby: "new-password_error_message" } if rodauth.field_error(rodauth.new_password_param)) %>
15
+ <%= content_tag(:span, rodauth.field_error(rodauth.new_password_param), class: "invalid-feedback", id: "new-password_error_message") if rodauth.field_error(rodauth.new_password_param) %>
16
+ </div>
17
+
18
+ <% if rodauth.require_password_confirmation? %>
19
+ <div class="form-group mb-3">
20
+ <%= form.label "password-confirm", rodauth.password_confirm_label, class: "form-label" %>
21
+ <%= form.password_field rodauth.password_confirm_param, value: "", id: "password-confirm", autocomplete: "new-password", required: true, class: "form-control #{"is-invalid" if rodauth.field_error(rodauth.password_confirm_param)}", aria: ({ invalid: true, describedby: "password-confirm_error_message" } if rodauth.field_error(rodauth.password_confirm_param)) %>
22
+ <%= content_tag(:span, rodauth.field_error(rodauth.password_confirm_param), class: "invalid-feedback", id: "password-confirm_error_message") if rodauth.field_error(rodauth.password_confirm_param) %>
23
+ </div>
24
+ <% end %>
25
+
26
+ <div class="form-group mb-3">
27
+ <%= form.submit rodauth.change_password_button, class: "btn btn-primary" %>
28
+ </div>
29
+ <% end %>
@@ -1,4 +1,15 @@
1
- <%%= form_tag <%= rodauth %>.close_account_path, method: :post do %>
2
- <%%= render "password_field" if <%= rodauth %>.close_account_requires_password? %>
3
- <%%= render "submit", value: "Close Account", class: "btn btn-danger" %>
4
- <%% end %>
1
+ <% content_for :title, rodauth.close_account_page_title %>
2
+
3
+ <%= form_with url: rodauth.close_account_path, method: :post do |form| %>
4
+ <% if rodauth.close_account_requires_password? %>
5
+ <div class="form-group mb-3">
6
+ <%= form.label "password", rodauth.password_label, class: "form-label" %>
7
+ <%= form.password_field rodauth.password_param, value: "", id: "password", autocomplete: rodauth.password_field_autocomplete_value, required: true, class: "form-control #{"is-invalid" if rodauth.field_error(rodauth.password_param)}", aria: ({ invalid: true, describedby: "password_error_message" } if rodauth.field_error(rodauth.password_param)) %>
8
+ <%= content_tag(:span, rodauth.field_error(rodauth.password_param), class: "invalid-feedback", id: "password_error_message") if rodauth.field_error(rodauth.password_param) %>
9
+ </div>
10
+ <% end %>
11
+
12
+ <div class="form-group mb-3">
13
+ <%= form.submit rodauth.close_account_button, class: "btn btn-danger" %>
14
+ </div>
15
+ <% end %>
@@ -1,4 +1,13 @@
1
- <%%= form_tag <%= rodauth %>.confirm_password_path, method: :post do %>
2
- <%%= render "password_field" %>
3
- <%%= render "submit", value: "Confirm Password" %>
4
- <%% end %>
1
+ <% content_for :title, rodauth.confirm_password_page_title %>
2
+
3
+ <%= form_with url: rodauth.confirm_password_path, method: :post do |form| %>
4
+ <div class="form-group mb-3">
5
+ <%= form.label "password", rodauth.password_label, class: "form-label" %>
6
+ <%= form.password_field rodauth.password_param, value: "", id: "password", autocomplete: rodauth.password_field_autocomplete_value, required: true, class: "form-control #{"is-invalid" if rodauth.field_error(rodauth.password_param)}", aria: ({ invalid: true, describedby: "password_error_message" } if rodauth.field_error(rodauth.password_param)) %>
7
+ <%= content_tag(:span, rodauth.field_error(rodauth.password_param), class: "invalid-feedback", id: "password_error_message") if rodauth.field_error(rodauth.password_param) %>
8
+ </div>
9
+
10
+ <div class="form-group mb-3">
11
+ <%= form.submit rodauth.confirm_password_button, class: "btn btn-primary" %>
12
+ </div>
13
+ <% end %>
@@ -1,7 +1,37 @@
1
- <%%= form_tag <%= rodauth %>.create_account_path, method: :post do %>
2
- <%%= render "login_field" %>
3
- <%%= render "login_confirm_field" if <%= rodauth %>.require_login_confirmation? %>
4
- <%%= render "password_field" if <%= rodauth %>.create_account_set_password? %>
5
- <%%= render "password_confirm_field" if <%= rodauth %>.create_account_set_password? && <%= rodauth %>.require_password_confirmation? %>
6
- <%%= render "submit", value: "Create Account" %>
7
- <%% end %>
1
+ <% content_for :title, rodauth.create_account_page_title %>
2
+
3
+ <%= form_with url: rodauth.create_account_path, method: :post do |form| %>
4
+ <div class="form-group mb-3">
5
+ <%= form.label "login", rodauth.login_label, class: "form-label" %>
6
+ <%= form.email_field rodauth.login_param, value: params[rodauth.login_param], id: "login", autocomplete: "email", required: true, class: "form-control #{"is-invalid" if rodauth.field_error(rodauth.login_param)}", aria: ({ invalid: true, describedby: "login_error_message" } if rodauth.field_error(rodauth.login_param)) %>
7
+ <%= content_tag(:span, rodauth.field_error(rodauth.login_param), class: "invalid-feedback", id: "login_error_message") if rodauth.field_error(rodauth.login_param) %>
8
+ </div>
9
+
10
+ <% if rodauth.require_login_confirmation? %>
11
+ <div class="form-group mb-3">
12
+ <%= form.label "login-confirm", rodauth.login_confirm_label, class: "form-label" %>
13
+ <%= form.email_field rodauth.login_confirm_param, value: params[rodauth.login_confirm_param], id: "login-confirm", autocomplete: "email", required: true, class: "form-control #{"is-invalid" if rodauth.field_error(rodauth.login_confirm_param)}", aria: ({ invalid: true, describedby: "login-confirm_error_message" } if rodauth.field_error(rodauth.login_confirm_param)) %>
14
+ <%= content_tag(:span, rodauth.field_error(rodauth.login_confirm_param), class: "invalid-feedback", id: "login-confirm_error_message") if rodauth.field_error(rodauth.login_confirm_param) %>
15
+ </div>
16
+ <% end %>
17
+
18
+ <% if rodauth.create_account_set_password? %>
19
+ <div class="form-group mb-3">
20
+ <%= form.label "password", rodauth.password_label, class: "form-label" %>
21
+ <%= form.password_field rodauth.password_param, value: "", id: "password", autocomplete: rodauth.password_field_autocomplete_value, required: true, class: "form-control #{"is-invalid" if rodauth.field_error(rodauth.password_param)}", aria: ({ invalid: true, describedby: "password_error_message" } if rodauth.field_error(rodauth.password_param)) %>
22
+ <%= content_tag(:span, rodauth.field_error(rodauth.password_param), class: "invalid-feedback", id: "password_error_message") if rodauth.field_error(rodauth.password_param) %>
23
+ </div>
24
+
25
+ <% if rodauth.require_password_confirmation? %>
26
+ <div class="form-group mb-3">
27
+ <%= form.label "password-confirm", rodauth.password_confirm_label, class: "form-label" %>
28
+ <%= form.password_field rodauth.password_confirm_param, value: "", id: "password-confirm", autocomplete: "new-password", required: true, class: "form-control #{"is-invalid" if rodauth.field_error(rodauth.password_confirm_param)}", aria: ({ invalid: true, describedby: "password-confirm_error_message" } if rodauth.field_error(rodauth.password_confirm_param)) %>
29
+ <%= content_tag(:span, rodauth.field_error(rodauth.password_confirm_param), class: "invalid-feedback", id: "password-confirm_error_message") if rodauth.field_error(rodauth.password_confirm_param) %>
30
+ </div>
31
+ <% end %>
32
+ <% end %>
33
+
34
+ <div class="form-group mb-3">
35
+ <%= form.submit rodauth.create_account_button, class: "btn btn-primary" %>
36
+ </div>
37
+ <% end %>
@@ -1,3 +1,7 @@
1
- <%%= form_tag <%= rodauth %>.email_auth_path, method: :post do %>
2
- <%%= render "submit", value: "Login" %>
3
- <%% end %>
1
+ <% content_for :title, rodauth.email_auth_page_title %>
2
+
3
+ <%= form_with url: rodauth.email_auth_path, method: :post do |form| %>
4
+ <div class="form-group mb-3">
5
+ <%= form.submit rodauth.login_button, class: "btn btn-primary" %>
6
+ </div>
7
+ <% end %>
@@ -1,3 +1,5 @@
1
- <%%= render "login_form_header" %>
2
- <%%= render "login_form" %>
3
- <%%= render "login_form_footer" %>
1
+ <% content_for :title, rodauth.login_page_title %>
2
+
3
+ <%= render "login_form_header" %>
4
+ <%= render "login_form" %>
5
+ <%= render "login_form_footer" %>
@@ -1,4 +1,16 @@
1
- <%%= form_tag <%= rodauth %>.logout_path, method: :post do %>
2
- <%%= render "global_logout_field" if <%= rodauth %>.features.include?(:active_sessions) %>
3
- <%%= render "submit", value: "Logout", class: "btn btn-warning" %>
4
- <%% end %>
1
+ <% content_for :title, rodauth.logout_page_title %>
2
+
3
+ <%= form_with url: rodauth.logout_path, method: :post do |form| %>
4
+ <% if rodauth.features.include?(:active_sessions) %>
5
+ <div class="form-group mb-3">
6
+ <div class="form-check">
7
+ <%= form.check_box rodauth.global_logout_param, id: "global-logout", class: "form-check-input" %>
8
+ <%= form.label "global-logout", rodauth.global_logout_label, class: "form-check-label" %>
9
+ </div>
10
+ </div>
11
+ <% end %>
12
+
13
+ <div class="form-group mb-3">
14
+ <%= form.submit rodauth.logout_button, class: "btn btn-warning" %>
15
+ </div>
16
+ <% end %>