test_webauthn_abort_signal.html (4468B)
1 <!DOCTYPE html> 2 <meta charset=utf-8> 3 <head> 4 <title>Test for aborting W3C Web Authentication request</title> 5 <script src="/tests/SimpleTest/SimpleTest.js"></script> 6 <script type="text/javascript" src="u2futil.js"></script> 7 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> 8 </head> 9 <body> 10 11 <h1>Test for aborting W3C Web Authentication request</h1> 12 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1415675">Mozilla Bug 1415675</a> 13 14 <script class="testbody" type="text/javascript"> 15 "use strict"; 16 17 function arrivingHereIsBad(aResult) { 18 ok(false, "Bad result! Received a: " + aResult); 19 } 20 21 function expectAbortError(aResult) { 22 is(aResult.code, DOMException.ABORT_ERR, "Expecting an AbortError"); 23 } 24 25 add_task(async () => { 26 // Enable USB tokens. 27 await SpecialPowers.pushPrefEnv({"set": [ 28 ["security.webauth.webauthn_enable_softtoken", false], 29 ["security.webauth.webauthn_enable_usbtoken", true], 30 ]}); 31 }); 32 33 // Start a new MakeCredential() request. 34 function requestMakeCredential(signal) { 35 let publicKey = { 36 rp: {id: document.domain, name: "none"}, 37 user: {id: new Uint8Array(), name: "none", displayName: "none"}, 38 challenge: crypto.getRandomValues(new Uint8Array(16)), 39 timeout: 5000, // the minimum timeout is actually 15 seconds 40 pubKeyCredParams: [{type: "public-key", alg: cose_alg_ECDSA_w_SHA256}], 41 }; 42 43 return navigator.credentials.create({publicKey, signal}); 44 } 45 46 // Start a new GetAssertion() request. 47 async function requestGetAssertion(signal) { 48 let newCredential = { 49 type: "public-key", 50 id: crypto.getRandomValues(new Uint8Array(16)), 51 transports: ["usb"], 52 }; 53 54 let publicKey = { 55 challenge: crypto.getRandomValues(new Uint8Array(16)), 56 timeout: 5000, // the minimum timeout is actually 15 seconds 57 rpId: document.domain, 58 allowCredentials: [newCredential] 59 }; 60 61 // Start the request, handle failures only. 62 return navigator.credentials.get({publicKey, signal}); 63 } 64 65 // Create an AbortController and abort immediately. 66 add_task(async function test_create_abortcontroller_and_abort() { 67 let ctrl = new AbortController(); 68 ctrl.abort(); 69 70 // The event shouldn't fire. 71 ctrl.signal.onabort = arrivingHereIsBad; 72 73 // MakeCredential() should abort immediately. 74 await requestMakeCredential(ctrl.signal) 75 .then(arrivingHereIsBad) 76 .catch(expectAbortError); 77 78 // GetAssertion() should abort immediately. 79 await requestGetAssertion(ctrl.signal) 80 .then(arrivingHereIsBad) 81 .catch(expectAbortError); 82 }); 83 84 // Request a new credential and abort the request. 85 add_task(async function test_request_credential_and_abort() { 86 let aborted = false; 87 let ctrl = new AbortController(); 88 89 ctrl.signal.onabort = () => { 90 ok(!aborted, "abort event fired once"); 91 aborted = true; 92 }; 93 94 // Request a new credential. 95 let request = requestMakeCredential(ctrl.signal) 96 .then(arrivingHereIsBad) 97 .catch(err => { 98 ok(aborted, "abort event was fired"); 99 expectAbortError(err); 100 }); 101 102 // Wait a tick for the statemachine to start. 103 await Promise.resolve(); 104 105 // Abort the request. 106 ok(!aborted, "request still pending"); 107 ctrl.abort(); 108 ok(aborted, "request aborted"); 109 110 // Wait for the request to terminate. 111 await request; 112 }); 113 114 // Request a new assertion and abort the request. 115 add_task(async function test_request_assertion_and_abort() { 116 let aborted = false; 117 let ctrl = new AbortController(); 118 119 ctrl.signal.onabort = () => { 120 ok(!aborted, "abort event fired once"); 121 aborted = true; 122 }; 123 124 // Request a new assertion. 125 let request = requestGetAssertion(ctrl.signal) 126 .then(arrivingHereIsBad) 127 .catch(err => { 128 ok(aborted, "abort event was fired"); 129 expectAbortError(err); 130 }); 131 132 // Wait a tick for the statemachine to start. 133 await Promise.resolve(); 134 135 // Abort the request. 136 ok(!aborted, "request still pending"); 137 ctrl.abort(); 138 ok(aborted, "request aborted"); 139 140 // Wait for the request to terminate. 141 await request; 142 }); 143 </script> 144 145 </body> 146 </html>