rodauth-rails 1.6.2 → 1.6.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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