From 4a3c201741490d62f1ee178b6f12cd0628f8ec50 Mon Sep 17 00:00:00 2001 From: miloschwartz Date: Wed, 3 Jun 2026 21:54:55 -0700 Subject: [PATCH] improve mfa autofill --- src/components/LoginForm.tsx | 1 + src/components/LoginPasswordForm.tsx | 1 + src/components/MfaInputForm.tsx | 95 ++++++++++------------------ 3 files changed, 36 insertions(+), 61 deletions(-) diff --git a/src/components/LoginForm.tsx b/src/components/LoginForm.tsx index 0bd606671..fe3c80667 100644 --- a/src/components/LoginForm.tsx +++ b/src/components/LoginForm.tsx @@ -345,6 +345,7 @@ export default function LoginForm({ error={error} loading={loading} formId="form" + username={form.getValues("email")} /> )} diff --git a/src/components/LoginPasswordForm.tsx b/src/components/LoginPasswordForm.tsx index b2cb31754..d6e0c0b79 100644 --- a/src/components/LoginPasswordForm.tsx +++ b/src/components/LoginPasswordForm.tsx @@ -265,6 +265,7 @@ export default function LoginPasswordForm({ }} error={error} loading={loading} + username={identifier} /> ); } diff --git a/src/components/MfaInputForm.tsx b/src/components/MfaInputForm.tsx index 221e51218..e80c730fc 100644 --- a/src/components/MfaInputForm.tsx +++ b/src/components/MfaInputForm.tsx @@ -1,6 +1,5 @@ "use client"; -import { useEffect, useRef } from "react"; import { UseFormReturn } from "react-hook-form"; import { Button } from "@app/components/ui/button"; import { @@ -8,17 +7,15 @@ import { FormControl, FormField, FormItem, + FormLabel, FormMessage } from "@app/components/ui/form"; -import { - InputOTP, - InputOTPGroup, - InputOTPSlot -} from "./ui/input-otp"; +import { InputOTP, InputOTPGroup, InputOTPSlot } from "./ui/input-otp"; import { Alert, AlertDescription } from "@app/components/ui/alert"; import { useTranslations } from "next-intl"; -import { REGEXP_ONLY_DIGITS_AND_CHARS } from "input-otp"; -import * as z from "zod"; +import { REGEXP_ONLY_DIGITS } from "input-otp"; + +const MFA_OTP_INPUT_ID = "mfa-otp-code"; type MfaInputFormProps = { form: UseFormReturn<{ code: string }>; @@ -27,6 +24,7 @@ type MfaInputFormProps = { error?: string | null; loading?: boolean; formId?: string; + username?: string; }; export default function MfaInputForm({ @@ -35,55 +33,10 @@ export default function MfaInputForm({ onBack, error, loading = false, - formId = "mfaForm" + formId = "mfaForm", + username }: MfaInputFormProps) { const t = useTranslations(); - const otpContainerRef = useRef(null); - - // Auto-focus MFA input when component mounts - useEffect(() => { - const focusInput = () => { - // Try using the ref first - if (otpContainerRef.current) { - const hiddenInput = otpContainerRef.current.querySelector( - "input" - ) as HTMLInputElement; - if (hiddenInput) { - hiddenInput.focus(); - return; - } - } - - // Fallback: query the DOM - const otpContainer = document.querySelector( - '[data-slot="input-otp"]' - ); - if (!otpContainer) return; - - const hiddenInput = otpContainer.querySelector( - "input" - ) as HTMLInputElement; - if (hiddenInput) { - hiddenInput.focus(); - return; - } - - // Last resort: click the first slot - const firstSlot = otpContainer.querySelector( - '[data-slot="input-otp-slot"]' - ) as HTMLElement; - if (firstSlot) { - firstSlot.click(); - } - }; - - // Use requestAnimationFrame to wait for the next paint - requestAnimationFrame(() => { - requestAnimationFrame(() => { - focusInput(); - }); - }); - }, []); return (
@@ -99,25 +52,45 @@ export default function MfaInputForm({ className="space-y-4" id={formId} > + {username ? ( + + ) : null} ( + + {t("otpAuth")} + -
+
{ field.onChange(value); if (value.length === 6) { - form.handleSubmit(onSubmit)(); + form.handleSubmit( + onSubmit + )(); } }} >