fix: harden connection, payload, and persisted state handling (#1354)

* fix: clean up Cloudflare tunnel timeouts

* fix: couple tunnel socket lifecycle

* fix: validate Docker console messages

* fix: bound homepage proxy responses

* fix: bound reconnect and response failures

* fix: harden persisted and socket state

* fix: support local connections to shared hosts
This commit is contained in:
ZacharyZcR
2026-08-28 10:36:39 +08:00
committed by GitHub
parent 703e8cd037
commit c129666d7f
28 changed files with 689 additions and 157 deletions
+21 -2
View File
@@ -88,6 +88,7 @@ import { isPhysicalShortcutKey, isTabKeyEvent } from "./terminal-key-event.ts";
import { installTouchWheelCoordinator } from "./touch-wheel-coordinator.ts";
import { loadTouchInputSettings } from "./touch-input-settings-store.ts";
import { quoteTerminalImagePath } from "./terminal-image-path.ts";
import { hydrateLocalSharedHostAuth } from "@/lib/remote-server-api.ts";
import {
getUserPreferences,
parseCustomKeybindings,
@@ -1265,6 +1266,7 @@ const TerminalInner = forwardRef<TerminalHandle, SSHTerminalProps>(
let baseWsUrl: string;
let wsProtocols: string[] = [];
let outboundHostConfig = hostConfig;
if (isDev) {
baseWsUrl = `${window.location.protocol === "https:" ? "wss" : "ws"}://localhost:30002`;
@@ -1287,6 +1289,22 @@ const TerminalInner = forwardRef<TerminalHandle, SSHTerminalProps>(
isConnectingRef.current = false;
return;
}
if (origin === "local") {
try {
outboundHostConfig = await hydrateLocalSharedHostAuth(hostConfig);
} catch (error) {
const message = getErrorMessage(
error,
"Failed to load shared SSH authentication",
);
setIsConnected(false);
setIsConnecting(false);
updateConnectionError(message);
addLog({ type: "error", stage: "auth", message });
isConnectingRef.current = false;
return;
}
}
baseWsUrl = resolvedUrl.url;
wsProtocols = resolvedUrl.protocols;
} else {
@@ -1319,13 +1337,14 @@ const TerminalInner = forwardRef<TerminalHandle, SSHTerminalProps>(
isReconnectingRef.current = false;
setIsConnecting(true);
setupWebSocketListeners(ws, cols, rows);
setupWebSocketListeners(ws, cols, rows, outboundHostConfig);
}
function setupWebSocketListeners(
ws: WebSocket,
cols: number,
rows: number,
outboundHostConfig: TerminalHostConfig,
) {
ws.addEventListener("open", () => {
alternateScreenModeRef.current = false;
@@ -1402,7 +1421,7 @@ const TerminalInner = forwardRef<TerminalHandle, SSHTerminalProps>(
data: {
cols,
rows,
hostConfig,
hostConfig: outboundHostConfig,
initialPath,
executeCommand,
tmuxAttachSession,