authentication-zero 2.12.4 → 2.13.0

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.
Files changed (27) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -0
  3. data/Gemfile.lock +1 -1
  4. data/lib/authentication_zero/version.rb +1 -1
  5. data/lib/generators/authentication/authentication_generator.rb +6 -3
  6. data/lib/generators/authentication/templates/controllers/api/application_controller.rb.tt +12 -0
  7. data/lib/generators/authentication/templates/controllers/api/identity/email_verifications_controller.rb.tt +2 -2
  8. data/lib/generators/authentication/templates/controllers/api/identity/password_resets_controller.rb.tt +9 -14
  9. data/lib/generators/authentication/templates/controllers/html/application_controller.rb.tt +12 -0
  10. data/lib/generators/authentication/templates/controllers/html/identity/email_verifications_controller.rb.tt +2 -2
  11. data/lib/generators/authentication/templates/controllers/html/identity/password_resets_controller.rb.tt +8 -13
  12. data/lib/generators/authentication/templates/erb/user_mailer/{email_verify_confirmation.html.erb.tt → email_verification.html.erb.tt} +1 -1
  13. data/lib/generators/authentication/templates/erb/user_mailer/{email_verify_confirmation.text.erb.tt → email_verification.text.erb.tt} +1 -1
  14. data/lib/generators/authentication/templates/erb/user_mailer/{password_reset_provision.html.erb.tt → password_reset.html.erb.tt} +1 -1
  15. data/lib/generators/authentication/templates/erb/user_mailer/{password_reset_provision.text.erb.tt → password_reset.text.erb.tt} +1 -1
  16. data/lib/generators/authentication/templates/mailers/user_mailer.rb.tt +4 -4
  17. data/lib/generators/authentication/templates/migrations/create_email_verification_tokens_migration.rb.tt +7 -0
  18. data/lib/generators/authentication/templates/migrations/create_password_reset_tokens_migration.rb.tt +7 -0
  19. data/lib/generators/authentication/templates/models/email_verification_token.rb.tt +3 -0
  20. data/lib/generators/authentication/templates/models/password_reset_token.rb.tt +3 -0
  21. data/lib/generators/authentication/templates/models/user.rb.tt +4 -1
  22. data/lib/generators/authentication/templates/test_unit/controllers/api/identity/email_verifications_controller_test.rb.tt +6 -15
  23. data/lib/generators/authentication/templates/test_unit/controllers/api/identity/password_resets_controller_test.rb.tt +8 -7
  24. data/lib/generators/authentication/templates/test_unit/controllers/html/identity/email_verifications_controller_test.rb.tt +6 -14
  25. data/lib/generators/authentication/templates/test_unit/controllers/html/identity/password_resets_controller_test.rb.tt +9 -6
  26. metadata +10 -7
  27. data/lib/generators/authentication/templates/models/locking.rb.tt +0 -10
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e153855bfc24252626eb9ccb0381fadf99eda55f66db6d80081de90ea07eede5
4
- data.tar.gz: a0fe741b9b4c073401fea77218fcfb2b7665041a073655bce689d0b84f5ee6ca
3
+ metadata.gz: 34663ddecbc5d0c0276a99a7f7d0f867e90c2f731e1c56a5d508738469647795
4
+ data.tar.gz: bbffe8e2dff90913524ff9744efa49cb1097d78745206579bb49251472a016ed
5
5
  SHA512:
6
- metadata.gz: 661fa249b995fd6c7e0076a480597c972178a9f05231ff271fc4ecd6e24916f7d0eda5a428d4e4251c2fc0c29de6ea4b8c902f1f3665557bf15e6e2aa5897533
7
- data.tar.gz: 699dc8d96580ba018fd238ff843ceed4d07a0b623f7b3dedd8ec88db2a2fa886025f26e8b5d526a817c0209d80db9a2b0bca0bdcb8c5f3122d10017d45e0b6f0
6
+ metadata.gz: 38dd57dfb438408fb9ff4099508568c90bc9416fe5e624b4e38eaeba4f886e61340a2104976e62d9214d95d57f45a15a8dac6dd8789022a4cf24f6225f4e98be
7
+ data.tar.gz: 9393b6ceb9203be1bf0c5643640422ec8c64d96af34b01087f20d533ed781dd8f6b553350d698658a8b5cf1a07b36c965822a03d836451bdcec44c882f87a39f
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## Authentication Zero 2.13.0 (May 2, 2022) ##
2
+
3
+ * Migrate tokens to a table structure
4
+ * Refactor lockable to a controller method
5
+
1
6
  ## Authentication Zero 2.12.0 (March 28, 2022) ##
2
7
 
3
8
  * Remove model option from generator
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- authentication-zero (2.12.4)
4
+ authentication-zero (2.13.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -1,3 +1,3 @@
1
1
  module AuthenticationZero
2
- VERSION = "2.12.4"
2
+ VERSION = "2.13.0"
3
3
  end
@@ -46,8 +46,8 @@ class AuthenticationGenerator < Rails::Generators::Base
46
46
 
47
47
  def add_environment_configurations
48
48
  ratelimit_code = <<~CODE
49
- # Rate limit general requests by IP address in a rate of 1000 requests per hour
50
- config.middleware.use(Rack::Ratelimit, name: "General", rate: [1000, 1.hour], redis: Redis.new, logger: Rails.logger) { |env| ActionDispatch::Request.new(env).ip }
49
+ # Rate limit general requests by IP address in a rate of 1000 requests per minute
50
+ config.middleware.use(Rack::Ratelimit, name: "General", rate: [1000, 1.minute], redis: Redis.new, logger: Rails.logger) { |env| ActionDispatch::Request.new(env).ip }
51
51
  CODE
52
52
 
53
53
  environment ratelimit_code, env: "production" if options.ratelimit?
@@ -56,14 +56,17 @@ class AuthenticationGenerator < Rails::Generators::Base
56
56
  def create_migrations
57
57
  migration_template "migrations/create_users_migration.rb", "#{db_migrate_path}/create_users.rb"
58
58
  migration_template "migrations/create_sessions_migration.rb", "#{db_migrate_path}/create_sessions.rb"
59
+ migration_template "migrations/create_email_verification_tokens_migration.rb", "#{db_migrate_path}/create_email_verification_tokens.rb"
60
+ migration_template "migrations/create_password_reset_tokens_migration.rb", "#{db_migrate_path}/create_password_reset_tokens.rb"
59
61
  migration_template "migrations/create_events_migration.rb", "#{db_migrate_path}/create_events.rb" if options.trackable?
60
62
  end
61
63
 
62
64
  def create_models
63
65
  template "models/user.rb", "app/models/user.rb"
64
66
  template "models/session.rb", "app/models/session.rb"
67
+ template "models/email_verification_token.rb", "app/models/email_verification_token.rb"
68
+ template "models/password_reset_token.rb", "app/models/password_reset_token.rb"
65
69
  template "models/current.rb", "app/models/current.rb"
66
- template "models/locking.rb", "app/models/locking.rb" if options.lockable?
67
70
  template "models/event.rb", "app/models/event.rb" if options.trackable?
68
71
  end
69
72
 
@@ -10,6 +10,18 @@ class ApplicationController < ActionController::API
10
10
  end
11
11
  end
12
12
  <%- end -%>
13
+ <%- if options.lockable? %>
14
+ def self.lock_on(actions, wait: 1.minute, attempts: 1000, &block)
15
+ before_action(only: actions) do
16
+ counter = Kredis.counter("lock_on:#{request.remote_ip}:#{params[:controller]}:#{params[:action]}", expires_in: wait)
17
+ counter.increment
18
+
19
+ if counter.value > attempts
20
+ instance_exec(&block)
21
+ end
22
+ end
23
+ end
24
+ <%- end -%>
13
25
 
14
26
  private
15
27
  def authenticate
@@ -8,7 +8,7 @@ class Identity::EmailVerificationsController < ApplicationController
8
8
  end
9
9
 
10
10
  def create
11
- UserMailer.with(user: Current.user).email_verify_confirmation.deliver_later
11
+ UserMailer.with(user: Current.user).email_verification.deliver_later
12
12
  end
13
13
 
14
14
  private
@@ -22,7 +22,7 @@ class Identity::EmailVerificationsController < ApplicationController
22
22
  render json: { error: "That email verification code is invalid" }, status: :bad_request
23
23
  end
24
24
  <%- else -%>
25
- @user = User.where(email: params[:email]).find_signed!(params[:token], purpose: params[:email])
25
+ @token = EmailVerificationToken.find_signed!(params[:sid]); @user = @token.user
26
26
  rescue
27
27
  render json: { error: "That email verification link is invalid" }, status: :bad_request
28
28
  <%- end -%>
@@ -1,22 +1,24 @@
1
1
  class Identity::PasswordResetsController < ApplicationController
2
2
  skip_before_action :authenticate
3
3
 
4
- <%- if options.lockable? -%>
5
- before_action :require_locking, only: :create
6
- <%- end -%>
7
4
  before_action :set_user, only: :update
5
+ <%- if options.lockable? %>
6
+ lock_on :create, wait: 1.hour, attempts: 10 do
7
+ render json: { error: "You've exceeded the maximum number of attempts" }, status: :too_many_requests
8
+ end
9
+ <%- end -%>
8
10
 
9
11
  def create
10
12
  if @user = User.find_by(email: params[:email], verified: true)
11
- UserMailer.with(user: @user).password_reset_provision.deliver_later
13
+ UserMailer.with(user: @user).password_reset.deliver_later
12
14
  else
13
- render json: { error: "You can't reset your password until you verify your email" }, status: :not_found
15
+ render json: { error: "You can't reset your password until you verify your email" }, status: :bad_request
14
16
  end
15
17
  end
16
18
 
17
19
  def update
18
20
  if @user.update(user_params)
19
- render json: @user
21
+ @token.destroy; render json: @user
20
22
  else
21
23
  render json: @user.errors, status: :unprocessable_entity
22
24
  end
@@ -24,7 +26,7 @@ class Identity::PasswordResetsController < ApplicationController
24
26
 
25
27
  private
26
28
  def set_user
27
- @user = User.find_signed!(params[:token], purpose: :password_reset)
29
+ @token = PasswordResetToken.find_signed!(params[:sid]); @user = @token.user
28
30
  rescue
29
31
  render json: { error: "That password reset link is invalid" }, status: :bad_request
30
32
  end
@@ -32,11 +34,4 @@ class Identity::PasswordResetsController < ApplicationController
32
34
  def user_params
33
35
  params.permit(:password, :password_confirmation)
34
36
  end
35
- <%- if options.lockable? %>
36
- def require_locking
37
- Locking.lock_on("password_reset_lock:#{request.remote_ip}", wait: 1.hour, attempts: 10) do
38
- render json: { error: "You've exceeded the maximum number of attempts" }, status: :too_many_requests
39
- end
40
- end
41
- <%- end -%>
42
37
  end
@@ -8,6 +8,18 @@ class ApplicationController < ActionController::Base
8
8
  end
9
9
  end
10
10
  <%- end -%>
11
+ <%- if options.lockable? %>
12
+ def self.lock_on(actions, wait: 1.minute, attempts: 1000, &block)
13
+ before_action(only: actions) do
14
+ counter = Kredis.counter("lock_on:#{request.remote_ip}:#{params[:controller]}:#{params[:action]}", expires_in: wait)
15
+ counter.increment
16
+
17
+ if counter.value > attempts
18
+ instance_exec(&block)
19
+ end
20
+ end
21
+ end
22
+ <%- end -%>
11
23
 
12
24
  private
13
25
  def authenticate
@@ -9,13 +9,13 @@ class Identity::EmailVerificationsController < ApplicationController
9
9
  end
10
10
 
11
11
  def create
12
- UserMailer.with(user: Current.user).email_verify_confirmation.deliver_later
12
+ UserMailer.with(user: Current.user).email_verification.deliver_later
13
13
  redirect_to root_path, notice: "We sent a verification email to your email address"
14
14
  end
15
15
 
16
16
  private
17
17
  def set_user
18
- @user = User.where(email: params[:email]).find_signed!(params[:token], purpose: params[:email])
18
+ @token = EmailVerificationToken.find_signed!(params[:sid]); @user = @token.user
19
19
  rescue
20
20
  redirect_to edit_identity_email_path, alert: "That email verification link is invalid"
21
21
  end
@@ -1,10 +1,12 @@
1
1
  class Identity::PasswordResetsController < ApplicationController
2
2
  skip_before_action :authenticate
3
3
 
4
- <%- if options.lockable? -%>
5
- before_action :require_locking, only: :create
6
- <%- end -%>
7
4
  before_action :set_user, only: %i[ edit update ]
5
+ <%- if options.lockable? %>
6
+ lock_on :create, wait: 1.hour, attempts: 10 do
7
+ redirect_to new_identity_password_reset_path, alert: "You've exceeded the maximum number of attempts"
8
+ end
9
+ <%- end -%>
8
10
 
9
11
  def new
10
12
  end
@@ -14,7 +16,7 @@ class Identity::PasswordResetsController < ApplicationController
14
16
 
15
17
  def create
16
18
  if @user = User.find_by(email: params[:email], verified: true)
17
- UserMailer.with(user: @user).password_reset_provision.deliver_later
19
+ UserMailer.with(user: @user).password_reset.deliver_later
18
20
  redirect_to sign_in_path, notice: "Check your email for reset instructions"
19
21
  else
20
22
  redirect_to new_identity_password_reset_path, alert: "You can't reset your password until you verify your email"
@@ -23,7 +25,7 @@ class Identity::PasswordResetsController < ApplicationController
23
25
 
24
26
  def update
25
27
  if @user.update(user_params)
26
- redirect_to sign_in_path, notice: "Your password was reset successfully. Please sign in"
28
+ @token.destroy; redirect_to sign_in_path, notice: "Your password was reset successfully. Please sign in"
27
29
  else
28
30
  render :edit, status: :unprocessable_entity
29
31
  end
@@ -31,7 +33,7 @@ class Identity::PasswordResetsController < ApplicationController
31
33
 
32
34
  private
33
35
  def set_user
34
- @user = User.find_signed!(params[:token], purpose: :password_reset)
36
+ @token = PasswordResetToken.find_signed!(params[:sid]); @user = @token.user
35
37
  rescue
36
38
  redirect_to new_identity_password_reset_path, alert: "That password reset link is invalid"
37
39
  end
@@ -39,11 +41,4 @@ class Identity::PasswordResetsController < ApplicationController
39
41
  def user_params
40
42
  params.permit(:password, :password_confirmation)
41
43
  end
42
- <%- if options.lockable? %>
43
- def require_locking
44
- Locking.lock_on("password_reset_lock:#{request.remote_ip}", wait: 1.hour, attempts: 10) do
45
- redirect_to new_identity_password_reset_path, alert: "You've exceeded the maximum number of attempts"
46
- end
47
- end
48
- <%- end -%>
49
44
  end
@@ -7,7 +7,7 @@
7
7
  <%- if code_verifiable? -%>
8
8
  <strong><%%= @user.verification_code.value %></strong>
9
9
  <%- else -%>
10
- <%%= link_to "Yes, use this email for my account", edit_identity_email_verification_url(token: @signed_id, email: @user.email) %>
10
+ <%%= link_to "Yes, use this email for my account", edit_identity_email_verification_url(sid: @signed_id) %>
11
11
  <%- end -%>
12
12
 
13
13
  <hr>
@@ -7,7 +7,7 @@ You must <%= code_verifiable? ? "put the code" : "hit the link" %> below to conf
7
7
  <%- if code_verifiable? -%>
8
8
  <%%= @user.verification_code.value %>
9
9
  <%- else -%>
10
- [Yes, use this email for my account]<%%= edit_identity_email_verification_url(token: @signed_id, email: @user.email) %>
10
+ [Yes, use this email for my account]<%%= edit_identity_email_verification_url(sid: @signed_id) %>
11
11
  <%- end -%>
12
12
 
13
13
  Have questions or need help? Just reply to this email and our support team will help you sort it out.
@@ -2,7 +2,7 @@
2
2
 
3
3
  <p>Can't remember your password for <strong><%%= @user.email %></strong>? That's OK, it happens. Just hit the link below to set a new one.</p>
4
4
 
5
- <p><%%= link_to "Reset my password", edit_identity_password_reset_url(token: @signed_id) %></p>
5
+ <p><%%= link_to "Reset my password", edit_identity_password_reset_url(sid: @signed_id) %></p>
6
6
 
7
7
  <p>If you did not request a password reset you can safely ignore this email, it expires in 20 minutes. Only someone with access to this email account can reset your password.</p>
8
8
 
@@ -2,7 +2,7 @@ Hey there,
2
2
 
3
3
  Can't remember your password for <%%= @user.email %>? That's OK, it happens. Just hit the link below to set a new one.
4
4
 
5
- [Reset my password]<%%= edit_identity_password_reset_url(token: @signed_id) %>
5
+ [Reset my password]<%%= edit_identity_password_reset_url(sid: @signed_id) %>
6
6
 
7
7
  If you did not request a password reset you can safely ignore this email, it expires in 20 minutes. Only someone with access to this email account can reset your password.
8
8
 
@@ -1,17 +1,17 @@
1
1
  class UserMailer < ApplicationMailer
2
- def password_reset_provision
2
+ def password_reset
3
3
  @user = params[:user]
4
- @signed_id = @user.signed_id(purpose: :password_reset, expires_in: 20.minutes)
4
+ @signed_id = @user.create_password_reset_token.signed_id(expires_in: 20.minutes)
5
5
 
6
6
  mail to: @user.email, subject: "Reset your password"
7
7
  end
8
8
 
9
- def email_verify_confirmation
9
+ def email_verification
10
10
  @user = params[:user]
11
11
  <%- if code_verifiable? -%>
12
12
  @user.verification_code.value = rand.to_s[2..7]
13
13
  <%- else -%>
14
- @signed_id = @user.signed_id(purpose: @user.email, expires_in: 2.days)
14
+ @signed_id = @user.create_email_verification_token.signed_id(expires_in: 2.days)
15
15
  <%- end -%>
16
16
 
17
17
  mail to: @user.email, subject: "Verify your email"
@@ -0,0 +1,7 @@
1
+ class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Migration.current_version %>]
2
+ def change
3
+ create_table :email_verification_tokens do |t|
4
+ t.references :user, null: false, foreign_key: true
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Migration.current_version %>]
2
+ def change
3
+ create_table :password_reset_tokens do |t|
4
+ t.references :user, null: false, foreign_key: true
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ class EmailVerificationToken < ApplicationRecord
2
+ belongs_to :user
3
+ end
@@ -0,0 +1,3 @@
1
+ class PasswordResetToken < ApplicationRecord
2
+ belongs_to :user
3
+ end
@@ -1,6 +1,9 @@
1
1
  class User < ApplicationRecord
2
2
  has_secure_password
3
3
 
4
+ has_one :email_verification_token, dependent: :destroy
5
+ has_one :password_reset_token, dependent: :destroy
6
+
4
7
  has_many :sessions, dependent: :destroy
5
8
  <%- if options.trackable? -%>
6
9
  has_many :events, dependent: :destroy
@@ -28,7 +31,7 @@ class User < ApplicationRecord
28
31
  end
29
32
 
30
33
  after_save_commit if: :email_previously_changed? do
31
- UserMailer.with(user: self).email_verify_confirmation.deliver_later
34
+ UserMailer.with(user: self).email_verification.deliver_later
32
35
  end
33
36
  <%- if options.trackable? %>
34
37
  after_save_commit if: :email_previously_changed? do
@@ -3,9 +3,6 @@ require "test_helper"
3
3
  class Identity::EmailVerificationsControllerTest < ActionDispatch::IntegrationTest
4
4
  setup do
5
5
  @user, @token = sign_in_as(users(:lazaro_nixon))
6
- @sid = @user.signed_id(purpose: @user.email, expires_in: 20.minutes)
7
- @sid_exp = @user.signed_id(purpose: @user.email, expires_in: 0.minutes)
8
-
9
6
  @user.update! verified: false
10
7
  end
11
8
 
@@ -14,7 +11,7 @@ class Identity::EmailVerificationsControllerTest < ActionDispatch::IntegrationTe
14
11
  end
15
12
 
16
13
  test "should send a verification email" do
17
- assert_enqueued_email_with UserMailer, :email_verify_confirmation, args: { user: @user } do
14
+ assert_enqueued_email_with UserMailer, :email_verification, args: { user: @user } do
18
15
  post identity_email_verification_url, headers: default_headers
19
16
  end
20
17
 
@@ -22,22 +19,16 @@ class Identity::EmailVerificationsControllerTest < ActionDispatch::IntegrationTe
22
19
  end
23
20
 
24
21
  test "should verify email" do
25
- get edit_identity_email_verification_url, params: { token: @sid, email: @user.email }, headers: default_headers
22
+ sid = @user.create_email_verification_token.signed_id(expires_in: 2.days)
23
+
24
+ get edit_identity_email_verification_url, params: { sid: sid }, headers: default_headers
26
25
  assert_response :no_content
27
26
  end
28
27
 
29
28
  test "should not verify email with expired token" do
30
- get edit_identity_email_verification_url, params: { token: @sid_exp, email: @user.email }, headers: default_headers
31
-
32
- assert_response :bad_request
33
- assert_equal "That email verification link is invalid", response.parsed_body["error"]
34
- end
35
-
36
- test "should not verify email with previous token" do
37
- @user.update! email: "other_email@hey.com"
38
-
39
- get edit_identity_email_verification_url, params: { token: @sid, email: @user.email_previously_was }, headers: default_headers
29
+ sid_exp = @user.create_email_verification_token.signed_id(expires_in: 0.minutes)
40
30
 
31
+ get edit_identity_email_verification_url, params: { sid: sid_exp }, headers: default_headers
41
32
  assert_response :bad_request
42
33
  assert_equal "That email verification link is invalid", response.parsed_body["error"]
43
34
  end
@@ -3,12 +3,10 @@ require "test_helper"
3
3
  class Identity::PasswordResetsControllerTest < ActionDispatch::IntegrationTest
4
4
  setup do
5
5
  @user = users(:lazaro_nixon)
6
- @sid = @user.signed_id(purpose: :password_reset, expires_in: 20.minutes)
7
- @sid_exp = @user.signed_id(purpose: :password_reset, expires_in: 0.minutes)
8
6
  end
9
7
 
10
8
  test "should send a password reset email" do
11
- assert_enqueued_email_with UserMailer, :password_reset_provision, args: { user: @user } do
9
+ assert_enqueued_email_with UserMailer, :password_reset, args: { user: @user } do
12
10
  post identity_password_reset_url, params: { email: @user.email }
13
11
  end
14
12
 
@@ -20,7 +18,7 @@ class Identity::PasswordResetsControllerTest < ActionDispatch::IntegrationTest
20
18
  post identity_password_reset_url, params: { email: "invalid_email@hey.com" }
21
19
  end
22
20
 
23
- assert_response :not_found
21
+ assert_response :bad_request
24
22
  assert_equal "You can't reset your password until you verify your email", response.parsed_body["error"]
25
23
  end
26
24
 
@@ -31,18 +29,21 @@ class Identity::PasswordResetsControllerTest < ActionDispatch::IntegrationTest
31
29
  post identity_password_reset_url, params: { email: @user.email }
32
30
  end
33
31
 
34
- assert_response :not_found
32
+ assert_response :bad_request
35
33
  assert_equal "You can't reset your password until you verify your email", response.parsed_body["error"]
36
34
  end
37
35
 
38
36
  test "should update password" do
39
- patch identity_password_reset_url, params: { token: @sid, password: "Secret6*4*2*", password_confirmation: "Secret6*4*2*" }
37
+ sid = @user.create_password_reset_token.signed_id(expires_in: 20.minutes)
38
+
39
+ patch identity_password_reset_url, params: { sid: sid, password: "Secret6*4*2*", password_confirmation: "Secret6*4*2*" }
40
40
  assert_response :success
41
41
  end
42
42
 
43
43
  test "should not update password with expired token" do
44
- patch identity_password_reset_url, params: { token: @sid_exp, password: "Secret6*4*2*", password_confirmation: "Secret6*4*2*" }
44
+ sid_exp = @user.create_password_reset_token.signed_id(expires_in: 0.minutes)
45
45
 
46
+ patch identity_password_reset_url, params: { sid: sid_exp, password: "Secret6*4*2*", password_confirmation: "Secret6*4*2*" }
46
47
  assert_response :bad_request
47
48
  assert_equal "That password reset link is invalid", response.parsed_body["error"]
48
49
  end
@@ -3,14 +3,11 @@ require "test_helper"
3
3
  class Identity::EmailVerificationsControllerTest < ActionDispatch::IntegrationTest
4
4
  setup do
5
5
  @user = sign_in_as(users(:lazaro_nixon))
6
- @sid = @user.signed_id(purpose: @user.email, expires_in: 20.minutes)
7
- @sid_exp = @user.signed_id(purpose: @user.email, expires_in: 0.minutes)
8
-
9
6
  @user.update! verified: false
10
7
  end
11
8
 
12
9
  test "should send a verification email" do
13
- assert_enqueued_email_with UserMailer, :email_verify_confirmation, args: { user: @user } do
10
+ assert_enqueued_email_with UserMailer, :email_verification, args: { user: @user } do
14
11
  post identity_email_verification_url
15
12
  end
16
13
 
@@ -18,21 +15,16 @@ class Identity::EmailVerificationsControllerTest < ActionDispatch::IntegrationTe
18
15
  end
19
16
 
20
17
  test "should verify email" do
21
- get edit_identity_email_verification_url(token: @sid, email: @user.email)
18
+ sid = @user.create_email_verification_token.signed_id(expires_in: 2.days)
19
+
20
+ get edit_identity_email_verification_url(sid: sid, email: @user.email)
22
21
  assert_redirected_to root_url
23
22
  end
24
23
 
25
24
  test "should not verify email with expired token" do
26
- get edit_identity_email_verification_url(token: @sid_exp, email: @user.email)
27
-
28
- assert_redirected_to edit_identity_email_url
29
- assert_equal "That email verification link is invalid", flash[:alert]
30
- end
31
-
32
- test "should not verify email with previous token" do
33
- @user.update! email: "other_email@hey.com"
25
+ sid_exp = @user.create_email_verification_token.signed_id(expires_in: 0.minutes)
34
26
 
35
- get edit_identity_email_verification_url(token: @sid, email: @user.email_previously_was)
27
+ get edit_identity_email_verification_url(sid: sid_exp, email: @user.email)
36
28
 
37
29
  assert_redirected_to edit_identity_email_url
38
30
  assert_equal "That email verification link is invalid", flash[:alert]
@@ -3,8 +3,6 @@ require "test_helper"
3
3
  class Identity::PasswordResetsControllerTest < ActionDispatch::IntegrationTest
4
4
  setup do
5
5
  @user = users(:lazaro_nixon)
6
- @sid = @user.signed_id(purpose: :password_reset, expires_in: 20.minutes)
7
- @sid_exp = @user.signed_id(purpose: :password_reset, expires_in: 0.minutes)
8
6
  end
9
7
 
10
8
  test "should get new" do
@@ -13,12 +11,14 @@ class Identity::PasswordResetsControllerTest < ActionDispatch::IntegrationTest
13
11
  end
14
12
 
15
13
  test "should get edit" do
16
- get edit_identity_password_reset_url(token: @sid)
14
+ sid = @user.create_password_reset_token.signed_id(expires_in: 20.minutes)
15
+
16
+ get edit_identity_password_reset_url(sid: sid)
17
17
  assert_response :success
18
18
  end
19
19
 
20
20
  test "should send a password reset email" do
21
- assert_enqueued_email_with UserMailer, :password_reset_provision, args: { user: @user } do
21
+ assert_enqueued_email_with UserMailer, :password_reset, args: { user: @user } do
22
22
  post identity_password_reset_url, params: { email: @user.email }
23
23
  end
24
24
 
@@ -46,13 +46,16 @@ class Identity::PasswordResetsControllerTest < ActionDispatch::IntegrationTest
46
46
  end
47
47
 
48
48
  test "should update password" do
49
- patch identity_password_reset_url, params: { token: @sid, password: "Secret6*4*2*", password_confirmation: "Secret6*4*2*" }
49
+ sid = @user.create_password_reset_token.signed_id(expires_in: 20.minutes)
50
+
51
+ patch identity_password_reset_url, params: { sid: sid, password: "Secret6*4*2*", password_confirmation: "Secret6*4*2*" }
50
52
  assert_redirected_to sign_in_url
51
53
  end
52
54
 
53
55
  test "should not update password with expired token" do
54
- patch identity_password_reset_url, params: { token: @sid_exp, password: "Secret6*4*2*", password_confirmation: "Secret6*4*2*" }
56
+ sid_exp = @user.create_password_reset_token.signed_id(expires_in: 0.minutes)
55
57
 
58
+ patch identity_password_reset_url, params: { sid: @sid_exp, password: "Secret6*4*2*", password_confirmation: "Secret6*4*2*" }
56
59
  assert_redirected_to new_identity_password_reset_url
57
60
  assert_equal "That password reset link is invalid", flash[:alert]
58
61
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: authentication-zero
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.12.4
4
+ version: 2.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nixon
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-04-16 00:00:00.000000000 Z
11
+ date: 2022-05-02 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email:
@@ -70,18 +70,21 @@ files:
70
70
  - lib/generators/authentication/templates/erb/sessions/sudos/new.html.erb.tt
71
71
  - lib/generators/authentication/templates/erb/two_factor_authentication/challenges/new.html.erb.tt
72
72
  - lib/generators/authentication/templates/erb/two_factor_authentication/totps/new.html.erb.tt
73
- - lib/generators/authentication/templates/erb/user_mailer/email_verify_confirmation.html.erb.tt
74
- - lib/generators/authentication/templates/erb/user_mailer/email_verify_confirmation.text.erb.tt
75
- - lib/generators/authentication/templates/erb/user_mailer/password_reset_provision.html.erb.tt
76
- - lib/generators/authentication/templates/erb/user_mailer/password_reset_provision.text.erb.tt
73
+ - lib/generators/authentication/templates/erb/user_mailer/email_verification.html.erb.tt
74
+ - lib/generators/authentication/templates/erb/user_mailer/email_verification.text.erb.tt
75
+ - lib/generators/authentication/templates/erb/user_mailer/password_reset.html.erb.tt
76
+ - lib/generators/authentication/templates/erb/user_mailer/password_reset.text.erb.tt
77
77
  - lib/generators/authentication/templates/mailers/session_mailer.rb.tt
78
78
  - lib/generators/authentication/templates/mailers/user_mailer.rb.tt
79
+ - lib/generators/authentication/templates/migrations/create_email_verification_tokens_migration.rb.tt
79
80
  - lib/generators/authentication/templates/migrations/create_events_migration.rb.tt
81
+ - lib/generators/authentication/templates/migrations/create_password_reset_tokens_migration.rb.tt
80
82
  - lib/generators/authentication/templates/migrations/create_sessions_migration.rb.tt
81
83
  - lib/generators/authentication/templates/migrations/create_users_migration.rb.tt
82
84
  - lib/generators/authentication/templates/models/current.rb.tt
85
+ - lib/generators/authentication/templates/models/email_verification_token.rb.tt
83
86
  - lib/generators/authentication/templates/models/event.rb.tt
84
- - lib/generators/authentication/templates/models/locking.rb.tt
87
+ - lib/generators/authentication/templates/models/password_reset_token.rb.tt
85
88
  - lib/generators/authentication/templates/models/session.rb.tt
86
89
  - lib/generators/authentication/templates/models/user.rb.tt
87
90
  - lib/generators/authentication/templates/test_unit/application_system_test_case.rb.tt
@@ -1,10 +0,0 @@
1
- class Locking
2
- def self.lock_on(key, wait:, attempts:, &block)
3
- counter = Kredis.counter(key, expires_in: wait)
4
- counter.increment
5
-
6
- if counter.value > attempts
7
- yield
8
- end
9
- end
10
- end