authentication-zero 2.9.3 → 2.10.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 (25) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/Gemfile.lock +1 -1
  4. data/README.md +7 -2
  5. data/lib/authentication_zero/version.rb +1 -1
  6. data/lib/generators/authentication/authentication_generator.rb +23 -1
  7. data/lib/generators/authentication/templates/controllers/api/identity/password_resets_controller.rb.tt +4 -4
  8. data/lib/generators/authentication/templates/controllers/html/identity/password_resets_controller.rb.tt +4 -4
  9. data/lib/generators/authentication/templates/controllers/html/sessions/sudos_controller.rb.tt +3 -3
  10. data/lib/generators/authentication/templates/controllers/html/sessions_controller_two_factor.rb.tt +41 -0
  11. data/lib/generators/authentication/templates/controllers/html/two_factor_authentication/challenges_controller.rb.tt +28 -0
  12. data/lib/generators/authentication/templates/controllers/html/two_factor_authentication/totps_controller.rb.tt +26 -0
  13. data/lib/generators/authentication/templates/erb/identity/password_resets/edit.html.erb.tt +1 -1
  14. data/lib/generators/authentication/templates/erb/passwords/edit.html.erb.tt +2 -2
  15. data/lib/generators/authentication/templates/erb/sessions/sudos/new.html.erb.tt +2 -2
  16. data/lib/generators/authentication/templates/erb/two_factor_authentication/challenges/new.html.erb.tt +16 -0
  17. data/lib/generators/authentication/templates/erb/two_factor_authentication/totps/new.html.erb.tt +28 -0
  18. data/lib/generators/authentication/templates/migrations/create_table_migration.rb.tt +7 -4
  19. data/lib/generators/authentication/templates/models/model.rb.tt +6 -6
  20. data/lib/generators/authentication/templates/models/session.rb.tt +2 -2
  21. data/lib/generators/authentication/templates/test_unit/controllers/api/identity/password_resets_controller_test.rb.tt +2 -2
  22. data/lib/generators/authentication/templates/test_unit/controllers/html/identity/password_resets_controller_test.rb.tt +2 -2
  23. data/lib/generators/authentication/templates/test_unit/system/identity/password_resets_test.rb.tt +2 -2
  24. data/lib/generators/authentication/templates/test_unit/test_helper.rb.tt +3 -3
  25. metadata +7 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d8173a1510dfbe78180ce29cbb83b5f79b84b0ed4ecacf0569344905c28f2a01
4
- data.tar.gz: 9d89bc1c96a4b59b7c7bf2437bd038036e747f4e78c0a7d5a81f1c0ae4c86f28
3
+ metadata.gz: c0ad4048d0c9df83173acebd1bbf770f519a7bb2a8b5b45c7e9af3c268904052
4
+ data.tar.gz: 06a897ebfc48122cfaf151a49b7412ef13b098069eb3bc7a2a4c088bcc711c90
5
5
  SHA512:
6
- metadata.gz: 34a5ed73cbd7f5e35cd9a1e16ae0e4880a677ffa94f3892c0c6292abb436b3fded01c4664dd5e77d5b8025718b60ea8507bdbd968243d94ef191980615b02ea4
7
- data.tar.gz: 2afb2c4fbc2bef0c7e06fab12cf783f04c6bc811d7150ed58f4a73f430c23925f4e790c6e3477729e04f2ade59b80dd30220667952d7b41cc98a4106fc4e064e
6
+ metadata.gz: fd26a42853d553616f366e1ddc57439ce91ba039f2cf25a5d3c80be48a6b0f0e7fee6816ead70587780ebc8a358e74e53543c0b6438eb39d7baf818aacc5191c
7
+ data.tar.gz: 657bb45b7e9edfd6a036e9df9a2df41a2b2001199e65586d82548d7bd4ade28946be06ec3dbb28ba6fba100e275881c1a02dbb3de29b8546899393829b4cdc97
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## Authentication Zero 2.10.0 (March 2, 2022) ##
2
+
3
+ * Implement two-factor
4
+
1
5
  ## Authentication Zero 2.9.0 (March 2, 2022) ##
2
6
 
3
7
  * Implement trackable
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- authentication-zero (2.9.3)
4
+ authentication-zero (2.10.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -11,6 +11,7 @@ The purpose of authentication zero is to generate a pre-built authentication sys
11
11
  - Checks if a password has been found in any data breach (--pwned)
12
12
  - Authentication by cookie
13
13
  - Authentication by token (--api)
14
+ - Two factor authentication (--two-factor)
14
15
  - Social Login with OmniAuth (--omniauthable)
15
16
  - Ask password before sensitive data changes, aka: sudo
16
17
  - Reset the user password and send reset instructions
@@ -53,7 +54,7 @@ root "home#index"
53
54
  ```
54
55
 
55
56
  ```
56
- $ rails generate controller home index
57
+ rails generate controller home index
57
58
  ```
58
59
 
59
60
  Add these lines to your `app/views/home/index.html.erb`:
@@ -79,6 +80,10 @@ Add these lines to your `app/views/home/index.html.erb`:
79
80
  <%# link_to "Activity Log", authentications_events_path %>
80
81
  </div>
81
82
 
83
+ <div>
84
+ <%# link_to "Two-Factor Authentication", new_two_factor_authentication_totp_path %>
85
+ </div>
86
+
82
87
  <br>
83
88
 
84
89
  <%= button_to "Log out", Current.session, method: :delete %>
@@ -93,7 +98,7 @@ config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
93
98
  ## Usage
94
99
 
95
100
  ```
96
- $ rails generate authentication user
101
+ rails generate authentication user
97
102
  ```
98
103
 
99
104
  Then run `bundle install` again!
@@ -1,3 +1,3 @@
1
1
  module AuthenticationZero
2
- VERSION = "2.9.3"
2
+ VERSION = "2.10.0"
3
3
  end
@@ -9,6 +9,7 @@ class AuthenticationGenerator < Rails::Generators::NamedBase
9
9
  class_option :ratelimit, type: :boolean, desc: "Add request rate limiting"
10
10
  class_option :omniauthable, type: :boolean, desc: "Add social login support"
11
11
  class_option :trackable, type: :boolean, desc: "Add activity log support"
12
+ class_option :two_factor, type: :boolean, desc: "Add two factor authentication"
12
13
 
13
14
  source_root File.expand_path("templates", __dir__)
14
15
 
@@ -29,6 +30,11 @@ class AuthenticationGenerator < Rails::Generators::NamedBase
29
30
  gem "omniauth", comment: "Use OmniAuth to support multi-provider authentication [https://github.com/omniauth/omniauth]"
30
31
  gem "omniauth-rails_csrf_protection", comment: "Provides a mitigation against CVE-2015-9284 [https://github.com/cookpad/omniauth-rails_csrf_protection]"
31
32
  end
33
+
34
+ if two_factor?
35
+ gem "rotp", comment: "Use rotp for generating and validating one time passwords [https://github.com/mdp/rotp]"
36
+ gem "rqrcode", comment: "Use rqrcode for creating and rendering QR codes into various formats [https://github.com/whomwah/rqrcode]"
37
+ end
32
38
  end
33
39
 
34
40
  def create_configuration_files
@@ -66,10 +72,16 @@ class AuthenticationGenerator < Rails::Generators::NamedBase
66
72
  def create_controllers
67
73
  template "controllers/#{format_folder}/application_controller.rb", "app/controllers/application_controller.rb", force: true
68
74
 
75
+ if two_factor?
76
+ directory "controllers/#{format_folder}/two_factor_authentication", "app/controllers/two_factor_authentication"
77
+ template "controllers/#{format_folder}/sessions_controller_two_factor.rb", "app/controllers/sessions_controller.rb"
78
+ else
79
+ template "controllers/#{format_folder}/sessions_controller.rb", "app/controllers/sessions_controller.rb"
80
+ end
81
+
69
82
  directory "controllers/#{format_folder}/identity", "app/controllers/identity"
70
83
  template "controllers/#{format_folder}/passwords_controller.rb", "app/controllers/passwords_controller.rb"
71
84
  template "controllers/#{format_folder}/registrations_controller.rb", "app/controllers/registrations_controller.rb"
72
- template "controllers/#{format_folder}/sessions_controller.rb", "app/controllers/sessions_controller.rb"
73
85
  template "controllers/#{format_folder}/sessions/sudos_controller.rb", "app/controllers/sessions/sudos_controller.rb"
74
86
  template "controllers/#{format_folder}/sessions/omniauth_controller.rb", "app/controllers/sessions/omniauth_controller.rb" if omniauthable?
75
87
  template "controllers/#{format_folder}/authentications/events_controller.rb", "app/controllers/authentications/events_controller.rb" if options.trackable?
@@ -87,6 +99,7 @@ class AuthenticationGenerator < Rails::Generators::NamedBase
87
99
  directory "erb/passwords", "app/views/passwords"
88
100
  directory "erb/registrations", "app/views/registrations"
89
101
  directory "erb/sessions", "app/views/sessions"
102
+ directory "erb/two_factor_authentication", "app/views/two_factor_authentication" if two_factor?
90
103
  directory "erb/authentications/events", "app/views/authentications/events" if options.trackable?
91
104
  end
92
105
  end
@@ -102,6 +115,11 @@ class AuthenticationGenerator < Rails::Generators::NamedBase
102
115
  route "get '/auth/failure', to: 'sessions/omniauth#failure'"
103
116
  end
104
117
 
118
+ if two_factor?
119
+ route "resource :totp, only: [:new, :create]", namespace: :two_factor_authentication
120
+ route "resource :challenge, only: [:new, :create]", namespace: :two_factor_authentication
121
+ end
122
+
105
123
  if options.trackable?
106
124
  route "resources :events, only: :index", namespace: :authentications
107
125
  end
@@ -133,4 +151,8 @@ class AuthenticationGenerator < Rails::Generators::NamedBase
133
151
  def omniauthable?
134
152
  options.omniauthable? && !options.api?
135
153
  end
154
+
155
+ def two_factor?
156
+ options.two_factor? && !options.api?
157
+ end
136
158
  end
@@ -1,9 +1,9 @@
1
1
  class Identity::PasswordResetsController < ApplicationController
2
2
  skip_before_action :authenticate
3
3
 
4
- <% if options.lockable? -%>
4
+ <%- if options.lockable? -%>
5
5
  before_action :require_locking, only: :create
6
- <% end -%>
6
+ <%- end -%>
7
7
  before_action :set_<%= singular_table_name %>, only: :update
8
8
 
9
9
  def create
@@ -32,11 +32,11 @@ class Identity::PasswordResetsController < ApplicationController
32
32
  def <%= "#{singular_table_name}_params" %>
33
33
  params.permit(:password, :password_confirmation)
34
34
  end
35
- <% if options.lockable? %>
35
+ <%- if options.lockable? %>
36
36
  def require_locking
37
37
  Locking.lock_on("password_reset_lock:#{request.remote_ip}", wait: 1.hour, attempts: 10) do
38
38
  render json: { error: "You've exceeded the maximum number of attempts" }, status: :too_many_requests
39
39
  end
40
40
  end
41
- <% end -%>
41
+ <%- end -%>
42
42
  end
@@ -1,9 +1,9 @@
1
1
  class Identity::PasswordResetsController < ApplicationController
2
2
  skip_before_action :authenticate
3
3
 
4
- <% if options.lockable? -%>
4
+ <%- if options.lockable? -%>
5
5
  before_action :require_locking, only: :create
6
- <% end -%>
6
+ <%- end -%>
7
7
  before_action :set_<%= singular_table_name %>, only: %i[ edit update ]
8
8
 
9
9
  def new
@@ -39,11 +39,11 @@ class Identity::PasswordResetsController < ApplicationController
39
39
  def <%= "#{singular_table_name}_params" %>
40
40
  params.permit(:password, :password_confirmation)
41
41
  end
42
- <% if options.lockable? %>
42
+ <%- if options.lockable? %>
43
43
  def require_locking
44
44
  Locking.lock_on("password_reset_lock:#{request.remote_ip}", wait: 1.hour, attempts: 10) do
45
45
  redirect_to new_identity_password_reset_path, alert: "You've exceeded the maximum number of attempts"
46
46
  end
47
47
  end
48
- <% end -%>
48
+ <%- end -%>
49
49
  end
@@ -5,11 +5,11 @@ class Sessions::SudosController < ApplicationController
5
5
  def create
6
6
  session = Current.session
7
7
 
8
- <% if omniauthable? -%>
8
+ <%- if omniauthable? -%>
9
9
  if session.<%= singular_table_name %>.authenticate(params[:password]) || session.<%= singular_table_name %>.provider
10
- <% else -%>
10
+ <%- else -%>
11
11
  if session.<%= singular_table_name %>.authenticate(params[:password])
12
- <% end -%>
12
+ <%- end -%>
13
13
  session.update!(sudo_at: Time.current); redirect_to(params[:proceed_to_url])
14
14
  else
15
15
  redirect_to new_sessions_sudo_path(proceed_to_url: params[:proceed_to_url]), alert: "The password you entered is incorrect"
@@ -0,0 +1,41 @@
1
+ class SessionsController < ApplicationController
2
+ skip_before_action :authenticate, only: %i[ new create ]
3
+
4
+ before_action :set_session, only: :destroy
5
+
6
+ def index
7
+ @sessions = Current.<%= singular_table_name %>.sessions.order(created_at: :desc)
8
+ end
9
+
10
+ def new
11
+ @<%= singular_table_name %> = <%= class_name %>.new
12
+ end
13
+
14
+ def create
15
+ <%= singular_table_name %> = <%= class_name %>.find_by(email: params[:email])
16
+
17
+ if <%= singular_table_name %> && <%= singular_table_name %>.authenticate(params[:password])
18
+ if <%= singular_table_name %>.otp_secret
19
+ signed_id = <%= singular_table_name %>.signed_id(purpose: :authentication_challenge, expires_in: 20.minutes)
20
+
21
+ redirect_to new_two_factor_authentication_challenge_path(token: signed_id)
22
+ else
23
+ @session = <%= singular_table_name %>.sessions.create!
24
+ cookies.signed.permanent[:session_token] = { value: @session.id, httponly: true }
25
+
26
+ redirect_to root_path, notice: "Signed in successfully"
27
+ end
28
+ else
29
+ redirect_to sign_in_path(email_hint: params[:email]), alert: "That email or password is incorrect"
30
+ end
31
+ end
32
+
33
+ def destroy
34
+ @session.destroy; redirect_to(sessions_path, notice: "That session has been logged out")
35
+ end
36
+
37
+ private
38
+ def set_session
39
+ @session = Current.<%= singular_table_name %>.sessions.find(params[:id])
40
+ end
41
+ end
@@ -0,0 +1,28 @@
1
+ class TwoFactorAuthentication::ChallengesController < ApplicationController
2
+ skip_before_action :authenticate
3
+
4
+ before_action :set_<%= singular_table_name %>
5
+
6
+ def new
7
+ end
8
+
9
+ def create
10
+ @totp = ROTP::TOTP.new(@<%= singular_table_name %>.otp_secret, issuer: "YourAppName")
11
+
12
+ if @totp.verify(params[:code], drift_behind: 15)
13
+ session = @<%= singular_table_name %>.sessions.create!
14
+ cookies.signed.permanent[:session_token] = { value: session.id, httponly: true }
15
+
16
+ redirect_to root_path, notice: "Signed in successfully"
17
+ else
18
+ redirect_to new_two_factor_authentication_challenge_path(token: params[:token]), alert: "That code didn't work. Please try again"
19
+ end
20
+ end
21
+
22
+ private
23
+ def set_<%= singular_table_name %>
24
+ @<%= singular_table_name %> = <%= class_name %>.find_signed!(params[:token], purpose: :authentication_challenge)
25
+ rescue
26
+ redirect_to sign_in_path, alert: "That's taking too long. Please re-enter your password and try again"
27
+ end
28
+ end
@@ -0,0 +1,26 @@
1
+ class TwoFactorAuthentication::TotpsController < ApplicationController
2
+ before_action :require_sudo
3
+ before_action :set_<%= singular_table_name %>
4
+ before_action :set_totp
5
+
6
+ def new
7
+ @qr_code = RQRCode::QRCode.new(@totp.provisioning_uri(@<%= singular_table_name %>.email))
8
+ end
9
+
10
+ def create
11
+ if @totp.verify(params[:code], drift_behind: 15)
12
+ @<%= singular_table_name %>.update! otp_secret: params[:secret]
13
+ redirect_to root_path, notice: "2FA is enabled on your account"
14
+ else
15
+ redirect_to two_factor_authentication_totp_path, alert: "That code didn't work. Please try again"
16
+ end
17
+ end
18
+
19
+ def set_<%= singular_table_name %>
20
+ @<%= singular_table_name %> = Current.<%= singular_table_name %>
21
+ end
22
+
23
+ def set_totp
24
+ @totp = ROTP::TOTP.new(params[:secret] || ROTP::Base32.random, issuer: "YourAppName")
25
+ end
26
+ end
@@ -13,7 +13,7 @@
13
13
  </div>
14
14
  <%% end %>
15
15
 
16
- <%%= hidden_field_tag :token, params[:token] %>
16
+ <%%= form.hidden_field :token, value: params[:token] %>
17
17
 
18
18
  <div>
19
19
  <%%= form.label :password, "New password", style: "display: block" %>
@@ -16,8 +16,8 @@
16
16
  <%% end %>
17
17
 
18
18
  <div>
19
- <%%= label_tag :current_password, nil, style: "display: block" %>
20
- <%%= password_field_tag :current_password, nil, required: true, autofocus: true, autocomplete: "current-password" %>
19
+ <%%= form.label :current_password, style: "display: block" %>
20
+ <%%= form.password_field :current_password, required: true, autofocus: true, autocomplete: "current-password" %>
21
21
  </div>
22
22
 
23
23
  <div>
@@ -4,10 +4,10 @@
4
4
 
5
5
  <%%= form_with(url: sessions_sudo_path) do |form| %>
6
6
 
7
- <%%= hidden_field_tag :proceed_to_url, params[:proceed_to_url] %>
7
+ <%%= form.hidden_field :proceed_to_url, value: params[:proceed_to_url] %>
8
8
 
9
9
  <div>
10
- <%%= password_field_tag :password, nil, required: true, autofocus: true, autocomplete: "current-password" %>
10
+ <%%= form.password_field :password, required: true, autofocus: true, autocomplete: "current-password" %>
11
11
  </div>
12
12
 
13
13
  <div>
@@ -0,0 +1,16 @@
1
+ <p style="color: red"><%%= alert %></p>
2
+
3
+ <%%= form_with(url: two_factor_authentication_challenge_path) do |form| %>
4
+ <%%= form.hidden_field :token, value: params[:token] %>
5
+
6
+ <div>
7
+ <%%= form.label :code do %>
8
+ <h1>Next, open the 2FA authenticator app on your phone and type the six digit code below:</h1>
9
+ <%% end %>
10
+ <%%= form.text_field :code, autofocus: true, required: true, autocomplete: :off %>
11
+ </div>
12
+
13
+ <div>
14
+ <%%= form.submit "Verify" %>
15
+ </div>
16
+ <%% end %>
@@ -0,0 +1,28 @@
1
+ <p style="color: red"><%%= alert %></p>
2
+
3
+ <h1>Upgrade your security with 2FA</h1>
4
+
5
+ <h2>Step 1: Get an Authenticator App</h2>
6
+ <p>First, you'll need a 2FA authenticator app on your phone. <strong>If you already have one, skip to step 2.</strong></p>
7
+ <p><strong>If you don't have one, or you aren't sure, we recommend Microsoft Authenticator</strong>. You can download it free on the Apple App Store for iPhone, or Google Play Store for Android. Please grab your phone, search the store, and install it now.</p>
8
+
9
+ <h2>Step 2: Scan + Enter the Code</h2>
10
+ <p>Next, open the authenticator app, tap "Scan QR code" or "+", and, when it asks, point your phone's camera at this QR code picture below.</p>
11
+
12
+ <figure>
13
+ <%%= image_tag @qr_code.as_png(resize_exactly_to: 200).to_data_url%>
14
+ <figcaption>Point your camera here</figcaption>
15
+ </figure>
16
+
17
+ <%%= form_with(url: two_factor_authentication_totp_path) do |form| %>
18
+ <%%= form.hidden_field :secret, value: @totp.secret %>
19
+
20
+ <div>
21
+ <%%= form.label :code, "After scanning with your camera, the app will generate a six-digit code. Enter it here:", style: "display: block" %>
22
+ <%%= form.text_field :code, autofocus: true, required: true, autocomplete: :off %>
23
+ </div>
24
+
25
+ <div>
26
+ <%%= form.submit "Verify and active" %>
27
+ </div>
28
+ <%% end %>
@@ -5,17 +5,20 @@ class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Mi
5
5
  t.string :password_digest, null: false
6
6
 
7
7
  t.boolean :verified, null: false, default: false
8
- <% if omniauthable? %>
8
+ <%- if two_factor? %>
9
+ t.string :otp_secret
10
+ <%- end -%>
11
+ <%- if omniauthable? %>
9
12
  t.string :provider
10
13
  t.string :uid
11
- <% end -%>
14
+ <%- end -%>
12
15
 
13
16
  t.timestamps
14
17
  end
15
18
 
16
19
  add_index :<%= table_name %>, :email, unique: true
17
- <% if omniauthable? -%>
20
+ <%- if omniauthable? -%>
18
21
  add_index :<%= table_name %>, [:provider, :uid], unique: true
19
- <% end -%>
22
+ <%- end -%>
20
23
  end
21
24
  end
@@ -2,18 +2,18 @@ class <%= class_name %> < ApplicationRecord
2
2
  has_secure_password
3
3
 
4
4
  has_many :sessions, dependent: :destroy
5
- <% if options.trackable? -%>
5
+ <%- if options.trackable? -%>
6
6
  has_many :events, dependent: :destroy
7
- <% end -%>
7
+ <%- end -%>
8
8
 
9
9
  validates :email, presence: true, uniqueness: true
10
10
  validates_format_of :email, with: /\A[^@\s]+@[^@\s]+\z/
11
11
 
12
12
  validates_length_of :password, minimum: 12, allow_nil: true
13
13
  validates_format_of :password, with: /(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])/, allow_nil: true, message: "might easily be guessed"
14
- <% if options.pwned? -%>
14
+ <%- if options.pwned? -%>
15
15
  validates :password, not_pwned: { message: "might easily be guessed" }
16
- <% end -%>
16
+ <%- end -%>
17
17
 
18
18
  before_validation do
19
19
  self.email = email.downcase.strip
@@ -30,7 +30,7 @@ class <%= class_name %> < ApplicationRecord
30
30
  after_save_commit if: :email_previously_changed? do
31
31
  IdentityMailer.with(user: self).email_verify_confirmation.deliver_later
32
32
  end
33
- <% if options.trackable? %>
33
+ <%- if options.trackable? %>
34
34
  after_save_commit if: :email_previously_changed? do
35
35
  events.create! action: "email_verification_requested"
36
36
  end
@@ -42,5 +42,5 @@ class <%= class_name %> < ApplicationRecord
42
42
  after_update if: :verified_previously_changed? do
43
43
  events.create! action: "email_verified" if verified?
44
44
  end
45
- <% end -%>
45
+ <%- end -%>
46
46
  end
@@ -10,7 +10,7 @@ class Session < ApplicationRecord
10
10
  after_create_commit do
11
11
  SessionMailer.with(session: self).signed_in_notification.deliver_later
12
12
  end
13
- <% if options.trackable? %>
13
+ <%- if options.trackable? %>
14
14
  after_create do
15
15
  <%= singular_table_name %>.events.create! action: "signed_in"
16
16
  end
@@ -18,5 +18,5 @@ class Session < ApplicationRecord
18
18
  after_destroy do
19
19
  <%= singular_table_name %>.events.create! action: "signed_out"
20
20
  end
21
- <% end -%>
21
+ <%- end -%>
22
22
  end
@@ -6,9 +6,9 @@ class Identity::PasswordResetsControllerTest < ActionDispatch::IntegrationTest
6
6
  @sid = @<%= singular_table_name %>.signed_id(purpose: :password_reset, expires_in: 20.minutes)
7
7
  @sid_exp = @<%= singular_table_name %>.signed_id(purpose: :password_reset, expires_in: 0.minutes)
8
8
  end
9
- <% if options.lockable? %>
9
+ <%- if options.lockable? %>
10
10
  teardown { Kredis.clear_all }
11
- <% end -%>
11
+ <%- end -%>
12
12
 
13
13
  test "should send a password reset email" do
14
14
  assert_enqueued_email_with IdentityMailer, :password_reset_provision, args: { <%= singular_table_name %>: @<%= singular_table_name %> } do
@@ -6,9 +6,9 @@ class Identity::PasswordResetsControllerTest < ActionDispatch::IntegrationTest
6
6
  @sid = @<%= singular_table_name %>.signed_id(purpose: :password_reset, expires_in: 20.minutes)
7
7
  @sid_exp = @<%= singular_table_name %>.signed_id(purpose: :password_reset, expires_in: 0.minutes)
8
8
  end
9
- <% if options.lockable? %>
9
+ <%- if options.lockable? %>
10
10
  teardown { Kredis.clear_all }
11
- <% end -%>
11
+ <%- end -%>
12
12
 
13
13
  test "should get new" do
14
14
  get new_identity_password_reset_url
@@ -5,9 +5,9 @@ class Identity::PasswordResetsTest < ApplicationSystemTestCase
5
5
  @<%= singular_table_name %> = <%= table_name %>(:lazaro_nixon)
6
6
  @sid = @<%= singular_table_name %>.signed_id(purpose: :password_reset, expires_in: 20.minutes)
7
7
  end
8
- <% if options.lockable? %>
8
+ <%- if options.lockable? %>
9
9
  teardown { Kredis.clear_all }
10
- <% end -%>
10
+ <%- end -%>
11
11
 
12
12
  test "sending a password reset email" do
13
13
  visit sign_in_url
@@ -10,13 +10,13 @@ class ActiveSupport::TestCase
10
10
  fixtures :all
11
11
 
12
12
  # Add more helper methods to be used by all tests here...
13
- <% if options.api? -%>
13
+ <%- if options.api? -%>
14
14
  def sign_in_as(<%= singular_table_name %>)
15
15
  post(sign_in_url, params: { email: <%= singular_table_name %>.email, password: "Secret1*3*5*" }); [<%= singular_table_name %>, response.headers["X-Session-Token"]]
16
16
  end
17
- <% else -%>
17
+ <%- else -%>
18
18
  def sign_in_as(<%= singular_table_name %>)
19
19
  post(sign_in_url, params: { email: <%= singular_table_name %>.email, password: "Secret1*3*5*" }); <%= singular_table_name %>
20
20
  end
21
- <% end -%>
21
+ <%- end -%>
22
22
  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.9.3
4
+ version: 2.10.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-03-08 00:00:00.000000000 Z
11
+ date: 2022-03-14 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email:
@@ -54,6 +54,9 @@ files:
54
54
  - lib/generators/authentication/templates/controllers/html/sessions/omniauth_controller.rb.tt
55
55
  - lib/generators/authentication/templates/controllers/html/sessions/sudos_controller.rb.tt
56
56
  - lib/generators/authentication/templates/controllers/html/sessions_controller.rb.tt
57
+ - lib/generators/authentication/templates/controllers/html/sessions_controller_two_factor.rb.tt
58
+ - lib/generators/authentication/templates/controllers/html/two_factor_authentication/challenges_controller.rb.tt
59
+ - lib/generators/authentication/templates/controllers/html/two_factor_authentication/totps_controller.rb.tt
57
60
  - lib/generators/authentication/templates/erb/authentications/events/index.html.erb
58
61
  - lib/generators/authentication/templates/erb/identity/emails/edit.html.erb.tt
59
62
  - lib/generators/authentication/templates/erb/identity/password_resets/edit.html.erb.tt
@@ -69,6 +72,8 @@ files:
69
72
  - lib/generators/authentication/templates/erb/sessions/index.html.erb.tt
70
73
  - lib/generators/authentication/templates/erb/sessions/new.html.erb.tt
71
74
  - lib/generators/authentication/templates/erb/sessions/sudos/new.html.erb.tt
75
+ - lib/generators/authentication/templates/erb/two_factor_authentication/challenges/new.html.erb.tt
76
+ - lib/generators/authentication/templates/erb/two_factor_authentication/totps/new.html.erb.tt
72
77
  - lib/generators/authentication/templates/mailers/identity_mailer.rb.tt
73
78
  - lib/generators/authentication/templates/mailers/session_mailer.rb.tt
74
79
  - lib/generators/authentication/templates/migrations/create_events_migration.rb.tt