Skip to content

Commit

Permalink
[SPC] Add auth-time tests using the new webdriver hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
stephenmcgruer committed Nov 15, 2021
1 parent ae48310 commit ca7ae27
Show file tree
Hide file tree
Showing 4 changed files with 177 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Test for the 'secure-payment-confirmation' payment method authentication - accepted case</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)),
payeeOrigin,
timeout: 60000,
instrument: {
displayName,
icon: ICON_URL,
},
}
}], PAYMENT_DETAILS);

const responsePromise = request.show();

const response = await responsePromise;
await response.complete('success');

const cred = response.details;
assert_equals(cred.id, credential.id);

const clientDataJSON = JSON.parse(arrayBufferToString(cred.response.clientDataJSON));
assert_equals(clientDataJSON.type, 'payment.get');
assert_equals(clientDataJSON.challenge, base64UrlEncode(challenge));
assert_equals(clientDataJSON.origin, window.location.origin);
assert_false(clientDataJSON.crossOrigin);

// Payment-specific information.
assert_equals(clientDataJSON.payment.rp, window.location.hostname);
assert_equals(clientDataJSON.payment.topOrigin, window.location.origin);
assert_equals(clientDataJSON.payment.payeeOrigin, payeeOrigin);
assert_equals(clientDataJSON.payment.total.value, PAYMENT_DETAILS.total.amount.value);
assert_equals(clientDataJSON.payment.total.currency, PAYMENT_DETAILS.total.amount.currency);
assert_equals(clientDataJSON.payment.instrument.icon, ICON_URL);
assert_equals(clientDataJSON.payment.instrument.displayName, displayName);

// TODO: Verify cred.response.signature, to validate that it covers all fields
// from clientDataJSON.
}, 'Successful SPC authentication');
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Test for the 'secure-payment-confirmation' payment method authentication - user rejects case</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("autoreject");
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)),
payeeOrigin,
timeout: 60000,
instrument: {
displayName,
icon: ICON_URL,
},
}
}], PAYMENT_DETAILS);

return promise_rejects_dom(t, "NotAllowedError", request.show());
}, 'Rejected SPC authentication');
</script>
Binary file added secure-payment-confirmation/troy.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
60 changes: 60 additions & 0 deletions secure-payment-confirmation/utils.sub.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
const PAYMENT_DETAILS = {
total: {label: 'Total', amount: {value: '0.01', currency: 'USD'}}
};
const ICON_URL = 'https://{{hosts[][www]}}:{{ports[https][0]}}/secure-payment-confirmation/troy.png';
const AUTHENTICATOR_OPTS = {
protocol: 'ctap2_1',
transport: 'internal',
hasResidentKey: true,
hasUserVerification: true,
isUserVerified: true,
};

// Creates and returns a WebAuthn credential, optionally with the payment
// extension set.
//
// Assumes that a virtual authenticator has already been created.
async function createCredential(set_payment_extension=true) {
const challengeBytes = new Uint8Array(16);
window.crypto.getRandomValues(challengeBytes);

const publicKey = {
challenge: challengeBytes,
rp: {
name: 'Acme',
},
user: {
id: new Uint8Array(16),
name: '[email protected]',
displayName: 'Jane Doe',
},
pubKeyCredParams: [{
type: 'public-key',
alg: -7, // 'ES256'
}],
authenticatorSelection: {
userVerification: 'required',
residentKey: 'required',
authenticatorAttachment: 'platform',
},
timeout: 30000,
};

if (set_payment_extension) {
publicKey.extensions = {
payment: { isPayment: true },
};
}

return navigator.credentials.create({publicKey});
}

function arrayBufferToString(buffer) {
return String.fromCharCode(...new Uint8Array(buffer));
}

function base64UrlEncode(data) {
let result = btoa(data);
return result.replace(/=+$/g, '').replace(/\+/g, "-").replace(/\//g, "_");
}

0 comments on commit ca7ae27

Please sign in to comment.