From 2c2de0d548a572d489cfb3a1acefea2a8e44c96b Mon Sep 17 00:00:00 2001 From: Logan Rosen Date: Wed, 26 Aug 2026 20:37:54 -0400 Subject: [PATCH] Bug 2059948 - Add Duo recovery-code regression coverage Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../rst/using/two-factor-authentication.rst | 8 +-- qa/t/2_test_login_duo.t | 49 ++++++++++++++++++- 2 files changed, 51 insertions(+), 6 deletions(-) diff --git a/docs/en/rst/using/two-factor-authentication.rst b/docs/en/rst/using/two-factor-authentication.rst index 8a128ac573..ea4b119a45 100644 --- a/docs/en/rst/using/two-factor-authentication.rst +++ b/docs/en/rst/using/two-factor-authentication.rst @@ -188,10 +188,10 @@ Do not store recovery codes with your password or on the device that provides your second factor. If you are unsure whether your codes remain private, generate and print a new set. -BMO recovery codes cannot replace a Duo verification, even though the 2FA -preferences page offers Duo users the recovery-code generator. Duo users should -configure more than one authentication method in Duo and contact `Mozilla -Service Desk`_ if none of those methods are available. +BMO does not offer its recovery-code generator for Duo accounts because BMO +recovery codes cannot replace a Duo verification. Duo users should configure +more than one authentication method in Duo and contact `Mozilla Service Desk`_ +if none of those methods are available. .. _two-factor-troubleshooting: diff --git a/qa/t/2_test_login_duo.t b/qa/t/2_test_login_duo.t index f991b54b8a..dfdd3b8eef 100644 --- a/qa/t/2_test_login_duo.t +++ b/qa/t/2_test_login_duo.t @@ -32,7 +32,8 @@ $sel->title_is('User Preferences'); $sel->click_ok('mfa-select-duo'); $sel->type_ok('mfa-duo-user', $config->{admin_user_login}); $sel->type_ok('mfa-password', $config->{admin_user_passwd}); -$sel->click_ok('update'); +$sel->driver->find_element('//form[@name="userprefsform"]')->submit; +$sel->wait_for_page_to_load(WAIT_TIME); $sel->click_ok('//a[contains(text(),"Redirect Back")]', 'Click Duo Security verification'); $sel->title_is('User Preferences'); @@ -40,10 +41,54 @@ $sel->is_text_present_ok( 'The changes to your two-factor authentication have been saved', 'Duo successfully enabled'); +ok( + !$sel->is_element_present('mfa-recovery'), + 'Recovery code generation is not offered for Duo' +); + +# A forged recovery request must fail before opening the Duo prompt. +$sel->driver->execute_script( + q{document.getElementById('mfa-auth-container').style.display = 'block';} +); +$sel->type_ok('mfa-password', $config->{admin_user_passwd}); +$sel->driver->execute_script(q{ + const source = document.forms.userprefsform; + const form = document.createElement('form'); + form.method = 'post'; + form.action = source.action; + + [ + ['tab', 'mfa'], + ['token', source.elements.token.value], + ['dosave', '1'], + ['mfa_action', 'recovery'], + ['mfa', 'TOTP'], + ['password', source.elements.password.value], + ].forEach(([name, value]) => { + const input = document.createElement('input'); + input.type = 'hidden'; + input.name = name; + input.value = value; + form.appendChild(input); + }); + + document.body.appendChild(form); + form.submit(); +}); +sleep(2); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is('Duo Security Error'); +$sel->is_text_present_ok( + 'Recovery codes are not available when using Duo Security', + 'Forged Duo recovery request rejected' +); + # Disable Duo for the admin user +$sel->open_ok('/userprefs.cgi?tab=mfa'); $sel->click_ok('mfa-disable'); $sel->type_ok('mfa-password', $config->{admin_user_passwd}); -$sel->click_ok('update'); +$sel->driver->find_element('//form[@name="userprefsform"]')->submit; +$sel->wait_for_page_to_load(WAIT_TIME); $sel->click_ok('//a[contains(text(),"Redirect Back")]', 'Click Duo Security verification'); $sel->title_is('User Preferences');