From 4ea4050c80fec1e1f55778a7d69e8894d568e5ed Mon Sep 17 00:00:00 2001 From: boban Date: Sat, 20 Jun 2026 16:19:40 +0200 Subject: [PATCH] =?UTF-8?q?fix(auth):=20R15=20review=20=E2=80=94=20restore?= =?UTF-8?q?=20one-time-code=20autofill,=20memoise=20pendingUser=20in=20ver?= =?UTF-8?q?ify?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - backup field: autocomplete=off -> one-time-code (backup codes ARE one-time codes; matches the main challenge field, the rest of the app, and the spec; restores password-manager OTP autofill that the earlier polish broke) - both verify() use the trait's memoised $this->pendingUser() instead of a fresh User::find(), saving a redundant query on the failed-attempt re-render (Pint dropped the now-unused User import in TwoFactorBackup) - spec: align trait backing-state visibility note to the implemented 'private' Co-Authored-By: Claude Opus 4.8 --- app/Livewire/Auth/TwoFactorBackup.php | 3 +-- app/Livewire/Auth/TwoFactorChallenge.php | 2 +- .../specs/2026-06-20-2fa-challenge-backup-view-design.md | 3 ++- resources/views/livewire/auth/two-factor-backup.blade.php | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/Livewire/Auth/TwoFactorBackup.php b/app/Livewire/Auth/TwoFactorBackup.php index 14546b9..a40a9c9 100644 --- a/app/Livewire/Auth/TwoFactorBackup.php +++ b/app/Livewire/Auth/TwoFactorBackup.php @@ -3,7 +3,6 @@ namespace App\Livewire\Auth; use App\Livewire\Concerns\CompletesTwoFactorChallenge; -use App\Models\User; use Illuminate\Validation\ValidationException; use Livewire\Attributes\Layout; use Livewire\Attributes\Validate; @@ -30,7 +29,7 @@ class TwoFactorBackup extends Component $this->assertNotRateLimited(); - $user = User::find(session('2fa.user')); + $user = $this->pendingUser(); if (! $user || ! $user->hasTwoFactorEnabled()) { session()->forget(['2fa.user', '2fa.remember']); diff --git a/app/Livewire/Auth/TwoFactorChallenge.php b/app/Livewire/Auth/TwoFactorChallenge.php index 29aacc0..663426b 100644 --- a/app/Livewire/Auth/TwoFactorChallenge.php +++ b/app/Livewire/Auth/TwoFactorChallenge.php @@ -37,7 +37,7 @@ class TwoFactorChallenge extends Component $this->assertNotRateLimited(); - $user = User::find(session('2fa.user')); + $user = $this->pendingUser(); if (! $user || ! $user->hasTwoFactorEnabled()) { session()->forget(['2fa.user', '2fa.remember']); diff --git a/docs/superpowers/specs/2026-06-20-2fa-challenge-backup-view-design.md b/docs/superpowers/specs/2026-06-20-2fa-challenge-backup-view-design.md index 4512b9d..57bfa3a 100644 --- a/docs/superpowers/specs/2026-06-20-2fa-challenge-backup-view-design.md +++ b/docs/superpowers/specs/2026-06-20-2fa-challenge-backup-view-design.md @@ -40,7 +40,8 @@ Extract the logic currently inline in `TwoFactorChallenge` into a trait used by components, so there is no duplication and **one shared rate-limit bucket set**: - `pendingUser(): ?User` — the memoised `User::find(session('2fa.user'))` resolver (move the existing - one; keep its backing state `protected` so both components share it). + one; keep its backing state `private` — an internal memoisation detail; each component gets its + own copy, and Livewire persists only public props, so the visibility is runtime-irrelevant). - `getPendingHasTotpProperty(): bool` — **keep the existing Livewire computed-property magic getter** (move it verbatim into the trait, do **not** turn it into a plain `pendingHasTotp()` method). This keeps every blade's `$this->pendingHasTotp` usage working unchanged — **no property→method rewrites diff --git a/resources/views/livewire/auth/two-factor-backup.blade.php b/resources/views/livewire/auth/two-factor-backup.blade.php index ef7aa71..6e97073 100644 --- a/resources/views/livewire/auth/two-factor-backup.blade.php +++ b/resources/views/livewire/auth/two-factor-backup.blade.php @@ -14,7 +14,7 @@
- @error('code')

{{ $message }}

@enderror