clusev/app/Livewire
boban 07fe404ce9 feat(terminal): web terminal — per-server SSH + Clusev host PTY (xterm.js + node sidecar)
A dedicated /terminal page with a target rail: one terminal per fleet server (SSH)
plus one for the Clusev host itself. php-fpm cannot hold an interactive PTY, so a
small Node sidecar (ws + ssh2 + node-pty) bridges xterm.js to the PTY.

Flow: the Livewire page mints a single-use, 60s TerminalSession token and dispatches
it to an Alpine xterm island; the browser opens a same-origin WS (/terminal/ws,
proxied by nginx in dev / Caddy in prod to terminal:3000); the sidecar burns the
token at an internal resolve endpoint (shared-secret header, private network only)
for a connection spec, then opens an SSH PTY (decrypted credential, never sent to the
browser) or a local host PTY. Real shell = native Tab/Shift-Tab completion.

Security:
- token burned ATOMICALLY (single conditional UPDATE) — no double-open race
- resolve endpoint guarded by hash_equals shared secret, exempt from CSRF + PanelScheme
  host enforcement (private net only), returns decrypted creds over the internal net
- sidecar enforces same-origin on the WS upgrade (hostname match, port-agnostic)
- single-use 60s tokens, swept daily so the table can't grow unbounded

Verified in-browser (R12): host + server terminals connect, accept keyboard input,
run commands, Tab-complete; cross-origin WS rejected; zero console errors. 9 feature
tests cover minting, the resolve spec, single-use burn, expiry, and locked creds.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 03:21:10 +02:00
..
Audit feat(audit): paginate the log + DB-wide search (v0.9.50) 2026-06-21 23:58:27 +02:00
Auth harden(auth): capture login IP once, assert 2fa-failed audit 2026-06-20 18:06:11 +02:00
Concerns feat(auth): feed BruteforceGuard from login + 2FA failures, audit them 2026-06-20 18:01:54 +02:00
Files feat(security): signed confirm-action tokens + airtight backup-code reveal 2026-06-15 18:35:33 +02:00
Help feat(wg): WireGuard help topic (registration + DE/EN content + test) 2026-06-20 22:46:04 +02:00
Modals feat(ssh-keys): name an added SSH key so it is identifiable 2026-06-25 00:53:49 +02:00
Release feat(release): deploy-to-public, promote-to-stable, yank actions (R5 + audit) 2026-06-23 03:26:14 +02:00
Servers refactor(metrics): interactive history chart — smooth, area, tooltip, instant ranges 2026-06-25 01:51:24 +02:00
Services feat(security): signed confirm-action tokens + airtight backup-code reveal 2026-06-15 18:35:33 +02:00
Settings harden(auth): fold IPv4-mapped IPv6, dedupe unbanAll, limit bans render, forged-token test 2026-06-20 18:53:52 +02:00
System fix(system): surface a failed restart sentinel write instead of a stuck state 2026-06-19 20:10:28 +02:00
Terminal feat(terminal): web terminal — per-server SSH + Clusev host PTY (xterm.js + node sidecar) 2026-06-25 03:21:10 +02:00
Versions fix(versions): keep the changelog series stable on reload (0.10 -> 0.1 bug) 2026-06-25 02:15:41 +02:00
Wireguard feat(audit): readable action labels + failures surfaced (v0.9.48) 2026-06-21 23:41:48 +02:00
Dashboard.php i18n: complete DE/EN localization (modals, shell, backend) + v0.3.0 2026-06-13 23:27:42 +02:00
ServerSwitcher.php fix(ui): keep the sidebar server-switcher in sync with the viewed server 2026-06-14 19:24:56 +02:00