From 39ee2b7a4961722a73e470f36a2636c73a05776d Mon Sep 17 00:00:00 2001 From: vladtechno Date: Tue, 18 Aug 2026 15:19:11 +1000 Subject: [PATCH] =?UTF-8?q?fix(pwa):=20=D0=BA=D0=BE=D0=B4=20=D0=B4=D0=B2?= =?UTF-8?q?=D1=83=D1=85=D1=84=D0=B0=D0=BA=D1=82=D0=BE=D1=80=D0=BA=D0=B8=20?= =?UTF-8?q?=D1=83=D1=85=D0=BE=D0=B4=D0=B8=D1=82=20=D1=81=D0=B0=D0=BC,=20?= =?UTF-8?q?=D0=B0=20=D0=BD=D0=B5=20=D0=B6=D0=B4=D1=91=D1=82=20=D0=BA=D0=BD?= =?UTF-8?q?=D0=BE=D0=BF=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Второй шаг входа сотрудника не отправлялся вовсе: у поля с кодом не было ни обработки Enter, ни автоотправки, а «Готово» на клавиатуре телефона — это как раз Enter. Со стороны выглядело как «код не принят», хотя запрос на /auth/2fa не уходил ни разу (в логах бэкенда — только login с ответом «нужен второй шаг»). Теперь шесть цифр отправляются сразу, Enter тоже работает, поле получает фокус и autocomplete=one-time-code (подсказка кода из СМС/менеджера паролей). Co-Authored-By: Claude Opus 5 --- .../frontend/src/pages/DevLoginPage.test.tsx | 3 ++- .../frontend/src/pages/DevLoginPage.tsx | 20 ++++++++++++++----- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/driver-pwa/frontend/src/pages/DevLoginPage.test.tsx b/driver-pwa/frontend/src/pages/DevLoginPage.test.tsx index 8f25e2d..b3e9763 100644 --- a/driver-pwa/frontend/src/pages/DevLoginPage.test.tsx +++ b/driver-pwa/frontend/src/pages/DevLoginPage.test.tsx @@ -59,8 +59,9 @@ describe("DevLoginPage", () => { await userEvent.click(screen.getByRole("button", { name: "Войти" })); expect(useStaff.getState().token).toBeNull(); + // Шестая цифра отправляет код сама: раньше форма ждала нажатия, а «Готово» на + // клавиатуре телефона ничего не делало — выглядело как «код не принят». await userEvent.type(await screen.findByPlaceholderText("000000"), "123456"); - await userEvent.click(screen.getByRole("button", { name: "Подтвердить" })); expect(staffApi.staffLogin2fa).toHaveBeenCalledWith("partial", "123456"); expect(useStaff.getState().token).toBe("staff-tok"); }); diff --git a/driver-pwa/frontend/src/pages/DevLoginPage.tsx b/driver-pwa/frontend/src/pages/DevLoginPage.tsx index 0d06b2f..e5771ef 100644 --- a/driver-pwa/frontend/src/pages/DevLoginPage.tsx +++ b/driver-pwa/frontend/src/pages/DevLoginPage.tsx @@ -42,11 +42,11 @@ export function DevLoginPage() { } } - async function submit2fa() { - if (!partial || code.length < 6 || busy) return; + async function submit2fa(value = code) { + if (!partial || value.length < 6 || busy) return; setBusy(true); try { - const r = await staffLogin2fa(partial, code); + const r = await staffLogin2fa(partial, value); if (!r.access_token) throw new Error("no token"); setStaff(r.access_token, username); setPartial(null); @@ -80,13 +80,23 @@ export function DevLoginPage() { <>

Код из приложения-аутентификатора.

setCode(e.target.value.replace(/\D/g, "").slice(0, 6))} + onChange={(e) => { + const next = e.target.value.replace(/\D/g, "").slice(0, 6); + setCode(next); + // Шесть цифр — код собран, ждать нажатия нечего: у TOTP всё равно + // остаётся секунд тридцать. Раньше отправки не было ни по Enter, ни + // по «Готово» на клавиатуре телефона, и это выглядело как «код не принят». + if (next.length === 6) void submit2fa(next); + }} + onKeyDown={(e) => { if (e.key === "Enter") void submit2fa(); }} placeholder="000000" className="card w-full px-4 py-3 mb-3 text-base tracking-widest bg-white" /> -