v1.10.0 #471
@@ -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;
|
||||
|
||||
@@ -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(() => {
|
||||
|
||||
Reference in New Issue
Block a user