v1.10.0 #471

Merged
LukeGus merged 106 commits from dev-1.10.0 into main 2026-01-01 04:20:12 +00:00
2 changed files with 52 additions and 52 deletions
Showing only changes of commit 731744d6c2 - Show all commits

View File

@@ -137,10 +137,14 @@ async function createJumpHostChain(
const clients: Client[] = [];
try {
for (let i = 0; i < jumpHosts.length; i++) {
const jumpHostConfig = await resolveJumpHost(jumpHosts[i].hostId, userId);
// Fetch all jump host configurations in parallel
const jumpHostConfigs = await Promise.all(
jumpHosts.map((jh) => resolveJumpHost(jh.hostId, userId)),
);
if (!jumpHostConfig) {
// Validate all configs resolved
for (let i = 0; i < jumpHostConfigs.length; i++) {
if (!jumpHostConfigs[i]) {
sshLogger.error(`Jump host ${i + 1} not found`, undefined, {
operation: "jump_host_chain",
hostId: jumpHosts[i].hostId,
@@ -148,6 +152,11 @@ async function createJumpHostChain(
clients.forEach((c) => c.end());
return null;
}
}
// Connect through jump hosts sequentially
for (let i = 0; i < jumpHostConfigs.length; i++) {
const jumpHostConfig = jumpHostConfigs[i];
const jumpClient = new Client();
clients.push(jumpClient);
@@ -623,7 +632,7 @@ wss.on("connection", async (ws: WebSocket, req) => {
);
cleanupSSH(connectionTimeout);
}
}, 120000);
}, 30000);
let resolvedCredentials = { password, key, keyPassword, keyType, authType };
let authMethodNotAvailable = false;
@@ -1053,10 +1062,10 @@ wss.on("connection", async (ws: WebSocket, req) => {
tryKeyboard: true,
keepaliveInterval: 30000,
keepaliveCountMax: 3,
readyTimeout: 120000,
readyTimeout: 30000,
tcpKeepAlive: true,
tcpKeepAliveInitialDelay: 30000,
timeout: 120000,
timeout: 30000,
env: {
TERM: "xterm-256color",
LANG: "en_US.UTF-8",
@@ -1191,21 +1200,18 @@ wss.on("connection", async (ws: WebSocket, req) => {
if (
hostConfig.useSocks5 &&
(hostConfig.socks5Host ||
(hostConfig.socks5ProxyChain && (hostConfig.socks5ProxyChain as any).length > 0))
(hostConfig.socks5ProxyChain &&
(hostConfig.socks5ProxyChain as any).length > 0))
) {
try {
const socks5Socket = await createSocks5Connection(
ip,
port,
{
const socks5Socket = await createSocks5Connection(ip, port, {
useSocks5: hostConfig.useSocks5,
socks5Host: hostConfig.socks5Host,
socks5Port: hostConfig.socks5Port,
socks5Username: hostConfig.socks5Username,
socks5Password: hostConfig.socks5Password,
socks5ProxyChain: hostConfig.socks5ProxyChain as any,
},
);
});
if (socks5Socket) {
connectConfig.sock = socks5Socket;

View File

@@ -637,7 +637,7 @@ export const Terminal = forwardRef<TerminalHandle, SSHTerminalProps>(
attemptReconnection();
}
}
}, 10000);
}, 15000);
ws.send(
JSON.stringify({
@@ -765,6 +765,7 @@ export const Terminal = forwardRef<TerminalHandle, SSHTerminalProps>(
...hostConfig.terminalConfig,
};
// Send all environment variables immediately without delays
if (
terminalConfig.environmentVariables &&
terminalConfig.environmentVariables.length > 0
@@ -777,11 +778,11 @@ export const Terminal = forwardRef<TerminalHandle, SSHTerminalProps>(
data: `export ${envVar.key}="${envVar.value}"\n`,
}),
);
await new Promise((resolve) => setTimeout(resolve, 100));
}
}
}
// Send startup snippet immediately after env vars
if (terminalConfig.startupSnippetId) {
try {
const snippets = await getSnippets();
@@ -796,13 +797,13 @@ export const Terminal = forwardRef<TerminalHandle, SSHTerminalProps>(
data: snippet.content + "\n",
}),
);
await new Promise((resolve) => setTimeout(resolve, 200));
}
} catch (err) {
console.warn("Failed to execute startup snippet:", err);
}
}
// Execute mosh command immediately if enabled
if (terminalConfig.autoMosh && ws.readyState === 1) {
ws.send(
JSON.stringify({
@@ -811,7 +812,7 @@ export const Terminal = forwardRef<TerminalHandle, SSHTerminalProps>(
}),
);
}
}, 500);
}, 100);
} else if (msg.type === "disconnected") {
wasDisconnectedBySSH.current = true;
setIsConnected(false);
@@ -1405,13 +1406,7 @@ export const Terminal = forwardRef<TerminalHandle, SSHTerminalProps>(
setIsConnecting(true);
const readyFonts =
(document as { fonts?: { ready?: Promise<unknown> } }).fonts
?.ready instanceof Promise
? (document as { fonts?: { ready?: Promise<unknown> } }).fonts.ready
: Promise.resolve();
readyFonts.then(() => {
// Start connection immediately without waiting for fonts
requestAnimationFrame(() => {
fitAddonRef.current?.fit();
if (terminal && terminal.cols > 0 && terminal.rows > 0) {
@@ -1440,7 +1435,6 @@ export const Terminal = forwardRef<TerminalHandle, SSHTerminalProps>(
connectToHost(cols, rows);
});
});
}, [terminal, hostConfig, visible, isConnected, isConnecting, splitScreen]);
useEffect(() => {