67 lines
2.0 KiB
PHP
67 lines
2.0 KiB
PHP
<?php
|
|
|
|
namespace App\Livewire\Terminal;
|
|
|
|
use App\Models\Server;
|
|
use App\Models\TerminalSession;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Illuminate\Support\Str;
|
|
use Livewire\Attributes\Layout;
|
|
use Livewire\Component;
|
|
|
|
/**
|
|
* Terminal page. Lists the targets (the Clusev host + each server) and, on selection, mints a
|
|
* single-use session token that the xterm.js island uses to open a WebSocket to the terminal
|
|
* sidecar. The component itself never touches the SSH connection or credentials — it only authorizes
|
|
* the operator and hands out a short-lived token (resolved server-side over the internal network).
|
|
*/
|
|
#[Layout('layouts.app')]
|
|
class Index extends Component
|
|
{
|
|
/** 'host' or a server uuid — drives the active-target highlight in the rail. */
|
|
public string $activeKey = '';
|
|
|
|
public function title(): string
|
|
{
|
|
return __('terminal.title');
|
|
}
|
|
|
|
/** Mint a single-use token for the chosen target and hand it to the xterm island via an event. */
|
|
public function open(string $kind, ?string $uuid = null): void
|
|
{
|
|
$serverId = null;
|
|
$label = __('terminal.host_label');
|
|
$this->activeKey = 'host';
|
|
|
|
if ($kind !== 'host') {
|
|
$kind = 'server';
|
|
$server = Server::where('uuid', $uuid)->first();
|
|
if ($server === null) {
|
|
return;
|
|
}
|
|
$serverId = $server->id;
|
|
$label = $server->name;
|
|
$this->activeKey = $server->uuid;
|
|
}
|
|
|
|
$token = Str::random(48);
|
|
TerminalSession::create([
|
|
'token' => $token,
|
|
'user_id' => Auth::id(),
|
|
'kind' => $kind,
|
|
'server_id' => $serverId,
|
|
'expires_at' => now()->addSeconds(60),
|
|
'created_at' => now(),
|
|
]);
|
|
|
|
$this->dispatch('terminal-open', token: $token, title: $label);
|
|
}
|
|
|
|
public function render()
|
|
{
|
|
return view('livewire.terminal.index', [
|
|
'servers' => Server::orderBy('name')->get(['uuid', 'name', 'status']),
|
|
])->title($this->title());
|
|
}
|
|
}
|