browser_webauthn_conditional_mediation.js (5404B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 "use strict"; 6 7 const TEST_URL = "https://example.com"; 8 9 let gAuthenticatorId = add_virtual_authenticator(); 10 let gExpectNotAllowedError = expectError("NotAllowed"); 11 let gExpectAbortError = expectError("Abort"); 12 let gPendingConditionalGetSubject = "webauthn:conditional-get-pending"; 13 let gWebAuthnService = Cc["@mozilla.org/webauthn/service;1"].getService( 14 Ci.nsIWebAuthnService 15 ); 16 17 add_task(async function test_webauthn_modal_request_cancels_conditional_get() { 18 // Open a new tab. 19 let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL); 20 21 let browser = tab.linkedBrowser.browsingContext.embedderElement; 22 let browsingContextId = browser.browsingContext.id; 23 24 let transactionId = gWebAuthnService.hasPendingConditionalGet( 25 browsingContextId, 26 TEST_URL 27 ); 28 Assert.equal(transactionId, 0, "should not have a pending conditional get"); 29 30 let requestStarted = TestUtils.topicObserved(gPendingConditionalGetSubject); 31 32 let active = true; 33 let condPromise = promiseWebAuthnGetAssertionDiscoverable(tab, "conditional") 34 .then(arrivingHereIsBad) 35 .catch(gExpectAbortError) 36 .then(() => (active = false)); 37 38 await requestStarted; 39 40 transactionId = gWebAuthnService.hasPendingConditionalGet( 41 browsingContextId, 42 TEST_URL 43 ); 44 Assert.notEqual(transactionId, 0, "should have a pending conditional get"); 45 46 ok(active, "conditional request should still be active"); 47 48 let promptPromise = promiseNotification("webauthn-prompt-register-direct"); 49 let modalPromise = promiseWebAuthnMakeCredential(tab, "direct"); 50 51 await condPromise; 52 53 ok(!active, "conditional request should not be active"); 54 55 // Proceed through the consent prompt 56 await promptPromise; 57 PopupNotifications.panel.firstElementChild.secondaryButton.click(); 58 await modalPromise; 59 60 // Close tab. 61 await BrowserTestUtils.removeTab(tab); 62 }); 63 64 add_task(async function test_webauthn_resume_conditional_get() { 65 // Open a new tab. 66 let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL); 67 68 let browser = tab.linkedBrowser.browsingContext.embedderElement; 69 let browsingContextId = browser.browsingContext.id; 70 71 let transactionId = gWebAuthnService.hasPendingConditionalGet( 72 browsingContextId, 73 TEST_URL 74 ); 75 Assert.equal(transactionId, 0, "should not have a pending conditional get"); 76 77 let requestStarted = TestUtils.topicObserved(gPendingConditionalGetSubject); 78 79 let active = true; 80 let promise = promiseWebAuthnGetAssertionDiscoverable(tab, "conditional") 81 .then(arrivingHereIsBad) 82 .catch(gExpectNotAllowedError) 83 .then(() => (active = false)); 84 85 await requestStarted; 86 87 transactionId = gWebAuthnService.hasPendingConditionalGet(0, TEST_URL); 88 Assert.equal( 89 transactionId, 90 0, 91 "hasPendingConditionalGet should check the browsing context id" 92 ); 93 94 transactionId = gWebAuthnService.hasPendingConditionalGet( 95 browsingContextId, 96 "https://example.org" 97 ); 98 Assert.equal( 99 transactionId, 100 0, 101 "hasPendingConditionalGet should check the origin" 102 ); 103 104 transactionId = gWebAuthnService.hasPendingConditionalGet( 105 browsingContextId, 106 TEST_URL 107 ); 108 Assert.notEqual(transactionId, 0, "should have a pending conditional get"); 109 110 ok(active, "request should still be active"); 111 112 gWebAuthnService.resumeConditionalGet(transactionId); 113 await promise; 114 115 ok(!active, "request should not be active"); 116 117 // Close tab. 118 await BrowserTestUtils.removeTab(tab); 119 }); 120 121 add_task(async function test_webauthn_select_autofill_entry() { 122 // Open a new tab. 123 let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL); 124 125 // Add credentials 126 let cred1 = await addCredential(gAuthenticatorId, "example.com"); 127 let cred2 = await addCredential(gAuthenticatorId, "example.com"); 128 129 let browser = tab.linkedBrowser.browsingContext.embedderElement; 130 let browsingContextId = browser.browsingContext.id; 131 132 let transactionId = gWebAuthnService.hasPendingConditionalGet( 133 browsingContextId, 134 TEST_URL 135 ); 136 Assert.equal(transactionId, 0, "should not have a pending conditional get"); 137 138 let requestStarted = TestUtils.topicObserved(gPendingConditionalGetSubject); 139 140 let active = true; 141 let promise = promiseWebAuthnGetAssertionDiscoverable(tab, "conditional") 142 .catch(arrivingHereIsBad) 143 .then(() => (active = false)); 144 145 await requestStarted; 146 147 transactionId = gWebAuthnService.hasPendingConditionalGet( 148 browsingContextId, 149 TEST_URL 150 ); 151 Assert.notEqual(transactionId, 0, "should have a pending conditional get"); 152 153 let autoFillEntries = gWebAuthnService.getAutoFillEntries(transactionId); 154 ok( 155 autoFillEntries.length == 2 && 156 autoFillEntries[0].rpId == "example.com" && 157 autoFillEntries[1].rpId == "example.com", 158 "should have two autofill entries for example.com" 159 ); 160 161 gWebAuthnService.selectAutoFillEntry( 162 transactionId, 163 autoFillEntries[0].credentialId 164 ); 165 let result = await promise; 166 167 ok(!active, "request should not be active"); 168 169 // Remove credentials 170 gWebAuthnService.removeCredential(gAuthenticatorId, cred1); 171 gWebAuthnService.removeCredential(gAuthenticatorId, cred2); 172 173 // Close tab. 174 await BrowserTestUtils.removeTab(tab); 175 });