From 8b4a6a034f3a6e21f7de02671c34e1cd32d26146 Mon Sep 17 00:00:00 2001 From: Andrew Min Date: Tue, 10 Oct 2023 21:40:17 -0400 Subject: [PATCH] add conditional check --- packages/http/src/webauthn.ts | 51 ++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/packages/http/src/webauthn.ts b/packages/http/src/webauthn.ts index 52e751618..943df5a2b 100644 --- a/packages/http/src/webauthn.ts +++ b/packages/http/src/webauthn.ts @@ -114,24 +114,49 @@ export async function getWebAuthnAssertion( payload: string, options?: TurnkeyCredentialRequestOptions ): Promise { - const signingOptions = await getCredentialRequestOptions(payload, options); - const clientGetResult = await webauthnCredentialGet(signingOptions); - const assertion = clientGetResult.toJSON(); - - const stamp: TWebAuthnStamp = { - authenticatorData: assertion.response.authenticatorData, - clientDataJson: assertion.response.clientDataJSON, - credentialId: assertion.id, - signature: assertion.response.signature, - }; + const supported = await isWebAuthnSupported(); + + if (supported) { + const signingOptions = await getCredentialRequestOptions(payload, options); + const clientGetResult = await webauthnCredentialGet(signingOptions); + const assertion = clientGetResult.toJSON(); + const stamp: TWebAuthnStamp = { + authenticatorData: assertion.response.authenticatorData, + clientDataJson: assertion.response.clientDataJSON, + credentialId: assertion.id, + signature: assertion.response.signature, + }; + + return JSON.stringify(stamp); + } - return JSON.stringify(stamp); + throw new Error("webauthn is not supported by this browser"); } export async function getWebAuthnAttestation( options: TurnkeyCredentialCreationOptions ): Promise { - const res = await webauthnCredentialCreate(options); + const supported = await isWebAuthnSupported(); + + if (supported) { + const res = await webauthnCredentialCreate(options); + + return toInternalAttestation(res.toJSON()); + } + + throw new Error("webauthn is not supported by this browser"); +} + +// For additional details see https://web.dev/articles/passkey-form-autofill#feature-detection +async function isWebAuthnSupported(): Promise { + if ( + window.PublicKeyCredential && + PublicKeyCredential.isConditionalMediationAvailable + ) { + const isCMA = await PublicKeyCredential.isConditionalMediationAvailable(); + + return isCMA; + } - return toInternalAttestation(res.toJSON()); + return false; }