[SPC] Add user activation to SPC tests (#33695)
* [SPC] Add user activation to SPC tests
Also adds a test that enforces that SPC must have user activation to be called.
* Fix test
diff --git a/secure-payment-confirmation/authentication-accepted.https.html b/secure-payment-confirmation/authentication-accepted.https.html
index 2e9611f..1677de3 100644
--- a/secure-payment-confirmation/authentication-accepted.https.html
+++ b/secure-payment-confirmation/authentication-accepted.https.html
@@ -42,6 +42,7 @@
}
}], PAYMENT_DETAILS);
+ await test_driver.bless('user activation');
const responsePromise = request.show();
const response = await responsePromise;
diff --git a/secure-payment-confirmation/authentication-cross-origin.sub.https.html b/secure-payment-confirmation/authentication-cross-origin.sub.https.html
index a9be91b..efdb798 100644
--- a/secure-payment-confirmation/authentication-cross-origin.sub.https.html
+++ b/secure-payment-confirmation/authentication-cross-origin.sub.https.html
@@ -47,6 +47,7 @@
}
}], PAYMENT_DETAILS);
+ await test_driver.bless('user activation');
const responsePromise = request.show();
const response = await responsePromise;
diff --git a/secure-payment-confirmation/authentication-icon-data-url.https.html b/secure-payment-confirmation/authentication-icon-data-url.https.html
index b4c01f3..dbdf666 100644
--- a/secure-payment-confirmation/authentication-icon-data-url.https.html
+++ b/secure-payment-confirmation/authentication-icon-data-url.https.html
@@ -43,6 +43,7 @@
}
}], PAYMENT_DETAILS);
+ await test_driver.bless('user activation');
const responsePromise = request.show();
const response = await responsePromise;
diff --git a/secure-payment-confirmation/authentication-in-iframe.sub.https.html b/secure-payment-confirmation/authentication-in-iframe.sub.https.html
index b3a01e3..951b540 100644
--- a/secure-payment-confirmation/authentication-in-iframe.sub.https.html
+++ b/secure-payment-confirmation/authentication-in-iframe.sub.https.html
@@ -36,7 +36,7 @@
// Wait for the iframe to load.
const readyPromise = new Promise(resolve => {
window.addEventListener('message', function handler(evt) {
- if (evt.source === frame.contentWindow) {
+ if (evt.source === frame.contentWindow && evt.data.type == 'loaded') {
window.removeEventListener('message', handler);
resolve(evt.data);
@@ -50,7 +50,7 @@
// race.
const resultPromise = new Promise(resolve => {
window.addEventListener('message', function handler(evt) {
- if (evt.source === frame.contentWindow) {
+ if (evt.source === frame.contentWindow && evt.data.type == 'spc_result') {
// We're done with the child iframe now.
document.body.removeChild(frame);
window.removeEventListener('message', handler);
diff --git a/secure-payment-confirmation/authentication-invalid-icon.https.html b/secure-payment-confirmation/authentication-invalid-icon.https.html
index 8987c7b..84c629f 100644
--- a/secure-payment-confirmation/authentication-invalid-icon.https.html
+++ b/secure-payment-confirmation/authentication-invalid-icon.https.html
@@ -42,6 +42,7 @@
},
}
}], PAYMENT_DETAILS);
+ await test_driver.bless('user activation');
await promise_rejects_dom(t, "NotSupportedError", request.show());
// Now try an icon that cannot be decoded.
@@ -59,6 +60,7 @@
},
}
}], PAYMENT_DETAILS);
+ await test_driver.bless('user activation');
await promise_rejects_dom(t, "NotSupportedError", request.show());
}, 'SPC authentication with an invalid icon');
@@ -96,6 +98,7 @@
}
}], PAYMENT_DETAILS);
+ await test_driver.bless('user activation');
const responsePromise = request.show();
const response = await responsePromise;
await response.complete('success');
diff --git a/secure-payment-confirmation/authentication-rejected.https.html b/secure-payment-confirmation/authentication-rejected.https.html
index 4973748..444733b 100644
--- a/secure-payment-confirmation/authentication-rejected.https.html
+++ b/secure-payment-confirmation/authentication-rejected.https.html
@@ -43,6 +43,7 @@
}
}], PAYMENT_DETAILS);
+ await test_driver.bless('user activation');
return promise_rejects_dom(t, "NotAllowedError", request.show());
}, 'Rejected SPC authentication');
</script>
diff --git a/secure-payment-confirmation/authentication-requires-user-activation.https.html b/secure-payment-confirmation/authentication-requires-user-activation.https.html
new file mode 100644
index 0000000..6519086
--- /dev/null
+++ b/secure-payment-confirmation/authentication-requires-user-activation.https.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Test for the 'secure-payment-confirmation' payment method authentication - requires user activation</title>
+<link rel="help" href="https://w3c.github.io/secure-payment-confirmation/sctn-authentication">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script src="utils.sub.js"></script>
+<script>
+'use strict';
+
+promise_test(async t => {
+ const authenticator = await window.test_driver.add_virtual_authenticator(
+ AUTHENTICATOR_OPTS);
+ t.add_cleanup(() => {
+ return window.test_driver.remove_virtual_authenticator(authenticator);
+ });
+
+ await window.test_driver.set_spc_transaction_mode("autoaccept");
+ t.add_cleanup(() => {
+ return window.test_driver.set_spc_transaction_mode("none");
+ });
+
+
+ const credential = await createCredential();
+
+ const challenge = 'server challenge';
+ const payeeOrigin = 'https://merchant.com';
+ const displayName = 'Troycard ***1234';
+ const request = new PaymentRequest([{
+ supportedMethods: 'secure-payment-confirmation',
+ data: {
+ credentialIds: [credential.rawId],
+ challenge: Uint8Array.from(challenge, c => c.charCodeAt(0)),
+ rpId: window.location.hostname,
+ payeeOrigin,
+ timeout: 60000,
+ instrument: {
+ displayName,
+ icon: ICON_URL,
+ },
+ }
+ }], PAYMENT_DETAILS);
+
+ return promise_rejects_dom(t, "SecurityError", request.show());
+}, 'SPC authentication not allowed without a user activation');
+</script>
diff --git a/secure-payment-confirmation/resources/iframe-authenticate.html b/secure-payment-confirmation/resources/iframe-authenticate.html
index 067cb58..e6a634f 100644
--- a/secure-payment-confirmation/resources/iframe-authenticate.html
+++ b/secure-payment-confirmation/resources/iframe-authenticate.html
@@ -1,6 +1,8 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>SPC Authentication iframe</title>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
<script src="../utils.sub.js"></script>
<script>
'use strict';
@@ -32,6 +34,8 @@
}
}], PAYMENT_DETAILS);
+ test_driver.set_test_context(window.parent);
+ await test_driver.bless('user activation');
const responsePromise = request.show();
const response = await responsePromise;
@@ -42,9 +46,9 @@
// Let our parent know the results. Some WebAuthn fields cannot be cloned, so
// we have to do some teardown ourselves.
const clientDataJSON = JSON.parse(arrayBufferToString(cred.response.clientDataJSON))
- window.parent.postMessage({ id: cred.id, clientDataJSON }, '*');
+ window.parent.postMessage({ type: 'spc_result', id: cred.id, clientDataJSON }, '*');
});
// Now let our parent know that we are ready to receive the credential ID.
-window.parent.postMessage(true, '*');
+window.parent.postMessage({ type: 'loaded' }, '*');
</script>