mirror of
https://github.com/pelican-dev/panel.git
synced 2025-05-19 21:04:44 +02:00
Basic two factor auth implementation (#1050)
* Basic two factor auth * Remove unused import * Add translation
This commit is contained in:
parent
da195fd2fe
commit
36a38ab947
@ -3,17 +3,84 @@
|
||||
namespace App\Filament\Pages\Auth;
|
||||
|
||||
use App\Extensions\OAuth\Providers\OAuthProvider;
|
||||
use App\Models\User;
|
||||
use Coderflex\FilamentTurnstile\Forms\Components\Turnstile;
|
||||
use Filament\Facades\Filament;
|
||||
use Filament\Forms\Components\Actions;
|
||||
use Filament\Forms\Components\Actions\Action;
|
||||
use Filament\Forms\Components\Component;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Http\Responses\Auth\Contracts\LoginResponse;
|
||||
use Filament\Notifications\Notification;
|
||||
use Filament\Pages\Auth\Login as BaseLogin;
|
||||
use Filament\Support\Colors\Color;
|
||||
use Illuminate\Support\Facades\Config;
|
||||
use Illuminate\Support\Sleep;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use PragmaRX\Google2FA\Google2FA;
|
||||
|
||||
class Login extends BaseLogin
|
||||
{
|
||||
private Google2FA $google2FA;
|
||||
|
||||
public bool $verifyTwoFactor = false;
|
||||
|
||||
public function boot(Google2FA $google2FA): void
|
||||
{
|
||||
$this->google2FA = $google2FA;
|
||||
}
|
||||
|
||||
public function authenticate(): ?LoginResponse
|
||||
{
|
||||
$data = $this->form->getState();
|
||||
Filament::auth()->once($this->getCredentialsFromFormData($data));
|
||||
|
||||
/** @var ?User $user */
|
||||
$user = Filament::auth()->user();
|
||||
|
||||
// Make sure that rate limits apply
|
||||
if (!$user) {
|
||||
return parent::authenticate();
|
||||
}
|
||||
|
||||
// 2FA disabled
|
||||
if (!$user->use_totp) {
|
||||
return parent::authenticate();
|
||||
}
|
||||
|
||||
$token = $data['2fa'] ?? null;
|
||||
|
||||
// 2FA not shown yet
|
||||
if ($token === null) {
|
||||
$this->verifyTwoFactor = true;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
$isValidToken = $this->google2FA->verifyKey(
|
||||
$user->totp_secret,
|
||||
$token,
|
||||
Config::integer('panel.auth.2fa.window'),
|
||||
);
|
||||
|
||||
if (!$isValidToken) {
|
||||
// Buffer to prevent bruteforce
|
||||
Sleep::sleep(1);
|
||||
|
||||
Notification::make()
|
||||
->title(trans('auth.failed-two-factor'))
|
||||
->body(trans('auth.failed'))
|
||||
->color('danger')
|
||||
->icon('tabler-auth-2fa')
|
||||
->danger()
|
||||
->send();
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return parent::authenticate();
|
||||
}
|
||||
|
||||
protected function getForms(): array
|
||||
{
|
||||
return [
|
||||
@ -24,6 +91,7 @@ class Login extends BaseLogin
|
||||
$this->getPasswordFormComponent(),
|
||||
$this->getRememberFormComponent(),
|
||||
$this->getOAuthFormComponent(),
|
||||
$this->getTwoFactorAuthenticationComponent(),
|
||||
Turnstile::make('captcha')
|
||||
->hidden(!config('turnstile.turnstile_enabled'))
|
||||
->validationMessages([
|
||||
@ -36,6 +104,15 @@ class Login extends BaseLogin
|
||||
];
|
||||
}
|
||||
|
||||
private function getTwoFactorAuthenticationComponent(): Component
|
||||
{
|
||||
return TextInput::make('2fa')
|
||||
->label(trans('auth.two-factor-code'))
|
||||
->hidden(fn () => !$this->verifyTwoFactor)
|
||||
->required()
|
||||
->live();
|
||||
}
|
||||
|
||||
protected function throwFailureValidationException(): never
|
||||
{
|
||||
$this->dispatch('reset-captcha');
|
||||
|
22
lang/en/auth.php
Normal file
22
lang/en/auth.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Authentication Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines are used during authentication for various
|
||||
| messages that we need to display to the user. You are free to modify
|
||||
| these language lines according to your application's requirements.
|
||||
|
|
||||
*/
|
||||
|
||||
'failed' => 'These credentials do not match our records.',
|
||||
'failed-two-factor' => 'Incorrect 2FA Code',
|
||||
'two-factor-code' => 'Two Factor Code',
|
||||
'password' => 'The provided password is incorrect.',
|
||||
'throttle' => 'Too many login attempts. Please try again in :seconds seconds.',
|
||||
|
||||
];
|
Loading…
x
Reference in New Issue
Block a user