Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pterodactyl
GitHub Repository: pterodactyl/panel
Path: blob/1.0-develop/app/Http/Controllers/Api/Client/Servers/WebsocketController.php
10280 views
1
<?php
2
3
namespace Pterodactyl\Http\Controllers\Api\Client\Servers;
4
5
use Carbon\CarbonImmutable;
6
use Pterodactyl\Models\Server;
7
use Illuminate\Http\JsonResponse;
8
use Pterodactyl\Models\Permission;
9
use Pterodactyl\Services\Nodes\NodeJWTService;
10
use Pterodactyl\Exceptions\Http\HttpForbiddenException;
11
use Pterodactyl\Http\Requests\Api\Client\ClientApiRequest;
12
use Pterodactyl\Services\Servers\GetUserPermissionsService;
13
use Pterodactyl\Http\Controllers\Api\Client\ClientApiController;
14
15
class WebsocketController extends ClientApiController
16
{
17
/**
18
* WebsocketController constructor.
19
*/
20
public function __construct(
21
private NodeJWTService $jwtService,
22
private GetUserPermissionsService $permissionsService,
23
) {
24
parent::__construct();
25
}
26
27
/**
28
* Generates a one-time token that is sent along in every websocket call to the Daemon.
29
* This is a signed JWT that the Daemon then uses to verify the user's identity, and
30
* allows us to continually renew this token and avoid users maintaining sessions wrongly,
31
* as well as ensure that user's only perform actions they're allowed to.
32
*/
33
public function __invoke(ClientApiRequest $request, Server $server): JsonResponse
34
{
35
$user = $request->user();
36
if ($user->cannot(Permission::ACTION_WEBSOCKET_CONNECT, $server)) {
37
throw new HttpForbiddenException('You do not have permission to connect to this server\'s websocket.');
38
}
39
40
$permissions = $this->permissionsService->handle($server, $user);
41
42
$node = $server->node;
43
if (!is_null($server->transfer)) {
44
// Check if the user has permissions to receive transfer logs.
45
if (!in_array('admin.websocket.transfer', $permissions)) {
46
throw new HttpForbiddenException('You do not have permission to view server transfer logs.');
47
}
48
49
// Redirect the websocket request to the new node if the server has been archived.
50
if ($server->transfer->archived) {
51
$node = $server->transfer->newNode;
52
}
53
}
54
55
$token = $this->jwtService
56
->setExpiresAt(CarbonImmutable::now()->addMinutes(10))
57
->setUser($request->user())
58
->setClaims([
59
'server_uuid' => $server->uuid,
60
'permissions' => $permissions,
61
])
62
->handle($node, $user->id . $server->uuid);
63
64
$socket = str_replace(['https://', 'http://'], ['wss://', 'ws://'], $node->getConnectionAddress());
65
66
return new JsonResponse([
67
'data' => [
68
'token' => $token->toString(),
69
'socket' => $socket . sprintf('/api/servers/%s/ws', $server->uuid),
70
],
71
]);
72
}
73
}
74
75