diff --git a/app/Filament/Server/Widgets/ServerConsole.php b/app/Filament/Server/Widgets/ServerConsole.php index 3f4eb7d18..2ac5bb9b4 100644 --- a/app/Filament/Server/Widgets/ServerConsole.php +++ b/app/Filament/Server/Widgets/ServerConsole.php @@ -2,8 +2,12 @@ namespace App\Filament\Server\Widgets; +use App\Exceptions\Http\HttpForbiddenException; +use App\Models\Permission; use App\Models\Server; use App\Models\User; +use App\Services\Nodes\NodeJWTService; +use App\Services\Servers\GetUserPermissionsService; use Filament\Widgets\Widget; use Illuminate\Support\Arr; use Livewire\Attributes\On; @@ -26,6 +30,33 @@ class ServerConsole extends Widget public string $input = ''; + protected function getToken(): string + { + if (!$this->user || !$this->server || $this->user->cannot(Permission::ACTION_WEBSOCKET_CONNECT, $this->server)) { + throw new HttpForbiddenException('You do not have permission to connect to this server\'s websocket.'); + } + // @phpstan-ignore-next-line + $permissions = app(GetUserPermissionsService::class)->handle($this->server, $this->user); + + // @phpstan-ignore-next-line + return app(NodeJWTService::class) + ->setExpiresAt(now()->addMinutes(10)->toImmutable()) + ->setUser($this->user) + ->setClaims([ + 'server_uuid' => $this->server->uuid, + 'permissions' => $permissions, + ]) + ->handle($this->server->node, $this->user->id . $this->server->uuid)->toString(); + } + + protected function getSocket(): string + { + $socket = str_replace(['https://', 'http://'], ['wss://', 'ws://'], $this->server->node->getConnectionAddress()); + $socket .= sprintf('/api/servers/%s/ws', $this->server->uuid); + + return $socket; + } + public function up(): void { $this->historyIndex = min($this->historyIndex + 1, count($this->history) - 1); diff --git a/resources/views/filament/components/server-console.blade.php b/resources/views/filament/components/server-console.blade.php index 16e4abd0d..cd1e0dedf 100644 --- a/resources/views/filament/components/server-console.blade.php +++ b/resources/views/filament/components/server-console.blade.php @@ -1,7 +1,11 @@ @assets - - + + @endassets
@@ -27,7 +31,7 @@ cursorStyle: 'underline', allowTransparency: true, rows: 35, - cols: 110, + cols: 110 // theme: theme, }; @@ -57,28 +61,8 @@ const handlePowerChangeEvent = (state) => terminal.writeln(TERMINAL_PRELUDE + 'Server marked as ' + state + '...\u001b[0m'); - @php - if ($user->cannot(\App\Models\Permission::ACTION_WEBSOCKET_CONNECT, $server)) { - throw new \App\Exceptions\Http\HttpForbiddenException('You do not have permission to connect to this server\'s websocket.'); - } - - $permissions = app(\App\Services\Servers\GetUserPermissionsService::class)->handle($server, $user); - - $socket = str_replace(['https://', 'http://'], ['wss://', 'ws://'], $server->node->getConnectionAddress()); - $socket .= sprintf('/api/servers/%s/ws', $server->uuid); - - $token = app(\App\Services\Nodes\NodeJWTService::class) - ->setExpiresAt(now()->addMinutes(10)->toImmutable()) - ->setUser($user) - ->setClaims([ - 'server_uuid' => $server->uuid, - 'permissions' => $permissions, - ]) - ->handle($server->node, $user->id . $server->uuid); - @endphp - - const socket = new WebSocket("{{ $socket }}"); - const token = '{{ $token->toString() }}'; + const socket = new WebSocket("{{ $this->getSocket() }}"); + let token = '{{ $this->getToken() }}'; socket.onmessage = function(websocketMessageEvent) { let eventData = JSON.parse(websocketMessageEvent.data); @@ -106,7 +90,14 @@ })); } - // TODO: handle "token expiring" and "token expired" + if (eventData.event === 'token expiring' || eventData.event === 'token expired') { + token = '{{ $this->getToken() }}'; + + socket.send(JSON.stringify({ + 'event': 'auth', + 'args': [token] + })); + } }; socket.onopen = (event) => {