Skip to content

Instantly share code, notes, and snippets.

@joostd
Created December 6, 2022 15:20
Show Gist options
  • Select an option

  • Save joostd/5a6dc63a0f1b8ef8b154b28e111bb4b3 to your computer and use it in GitHub Desktop.

Select an option

Save joostd/5a6dc63a0f1b8ef8b154b28e111bb4b3 to your computer and use it in GitHub Desktop.
passkey abortcontroller
<script>
let abortController;
function start() {
abortController = new AbortController();
// setTimeout(() => abortController.abort(), 5000); // automatically abort after 5 seconds
abortController.signal.addEventListener( 'abort', () => {
if(abortController.signal.aborted) console.log("event: signal aborted");
});
const challenge = new Uint8Array(32);
self.crypto.getRandomValues(challenge);
navigator.credentials.get(
{
publicKey: {
authenticatorSelection: { authenticatorAttachment: 'platform'},
timeout: 4000,
challenge: challenge.buffer
},
signal: abortController.signal,
mediation: 'conditional' // use autofill instead of the modal webauthn dialog
}
).then(assertion => {
console.log("Credential ID: ", assertion.id);
}).catch(error => {
if (error instanceof DOMException && error.name === "AbortError") {
console.log("canceled credentials.get() request");
} else {
console.error('other error: ' + error);
}
});
}
function abort() {
if(abortController) abortController.abort(); // will cause the promise object returned by credentials.get() to reject with an DOMException named `AbortError`
}
// start();
</script>
<label for="username">Username:</label>
<input type="text" id="username" autoComplete="username webauthn" />
<button id="start" onClick="start()">start</button>
<button id="abort" onClick="abort()">abort</button>
@joostd
Copy link
Author

joostd commented Dec 6, 2022

Strange behaviour on macOS 13.0.1, Safari (16.1):

  1. start; abort => Safari doesn't catch the rejected promise.
  2. start; click username field; select passkey in autofill popup; touchID (Credential ID is logged on console) => autofill pops up again?

Chrome (108) works as expected.

To test, start a web server (python3 -m http.server 8000) and open http://localhost:8000/abortController.html (may need to create a passkey first)

@joostd
Copy link
Author

joostd commented Dec 6, 2022

Also, when uncommenting line 7. Chrome cancels the WebAuthn dialog after 5 seconds, but Safari doesn't.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment