From 425406d7c1e2b79a27d49c876823989bf5c53913 Mon Sep 17 00:00:00 2001 From: panteliselef Date: Thu, 21 Mar 2024 14:57:44 +0200 Subject: [PATCH 1/7] chore(clerk-js): Improve error handling in retrieval of passkeys --- packages/clerk-js/src/core/errors.ts | 6 ++++++ packages/clerk-js/src/core/resources/SignIn.ts | 12 ++++++------ packages/clerk-js/src/ui/components/SignIn/shared.ts | 12 ++++++++---- packages/clerk-js/src/utils/passkeys.ts | 7 ++++++- packages/localizations/src/en-US.ts | 1 + packages/types/src/localization.ts | 1 + 6 files changed, 28 insertions(+), 11 deletions(-) diff --git a/packages/clerk-js/src/core/errors.ts b/packages/clerk-js/src/core/errors.ts index cd350ce7a6b..19ec9c645d3 100644 --- a/packages/clerk-js/src/core/errors.ts +++ b/packages/clerk-js/src/core/errors.ts @@ -113,3 +113,9 @@ export function clerkInvalidRoutingStrategy(strategy?: string): never { export function clerkUnsupportedReloadMethod(className: string): never { throw new Error(`${errorPrefix} Calling ${className}.reload is not currently supported. Please contact support.`); } + +export function clerkMissingWebAuthnPublicKeyRequestOptions(): never { + throw new Error( + `${errorPrefix} Missing publicKey. When calling 'navigator.credentials.create()' is it required to pass a publicKey object.`, + ); +} diff --git a/packages/clerk-js/src/core/resources/SignIn.ts b/packages/clerk-js/src/core/resources/SignIn.ts index 9672d93afa9..297862e8b94 100644 --- a/packages/clerk-js/src/core/resources/SignIn.ts +++ b/packages/clerk-js/src/core/resources/SignIn.ts @@ -41,6 +41,7 @@ import { clerkInvalidFAPIResponse, clerkInvalidStrategy, clerkMissingOptionError, + clerkMissingWebAuthnPublicKeyRequestOptions, clerkVerifyEmailAddressCalledBeforeCreate, clerkVerifyPasskeyCalledBeforeCreate, clerkVerifyWeb3WalletCalledBeforeCreate, @@ -294,11 +295,10 @@ export class SignIn extends BaseResource implements SignInResource { } const { nonce } = this.firstFactorVerification; - const publicKey = nonce ? convertJSONToPublicKeyRequestOptions(JSON.parse(nonce)) : null; + const publicKeyOptions = nonce ? convertJSONToPublicKeyRequestOptions(JSON.parse(nonce)) : null; - if (!publicKey) { - // TODO-PASSKEYS: Implement this later - throw 'Missing key'; + if (!publicKeyOptions) { + clerkMissingWebAuthnPublicKeyRequestOptions(); } let canUseConditionalUI = false; @@ -311,9 +311,9 @@ export class SignIn extends BaseResource implements SignInResource { canUseConditionalUI = await isWebAuthnAutofillSupported(); } - // Invoke the WebAuthn get() method. + // Invoke the navigator.create.get() method. const { publicKeyCredential, error } = await webAuthnGetCredential({ - publicKeyOptions: publicKey, + publicKeyOptions, conditionalUI: canUseConditionalUI, }); diff --git a/packages/clerk-js/src/ui/components/SignIn/shared.ts b/packages/clerk-js/src/ui/components/SignIn/shared.ts index f8882665d71..63c9820e5e2 100644 --- a/packages/clerk-js/src/ui/components/SignIn/shared.ts +++ b/packages/clerk-js/src/ui/components/SignIn/shared.ts @@ -37,10 +37,14 @@ function useHandleAuthenticateWithPasskey() { } } catch (err) { const { flow } = args[0] || {}; - // In case of autofill, if retrieval of credentials is aborted just return to avoid updating state of unmounted components. - if (flow === 'autofill' && isClerkRuntimeError(err)) { - const skipActionCodes = ['passkey_retrieval_aborted', 'passkey_retrieval_cancelled']; - if (skipActionCodes.includes(err.code)) { + + if (isClerkRuntimeError(err)) { + // In any case if the call gets aborted we should skip showing an error. This prevents updating the state of unmounted components. + if (err.code === 'passkey_retrieval_aborted') { + return; + } + // In case of autofill, if retrieval of credentials is cancelled by the user avoid showing errors as it results to pour UX. + if (flow === 'autofill' && err.code === 'passkey_retrieval_cancelled') { return; } } diff --git a/packages/clerk-js/src/utils/passkeys.ts b/packages/clerk-js/src/utils/passkeys.ts index fdca7ae6f6f..a4cb15a39d3 100644 --- a/packages/clerk-js/src/utils/passkeys.ts +++ b/packages/clerk-js/src/utils/passkeys.ts @@ -29,6 +29,7 @@ type ClerkWebAuthnErrorCode = | 'passkey_retrieval_aborted' | 'passkey_retrieval_cancelled' | 'passkey_registration_cancelled' + | 'passkey_retrieval_invalid_rpID_or_domain' | 'passkey_credential_create_failed' | 'passkey_credential_get_failed'; @@ -155,7 +156,7 @@ async function webAuthnGetCredential({ return { publicKeyCredential: credential, error: null }; } catch (e) { - return { error: handlePublicKeyGetError(e), publicKeyCredential: null }; + return { error: handlePublicKeyGetError(e, publicKeyOptions), publicKeyCredential: null }; } } @@ -185,6 +186,10 @@ function handlePublicKeyGetError(error: Error): ClerkWebAuthnError | ClerkRuntim if (error.name === 'NotAllowedError') { return new ClerkWebAuthnError(error.message, { code: 'passkey_retrieval_cancelled' }); } + + if (error.name === 'SecurityError') { + return new ClerkWebAuthnError(error.message, { code: 'passkey_retrieval_invalid_rpID_or_domain' }); + } return error; } diff --git a/packages/localizations/src/en-US.ts b/packages/localizations/src/en-US.ts index 61faa01a540..47b1ec30d09 100644 --- a/packages/localizations/src/en-US.ts +++ b/packages/localizations/src/en-US.ts @@ -442,6 +442,7 @@ export const enUS: LocalizationResource = { 'Sign up unsuccessful due to failed security validations. Please refresh the page to try again or reach out to support for more assistance.', captcha_unavailable: 'Sign up unsuccessful due to failed bot validation. Please refresh the page to try again or reach out to support for more assistance.', + passkey_retrieval_cancelled: 'Passkey verification was cancelled or timed out.', form_code_incorrect: '', form_identifier_exists: '', form_identifier_not_found: '', diff --git a/packages/types/src/localization.ts b/packages/types/src/localization.ts index 8f2b234e256..66ab5d0267a 100644 --- a/packages/types/src/localization.ts +++ b/packages/types/src/localization.ts @@ -723,6 +723,7 @@ type UnstableErrors = WithParamName<{ form_identifier_not_found: LocalizationValue; captcha_unavailable: LocalizationValue; captcha_invalid: LocalizationValue; + passkey_retrieval_cancelled: LocalizationValue; form_password_pwned: LocalizationValue; form_username_invalid_length: LocalizationValue; form_username_invalid_character: LocalizationValue; From 142b9a7234225e0e356cec14c6eb935fd5e37a0d Mon Sep 17 00:00:00 2001 From: panteliselef Date: Thu, 21 Mar 2024 15:02:09 +0200 Subject: [PATCH 2/7] chore(clerk-js): Add changeset --- .changeset/eight-buttons-wink.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .changeset/eight-buttons-wink.md diff --git a/.changeset/eight-buttons-wink.md b/.changeset/eight-buttons-wink.md new file mode 100644 index 00000000000..a845151cc84 --- /dev/null +++ b/.changeset/eight-buttons-wink.md @@ -0,0 +1,2 @@ +--- +--- From bdaa534ca3e145c5dbbf7c075f19114ca340552b Mon Sep 17 00:00:00 2001 From: panteliselef Date: Thu, 21 Mar 2024 16:28:02 +0200 Subject: [PATCH 3/7] chore(clerk-js): Improve error handling in creation of passkeys --- packages/clerk-js/src/core/errors.ts | 4 +- .../clerk-js/src/core/resources/Passkey.ts | 20 ++++---- .../clerk-js/src/core/resources/SignIn.ts | 11 +++-- packages/clerk-js/src/utils/passkeys.ts | 48 +++++++++++-------- packages/localizations/src/en-US.ts | 4 ++ packages/types/src/localization.ts | 4 ++ 6 files changed, 56 insertions(+), 35 deletions(-) diff --git a/packages/clerk-js/src/core/errors.ts b/packages/clerk-js/src/core/errors.ts index 19ec9c645d3..1085978bf00 100644 --- a/packages/clerk-js/src/core/errors.ts +++ b/packages/clerk-js/src/core/errors.ts @@ -114,8 +114,8 @@ export function clerkUnsupportedReloadMethod(className: string): never { throw new Error(`${errorPrefix} Calling ${className}.reload is not currently supported. Please contact support.`); } -export function clerkMissingWebAuthnPublicKeyRequestOptions(): never { +export function clerkMissingWebAuthnPublicKeyOptions(name: 'create' | 'get'): never { throw new Error( - `${errorPrefix} Missing publicKey. When calling 'navigator.credentials.create()' is it required to pass a publicKey object.`, + `${errorPrefix} Missing publicKey. When calling 'navigator.credentials.${name}()' is it required to pass a publicKey object.`, ); } diff --git a/packages/clerk-js/src/core/resources/Passkey.ts b/packages/clerk-js/src/core/resources/Passkey.ts index d29dd5ab687..c9cadd21c35 100644 --- a/packages/clerk-js/src/core/resources/Passkey.ts +++ b/packages/clerk-js/src/core/resources/Passkey.ts @@ -10,12 +10,14 @@ import type { import { unixEpochToDate } from '../../utils/date'; import { + ClerkWebAuthnError, isWebAuthnPlatformAuthenticatorSupported, isWebAuthnSupported, serializePublicKeyCredential, webAuthnCreateCredential, } from '../../utils/passkeys'; -import { BaseResource, ClerkRuntimeError, DeletedObject, PasskeyVerification } from './internal'; +import { clerkMissingWebAuthnPublicKeyOptions } from '../errors'; +import { BaseResource, DeletedObject, PasskeyVerification } from './internal'; export class Passkey extends BaseResource implements PasskeyResource { id!: string; @@ -60,8 +62,8 @@ export class Passkey extends BaseResource implements PasskeyResource { * As a precaution we need to check if WebAuthn is supported. */ if (!isWebAuthnSupported()) { - throw new ClerkRuntimeError('Passkeys are not supported', { - code: 'passkeys_unsupported', + throw new ClerkWebAuthnError('Passkeys are not supported in this device.', { + code: 'passkey_not_supported', }); } @@ -73,15 +75,17 @@ export class Passkey extends BaseResource implements PasskeyResource { // This should never occur, just a fail-safe if (!publicKey) { - // TODO-PASSKEYS: Implement this later - throw 'Missing key'; + clerkMissingWebAuthnPublicKeyOptions('create'); } if (publicKey.authenticatorSelection?.authenticatorAttachment === 'platform') { if (!(await isWebAuthnPlatformAuthenticatorSupported())) { - throw new ClerkRuntimeError('Platform authenticator is not supported', { - code: 'passkeys_unsupported_platform_authenticator', - }); + throw new ClerkWebAuthnError( + 'Registration requires a platform authenticator but the device does not support it.', + { + code: 'passkeys_pa_not_supported', + }, + ); } } diff --git a/packages/clerk-js/src/core/resources/SignIn.ts b/packages/clerk-js/src/core/resources/SignIn.ts index 297862e8b94..742c8afbdd9 100644 --- a/packages/clerk-js/src/core/resources/SignIn.ts +++ b/packages/clerk-js/src/core/resources/SignIn.ts @@ -1,4 +1,4 @@ -import { ClerkRuntimeError, deepSnakeToCamel, Poller } from '@clerk/shared'; +import { deepSnakeToCamel, Poller } from '@clerk/shared'; import type { __experimental_PasskeyFactor, AttemptFirstFactorParams, @@ -30,6 +30,7 @@ import type { import { generateSignatureWithMetamask, getMetamaskIdentifier, windowNavigate } from '../../utils'; import { + ClerkWebAuthnError, convertJSONToPublicKeyRequestOptions, isWebAuthnAutofillSupported, isWebAuthnSupported, @@ -41,7 +42,7 @@ import { clerkInvalidFAPIResponse, clerkInvalidStrategy, clerkMissingOptionError, - clerkMissingWebAuthnPublicKeyRequestOptions, + clerkMissingWebAuthnPublicKeyOptions, clerkVerifyEmailAddressCalledBeforeCreate, clerkVerifyPasskeyCalledBeforeCreate, clerkVerifyWeb3WalletCalledBeforeCreate, @@ -272,8 +273,8 @@ export class SignIn extends BaseResource implements SignInResource { * As a precaution we need to check if WebAuthn is supported. */ if (!isWebAuthnSupported()) { - throw new ClerkRuntimeError('Passkeys are not supported', { - code: 'passkeys_unsupported', + throw new ClerkWebAuthnError('Passkeys are not supported', { + code: 'passkey_not_supported', }); } @@ -298,7 +299,7 @@ export class SignIn extends BaseResource implements SignInResource { const publicKeyOptions = nonce ? convertJSONToPublicKeyRequestOptions(JSON.parse(nonce)) : null; if (!publicKeyOptions) { - clerkMissingWebAuthnPublicKeyRequestOptions(); + clerkMissingWebAuthnPublicKeyOptions('get'); } let canUseConditionalUI = false; diff --git a/packages/clerk-js/src/utils/passkeys.ts b/packages/clerk-js/src/utils/passkeys.ts index a4cb15a39d3..932b250e64e 100644 --- a/packages/clerk-js/src/utils/passkeys.ts +++ b/packages/clerk-js/src/utils/passkeys.ts @@ -25,13 +25,18 @@ type WebAuthnGetCredentialReturn = CredentialReturn<__experimental_PublicKeyCredentialWithAuthenticatorAssertionResponse>; type ClerkWebAuthnErrorCode = - | 'passkey_exists' - | 'passkey_retrieval_aborted' + // Generic + | 'passkey_not_supported' + | 'passkeys_pa_not_supported' + | 'passkey_invalid_rpID_or_domain' + | 'passkey_already_exists' + | 'passkey_operation_aborted' + // Retrieval | 'passkey_retrieval_cancelled' + | 'passkey_retrieval_failed' + // Registration | 'passkey_registration_cancelled' - | 'passkey_retrieval_invalid_rpID_or_domain' - | 'passkey_credential_create_failed' - | 'passkey_credential_get_failed'; + | 'passkey_registration_failed'; function isWebAuthnSupported() { return ( @@ -93,7 +98,7 @@ async function webAuthnCreateCredential( if (!credential) { return { error: new ClerkWebAuthnError('Browser failed to create credential', { - code: 'passkey_credential_create_failed', + code: 'passkey_registration_failed', }), publicKeyCredential: null, }; @@ -149,17 +154,27 @@ async function webAuthnGetCredential({ if (!credential) { return { - error: new ClerkWebAuthnError('Browser failed to get credential', { code: 'passkey_credential_get_failed' }), + error: new ClerkWebAuthnError('Browser failed to get credential', { code: 'passkey_retrieval_failed' }), publicKeyCredential: null, }; } return { publicKeyCredential: credential, error: null }; } catch (e) { - return { error: handlePublicKeyGetError(e, publicKeyOptions), publicKeyCredential: null }; + return { error: handlePublicKeyGetError(e), publicKeyCredential: null }; } } +function handlePublicKeyError(error: Error): ClerkWebAuthnError | ClerkRuntimeError | Error { + if (error.name === 'AbortError') { + return new ClerkWebAuthnError(error.message, { code: 'passkey_operation_aborted' }); + } + if (error.name === 'SecurityError') { + return new ClerkWebAuthnError(error.message, { code: 'passkey_invalid_rpID_or_domain' }); + } + return error; +} + /** * Map webauthn errors from `navigator.credentials.create()` to Clerk-js errors * @param error @@ -167,11 +182,12 @@ async function webAuthnGetCredential({ function handlePublicKeyCreateError(error: Error): ClerkWebAuthnError | ClerkRuntimeError | Error { if (error.name === 'InvalidStateError') { // Note: Firefox will throw 'NotAllowedError' when passkeys exists - return new ClerkWebAuthnError(error.message, { code: 'passkey_exists' }); - } else if (error.name === 'NotAllowedError') { + return new ClerkWebAuthnError(error.message, { code: 'passkey_already_exists' }); + } + if (error.name === 'NotAllowedError') { return new ClerkWebAuthnError(error.message, { code: 'passkey_registration_cancelled' }); } - return error; + return handlePublicKeyError(error); } /** @@ -179,18 +195,10 @@ function handlePublicKeyCreateError(error: Error): ClerkWebAuthnError | ClerkRun * @param error */ function handlePublicKeyGetError(error: Error): ClerkWebAuthnError | ClerkRuntimeError | Error { - if (error.name === 'AbortError') { - return new ClerkWebAuthnError(error.message, { code: 'passkey_retrieval_aborted' }); - } - if (error.name === 'NotAllowedError') { return new ClerkWebAuthnError(error.message, { code: 'passkey_retrieval_cancelled' }); } - - if (error.name === 'SecurityError') { - return new ClerkWebAuthnError(error.message, { code: 'passkey_retrieval_invalid_rpID_or_domain' }); - } - return error; + return handlePublicKeyError(error); } function convertJSONToPublicKeyCreateOptions(jsonPublicKey: PublicKeyCredentialCreationOptionsJSON) { diff --git a/packages/localizations/src/en-US.ts b/packages/localizations/src/en-US.ts index 47b1ec30d09..fc24f0c4524 100644 --- a/packages/localizations/src/en-US.ts +++ b/packages/localizations/src/en-US.ts @@ -442,7 +442,11 @@ export const enUS: LocalizationResource = { 'Sign up unsuccessful due to failed security validations. Please refresh the page to try again or reach out to support for more assistance.', captcha_unavailable: 'Sign up unsuccessful due to failed bot validation. Please refresh the page to try again or reach out to support for more assistance.', + passkey_not_supported: 'Passkeys are not supported in this device.', + passkeys_pa_not_supported: 'Registration requires a platform authenticator but the device does not support it.', passkey_retrieval_cancelled: 'Passkey verification was cancelled or timed out.', + passkey_registration_cancelled: 'Passkey registration was cancelled or timed out.', + passkey_already_exists: 'A passkey is already registered with this device.', form_code_incorrect: '', form_identifier_exists: '', form_identifier_not_found: '', diff --git a/packages/types/src/localization.ts b/packages/types/src/localization.ts index 66ab5d0267a..b3903efa0de 100644 --- a/packages/types/src/localization.ts +++ b/packages/types/src/localization.ts @@ -723,7 +723,11 @@ type UnstableErrors = WithParamName<{ form_identifier_not_found: LocalizationValue; captcha_unavailable: LocalizationValue; captcha_invalid: LocalizationValue; + passkey_not_supported: LocalizationValue; + passkeys_pa_not_supported: LocalizationValue; passkey_retrieval_cancelled: LocalizationValue; + passkey_registration_cancelled: LocalizationValue; + passkey_already_exists: LocalizationValue; form_password_pwned: LocalizationValue; form_username_invalid_length: LocalizationValue; form_username_invalid_character: LocalizationValue; From 335ba7f14cb5db7183a9d08bcb09e9c6bc1497ee Mon Sep 17 00:00:00 2001 From: panteliselef Date: Thu, 21 Mar 2024 16:49:29 +0200 Subject: [PATCH 4/7] chore(clerk-js): Update usage --- packages/clerk-js/src/ui/components/SignIn/shared.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/clerk-js/src/ui/components/SignIn/shared.ts b/packages/clerk-js/src/ui/components/SignIn/shared.ts index 63c9820e5e2..88e3e86c225 100644 --- a/packages/clerk-js/src/ui/components/SignIn/shared.ts +++ b/packages/clerk-js/src/ui/components/SignIn/shared.ts @@ -40,7 +40,7 @@ function useHandleAuthenticateWithPasskey() { if (isClerkRuntimeError(err)) { // In any case if the call gets aborted we should skip showing an error. This prevents updating the state of unmounted components. - if (err.code === 'passkey_retrieval_aborted') { + if (err.code === 'passkey_operation_aborted') { return; } // In case of autofill, if retrieval of credentials is cancelled by the user avoid showing errors as it results to pour UX. From 481e07d73fc22551364bd7a31ecd92b0bbbf8fcf Mon Sep 17 00:00:00 2001 From: panteliselef Date: Thu, 21 Mar 2024 21:07:00 +0200 Subject: [PATCH 5/7] chore(clerk-js): Fix typos --- packages/clerk-js/src/core/errors.ts | 2 +- packages/clerk-js/src/core/resources/Passkey.ts | 2 +- packages/localizations/src/en-US.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/clerk-js/src/core/errors.ts b/packages/clerk-js/src/core/errors.ts index 1085978bf00..b917db134c4 100644 --- a/packages/clerk-js/src/core/errors.ts +++ b/packages/clerk-js/src/core/errors.ts @@ -116,6 +116,6 @@ export function clerkUnsupportedReloadMethod(className: string): never { export function clerkMissingWebAuthnPublicKeyOptions(name: 'create' | 'get'): never { throw new Error( - `${errorPrefix} Missing publicKey. When calling 'navigator.credentials.${name}()' is it required to pass a publicKey object.`, + `${errorPrefix} Missing publicKey. When calling 'navigator.credentials.${name}()' it is required to pass a publicKey object.`, ); } diff --git a/packages/clerk-js/src/core/resources/Passkey.ts b/packages/clerk-js/src/core/resources/Passkey.ts index c9cadd21c35..d3cec54e120 100644 --- a/packages/clerk-js/src/core/resources/Passkey.ts +++ b/packages/clerk-js/src/core/resources/Passkey.ts @@ -62,7 +62,7 @@ export class Passkey extends BaseResource implements PasskeyResource { * As a precaution we need to check if WebAuthn is supported. */ if (!isWebAuthnSupported()) { - throw new ClerkWebAuthnError('Passkeys are not supported in this device.', { + throw new ClerkWebAuthnError('Passkeys are not supported on this device.', { code: 'passkey_not_supported', }); } diff --git a/packages/localizations/src/en-US.ts b/packages/localizations/src/en-US.ts index fc24f0c4524..33228752448 100644 --- a/packages/localizations/src/en-US.ts +++ b/packages/localizations/src/en-US.ts @@ -442,7 +442,7 @@ export const enUS: LocalizationResource = { 'Sign up unsuccessful due to failed security validations. Please refresh the page to try again or reach out to support for more assistance.', captcha_unavailable: 'Sign up unsuccessful due to failed bot validation. Please refresh the page to try again or reach out to support for more assistance.', - passkey_not_supported: 'Passkeys are not supported in this device.', + passkey_not_supported: 'Passkeys are not supported on this device.', passkeys_pa_not_supported: 'Registration requires a platform authenticator but the device does not support it.', passkey_retrieval_cancelled: 'Passkey verification was cancelled or timed out.', passkey_registration_cancelled: 'Passkey registration was cancelled or timed out.', From 405f16243434640413a5448ec0d164a35dcf37e8 Mon Sep 17 00:00:00 2001 From: panteliselef Date: Mon, 25 Mar 2024 14:03:33 +0200 Subject: [PATCH 6/7] chore(clerk-js): Add changeset --- .changeset/slow-plants-grin.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 .changeset/slow-plants-grin.md diff --git a/.changeset/slow-plants-grin.md b/.changeset/slow-plants-grin.md new file mode 100644 index 00000000000..aca497a7a1e --- /dev/null +++ b/.changeset/slow-plants-grin.md @@ -0,0 +1,33 @@ +--- +'@clerk/localizations': minor +'@clerk/clerk-js': minor +'@clerk/types': minor +--- + +Improved error handling for registration and retrieval of passkeys. +ClerkRuntimeError codes introduced: +- `passkey_not_supported` +- `passkeys_pa_not_supported` +- `passkey_invalid_rpID_or_domain` +- `passkey_already_exists` +- `passkey_operation_aborted` +- `passkey_retrieval_cancelled` +- `passkey_retrieval_failed` +- `passkey_registration_cancelled` +- `passkey_registration_failed` + +Example usage: + +```ts +try { + await __experimental_authenticateWithPasskey(...args); +}catch (e) { + if (isClerkRuntimeError(e)) { + if (err.code === 'passkey_operation_aborted') { + ... + } + } +} + + +``` From 0718cc91c2279fbfba4e7f9ac8feadc25ba46895 Mon Sep 17 00:00:00 2001 From: panteliselef Date: Mon, 25 Mar 2024 14:05:18 +0200 Subject: [PATCH 7/7] chore(clerk-js): Add changeset --- .changeset/eight-buttons-wink.md | 31 ++++++++++++++++++++++++++++++ .changeset/slow-plants-grin.md | 33 -------------------------------- 2 files changed, 31 insertions(+), 33 deletions(-) delete mode 100644 .changeset/slow-plants-grin.md diff --git a/.changeset/eight-buttons-wink.md b/.changeset/eight-buttons-wink.md index a845151cc84..aca497a7a1e 100644 --- a/.changeset/eight-buttons-wink.md +++ b/.changeset/eight-buttons-wink.md @@ -1,2 +1,33 @@ --- +'@clerk/localizations': minor +'@clerk/clerk-js': minor +'@clerk/types': minor --- + +Improved error handling for registration and retrieval of passkeys. +ClerkRuntimeError codes introduced: +- `passkey_not_supported` +- `passkeys_pa_not_supported` +- `passkey_invalid_rpID_or_domain` +- `passkey_already_exists` +- `passkey_operation_aborted` +- `passkey_retrieval_cancelled` +- `passkey_retrieval_failed` +- `passkey_registration_cancelled` +- `passkey_registration_failed` + +Example usage: + +```ts +try { + await __experimental_authenticateWithPasskey(...args); +}catch (e) { + if (isClerkRuntimeError(e)) { + if (err.code === 'passkey_operation_aborted') { + ... + } + } +} + + +``` diff --git a/.changeset/slow-plants-grin.md b/.changeset/slow-plants-grin.md deleted file mode 100644 index aca497a7a1e..00000000000 --- a/.changeset/slow-plants-grin.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -'@clerk/localizations': minor -'@clerk/clerk-js': minor -'@clerk/types': minor ---- - -Improved error handling for registration and retrieval of passkeys. -ClerkRuntimeError codes introduced: -- `passkey_not_supported` -- `passkeys_pa_not_supported` -- `passkey_invalid_rpID_or_domain` -- `passkey_already_exists` -- `passkey_operation_aborted` -- `passkey_retrieval_cancelled` -- `passkey_retrieval_failed` -- `passkey_registration_cancelled` -- `passkey_registration_failed` - -Example usage: - -```ts -try { - await __experimental_authenticateWithPasskey(...args); -}catch (e) { - if (isClerkRuntimeError(e)) { - if (err.code === 'passkey_operation_aborted') { - ... - } - } -} - - -```