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 @@