From b8177890a5f8956af682fe1145a85fe152d48366 Mon Sep 17 00:00:00 2001 From: Joseph Rollinson Date: Sat, 17 Oct 2026 21:50:03 -0400 Subject: [PATCH] fix: prevent double submission of login and TOTP forms The TOTP form auto-submits when the sixth digit is entered (#790), but a follow-up Enter keypress or password-manager form submit still fires a second POST /api/user/totp. The first request consumes the pending TOTP session, so the duplicate gets 401 and the mutation error handler raises a false verification-failed toast right before the redirect. The login form has the same unguarded path: autofill plus Enter double-submits /api/user/login, creating extra pending TOTP sessions and counting against the login rate limit. Ignore submissions while the mutation is pending or after it succeeded; retries after a failed verification still work. AI disclosure per AI_POLICY.md: drafted with AI assistance, small patch, to be reviewed and understood by the author before marking ready. --- frontend/src/pages/login-page.tsx | 11 +++++++++-- frontend/src/pages/totp-page.tsx | 5 ++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/frontend/src/pages/login-page.tsx b/frontend/src/pages/login-page.tsx index 91478e6c..b47b1842 100644 --- a/frontend/src/pages/login-page.tsx +++ b/frontend/src/pages/login-page.tsx @@ -122,7 +122,11 @@ export const LoginPage = () => { }, }); - const { mutate: loginMutate, isPending: loginIsPending } = useMutation({ + const { + mutate: loginMutate, + isPending: loginIsPending, + isSuccess: loginIsSuccess, + } = useMutation({ mutationFn: (values: LoginSchema) => axios.post("/api/user/login", values), mutationKey: ["login"], onSuccess: (data) => { @@ -309,7 +313,10 @@ export const LoginPage = () => { )} {userAuthConfigured && ( loginMutate(values)} + onSubmit={(values) => { + if (loginIsPending || loginIsSuccess) return; + loginMutate(values); + }} loading={loginIsPending || oauthIsPending} formId={formId} params={(() => { diff --git a/frontend/src/pages/totp-page.tsx b/frontend/src/pages/totp-page.tsx index 3b9a6ef7..209194de 100644 --- a/frontend/src/pages/totp-page.tsx +++ b/frontend/src/pages/totp-page.tsx @@ -87,7 +87,10 @@ export const TotpPage = () => { totpMutation.mutate(values)} + onSubmit={(values) => { + if (totpMutation.isPending || totpMutation.isSuccess) return; + totpMutation.mutate(values); + }} />