rodauth-rails 1.6.2 → 1.6.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f29cbaceb49208cac659dd31cbfcb874bf0df2c3b6b0133680f75904ab07a578
4
- data.tar.gz: 2c9c7ed9e5d91428f15058274c0896298402e93d22a94c90c7d127e33699a1a7
3
+ metadata.gz: a49174b3518279a0414854312fe7ce6e5f8c9094b41a39d7e5f89b1860e844aa
4
+ data.tar.gz: 6a3fe7d3577aaaa944630b874688d6223139cb50877aa700157b537eeea97f35
5
5
  SHA512:
6
- metadata.gz: 546070f740b95f26d8f29b632672339215383737e9b6497c64d613c3c07929052477022a4e70051254d267a037c7b794448674aa99927d26edb4322cf274f778
7
- data.tar.gz: 638ecc60b072197c490180a8241ed5af02ed3d6114f3cf5aa2e621ced9296e175d6d5b579543e43d23283164d3193551eb68efd54b2ef3b68cb79f49462397d8
6
+ metadata.gz: 7ef86cb7557eb8aadf205ea5593332e678e6165768aa4288d6ba50456d608fff0eca2c4ce33bd767111ac5a6f07a4fae00d39fd9957ead4198abb4d40816fc77
7
+ data.tar.gz: 22158dec21b5cb2d5b6b77fc29c34515bf7cf90febafa87c576536a31f96866fb404f488d1970cd0db9fae2503b6dc274318e017311d6a6b0eb765e00e714776
data/CHANGELOG.md CHANGED
@@ -1,3 +1,23 @@
1
+ ## 1.6.4 (2022-11-24)
2
+
3
+ * Make `#rails_account` work on directly allocated Rodauth object with `@account` set (@janko)
4
+
5
+ * Add commented out email configuration for `password_reset_notify` feature (@janko)
6
+
7
+ * Design generated mailer in a way that exposes the Rodauth object (@janko)
8
+
9
+ * Fix generated logout page always logging out globally when using active sessions feature (@janko)
10
+
11
+ ## 1.6.3 (2022-11-15)
12
+
13
+ * Suggest passing an integer to `verify_account_grace_period` instead of `ActiveSupport::Duration` (@vlado)
14
+
15
+ * Use `pass` plugin for forwarding other `{prefix}/*` requests when automatically routing the prefix (@janko)
16
+
17
+ * Set minimum password length to 8 in the generated configuration, as per OWASP recommendation (@janko)
18
+
19
+ * Set maximum password bytesize to 72 in the generated configuration, as bcrypt truncates inputs longer than 72 bytes (@janko)
20
+
1
21
  ## 1.6.2 (2022-09-19)
2
22
 
3
23
  * Use matching precision for current timestamp default values in Active Record 7.0+ migrations on MySQL (@janko)
data/README.md CHANGED
@@ -40,26 +40,27 @@ of the advantages that stand out for me:
40
40
  * consistent before/after hooks around everything
41
41
  * dedicated object encapsulating all authentication logic
42
42
 
43
- One common concern is the fact that, unlike most other authentication
44
- frameworks for Rails, Rodauth uses [Sequel] for database interaction instead of
45
- Active Record. There are good reasons for this, and to make Rodauth work
46
- smoothly alongside Active Record, rodauth-rails configures Sequel to [reuse
47
- Active Record's database connection][sequel-activerecord_connection].
43
+ ### Sequel
48
44
 
49
- ## Installation
45
+ One common concern for people coming from other Rails authentication frameworks
46
+ is the fact that Rodauth uses [Sequel] for database interaction instead of
47
+ Active Record. Sequel has powerful APIs for building advanced queries,
48
+ supporting complex SQL expressions, database-agnostic date arithmetic, SQL
49
+ function calls and more, all without having to drop down to raw SQL.
50
50
 
51
- Add the gem to your Gemfile:
51
+ For Rails apps using Active Record, rodauth-rails configures Sequel to [reuse
52
+ Active Record's database connection][sequel-activerecord_connection]. This
53
+ makes it run smoothly alongside Active Record, even allowing calling Active
54
+ Record code from within Rodauth configuration. So, for all intents and
55
+ purposes, Sequel can be treated just as an implementation detail of Rodauth.
52
56
 
53
- ```rb
54
- gem "rodauth-rails", "~> 1.0"
57
+ ## Installation
55
58
 
56
- # gem "jwt", require: false # for JWT feature
57
- # gem "rotp", require: false # for OTP feature
58
- # gem "rqrcode", require: false # for OTP feature
59
- # gem "webauthn", require: false # for WebAuthn feature
60
- ```
59
+ Add the gem to your project:
61
60
 
62
- Then run `bundle install`.
61
+ ```sh
62
+ $ bundle add rodauth-rails
63
+ ```
63
64
 
64
65
  Next, run the install generator:
65
66
 
@@ -143,36 +144,44 @@ authentication experience, and the forms use [Bootstrap] markup.
143
144
 
144
145
  ### Current account
145
146
 
146
- The `#current_account` method is defined in controllers and views, which
147
- returns the model instance of the currently logged in account. If the account
148
- doesn't exist in the database, the session will be cleared.
147
+ The Rodauth object defines a `#rails_account` method, which returns a model
148
+ instance of the currently logged in account. You can create a helper method for
149
+ easy access from controllers and views:
149
150
 
150
151
  ```rb
151
- current_account #=> #<Account id=123 email="user@example.com">
152
- current_account.email #=> "user@example.com"
153
- ```
152
+ class ApplicationController < ActionController::Base
153
+ private
154
154
 
155
- Pass the configuration name to retrieve accounts belonging to other Rodauth
156
- configurations:
155
+ def current_account
156
+ rodauth.rails_account
157
+ end
158
+ helper_method :current_account # skip if inheriting from ActionController::API
159
+ end
160
+ ```
157
161
 
158
162
  ```rb
159
- current_account(:admin)
163
+ current_account #=> #<Account id=123 email="user@example.com">
164
+ current_account.email #=> "user@example.com"
160
165
  ```
161
166
 
162
- This just delegates to the `#rails_account` method on the Rodauth object.
167
+ If the session is logged in, but the account doesn't exist in the database, the
168
+ session will be reset.
163
169
 
164
170
  #### Custom account model
165
171
 
166
- The `#current_account` method will try to infer the account model class from
167
- the configured table name. If that fails, you can set the account model
168
- manually:
172
+ The `#rails_account` method will try to infer the account model class from
173
+ the configured table name. For example, if the `accounts_table` is set to
174
+ `:users`, it will automatically assume the model class of `User`.
175
+
176
+ However, if the model class cannot be inferred from the table name, you can
177
+ configure it manually:
169
178
 
170
179
  ```rb
171
180
  # app/misc/rodauth_main.rb
172
181
  class RodauthMain < Rodauth::Rails::Auth
173
182
  configure do
174
183
  # ...
175
- rails_account_model Authentication::Account # custom model name
184
+ rails_account_model { Authentication::Account } # custom model name
176
185
  end
177
186
  end
178
187
  ```
@@ -526,7 +535,7 @@ handles both storing the password hash in a column on the accounts table, or in
526
535
  a separate table.
527
536
 
528
537
  ```rb
529
- account = Account.create!(email: "user@example.com", password: "secret")
538
+ account = Account.create!(email: "user@example.com", password: "secret123")
530
539
 
531
540
  # when password hash is stored in a column on the accounts table
532
541
  account.password_hash #=> "$2a$12$k/Ub1I2iomi84RacqY89Hu4.M0vK7klRnRtzorDyvOkVI.hKhkNw."
@@ -649,7 +658,7 @@ end
649
658
  ```
650
659
  ```rb
651
660
  # primary configuration
652
- RodauthApp.rodauth.create_account(login: "user@example.com", password: "secret")
661
+ RodauthApp.rodauth.create_account(login: "user@example.com", password: "secret123")
653
662
  RodauthApp.rodauth.verify_account(account_login: "user@example.com")
654
663
 
655
664
  # secondary configuration
@@ -719,10 +728,9 @@ Rodauth::Rails.rodauth(:admin, params: { "param" => "value" })
719
728
  ## Testing
720
729
 
721
730
  For system and integration tests, which run the whole middleware stack,
722
- authentication can be exercised normally via HTTP endpoints. See [this wiki
723
- page](https://github.com/janko/rodauth-rails/wiki/Testing) for some examples.
731
+ authentication can be exercised normally via HTTP endpoints. For example, given
732
+ a controller
724
733
 
725
- For controller tests, you can log in accounts by modifying the session:
726
734
 
727
735
  ```rb
728
736
  # app/controllers/articles_controller.rb
@@ -734,9 +742,23 @@ class ArticlesController < ApplicationController
734
742
  end
735
743
  end
736
744
  ```
745
+
746
+ One can write `ActionDispatch::IntegrationTest` test helpers for `login` and
747
+ `logout` by making requests to the rodauth endpoints
748
+
737
749
  ```rb
738
750
  # test/controllers/articles_controller_test.rb
739
- class ArticlesControllerTest < ActionController::TestCase
751
+ class ArticlesControllerTest < ActionDispatch::IntegrationTest
752
+ def login(login, password)
753
+ post "/login", params: { login: login, password: password }
754
+ assert_redirected_to "/"
755
+ end
756
+
757
+ def logout
758
+ post "/logout"
759
+ assert_redirected_to "/"
760
+ end
761
+
740
762
  test "required authentication" do
741
763
  get :index
742
764
 
@@ -744,8 +766,8 @@ class ArticlesControllerTest < ActionController::TestCase
744
766
  assert_redirected_to "/login"
745
767
  assert_equal "Please login to continue", flash[:alert]
746
768
 
747
- account = Account.create!(email: "user@example.com", password: "secret", status: "verified")
748
- login(account)
769
+ account = Account.create!(email: "user@example.com", password: "secret123", status: "verified")
770
+ login(account.email, "secret123")
749
771
 
750
772
  get :index
751
773
  assert_response 200
@@ -756,45 +778,11 @@ class ArticlesControllerTest < ActionController::TestCase
756
778
  assert_response 302
757
779
  assert_equal "Please login to continue", flash[:alert]
758
780
  end
759
-
760
- private
761
-
762
- # Manually modify the session into what Rodauth expects.
763
- def login(account)
764
- session[:account_id] = account.id
765
- session[:authenticated_by] = ["password"] # or ["password", "totp"] for MFA
766
- end
767
-
768
- def logout
769
- session.clear
770
- end
771
781
  end
772
782
  ```
773
783
 
774
- If you're using multiple configurations with different session prefixes, you'll need
775
- to make sure to use those in controller tests as well:
776
-
777
- ```rb
778
- class RodauthAdmin < Rodauth::Rails::Auth
779
- configure do
780
- session_key_prefix "admin_"
781
- end
782
- end
783
- ```
784
- ```rb
785
- # in a controller test:
786
- session[:admin_account_id] = account.id
787
- session[:admin_authenticated_by] = ["password"]
788
- ```
789
-
790
- If you want to access the Rodauth instance in controller tests, you can do so
791
- through the controller instance:
792
-
793
- ```rb
794
- # in a controller test:
795
- @controller.rodauth #=> #<RodauthMain ...>
796
- @controller.rodauth(:admin) #=> #<RodauthAdmin ...>
797
- ```
784
+ For more examples and information about testing with rodauth, see
785
+ [this wiki page about testing](https://github.com/janko/rodauth-rails/wiki/Testing).
798
786
 
799
787
  ## Configuring
800
788
 
@@ -1068,19 +1056,6 @@ end
1068
1056
  <% rodauth(:admin) #=> #<RodauthAdmin> (if using multiple configurations) %>
1069
1057
  ```
1070
1058
 
1071
- ### Sequel
1072
-
1073
- Rodauth uses the [Sequel] library for database interaction, which offers
1074
- powerful APIs for building advanced queries (it supports SQL expressions,
1075
- database-agnostic date arithmetic, SQL function calls).
1076
-
1077
- If you're using Active Record in your application, the `rodauth:install`
1078
- generator automatically configures Sequel to reuse ActiveRecord's database
1079
- connection, using the [sequel-activerecord_connection] gem.
1080
-
1081
- This means that, from the usage perspective, Sequel can be considered just
1082
- as an implementation detail of Rodauth.
1083
-
1084
1059
  ## Rodauth defaults
1085
1060
 
1086
1061
  rodauth-rails changes some of the default Rodauth settings for easier setup:
@@ -1,64 +1,60 @@
1
1
  class RodauthMailer < ApplicationMailer
2
2
  def verify_account(name, account_id, key)
3
- @email_link = email_link(name, :verify_account, account_id, key)
4
- @account = find_account(name, account_id)
3
+ @rodauth = rodauth(name, account_id) { @verify_account_key_value = key }
4
+ @account = @rodauth.rails_account
5
5
 
6
- mail to: @account.email, subject: rodauth(name).verify_account_email_subject
6
+ mail to: @account.email, subject: @rodauth.verify_account_email_subject
7
7
  end
8
8
 
9
9
  def reset_password(name, account_id, key)
10
- @email_link = email_link(name, :reset_password, account_id, key)
11
- @account = find_account(name, account_id)
10
+ @rodauth = rodauth(name, account_id) { @reset_password_key_value = key }
11
+ @account = @rodauth.rails_account
12
12
 
13
- mail to: @account.email, subject: rodauth(name).reset_password_email_subject
13
+ mail to: @account.email, subject: @rodauth.reset_password_email_subject
14
14
  end
15
15
 
16
16
  def verify_login_change(name, account_id, key)
17
- @email_link = email_link(name, :verify_login_change, account_id, key)
18
- @account = find_account(name, account_id)
17
+ @rodauth = rodauth(name, account_id) { @verify_login_change_key_value = key }
18
+ @account = @rodauth.rails_account
19
19
  @new_email = @account.login_change_key.login
20
20
 
21
- mail to: @new_email, subject: rodauth(name).verify_login_change_email_subject
21
+ mail to: @new_email, subject: @rodauth.verify_login_change_email_subject
22
22
  end
23
23
 
24
24
  def password_changed(name, account_id)
25
- @account = find_account(name, account_id)
25
+ @rodauth = rodauth(name, account_id)
26
+ @account = @rodauth.rails_account
26
27
 
27
- mail to: @account.email, subject: rodauth(name).password_changed_email_subject
28
+ mail to: @account.email, subject: @rodauth.password_changed_email_subject
28
29
  end
29
30
 
31
+ # def reset_password_notify(name, account_id)
32
+ # @rodauth = rodauth(name, account_id)
33
+ # @account = @rodauth.rails_account
34
+
35
+ # mail to: @account.email, subject: @rodauth.reset_password_notify_email_subject
36
+ # end
37
+
30
38
  # def email_auth(name, account_id, key)
31
- # @email_link = email_link(name, :email_auth, account_id, key)
32
- # @account = find_account(name, account_id)
39
+ # @rodauth = rodauth(name, account_id) { @email_auth_key_value = key }
40
+ # @account = @rodauth.rails_account
33
41
 
34
- # mail to: @account.email, subject: rodauth(name).email_auth_email_subject
42
+ # mail to: @account.email, subject: @rodauth.email_auth_email_subject
35
43
  # end
36
44
 
37
45
  # def unlock_account(name, account_id, key)
38
- # @email_link = email_link(name, :unlock_account, account_id, key)
39
- # @account = find_account(name, account_id)
46
+ # @rodauth = rodauth(name, account_id) { @unlock_account_key_value = key }
47
+ # @account = @rodauth.rails_account
40
48
 
41
- # mail to: @account.email, subject: rodauth(name).unlock_account_email_subject
49
+ # mail to: @account.email, subject: @rodauth.unlock_account_email_subject
42
50
  # end
43
51
 
44
52
  private
45
53
 
46
- def find_account(_name, account_id)
47
- <% if defined?(ActiveRecord::Railtie) -%>
48
- Account.find(account_id)
49
- <% else -%>
50
- Account.with_pk!(account_id)
51
- <% end -%>
52
- end
53
-
54
- def email_link(name, action, account_id, key)
55
- instance = rodauth(name)
56
- instance.instance_variable_set(:@account, { id: account_id })
57
- instance.instance_variable_set(:"@#{action}_key_value", key)
58
- instance.public_send(:"#{action}_email_link")
59
- end
60
-
61
- def rodauth(name)
62
- RodauthApp.rodauth(name).allocate
54
+ def rodauth(name, account_id, &block)
55
+ instance = RodauthApp.rodauth(name).allocate
56
+ instance.instance_eval { @account = account_ds(account_id).first! }
57
+ instance.instance_eval(&block) if block
58
+ instance
63
59
  end
64
60
  end
@@ -40,6 +40,11 @@ class RodauthMain < Rodauth::Rails::Auth
40
40
  # Store password hash in a column instead of a separate table.
41
41
  account_password_hash_column :password_hash
42
42
 
43
+ # Passwords shorter than 8 characters are considered weak according to OWASP.
44
+ password_minimum_length 8
45
+ # bcrypt has a maximum input length of 72 bytes, truncating any extra bytes.
46
+ password_maximum_bytes 72
47
+
43
48
  # Set password when creating account instead of when verifying.
44
49
  verify_account_set_password? false
45
50
 
@@ -71,6 +76,9 @@ class RodauthMain < Rodauth::Rails::Auth
71
76
  create_password_changed_email do
72
77
  RodauthMailer.password_changed(self.class.configuration_name, account_id)
73
78
  end
79
+ # create_reset_password_notify_email do
80
+ # RodauthMailer.reset_password_notify(self.class.configuration_name, account_id)
81
+ # end
74
82
  # create_email_auth_email do
75
83
  # RodauthMailer.email_auth(self.class.configuration_name, account_id, email_auth_key_value)
76
84
  # end
@@ -150,7 +158,7 @@ class RodauthMain < Rodauth::Rails::Auth
150
158
 
151
159
  # ==> Deadlines
152
160
  # Change default deadlines for some actions.
153
- # verify_account_grace_period 3.days
161
+ # verify_account_grace_period 3.days.to_i
154
162
  # reset_password_deadline_interval Hash[hours: 6]
155
163
  # verify_login_change_deadline_interval Hash[days: 2]
156
164
  <% unless jwt? -%>
@@ -2,7 +2,7 @@
2
2
  <% if rodauth.features.include?(:active_sessions) %>
3
3
  <div class="form-group mb-3">
4
4
  <div class="form-check">
5
- <%= form.check_box rodauth.global_logout_param, id: "global-logout", class: "form-check-input" %>
5
+ <%= form.check_box rodauth.global_logout_param, id: "global-logout", class: "form-check-input", include_hidden: false %>
6
6
  <%= form.label "global-logout", rodauth.global_logout_label, class: "form-check-label" %>
7
7
  </div>
8
8
  </div>
@@ -1,5 +1,5 @@
1
1
  Someone has requested a login link for the account with this email
2
2
  address. If you did not request a login link, please ignore this
3
3
  message. If you requested a login link, please go to
4
- <%= @email_link %>
4
+ <%= @rodauth.email_auth_email_link %>
5
5
  to login to this account.
@@ -1,5 +1,5 @@
1
1
  Someone has requested a password reset for the account with this email
2
2
  address. If you did not request a password reset, please ignore this
3
3
  message. If you requested a password reset, please go to
4
- <%= @email_link %>
4
+ <%= @rodauth.reset_password_email_link %>
5
5
  to reset the password for the account.
@@ -0,0 +1,2 @@
1
+ Someone (hopefully you) has reset the password for the account
2
+ associated to this email address.
@@ -1,5 +1,5 @@
1
- Someone has requested that the account with this email be unlocked.
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
- <%= @email_link %>
4
+ <%= @rodauth.unlock_account_email_link %>
5
5
  to unlock this account.
@@ -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
- <%= @email_link %>
3
+ <%= @rodauth.verify_account_email_link %>
4
4
  to verify the account.
@@ -6,5 +6,5 @@ New email: <%= @new_email %>
6
6
 
7
7
  If you did not request this login change, please ignore this message. If you
8
8
  requested this login change, please go to
9
- <%= @email_link %>
9
+ <%= @rodauth.verify_login_change_email_link %>
10
10
  to verify the login change.
@@ -19,6 +19,7 @@ module Rodauth
19
19
 
20
20
  plugin :hooks
21
21
  plugin :render, layout: false
22
+ plugin :pass
22
23
 
23
24
  def self.configure(*args, **options, &block)
24
25
  auth_class = args.shift if args[0].is_a?(Class)
@@ -30,6 +31,7 @@ module Rodauth
30
31
 
31
32
  plugin :rodauth, auth_class: auth_class, name: name, csrf: false, flash: false, json: true, **options, &block
32
33
 
34
+ # we need to do it after request methods from rodauth have been included
33
35
  self::RodaRequest.include RequestMethods
34
36
  end
35
37
 
@@ -66,13 +68,15 @@ module Rodauth
66
68
  end
67
69
 
68
70
  module RequestMethods
71
+ # Automatically route the prefix if it hasn't been routed already. This
72
+ # way people only have to update prefix in their Rodauth configurations.
69
73
  def rodauth(name = nil)
70
74
  prefix = scope.rodauth(name).prefix
71
75
 
72
76
  if prefix.present? && remaining_path == path_info
73
77
  on prefix[1..-1] do
74
78
  super
75
- break # forward other `{prefix}/*` requests to the rails router
79
+ pass # forward other {prefix}/* requests downstream
76
80
  end
77
81
  else
78
82
  super
@@ -1,15 +1,19 @@
1
+ require "active_support/concern"
2
+
1
3
  module Rodauth
2
4
  module Rails
3
5
  module Feature
4
6
  module Base
5
- def self.included(feature)
6
- feature.auth_methods :rails_controller
7
- feature.auth_value_methods :rails_account_model
8
- feature.auth_cached_method :rails_controller_instance
7
+ extend ActiveSupport::Concern
8
+
9
+ included do
10
+ auth_methods :rails_controller
11
+ auth_value_methods :rails_account_model
12
+ auth_cached_method :rails_controller_instance
9
13
  end
10
14
 
11
15
  def rails_account
12
- return unless logged_in?
16
+ return unless account || logged_in?
13
17
 
14
18
  account_from_session unless account
15
19
 
@@ -2,6 +2,8 @@ module Rodauth
2
2
  module Rails
3
3
  module Feature
4
4
  module Callbacks
5
+ extend ActiveSupport::Concern
6
+
5
7
  private
6
8
 
7
9
  def _around_rodauth
@@ -2,8 +2,10 @@ module Rodauth
2
2
  module Rails
3
3
  module Feature
4
4
  module Csrf
5
- def self.included(feature)
6
- feature.auth_methods(
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ auth_methods(
7
9
  :rails_csrf_tag,
8
10
  :rails_csrf_param,
9
11
  :rails_csrf_token,
@@ -2,8 +2,10 @@ module Rodauth
2
2
  module Rails
3
3
  module Feature
4
4
  module Email
5
- def self.included(feature)
6
- feature.depends :email_base
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ depends :email_base
7
9
  end
8
10
 
9
11
  private
@@ -2,6 +2,8 @@ module Rodauth
2
2
  module Rails
3
3
  module Feature
4
4
  module Instrumentation
5
+ extend ActiveSupport::Concern
6
+
5
7
  private
6
8
 
7
9
  def _around_rodauth
@@ -2,6 +2,8 @@ module Rodauth
2
2
  module Rails
3
3
  module Feature
4
4
  module InternalRequest
5
+ extend ActiveSupport::Concern
6
+
5
7
  def domain
6
8
  return super unless missing_host? && rails_url_options
7
9
 
@@ -2,8 +2,10 @@ module Rodauth
2
2
  module Rails
3
3
  module Feature
4
4
  module Render
5
- def self.included(feature)
6
- feature.auth_methods :rails_render
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ auth_methods :rails_render
7
9
  end
8
10
 
9
11
  # Renders templates with layout. First tries to render a user-defined
@@ -1,5 +1,5 @@
1
1
  module Rodauth
2
2
  module Rails
3
- VERSION = "1.6.2"
3
+ VERSION = "1.6.4"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rodauth-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.2
4
+ version: 1.6.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Janko Marohnić
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-09-19 00:00:00.000000000 Z
11
+ date: 2022-11-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -265,6 +265,7 @@ files:
265
265
  - lib/generators/rodauth/templates/app/views/rodauth_mailer/email_auth.text.erb
266
266
  - lib/generators/rodauth/templates/app/views/rodauth_mailer/password_changed.text.erb
267
267
  - lib/generators/rodauth/templates/app/views/rodauth_mailer/reset_password.text.erb
268
+ - lib/generators/rodauth/templates/app/views/rodauth_mailer/reset_password_notify.text.erb
268
269
  - lib/generators/rodauth/templates/app/views/rodauth_mailer/unlock_account.text.erb
269
270
  - lib/generators/rodauth/templates/app/views/rodauth_mailer/verify_account.text.erb
270
271
  - lib/generators/rodauth/templates/app/views/rodauth_mailer/verify_login_change.text.erb