Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions app/controllers/concerns/remember_device_concern.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
module RememberDeviceConcern
extend ActiveSupport::Concern

def save_user_opted_remember_device_pref
cookies.encrypted[:user_opted_remember_device_preference] = params[:remember_device]
def save_user_opted_remember_device_pref(remember_device_preference)
cookies.encrypted[:user_opted_remember_device_preference] = remember_device_preference
end

def save_remember_device_preference
return if params[:remember_device] != '1' && params[:remember_device] != 'true'
def save_remember_device_preference(remember_device_preference)
return if remember_device_preference != '1' && remember_device_preference != 'true'
cookies.encrypted[:remember_device] = {
value: RememberDeviceCookie.new(user_id: current_user.id, created_at: Time.zone.now).to_json,
expires: remember_device_cookie_expiration,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,9 @@ def reset_attempt_count_if_user_no_longer_locked_out
).call
end

def handle_remember_device
save_user_opted_remember_device_pref
save_remember_device_preference
def handle_remember_device_preference(remember_device_preference)
save_user_opted_remember_device_pref(remember_device_preference)
save_remember_device_preference(remember_device_preference)
end

# Method will be renamed in the next refactor.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ def handle_invalid_backup_code

def handle_result(result)
if result.success?
handle_remember_device_preference(backup_code_params[:remember_device])
handle_valid_verification_for_authentication_context(
auth_method: TwoFactorAuthenticatable::AuthMethod::BACKUP_CODE,
)
Expand All @@ -72,7 +73,7 @@ def handle_result(result)
end

def backup_code_params
params.require(:backup_code_verification_form).permit :backup_code
params.require(:backup_code_verification_form).permit(:backup_code, :remember_device)
end

def handle_valid_backup_code
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def create
result = otp_verification_form.submit
post_analytics(result)
if result.success?
handle_remember_device
handle_remember_device_preference(params[:remember_device])

if UserSessionContext.confirmation_context?(context)
handle_valid_confirmation_otp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def create
handle_valid_verification_for_authentication_context(
auth_method: TwoFactorAuthenticatable::AuthMethod::TOTP,
)
handle_remember_device
handle_remember_device_preference(params[:remember_device])
redirect_to after_sign_in_path_for(current_user)
else
handle_invalid_otp(context: context, type: 'totp')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def handle_valid_webauthn
auth_method: TwoFactorAuthenticatable::AuthMethod::WEBAUTHN,
)
end
handle_remember_device
handle_remember_device_preference(params[:remember_device])
redirect_to after_sign_in_path_for(current_user)
end

Expand Down
2 changes: 1 addition & 1 deletion app/controllers/users/totp_setup_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ def process_valid_code
handle_valid_verification_for_confirmation_context(
auth_method: TwoFactorAuthenticatable::AuthMethod::TOTP,
)
handle_remember_device
handle_remember_device_preference(params[:remember_device])
flash[:success] = t('notices.totp_configured')
user_session.delete(:new_totp_secret)
redirect_to next_setup_path || after_mfa_setup_path
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/users/webauthn_setup_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ def process_valid_webauthn(form)
platform_authenticator: form.platform_authenticator?,
enabled_mfa_methods_count: mfa_user.enabled_mfa_methods_count,
)
handle_remember_device
handle_remember_device_preference(params[:remember_device])
if form.platform_authenticator?
handle_valid_verification_for_confirmation_context(
auth_method: TwoFactorAuthenticatable::AuthMethod::WEBAUTHN_PLATFORM,
Expand Down
2 changes: 1 addition & 1 deletion app/views/partials/backup_code/_entry_fields.html.erb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div class="margin-bottom-4">
<div class="margin-bottom-2">
<%= f.input attribute_name,
label: t('forms.two_factor.backup_code'),
input_html: { autocapitalize: 'none',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@
html: { autocomplete: 'off', method: :post },
) do |f| %>
<%= render 'partials/backup_code/entry_fields', f: f, attribute_name: :backup_code %>
<%= f.input(
:remember_device,
as: :boolean,
label: t('forms.messages.remember_device'),
wrapper_html: { class: 'margin-top-2' },
input_html: {
class: 'usa-checkbox__input--bordered',
checked: @presenter.remember_device_box_checked?,
},
) %>
<%= f.submit t('forms.buttons.submit.default'), class: 'display-block margin-y-5' %>
<% end %>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,36 @@
expect(subject.user_session[TwoFactorAuthenticatable::NEED_AUTHENTICATION]).to eq false
end

context 'with remember_device in the params' do
it 'saves an encrypted cookie' do
stub_sign_in_before_2fa(user)

freeze_time do
expect(cookies.encrypted[:remember_device]).to eq nil
post(
:create,
params: {
backup_code_verification_form: {
backup_code: backup_codes.first,
remember_device: '1',
},
},
)

remember_device_cookie = RememberDeviceCookie.from_json(
cookies.encrypted[:remember_device],
)
expiration_interval = IdentityConfig.store.remember_device_expiration_hours_aal_1.hours
expect(
remember_device_cookie.valid_for_user?(
user: user,
expiration_interval: expiration_interval,
),
).to eq true
end
end
end

it 'tracks the valid authentication event when there are exisitng codes' do
freeze_time do
stub_sign_in_before_2fa(user)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -321,20 +321,28 @@

context 'with remember_device in the params' do
it 'saves an encrypted cookie' do
remember_device_cookie = instance_double(RememberDeviceCookie)
allow(remember_device_cookie).to receive(:to_json).and_return('asdf1234')
allow(RememberDeviceCookie).to receive(:new).and_return(remember_device_cookie)

post(
:create,
params: {
code: subject.current_user.direct_otp,
otp_delivery_preference: 'sms',
remember_device: '1',
},
)
freeze_time do
expect(cookies.encrypted[:remember_device]).to eq nil
post(
:create,
params: {
code: subject.current_user.direct_otp,
otp_delivery_preference: 'sms',
remember_device: '1',
},
)

expect(cookies.encrypted[:remember_device]).to eq('asdf1234')
remember_device_cookie = RememberDeviceCookie.from_json(
cookies.encrypted[:remember_device],
)
expiration_interval = IdentityConfig.store.remember_device_expiration_hours_aal_1.hours
expect(
remember_device_cookie.valid_for_user?(
user: subject.current_user,
expiration_interval: expiration_interval,
),
).to eq true
end
end
end

Expand Down Expand Up @@ -674,20 +682,28 @@

context 'with remember_device in the params' do
it 'saves an encrypted cookie' do
remember_device_cookie = instance_double(RememberDeviceCookie)
allow(remember_device_cookie).to receive(:to_json).and_return('asdf1234')
allow(RememberDeviceCookie).to receive(:new).and_return(remember_device_cookie)

post(
:create,
params: {
code: subject.current_user.direct_otp,
otp_delivery_preference: 'sms',
remember_device: '1',
},
)
freeze_time do
expect(cookies.encrypted[:remember_device]).to eq nil
post(
:create,
params: {
code: subject.current_user.direct_otp,
otp_delivery_preference: 'sms',
remember_device: '1',
},
)

expect(cookies.encrypted[:remember_device]).to eq('asdf1234')
remember_device_cookie = RememberDeviceCookie.from_json(
cookies.encrypted[:remember_device],
)
expiration_interval = IdentityConfig.store.remember_device_expiration_hours_aal_1.hours
expect(
remember_device_cookie.valid_for_user?(
user: subject.current_user,
expiration_interval: expiration_interval,
),
).to eq true
end
end
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
expect(page).to \
have_content t('two_factor_authentication.login_options.backup_code_info')
visit login_two_factor_backup_code_path
uncheck(t('forms.messages.remember_device'))
fill_in :backup_code_verification_form_backup_code, with: codes[index]
click_on 'Submit'
if index == BackupCodeGenerator::NUMBER_OF_CODES - 1
Expand Down