Source code

Revision control

Copy as Markdown

Other Tools

<!DOCTYPE html>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<body></body>
<script type="module">
// @ts-check
/**
* @typedef {import('./dc-types').EventData} EventData
* @typedef {import('./dc-types').PostData} PostData
*/
/**
* @param {MessageEvent<EventData>} event
*/
async function messageListener(event) {
if (!event.data || typeof event.data !== "object") {
throw new Error(
`Message data must be an object in conforming to EventData (see dc-types.js): ${event.data}`
);
}
/** @type {EventData} */
const { data } = event;
const abortController = new AbortController();
if (data.abort) {
if (!data.options) {
data.options = {};
}
data.options.signal = abortController.signal;
}
if (data.needsActivation) {
await test_driver.bless("user activation", null, window);
}
let result;
try {
/** @type {CredentialsContainer} */
const identity = navigator.identity;
if (data.abort === "before") {
abortController.abort();
}
let promise;
switch (data.action) {
case "ping":
promise = Promise.resolve("pong");
break;
case "create":
promise = identity.create(data.options);
break;
case "get":
promise = identity.get(data.options);
break;
case "preventSilentAccess":
promise = identity.preventSilentAccess();
break;
default:
throw new Error(
`Unsupported action in ${window.location}: ${data.action}`
);
}
if (data.abort === "after") {
abortController.abort();
}
result = await promise;
} catch (error) {
result = {
constructor: error.constructor.name,
name: error.name,
message: error.message,
};
} finally {
event.source?.postMessage(result, event.origin);
}
}
window.addEventListener("message", messageListener);
</script>