Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
067ef37
changelog: User-Facing Improvements, authentication improvements, add…
jmdembe Jun 12, 2023
31e4ac2
add view, copy to skeleton view
jmdembe Jun 12, 2023
919dfec
additional translations, layout of view
jmdembe Jun 13, 2023
10b4ea6
more layout work
jmdembe Jun 14, 2023
cc9af87
add redirect for backup codes setup
jmdembe Jun 14, 2023
d55e69c
protect from going back to screen if authenticated
jmdembe Jun 14, 2023
a879543
Merge branch 'main' into LG-9951-backup-codes-warning
jmdembe Jun 15, 2023
2cf1599
change redirect to happen in confirmation screen on skip
jmdembe Jun 15, 2023
7c9d401
fix logic to only redirect for backup code setup
jmdembe Jun 15, 2023
cb7669a
add test for skip for now option
jmdembe Jun 16, 2023
6d4293e
change redirect to second mfa path
jmdembe Jun 20, 2023
c21040b
fix multiple mfa sign up spec
jmdembe Jun 20, 2023
1058d60
edit sign up spec test
jmdembe Jun 20, 2023
fe7aa37
Merge branch 'main' into LG-9951-backup-codes-warning
jmdembe Jun 20, 2023
e077013
lint fix
jmdembe Jun 20, 2023
5d1e31f
Merge branch 'main' into LG-9951-backup-codes-warning
jmdembe Jun 21, 2023
ec372bc
edit test for redirect after backup code setup
jmdembe Jun 21, 2023
0460e74
fix error test wrt app name; edit translation
jmdembe Jun 21, 2023
97e2be0
dynamically load app name in text
jmdembe Jun 21, 2023
ec14b02
edit test for MFA cta banner
jmdembe Jun 21, 2023
95eca8c
WIP: check for setup and other codes setup
jmdembe Jun 21, 2023
7079f51
fix bug to redirect when method is already set up
jmdembe Jun 22, 2023
1276149
Merge branch 'main' into LG-9951-backup-codes-warning
jmdembe Jun 22, 2023
67f05a2
add good test
jmdembe Jun 22, 2023
e46983b
remove method
jmdembe Jun 22, 2023
ddea7a3
remove unused method
jmdembe Jun 23, 2023
70787a1
remove test
jmdembe Jun 23, 2023
e7ca55c
Merge branch 'main' into LG-9951-backup-codes-warning
jmdembe Jun 23, 2023
c4031e1
Address PR comment: refactor method and remove extra method
jmdembe Jun 23, 2023
d0e16be
add tests
jmdembe Jun 23, 2023
220480f
lint fix
jmdembe Jun 23, 2023
6b3c18a
remove unnecessary margins and borders
jmdembe Jun 26, 2023
6a96a38
adjust margins a little bit
jmdembe Jun 26, 2023
33b1ce6
Update app/views/users/backup_code_setup/confirm_backup_codes.erb
jmdembe Jun 26, 2023
79c527a
rename confirm backup codes view
jmdembe Jun 26, 2023
e816c33
lint fix
jmdembe Jun 26, 2023
876ddf2
set up buttons in grid
jmdembe Jun 27, 2023
49bfd12
Update app/views/users/backup_code_setup/confirm_backup_codes.html.erb
jmdembe Jun 28, 2023
25b2628
lint fix
jmdembe Jun 28, 2023
a0a051d
Update spec/features/users/sign_up_spec.rb
jmdembe Jun 28, 2023
c2d4525
add helper for backup code confirmation click
jmdembe Jun 28, 2023
1fc132c
remove uneeded spec
jmdembe Jun 29, 2023
4ed14c3
Merge branch 'main' into LG-9951-backup-codes-warning
jmdembe Jun 29, 2023
a25d75d
update test
jmdembe Jun 29, 2023
0ce10e0
Merge branch 'main' into LG-9951-backup-codes-warning
jmdembe Jun 29, 2023
3ef970a
fix page footer link
jmdembe Jun 29, 2023
cb05246
fix button width
jmdembe Jun 29, 2023
8216d8a
remove uneeded class from sass file
jmdembe Jun 29, 2023
d838c59
make buttons full width
jmdembe Jun 30, 2023
42452c2
lint fixes
jmdembe Jun 30, 2023
c887445
Merge branch 'main' into LG-9951-backup-codes-warning
jmdembe Jun 30, 2023
6d75996
Update app/views/users/backup_code_setup/confirm_backup_codes.html.erb
jmdembe Jun 30, 2023
c8883ef
Update config/locales/two_factor_authentication/en.yml
jmdembe Jun 30, 2023
7e8c352
add html to key
jmdembe Jun 30, 2023
d188217
fix english key
jmdembe Jun 30, 2023
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
14 changes: 13 additions & 1 deletion app/controllers/mfa_confirmation_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def skip
pii_like_keypaths: [[:mfa_method_counts, :phone]],
success: true,
)
redirect_to after_mfa_setup_path
redirect_to after_skip_path
end

def new
Expand Down Expand Up @@ -74,4 +74,16 @@ def handle_max_password_attempts_reached
def mfa_context
@mfa_context ||= MfaContext.new(current_user)
end

def after_skip_path
if backup_code_confirmation_needed?
confirm_backup_codes_path
else
after_mfa_setup_path
end
end

def backup_code_confirmation_needed?
!MfaPolicy.new(current_user).multiple_factors_enabled? && user_backup_codes_configured?
end
end
2 changes: 2 additions & 0 deletions app/controllers/users/backup_code_setup_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ def reminder
flash.now[:success] = t('notices.authenticated_successfully')
end

def confirm_backup_codes; end

private

def track_backup_codes_created
Expand Down
37 changes: 37 additions & 0 deletions app/views/users/backup_code_setup/confirm_backup_codes.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<% title t('titles.backup_codes') %>

<%= render PageHeadingComponent.new.with_content(t('titles.backup_codes')) %>

<p>
<%= t('two_factor_authentication.backup_codes.warning_html') %>
</p>

<p>
<%= t('two_factor_authentication.backup_codes.instructions', app_name: APP_NAME) %>
</p>

<div class="grid-row margin-top-5">
<div class="tablet:grid-col-6">
<%= render ButtonComponent.new(
action: ->(**tag_options, &block) { link_to(sign_up_completed_path, **tag_options, &block) },
big: true,
full_width: true,
class: 'margin-bottom-205',
).with_content(t('two_factor_authentication.backup_codes.saved_backup_codes')) %>
</div>
</div>
<div class="grid-row">
<div class="tablet:grid-col-6">
<%= render ButtonComponent.new(
action: ->(**tag_options, &block) { link_to(backup_code_regenerate_path, **tag_options, &block) },
big: true,
full_width: true,
outline: true,
).with_content(t('two_factor_authentication.backup_codes.new_backup_codes')) %>
</div>
</div>

<%= render PageFooterComponent.new do %>
<%= link_to t('two_factor_authentication.backup_codes.add_another_authentication_option'), second_mfa_setup_path %>
<% end %>

1 change: 1 addition & 0 deletions config/locales/titles/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ en:
account_locked: Account temporarily locked
add_info:
phone: Add a phone number
backup_codes: Don’t lose your backup codes
confirmations:
delete: Please confirm
new: Resend confirmation instructions for your account
Expand Down
1 change: 1 addition & 0 deletions config/locales/titles/es.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ es:
account_locked: Cuenta bloqueada temporalmente
add_info:
phone: Agregar un número de teléfono
backup_codes: No pierda sus códigos de respaldo
confirmations:
delete: Por favor confirmar
new: Reenviar instrucciones de confirmación de su cuenta
Expand Down
1 change: 1 addition & 0 deletions config/locales/titles/fr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ fr:
account_locked: Compte temporairement verrouillé
add_info:
phone: Ajouter un numéro de téléphone
backup_codes: Ne perdez pas vos codes de sauvegarde
confirmations:
delete: Veuillez confirmer
new: Envoyer les instructions de confirmation pour votre compte
Expand Down
10 changes: 10 additions & 0 deletions config/locales/two_factor_authentication/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@ en:
backup_code_header_text: Enter your backup security code
backup_code_prompt: You can use this security code once. After you enter it,
you’ll need to use a new key.
backup_codes:
add_another_authentication_option: '‹ Add another authentication option'
Comment thread
aduth marked this conversation as resolved.
instructions: If you don’t have access to another device, keep your backup codes
safe. If you lose your backup codes, you won’t be able to sign into
%{app_name}.
new_backup_codes: I need new backup&nbsp;codes
saved_backup_codes: I’ve saved my backup codes
warning_html: <strong>You’ve only set up backup codes on your account.
</strong>If you have access to another device, such as a phone, protect
your account with another authentication method.
choose_another_option: '‹ Choose another option'
header_text: Enter your one-time code
important_alert_icon: important alert icon
Expand Down
10 changes: 10 additions & 0 deletions config/locales/two_factor_authentication/es.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@ es:
backup_code_header_text: Ingrese su código de seguridad de respaldo
backup_code_prompt: Puede utilizar este código de seguridad una vez. Después de
ingresarlo, deberá usar una nueva clave.
backup_codes:
add_another_authentication_option: '‹ Añada otra opción de autenticación'
instructions: Si no tiene acceso a otro dispositivo, guarde bien sus códigos de
respaldo. No podrá iniciar sesión en %{app_name} si pierde sus códigos
de respaldo.
new_backup_codes: Necesito nuevos códigos de respaldo
saved_backup_codes: Ya guardé mis códigos de respaldo
warning_html: <strong>Solo ha configurado códigos de respaldo en su cuenta.
</strong>Si tiene acceso a otro dispositivo, como un celular, proteja su
cuenta mediante otro método de autenticación.
choose_another_option: '‹ Elige otra opción'
header_text: Introduzca su código único
important_alert_icon: ícono de aviso importante
Expand Down
11 changes: 11 additions & 0 deletions config/locales/two_factor_authentication/fr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,17 @@ fr:
backup_code_header_text: Entrez votre code de sécurité de secours
backup_code_prompt: Vous pouvez utiliser ce code de sécurité une fois. Après
l’avoir entré, vous devrez utiliser une nouvelle clé.
backup_codes:
add_another_authentication_option: '‹ Ajouter une autre option d’authentification'
instructions: Si vous n’avez pas accès à un autre appareil, conservez vos codes
de sauvegarde en lieu sûr. Si vous perdez vos codes de sauvegarde, vous
ne pourrez plus vous connecter à %{app_name}.
new_backup_codes: J’ai besoin de nouveaux codes de sauvegarde
saved_backup_codes: J’ai sauvegardé mes codes de sauvegarde
warning_html: <strong>Vous n’avez configuré que des codes de sauvegarde sur
votre compte. </strong>Si vous avez accès à un autre appareil, tel qu’un
téléphone, protégez votre compte à l’aide d’une autre méthode
d’authentification.
choose_another_option: '‹ Choisissez une autre option'
header_text: Entrez votre code à usage unique
important_alert_icon: Icône d’alerte importante
Expand Down
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@
get '/backup_code_delete' => 'users/backup_code_setup#confirm_delete'
get '/backup_code_create' => 'users/backup_code_setup#confirm_create'
delete '/backup_code_delete' => 'users/backup_code_setup#delete'
get '/confirm_backup_codes' => 'users/backup_code_setup#confirm_backup_codes'

get '/piv_cac_delete' => 'users/piv_cac_setup#confirm_delete'
get '/auth_app_delete' => 'users/totp_setup#confirm_delete'
Expand Down
28 changes: 27 additions & 1 deletion spec/features/multi_factor_authentication/mfa_cta_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,38 @@
it 'displays a banner after configuring a single MFA method' do
visit_idp_from_sp_with_ial1(:oidc)
user = sign_up_and_set_password
select_2fa_option('backup_code')
select_2fa_option('phone')
click_continue

fill_in :new_phone_form_phone, with: '3015551212'
click_send_one_time_code

fill_in_code_with_last_phone_otp
click_submit_default

expect(page).to have_content(t('notices.phone_confirmed'))

click_button t('mfa.skip')
expect(page).to have_current_path(sign_up_completed_path)
expect(MfaPolicy.new(user).multiple_factors_enabled?).to eq false
expect(page).to have_content(t('mfa.second_method_warning.text'))
end

it 'displays a banner after confirming that backup codes are saved' do
visit_idp_from_sp_with_ial1(:oidc)
user = sign_up_and_set_password
select_2fa_option('backup_code')
click_continue

click_button t('mfa.skip')
expect(MfaPolicy.new(user).multiple_factors_enabled?).to eq false
expect(page).to have_current_path(confirm_backup_codes_path)

acknowledge_backup_code_confirmation

expect(page).to have_content(t('mfa.second_method_warning.text'))
end

it 'does not display a banner after configuring multiple MFA methods' do
visit_idp_from_sp_with_ial1(:oidc)
sign_up_and_set_password
Expand All @@ -41,6 +64,9 @@

set_up_mfa_with_backup_codes
click_button t('mfa.skip')

expect(page).to have_current_path(confirm_backup_codes_path)
acknowledge_backup_code_confirmation
click_link(t('mfa.second_method_warning.link'))
expect(page).to have_current_path(second_mfa_setup_path)
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,18 +58,17 @@
end
end

it 'directs backup code only users to the SP during sign up' do
it 'directs to SP after backup code confirmation' do
visit_idp_from_sp_with_ial1(:oidc)
sign_up_and_set_password
select_2fa_option('backup_code')
click_continue
skip_second_mfa_prompt

expect(page).to have_current_path(sign_up_completed_path)
expect(page).to have_current_path(confirm_backup_codes_path)
acknowledge_backup_code_confirmation

click_agree_and_continue
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if the click_agree_and_continue was meaningful in testing anything previously, but we lost it in the revisions here. Should it be added back?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on what I understood, it did not seem to be meaningful. If I am missing something, I would be more than happy to include it back in


expect(current_url).to start_with('http://localhost:7654/auth/result')
expect(current_path).to eq(sign_up_completed_path)
end

context 'when the user needs a backup code reminder' do
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,19 +80,20 @@

expect(current_path).to eq authentication_methods_setup_path

click_2fa_option('backup_code')
click_2fa_option('phone')

click_continue

expect(current_path).to eq backup_code_setup_path
expect(page).
to have_content t('titles.phone_setup')

click_continue

expect(page).to have_link(t('components.download_button.label'))

click_continue
fill_in 'new_phone_form_phone', with: '301-555-1212'
click_send_one_time_code

expect(page).to have_content(t('notices.backup_codes_configured'))
fill_in_code_with_last_phone_otp
click_submit_default

expect(page).to have_current_path(
auth_method_confirmation_path,
Expand Down Expand Up @@ -136,6 +137,42 @@
end
end

context 'when backup codes are the only selected option' do
before do
sign_in_before_2fa

expect(current_path).to eq authentication_methods_setup_path

click_2fa_option('backup_code')

click_continue

expect(current_path).to eq backup_code_setup_path

click_continue

expect(page).to have_link(t('components.download_button.label'))

click_continue

expect(page).to have_current_path(
auth_method_confirmation_path,
)

click_button t('mfa.skip')
end

it 'goes to the next page after user confirms that they have saved their backup codes' do
acknowledge_backup_code_confirmation
expect(page).to have_current_path account_path
end

it 'regenerates backup codes path if a user clicks that they need new backup codes' do
click_link t('two_factor_authentication.backup_codes.new_backup_codes')
expect(page).to have_current_path backup_code_regenerate_path
end
end

def click_2fa_option(option)
find("label[for='two_factor_options_form_selection_#{option}']").click
end
Expand Down
13 changes: 12 additions & 1 deletion spec/features/users/sign_up_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,6 @@ def clipboard_text
set_up_2fa_with_backup_codes
skip_second_mfa_prompt

expect(page).to have_current_path account_path
visit add_phone_path
expect(page).to have_current_path add_phone_path
end
Expand Down Expand Up @@ -386,4 +385,16 @@ def clipboard_text
select_2fa_option('piv_cac')
expect(page).to_not have_content(t('two_factor_authentication.piv_cac_fallback.question'))
end

it 'allows a user to sign up with backup codes and add methods after without reauthentication' do
sign_in_user
set_up_2fa_with_backup_codes
skip_second_mfa_prompt

acknowledge_backup_code_confirmation

expect(page).to have_current_path account_path
visit add_phone_path
expect(page).to have_current_path add_phone_path
end
end
4 changes: 4 additions & 0 deletions spec/support/features/session_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -712,5 +712,9 @@ def expect_branded_experience
# Check for branded experience as being the header containing the Login.gov and partner logos
expect(page).to have_css(".page-header--basic img[alt='#{APP_NAME}'] ~ img")
end

def acknowledge_backup_code_confirmation
click_on t('two_factor_authentication.backup_codes.saved_backup_codes')
end
end
end