quo_vadis 2.1.11 → 2.2.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 +9 -0
- data/README.md +50 -99
- data/app/controllers/quo_vadis/confirmations_controller.rb +26 -61
- data/app/controllers/quo_vadis/password_resets_controller.rb +64 -32
- data/app/controllers/quo_vadis/sessions_controller.rb +0 -5
- data/app/mailers/quo_vadis/mailer.rb +2 -2
- data/app/models/quo_vadis/account.rb +32 -0
- data/app/models/quo_vadis/password.rb +6 -1
- data/app/views/quo_vadis/confirmations/new.html.erb +19 -7
- data/app/views/quo_vadis/mailer/account_confirmation.text.erb +2 -3
- data/app/views/quo_vadis/mailer/reset_password.text.erb +2 -2
- data/app/views/quo_vadis/password_resets/edit.html.erb +13 -1
- data/app/views/quo_vadis/password_resets/new.html.erb +1 -1
- data/config/locales/quo_vadis.en.yml +9 -7
- data/config/routes.rb +4 -12
- data/lib/quo_vadis/controller.rb +20 -10
- data/lib/quo_vadis/defaults.rb +2 -2
- data/lib/quo_vadis/version.rb +1 -1
- data/lib/quo_vadis.rb +2 -2
- data/test/dummy/app/controllers/sign_ups_controller.rb +2 -11
- data/test/fixtures/quo_vadis/mailer/account_confirmation.text +2 -3
- data/test/fixtures/quo_vadis/mailer/reset_password.text +2 -2
- data/test/integration/account_confirmation_test.rb +42 -86
- data/test/integration/controller_test.rb +8 -8
- data/test/integration/logging_test.rb +31 -7
- data/test/integration/password_login_test.rb +1 -1
- data/test/integration/password_reset_test.rb +89 -54
- data/test/mailers/mailer_test.rb +2 -2
- data/test/models/account_test.rb +48 -0
- data/test/models/session_test.rb +4 -0
- metadata +2 -10
- data/app/models/quo_vadis/account_confirmation_token.rb +0 -17
- data/app/models/quo_vadis/password_reset_token.rb +0 -17
- data/app/models/quo_vadis/token.rb +0 -42
- data/app/views/quo_vadis/confirmations/edit.html.erb +0 -10
- data/app/views/quo_vadis/confirmations/edit_email.html.erb +0 -14
- data/app/views/quo_vadis/confirmations/index.html.erb +0 -14
- data/app/views/quo_vadis/password_resets/index.html.erb +0 -5
- data/test/models/token_test.rb +0 -70
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'rotp'
|
4
|
+
|
3
5
|
module QuoVadis
|
4
6
|
class Account < ActiveRecord::Base
|
5
7
|
|
@@ -18,6 +20,26 @@ module QuoVadis
|
|
18
20
|
after_update :log_identifier_change, if: :saved_change_to_identifier?
|
19
21
|
after_update :notify_identifier_change, if: :saved_change_to_identifier?
|
20
22
|
|
23
|
+
scope :unconfirmed, -> { where confirmed_at: nil }
|
24
|
+
|
25
|
+
def otp_for_confirmation(counter)
|
26
|
+
hotp_for_confirmation.at(counter)
|
27
|
+
end
|
28
|
+
|
29
|
+
# If the `otp` is valid for the `counter`, confirms the account and returns truthy.
|
30
|
+
# Otherwise returns falsey.
|
31
|
+
def confirm(otp, counter)
|
32
|
+
hotp_for_confirmation.verify(otp, counter) && confirmed!
|
33
|
+
end
|
34
|
+
|
35
|
+
def otp_for_password_reset(counter)
|
36
|
+
hotp_for_password_reset.at(counter)
|
37
|
+
end
|
38
|
+
|
39
|
+
def verify_password_reset(otp, counter)
|
40
|
+
hotp_for_password_reset.verify(otp, counter)
|
41
|
+
end
|
42
|
+
|
21
43
|
def confirmed?
|
22
44
|
confirmed_at.present?
|
23
45
|
end
|
@@ -51,6 +73,16 @@ module QuoVadis
|
|
51
73
|
|
52
74
|
private
|
53
75
|
|
76
|
+
def hotp_for_confirmation
|
77
|
+
key = ROTP::Base32.encode("#{id}-#{Rails.application.secret_key_base}")
|
78
|
+
ROTP::HOTP.new(key)
|
79
|
+
end
|
80
|
+
|
81
|
+
def hotp_for_password_reset
|
82
|
+
key = ROTP::Base32.encode("#{id}-#{password.password_digest}")
|
83
|
+
ROTP::HOTP.new(key)
|
84
|
+
end
|
85
|
+
|
54
86
|
def log_identifier_change
|
55
87
|
from, to = saved_change_to_identifier
|
56
88
|
Log.create(
|
@@ -46,7 +46,12 @@ module QuoVadis
|
|
46
46
|
|
47
47
|
self.password = new_plaintext
|
48
48
|
self.password_confirmation = new_plaintext_confirmation
|
49
|
-
save
|
49
|
+
if save
|
50
|
+
# Logout account's sessions because password has changed.
|
51
|
+
# Assumes model is not logged in.
|
52
|
+
account.sessions.destroy_all
|
53
|
+
true
|
54
|
+
end
|
50
55
|
end
|
51
56
|
|
52
57
|
private
|
@@ -1,16 +1,28 @@
|
|
1
|
-
<h1>
|
1
|
+
<h1>Account confirmation</h1>
|
2
2
|
|
3
|
-
|
3
|
+
<p>We have sent a confirmation code to <%= @account.model.email %>.</p>
|
4
4
|
|
5
|
-
|
5
|
+
<!-- flash could go here -->
|
6
6
|
|
7
|
-
<%= form_with url:
|
7
|
+
<%= form_with url: confirm_path, method: :post do %>
|
8
8
|
<p>
|
9
|
-
|
10
|
-
|
9
|
+
<label for="otp">Your confirmation code:</label>
|
10
|
+
<input
|
11
|
+
name="otp"
|
12
|
+
id="otp"
|
13
|
+
type="text"
|
14
|
+
inputmode="numeric"
|
15
|
+
pattern="\d*"
|
16
|
+
autofocus="true"
|
17
|
+
autocomplete="one-time-password"
|
18
|
+
maxlength="6">
|
11
19
|
</p>
|
12
20
|
|
13
21
|
<p>
|
14
|
-
|
22
|
+
<button type="submit">Confirm me!</button>
|
15
23
|
</p>
|
16
24
|
<% end %>
|
25
|
+
|
26
|
+
<p>
|
27
|
+
<%= button_to "Send me a new confirmation code", send_confirmation_path %>
|
28
|
+
</p>
|
@@ -1,6 +1,18 @@
|
|
1
1
|
<h1>Reset password</h1>
|
2
2
|
|
3
|
-
<%= form_with model: @password, url: password_reset_path
|
3
|
+
<%= form_with model: @password, url: password_reset_path, method: :put do |f| %>
|
4
|
+
<p>
|
5
|
+
<%= f.label :otp, 'Your password reset code' %>
|
6
|
+
<%= f.text_field :otp,
|
7
|
+
value: params.dig(:password, :otp),
|
8
|
+
inputmode: 'numeric',
|
9
|
+
pattern: '\d*',
|
10
|
+
autofocus: true,
|
11
|
+
autocomplete: 'one-time-password',
|
12
|
+
maxlength: 6 %>
|
13
|
+
</p>
|
14
|
+
|
15
|
+
|
4
16
|
<p>
|
5
17
|
<%= f.label :password %>
|
6
18
|
<%= f.password_field :password, autocomplete: 'new-password' %>
|
@@ -11,15 +11,17 @@ en:
|
|
11
11
|
password:
|
12
12
|
update: Your password has been changed.
|
13
13
|
password_reset:
|
14
|
-
create:
|
15
|
-
unknown:
|
14
|
+
create: Please check your email for your reset code.
|
15
|
+
unknown: Please check your email for your reset code.
|
16
|
+
expired: Your reset code has expired. Please request another one.
|
17
|
+
invalid: Sorry, the code was incorrect. Please try again.
|
16
18
|
reset: Your password has been changed and you are logged in.
|
17
19
|
confirmation:
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
confirmed: Thanks for confirming your account.
|
20
|
+
unknown: You have already confirmed your account.
|
21
|
+
sent: Please check your email for your confirmation code.
|
22
|
+
expired: Your confirmation code has expired. Please request another one.
|
23
|
+
invalid: Sorry, the code was incorrect. Please try again.
|
24
|
+
confirmed: Thanks for confirming your account.
|
23
25
|
totp:
|
24
26
|
unverified: Sorry, the code was incorrect. Please check your system clock is correct and try again.
|
25
27
|
setup: Please set up two factor authentication.
|
data/config/routes.rb
CHANGED
@@ -11,19 +11,11 @@ QuoVadis::Engine.routes.draw do
|
|
11
11
|
|
12
12
|
resource :password, only: [:edit, :update]
|
13
13
|
|
14
|
-
|
15
|
-
get '/pwd-reset/:token', to: 'password_resets#edit', as: 'password_reset'
|
16
|
-
put '/pwd-reset/:token', to: 'password_resets#update'
|
14
|
+
resource :password_reset, only: [:new, :create, :edit, :update]
|
17
15
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
put :update_email
|
22
|
-
post :resend
|
23
|
-
end
|
24
|
-
end
|
25
|
-
get '/confirm/:token', to: 'confirmations#edit', as: 'confirmation'
|
26
|
-
put '/confirm/:token', to: 'confirmations#update'
|
16
|
+
get '/confirm', to: 'confirmations#new'
|
17
|
+
post '/confirm', to: 'confirmations#create'
|
18
|
+
post '/confirm/send', to: 'confirmations#resend', as: 'send_confirmation'
|
27
19
|
|
28
20
|
resources :totps, only: [:new, :create] do
|
29
21
|
collection do
|
data/lib/quo_vadis/controller.rb
CHANGED
@@ -16,7 +16,13 @@ module QuoVadis
|
|
16
16
|
|
17
17
|
|
18
18
|
def require_password_authentication
|
19
|
-
|
19
|
+
if logged_in?
|
20
|
+
if QuoVadis.accounts_require_confirmation && !authenticated_model.qv_account.confirmed?
|
21
|
+
qv.request_confirmation authenticated_model
|
22
|
+
redirect_to quo_vadis.confirm_path
|
23
|
+
end
|
24
|
+
return
|
25
|
+
end
|
20
26
|
session[:qv_bookmark] = request.original_fullpath
|
21
27
|
redirect_to quo_vadis.login_path, notice: QuoVadis.translate('flash.require_authentication')
|
22
28
|
end
|
@@ -85,15 +91,6 @@ module QuoVadis
|
|
85
91
|
end
|
86
92
|
|
87
93
|
|
88
|
-
def request_confirmation(model)
|
89
|
-
token = QuoVadis::AccountConfirmationToken.generate model.qv_account
|
90
|
-
QuoVadis.deliver :account_confirmation, {email: model.email, url: quo_vadis.confirmation_url(token)}
|
91
|
-
session[:account_pending_confirmation] = model.qv_account.id
|
92
|
-
|
93
|
-
flash[:notice] = QuoVadis.translate 'flash.confirmation.create'
|
94
|
-
end
|
95
|
-
|
96
|
-
|
97
94
|
def qv
|
98
95
|
@qv_wrapper ||= QuoVadisWrapper.new self
|
99
96
|
end
|
@@ -143,6 +140,19 @@ module QuoVadis
|
|
143
140
|
old_session.each { |k,v| rails_session[k] = v }
|
144
141
|
end
|
145
142
|
|
143
|
+
def request_confirmation(model)
|
144
|
+
rails_session[:account_pending_confirmation] = model.qv_account.id
|
145
|
+
|
146
|
+
expiration = QuoVadis.account_confirmation_otp_lifetime.from_now.to_i
|
147
|
+
rails_session[:account_confirmation_expires_at] = expiration
|
148
|
+
|
149
|
+
otp = model.qv_account.otp_for_confirmation(expiration)
|
150
|
+
|
151
|
+
QuoVadis.deliver :account_confirmation, {email: model.email, otp: otp}
|
152
|
+
|
153
|
+
controller.flash[:notice] = QuoVadis.translate 'flash.confirmation.sent'
|
154
|
+
end
|
155
|
+
|
146
156
|
# Assumes user is logged in.
|
147
157
|
def second_factor_required?
|
148
158
|
QuoVadis.two_factor_authentication_mandatory || authenticated_model.qv_account.has_two_factors?
|
data/lib/quo_vadis/defaults.rb
CHANGED
@@ -7,9 +7,9 @@ QuoVadis.configure do
|
|
7
7
|
session_lifetime :session
|
8
8
|
session_lifetime_extend_to_end_of_day false
|
9
9
|
session_idle_timeout :lifetime
|
10
|
-
|
10
|
+
password_reset_otp_lifetime 10.minutes
|
11
11
|
accounts_require_confirmation false
|
12
|
-
|
12
|
+
account_confirmation_otp_lifetime 10.minutes
|
13
13
|
mailer_superclass 'ApplicationMailer'
|
14
14
|
mail_headers ({ from: 'Example App <support@example.com>' })
|
15
15
|
enqueue_transactional_emails true
|
data/lib/quo_vadis/version.rb
CHANGED
data/lib/quo_vadis.rb
CHANGED
@@ -24,11 +24,11 @@ module QuoVadis
|
|
24
24
|
:session_lifetime, # :session | ActiveSupport::Duration | [integer] seconds
|
25
25
|
:session_lifetime_extend_to_end_of_day,# true | false
|
26
26
|
:session_idle_timeout, # :lifetime | ActiveSupport::Duration | [integer] seconds
|
27
|
-
:
|
27
|
+
:password_reset_otp_lifetime, # ActiveSupport::Duration | [integer] seconds
|
28
28
|
:mailer_superclass, # string
|
29
29
|
:mail_headers, # hash
|
30
30
|
:accounts_require_confirmation, # true | false
|
31
|
-
:
|
31
|
+
:account_confirmation_otp_lifetime, # ActiveSupport::Duration | [integer] seconds
|
32
32
|
:enqueue_transactional_emails, # true | false
|
33
33
|
:app_name, # string
|
34
34
|
:two_factor_authentication_mandatory, # true | false
|
@@ -1,8 +1,6 @@
|
|
1
1
|
# To test sign-ups with confirmation (activation / verification)
|
2
2
|
class SignUpsController < ApplicationController
|
3
3
|
|
4
|
-
around_action :toggle_confirmation
|
5
|
-
|
6
4
|
def new
|
7
5
|
@user = User.new
|
8
6
|
end
|
@@ -11,9 +9,9 @@ class SignUpsController < ApplicationController
|
|
11
9
|
def create
|
12
10
|
@user = User.new user_params
|
13
11
|
if @user.save
|
12
|
+
login @user
|
14
13
|
if QuoVadis.accounts_require_confirmation
|
15
|
-
|
16
|
-
redirect_to quo_vadis.confirmations_path
|
14
|
+
redirect_to secret_articles_path
|
17
15
|
else
|
18
16
|
redirect_to articles_path
|
19
17
|
end
|
@@ -37,11 +35,4 @@ class SignUpsController < ApplicationController
|
|
37
35
|
params.require(:user).permit(:name, :email, :password, :password_confirmation)
|
38
36
|
end
|
39
37
|
|
40
|
-
def toggle_confirmation
|
41
|
-
QuoVadis.accounts_require_confirmation true
|
42
|
-
yield
|
43
|
-
ensure
|
44
|
-
QuoVadis.accounts_require_confirmation false
|
45
|
-
end
|
46
|
-
|
47
38
|
end
|
@@ -14,136 +14,92 @@ class AccountConfirmationTest < IntegrationTest
|
|
14
14
|
test 'new signup requiring confirmation' do
|
15
15
|
assert_emails 1 do
|
16
16
|
post sign_ups_path(user: {name: 'Bob', email: 'bob@example.com', password: '123456789abc'})
|
17
|
+
refute QuoVadis::Account.last.confirmed?
|
18
|
+
assert controller.logged_in?
|
19
|
+
|
20
|
+
# verify response
|
21
|
+
assert_redirected_to '/articles/secret'
|
22
|
+
follow_redirect!
|
23
|
+
assert_redirected_to '/confirm'
|
24
|
+
follow_redirect!
|
25
|
+
assert_equal 'Please check your email for your confirmation code.', flash[:notice]
|
17
26
|
end
|
18
|
-
refute QuoVadis::Account.last.confirmed?
|
19
|
-
|
20
|
-
# verify response
|
21
|
-
assert_response :redirect
|
22
|
-
follow_redirect!
|
23
|
-
assert_equal 'A link to confirm your account has been emailed to you.', flash[:notice]
|
24
27
|
|
25
|
-
#
|
26
|
-
|
27
|
-
|
28
|
-
assert_response :success
|
29
|
-
action_path = extract_path_from_email
|
30
|
-
assert_select "form[action='#{action_path}']"
|
31
|
-
|
32
|
-
# click button on confirmation page
|
33
|
-
put action_path
|
28
|
+
# type in confirmation code from email
|
29
|
+
code = extract_code_from_email
|
30
|
+
post quo_vadis.confirm_path(otp: code)
|
34
31
|
|
35
32
|
# verify logged in
|
36
33
|
assert_redirected_to '/sign_ups/confirmed'
|
37
34
|
follow_redirect!
|
38
35
|
assert_redirected_to '/articles/secret'
|
39
|
-
assert_equal 'Thanks for confirming your account.
|
40
|
-
assert controller.logged_in?
|
36
|
+
assert_equal 'Thanks for confirming your account.', flash[:notice]
|
41
37
|
assert QuoVadis::Account.last.confirmed?
|
42
38
|
end
|
43
39
|
|
44
40
|
|
45
|
-
test '
|
46
|
-
assert_emails 1 do
|
47
|
-
post sign_ups_path(user: {name: 'Bob', email: 'bob@example.com', password: '123456789abc'})
|
48
|
-
end
|
49
|
-
|
50
|
-
get quo_vadis.edit_email_confirmations_path
|
51
|
-
assert_response :success
|
52
|
-
|
53
|
-
# First email: changed-email notifier sent to original address
|
54
|
-
# Second email: confirmation email sent to new address
|
55
|
-
assert_emails 2 do
|
56
|
-
put quo_vadis.update_email_confirmations_path(email: 'bobby@example.com')
|
57
|
-
end
|
58
|
-
assert_equal ['bobby@example.com'], ActionMailer::Base.deliveries.last.to
|
59
|
-
assert_redirected_to quo_vadis.confirmations_path
|
60
|
-
end
|
61
|
-
|
62
|
-
|
63
|
-
test 'resend confirmation email in same session' do
|
41
|
+
test 'resend confirmation email' do
|
64
42
|
assert_emails 1 do
|
65
43
|
post sign_ups_path(user: {name: 'Bob', email: 'bob@example.com', password: '123456789abc'})
|
44
|
+
assert_redirected_to '/articles/secret'
|
45
|
+
follow_redirect!
|
66
46
|
end
|
67
47
|
|
68
48
|
assert_emails 1 do
|
69
|
-
post quo_vadis.
|
49
|
+
post quo_vadis.send_confirmation_path
|
70
50
|
end
|
71
51
|
end
|
72
52
|
|
73
53
|
|
74
|
-
test '
|
75
|
-
User.create! name: 'bob', email: 'bob@example.com', password: '123456789abc'
|
76
|
-
|
77
|
-
get quo_vadis.new_confirmation_path
|
78
|
-
assert_response :success
|
79
|
-
|
80
|
-
assert_emails 1 do
|
81
|
-
post quo_vadis.confirmations_path(email: 'bob@example.com')
|
82
|
-
end
|
83
|
-
|
84
|
-
assert_redirected_to '/confirmations'
|
85
|
-
assert_equal 'A link to confirm your account has been emailed to you.', flash[:notice]
|
86
|
-
end
|
87
|
-
|
88
|
-
|
89
|
-
test 'resend confirmation email: unknown identifier' do
|
90
|
-
assert_no_emails do
|
91
|
-
post quo_vadis.confirmations_path(email: 'bob@example.com')
|
92
|
-
end
|
93
|
-
|
94
|
-
assert_redirected_to quo_vadis.new_confirmation_path
|
95
|
-
assert_equal 'Sorry, your account could not be found. Please try again.', flash[:alert]
|
96
|
-
end
|
97
|
-
|
98
|
-
|
99
|
-
test 'reusing a token' do
|
54
|
+
test 'cannot reuse a confirmation code' do
|
100
55
|
assert_emails 1 do
|
101
56
|
post sign_ups_path(user: {name: 'Bob', email: 'bob@example.com', password: '123456789abc'})
|
57
|
+
follow_redirect!
|
102
58
|
end
|
103
59
|
|
104
|
-
|
60
|
+
code = extract_code_from_email
|
61
|
+
post quo_vadis.confirm_path(otp: code)
|
62
|
+
assert QuoVadis::Account.last.confirmed?
|
63
|
+
assert_equal 'Thanks for confirming your account.', flash[:notice]
|
105
64
|
|
65
|
+
post quo_vadis.confirm_path(otp: code)
|
66
|
+
assert_equal 'You have already confirmed your account.', flash[:alert]
|
106
67
|
assert_redirected_to '/sign_ups/confirmed'
|
107
|
-
follow_redirect!
|
108
|
-
assert_redirected_to '/articles/secret'
|
109
|
-
assert_equal 'Thanks for confirming your account. You are now logged in.', flash[:notice]
|
110
|
-
|
111
|
-
put extract_path_from_email
|
112
|
-
assert_redirected_to quo_vadis.new_confirmation_path
|
113
|
-
assert_equal 'Either the link has expired or your account has already been confirmed.', flash[:alert]
|
114
68
|
end
|
115
69
|
|
116
70
|
|
117
|
-
test '
|
71
|
+
test 'confirmation code expired' do
|
118
72
|
assert_emails 1 do
|
119
73
|
post sign_ups_path(user: {name: 'Bob', email: 'bob@example.com', password: '123456789abc'})
|
74
|
+
follow_redirect!
|
120
75
|
end
|
121
76
|
|
122
|
-
travel QuoVadis.
|
123
|
-
get extract_url_from_email
|
77
|
+
travel QuoVadis.account_confirmation_otp_lifetime + 1.minute
|
124
78
|
|
125
|
-
|
126
|
-
|
79
|
+
code = extract_code_from_email
|
80
|
+
post quo_vadis.confirm_path(otp: code)
|
81
|
+
refute QuoVadis::Account.last.confirmed?
|
82
|
+
assert_equal 'Your confirmation code has expired. Please request another one.', flash[:alert]
|
83
|
+
assert_redirected_to quo_vadis.confirm_path
|
127
84
|
end
|
128
85
|
|
129
86
|
|
130
|
-
test 'accounts requiring confirmation
|
87
|
+
test 'accounts requiring confirmation can log in but have to confirm' do
|
131
88
|
User.create! name: 'bob', email: 'bob@example.com', password: '123456789abc'
|
132
89
|
post quo_vadis.login_path(email: 'bob@example.com', password: '123456789abc')
|
133
|
-
assert_redirected_to
|
134
|
-
|
135
|
-
|
90
|
+
assert_redirected_to '/articles/secret'
|
91
|
+
follow_redirect!
|
92
|
+
assert_redirected_to quo_vadis.confirm_path
|
93
|
+
follow_redirect!
|
94
|
+
assert controller.logged_in?
|
95
|
+
assert_equal 'Please check your email for your confirmation code.', flash[:notice]
|
136
96
|
end
|
137
97
|
|
138
98
|
|
139
99
|
private
|
140
100
|
|
141
|
-
def
|
142
|
-
ActionMailer::Base.deliveries.last.decoded[%r{
|
143
|
-
end
|
144
|
-
|
145
|
-
def extract_path_from_email
|
146
|
-
extract_url_from_email.sub 'http://www.example.com', ''
|
101
|
+
def extract_code_from_email
|
102
|
+
ActionMailer::Base.deliveries.last.decoded[%r{\d{6}}, 0]
|
147
103
|
end
|
148
104
|
|
149
105
|
end
|
@@ -206,14 +206,14 @@ class ControllerTest < IntegrationTest
|
|
206
206
|
end
|
207
207
|
|
208
208
|
|
209
|
-
test 'request_confirmation' do
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
end
|
209
|
+
# test 'request_confirmation' do
|
210
|
+
# get articles_path
|
211
|
+
|
212
|
+
# assert_emails 1 do
|
213
|
+
# controller.request_confirmation User.last
|
214
|
+
# end
|
215
|
+
# assert_equal 'A link to confirm your account has been emailed to you.', flash[:notice]
|
216
|
+
# end
|
217
217
|
|
218
218
|
|
219
219
|
test 'session lifetime exceeded' do
|
@@ -163,22 +163,42 @@ class LoggingTest < IntegrationTest
|
|
163
163
|
|
164
164
|
|
165
165
|
test 'password.reset' do
|
166
|
+
assert_emails 1 do
|
167
|
+
post quo_vadis.password_reset_path(email: 'bob@example.com')
|
168
|
+
follow_redirect!
|
169
|
+
end
|
170
|
+
|
166
171
|
assert_difference 'QuoVadis::Log.count', 2 do
|
167
|
-
|
168
|
-
|
172
|
+
put quo_vadis.password_reset_path(password: {
|
173
|
+
otp: extract_code_from_email,
|
174
|
+
password: 'secretsecret',
|
175
|
+
password_confirmation: 'secretsecret',
|
176
|
+
})
|
169
177
|
end
|
178
|
+
|
170
179
|
assert_equal QuoVadis::Log::PASSWORD_RESET, QuoVadis::Log.first.action
|
171
180
|
assert_equal QuoVadis::Log::LOGIN_SUCCESS, log.action
|
172
181
|
end
|
173
182
|
|
174
183
|
|
175
184
|
test 'account.confirmation' do
|
176
|
-
|
177
|
-
|
178
|
-
|
185
|
+
QuoVadis.accounts_require_confirmation true
|
186
|
+
|
187
|
+
assert_emails 1 do
|
188
|
+
login
|
189
|
+
assert_redirected_to '/articles/secret'
|
190
|
+
follow_redirect!
|
191
|
+
assert_redirected_to '/confirm'
|
192
|
+
follow_redirect!
|
179
193
|
end
|
180
|
-
|
181
|
-
|
194
|
+
|
195
|
+
assert_difference 'QuoVadis::Log.count' do
|
196
|
+
post quo_vadis.confirm_path(otp: extract_code_from_email)
|
197
|
+
end
|
198
|
+
|
199
|
+
assert_equal QuoVadis::Log::ACCOUNT_CONFIRMATION, log.action
|
200
|
+
ensure
|
201
|
+
QuoVadis.accounts_require_confirmation false
|
182
202
|
end
|
183
203
|
|
184
204
|
|
@@ -241,4 +261,8 @@ class LoggingTest < IntegrationTest
|
|
241
261
|
end
|
242
262
|
end
|
243
263
|
|
264
|
+
def extract_code_from_email
|
265
|
+
ActionMailer::Base.deliveries.last.decoded[%r{\d{6}}, 0]
|
266
|
+
end
|
267
|
+
|
244
268
|
end
|