createcredential-cross-origin-iframe.https.sub.html (4684B)
1 <!DOCTYPE html> 2 <meta charset="utf-8"> 3 <title>WebAuthn credential.create() in a cross-origin iframe tests</title> 4 <meta name="timeout" content="long"> 5 <link rel="help" href="https://w3c.github.io/webauthn/#publickey-credentials-create-feature"> 6 <script src="/resources/testharness.js"></script> 7 <script src="/resources/testharnessreport.js"></script> 8 <script src="/resources/testdriver.js"></script> 9 <script src="/resources/testdriver-vendor.js"></script> 10 <script src=helpers.js></script> 11 <body></body> 12 <script> 13 standardSetup(function() { 14 "use strict"; 15 16 const targetOrigin = "https://{{hosts[alt][www]}}:{{ports[https][0]}}"; 17 18 // Returns a |Promise| that gets resolved with |event.data| when |window| 19 // receives a "message" event whose |event.data.type| matches the string 20 // |message_data_type|. 21 function getMessageData(message_data_type) { 22 return new Promise(resolve => { 23 function waitAndRemove(e) { 24 if (!e.data || e.data.type != message_data_type) 25 return; 26 window.removeEventListener("message", waitAndRemove); 27 resolve(e.data); 28 } 29 window.addEventListener("message", waitAndRemove); 30 }); 31 } 32 33 // Creates an iframe with the given `src` and (optional) allow attribute. 34 // Waits for the iframe to load, based on receiving a "subframe-loaded" 35 // message from the iframe. 36 async function createIframe(test, src, allow) { 37 const iframeElement = document.createElement("iframe"); 38 document.body.appendChild(iframeElement); 39 test.add_cleanup(() => { 40 iframeElement.remove(); 41 }); 42 43 if (allow !== undefined) { 44 iframeElement.allow = allow; 45 } 46 47 const loadedPromise = getMessageData("subframe-loaded"); 48 iframeElement.src = src; 49 await loadedPromise; 50 51 return iframeElement; 52 } 53 54 promise_test(async (test) => { 55 const src = `${targetOrigin}/webauthn/resources/webauthn-subframe.sub.html`; 56 const iframe = await createIframe(test, src); 57 58 const resultPromise = getMessageData("result"); 59 iframe.contentWindow.postMessage({type: "create-credential"}, {targetOrigin: targetOrigin}); 60 const data = await resultPromise; 61 62 assert_equals(data.result, "failure"); 63 assert_equals(data.error.name, "NotAllowedError"); 64 }, "create() in cross-origin iframe fails without permissions policy"); 65 66 promise_test(async (test) => { 67 const src = `${targetOrigin}/webauthn/resources/webauthn-subframe.sub.html`; 68 const iframe = await createIframe(test, src, "publickey-credentials-create"); 69 70 const resultPromise = getMessageData("result"); 71 iframe.contentWindow.postMessage({type: "create-credential", addUserActivation: false}, {targetOrigin: targetOrigin}); 72 const data = await resultPromise; 73 74 assert_equals(data.result, "failure"); 75 assert_equals(data.error.name, "NotAllowedError"); 76 }, "create() in cross-origin iframe fails with permissions policy but no user activation"); 77 78 promise_test(async (test) => { 79 const src = `${targetOrigin}/webauthn/resources/webauthn-subframe.sub.html`; 80 const iframe = await createIframe(test, src, "publickey-credentials-create"); 81 82 const resultPromise = getMessageData("result"); 83 iframe.contentWindow.postMessage({type: "create-credential", addUserActivation: true}, {targetOrigin: targetOrigin}); 84 const data = await resultPromise; 85 86 assert_equals(data.result, "success", `Expected success but got error: "${data.errorMessage}"`); 87 }, "create() in cross-origin iframe succeeds with permissions policy and user activation"); 88 89 promise_test(async (test) => { 90 const src = `${targetOrigin}/webauthn/resources/webauthn-subframe.sub.html`; 91 const iframe = await createIframe(test, src, "publickey-credentials-create"); 92 93 // For this call, we have a user activation in this main frame, but not 94 // in the iframe. That shouldn't be sufficient - the user activation has 95 // to be on the iframe itself. 96 await test_driver.bless("create credential, main frame activation"); 97 const resultPromise = getMessageData("result"); 98 iframe.contentWindow.postMessage({type: "create-credential", addUserActivation: false}, {targetOrigin: targetOrigin}); 99 const data = await resultPromise; 100 101 assert_equals(data.result, "failure"); 102 assert_equals(data.error.name, "NotAllowedError"); 103 }, "create() in cross-origin iframe requires user activation on the iframe, not the main frame"); 104 }); 105 </script>