From ef1a208b95b392b97464e3e5c9ef146a27047b15 Mon Sep 17 00:00:00 2001 From: Lance Pioch Date: Fri, 31 May 2024 01:26:28 -0400 Subject: [PATCH 1/9] Add 2fa setup --- .../UserResource/Pages/EditProfile.php | 61 ++++++++++++++++++- 1 file changed, 58 insertions(+), 3 deletions(-) diff --git a/app/Filament/Resources/UserResource/Pages/EditProfile.php b/app/Filament/Resources/UserResource/Pages/EditProfile.php index 7fe5728cf..386e30122 100644 --- a/app/Filament/Resources/UserResource/Pages/EditProfile.php +++ b/app/Filament/Resources/UserResource/Pages/EditProfile.php @@ -2,10 +2,12 @@ namespace App\Filament\Resources\UserResource\Pages; +use App\Exceptions\Service\User\TwoFactorAuthenticationTokenInvalid; use App\Facades\Activity; use App\Models\ActivityLog; use App\Models\ApiKey; use App\Models\User; +use App\Services\Users\ToggleTwoFactorService; use App\Services\Users\TwoFactorSetupService; use chillerlan\QRCode\Common\EccLevel; use chillerlan\QRCode\Common\Version; @@ -22,6 +24,7 @@ use Filament\Forms\Components\TagsInput; use Filament\Forms\Components\Tabs\Tab; use Filament\Forms\Components\TextInput; use Filament\Forms\Get; +use Filament\Notifications\Notification; use Illuminate\Database\Eloquent\Builder; use Illuminate\Support\Facades\Hash; use Illuminate\Support\HtmlString; @@ -99,12 +102,20 @@ class EditProfile extends \Filament\Pages\Auth\EditProfile if ($this->getUser()->use_totp) { return [ - Placeholder::make('2FA already enabled!'), + Placeholder::make('2fa-already-enabled') + ->label('Two Factor Authentication is currently enabled!'), + TextInput::make('2fa-disable-code') + ->label('Disable 2FA') + ->helperText('Enter your current 2FA code to disable Two Factor Authentication'), ]; } $setupService = app(TwoFactorSetupService::class); - ['image_url_data' => $url] = $setupService->handle($this->getUser()); + ['image_url_data' => $url, 'secret' => $secret] = cache()->remember( + 'current-two-factor-state', + now()->addMinutes(5), fn () => + $setupService->handle($this->getUser()) + ); $options = new QROptions([ 'svgLogo' => public_path('pelican.svg'), @@ -149,7 +160,15 @@ class EditProfile extends \Filament\Pages\Auth\EditProfile ->content(fn () => new HtmlString("
$image
")) - ->default('asdfasdf'), + ->helperText($secret), + TextInput::make('2facode') + ->requiredWith('2fapassword') + ->helperText('Scan the QR code above using your two-step authentication app, then enter the code generated.'), + TextInput::make('2fapassword') + ->requiredWith('2facode') + ->currentPassword() + ->password() + ->helperText('Enter your current password to verify.'), ]; }), @@ -235,4 +254,40 @@ class EditProfile extends \Filament\Pages\Auth\EditProfile ), ]; } + + protected function handleRecordUpdate($record, $data): \Illuminate\Database\Eloquent\Model + { + if ($token = $data['2facode'] ?? null) { + /** @var ToggleTwoFactorService $service */ + $service = resolve(ToggleTwoFactorService::class); + + $service->handle($record, $token, true); + } + + if ($token = $data['2fa-disable-code'] ?? null) { + /** @var ToggleTwoFactorService $service */ + $service = resolve(ToggleTwoFactorService::class); + + $service->handle($record, $token, false); + + cache()->forget('current-two-factor-state'); + } + + return parent::handleRecordUpdate($record, $data); + } + + public function exception($e, $stopPropagation): void + { + if ($e instanceof TwoFactorAuthenticationTokenInvalid) { + Notification::make() + ->title('Invalid 2FA Code') + ->body($e->getMessage()) + ->color('danger') + ->icon('tabler-2fa') + ->danger() + ->send(); + + $stopPropagation(); + } + } } From 7657364208d0f792d7dbf03b60f6bbe68a36b6b9 Mon Sep 17 00:00:00 2001 From: Lance Pioch Date: Fri, 31 May 2024 01:38:32 -0400 Subject: [PATCH 2/9] Cache per user and show backup tokens temporarily --- .../Resources/UserResource/Pages/EditProfile.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/app/Filament/Resources/UserResource/Pages/EditProfile.php b/app/Filament/Resources/UserResource/Pages/EditProfile.php index 386e30122..8f6170be5 100644 --- a/app/Filament/Resources/UserResource/Pages/EditProfile.php +++ b/app/Filament/Resources/UserResource/Pages/EditProfile.php @@ -104,6 +104,11 @@ class EditProfile extends \Filament\Pages\Auth\EditProfile return [ Placeholder::make('2fa-already-enabled') ->label('Two Factor Authentication is currently enabled!'), + Placeholder::make('backup-tokens') + ->hidden(fn () => !cache()->get("users.{$this->getUser()->id}.2fa.tokens")) + ->helperText(cache()->get("users.{$this->getUser()->id}.2fa.tokens") . + ' - these will not be shown again!') + ->label("Backup Tokens:"), TextInput::make('2fa-disable-code') ->label('Disable 2FA') ->helperText('Enter your current 2FA code to disable Two Factor Authentication'), @@ -112,7 +117,7 @@ class EditProfile extends \Filament\Pages\Auth\EditProfile $setupService = app(TwoFactorSetupService::class); ['image_url_data' => $url, 'secret' => $secret] = cache()->remember( - 'current-two-factor-state', + "users.{$this->getUser()->id}.2fa.state", now()->addMinutes(5), fn () => $setupService->handle($this->getUser()) ); @@ -261,7 +266,8 @@ class EditProfile extends \Filament\Pages\Auth\EditProfile /** @var ToggleTwoFactorService $service */ $service = resolve(ToggleTwoFactorService::class); - $service->handle($record, $token, true); + $tokens = $service->handle($record, $token, true); + cache()->set("users.$record->id.2fa.tokens", implode("\n", $tokens), now()->addSeconds(15)); } if ($token = $data['2fa-disable-code'] ?? null) { @@ -270,7 +276,7 @@ class EditProfile extends \Filament\Pages\Auth\EditProfile $service->handle($record, $token, false); - cache()->forget('current-two-factor-state'); + cache()->forget("users.$record->id.2fa.state"); } return parent::handleRecordUpdate($record, $data); From 5519931ee53e4022915b446bd6a898cb67d39a90 Mon Sep 17 00:00:00 2001 From: Lance Pioch Date: Fri, 31 May 2024 01:42:02 -0400 Subject: [PATCH 3/9] Pint --- app/Filament/Resources/UserResource/Pages/EditProfile.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/Filament/Resources/UserResource/Pages/EditProfile.php b/app/Filament/Resources/UserResource/Pages/EditProfile.php index 8f6170be5..4b7c22b5d 100644 --- a/app/Filament/Resources/UserResource/Pages/EditProfile.php +++ b/app/Filament/Resources/UserResource/Pages/EditProfile.php @@ -108,7 +108,7 @@ class EditProfile extends \Filament\Pages\Auth\EditProfile ->hidden(fn () => !cache()->get("users.{$this->getUser()->id}.2fa.tokens")) ->helperText(cache()->get("users.{$this->getUser()->id}.2fa.tokens") . ' - these will not be shown again!') - ->label("Backup Tokens:"), + ->label('Backup Tokens:'), TextInput::make('2fa-disable-code') ->label('Disable 2FA') ->helperText('Enter your current 2FA code to disable Two Factor Authentication'), @@ -118,8 +118,7 @@ class EditProfile extends \Filament\Pages\Auth\EditProfile ['image_url_data' => $url, 'secret' => $secret] = cache()->remember( "users.{$this->getUser()->id}.2fa.state", - now()->addMinutes(5), fn () => - $setupService->handle($this->getUser()) + now()->addMinutes(5), fn () => $setupService->handle($this->getUser()) ); $options = new QROptions([ From 9174de2d8cc0b238d5f64b242750cd5ce7e2a7cf Mon Sep 17 00:00:00 2001 From: notCharles Date: Fri, 31 May 2024 17:24:03 -0400 Subject: [PATCH 4/9] Add Labels --- app/Filament/Resources/UserResource/Pages/EditProfile.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/Filament/Resources/UserResource/Pages/EditProfile.php b/app/Filament/Resources/UserResource/Pages/EditProfile.php index 4b7c22b5d..d6eeac501 100644 --- a/app/Filament/Resources/UserResource/Pages/EditProfile.php +++ b/app/Filament/Resources/UserResource/Pages/EditProfile.php @@ -164,11 +164,13 @@ class EditProfile extends \Filament\Pages\Auth\EditProfile ->content(fn () => new HtmlString("
$image
")) - ->helperText($secret), + ->helperText('Setup Key: '. $secret), TextInput::make('2facode') + ->label('Code') ->requiredWith('2fapassword') ->helperText('Scan the QR code above using your two-step authentication app, then enter the code generated.'), TextInput::make('2fapassword') + ->label('Current Password') ->requiredWith('2facode') ->currentPassword() ->password() From 7762e68a6cbf5d4d4b4d79d468d5278fa4ce5142 Mon Sep 17 00:00:00 2001 From: Lance Pioch Date: Sat, 1 Jun 2024 12:49:19 -0400 Subject: [PATCH 5/9] Make qr code visible on light mode --- app/Filament/Resources/UserResource/Pages/EditProfile.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Filament/Resources/UserResource/Pages/EditProfile.php b/app/Filament/Resources/UserResource/Pages/EditProfile.php index d6eeac501..5f56f8fa4 100644 --- a/app/Filament/Resources/UserResource/Pages/EditProfile.php +++ b/app/Filament/Resources/UserResource/Pages/EditProfile.php @@ -162,7 +162,7 @@ class EditProfile extends \Filament\Pages\Auth\EditProfile Placeholder::make('qr') ->label('Scan QR Code') ->content(fn () => new HtmlString(" -
$image
+
$image
")) ->helperText('Setup Key: '. $secret), TextInput::make('2facode') From 67cb3d4816562f5d1f22f096fd39c2fc9877b7db Mon Sep 17 00:00:00 2001 From: Lance Pioch Date: Sat, 1 Jun 2024 12:49:36 -0400 Subject: [PATCH 6/9] Show backup tokens better --- .../Resources/UserResource/Pages/EditProfile.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/app/Filament/Resources/UserResource/Pages/EditProfile.php b/app/Filament/Resources/UserResource/Pages/EditProfile.php index 5f56f8fa4..c047b3262 100644 --- a/app/Filament/Resources/UserResource/Pages/EditProfile.php +++ b/app/Filament/Resources/UserResource/Pages/EditProfile.php @@ -22,6 +22,7 @@ use Filament\Forms\Components\Select; use Filament\Forms\Components\Tabs; use Filament\Forms\Components\TagsInput; use Filament\Forms\Components\Tabs\Tab; +use Filament\Forms\Components\Textarea; use Filament\Forms\Components\TextInput; use Filament\Forms\Get; use Filament\Notifications\Notification; @@ -104,10 +105,12 @@ class EditProfile extends \Filament\Pages\Auth\EditProfile return [ Placeholder::make('2fa-already-enabled') ->label('Two Factor Authentication is currently enabled!'), - Placeholder::make('backup-tokens') + Textarea::make('backup-tokens') ->hidden(fn () => !cache()->get("users.{$this->getUser()->id}.2fa.tokens")) - ->helperText(cache()->get("users.{$this->getUser()->id}.2fa.tokens") . - ' - these will not be shown again!') + ->rows(10) + ->readOnly() + ->formatStateUsing(fn () => cache()->get("users.{$this->getUser()->id}.2fa.tokens")) + ->helperText('These will not be shown again!') ->label('Backup Tokens:'), TextInput::make('2fa-disable-code') ->label('Disable 2FA') From cd4b7cbf9eee898d25b047de2771ed0822b07f5a Mon Sep 17 00:00:00 2001 From: Lance Pioch Date: Sat, 1 Jun 2024 13:03:46 -0400 Subject: [PATCH 7/9] Refresh this --- app/Filament/Resources/UserResource/Pages/EditProfile.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/Filament/Resources/UserResource/Pages/EditProfile.php b/app/Filament/Resources/UserResource/Pages/EditProfile.php index c047b3262..ece225c8b 100644 --- a/app/Filament/Resources/UserResource/Pages/EditProfile.php +++ b/app/Filament/Resources/UserResource/Pages/EditProfile.php @@ -272,6 +272,8 @@ class EditProfile extends \Filament\Pages\Auth\EditProfile $tokens = $service->handle($record, $token, true); cache()->set("users.$record->id.2fa.tokens", implode("\n", $tokens), now()->addSeconds(15)); + + $this->redirectRoute('filament.admin.auth.profile', ['tab' => '-2fa-tab']); } if ($token = $data['2fa-disable-code'] ?? null) { From c31b7b8c6a2a27bc62c2aeaf250525e4d77a27b2 Mon Sep 17 00:00:00 2001 From: notCharles Date: Sat, 1 Jun 2024 15:52:13 -0400 Subject: [PATCH 8/9] Correctly save labels on create --- app/Filament/Resources/ServerResource/Pages/CreateServer.php | 2 +- app/Services/Servers/ServerCreationService.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/Filament/Resources/ServerResource/Pages/CreateServer.php b/app/Filament/Resources/ServerResource/Pages/CreateServer.php index a19129202..78ee1eec4 100644 --- a/app/Filament/Resources/ServerResource/Pages/CreateServer.php +++ b/app/Filament/Resources/ServerResource/Pages/CreateServer.php @@ -687,7 +687,7 @@ class CreateServer extends CreateRecord ->label('Container Labels') ->keyLabel('Title') ->valueLabel('Description') - ->columnSpan(1), + ->columnSpan(3), ]), ]), ]); diff --git a/app/Services/Servers/ServerCreationService.php b/app/Services/Servers/ServerCreationService.php index 57d8ad086..d555f7876 100644 --- a/app/Services/Servers/ServerCreationService.php +++ b/app/Services/Servers/ServerCreationService.php @@ -154,6 +154,7 @@ class ServerCreationService 'database_limit' => Arr::get($data, 'database_limit') ?? 0, 'allocation_limit' => Arr::get($data, 'allocation_limit') ?? 0, 'backup_limit' => Arr::get($data, 'backup_limit') ?? 0, + 'docker_labels' => Arr::get($data, 'docker_labels'), ]); } From b804878d7b0dbdd2562938e6aa723bbb727da173 Mon Sep 17 00:00:00 2001 From: kubi Date: Sat, 1 Jun 2024 20:42:44 +0000 Subject: [PATCH 9/9] Fix labels position in server config --- app/Services/Servers/ServerConfigurationStructureService.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Services/Servers/ServerConfigurationStructureService.php b/app/Services/Servers/ServerConfigurationStructureService.php index 75fae45e0..29ea396c6 100644 --- a/app/Services/Servers/ServerConfigurationStructureService.php +++ b/app/Services/Servers/ServerConfigurationStructureService.php @@ -50,6 +50,7 @@ class ServerConfigurationStructureService 'environment' => $this->environment->handle($server), 'invocation' => $server->startup, 'skip_egg_scripts' => $server->skip_scripts, + 'labels' => $server->docker_labels, 'build' => [ 'memory_limit' => $server->memory, 'swap' => $server->swap, @@ -62,7 +63,6 @@ class ServerConfigurationStructureService 'container' => [ 'image' => $server->image, 'requires_rebuild' => false, - 'labels' => $server->docker_labels, ], 'allocations' => [ 'force_outgoing_ip' => $server->egg->force_outgoing_ip,