diff --git a/packages/connect-react/src/components/append/AppendAfterErrorScreen.tsx b/packages/connect-react/src/components/append/AppendAfterErrorScreen.tsx
index 8d31d6fe..833c0ef8 100644
--- a/packages/connect-react/src/components/append/AppendAfterErrorScreen.tsx
+++ b/packages/connect-react/src/components/append/AppendAfterErrorScreen.tsx
@@ -63,7 +63,7 @@ const AppendAfterErrorScreen = ({ attestationOptions }: { attestationOptions: st
void handleErrorSoft(situationCode, true, true, error);
break;
case AppendSituationCode.ClientExcludeCredentialsMatch:
- void handleCredentialExistsError(error);
+ void handleCredentialExistsError(attestationOptions, error);
break;
case AppendSituationCode.ExplicitSkipByUser:
void handleSkip(situationCode, true);
diff --git a/packages/connect-react/src/components/append/AppendInitScreen.tsx b/packages/connect-react/src/components/append/AppendInitScreen.tsx
index e4e03262..c4a8dc66 100644
--- a/packages/connect-react/src/components/append/AppendInitScreen.tsx
+++ b/packages/connect-react/src/components/append/AppendInitScreen.tsx
@@ -244,7 +244,7 @@ const AppendInitScreen = () => {
setAppendLoading(false);
break;
case AppendSituationCode.ClientExcludeCredentialsMatch:
- void handleCredentialExistsError(error);
+ void handleCredentialExistsError(attestationOptions, error);
setAppendLoading(false);
break;
case AppendSituationCode.DeniedByPartialRollout:
diff --git a/packages/connect-react/src/components/passkeyList/PasskeyListScreen.tsx b/packages/connect-react/src/components/passkeyList/PasskeyListScreen.tsx
index 0a082d63..c0528ae6 100644
--- a/packages/connect-react/src/components/passkeyList/PasskeyListScreen.tsx
+++ b/packages/connect-react/src/components/passkeyList/PasskeyListScreen.tsx
@@ -137,7 +137,11 @@ const PasskeyListScreen = () => {
}
if (res.val.type === ConnectErrorType.ExcludeCredentialsMatch) {
- return handleSituation(PasskeyListSituationCode.ClientExcludeCredentialsMatch, res.val);
+ return handleSituation(
+ PasskeyListSituationCode.ClientExcludeCredentialsMatch,
+ res.val,
+ startAppendRes.val.attestationOptions,
+ );
}
return handleSituation(PasskeyListSituationCode.CboApiNotAvailablePostAuthenticator, res.val);
@@ -171,7 +175,11 @@ const PasskeyListScreen = () => {
statefulLoader.current.finish();
};
- const handleSituation = (situationCode: PasskeyListSituationCode, error?: ConnectError) => {
+ const handleSituation = (
+ situationCode: PasskeyListSituationCode,
+ error?: ConnectError,
+ attestationOptions?: string,
+ ) => {
const messageCode = `situation: ${situationCode}`;
log.debug(messageCode);
@@ -179,7 +187,10 @@ const PasskeyListScreen = () => {
switch (situationCode) {
case PasskeyListSituationCode.ClientExcludeCredentialsMatch:
setAppendLoading(false);
- void getConnectService().recordEventAppendCredentialExistsError(`${messageCode} ${error?.track()}`);
+ void getConnectService().recordEventAppendCredentialExistsError(
+ attestationOptions ?? '',
+ `${messageCode} ${error?.track()}`,
+ );
show();
break;
case PasskeyListSituationCode.CboApiPasskeysNotSupportedLight:
diff --git a/packages/connect-react/src/contexts/AppendProcessContext.ts b/packages/connect-react/src/contexts/AppendProcessContext.ts
index 6513b5f3..7335e1ad 100644
--- a/packages/connect-react/src/contexts/AppendProcessContext.ts
+++ b/packages/connect-react/src/contexts/AppendProcessContext.ts
@@ -22,7 +22,7 @@ export interface AppendProcessContextProps {
error?: ConnectError,
) => Promise;
handleErrorHard: (situation: AppendSituationCode, expected: boolean, error?: ConnectError) => Promise;
- handleCredentialExistsError: (error?: ConnectError) => Promise;
+ handleCredentialExistsError: (attestationOptions: string, error?: ConnectError) => Promise;
handleSkip: (situation: AppendSituationCode, explicit?: boolean) => Promise;
onReadMoreClick: () => Promise;
flags: Flags | undefined;
diff --git a/packages/connect-react/src/contexts/AppendProcessProvider.tsx b/packages/connect-react/src/contexts/AppendProcessProvider.tsx
index 30cf0d34..e86dcb48 100644
--- a/packages/connect-react/src/contexts/AppendProcessProvider.tsx
+++ b/packages/connect-react/src/contexts/AppendProcessProvider.tsx
@@ -74,10 +74,10 @@ export const AppendProcessProvider: FC> = ({ children,
}, [getConnectService, config]);
const handleCredentialExistsError = useCallback(
- async (error?: ConnectError) => {
+ async (attestationOptions: string, error?: ConnectError) => {
log.debug('error (credential-exists)');
- await getConnectService().recordEventAppendCredentialExistsError(error?.track() ?? '');
+ await getConnectService().recordEventAppendCredentialExistsError(error?.track() ?? '', attestationOptions);
void config.onComplete('complete-noop', getConnectService().encodeClientState());
},
[getConnectService, config],
diff --git a/packages/web-core/src/services/ConnectService.ts b/packages/web-core/src/services/ConnectService.ts
index 1e9558f4..475369f8 100644
--- a/packages/web-core/src/services/ConnectService.ts
+++ b/packages/web-core/src/services/ConnectService.ts
@@ -644,8 +644,13 @@ export class ConnectService {
return this.#recordEvent(PasskeyEventType.UserAppendAfterLoginErrorBlacklisted);
}
- recordEventAppendCredentialExistsError(messageCode: string) {
- return this.#recordEvent(PasskeyEventType.AppendCredentialExists, messageCode);
+ recordEventAppendCredentialExistsError(messageCode: string, attestationOptions: string) {
+ let challenge;
+ if (attestationOptions) {
+ challenge = WebAuthnService.challengeFromAttestationOptions(attestationOptions);
+ }
+
+ return this.#recordEvent(PasskeyEventType.AppendCredentialExists, messageCode, challenge);
}
recordEventAppendError() {