authentication-in-iframe.sub.https.html (5519B)
1 <!DOCTYPE html> 2 <meta charset="utf-8"> 3 <title>Test for the 'secure-payment-confirmation' payment method authentication - cross origin</title> 4 <link rel="help" href="https://w3c.github.io/secure-payment-confirmation#sctn-authentication"> 5 <script src="/resources/testharness.js"></script> 6 <script src="/resources/testharnessreport.js"></script> 7 <script src="/resources/testdriver.js"></script> 8 <script src="/resources/testdriver-vendor.js"></script> 9 <script src="utils.sub.js"></script> 10 11 <!-- This test requires a non-empty body to workaround https://github.com/web-platform-tests/wpt/issues/34563 --> 12 <body><div>Non-empty body</div></body> 13 14 <script> 15 'use strict'; 16 17 promise_test(async t => { 18 // Make sure that we are testing calling SPC in a cross-origin iframe. 19 assert_not_equals(window.location.hostname, '{{hosts[alt][]}}', 20 'This test must not be run on the alt hostname.'); 21 22 const authenticator = await window.test_driver.add_virtual_authenticator( 23 AUTHENTICATOR_OPTS); 24 t.add_cleanup(() => { 25 return window.test_driver.remove_virtual_authenticator(authenticator); 26 }); 27 28 await window.test_driver.set_spc_transaction_mode('autoAccept'); 29 t.add_cleanup(() => { 30 return window.test_driver.set_spc_transaction_mode('none'); 31 }); 32 33 const credential = await createCredential(); 34 35 const frame = document.createElement('iframe'); 36 frame.allow = 'payment'; 37 frame.src = 'https://{{hosts[alt][]}}:{{ports[https][0]}}' + 38 '/secure-payment-confirmation/resources/iframe-authenticate.html'; 39 40 // Wait for the iframe to load. 41 const readyPromise = new Promise(resolve => { 42 window.addEventListener('message', function handler(evt) { 43 if (evt.source === frame.contentWindow && evt.data.type == 'loaded') { 44 window.removeEventListener('message', handler); 45 46 resolve(evt.data); 47 } 48 }); 49 }); 50 document.body.appendChild(frame); 51 await readyPromise; 52 53 // Setup the result promise before triggering authentication, to avoid a 54 // race. 55 const resultPromise = new Promise(resolve => { 56 window.addEventListener('message', function handler(evt) { 57 if (evt.source === frame.contentWindow && evt.data.type == 'spc_result') { 58 // We're done with the child iframe now. 59 document.body.removeChild(frame); 60 window.removeEventListener('message', handler); 61 62 resolve(evt.data); 63 } 64 }); 65 }); 66 67 const rpId = window.location.hostname; 68 frame.contentWindow.postMessage([credential.rawId, rpId], '*'); 69 70 const result = await resultPromise; 71 72 assert_not_own_property(result, 'error'); 73 74 assert_equals(result.id, credential.id); 75 assert_equals(result.clientDataJSON.origin, 'https://{{hosts[alt][]}}:{{ports[https][0]}}'); 76 assert_equals(result.clientDataJSON.payment.topOrigin, window.location.origin); 77 // The credential was created in this frame, and so we are the rp. 78 assert_equals(result.clientDataJSON.payment.rpId, window.location.hostname); 79 // The payeeOrigin should be unrelated to what the origin and topOrigin are. 80 assert_equals(result.clientDataJSON.payment.payeeOrigin, 'https://merchant.com'); 81 }, 'SPC authentication ceremony in cross-origin iframe'); 82 83 promise_test(async t => { 84 // Make sure that we are testing calling SPC in a cross-origin iframe. 85 assert_not_equals(window.location.hostname, '{{hosts[alt][]}}', 86 'This test must not be run on the alt hostname.'); 87 88 const authenticator = await window.test_driver.add_virtual_authenticator( 89 AUTHENTICATOR_OPTS); 90 t.add_cleanup(() => { 91 return window.test_driver.remove_virtual_authenticator(authenticator); 92 }); 93 94 await window.test_driver.set_spc_transaction_mode('autoAccept'); 95 t.add_cleanup(() => { 96 return window.test_driver.set_spc_transaction_mode('none'); 97 }); 98 99 const credential = await createCredential(); 100 101 const frame = document.createElement('iframe'); 102 // This iframe does *not* have a payments permission specified on it, and so 103 // should not allow SPC authentication. 104 frame.src = 'https://{{hosts[alt][]}}:{{ports[https][0]}}' + 105 '/secure-payment-confirmation/resources/iframe-authenticate.html'; 106 107 // Wait for the iframe to load. 108 const readyPromise = new Promise(resolve => { 109 window.addEventListener('message', function handler(evt) { 110 if (evt.source === frame.contentWindow && evt.data.type == 'loaded') { 111 window.removeEventListener('message', handler); 112 113 resolve(evt.data); 114 } 115 }); 116 }); 117 document.body.appendChild(frame); 118 await readyPromise; 119 120 // Setup the result promise before triggering authentication, to avoid a 121 // race. 122 const resultPromise = new Promise(resolve => { 123 window.addEventListener('message', function handler(evt) { 124 if (evt.source === frame.contentWindow && evt.data.type == 'spc_result') { 125 // We're done with the child iframe now. 126 document.body.removeChild(frame); 127 window.removeEventListener('message', handler); 128 129 resolve(evt.data); 130 } 131 }); 132 }); 133 134 const rpId = window.location.hostname; 135 frame.contentWindow.postMessage([credential.rawId, rpId], '*'); 136 137 const result = await resultPromise; 138 139 assert_own_property(result, 'error'); 140 assert_true(result.error instanceof DOMException); 141 assert_equals(result.error.name, 'SecurityError'); 142 143 assert_not_own_property(result, 'id'); 144 assert_not_own_property(result, 'clientDataJSON'); 145 }, 'SPC authentication ceremony in cross-origin iframe without payment permission'); 146 </script>