authentication-zero 2.9.3 → 2.10.0

Sign up to get free protection for your applications and to get access to all the features.
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