fix(login): the two-factor code field is set up for one-time codes and a password manager

The code step drops the email field, so a password manager had no login to
match a one-time code to; the step now keeps the address in a hidden username
field. The code field names itself and sets its keyboard hints directly
(characters, no autocorrect), as autoFocus gave it focus before anything could
prepare it, and its placeholder is translated.
This commit is contained in:
Maurice
2026-11-10 09:23:16 +01:00
parent 20eeaeb61f
commit 6a0ae482d7
29 changed files with 51 additions and 1 deletions
+23 -1
View File
@@ -751,6 +751,19 @@ export default function LoginPage(): React.ReactElement {
>
{t('login.mfaCodeLabel')}
</label>
{/* The account the code belongs to, for password managers: they match a
one-time code to a saved login through the username in the same form,
and the email field is gone in this step. */}
<input
type="text"
name="username"
autoComplete="username"
value={email}
readOnly
tabIndex={-1}
aria-hidden="true"
className="sr-only"
/>
<div style={{ position: 'relative' }}>
<KeyRound
size={15}
@@ -765,13 +778,22 @@ export default function LoginPage(): React.ReactElement {
/>
<input
type="text"
id="totp"
name="totp"
// Text, not numeric: backup codes carry letters. The hints are set here
// rather than left to native/keyboardFields.ts, because autoFocus gives
// the field focus before any touch could prepare it.
inputMode="text"
autoComplete="one-time-code"
autoCapitalize="characters"
autoCorrect="off"
spellCheck={false}
enterKeyHint="go"
value={mfaCode}
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
setMfaCode(e.target.value.toUpperCase().slice(0, 24))
}
placeholder="000000 or XXXX-XXXX"
placeholder={t('login.mfaPlaceholder')}
required
autoFocus
style={inputBase}
+1
View File
@@ -36,6 +36,7 @@ const login: TranslationStrings = {
'login.mfaTitle': 'المصادقة الثنائية',
'login.mfaSubtitle': 'أدخل الرمز المكون من 6 أرقام من تطبيق المصادقة.',
'login.mfaCodeLabel': 'رمز التحقق',
'login.mfaPlaceholder': '000000 أو XXXX-XXXX',
'login.mfaCodeRequired': 'أدخل الرمز من تطبيق المصادقة.',
'login.mfaHint': 'افتح Google Authenticator أو Authy أو أي تطبيق TOTP آخر.',
'login.mfaBack': '← العودة لتسجيل الدخول',
+1
View File
@@ -39,6 +39,7 @@ const login: TranslationStrings = {
'login.mfaTitle': 'İki faktorlu autentifikasiya',
'login.mfaSubtitle': 'Autentifikator tətbiqinizdəki 6 rəqəmli kodu daxil edin.',
'login.mfaCodeLabel': 'Doğrulama kodu',
'login.mfaPlaceholder': '000000 və ya XXXX-XXXX',
'login.mfaCodeRequired': 'Autentifikator tətbiqinizdəki kodu daxil edin.',
'login.mfaHint': 'Google Authenticator, Authy və ya başqa TOTP tətbiqini açın.',
'login.mfaBack': '← Girişə qayıt',
+1
View File
@@ -38,6 +38,7 @@ const login: TranslationStrings = {
'login.mfaTitle': 'Autenticação em duas etapas',
'login.mfaSubtitle': 'Digite o código de 6 dígitos do seu app autenticador.',
'login.mfaCodeLabel': 'Código de verificação',
'login.mfaPlaceholder': '000000 ou XXXX-XXXX',
'login.mfaCodeRequired': 'Digite o código do app autenticador.',
'login.mfaHint': 'Abra o Google Authenticator, Authy ou outro app TOTP.',
'login.mfaBack': '← Voltar ao login',
+1
View File
@@ -26,6 +26,7 @@ const login: TranslationStrings = {
'login.mfaTitle': 'Autenticació de dos factors',
'login.mfaSubtitle': "Introdueix el codi de 6 dígits de la teva app d'autenticació.",
'login.mfaCodeLabel': 'Codi de verificació',
'login.mfaPlaceholder': '000000 o XXXX-XXXX',
'login.mfaCodeRequired': "Introdueix el codi de la teva app d'autenticació.",
'login.mfaHint': 'Obre Google Authenticator, Authy o una altra app TOTP.',
'login.mfaBack': "← Torna a l'inici de sessió",
+1
View File
@@ -38,6 +38,7 @@ const login: TranslationStrings = {
'login.mfaTitle': 'Dvoufaktorové ověření',
'login.mfaSubtitle': 'Zadejte 6místný kód z vaší autentizační aplikace.',
'login.mfaCodeLabel': 'Ověřovací kód',
'login.mfaPlaceholder': '000000 nebo XXXX-XXXX',
'login.mfaCodeRequired': 'Zadejte kód z aplikace.',
'login.mfaHint': 'Otevřete Google Authenticator, Authy nebo jinou TOTP aplikaci.',
'login.mfaBack': '← Zpět k přihlášení',
+1
View File
@@ -38,6 +38,7 @@ const login: TranslationStrings = {
'login.mfaTitle': 'Zwei-Faktor-Authentifizierung',
'login.mfaSubtitle': 'Gib den 6-stelligen Code aus deiner Authenticator-App ein.',
'login.mfaCodeLabel': 'Bestätigungscode',
'login.mfaPlaceholder': '000000 oder XXXX-XXXX',
'login.mfaCodeRequired': 'Bitte den Code aus der Authenticator-App eingeben.',
'login.mfaHint': 'Google Authenticator, Authy oder eine andere TOTP-App öffnen.',
'login.mfaBack': '← Zurück zur Anmeldung',
+1
View File
@@ -38,6 +38,7 @@ const login: TranslationStrings = {
'login.mfaTitle': 'Two-factor authentication',
'login.mfaSubtitle': 'Enter the 6-digit code from your authenticator app.',
'login.mfaCodeLabel': 'Verification code',
'login.mfaPlaceholder': '000000 or XXXX-XXXX',
'login.mfaCodeRequired': 'Enter the code from your authenticator app.',
'login.mfaHint': 'Open Google Authenticator, Authy, or another TOTP app.',
'login.mfaBack': '← Back to sign in',
+1
View File
@@ -26,6 +26,7 @@ const login: TranslationStrings = {
'login.mfaTitle': 'Autenticación de dos factores',
'login.mfaSubtitle': 'Introduce el código de 6 dígitos de tu app de autenticación.',
'login.mfaCodeLabel': 'Código de verificación',
'login.mfaPlaceholder': '000000 o XXXX-XXXX',
'login.mfaCodeRequired': 'Introduce el código de tu app de autenticación.',
'login.mfaHint': 'Abre Google Authenticator, Authy u otra app TOTP.',
'login.mfaBack': '← Volver al inicio de sesión',
+1
View File
@@ -38,6 +38,7 @@ const login: TranslationStrings = {
'login.mfaTitle': 'Kaheastmeline autentimine',
'login.mfaSubtitle': 'Sisesta oma autentimisrakenduse 6-kohaline kood.',
'login.mfaCodeLabel': 'Kinnituskood',
'login.mfaPlaceholder': '000000 või XXXX-XXXX',
'login.mfaCodeRequired': 'Sisesta autentimisrakenduse kood.',
'login.mfaHint': 'Ava Google Authenticator, Authy või muu TOTP-rakendus.',
'login.mfaBack': '← Tagasi sisselogimise juurde',
+1
View File
@@ -26,6 +26,7 @@ const login: TranslationStrings = {
'login.mfaTitle': 'Authentification à deux facteurs',
'login.mfaSubtitle': "Entrez le code à 6 chiffres de votre application d'authentification.",
'login.mfaCodeLabel': 'Code de vérification',
'login.mfaPlaceholder': '000000 ou XXXX-XXXX',
'login.mfaCodeRequired': "Entrez le code de votre application d'authentification.",
'login.mfaHint': 'Ouvrez Google Authenticator, Authy ou une autre application TOTP.',
'login.mfaBack': '← Retour à la connexion',
+1
View File
@@ -40,6 +40,7 @@ const login: TranslationStrings = {
'login.mfaTitle': 'Έλεγχος ταυτότητας δύο παραγόντων',
'login.mfaSubtitle': 'Εισάγετε τον 6ψήφιο κωδικό από την εφαρμογή authenticator σας.',
'login.mfaCodeLabel': 'Κωδικός επαλήθευσης',
'login.mfaPlaceholder': '000000 ή XXXX-XXXX',
'login.mfaCodeRequired': 'Εισάγετε τον κωδικό από την εφαρμογή authenticator σας.',
'login.mfaHint': 'Ανοίξτε το Google Authenticator, Authy ή άλλη εφαρμογή TOTP.',
'login.mfaBack': '← Πίσω στη σύνδεση',
+1
View File
@@ -37,6 +37,7 @@ const login: TranslationStrings = {
'login.mfaTitle': 'אימות דו-שלבי',
'login.mfaSubtitle': 'הזינו את הקוד בן 6 הספרות מאפליקציית האימות.',
'login.mfaCodeLabel': 'קוד אימות',
'login.mfaPlaceholder': '000000 או XXXX-XXXX',
'login.mfaCodeRequired': 'הזינו את הקוד מאפליקציית האימות.',
'login.mfaHint': 'פתחו את Google Authenticator, Authy או אפליקציית TOTP אחרת.',
'login.mfaBack': '→ חזרה להתחברות',
+1
View File
@@ -39,6 +39,7 @@ const login: TranslationStrings = {
'login.mfaTitle': 'Kétfaktoros hitelesítés',
'login.mfaSubtitle': 'Add meg a 6 jegyű kódot a hitelesítő alkalmazásból.',
'login.mfaCodeLabel': 'Ellenőrző kód',
'login.mfaPlaceholder': '000000 vagy XXXX-XXXX',
'login.mfaCodeRequired': 'Add meg a kódot a hitelesítő alkalmazásból.',
'login.mfaHint': 'Nyisd meg a Google Authenticator, Authy vagy más TOTP alkalmazást.',
'login.mfaBack': '← Vissza a bejelentkezéshez',
+1
View File
@@ -38,6 +38,7 @@ const login: TranslationStrings = {
'login.mfaTitle': 'Autentikasi dua faktor',
'login.mfaSubtitle': 'Masukkan kode 6 digit dari aplikasi autentikator kamu.',
'login.mfaCodeLabel': 'Kode verifikasi',
'login.mfaPlaceholder': '000000 atau XXXX-XXXX',
'login.mfaCodeRequired': 'Masukkan kode dari aplikasi autentikator kamu.',
'login.mfaHint': 'Buka Google Authenticator, Authy, atau aplikasi TOTP lainnya.',
'login.mfaBack': '← Kembali ke halaman masuk',
+1
View File
@@ -39,6 +39,7 @@ const login: TranslationStrings = {
'login.mfaTitle': 'Autenticazione a due fattori',
'login.mfaSubtitle': 'Inserisci il codice a 6 cifre dalla tua app authenticator.',
'login.mfaCodeLabel': 'Codice di verifica',
'login.mfaPlaceholder': '000000 o XXXX-XXXX',
'login.mfaCodeRequired': 'Inserisci il codice dalla tua app authenticator.',
'login.mfaHint': "Apri Google Authenticator, Authy o un'altra app TOTP.",
'login.mfaBack': "← Torna all'accesso",
+1
View File
@@ -38,6 +38,7 @@ const login: TranslationStrings = {
'login.mfaTitle': '二要素認証',
'login.mfaSubtitle': '認証アプリの6桁コードを入力してください。',
'login.mfaCodeLabel': '確認コード',
'login.mfaPlaceholder': '000000 または XXXX-XXXX',
'login.mfaCodeRequired': '認証アプリのコードを入力してください。',
'login.mfaHint': 'Google Authenticator、Authy などのTOTPアプリを開いてください。',
'login.mfaBack': '← サインインに戻る',
+1
View File
@@ -37,6 +37,7 @@ const login: TranslationStrings = {
'login.mfaTitle': '2단계 인증',
'login.mfaSubtitle': '인증 앱의 6자리 코드를 입력하세요.',
'login.mfaCodeLabel': '인증 코드',
'login.mfaPlaceholder': '000000 또는 XXXX-XXXX',
'login.mfaCodeRequired': '인증 앱의 코드를 입력하세요.',
'login.mfaHint': 'Google Authenticator, Authy 또는 다른 TOTP 앱을 열어주세요.',
'login.mfaBack': '← 로그인으로 돌아가기',
+1
View File
@@ -25,6 +25,7 @@ const login: TranslationStrings = {
'login.mfaTitle': 'Tweefactorauthenticatie',
'login.mfaSubtitle': 'Voer de 6-cijferige code van je authenticator-app in.',
'login.mfaCodeLabel': 'Verificatiecode',
'login.mfaPlaceholder': '000000 of XXXX-XXXX',
'login.mfaCodeRequired': 'Voer de code van je authenticator-app in.',
'login.mfaHint': 'Open Google Authenticator, Authy of een andere TOTP-app.',
'login.mfaBack': '← Terug naar inloggen',
+1
View File
@@ -37,6 +37,7 @@ const login: TranslationStrings = {
'login.mfaTitle': 'Uwierzytelnianie dwuskładnikowe',
'login.mfaSubtitle': 'Wprowadź 6-cyfrowy kod z aplikacji uwierzytelniającej.',
'login.mfaCodeLabel': 'Kod weryfikacyjny',
'login.mfaPlaceholder': '000000 lub XXXX-XXXX',
'login.mfaCodeRequired': 'Wprowadź kod z aplikacji uwierzytelniającej.',
'login.mfaHint': 'Otwórz Google Authenticator, Authy lub inną aplikację TOTP.',
'login.mfaBack': '← Powrót do logowania',
+1
View File
@@ -26,6 +26,7 @@ const login: TranslationStrings = {
'login.mfaTitle': 'Двухфакторная аутентификация',
'login.mfaSubtitle': 'Введите 6-значный код из приложения-аутентификатора.',
'login.mfaCodeLabel': 'Код подтверждения',
'login.mfaPlaceholder': '000000 или XXXX-XXXX',
'login.mfaCodeRequired': 'Введите код из приложения-аутентификатора.',
'login.mfaHint': 'Откройте Google Authenticator, Authy или другое TOTP-приложение.',
'login.mfaBack': '← Назад к входу',
+1
View File
@@ -38,6 +38,7 @@ const login: TranslationStrings = {
'login.mfaTitle': 'Dvojfaktorové overenie',
'login.mfaSubtitle': 'Zadajte 6-miestny kód z vašej autentifikačnej aplikácie.',
'login.mfaCodeLabel': 'Overovací kód',
'login.mfaPlaceholder': '000000 alebo XXXX-XXXX',
'login.mfaCodeRequired': 'Zadajte kód z vašej autentifikačnej aplikácie.',
'login.mfaHint': 'Otvorte Google Authenticator, Authy alebo inú TOTP aplikáciu.',
'login.mfaBack': '← Späť na prihlásenie',
+1
View File
@@ -39,6 +39,7 @@ const login: TranslationStrings = {
'login.mfaTitle': 'Tvåfaktorsautentisering',
'login.mfaSubtitle': 'Ange den 6-siffriga koden från din autentiseringsapp.',
'login.mfaCodeLabel': 'Verifieringskod',
'login.mfaPlaceholder': '000000 eller XXXX-XXXX',
'login.mfaCodeRequired': 'Ange koden från din autentiseringsapp.',
'login.mfaHint': 'Öppna Google Authenticator, Authy eller någon annan TOTP-app.',
'login.mfaBack': '← Tillbaka till inloggningen',
+1
View File
@@ -38,6 +38,7 @@ const login: TranslationStrings = {
'login.mfaTitle': 'การรับรองความถูกต้องด้วยสองปัจจัย',
'login.mfaSubtitle': 'ป้อนรหัส 6 หลักจากแอปยืนยันตัวตนของคุณ',
'login.mfaCodeLabel': 'รหัสยืนยัน',
'login.mfaPlaceholder': '000000 หรือ XXXX-XXXX',
'login.mfaCodeRequired': 'ป้อนรหัสจากแอปยืนยันตัวตนของคุณ',
'login.mfaHint': 'เปิด Google Authenticator, Authy หรือแอป TOTP อื่น',
'login.mfaBack': '← กลับไปลงชื่อเข้าใช้',
+1
View File
@@ -39,6 +39,7 @@ const login: TranslationStrings = {
'login.mfaTitle': 'İki faktörlü kimlik doğrulama',
'login.mfaSubtitle': 'Kimlik doğrulayıcı uygulamanızdan 6 haneli kodu girin.',
'login.mfaCodeLabel': 'Doğrulama kodu',
'login.mfaPlaceholder': '000000 veya XXXX-XXXX',
'login.mfaCodeRequired': 'Kimlik doğrulayıcı uygulamanızdan kodu girin.',
'login.mfaHint': "Google Authenticator'ı, Authy'yi veya başka bir TOTP uygulamasını açın.",
'login.mfaBack': '← Oturum açmaya geri dön',
+1
View File
@@ -25,6 +25,7 @@ const login: TranslationStrings = {
'login.mfaTitle': 'Двофакторна автентифікація',
'login.mfaSubtitle': 'Введіть 6-значний код з додатка-автентифікатора.',
'login.mfaCodeLabel': 'Код підтвердження',
'login.mfaPlaceholder': '000000 або XXXX-XXXX',
'login.mfaCodeRequired': 'Введіть код із додатка-автентифікатора.',
'login.mfaHint': 'Відкрийте Google Authenticator, Authy або інший TOTP-додаток.',
'login.mfaBack': '← Назад до входу',
+1
View File
@@ -38,6 +38,7 @@ const login: TranslationStrings = {
'login.mfaTitle': 'Xác thực hai yếu tố',
'login.mfaSubtitle': 'Nhập mã gồm 6 chữ số từ ứng dụng xác thực của bạn.',
'login.mfaCodeLabel': 'Mã xác minh',
'login.mfaPlaceholder': '000000 hoặc XXXX-XXXX',
'login.mfaCodeRequired': 'Nhập mã từ ứng dụng xác thực của bạn.',
'login.mfaHint': 'Mở Google Authenticator, Authy hoặc ứng dụng TOTP khác.',
'login.mfaBack': '← Quay lại đăng nhập',
+1
View File
@@ -25,6 +25,7 @@ const login: TranslationStrings = {
'login.mfaTitle': '雙因素認證',
'login.mfaSubtitle': '請輸入身份驗證器應用中的 6 位驗證碼。',
'login.mfaCodeLabel': '驗證碼',
'login.mfaPlaceholder': '000000 或 XXXX-XXXX',
'login.mfaCodeRequired': '請輸入身份驗證器應用中的驗證碼。',
'login.mfaHint': '開啟 Google Authenticator、Authy 或其他 TOTP 應用。',
'login.mfaBack': '← 返回登入',
+1
View File
@@ -25,6 +25,7 @@ const login: TranslationStrings = {
'login.mfaTitle': '双因素认证',
'login.mfaSubtitle': '请输入身份验证器应用中的 6 位验证码。',
'login.mfaCodeLabel': '验证码',
'login.mfaPlaceholder': '000000 或 XXXX-XXXX',
'login.mfaCodeRequired': '请输入身份验证器应用中的验证码。',
'login.mfaHint': '打开 Google Authenticator、Authy 或其他 TOTP 应用。',
'login.mfaBack': '← 返回登录',