e6f38d9481
* docs: remove requirement for setting APP_KEY manually * optimize date picker * clean up modals * spot light working * reorganization * add lazy load * wip * remove filament * styling
289 lines
9.7 KiB
PHP
289 lines
9.7 KiB
PHP
<?php
|
|
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Laravel\Fortify\Actions\ConfirmTwoFactorAuthentication;
|
|
use Laravel\Fortify\Actions\DisableTwoFactorAuthentication;
|
|
use Laravel\Fortify\Actions\EnableTwoFactorAuthentication;
|
|
use Laravel\Fortify\Actions\GenerateNewRecoveryCodes;
|
|
use Livewire\Volt\Component;
|
|
use Laravel\Fortify\Features;
|
|
use App\Traits\ConfirmsPasswords;
|
|
|
|
new class extends Component
|
|
{
|
|
use ConfirmsPasswords;
|
|
|
|
/**
|
|
* Indicates if two factor authentication QR code is being displayed.
|
|
*
|
|
* @var bool
|
|
*/
|
|
public $showingQrCode = false;
|
|
|
|
/**
|
|
* Indicates if the two factor authentication confirmation input and button are being displayed.
|
|
*
|
|
* @var bool
|
|
*/
|
|
public $showingConfirmation = false;
|
|
|
|
/**
|
|
* Indicates if two factor authentication recovery codes are being displayed.
|
|
*
|
|
* @var bool
|
|
*/
|
|
public $showingRecoveryCodes = false;
|
|
|
|
/**
|
|
* The OTP code for confirming two factor authentication.
|
|
*
|
|
* @var string|null
|
|
*/
|
|
public $code;
|
|
|
|
/**
|
|
* Mount the component.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function mount()
|
|
{
|
|
if (Features::optionEnabled(Features::twoFactorAuthentication(), 'confirm') &&
|
|
is_null(Auth::user()->two_factor_confirmed_at)) {
|
|
app(DisableTwoFactorAuthentication::class)(Auth::user());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Enable two factor authentication for the user.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function enableTwoFactorAuthentication(EnableTwoFactorAuthentication $enable)
|
|
{
|
|
if (Features::optionEnabled(Features::twoFactorAuthentication(), 'confirmPassword')) {
|
|
$this->ensurePasswordIsConfirmed();
|
|
}
|
|
|
|
$enable(Auth::user());
|
|
|
|
$this->showingQrCode = true;
|
|
|
|
if (Features::optionEnabled(Features::twoFactorAuthentication(), 'confirm')) {
|
|
$this->showingConfirmation = true;
|
|
} else {
|
|
$this->showingRecoveryCodes = true;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Confirm two factor authentication for the user.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function confirmTwoFactorAuthentication(ConfirmTwoFactorAuthentication $confirm)
|
|
{
|
|
if (Features::optionEnabled(Features::twoFactorAuthentication(), 'confirmPassword')) {
|
|
$this->ensurePasswordIsConfirmed();
|
|
}
|
|
|
|
$confirm(Auth::user(), $this->code);
|
|
|
|
$this->showingQrCode = false;
|
|
$this->showingConfirmation = false;
|
|
$this->showingRecoveryCodes = true;
|
|
}
|
|
|
|
/**
|
|
* Display the user's recovery codes.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function showRecoveryCodes()
|
|
{
|
|
if (Features::optionEnabled(Features::twoFactorAuthentication(), 'confirmPassword')) {
|
|
$this->ensurePasswordIsConfirmed();
|
|
}
|
|
|
|
$this->showingRecoveryCodes = true;
|
|
}
|
|
|
|
/**
|
|
* Generate new recovery codes for the user.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function regenerateRecoveryCodes(GenerateNewRecoveryCodes $generate)
|
|
{
|
|
if (Features::optionEnabled(Features::twoFactorAuthentication(), 'confirmPassword')) {
|
|
$this->ensurePasswordIsConfirmed();
|
|
}
|
|
|
|
$generate(Auth::user());
|
|
|
|
$this->showingRecoveryCodes = true;
|
|
}
|
|
|
|
/**
|
|
* Disable two factor authentication for the user.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function disableTwoFactorAuthentication(DisableTwoFactorAuthentication $disable)
|
|
{
|
|
if (Features::optionEnabled(Features::twoFactorAuthentication(), 'confirmPassword')) {
|
|
$this->ensurePasswordIsConfirmed();
|
|
}
|
|
|
|
$disable(Auth::user());
|
|
|
|
$this->showingQrCode = false;
|
|
$this->showingConfirmation = false;
|
|
$this->showingRecoveryCodes = false;
|
|
}
|
|
|
|
/**
|
|
* Get the current user of the application.
|
|
*
|
|
* @return mixed
|
|
*/
|
|
public function getUserProperty()
|
|
{
|
|
return Auth::user();
|
|
}
|
|
|
|
/**
|
|
* Determine if two factor authentication is enabled.
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function getEnabledProperty()
|
|
{
|
|
return ! empty($this->user->two_factor_secret);
|
|
}
|
|
}; ?>
|
|
|
|
<x-forms.action-section>
|
|
<x-slot name="title">
|
|
{{ __('Two Factor Authentication') }}
|
|
</x-slot>
|
|
|
|
<x-slot name="description">
|
|
{{ __('Add additional security to your account using two factor authentication.') }}
|
|
</x-slot>
|
|
|
|
<x-slot name="content">
|
|
<h3 class="text-lg font-medium">
|
|
@if ($this->enabled)
|
|
@if ($showingConfirmation)
|
|
{{ __('Finish enabling two factor authentication.') }}
|
|
@else
|
|
{{ __('You have enabled two factor authentication.') }}
|
|
@endif
|
|
@else
|
|
{{ __('You have not enabled two factor authentication.') }}
|
|
@endif
|
|
</h3>
|
|
|
|
<div class="mt-3 max-w-xl text-sm">
|
|
<p>
|
|
{{ __('When two factor authentication is enabled, you will be prompted for a secure, random token during authentication. You may retrieve this token from your phone\'s Google Authenticator application.') }}
|
|
</p>
|
|
</div>
|
|
|
|
@if ($this->enabled)
|
|
@if ($showingQrCode)
|
|
<div class="mt-4 max-w-xl text-sm text-gray-600 dark:text-gray-400">
|
|
<p class="font-semibold">
|
|
@if ($showingConfirmation)
|
|
{{ __('To finish enabling two factor authentication, scan the following QR code using your phone\'s authenticator application or enter the setup key and provide the generated OTP code.') }}
|
|
@else
|
|
{{ __('Two factor authentication is now enabled. Scan the following QR code using your phone\'s authenticator application or enter the setup key.') }}
|
|
@endif
|
|
</p>
|
|
</div>
|
|
|
|
<div class="mt-4 p-2 inline-block bg-white">
|
|
{!! $this->user->twoFactorQrCodeSvg() !!}
|
|
</div>
|
|
|
|
<div class="mt-4 max-w-xl text-sm text-gray-600 dark:text-gray-400">
|
|
<p class="font-semibold">
|
|
{{ __('Setup Key') }}: {{ decrypt($this->user->two_factor_secret) }}
|
|
</p>
|
|
</div>
|
|
|
|
@if ($showingConfirmation)
|
|
<div class="mt-4">
|
|
|
|
|
|
<x-ui.input id="code" label="{{ __('Code') }}" type="text" name="code" class="block mt-1 w-1/2" inputmode="numeric" autofocus autocomplete="one-time-code"
|
|
wire:model="code"
|
|
wire:keydown.enter="confirmTwoFactorAuthentication" />
|
|
|
|
</div>
|
|
@endif
|
|
@endif
|
|
|
|
@if ($showingRecoveryCodes)
|
|
<div class="mt-4 max-w-xl text-sm text-gray-600 dark:text-gray-400">
|
|
<p class="font-semibold">
|
|
{{ __('Store these recovery codes in a secure password manager. They can be used to recover access to your account if your two factor authentication device is lost.') }}
|
|
</p>
|
|
</div>
|
|
|
|
<div class="grid gap-1 max-w-xl mt-4 px-4 py-4 font-mono text-sm bg-base-100 dark:text-gray-100 rounded-lg">
|
|
@foreach (json_decode(decrypt($this->user->two_factor_recovery_codes), true) as $code)
|
|
<div>{{ $code }}</div>
|
|
@endforeach
|
|
</div>
|
|
@endif
|
|
@endif
|
|
|
|
<div class="mt-5">
|
|
@if (! $this->enabled)
|
|
<x-forms.confirms-password wire:then="enableTwoFactorAuthentication">
|
|
<x-ui.button type="button" wire:loading.attr="disabled">
|
|
{{ __('Enable') }}
|
|
</x-ui.button>
|
|
</x-forms.confirms-password>
|
|
@else
|
|
@if ($showingRecoveryCodes)
|
|
<x-forms.confirms-password wire:then="regenerateRecoveryCodes">
|
|
<x-ui.button class="btn-outline" class="me-3">
|
|
{{ __('Regenerate Recovery Codes') }}
|
|
</x-ui.button>
|
|
</x-forms.confirms-password>
|
|
@elseif ($showingConfirmation)
|
|
<x-forms.confirms-password wire:then="confirmTwoFactorAuthentication">
|
|
<x-ui.button type="button" class="me-3" wire:loading.attr="disabled">
|
|
{{ __('Confirm') }}
|
|
</x-ui.button>
|
|
</x-forms.confirms-password>
|
|
@else
|
|
<x-forms.confirms-password wire:then="showRecoveryCodes">
|
|
<x-ui.button class="btn-outline" class="me-3">
|
|
{{ __('Show Recovery Codes') }}
|
|
</x-ui.button>
|
|
</x-forms.confirms-password>
|
|
@endif
|
|
|
|
@if ($showingConfirmation)
|
|
<x-forms.confirms-password wire:then="disableTwoFactorAuthentication">
|
|
<x-ui.button class="btn-outline" wire:loading.attr="disabled">
|
|
{{ __('Cancel') }}
|
|
</x-ui.button>
|
|
</x-forms.confirms-password>
|
|
@else
|
|
<x-forms.confirms-password wire:then="disableTwoFactorAuthentication">
|
|
<x-ui.button class="btn-error text-white" wire:loading.attr="disabled">
|
|
{{ __('Disable') }}
|
|
</x-ui.button>
|
|
</x-forms.confirms-password>
|
|
@endif
|
|
|
|
@endif
|
|
</div>
|
|
</x-slot>
|
|
</x-forms.action-section>
|