mirror of
https://github.com/pelican-dev/panel.git
synced 2025-05-20 00:34:44 +02:00
Handle token expiring
and token expired
websocket events (#755)
* handle `token expiring` and `token expired` events * fix "getToken" * Move logic to Widget instead of blade & add user check --------- Co-authored-by: RMartinOscar <40749467+RMartinOscar@users.noreply.github.com>
This commit is contained in:
parent
bbfdee356b
commit
6d42a15ec3
@ -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);
|
||||
|
@ -1,7 +1,11 @@
|
||||
<x-filament::widget>
|
||||
@assets
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/xterm/5.5.0/xterm.js" integrity="sha512-Gujw5GajF5is3nMoGv9X+tCMqePLL/60qvAv1LofUZTV9jK8ENbM9L+maGmOsNzuZaiuyc/fpph1KT9uR5w3CQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/xterm/5.5.0/xterm.css" integrity="sha512-AbNrj/oSHJaILgcdnkYm+DQ08SqVbZ8jlkJbFyyS1WDcAaXAcAfxJnCH69el7oVgTwVwyA5u5T+RdFyUykrV3Q==" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/xterm/5.5.0/xterm.js"
|
||||
integrity="sha512-Gujw5GajF5is3nMoGv9X+tCMqePLL/60qvAv1LofUZTV9jK8ENbM9L+maGmOsNzuZaiuyc/fpph1KT9uR5w3CQ=="
|
||||
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/xterm/5.5.0/xterm.css"
|
||||
integrity="sha512-AbNrj/oSHJaILgcdnkYm+DQ08SqVbZ8jlkJbFyyS1WDcAaXAcAfxJnCH69el7oVgTwVwyA5u5T+RdFyUykrV3Q=="
|
||||
crossorigin="anonymous" referrerpolicy="no-referrer" />
|
||||
@endassets
|
||||
|
||||
<div id="terminal" wire:ignore></div>
|
||||
@ -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) => {
|
||||
|
Loading…
x
Reference in New Issue
Block a user