dispatch('openModal', component: 'modals.confirm-action', arguments: [ 'heading' => __('settings.disable_2fa_heading'), 'body' => __('settings.disable_2fa_body'), 'confirmLabel' => __('common.disable'), 'danger' => true, 'icon' => 'shield', 'notify' => __('settings.disable_2fa_notify'), 'token' => ConfirmToken::issue( 'twoFactorDisabled', [], 'two_factor.disable', Auth::user()?->email, ), ], ); } #[On('twoFactorDisabled')] public function disableTwoFactor(string $confirmToken): void { try { ConfirmToken::consume($confirmToken, 'twoFactorDisabled'); } catch (InvalidConfirmToken) { return; // forged / replayed / direct-bypass attempt — no-op } // Remove the TOTP factor only — security keys are managed on their own card. If no // factor remains afterwards, the backup codes are dropped too. Auth::user()->forceFill([ 'two_factor_secret' => null, 'two_factor_confirmed_at' => null, ])->save(); Auth::user()->resetIfNoFactor(); } public function render() { return view('livewire.settings.security', [ 'twoFactorEnabled' => Auth::user()->hasTwoFactorEnabled(), 'hasTotp' => Auth::user()->hasTotp(), ]); } }