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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/Gemfile.lock +1 -1
- data/README.md +7 -2
- data/lib/authentication_zero/version.rb +1 -1
- data/lib/generators/authentication/authentication_generator.rb +23 -1
- data/lib/generators/authentication/templates/controllers/api/identity/password_resets_controller.rb.tt +4 -4
- data/lib/generators/authentication/templates/controllers/html/identity/password_resets_controller.rb.tt +4 -4
- data/lib/generators/authentication/templates/controllers/html/sessions/sudos_controller.rb.tt +3 -3
- data/lib/generators/authentication/templates/controllers/html/sessions_controller_two_factor.rb.tt +41 -0
- data/lib/generators/authentication/templates/controllers/html/two_factor_authentication/challenges_controller.rb.tt +28 -0
- data/lib/generators/authentication/templates/controllers/html/two_factor_authentication/totps_controller.rb.tt +26 -0
- data/lib/generators/authentication/templates/erb/identity/password_resets/edit.html.erb.tt +1 -1
- data/lib/generators/authentication/templates/erb/passwords/edit.html.erb.tt +2 -2
- data/lib/generators/authentication/templates/erb/sessions/sudos/new.html.erb.tt +2 -2
- data/lib/generators/authentication/templates/erb/two_factor_authentication/challenges/new.html.erb.tt +16 -0
- data/lib/generators/authentication/templates/erb/two_factor_authentication/totps/new.html.erb.tt +28 -0
- data/lib/generators/authentication/templates/migrations/create_table_migration.rb.tt +7 -4
- data/lib/generators/authentication/templates/models/model.rb.tt +6 -6
- data/lib/generators/authentication/templates/models/session.rb.tt +2 -2
- data/lib/generators/authentication/templates/test_unit/controllers/api/identity/password_resets_controller_test.rb.tt +2 -2
- data/lib/generators/authentication/templates/test_unit/controllers/html/identity/password_resets_controller_test.rb.tt +2 -2
- data/lib/generators/authentication/templates/test_unit/system/identity/password_resets_test.rb.tt +2 -2
- data/lib/generators/authentication/templates/test_unit/test_helper.rb.tt +3 -3
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c0ad4048d0c9df83173acebd1bbf770f519a7bb2a8b5b45c7e9af3c268904052
|
4
|
+
data.tar.gz: 06a897ebfc48122cfaf151a49b7412ef13b098069eb3bc7a2a4c088bcc711c90
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fd26a42853d553616f366e1ddc57439ce91ba039f2cf25a5d3c80be48a6b0f0e7fee6816ead70587780ebc8a358e74e53543c0b6438eb39d7baf818aacc5191c
|
7
|
+
data.tar.gz: 657bb45b7e9edfd6a036e9df9a2df41a2b2001199e65586d82548d7bd4ade28946be06ec3dbb28ba6fba100e275881c1a02dbb3de29b8546899393829b4cdc97
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
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
|
-
|
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
|
-
|
101
|
+
rails generate authentication user
|
97
102
|
```
|
98
103
|
|
99
104
|
Then run `bundle install` again!
|
@@ -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
|
-
|
4
|
+
<%- if options.lockable? -%>
|
5
5
|
before_action :require_locking, only: :create
|
6
|
-
|
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
|
-
|
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
|
-
|
41
|
+
<%- end -%>
|
42
42
|
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
class Identity::PasswordResetsController < ApplicationController
|
2
2
|
skip_before_action :authenticate
|
3
3
|
|
4
|
-
|
4
|
+
<%- if options.lockable? -%>
|
5
5
|
before_action :require_locking, only: :create
|
6
|
-
|
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
|
-
|
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
|
-
|
48
|
+
<%- end -%>
|
49
49
|
end
|
data/lib/generators/authentication/templates/controllers/html/sessions/sudos_controller.rb.tt
CHANGED
@@ -5,11 +5,11 @@ class Sessions::SudosController < ApplicationController
|
|
5
5
|
def create
|
6
6
|
session = Current.session
|
7
7
|
|
8
|
-
|
8
|
+
<%- if omniauthable? -%>
|
9
9
|
if session.<%= singular_table_name %>.authenticate(params[:password]) || session.<%= singular_table_name %>.provider
|
10
|
-
|
10
|
+
<%- else -%>
|
11
11
|
if session.<%= singular_table_name %>.authenticate(params[:password])
|
12
|
-
|
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"
|
data/lib/generators/authentication/templates/controllers/html/sessions_controller_two_factor.rb.tt
ADDED
@@ -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
|
@@ -16,8 +16,8 @@
|
|
16
16
|
<%% end %>
|
17
17
|
|
18
18
|
<div>
|
19
|
-
<%%=
|
20
|
-
<%%=
|
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
|
-
<%%=
|
7
|
+
<%%= form.hidden_field :proceed_to_url, value: params[:proceed_to_url] %>
|
8
8
|
|
9
9
|
<div>
|
10
|
-
<%%=
|
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 %>
|
data/lib/generators/authentication/templates/erb/two_factor_authentication/totps/new.html.erb.tt
ADDED
@@ -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
|
-
|
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
|
-
|
14
|
+
<%- end -%>
|
12
15
|
|
13
16
|
t.timestamps
|
14
17
|
end
|
15
18
|
|
16
19
|
add_index :<%= table_name %>, :email, unique: true
|
17
|
-
|
20
|
+
<%- if omniauthable? -%>
|
18
21
|
add_index :<%= table_name %>, [:provider, :uid], unique: true
|
19
|
-
|
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
|
-
|
5
|
+
<%- if options.trackable? -%>
|
6
6
|
has_many :events, dependent: :destroy
|
7
|
-
|
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
|
-
|
14
|
+
<%- if options.pwned? -%>
|
15
15
|
validates :password, not_pwned: { message: "might easily be guessed" }
|
16
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
9
|
+
<%- if options.lockable? %>
|
10
10
|
teardown { Kredis.clear_all }
|
11
|
-
|
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
|
-
|
9
|
+
<%- if options.lockable? %>
|
10
10
|
teardown { Kredis.clear_all }
|
11
|
-
|
11
|
+
<%- end -%>
|
12
12
|
|
13
13
|
test "should get new" do
|
14
14
|
get new_identity_password_reset_url
|
data/lib/generators/authentication/templates/test_unit/system/identity/password_resets_test.rb.tt
CHANGED
@@ -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
|
-
|
8
|
+
<%- if options.lockable? %>
|
9
9
|
teardown { Kredis.clear_all }
|
10
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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.
|
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-
|
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
|