From de044595a766492961c50e0bfdbcba2fa1408feb Mon Sep 17 00:00:00 2001
From: Amir
Date: Thu, 27 Oct 2022 17:50:24 +0400
Subject: [PATCH] Implementation of Admin Two Factor Authentication
---
app/Actions/Fortify/ConfirmPassword.php | 52 +++++
...woFactorAuthenticatedSessionController.php | 73 +++++++
.../TwoFactorAuthenticationController.php | 44 +++++
.../RedirectIfTwoFactorAuthenticatable.php | 42 ++--
app/Actions/Jetstream/DeleteUser.php | 11 +-
.../AdminTwoFactorAuthenticationForm.php | 181 ++++++++++++++++++
app/Providers/FortifyServiceProvider.php | 6 +-
app/Traits/ConfirmsPasswords.php | 116 +++++++++++
...add_two_factor_columns_to_admins_table.php | 50 +++++
resources/views/navigation-menu.blade.php | 2 +-
...n-two-factor-authentication-form.blade.php | 126 ++++++++++++
resources/views/profile/show.blade.php | 48 +++--
.../two-factor-authentication-form.blade.php | 4 +-
.../components/application-mark.blade.php | 10 +-
routes/admin.php | 25 +++
15 files changed, 742 insertions(+), 48 deletions(-)
create mode 100644 app/Actions/Fortify/ConfirmPassword.php
create mode 100644 app/Actions/Fortify/Controllers/TwoFactorAuthenticatedSessionController.php
create mode 100644 app/Actions/Fortify/Controllers/TwoFactorAuthenticationController.php
create mode 100644 app/Http/Livewire/AdminTwoFactorAuthenticationForm.php
create mode 100644 app/Traits/ConfirmsPasswords.php
create mode 100644 database/migrations/2014_10_12_300000_add_two_factor_columns_to_admins_table.php
create mode 100644 resources/views/profile/admin-two-factor-authentication-form.blade.php
diff --git a/app/Actions/Fortify/ConfirmPassword.php b/app/Actions/Fortify/ConfirmPassword.php
new file mode 100644
index 0000000..07d7c87
--- /dev/null
+++ b/app/Actions/Fortify/ConfirmPassword.php
@@ -0,0 +1,52 @@
+guard = $guard;
+ $this->limiter = $limiter;
+ }
+ /**
+ * Confirm that the given password is valid for the given user.
+ *
+ * @param \Illuminate\Contracts\Auth\StatefulGuard $guard
+ * @param mixed $user
+ * @param string|null $password
+ * @return bool
+ */
+ public function __invoke(StatefulGuard $guard, $user, ?string $password = null)
+ {
+
+ $username = config('fortify.username');
+
+ return is_null(Fortify::$confirmPasswordsUsingCallback) ? $this->guard->validate([
+ $username => $user->{$username},
+ 'password' => $password,
+ ]) : $this->confirmPasswordUsingCustomCallback($user, $password);
+ }
+
+ /**
+ * Confirm the user's password using a custom callback.
+ *
+ * @param mixed $user
+ * @param string|null $password
+ * @return bool
+ */
+ protected function confirmPasswordUsingCustomCallback($user, ?string $password = null)
+ {
+ return call_user_func(
+ Fortify::$confirmPasswordsUsingCallback,
+ $user,
+ $password
+ );
+ }
+}
diff --git a/app/Actions/Fortify/Controllers/TwoFactorAuthenticatedSessionController.php b/app/Actions/Fortify/Controllers/TwoFactorAuthenticatedSessionController.php
new file mode 100644
index 0000000..0444c26
--- /dev/null
+++ b/app/Actions/Fortify/Controllers/TwoFactorAuthenticatedSessionController.php
@@ -0,0 +1,73 @@
+guard = $guard;
+ }
+
+ /**
+ * Show the two factor authentication challenge view.
+ *
+ * @param \Laravel\Fortify\Http\Requests\TwoFactorLoginRequest $request
+ * @return \Laravel\Fortify\Contracts\TwoFactorChallengeViewResponse
+ */
+ public function create(TwoFactorLoginRequest $request): TwoFactorChallengeViewResponse
+ {
+ if (! $request->hasChallengedUser()) {
+ throw new HttpResponseException(redirect()->route('admin.login'));
+ }
+
+ return app(TwoFactorChallengeViewResponse::class);
+ }
+
+ /**
+ * Attempt to authenticate a new session using the two factor authentication code.
+ *
+ * @param \Laravel\Fortify\Http\Requests\TwoFactorLoginRequest $request
+ * @return mixed
+ */
+ public function store(TwoFactorLoginRequest $request)
+ {
+ $user = $request->challengedUser();
+
+ if ($code = $request->validRecoveryCode()) {
+ $user->replaceRecoveryCode($code);
+
+ event(new RecoveryCodeReplaced($user, $code));
+ } elseif (! $request->hasValidCode()) {
+ return app(FailedTwoFactorLoginResponse::class)->toResponse($request);
+ }
+
+ $this->guard->login($user, $request->remember());
+
+ $request->session()->regenerate();
+
+ return app(TwoFactorLoginResponse::class);
+ }
+}
diff --git a/app/Actions/Fortify/Controllers/TwoFactorAuthenticationController.php b/app/Actions/Fortify/Controllers/TwoFactorAuthenticationController.php
new file mode 100644
index 0000000..121876d
--- /dev/null
+++ b/app/Actions/Fortify/Controllers/TwoFactorAuthenticationController.php
@@ -0,0 +1,44 @@
+user());
+
+ return $request->wantsJson()
+ ? new JsonResponse('', 200)
+ : back()->with('status', 'two-factor-authentication-enabled');
+ }
+
+ /**
+ * Disable two factor authentication for the user.
+ *
+ * @param \Illuminate\Http\Request $request
+ * @param \Laravel\Fortify\Actions\DisableTwoFactorAuthentication $disable
+ * @return \Symfony\Component\HttpFoundation\Response
+ */
+ public function destroy(Request $request, DisableTwoFactorAuthentication $disable)
+ {
+ $disable($request->user());
+
+ return $request->wantsJson()
+ ? new JsonResponse('', 200)
+ : back()->with('status', 'two-factor-authentication-disabled');
+ }
+}
diff --git a/app/Actions/Fortify/RedirectIfTwoFactorAuthenticatable.php b/app/Actions/Fortify/RedirectIfTwoFactorAuthenticatable.php
index 10486d6..c29b6c0 100644
--- a/app/Actions/Fortify/RedirectIfTwoFactorAuthenticatable.php
+++ b/app/Actions/Fortify/RedirectIfTwoFactorAuthenticatable.php
@@ -4,6 +4,7 @@
use Illuminate\Auth\Events\Failed;
use Illuminate\Contracts\Auth\StatefulGuard;
+use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\ValidationException;
use Laravel\Fortify\Events\TwoFactorAuthenticationChallenged;
use Laravel\Fortify\Fortify;
@@ -29,12 +30,13 @@ class RedirectIfTwoFactorAuthenticatable
/**
* Create a new controller instance.
*
- * @param \Illuminate\Contracts\Auth\StatefulGuard $guard
- * @param \Laravel\Fortify\LoginRateLimiter $limiter
+ * @param \Illuminate\Contracts\Auth\StatefulGuard $guard
+ * @param \Laravel\Fortify\LoginRateLimiter $limiter
* @return void
*/
public function __construct(StatefulGuard $guard, LoginRateLimiter $limiter)
{
+
$this->guard = $guard;
$this->limiter = $limiter;
}
@@ -42,8 +44,8 @@ public function __construct(StatefulGuard $guard, LoginRateLimiter $limiter)
/**
* Handle the incoming request.
*
- * @param \Illuminate\Http\Request $request
- * @param callable $next
+ * @param \Illuminate\Http\Request $request
+ * @param callable $next
* @return mixed
*/
public function handle($request, $next)
@@ -52,7 +54,7 @@ public function handle($request, $next)
if (Fortify::confirmsTwoFactorAuthentication()) {
if (optional($user)->two_factor_secret &&
- ! is_null(optional($user)->two_factor_confirmed_at) &&
+ !is_null(optional($user)->two_factor_confirmed_at) &&
in_array(TwoFactorAuthenticatable::class, class_uses_recursive($user))) {
return $this->twoFactorChallengeResponse($request, $user);
} else {
@@ -71,14 +73,14 @@ public function handle($request, $next)
/**
* Attempt to validate the incoming credentials.
*
- * @param \Illuminate\Http\Request $request
+ * @param \Illuminate\Http\Request $request
* @return mixed
*/
protected function validateCredentials($request)
{
if (Fortify::$authenticateUsingCallback) {
return tap(call_user_func(Fortify::$authenticateUsingCallback, $request), function ($user) use ($request) {
- if (! $user) {
+ if (!$user) {
$this->fireFailedEvent($request);
$this->throwFailedAuthenticationException($request);
@@ -89,7 +91,7 @@ protected function validateCredentials($request)
$model = $this->guard->getProvider()->getModel();
return tap($model::where(Fortify::username(), $request->{Fortify::username()})->first(), function ($user) use ($request) {
- if (! $user || ! $this->guard->getProvider()->validateCredentials($user, ['password' => $request->password])) {
+ if (!$user || !$this->guard->getProvider()->validateCredentials($user, ['password' => $request->password])) {
$this->fireFailedEvent($request, $user);
$this->throwFailedAuthenticationException($request);
@@ -100,7 +102,7 @@ protected function validateCredentials($request)
/**
* Throw a failed authentication validation exception.
*
- * @param \Illuminate\Http\Request $request
+ * @param \Illuminate\Http\Request $request
* @return void
*
* @throws \Illuminate\Validation\ValidationException
@@ -117,8 +119,8 @@ protected function throwFailedAuthenticationException($request)
/**
* Fire the failed authentication attempt event with the given arguments.
*
- * @param \Illuminate\Http\Request $request
- * @param \Illuminate\Contracts\Auth\Authenticatable|null $user
+ * @param \Illuminate\Http\Request $request
+ * @param \Illuminate\Contracts\Auth\Authenticatable|null $user
* @return void
*/
protected function fireFailedEvent($request, $user = null)
@@ -132,8 +134,8 @@ protected function fireFailedEvent($request, $user = null)
/**
* Get the two factor authentication enabled response.
*
- * @param \Illuminate\Http\Request $request
- * @param mixed $user
+ * @param \Illuminate\Http\Request $request
+ * @param mixed $user
* @return \Symfony\Component\HttpFoundation\Response
*/
protected function twoFactorChallengeResponse($request, $user)
@@ -145,8 +147,16 @@ protected function twoFactorChallengeResponse($request, $user)
TwoFactorAuthenticationChallenged::dispatch($user);
- return $request->wantsJson()
- ? response()->json(['two_factor' => true])
- : redirect()->route('two-factor.login');
+ if ($user->getTable() == 'admins') {
+
+ return $request->wantsJson()
+ ? response()->json(['admin.two_factor' => true])
+ : redirect()->route('admin.two-factor.login');
+ } else {
+ return $request->wantsJson()
+ ? response()->json(['two_factor' => true])
+ : redirect()->route('two-factor.login');
+ }
+
}
}
diff --git a/app/Actions/Jetstream/DeleteUser.php b/app/Actions/Jetstream/DeleteUser.php
index 65a127f..1031ac9 100644
--- a/app/Actions/Jetstream/DeleteUser.php
+++ b/app/Actions/Jetstream/DeleteUser.php
@@ -2,6 +2,7 @@
namespace App\Actions\Jetstream;
+use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Laravel\Jetstream\Contracts\DeletesTeams;
use Laravel\Jetstream\Contracts\DeletesUsers;
@@ -50,10 +51,12 @@ public function delete($user)
*/
protected function deleteTeams($user)
{
- $user->teams()->detach();
+ if(!Auth::guard('admin')->check()) {
+ $user->teams()->detach();
- $user->ownedTeams->each(function ($team) {
- $this->deletesTeams->delete($team);
- });
+ $user->ownedTeams->each(function ($team) {
+ $this->deletesTeams->delete($team);
+ });
+ }
}
}
diff --git a/app/Http/Livewire/AdminTwoFactorAuthenticationForm.php b/app/Http/Livewire/AdminTwoFactorAuthenticationForm.php
new file mode 100644
index 0000000..287b9c7
--- /dev/null
+++ b/app/Http/Livewire/AdminTwoFactorAuthenticationForm.php
@@ -0,0 +1,181 @@
+two_factor_confirmed_at)) {
+ app(DisableTwoFactorAuthentication::class)(Auth::user());
+ }
+ }
+
+ /**
+ * Enable two factor authentication for the user.
+ *
+ * @param \Laravel\Fortify\Actions\EnableTwoFactorAuthentication $enable
+ * @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.
+ *
+ * @param \Laravel\Fortify\Actions\ConfirmTwoFactorAuthentication $confirm
+ * @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.
+ *
+ * @param \Laravel\Fortify\Actions\GenerateNewRecoveryCodes $generate
+ * @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.
+ *
+ * @param \Laravel\Fortify\Actions\DisableTwoFactorAuthentication $disable
+ * @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);
+ }
+
+ /**
+ * Render the component.
+ *
+ * @return \Illuminate\View\View
+ */
+ public function render()
+ {
+ return view('profile.admin-two-factor-authentication-form');
+ }
+}
diff --git a/app/Providers/FortifyServiceProvider.php b/app/Providers/FortifyServiceProvider.php
index 3ff764a..1d1bf36 100644
--- a/app/Providers/FortifyServiceProvider.php
+++ b/app/Providers/FortifyServiceProvider.php
@@ -1,7 +1,9 @@
app
- ->when([AdminController::class, AttemptToAuthenticate::class, RedirectIfTwoFactorAuthenticatable::class,
- PasswordResetLinkController::class, NewPasswordController::class,ProfileInformationController::class, UpdateUserProfileInformation::class])
+ ->when([AdminController::class, AttemptToAuthenticate::class, RedirectIfTwoFactorAuthenticatable::class,ConfirmPassword::class,
+ PasswordResetLinkController::class, NewPasswordController::class,ProfileInformationController::class, UpdateUserProfileInformation::class,TwoFactorAuthenticatedSessionController::class])
->needs(StatefulGuard::class)
->give(function () {
return Auth::guard('admin');
diff --git a/app/Traits/ConfirmsPasswords.php b/app/Traits/ConfirmsPasswords.php
new file mode 100644
index 0000000..90ecca9
--- /dev/null
+++ b/app/Traits/ConfirmsPasswords.php
@@ -0,0 +1,116 @@
+resetErrorBag();
+
+ if ($this->passwordIsConfirmed()) {
+ return $this->dispatchBrowserEvent('password-confirmed', [
+ 'id' => $confirmableId,
+ ]);
+ }
+
+ $this->confirmingPassword = true;
+ $this->confirmableId = $confirmableId;
+ $this->confirmablePassword = '';
+
+ $this->dispatchBrowserEvent('confirming-password');
+ }
+
+ /**
+ * Stop confirming the user's password.
+ *
+ * @return void
+ */
+ public function stopConfirmingPassword()
+ {
+ $this->confirmingPassword = false;
+ $this->confirmableId = null;
+ $this->confirmablePassword = '';
+ }
+
+ /**
+ * Confirm the user's password.
+ *
+ * @return void
+ */
+ public function confirmPassword()
+ {
+ if (! app(ConfirmPassword::class)(app(StatefulGuard::class), Auth::user(), $this->confirmablePassword)) {
+ throw ValidationException::withMessages([
+ 'confirmable_password' => [__('This password does not match our records.')],
+ ]);
+ }
+
+ session(['auth.password_confirmed_at' => time()]);
+
+ $this->dispatchBrowserEvent('password-confirmed', [
+ 'id' => $this->confirmableId,
+ ]);
+
+ $this->stopConfirmingPassword();
+ }
+
+ /**
+ * Ensure that the user's password has been recently confirmed.
+ *
+ * @param int|null $maximumSecondsSinceConfirmation
+ * @return void
+ */
+ protected function ensurePasswordIsConfirmed($maximumSecondsSinceConfirmation = null)
+ {
+ $maximumSecondsSinceConfirmation = $maximumSecondsSinceConfirmation ?: config('auth.password_timeout', 900);
+
+ $this->passwordIsConfirmed($maximumSecondsSinceConfirmation) ? null : abort(403);
+ }
+
+ /**
+ * Determine if the user's password has been recently confirmed.
+ *
+ * @param int|null $maximumSecondsSinceConfirmation
+ * @return bool
+ */
+ protected function passwordIsConfirmed($maximumSecondsSinceConfirmation = null)
+ {
+ $maximumSecondsSinceConfirmation = $maximumSecondsSinceConfirmation ?: config('auth.password_timeout', 900);
+
+ return (time() - session('auth.password_confirmed_at', 0)) < $maximumSecondsSinceConfirmation;
+ }
+}
diff --git a/database/migrations/2014_10_12_300000_add_two_factor_columns_to_admins_table.php b/database/migrations/2014_10_12_300000_add_two_factor_columns_to_admins_table.php
new file mode 100644
index 0000000..5f9e4f8
--- /dev/null
+++ b/database/migrations/2014_10_12_300000_add_two_factor_columns_to_admins_table.php
@@ -0,0 +1,50 @@
+text('two_factor_secret')
+ ->after('password')
+ ->nullable();
+
+ $table->text('two_factor_recovery_codes')
+ ->after('two_factor_secret')
+ ->nullable();
+
+ if (Fortify::confirmsTwoFactorAuthentication()) {
+ $table->timestamp('two_factor_confirmed_at')
+ ->after('two_factor_recovery_codes')
+ ->nullable();
+ }
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::table('admins', function (Blueprint $table) {
+ $table->dropColumn(array_merge([
+ 'two_factor_secret',
+ 'two_factor_recovery_codes',
+ ], Fortify::confirmsTwoFactorAuthentication() ? [
+ 'two_factor_confirmed_at',
+ ] : []));
+ });
+ }
+};
diff --git a/resources/views/navigation-menu.blade.php b/resources/views/navigation-menu.blade.php
index 96bf7a5..fcfab70 100644
--- a/resources/views/navigation-menu.blade.php
+++ b/resources/views/navigation-menu.blade.php
@@ -10,7 +10,7 @@
-
+
{{ __('Dashboard') }}
diff --git a/resources/views/profile/admin-two-factor-authentication-form.blade.php b/resources/views/profile/admin-two-factor-authentication-form.blade.php
new file mode 100644
index 0000000..de42e4f
--- /dev/null
+++ b/resources/views/profile/admin-two-factor-authentication-form.blade.php
@@ -0,0 +1,126 @@
+
+
+ {{ __('Two Factor Authentication') }}
+
+
+
+ {{ __('Add additional security to your account using two factor authentication.') }}
+
+
+
+
+ @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
+
+
+
+
+ {{ __('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.') }}
+
+
+
+ @if ($this->enabled)
+ @if ($showingQrCode)
+
+
+ @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
+
+
+
+
+
+ {!! $this->user->twoFactorQrCodeSvg() !!}
+
+
+
+
+
+ {{ __('Setup Key') }}: {{ decrypt($this->user->two_factor_secret) }}
+
+
+
+ @if ($showingConfirmation)
+
+
+
+
+
+
+
+ @endif
+ @endif
+
+ @if ($showingRecoveryCodes)
+
+
+ {{ __('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.') }}
+
+
+
+
+ @foreach (json_decode(decrypt($this->user->two_factor_recovery_codes), true) as $code)
+
{{ $code }}
+ @endforeach
+
+ @endif
+ @endif
+
+
+ @if (! $this->enabled)
+
+
+ {{ __('Enable') }}
+
+
+ @else
+ @if ($showingRecoveryCodes)
+
+
+ {{ __('Regenerate Recovery Codes') }}
+
+
+ @elseif ($showingConfirmation)
+
+
+ {{ __('Confirm') }}
+
+
+ @else
+
+
+ {{ __('Show Recovery Codes') }}
+
+
+ @endif
+
+ @if ($showingConfirmation)
+
+
+ {{ __('Cancel') }}
+
+
+ @else
+
+
+ {{ __('Disable') }}
+
+
+ @endif
+
+ @endif
+
+
+
diff --git a/resources/views/profile/show.blade.php b/resources/views/profile/show.blade.php
index ea077b5..5d28d28 100644
--- a/resources/views/profile/show.blade.php
+++ b/resources/views/profile/show.blade.php
@@ -16,33 +16,39 @@
@endif
- {{-- @if (Laravel\Fortify\Features::enabled(Laravel\Fortify\Features::updatePasswords()))--}}
- {{-- --}}
- {{-- @livewire('profile.update-password-form')--}}
- {{--
--}}
+ @if (Laravel\Fortify\Features::enabled(Laravel\Fortify\Features::updatePasswords()))
+
+ @livewire('profile.update-password-form')
+
- {{-- --}}
- {{-- @endif--}}
+
+ @endif
- {{-- @if (Laravel\Fortify\Features::canManageTwoFactorAuthentication())--}}
- {{-- --}}
- {{-- @livewire('profile.two-factor-authentication-form')--}}
- {{--
--}}
+ @if (Laravel\Fortify\Features::canManageTwoFactorAuthentication())
+
- {{--
--}}
- {{-- @endif--}}
+ @if(Auth::guard('admin')->check())
+ @livewire('admin-two-factor-authentication-form')
+ @else
+ @livewire('profile.two-factor-authentication-form')
+ @endif
- {{--
--}}
- {{-- @livewire('profile.logout-other-browser-sessions-form')--}}
- {{--
--}}
+
- {{-- @if (Laravel\Jetstream\Jetstream::hasAccountDeletionFeatures())--}}
- {{-- --}}
+
+ @endif
- {{-- --}}
- {{-- @livewire('profile.delete-user-form')--}}
- {{--
--}}
- {{-- @endif--}}
+
+ @livewire('profile.logout-other-browser-sessions-form')
+
+
+ @if (Laravel\Jetstream\Jetstream::hasAccountDeletionFeatures())
+
+
+
+ @livewire('profile.delete-user-form')
+
+ @endif
diff --git a/resources/views/profile/two-factor-authentication-form.blade.php b/resources/views/profile/two-factor-authentication-form.blade.php
index 4af049a..92e2a16 100644
--- a/resources/views/profile/two-factor-authentication-form.blade.php
+++ b/resources/views/profile/two-factor-authentication-form.blade.php
@@ -38,8 +38,10 @@
-
+
+
{!! $this->user->twoFactorQrCodeSvg() !!}
+
diff --git a/resources/views/vendor/jetstream/components/application-mark.blade.php b/resources/views/vendor/jetstream/components/application-mark.blade.php
index 55c25f2..c96d233 100644
--- a/resources/views/vendor/jetstream/components/application-mark.blade.php
+++ b/resources/views/vendor/jetstream/components/application-mark.blade.php
@@ -1,4 +1,8 @@
-
-
-
+
+
+
diff --git a/routes/admin.php b/routes/admin.php
index 115a3e3..6d029de 100644
--- a/routes/admin.php
+++ b/routes/admin.php
@@ -1,6 +1,12 @@
name('profile.show');
Route::put('/profile-information', [\App\Actions\Fortify\Controllers\ProfileInformationController::class, 'update'])->name('user-profile-information.update');
+ Route::get('/two-factor-challenge', [TwoFactorAuthenticatedSessionController::class, 'create'])->name('two-factor.login');
+ Route::post('/admin/two-factor-authentication', [TwoFactorAuthenticationController::class, 'store'])->name('two-factor.enable');
+
+ Route::post('/admin/confirmed-two-factor-authentication', [ConfirmedTwoFactorAuthenticationController::class, 'store'])->name('two-factor.confirm');
+
+ Route::delete('/admin/two-factor-authentication', [TwoFactorAuthenticationController::class, 'destroy'])
+ ->name('two-factor.disable');
+
+ Route::get('/admin/two-factor-qr-code', [TwoFactorQrCodeController::class, 'show'])
+ ->name('two-factor.qr-code');
+
+ Route::get('/admin/two-factor-secret-key', [TwoFactorSecretKeyController::class, 'show'])
+ ->name('two-factor.secret-key');
+
+ Route::get('/admin/two-factor-recovery-codes', [RecoveryCodeController::class, 'index'])
+ ->name('two-factor.recovery-codes');
+
+ Route::post('/admin/two-factor-recovery-codes', [RecoveryCodeController::class, 'store']);
+
Route::post('logout', [\App\Http\Controllers\AdminController::class, 'destroy'])->name('logout');
});
});