2025-09-26 17:41:28 -05:00
< ? 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 );
}
}; ?>
2024-08-01 13:53:10 -05:00
<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">
2025-09-26 17:41:28 -05:00
<h3 class="text-lg font-medium">
2024-08-01 13:53:10 -05:00
@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>
2025-09-26 17:41:28 -05:00
<div class="mt-3 max-w-xl text-sm">
2024-08-01 13:53:10 -05:00
<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">
2025-09-26 17:41:28 -05:00
<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"
2024-08-01 13:53:10 -05:00
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>
2025-09-26 17:41:28 -05:00
<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">
2024-08-01 13:53:10 -05:00
@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">
2025-09-26 17:41:28 -05:00
<x-ui.button type="button" wire:loading.attr="disabled">
2024-08-01 13:53:10 -05:00
{{ __('Enable') }}
2025-09-26 17:41:28 -05:00
</x-ui.button>
2024-08-01 13:53:10 -05:00
</x-forms.confirms-password>
@else
@if ($showingRecoveryCodes)
<x-forms.confirms-password wire:then="regenerateRecoveryCodes">
2025-09-26 17:41:28 -05:00
<x-ui.button class="btn-outline" class="me-3">
2024-08-01 13:53:10 -05:00
{{ __('Regenerate Recovery Codes') }}
2025-09-26 17:41:28 -05:00
</x-ui.button>
2024-08-01 13:53:10 -05:00
</x-forms.confirms-password>
@elseif ($showingConfirmation)
<x-forms.confirms-password wire:then="confirmTwoFactorAuthentication">
2025-09-26 17:41:28 -05:00
<x-ui.button type="button" class="me-3" wire:loading.attr="disabled">
2024-08-01 13:53:10 -05:00
{{ __('Confirm') }}
2025-09-26 17:41:28 -05:00
</x-ui.button>
2024-08-01 13:53:10 -05:00
</x-forms.confirms-password>
@else
<x-forms.confirms-password wire:then="showRecoveryCodes">
2025-09-26 17:41:28 -05:00
<x-ui.button class="btn-outline" class="me-3">
2024-08-01 13:53:10 -05:00
{{ __('Show Recovery Codes') }}
2025-09-26 17:41:28 -05:00
</x-ui.button>
2024-08-01 13:53:10 -05:00
</x-forms.confirms-password>
@endif
@if ($showingConfirmation)
<x-forms.confirms-password wire:then="disableTwoFactorAuthentication">
2025-09-26 17:41:28 -05:00
<x-ui.button class="btn-outline" wire:loading.attr="disabled">
2024-08-01 13:53:10 -05:00
{{ __('Cancel') }}
2025-09-26 17:41:28 -05:00
</x-ui.button>
2024-08-01 13:53:10 -05:00
</x-forms.confirms-password>
@else
<x-forms.confirms-password wire:then="disableTwoFactorAuthentication">
2025-09-26 17:41:28 -05:00
<x-ui.button class="btn-error text-white" wire:loading.attr="disabled">
2024-08-01 13:53:10 -05:00
{{ __('Disable') }}
2025-09-26 17:41:28 -05:00
</x-ui.button>
2024-08-01 13:53:10 -05:00
</x-forms.confirms-password>
@endif
@endif
</div>
</x-slot>
</x-forms.action-section>