Skip to content

Commit 6b8cf1d

Browse files
committed
feat(account): show specific error when passkey already registered
Handle WebAuthn error codes in passkey binding flow to show more specific error messages instead of generic "Failed to create" message. - Show "passkey already registered" error when authenticator is already registered to the account - Silently handle user cancellation (ERROR_CEREMONY_ABORTED)
1 parent 24f48bf commit 6b8cf1d

File tree

19 files changed

+53
-1
lines changed

19 files changed

+53
-1
lines changed

packages/account/src/pages/PasskeyBinding/index.tsx

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import Button from '@experience/shared/components/Button';
22
import { AccountCenterControlValue, MfaFactor, type Mfa } from '@logto/schemas';
33
import { trySafe } from '@silverhand/essentials';
4-
import { browserSupportsWebAuthn, startRegistration } from '@simplewebauthn/browser';
4+
import { browserSupportsWebAuthn, startRegistration, WebAuthnError } from '@simplewebauthn/browser';
55
import { useCallback, useContext, useEffect, useState } from 'react';
66
import { useTranslation } from 'react-i18next';
77
import { useNavigate } from 'react-router-dom';
@@ -105,6 +105,23 @@ const PasskeyBinding = () => {
105105
async () => startRegistration(registrationOptions),
106106
(error) => {
107107
console.error('WebAuthn registration failed:', error);
108+
109+
if (error instanceof WebAuthnError) {
110+
switch (error.code) {
111+
case 'ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED': {
112+
setToast(t('account_center.mfa.passkey_already_registered'));
113+
return;
114+
}
115+
case 'ERROR_CEREMONY_ABORTED': {
116+
// User cancelled the operation, no need to show error
117+
return;
118+
}
119+
default: {
120+
break;
121+
}
122+
}
123+
}
124+
108125
setToast(t('mfa.webauthn_failed_to_create'));
109126
}
110127
);

packages/phrases-experience/src/locales/ar/account-center.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ const account_center = {
100100
backup_code_not_enabled: 'رمز النسخ الاحتياطي غير ممكّن. يرجى الاتصال بالمسؤول لتمكينه.',
101101
backup_code_requires_other_mfa: 'تتطلب رموز النسخ الاحتياطي إعداد طريقة MFA أخرى أولاً.',
102102
passkey_not_enabled: 'مفتاح المرور غير مفعّل. يرجى التواصل مع المسؤول لتفعيله.',
103+
passkey_already_registered:
104+
'This passkey is already registered to your account. Please use a different authenticator.',
103105
},
104106
update_success: {
105107
default: {

packages/phrases-experience/src/locales/de/account-center.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@ const account_center = {
117117
'Für Backup-Codes muss zuerst eine andere MFA-Methode eingerichtet werden.',
118118
passkey_not_enabled:
119119
'Passkey ist nicht aktiviert. Bitte kontaktieren Sie Ihren Administrator, um es zu aktivieren.',
120+
passkey_already_registered:
121+
'This passkey is already registered to your account. Please use a different authenticator.',
120122
},
121123
update_success: {
122124
default: {

packages/phrases-experience/src/locales/en/account-center.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ const account_center = {
108108
'Backup code is not enabled. Please contact your administrator to enable it.',
109109
backup_code_requires_other_mfa: 'Backup codes require another MFA method to be set up first.',
110110
passkey_not_enabled: 'Passkey is not enabled. Please contact your administrator to enable it.',
111+
passkey_already_registered:
112+
'This passkey is already registered to your account. Please use a different authenticator.',
111113
},
112114
update_success: {
113115
default: {

packages/phrases-experience/src/locales/es/account-center.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ const account_center = {
113113
'Los códigos de respaldo requieren que se configure otro método MFA primero.',
114114
passkey_not_enabled:
115115
'Passkey no está habilitado. Por favor, contacta a tu administrador para habilitarlo.',
116+
passkey_already_registered:
117+
'This passkey is already registered to your account. Please use a different authenticator.',
116118
},
117119
update_success: {
118120
default: {

packages/phrases-experience/src/locales/fr/account-center.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ const account_center = {
114114
"Les codes de secours nécessitent qu'une autre méthode MFA soit d'abord configurée.",
115115
passkey_not_enabled:
116116
"Passkey n'est pas activé. Veuillez contacter votre administrateur pour l'activer.",
117+
passkey_already_registered:
118+
'This passkey is already registered to your account. Please use a different authenticator.',
117119
},
118120
update_success: {
119121
default: {

packages/phrases-experience/src/locales/it/account-center.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,8 @@ const account_center = {
112112
backup_code_requires_other_mfa:
113113
'I codici di backup richiedono che venga prima configurato un altro metodo MFA.',
114114
passkey_not_enabled: "Passkey non è abilitato. Contatta l'amministratore per abilitarlo.",
115+
passkey_already_registered:
116+
'This passkey is already registered to your account. Please use a different authenticator.',
115117
},
116118
update_success: {
117119
default: {

packages/phrases-experience/src/locales/ja/account-center.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ const account_center = {
105105
backup_code_requires_other_mfa:
106106
'バックアップコードを使用するには、まず他の MFA メソッドを設定する必要があります。',
107107
passkey_not_enabled: 'パスキーが有効になっていません。管理者に連絡して有効にしてください。',
108+
passkey_already_registered:
109+
'This passkey is already registered to your account. Please use a different authenticator.',
108110
},
109111
update_success: {
110112
default: {

packages/phrases-experience/src/locales/ko/account-center.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ const account_center = {
102102
'백업 코드가 활성화되지 않았습니다. 관리자에게 문의하여 활성화하십시오.',
103103
backup_code_requires_other_mfa: '백업 코드를 사용하려면 다른 MFA 방법을 먼저 설정해야 합니다.',
104104
passkey_not_enabled: '패스키가 활성화되지 않았습니다. 관리자에게 문의하여 활성화하세요.',
105+
passkey_already_registered:
106+
'This passkey is already registered to your account. Please use a different authenticator.',
105107
},
106108
update_success: {
107109
default: {

packages/phrases-experience/src/locales/pl-pl/account-center.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ const account_center = {
108108
'Kody zapasowe wymagają wcześniejszego skonfigurowania innej metody MFA.',
109109
passkey_not_enabled:
110110
'Passkey nie jest włączony. Skontaktuj się z administratorem, aby go włączyć.',
111+
passkey_already_registered:
112+
'This passkey is already registered to your account. Please use a different authenticator.',
111113
},
112114
update_success: {
113115
default: {

0 commit comments

Comments
 (0)