authentication-zero 2.12.5 → 2.14.0

Sign up to get free protection for your applications and to get access to all the features.
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 +10 -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 +6 -13
  9. data/lib/generators/authentication/templates/controllers/html/application_controller.rb.tt +10 -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 +5 -12
  12. data/lib/generators/authentication/templates/erb/user_mailer/{email_confirmation.html.erb.tt → email_verification.html.erb.tt} +1 -1
  13. data/lib/generators/authentication/templates/erb/user_mailer/{email_confirmation.text.erb.tt → email_verification.text.erb.tt} +1 -1
  14. data/lib/generators/authentication/templates/erb/user_mailer/password_reset.html.erb.tt +1 -1
  15. data/lib/generators/authentication/templates/erb/user_mailer/password_reset.text.erb.tt +1 -1
  16. data/lib/generators/authentication/templates/mailers/user_mailer.rb.tt +3 -3
  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 +7 -6
  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 +8 -5
  26. metadata +8 -5
  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: 56295ed54d4a467ec1245634e3ab828d5128c601805bdaff0f232f9cd69ed08e
4
- data.tar.gz: c8789b35631e6f4be5c6ba3f666eaa997f5dcdca2c23ba23fe013b0f55d36e2c
3
+ metadata.gz: 6a0e9d758b6d4e0b0c40fbda4a80145e842d11a5cf0b4ec06491bcef39eeae7d
4
+ data.tar.gz: 5701d90d2ca54430f67984367d2e0fd26e2fbe137a4d2d1e3261173c62072724
5
5
  SHA512:
6
- metadata.gz: 31e6c3963edabe40e298b758d4295ab03f13960aa5dae81089f4f2c3769589c45b56b2a4cd2c7faad373b681b03c5f52a90bb4a55696d64c203c6ae60b860ca0
7
- data.tar.gz: 6cebd96d1801c3d53de594d16d8b9864683acd1b4a176cf6c7bcf6f706e57a8a8865c845ae9faa793070ebff733436bd48bca65f52d21e4dcce660861960fe63
6
+ metadata.gz: 4fcdd24221c895d34988aa6be949a9dd5ba7be283df6e48acb0431bad502c6dd8212617e766d7f547c90135ea19f4956d97369621efb5409c6907afe3d7ab65c
7
+ data.tar.gz: 93308abcdfa186d607fec5b920bae4e87c1a1f92638b74d012a7d6e3e7914339efb9c8bdb9e41e7ac36531ef082535a3933d5b7a0ebcd02ae0c56f28cb926d18
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.5)
4
+ authentication-zero (2.14.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -1,3 +1,3 @@
1
1
  module AuthenticationZero
2
- VERSION = "2.12.5"
2
+ VERSION = "2.14.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,16 @@ class ApplicationController < ActionController::API
10
10
  end
11
11
  end
12
12
  <%- end -%>
13
+ <%- if options.lockable? %>
14
+ def require_lock(wait: 1.hour, attempts: 10)
15
+ counter = Kredis.counter("require_lock:#{request.remote_ip}:#{params[:controller]}:#{params[:action]}", expires_in: wait)
16
+ counter.increment
17
+
18
+ if counter.value > attempts
19
+ render json: { error: "You've exceeded the maximum number of attempts" }, status: :too_many_requests
20
+ end
21
+ end
22
+ <%- end -%>
13
23
 
14
24
  private
15
25
  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_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: "verify_#{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,22 @@
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
+ before_action :require_lock, only: :create
7
+ <%- end -%>
8
8
 
9
9
  def create
10
10
  if @user = User.find_by(email: params[:email], verified: true)
11
11
  UserMailer.with(user: @user).password_reset.deliver_later
12
12
  else
13
- render json: { error: "You can't reset your password until you verify your email" }, status: :not_found
13
+ render json: { error: "You can't reset your password until you verify your email" }, status: :bad_request
14
14
  end
15
15
  end
16
16
 
17
17
  def update
18
18
  if @user.update(user_params)
19
- render json: @user
19
+ @token.destroy; render json: @user
20
20
  else
21
21
  render json: @user.errors, status: :unprocessable_entity
22
22
  end
@@ -24,7 +24,7 @@ class Identity::PasswordResetsController < ApplicationController
24
24
 
25
25
  private
26
26
  def set_user
27
- @user = User.find_signed!(params[:token], purpose: :password_reset)
27
+ @token = PasswordResetToken.find_signed!(params[:sid]); @user = @token.user
28
28
  rescue
29
29
  render json: { error: "That password reset link is invalid" }, status: :bad_request
30
30
  end
@@ -32,11 +32,4 @@ class Identity::PasswordResetsController < ApplicationController
32
32
  def user_params
33
33
  params.permit(:password, :password_confirmation)
34
34
  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
35
  end
@@ -8,6 +8,16 @@ class ApplicationController < ActionController::Base
8
8
  end
9
9
  end
10
10
  <%- end -%>
11
+ <%- if options.lockable? %>
12
+ def require_lock(wait: 1.hour, attempts: 10)
13
+ counter = Kredis.counter("require_lock:#{request.remote_ip}:#{params[:controller]}:#{params[:action]}", expires_in: wait)
14
+ counter.increment
15
+
16
+ if counter.value > attempts
17
+ redirect_to new_identity_password_reset_path, alert: "You've exceeded the maximum number of attempts"
18
+ end
19
+ end
20
+ <%- end -%>
11
21
 
12
22
  private
13
23
  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_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: "verify_#{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,10 @@
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
+ before_action :require_lock, only: :create
7
+ <%- end -%>
8
8
 
9
9
  def new
10
10
  end
@@ -23,7 +23,7 @@ class Identity::PasswordResetsController < ApplicationController
23
23
 
24
24
  def update
25
25
  if @user.update(user_params)
26
- redirect_to sign_in_path, notice: "Your password was reset successfully. Please sign in"
26
+ @token.destroy; redirect_to sign_in_path, notice: "Your password was reset successfully. Please sign in"
27
27
  else
28
28
  render :edit, status: :unprocessable_entity
29
29
  end
@@ -31,7 +31,7 @@ class Identity::PasswordResetsController < ApplicationController
31
31
 
32
32
  private
33
33
  def set_user
34
- @user = User.find_signed!(params[:token], purpose: :password_reset)
34
+ @token = PasswordResetToken.find_signed!(params[:sid]); @user = @token.user
35
35
  rescue
36
36
  redirect_to new_identity_password_reset_path, alert: "That password reset link is invalid"
37
37
  end
@@ -39,11 +39,4 @@ class Identity::PasswordResetsController < ApplicationController
39
39
  def user_params
40
40
  params.permit(:password, :password_confirmation)
41
41
  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
42
  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
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_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: "verify_#{@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_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: "verify_#{@user.email}", expires_in: 20.minutes)
7
- @sid_exp = @user.signed_id(purpose: "verify_#{@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_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,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 send a password reset email" do
@@ -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: "verify_#{@user.email}", expires_in: 20.minutes)
7
- @sid_exp = @user.signed_id(purpose: "verify_#{@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_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,7 +11,9 @@ 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
 
@@ -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.5
4
+ version: 2.14.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-23 00:00:00.000000000 Z
11
+ date: 2022-05-03 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_confirmation.html.erb.tt
74
- - lib/generators/authentication/templates/erb/user_mailer/email_confirmation.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
75
  - lib/generators/authentication/templates/erb/user_mailer/password_reset.html.erb.tt
76
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