diff options
Diffstat (limited to 'dom/u2f/tests/browser/browser_abort_visibility.js')
-rw-r--r-- | dom/u2f/tests/browser/browser_abort_visibility.js | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/dom/u2f/tests/browser/browser_abort_visibility.js b/dom/u2f/tests/browser/browser_abort_visibility.js new file mode 100644 index 0000000000..1eb915fc76 --- /dev/null +++ b/dom/u2f/tests/browser/browser_abort_visibility.js @@ -0,0 +1,137 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +const TEST_URL = + "https://example.com/browser/dom/u2f/tests/browser/tab_u2f_result.html"; + +async function assertStatus(tab, expected) { + let actual = await SpecialPowers.spawn( + tab.linkedBrowser, + [], + async function() { + return content.document.getElementById("status").value; + } + ); + is(actual, expected, "u2f request " + expected); +} + +async function waitForStatus(tab, expected) { + /* eslint-disable no-shadow */ + await SpecialPowers.spawn(tab.linkedBrowser, [[expected]], async function( + expected + ) { + return ContentTaskUtils.waitForCondition(() => { + return content.document.getElementById("status").value == expected; + }); + }); + /* eslint-enable no-shadow */ + + await assertStatus(tab, expected); +} + +function startMakeCredentialRequest(tab) { + let challenge = crypto.getRandomValues(new Uint8Array(16)); + challenge = bytesToBase64UrlSafe(challenge); + + /* eslint-disable no-shadow */ + return SpecialPowers.spawn(tab.linkedBrowser, [[challenge]], async function([ + challenge, + ]) { + let appId = content.location.origin; + let request = { version: "U2F_V2", challenge }; + + let status = content.document.getElementById("status"); + + content.u2f.register(appId, [request], [], result => { + status.value = result.errorCode ? "aborted" : completed; + }); + + status.value = "pending"; + }); + /* eslint-enable no-shadow */ +} + +function startGetAssertionRequest(tab) { + let challenge = crypto.getRandomValues(new Uint8Array(16)); + challenge = bytesToBase64UrlSafe(challenge); + + let keyHandle = crypto.getRandomValues(new Uint8Array(16)); + keyHandle = bytesToBase64UrlSafe(keyHandle); + + /* eslint-disable no-shadow */ + return SpecialPowers.spawn( + tab.linkedBrowser, + [[challenge, keyHandle]], + async function([challenge, keyHandle]) { + let appId = content.location.origin; + let key = { version: "U2F_V2", keyHandle }; + + let status = content.document.getElementById("status"); + + content.u2f.sign(appId, challenge, [key], result => { + status.value = result.errorCode ? "aborted" : completed; + }); + + status.value = "pending"; + } + ); + /* eslint-enable no-shadow */ +} + +// Test that MakeCredential() and GetAssertion() requests +// are aborted when the current tab loses its focus. +add_task(async function test_abort() { + // Enable the USB token. + Services.prefs.setBoolPref("security.webauth.u2f", true); + Services.prefs.setBoolPref( + "security.webauth.webauthn_enable_softtoken", + false + ); + Services.prefs.setBoolPref("security.webauth.webauthn_enable_usbtoken", true); + Services.prefs.setBoolPref( + "security.webauth.webauthn_enable_android_fido2", + false + ); + + // Create a new tab for the MakeCredential() request. + let tab_create = await BrowserTestUtils.openNewForegroundTab( + gBrowser, + TEST_URL + ); + + // Start the request. + await startMakeCredentialRequest(tab_create); + await assertStatus(tab_create, "pending"); + + // Open another tab and switch to it. The first will lose focus. + let tab_get = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL); + + // Start a GetAssertion() request in the second tab. That will abort the first. + await startGetAssertionRequest(tab_get); + await waitForStatus(tab_get, "pending"); + await waitForStatus(tab_create, "aborted"); + + // Start a second request in the second tab. It should remain pending. + await startGetAssertionRequest(tab_get); + await waitForStatus(tab_get, "pending"); + + // Switch back to the first tab. The second should still be pending + await BrowserTestUtils.switchTab(gBrowser, tab_create); + await assertStatus(tab_get, "pending"); + + // Switch back to the get tab. The second should remain pending + await BrowserTestUtils.switchTab(gBrowser, tab_get); + await assertStatus(tab_get, "pending"); + + // Close tabs. + BrowserTestUtils.removeTab(tab_create); + BrowserTestUtils.removeTab(tab_get); + + // Cleanup. + Services.prefs.clearUserPref("security.webauth.u2f"); + Services.prefs.clearUserPref("security.webauth.webauthn_enable_softtoken"); + Services.prefs.clearUserPref("security.webauth.webauthn_enable_usbtoken"); +}); |