authentication-zero 2.16.3 → 2.16.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (21) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +26 -0
  3. data/Gemfile.lock +1 -1
  4. data/README.md +24 -19
  5. data/lib/authentication_zero/version.rb +1 -1
  6. data/lib/generators/authentication/authentication_generator.rb +11 -2
  7. data/lib/generators/authentication/templates/controllers/api/identity/password_resets_controller.rb.tt +6 -2
  8. data/lib/generators/authentication/templates/controllers/api/sessions/passwordlesses_controller.rb.tt +34 -0
  9. data/lib/generators/authentication/templates/controllers/api/sessions_controller.rb.tt +1 -1
  10. data/lib/generators/authentication/templates/controllers/html/identity/email_verifications_controller.rb.tt +5 -1
  11. data/lib/generators/authentication/templates/controllers/html/identity/password_resets_controller.rb.tt +11 -3
  12. data/lib/generators/authentication/templates/controllers/html/sessions/passwordlesses_controller.rb.tt +42 -0
  13. data/lib/generators/authentication/templates/controllers/html/sessions_controller.rb.tt +1 -2
  14. data/lib/generators/authentication/templates/erb/sessions/new.html.erb.tt +8 -0
  15. data/lib/generators/authentication/templates/erb/sessions/passwordlesses/new.html.erb.tt +14 -0
  16. data/lib/generators/authentication/templates/erb/user_mailer/passwordless.html.erb.tt +9 -0
  17. data/lib/generators/authentication/templates/mailers/user_mailer.rb.tt +8 -0
  18. data/lib/generators/authentication/templates/migrations/create_sign_in_tokens_migration.rb.tt +7 -0
  19. data/lib/generators/authentication/templates/models/sign_in_token.rb.tt +3 -0
  20. data/lib/generators/authentication/templates/models/user.rb.tt +6 -3
  21. metadata +8 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4a9f5862b8b603990471ab970d13cf934f73252c55a734a39a90198406066a75
4
- data.tar.gz: d6bf9bda2ef8d19df6da9207e40e5621eb1157b2073921ff5dbee6ce00ff22a2
3
+ metadata.gz: 02c890d34404e8613c543d9597e31f5a3cd3b7c14ea066f2096d1fbcb57ef372
4
+ data.tar.gz: 93cb08256ae2817af9ebf3a5f4a4391c6012ee27854a8437a2cba47166521b7c
5
5
  SHA512:
6
- metadata.gz: 8ccdcba2c6dd5edf45b60acd1462ef02eb46bf4e4f9a9a0a7860a2e840ff18f58a1d655b2f9e7f3c45cc497aac04fc269ae86186df6cbdbfb70f46e51bc49db0
7
- data.tar.gz: e70d3a8012378093f060dc5084089ed77c87d6cc271db810b624c588324797e7c1748bd1bc345a5d5dce2ff0f3e6cabab7ba1f20e3abc8d3e7e590c43a799844
6
+ metadata.gz: 5af869dca3d8bc1b6ff2321687e6e241adb4f278910697b588421722f0cb92346fcb214042ccb7fe1acf510fc66bc35d473edc4d7152054bdcd3f9d52f1def8f
7
+ data.tar.gz: 360a9e95c2794105966c7b76720a4ac123bcb7558389e27fa3aa87e8b71d995e5fd33e2ee066551f48c82b8c0c9734b9eae1b6a72bafc14486f645e07694544d
data/CHANGELOG.md CHANGED
@@ -1,3 +1,29 @@
1
+ ## Authentication Zero 2.16.5 ##
2
+
3
+ * Revoke all password reset tokens (security enhancement)
4
+ * Sign in without password (new feature)
5
+
6
+ ## Authentication Zero 2.16.4 (February 11, 2023) ##
7
+
8
+ * Increase attemps for lockable sign-in
9
+
10
+ ## Authentication Zero 2.16.3 (December 30, 2022) ##
11
+
12
+ * Require lock for sign in when lockable
13
+
14
+ ## Authentication Zero 2.16.2 (December 21, 2022) ##
15
+
16
+ * Remove api documentation and reference for api docs from README
17
+ * Remove bundle install instruction
18
+ * Dont require sudo for omniauth users
19
+ * Add gems instead of uncomment gemfile lines
20
+ * Fix home view
21
+
22
+ ## Authentication Zero 2.16.1 (December 20, 2022) ##
23
+
24
+ * Safe navigation for email normalization
25
+ * Fix omniauth not verifying user
26
+
1
27
  ## Authentication Zero 2.16.0 (May 2, 2022) ##
2
28
 
3
29
  * Generate home controller
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- authentication-zero (2.16.3)
4
+ authentication-zero (2.16.5)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -2,6 +2,22 @@
2
2
 
3
3
  The purpose of authentication zero is to generate a pre-built authentication system into a rails application (web or api-only) that follows both security and rails best practices. By generating code into the user's application instead of using a library, the user has complete freedom to modify the authentication system so it works best with their app.
4
4
 
5
+ ## Installation
6
+
7
+ ```
8
+ $ bundle add authentication-zero
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```
14
+ $ rails generate authentication
15
+ ```
16
+
17
+ ## Developer responsibilities
18
+
19
+ Since Authentication Zero generates this code into your application instead of building these modules into the gem itself, you now have complete freedom to modify the authentication system, so it works best with your use case. The one caveat with using a generated authentication system is it will not be updated after it's been generated. Therefore, as improvements are made to the output of `rails generate authentication`, it becomes your responsibility to determine if these changes need to be ported into your application. Security-related and other important improvements will be explicitly and clearly marked in the `CHANGELOG.md` file and upgrade notes.
20
+
5
21
  ## Features
6
22
 
7
23
  - **Simplest code ever (~200 lines of code)**
@@ -11,6 +27,7 @@ The purpose of authentication zero is to generate a pre-built authentication sys
11
27
  - Checks if a password has been found in any data breach (--pwned)
12
28
  - Authentication by cookie
13
29
  - Authentication by token (--api)
30
+ - Passwordless authentication (--passwordless)
14
31
  - Two factor authentication (--two-factor)
15
32
  - Social Login with OmniAuth (--omniauthable)
16
33
  - Verify email using a link with token
@@ -25,29 +42,17 @@ The purpose of authentication zero is to generate a pre-built authentication sys
25
42
  - Activity log (--trackable)
26
43
  - Log out
27
44
 
28
- ## Security and best practices
45
+ ## Generated code
29
46
 
30
- - [has_secure_password](https://api.rubyonrails.org/classes/ActiveModel/SecurePassword/ClassMethods.html#method-i-has_secure_password): Adds methods to set and authenticate against a BCrypt password.
47
+ - [has_secure_password](https://api.rubyonrails.org/classes/ActiveModel/SecurePassword/ClassMethods.html#method-i-has_secure_password): Adds methods to set and authenticate against a bcrypt password.
31
48
  - [signed cookies](https://api.rubyonrails.org/classes/ActionDispatch/Cookies.html): Returns a jar that'll automatically generate a signed representation of cookie value and verify it when reading from the cookie again.
32
49
  - [httponly cookies](https://api.rubyonrails.org/classes/ActionDispatch/Cookies.html): A cookie with the httponly attribute is inaccessible to the JavaScript, this precaution helps mitigate cross-site scripting (XSS) attacks.
33
50
  - [signed_id](https://api.rubyonrails.org/classes/ActiveRecord/SignedId.html): Returns a signed id that is tamper proof, so it's safe to send in an email or otherwise share with the outside world.
34
- - [Current attributes](https://api.rubyonrails.org/classes/ActiveSupport/CurrentAttributes.html): Abstract super class that provides a thread-isolated attributes singleton, which resets automatically before and after each request.
35
- - [Action mailer](https://api.rubyonrails.org/classes/ActionMailer/Base.html): Action Mailer allows you to send email from your application using a mailer model and views.
36
- - [Log filtering](https://guides.rubyonrails.org/action_controller_overview.html#log-filtering): Parameters 'token' and 'password' are marked [FILTERED] in the log.
37
- - [Functional Tests](https://guides.rubyonrails.org/testing.html#functional-tests-for-your-controllers): In Rails, testing the various actions of a controller is a form of writing functional tests.
38
- - [System Testing](https://guides.rubyonrails.org/testing.html#system-testing): System tests allow you to test user interactions with your application, running tests in either a real or a headless browser.
39
-
40
- ## Installation
41
-
42
- ```
43
- $ bundle add authentication-zero
44
- ```
45
-
46
- ## Usage
47
-
48
- ```
49
- $ rails generate authentication
50
- ```
51
+ - [current attributes](https://api.rubyonrails.org/classes/ActiveSupport/CurrentAttributes.html): Abstract super class that provides a thread-isolated attributes singleton, which resets automatically before and after each request.
52
+ - [action mailer](https://api.rubyonrails.org/classes/ActionMailer/Base.html): Action Mailer allows you to send email from your application using a mailer model and views.
53
+ - [log filtering](https://guides.rubyonrails.org/action_controller_overview.html#log-filtering): Parameters 'token' and 'password' are marked [FILTERED] in the log.
54
+ - [functional tests](https://guides.rubyonrails.org/testing.html#functional-tests-for-your-controllers): In Rails, testing the various actions of a controller is a form of writing functional tests.
55
+ - [system testing](https://guides.rubyonrails.org/testing.html#system-testing): System tests allow you to test user interactions with your application, running tests in either a real or a headless browser.
51
56
 
52
57
  ## Development
53
58
 
@@ -1,3 +1,3 @@
1
1
  module AuthenticationZero
2
- VERSION = "2.16.3"
2
+ VERSION = "2.16.5"
3
3
  end
@@ -8,6 +8,7 @@ class AuthenticationGenerator < Rails::Generators::Base
8
8
  class_option :code_verifiable, type: :boolean, desc: "Add email verification using a code for api"
9
9
  class_option :sudoable, type: :boolean, desc: "Add password request before sensitive data changes"
10
10
  class_option :lockable, type: :boolean, desc: "Add password reset locking"
11
+ class_option :passwordless, type: :boolean, desc: "Add passwordless sign"
11
12
  class_option :omniauthable, type: :boolean, desc: "Add social login support"
12
13
  class_option :trackable, type: :boolean, desc: "Add activity log support"
13
14
  class_option :two_factor, type: :boolean, desc: "Add two factor authentication"
@@ -52,6 +53,7 @@ class AuthenticationGenerator < Rails::Generators::Base
52
53
  migration_template "migrations/create_sessions_migration.rb", "#{db_migrate_path}/create_sessions.rb"
53
54
  migration_template "migrations/create_email_verification_tokens_migration.rb", "#{db_migrate_path}/create_email_verification_tokens.rb"
54
55
  migration_template "migrations/create_password_reset_tokens_migration.rb", "#{db_migrate_path}/create_password_reset_tokens.rb"
56
+ migration_template "migrations/create_sign_in_tokens_migration.rb", "#{db_migrate_path}/create_sign_in_tokens_migration.rb" if options.passwordless?
55
57
  migration_template "migrations/create_events_migration.rb", "#{db_migrate_path}/create_events.rb" if options.trackable?
56
58
  end
57
59
 
@@ -60,6 +62,7 @@ class AuthenticationGenerator < Rails::Generators::Base
60
62
  template "models/session.rb", "app/models/session.rb"
61
63
  template "models/email_verification_token.rb", "app/models/email_verification_token.rb"
62
64
  template "models/password_reset_token.rb", "app/models/password_reset_token.rb"
65
+ template "models/sign_in_token.rb", "app/models/sign_in_token.rb" if options.passwordless?
63
66
  template "models/current.rb", "app/models/current.rb"
64
67
  template "models/event.rb", "app/models/event.rb" if options.trackable?
65
68
  end
@@ -79,6 +82,7 @@ class AuthenticationGenerator < Rails::Generators::Base
79
82
  template "controllers/#{format_folder}/home_controller.rb", "app/controllers/home_controller.rb" unless options.api?
80
83
  template "controllers/#{format_folder}/sessions/sudos_controller.rb", "app/controllers/sessions/sudos_controller.rb" if options.sudoable?
81
84
  template "controllers/#{format_folder}/sessions/omniauth_controller.rb", "app/controllers/sessions/omniauth_controller.rb" if omniauthable?
85
+ template "controllers/#{format_folder}/sessions/passwordlesses_controller.rb", "app/controllers/sessions/passwordlesses_controller.rb" if options.passwordless?
82
86
  template "controllers/#{format_folder}/authentications/events_controller.rb", "app/controllers/authentications/events_controller.rb" if options.trackable?
83
87
  end
84
88
 
@@ -96,10 +100,11 @@ class AuthenticationGenerator < Rails::Generators::Base
96
100
  directory "erb/passwords", "app/views/passwords"
97
101
  directory "erb/registrations", "app/views/registrations"
98
102
 
99
- template "erb/sessions/index.html.erb", "app/views/sessions/index.html.erb"
100
- template "erb/sessions/new.html.erb", "app/views/sessions/new.html.erb"
103
+ template "erb/sessions/index.html.erb", "app/views/sessions/index.html.erb"
104
+ template "erb/sessions/new.html.erb", "app/views/sessions/new.html.erb"
101
105
 
102
106
  directory "erb/sessions/sudos", "app/views/sessions/sudos" if options.sudoable?
107
+ directory "erb/sessions/passwordlesses", "app/views/sessions/passwordlesses" if options.passwordless?
103
108
 
104
109
  directory "erb/two_factor_authentication", "app/views/two_factor_authentication" if two_factor?
105
110
  directory "erb/authentications/events", "app/views/authentications/events" if options.trackable?
@@ -113,6 +118,10 @@ class AuthenticationGenerator < Rails::Generators::Base
113
118
  def add_routes
114
119
  route "root 'home#index'" unless options.api?
115
120
 
121
+ if options.passwordless?
122
+ route "resource :passwordless, only: [:new, :edit, :create]", namespace: :sessions
123
+ end
124
+
116
125
  if omniauthable?
117
126
  route "post '/auth/:provider/callback', to: 'sessions/omniauth#create'"
118
127
  route "get '/auth/:provider/callback', to: 'sessions/omniauth#create'"
@@ -1,10 +1,10 @@
1
1
  class Identity::PasswordResetsController < ApplicationController
2
2
  skip_before_action :authenticate
3
3
 
4
- before_action :set_user, only: :update
5
4
  <%- if options.lockable? -%>
6
5
  before_action :require_lock, only: :create
7
6
  <%- end -%>
7
+ before_action :set_user, only: :update
8
8
 
9
9
  def create
10
10
  if @user = User.find_by(email: params[:email], verified: true)
@@ -16,7 +16,7 @@ class Identity::PasswordResetsController < ApplicationController
16
16
 
17
17
  def update
18
18
  if @user.update(user_params)
19
- @token.destroy; render json: @user
19
+ revoke_tokens; render(json: @user)
20
20
  else
21
21
  render json: @user.errors, status: :unprocessable_entity
22
22
  end
@@ -32,4 +32,8 @@ class Identity::PasswordResetsController < ApplicationController
32
32
  def user_params
33
33
  params.permit(:password, :password_confirmation)
34
34
  end
35
+
36
+ def revoke_tokens
37
+ @user.password_reset_tokens.delete_all
38
+ end
35
39
  end
@@ -0,0 +1,34 @@
1
+ class Sessions::PasswordlessesController < ApplicationController
2
+ skip_before_action :authenticate
3
+
4
+ <%- if options.lockable? -%>
5
+ before_action :require_lock, only: :create
6
+ <%- end -%>
7
+ before_action :set_user, only: :edit
8
+
9
+ def edit
10
+ @session = @user.sessions.create!
11
+ response.set_header "X-Session-Token", @session.signed_id
12
+
13
+ revoke_tokens; render(json: @session, status: :created)
14
+ end
15
+
16
+ def create
17
+ if @user = User.find_by(email: params[:email], verified: true)
18
+ UserMailer.with(user: @user).passwordless.deliver_later
19
+ else
20
+ render json: { error: "You can't sign in until you verify your email" }, status: :bad_request
21
+ end
22
+ end
23
+
24
+ private
25
+ def set_user
26
+ @token = SignInToken.find_signed!(params[:sid]); @user = @token.user
27
+ rescue
28
+ render json: { error: "That sign in link is invalid" }, status: :bad_request
29
+ end
30
+
31
+ def revoke_tokens
32
+ @user.sign_in_tokens.delete_all
33
+ end
34
+ end
@@ -2,7 +2,7 @@ class SessionsController < ApplicationController
2
2
  skip_before_action :authenticate, only: :create
3
3
 
4
4
  <%- if options.lockable? -%>
5
- before_action :require_lock, only: :create
5
+ before_action :require_lock, attempts: 20, only: :create
6
6
  <%- end -%>
7
7
  before_action :set_session, only: %i[ show destroy ]
8
8
 
@@ -9,7 +9,7 @@ class Identity::EmailVerificationsController < ApplicationController
9
9
  end
10
10
 
11
11
  def create
12
- UserMailer.with(user: Current.user).email_verification.deliver_later
12
+ send_email_verification
13
13
  redirect_to root_path, notice: "We sent a verification email to your email address"
14
14
  end
15
15
 
@@ -19,4 +19,8 @@ class Identity::EmailVerificationsController < ApplicationController
19
19
  rescue
20
20
  redirect_to edit_identity_email_path, alert: "That email verification link is invalid"
21
21
  end
22
+
23
+ def send_email_verification
24
+ UserMailer.with(user: Current.user).email_verification.deliver_later
25
+ end
22
26
  end
@@ -1,10 +1,10 @@
1
1
  class Identity::PasswordResetsController < ApplicationController
2
2
  skip_before_action :authenticate
3
3
 
4
- before_action :set_user, only: %i[ edit update ]
5
4
  <%- if options.lockable? -%>
6
5
  before_action :require_lock, only: :create
7
6
  <%- end -%>
7
+ before_action :set_user, only: %i[ edit update ]
8
8
 
9
9
  def new
10
10
  end
@@ -14,7 +14,7 @@ class Identity::PasswordResetsController < ApplicationController
14
14
 
15
15
  def create
16
16
  if @user = User.find_by(email: params[:email], verified: true)
17
- UserMailer.with(user: @user).password_reset.deliver_later
17
+ send_password_reset_email
18
18
  redirect_to sign_in_path, notice: "Check your email for reset instructions"
19
19
  else
20
20
  redirect_to new_identity_password_reset_path, alert: "You can't reset your password until you verify your email"
@@ -23,7 +23,7 @@ class Identity::PasswordResetsController < ApplicationController
23
23
 
24
24
  def update
25
25
  if @user.update(user_params)
26
- @token.destroy; redirect_to(sign_in_path, notice: "Your password was reset successfully. Please sign in")
26
+ revoke_tokens; 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
@@ -39,4 +39,12 @@ class Identity::PasswordResetsController < ApplicationController
39
39
  def user_params
40
40
  params.permit(:password, :password_confirmation)
41
41
  end
42
+
43
+ def send_password_reset_email
44
+ UserMailer.with(user: @user).password_reset.deliver_later
45
+ end
46
+
47
+ def revoke_tokens
48
+ @user.password_reset_tokens.delete_all
49
+ end
42
50
  end
@@ -0,0 +1,42 @@
1
+ class Sessions::PasswordlessesController < ApplicationController
2
+ skip_before_action :authenticate
3
+
4
+ <%- if options.lockable? -%>
5
+ before_action :require_lock, only: :create
6
+ <%- end -%>
7
+ before_action :set_user, only: :edit
8
+
9
+ def new
10
+ end
11
+
12
+ def edit
13
+ @session = @user.sessions.create!
14
+ cookies.signed.permanent[:session_token] = { value: @session.id, httponly: true }
15
+
16
+ revoke_tokens; redirect_to(root_path, notice: "Signed in successfully")
17
+ end
18
+
19
+ def create
20
+ if @user = User.find_by(email: params[:email], verified: true)
21
+ send_passwordless_email
22
+ redirect_to sign_in_path, notice: "Check your email for sign in instructions"
23
+ else
24
+ redirect_to new_sessions_passwordless_path, alert: "You can't sign in until you verify your email"
25
+ end
26
+ end
27
+
28
+ private
29
+ def set_user
30
+ @token = SignInToken.find_signed!(params[:sid]); @user = @token.user
31
+ rescue
32
+ redirect_to new_sessions_passwordless_path, alert: "That sign in link is invalid"
33
+ end
34
+
35
+ def send_passwordless_email
36
+ UserMailer.with(user: @user).passwordless.deliver_later
37
+ end
38
+
39
+ def revoke_tokens
40
+ @user.sign_in_tokens.delete_all
41
+ end
42
+ end
@@ -2,7 +2,7 @@ class SessionsController < ApplicationController
2
2
  skip_before_action :authenticate, only: %i[ new create ]
3
3
 
4
4
  <%- if options.lockable? -%>
5
- before_action :require_lock, only: :create
5
+ before_action :require_lock, attempts: 20, only: :create
6
6
  <%- end -%>
7
7
  before_action :set_session, only: :destroy
8
8
 
@@ -21,7 +21,6 @@ class SessionsController < ApplicationController
21
21
  <%- if two_factor? -%>
22
22
  if user.otp_secret
23
23
  signed_id = user.signed_id(purpose: :authentication_challenge, expires_in: 20.minutes)
24
-
25
24
  redirect_to new_two_factor_authentication_challenge_path(token: signed_id)
26
25
  else
27
26
  @session = user.sessions.create!
@@ -18,6 +18,14 @@
18
18
  <%%= form.submit "Sign in" %>
19
19
  </div>
20
20
  <%% end %>
21
+
22
+ <br>
23
+
24
+ <%- if options.passwordless? %>
25
+ <div>
26
+ <%%= link_to "Sign in without password", new_sessions_passwordless_path %>
27
+ </div>
28
+ <%- end -%>
21
29
  <%- if omniauthable? %>
22
30
  <div>
23
31
  <%%= button_to "Sign in with OmniAuth", "/auth/developer", "data-turbo" => false %>
@@ -0,0 +1,14 @@
1
+ <p style="color: red"><%%= alert %></p>
2
+
3
+ <h1>Sign in without password</h1>
4
+
5
+ <%%= form_with(url: sessions_passwordless_path) do |form| %>
6
+ <div>
7
+ <%%= form.label :email, style: "display: block" %>
8
+ <%%= form.email_field :email, autofocus: true, required: true %>
9
+ </div>
10
+
11
+ <div>
12
+ <%%= form.submit "Sign in" %>
13
+ </div>
14
+ <%% end %>
@@ -0,0 +1,9 @@
1
+ <p>Hey there,</p>
2
+
3
+ <p>You requested a magic sign-in link. Here you go:</p>
4
+
5
+ <%%= link_to "Sign in without password", edit_sessions_passwordless_url(sid: @signed_id) %>
6
+
7
+ <hr>
8
+
9
+ <p>Have questions or need help? Just reply to this email and our support team will help you sort it out.</p>
@@ -16,4 +16,12 @@ class UserMailer < ApplicationMailer
16
16
 
17
17
  mail to: @user.email, subject: "Verify your email"
18
18
  end
19
+ <%- if options.passwordless? %>
20
+ def passwordless
21
+ @user = params[:user]
22
+ @signed_id = @user.sign_in_tokens.create.signed_id(expires_in: 1.day)
23
+
24
+ mail to: @user.email, subject: "Your sign in link"
25
+ end
26
+ <%- end -%>
19
27
  end
@@ -0,0 +1,7 @@
1
+ class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Migration.current_version %>]
2
+ def change
3
+ create_table :sign_in_tokens do |t|
4
+ t.references :user, null: false, foreign_key: true
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ class SignInToken < ApplicationRecord
2
+ belongs_to :user
3
+ end
@@ -3,6 +3,9 @@ class User < ApplicationRecord
3
3
 
4
4
  has_many :email_verification_tokens, dependent: :destroy
5
5
  has_many :password_reset_tokens, dependent: :destroy
6
+ <%- if options.passwordless? -%>
7
+ has_many :sign_in_tokens, dependent: :destroy
8
+ <%- end -%>
6
9
 
7
10
  has_many :sessions, dependent: :destroy
8
11
  <%- if options.trackable? -%>
@@ -22,7 +25,7 @@ class User < ApplicationRecord
22
25
  self.email = email.downcase.strip
23
26
  end
24
27
 
25
- before_validation if: :email_changed?, unless: :new_record? do
28
+ before_validation if: :email_changed?, on: :update do
26
29
  self.verified = false
27
30
  end
28
31
 
@@ -38,8 +41,8 @@ class User < ApplicationRecord
38
41
  events.create! action: "password_changed"
39
42
  end
40
43
 
41
- after_update if: :verified_previously_changed? do
42
- events.create! action: "email_verified" if verified?
44
+ after_update if: [:verified_previously_changed?, :verified?] do
45
+ events.create! action: "email_verified"
43
46
  end
44
47
  <%- end -%>
45
48
  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.16.3
4
+ version: 2.16.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nixon
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-01-05 00:00:00.000000000 Z
11
+ date: 2023-02-13 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email:
@@ -44,6 +44,7 @@ files:
44
44
  - lib/generators/authentication/templates/controllers/api/identity/password_resets_controller.rb.tt
45
45
  - lib/generators/authentication/templates/controllers/api/passwords_controller.rb.tt
46
46
  - lib/generators/authentication/templates/controllers/api/registrations_controller.rb.tt
47
+ - lib/generators/authentication/templates/controllers/api/sessions/passwordlesses_controller.rb.tt
47
48
  - lib/generators/authentication/templates/controllers/api/sessions/sudos_controller.rb.tt
48
49
  - lib/generators/authentication/templates/controllers/api/sessions_controller.rb.tt
49
50
  - lib/generators/authentication/templates/controllers/html/application_controller.rb.tt
@@ -55,6 +56,7 @@ files:
55
56
  - lib/generators/authentication/templates/controllers/html/passwords_controller.rb.tt
56
57
  - lib/generators/authentication/templates/controllers/html/registrations_controller.rb.tt
57
58
  - lib/generators/authentication/templates/controllers/html/sessions/omniauth_controller.rb.tt
59
+ - lib/generators/authentication/templates/controllers/html/sessions/passwordlesses_controller.rb.tt
58
60
  - lib/generators/authentication/templates/controllers/html/sessions/sudos_controller.rb.tt
59
61
  - lib/generators/authentication/templates/controllers/html/sessions_controller.rb.tt
60
62
  - lib/generators/authentication/templates/controllers/html/two_factor_authentication/challenges_controller.rb.tt
@@ -69,23 +71,27 @@ files:
69
71
  - lib/generators/authentication/templates/erb/session_mailer/signed_in_notification.html.erb.tt
70
72
  - lib/generators/authentication/templates/erb/sessions/index.html.erb.tt
71
73
  - lib/generators/authentication/templates/erb/sessions/new.html.erb.tt
74
+ - lib/generators/authentication/templates/erb/sessions/passwordlesses/new.html.erb.tt
72
75
  - lib/generators/authentication/templates/erb/sessions/sudos/new.html.erb.tt
73
76
  - lib/generators/authentication/templates/erb/two_factor_authentication/challenges/new.html.erb.tt
74
77
  - lib/generators/authentication/templates/erb/two_factor_authentication/totps/new.html.erb.tt
75
78
  - lib/generators/authentication/templates/erb/user_mailer/email_verification.html.erb.tt
76
79
  - lib/generators/authentication/templates/erb/user_mailer/password_reset.html.erb.tt
80
+ - lib/generators/authentication/templates/erb/user_mailer/passwordless.html.erb.tt
77
81
  - lib/generators/authentication/templates/mailers/session_mailer.rb.tt
78
82
  - lib/generators/authentication/templates/mailers/user_mailer.rb.tt
79
83
  - lib/generators/authentication/templates/migrations/create_email_verification_tokens_migration.rb.tt
80
84
  - lib/generators/authentication/templates/migrations/create_events_migration.rb.tt
81
85
  - lib/generators/authentication/templates/migrations/create_password_reset_tokens_migration.rb.tt
82
86
  - lib/generators/authentication/templates/migrations/create_sessions_migration.rb.tt
87
+ - lib/generators/authentication/templates/migrations/create_sign_in_tokens_migration.rb.tt
83
88
  - lib/generators/authentication/templates/migrations/create_users_migration.rb.tt
84
89
  - lib/generators/authentication/templates/models/current.rb.tt
85
90
  - lib/generators/authentication/templates/models/email_verification_token.rb.tt
86
91
  - lib/generators/authentication/templates/models/event.rb.tt
87
92
  - lib/generators/authentication/templates/models/password_reset_token.rb.tt
88
93
  - lib/generators/authentication/templates/models/session.rb.tt
94
+ - lib/generators/authentication/templates/models/sign_in_token.rb.tt
89
95
  - lib/generators/authentication/templates/models/user.rb.tt
90
96
  - lib/generators/authentication/templates/test_unit/application_system_test_case.rb.tt
91
97
  - lib/generators/authentication/templates/test_unit/controllers/api/identity/email_verifications_controller_test.rb.tt