From 8ba0195ba13864ad390e3c6efedff925adc238b0 Mon Sep 17 00:00:00 2001 From: Philipp Reinking Date: Thu, 22 Oct 2026 15:56:50 +0200 Subject: [PATCH] Make the 2FA Log in button submit the form Co-Authored-By: Claude Sonnet 5.5 --- CHANGELOG.md | 1 + .../js/Pages/Auth/TwoFactorChallenge.test.ts | 45 +++++++++++++++++++ .../js/Pages/Auth/TwoFactorChallenge.vue | 1 + 3 files changed, 47 insertions(+) create mode 100644 resources/js/Pages/Auth/TwoFactorChallenge.test.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index bd0f0f43..9ee045bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ Lines marked **Upgrade step** need you to act after updating. ### Fixed +- Clicking "Log in" on the two-factor code screen now sends the code. Before, only Enter worked. (#299) - No more PHP 8.5 deprecation warning for the MySQL SSL option on container start. (#298) ## [2.3.0] - 2026-10-22 diff --git a/resources/js/Pages/Auth/TwoFactorChallenge.test.ts b/resources/js/Pages/Auth/TwoFactorChallenge.test.ts new file mode 100644 index 00000000..bb48a547 --- /dev/null +++ b/resources/js/Pages/Auth/TwoFactorChallenge.test.ts @@ -0,0 +1,45 @@ +import { mount } from "@vue/test-utils"; +import { beforeEach, describe, expect, it, vi } from "vitest"; +import { router, useForm } from "@inertiajs/vue3"; +import TwoFactorChallenge from "./TwoFactorChallenge.vue"; + +const mountChallenge = () => + mount(TwoFactorChallenge, { + attachTo: document.body, + global: { + mocks: { $inertia: { form: useForm }, route: (name: string) => name }, + stubs: { Head: true, Link: true, JetValidationErrors: true }, + }, + }); + +describe("log in button on the two-factor challenge", () => { + beforeEach(() => { + vi.restoreAllMocks(); + vi.spyOn(router, "post").mockImplementation(() => {}); + }); + + it("sends the code when clicked", async () => { + const wrapper = mountChallenge(); + + await wrapper.find("input").setValue("123456"); + await wrapper.find("button[type=submit]").trigger("click"); + + expect(router.post).toHaveBeenCalledOnce(); + expect(vi.mocked(router.post).mock.calls[0][1]).toMatchObject({ + code: "123456", + }); + }); + + it("sends the recovery code when clicked", async () => { + const wrapper = mountChallenge(); + + await wrapper.find("button[type=button]").trigger("click"); + await wrapper.find("input").setValue("abc-def"); + await wrapper.find("button[type=submit]").trigger("click"); + + expect(router.post).toHaveBeenCalledOnce(); + expect(vi.mocked(router.post).mock.calls[0][1]).toMatchObject({ + recovery_code: "abc-def", + }); + }); +}); diff --git a/resources/js/Pages/Auth/TwoFactorChallenge.vue b/resources/js/Pages/Auth/TwoFactorChallenge.vue index c69bc7dd..08fef71b 100644 --- a/resources/js/Pages/Auth/TwoFactorChallenge.vue +++ b/resources/js/Pages/Auth/TwoFactorChallenge.vue @@ -68,6 +68,7 @@