62 lines
1.7 KiB
PHP
62 lines
1.7 KiB
PHP
<?php
|
|
|
|
namespace App\Livewire\Auth;
|
|
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Illuminate\Validation\ValidationException;
|
|
use Livewire\Attributes\Layout;
|
|
use Livewire\Attributes\Validate;
|
|
use Livewire\Component;
|
|
use PragmaRX\Google2FAQRCode\Google2FA;
|
|
|
|
#[Layout('layouts.app')]
|
|
class TwoFactorSetup extends Component
|
|
{
|
|
public string $secret = '';
|
|
|
|
#[Validate('required|string')]
|
|
public string $code = '';
|
|
|
|
public function mount()
|
|
{
|
|
if (Auth::user()->hasTotp()) {
|
|
return $this->redirect(route('settings'), navigate: true);
|
|
}
|
|
|
|
$this->secret = (new Google2FA)->generateSecretKey();
|
|
}
|
|
|
|
public function confirm()
|
|
{
|
|
$this->validate();
|
|
|
|
if (! (new Google2FA)->verifyKey($this->secret, preg_replace('/\s+/', '', $this->code))) {
|
|
throw ValidationException::withMessages(['code' => __('auth.code_mismatch')]);
|
|
}
|
|
|
|
Auth::user()->forceFill([
|
|
'two_factor_secret' => $this->secret,
|
|
'two_factor_confirmed_at' => now(),
|
|
])->save();
|
|
|
|
// First factor enrolled and no codes yet → generate the single recovery set and
|
|
// ask Settings to pop the modal (the app layout hosts wire-elements/modal).
|
|
if (! Auth::user()->hasRecoveryCodes()) {
|
|
Auth::user()->replaceRecoveryCodes();
|
|
session()->flash('open_recovery_modal', true);
|
|
}
|
|
|
|
return $this->redirect(route('settings'), navigate: true);
|
|
}
|
|
|
|
public function qrCode(): string
|
|
{
|
|
return (new Google2FA)->getQRCodeInline('Clusev', Auth::user()->email, $this->secret);
|
|
}
|
|
|
|
public function render()
|
|
{
|
|
return view('livewire.auth.two-factor-setup')->title(__('auth.title_setup'));
|
|
}
|
|
}
|