> public static function modalMaxWidth(): string { // mögliche Werte: 'sm','md','lg','xl','2xl','3xl','4xl','5xl','6xl','7xl' return 'xl'; // kompakt für TOTP } public function mount(): void { $user = Auth::user(); $ga = new GoogleAuthenticator(); // Falls User schon Secret hat: wiederverwenden, sonst neues anlegen $this->secret = $user->totp_secret ?: $ga->createSecret(); $issuer = config('app.name', 'MailWolt'); // getQRCodeUrl(accountName, secret, issuer) => PNG Data-URI $this->qrPng = $ga->getQRCodeUrl($user->email, $this->secret, $issuer); $this->alreadyActive = (bool) ($user->two_factor_enabled ?? false); } #[On('security:totp:enable')] public function verifyAndEnable(string $code): void { $code = preg_replace('/\D/', '', $code ?? ''); if (strlen($code) !== 6) { $this->dispatch('toast', body: 'Bitte 6-stelligen Code eingeben.'); return; } $ga = new GoogleAuthenticator(); $ok = $ga->verifyCode($this->secret, $code, 2); // 2 × 30 s Toleranz if (!$ok) { $this->dispatch('toast', body: 'Code ungültig. Versuche es erneut.'); return; } $user = Auth::user(); $user->totp_secret = $this->secret; $user->two_factor_enabled = true; $user->save(); $this->dispatch('totp-enabled'); $this->dispatch('toast', body: 'TOTP aktiviert.'); $this->dispatch('closeModal'); } public function disable(): void { $user = Auth::user(); $user->totp_secret = null; $user->two_factor_enabled = false; $user->save(); $this->dispatch('totp-disabled'); $this->dispatch('toast', body: 'TOTP deaktiviert.'); $this->dispatch('closeModal'); } public function saveAccount() { /* $this->validate(..); user->update([...]) */ } public function changePassword() { /* validate & set */ } public function changeEmail() { /* validate, send verify link, etc. */ } public function openRecovery() { /* optional modal or page */ } public function logoutOthers() { /* … */ } public function logoutSession(string $id) { /* … */ } public function render() { return view('livewire.ui.security.modal.totp-setup-modal'); } }