mirror of
https://github.com/binaricat/Netcatty.git
synced 2026-10-29 18:11:40 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3cae060ed8 |
No files matched your search
@@ -47,6 +47,7 @@ import { buildSshDeepLinkConnectionHost, buildSshDeepLinkEphemeralHost, buildSsh
|
||||
import { buildTelnetDeepLinkConnectionHost, buildTelnetDeepLinkEphemeralHostFromSaved, buildTelnetDeepLinkOpenHost, findTelnetDeepLinkHost, materializeTelnetDeepLinkMatchHost, parseTelnetDeepLink } from '../../domain/telnetDeepLink';
|
||||
import { buildJmsDeepLinkEphemeralHost, isSupportedJmsProtocol, parseJmsDeepLink } from '../../domain/jmsDeepLink';
|
||||
import { applyEphemeralHostDistroUpdate, applyEphemeralHostsUpdate, splitHostsUpdateByEphemeral } from '../../domain/ephemeralHosts';
|
||||
import { prepareConnectionHost } from '../../domain/legacyAlgorithms';
|
||||
import { resolveHostAuth } from '../../domain/sshAuth';
|
||||
import { isEncryptedCredentialPlaceholder, stripSyncPayloadEncryptedCredentials } from '../../domain/credentials';
|
||||
import {
|
||||
@@ -1450,11 +1451,15 @@ export function AppSideEffects() {
|
||||
|
||||
// Wrapper to connect to host with logging
|
||||
const handleConnectToHost = useCallback((host: Host, alreadyEffective = false, hidden = false) => {
|
||||
if (host.ephemeral) {
|
||||
const connectionHost = prepareConnectionHost(
|
||||
host,
|
||||
terminalSettings.temporaryConnectionsAllowLegacyAlgorithms,
|
||||
);
|
||||
if (connectionHost.ephemeral) {
|
||||
setEphemeralHosts((previous) => {
|
||||
const existingIndex = previous.findIndex((candidate) => candidate.id === host.id);
|
||||
if (existingIndex < 0) return [...previous, host];
|
||||
return previous.map((candidate, index) => index === existingIndex ? host : candidate);
|
||||
const existingIndex = previous.findIndex((candidate) => candidate.id === connectionHost.id);
|
||||
if (existingIndex < 0) return [...previous, connectionHost];
|
||||
return previous.map((candidate, index) => index === existingIndex ? connectionHost : candidate);
|
||||
});
|
||||
}
|
||||
const effectiveHostResolver = alreadyEffective
|
||||
@@ -1464,7 +1469,7 @@ export function AppSideEffects() {
|
||||
addConnectionLog,
|
||||
connectToHost,
|
||||
discoveredShells,
|
||||
host,
|
||||
host: connectionHost,
|
||||
identities,
|
||||
keys,
|
||||
resolveEffectiveHost: effectiveHostResolver,
|
||||
@@ -1472,7 +1477,7 @@ export function AppSideEffects() {
|
||||
resolveShellSetting,
|
||||
systemInfoRef,
|
||||
terminalSettings,
|
||||
}), host, hidden);
|
||||
}), connectionHost, hidden);
|
||||
}, [addConnectionLog, connectToHost, resolveEffectiveHost, identities, keys, discoveredShells, terminalSettings]);
|
||||
|
||||
const handleConnectToHostWithTabName = useCallback((host: Host, tabName?: string) => {
|
||||
|
||||
@@ -836,6 +836,8 @@ Highlight the focused split pane:
|
||||
'settings.terminal.section.connection': 'Connection',
|
||||
'settings.terminal.connection.verifyHostKeys': 'Verify SSH host keys',
|
||||
'settings.terminal.connection.verifyHostKeys.desc': 'Ask before connecting to a new or changed SSH host key. Turn this off only for trusted private networks.',
|
||||
'settings.terminal.connection.temporaryLegacyAlgorithms': 'Allow legacy algorithms for temporary connections',
|
||||
'settings.terminal.connection.temporaryLegacyAlgorithms.desc': 'SSH connections with no saved host, including PuTTY-style launches and quick connect, offer the same deprecated algorithms as the per-host option. Saved hosts keep their own setting. Off by default; these algorithms have known weaknesses.',
|
||||
'settings.terminal.connection.sshAutoReconnectEnabled': 'Automatically reconnect SSH sessions',
|
||||
'settings.terminal.connection.sshAutoReconnectEnabled.desc': 'When turned on, established SSH sessions that drop unexpectedly try to reconnect every 5 seconds until the tab is closed or the connection succeeds.',
|
||||
'settings.terminal.connection.keepaliveInterval': 'Keepalive Interval',
|
||||
|
||||
@@ -751,6 +751,8 @@ Resalta el panel dividido enfocado:
|
||||
'settings.terminal.section.connection': 'Conexión',
|
||||
'settings.terminal.connection.verifyHostKeys': 'Verificar las claves de host SSH',
|
||||
'settings.terminal.connection.verifyHostKeys.desc': 'Pregunta antes de conectarse a una clave de host SSH nueva o modificada. Desactívalo solo en redes privadas de confianza.',
|
||||
'settings.terminal.connection.temporaryLegacyAlgorithms': 'Permitir algoritmos heredados en conexiones temporales',
|
||||
'settings.terminal.connection.temporaryLegacyAlgorithms.desc': 'Las conexiones SSH sin un host guardado, incluidos los inicios al estilo PuTTY y la conexión rápida, ofrecen los mismos algoritmos obsoletos que la opción por host. Los hosts guardados conservan su propio ajuste. Desactivado de forma predeterminada; estos algoritmos tienen debilidades conocidas.',
|
||||
'settings.terminal.connection.sshAutoReconnectEnabled': 'Reconectar sesiones SSH automáticamente',
|
||||
'settings.terminal.connection.sshAutoReconnectEnabled.desc': 'Cuando está activado, las sesiones SSH establecidas que se caen inesperadamente intentan reconectarse cada 5 segundos hasta que la pestaña se cierra o la conexión se establece.',
|
||||
'settings.terminal.connection.keepaliveInterval': 'Intervalo de keepalive',
|
||||
|
||||
@@ -791,6 +791,8 @@ export const ruCoreMessages: Messages = {
|
||||
'settings.terminal.localShellSidePanel.autoOpenPane.desc': 'Выберите, какую панель открывать в первую очередь.',
|
||||
'settings.terminal.localShellSidePanel.pane.files': 'Файлы',
|
||||
'settings.terminal.section.connection': 'Подключение',
|
||||
'settings.terminal.connection.temporaryLegacyAlgorithms': 'Устаревшие алгоритмы для временных подключений',
|
||||
'settings.terminal.connection.temporaryLegacyAlgorithms.desc': 'SSH-подключения без сохранённого хоста, включая запуск в стиле PuTTY и быстрое подключение, предлагают те же устаревшие алгоритмы, что и настройка хоста. Сохранённые хосты используют свою настройку. По умолчанию выключено: у этих алгоритмов есть известные слабости.',
|
||||
'settings.terminal.connection.keepaliveInterval': 'Интервал keepalive',
|
||||
'settings.terminal.connection.keepaliveInterval.desc': 'Как часто (в секундах) отправлять keepalive-пакеты на уровне SSH. Установите 0, чтобы отключить глобально. Учтите, что отдельные хосты могут переопределять это значение в своих настройках.',
|
||||
'settings.terminal.connection.keepaliveCountMax': 'Макс. число пропущенных keepalive',
|
||||
|
||||
@@ -47,6 +47,22 @@ test("localized settings include workspace focus indicator labels", () => {
|
||||
}
|
||||
});
|
||||
|
||||
test("localized settings include temporary-connection legacy algorithm labels", () => {
|
||||
const keys = [
|
||||
"settings.terminal.connection.temporaryLegacyAlgorithms",
|
||||
"settings.terminal.connection.temporaryLegacyAlgorithms.desc",
|
||||
];
|
||||
const locales = [{ name: "en", messages: en }, ...LOCALIZED_SETTINGS_LOCALES];
|
||||
|
||||
for (const locale of locales) {
|
||||
const missing = keys.filter((key) => !locale.messages[key]);
|
||||
assert.deepEqual(missing, [], `${locale.name} is missing temporary legacy algorithm labels`);
|
||||
}
|
||||
|
||||
assert.match(zhCN["settings.terminal.connection.temporaryLegacyAlgorithms"], /临时连接允许旧版算法/);
|
||||
assert.match(zhTW["settings.terminal.connection.temporaryLegacyAlgorithms"], /臨時連線允許舊版演算法/);
|
||||
});
|
||||
|
||||
test("localized settings include the global default proxy labels", () => {
|
||||
const keys = [
|
||||
"settings.terminal.connection.defaultProxy",
|
||||
|
||||
@@ -454,6 +454,8 @@ export const zhCNTerminalMessages: Messages = {
|
||||
'settings.terminal.localShell.startDir.notFound': '目录不存在',
|
||||
'settings.terminal.localShell.startDir.isFile': '路径是文件,不是目录',
|
||||
'settings.terminal.section.connection': '连接',
|
||||
'settings.terminal.connection.temporaryLegacyAlgorithms': '临时连接允许旧版算法',
|
||||
'settings.terminal.connection.temporaryLegacyAlgorithms.desc': '没有对应已保存主机的 SSH 连接(包括外部程序以 PuTTY 参数启动,以及快速连接)会使用与主机「允许旧版算法」相同的已弃用算法。已保存主机仍使用自己的设置。默认关闭,这些算法有已知安全问题。',
|
||||
'settings.terminal.connection.defaultProxy': '默认代理',
|
||||
'settings.terminal.connection.defaultProxy.desc': '主机没有单独设置、也没有从分组继承代理时使用的已保存代理。选择“无”则直接连接。',
|
||||
'settings.terminal.connection.defaultProxy.none': '无',
|
||||
|
||||
@@ -454,6 +454,8 @@ export const zhTWTerminalMessages: Messages = {
|
||||
'settings.terminal.localShell.startDir.notFound': '目錄不存在',
|
||||
'settings.terminal.localShell.startDir.isFile': '路徑是檔案,不是目錄',
|
||||
'settings.terminal.section.connection': '連線',
|
||||
'settings.terminal.connection.temporaryLegacyAlgorithms': '臨時連線允許舊版演算法',
|
||||
'settings.terminal.connection.temporaryLegacyAlgorithms.desc': '沒有對應已儲存主機的 SSH 連線(包括外部程式以 PuTTY 參數啟動,以及快速連線)會使用與主機「允許舊版演算法」相同的已棄用演算法。已儲存主機仍使用自己的設定。預設關閉,這些演算法有已知安全問題。',
|
||||
'settings.terminal.connection.defaultProxy': '預設代理',
|
||||
'settings.terminal.connection.defaultProxy.desc': '主機沒有單獨設定、也沒有從群組繼承代理時使用的已儲存代理。選擇「無」則直接連線。',
|
||||
'settings.terminal.connection.defaultProxy.none': '無',
|
||||
|
||||
@@ -998,6 +998,16 @@ function SettingsTerminalTab(props: {
|
||||
onChange={(v) => updateTerminalSetting("verifyHostKeys", v)}
|
||||
/>
|
||||
</SettingRow>
|
||||
<SettingRow
|
||||
anchorId="terminal-temporary-legacy-algorithms"
|
||||
label={t("settings.terminal.connection.temporaryLegacyAlgorithms")}
|
||||
description={t("settings.terminal.connection.temporaryLegacyAlgorithms.desc")}
|
||||
>
|
||||
<Toggle
|
||||
checked={terminalSettings.temporaryConnectionsAllowLegacyAlgorithms}
|
||||
onChange={(v) => updateTerminalSetting("temporaryConnectionsAllowLegacyAlgorithms", v)}
|
||||
/>
|
||||
</SettingRow>
|
||||
<SettingRow
|
||||
anchorId="terminal-ssh-auto-reconnect"
|
||||
label={t("settings.terminal.connection.sshAutoReconnectEnabled")}
|
||||
|
||||
@@ -486,5 +486,6 @@ export const sanitizeHost = (host: Host, snippets: Snippet[] = []): Host => {
|
||||
pluginConnection,
|
||||
};
|
||||
delete (sanitized as { singleChannelSsh?: unknown }).singleChannelSsh;
|
||||
delete (sanitized as { backedBySavedHost?: boolean }).backedBySavedHost;
|
||||
return stripBuiltInConnectionFieldsForPluginHost(sanitized);
|
||||
};
|
||||
@@ -0,0 +1,137 @@
|
||||
import assert from "node:assert/strict";
|
||||
import test from "node:test";
|
||||
|
||||
import { sanitizeHost } from "./host.ts";
|
||||
import {
|
||||
prepareConnectionHost,
|
||||
resolveConnectionLegacyAlgorithms,
|
||||
} from "./legacyAlgorithms.ts";
|
||||
import { normalizeTerminalSettings } from "./models/terminal.ts";
|
||||
import type { Host } from "./models.ts";
|
||||
|
||||
const host = (overrides: Partial<Host> = {}): Host => ({
|
||||
id: "host-1",
|
||||
label: "host",
|
||||
hostname: "bastion.example",
|
||||
username: "root",
|
||||
tags: [],
|
||||
os: "linux",
|
||||
protocol: "ssh",
|
||||
...overrides,
|
||||
});
|
||||
|
||||
test("a saved host uses its per-host legacy algorithm value when the global setting is on", () => {
|
||||
const saved = host({
|
||||
hostname: "127.0.0.1",
|
||||
port: 2222,
|
||||
legacyAlgorithms: false,
|
||||
});
|
||||
|
||||
assert.equal(prepareConnectionHost(saved, true), saved);
|
||||
assert.equal(resolveConnectionLegacyAlgorithms({
|
||||
hasSavedHost: true,
|
||||
hostLegacyAlgorithms: false,
|
||||
temporaryConnectionsAllowLegacyAlgorithms: true,
|
||||
}), false);
|
||||
});
|
||||
|
||||
test("a saved host keeps legacy algorithms enabled when the global setting is off", () => {
|
||||
const saved = host({ legacyAlgorithms: true });
|
||||
|
||||
assert.equal(prepareConnectionHost(saved, false), saved);
|
||||
assert.equal(resolveConnectionLegacyAlgorithms({
|
||||
hasSavedHost: true,
|
||||
hostLegacyAlgorithms: true,
|
||||
temporaryConnectionsAllowLegacyAlgorithms: false,
|
||||
}), true);
|
||||
});
|
||||
|
||||
test("a saved host with no explicit value does not inherit the global temporary setting", () => {
|
||||
const saved = host({ hostname: "127.0.0.1", legacyAlgorithms: undefined });
|
||||
|
||||
assert.equal(prepareConnectionHost(saved, true), saved);
|
||||
assert.equal(resolveConnectionLegacyAlgorithms({
|
||||
hasSavedHost: true,
|
||||
hostLegacyAlgorithms: undefined,
|
||||
temporaryConnectionsAllowLegacyAlgorithms: true,
|
||||
}), false);
|
||||
});
|
||||
|
||||
test("a temporary connection uses the global legacy algorithm value", () => {
|
||||
const temporary = host({
|
||||
id: "ephemeral-1",
|
||||
ephemeral: true,
|
||||
hostname: "127.0.0.1",
|
||||
port: 54321,
|
||||
});
|
||||
|
||||
assert.equal(prepareConnectionHost(temporary, true).legacyAlgorithms, true);
|
||||
assert.equal(prepareConnectionHost(temporary, false).legacyAlgorithms, undefined);
|
||||
assert.equal(resolveConnectionLegacyAlgorithms({
|
||||
hasSavedHost: false,
|
||||
temporaryConnectionsAllowLegacyAlgorithms: true,
|
||||
}), true);
|
||||
assert.equal(resolveConnectionLegacyAlgorithms({
|
||||
hasSavedHost: false,
|
||||
hostLegacyAlgorithms: true,
|
||||
temporaryConnectionsAllowLegacyAlgorithms: false,
|
||||
}), false);
|
||||
});
|
||||
|
||||
test("an ephemeral clone of a saved host keeps that host's legacy algorithm value", () => {
|
||||
const cloned = host({
|
||||
id: "ephemeral-from-saved",
|
||||
ephemeral: true,
|
||||
backedBySavedHost: true,
|
||||
hostname: "127.0.0.1",
|
||||
port: 61000,
|
||||
legacyAlgorithms: false,
|
||||
});
|
||||
|
||||
assert.equal(prepareConnectionHost(cloned, true), cloned);
|
||||
assert.equal(prepareConnectionHost(host({
|
||||
ephemeral: true,
|
||||
backedBySavedHost: true,
|
||||
legacyAlgorithms: true,
|
||||
}), false).legacyAlgorithms, true);
|
||||
});
|
||||
|
||||
test("temporary connection legacy algorithms default to off", () => {
|
||||
const temporary = host({ ephemeral: true, hostname: "127.0.0.1" });
|
||||
|
||||
assert.equal(resolveConnectionLegacyAlgorithms({ hasSavedHost: false }), false);
|
||||
assert.equal(prepareConnectionHost(temporary).legacyAlgorithms, undefined);
|
||||
assert.equal(normalizeTerminalSettings().temporaryConnectionsAllowLegacyAlgorithms, false);
|
||||
assert.equal(
|
||||
normalizeTerminalSettings({ temporaryConnectionsAllowLegacyAlgorithms: true })
|
||||
.temporaryConnectionsAllowLegacyAlgorithms,
|
||||
true,
|
||||
);
|
||||
assert.equal(
|
||||
normalizeTerminalSettings({
|
||||
temporaryConnectionsAllowLegacyAlgorithms: "yes" as never,
|
||||
}).temporaryConnectionsAllowLegacyAlgorithms,
|
||||
false,
|
||||
);
|
||||
});
|
||||
|
||||
test("saved-host clones do not persist the runtime backing marker", () => {
|
||||
const sanitized = sanitizeHost(host({
|
||||
ephemeral: true,
|
||||
backedBySavedHost: true,
|
||||
legacyAlgorithms: true,
|
||||
}));
|
||||
|
||||
assert.equal("backedBySavedHost" in sanitized, false);
|
||||
assert.equal(sanitized.legacyAlgorithms, true);
|
||||
});
|
||||
|
||||
test("temporary telnet connections do not receive the SSH legacy algorithm flag", () => {
|
||||
const telnet = host({
|
||||
ephemeral: true,
|
||||
protocol: "telnet",
|
||||
hostname: "127.0.0.1",
|
||||
});
|
||||
|
||||
assert.equal(prepareConnectionHost(telnet, true), telnet);
|
||||
});
|
||||
@@ -0,0 +1,58 @@
|
||||
import type { Host } from "./models";
|
||||
|
||||
export interface ConnectionLegacyAlgorithmInput {
|
||||
/** True when a saved vault host owns this connection, including an ephemeral clone of one. */
|
||||
hasSavedHost: boolean;
|
||||
/** Per-host value after that host's own settings are applied. */
|
||||
hostLegacyAlgorithms?: boolean;
|
||||
/**
|
||||
* Global opt-in for SSH connections with no saved host.
|
||||
* Missing or any non-true value stays off.
|
||||
*/
|
||||
temporaryConnectionsAllowLegacyAlgorithms?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saved hosts keep their own legacy-algorithm choice. Connections with no
|
||||
* saved host use the global temporary-connection opt-in, which defaults to
|
||||
* off. The address is not an input, so 127.0.0.1 alone never opts in.
|
||||
*/
|
||||
export function resolveConnectionLegacyAlgorithms(
|
||||
input: ConnectionLegacyAlgorithmInput,
|
||||
): boolean {
|
||||
if (input.hasSavedHost) return input.hostLegacyAlgorithms === true;
|
||||
return input.temporaryConnectionsAllowLegacyAlgorithms === true;
|
||||
}
|
||||
|
||||
export function connectionHasSavedHost(
|
||||
host: Pick<Host, "ephemeral" | "backedBySavedHost"> | null | undefined,
|
||||
): boolean {
|
||||
if (!host) return false;
|
||||
if (host.backedBySavedHost === true) return true;
|
||||
return host.ephemeral !== true;
|
||||
}
|
||||
|
||||
function isTemporarySshHost(
|
||||
host: Pick<Host, "ephemeral" | "backedBySavedHost" | "protocol">,
|
||||
): boolean {
|
||||
if (connectionHasSavedHost(host)) return false;
|
||||
return host.protocol === undefined || host.protocol === "ssh";
|
||||
}
|
||||
|
||||
/**
|
||||
* Stamp the resolved legacy-algorithm flag onto unsaved temporary SSH hosts.
|
||||
* Saved hosts, and ephemeral clones of saved hosts, are returned unchanged so
|
||||
* their own value (including a later group default) still applies.
|
||||
*/
|
||||
export function prepareConnectionHost<T extends Host>(
|
||||
host: T,
|
||||
temporaryConnectionsAllowLegacyAlgorithms?: boolean,
|
||||
): T {
|
||||
if (!isTemporarySshHost(host)) return host;
|
||||
const legacyAlgorithms = resolveConnectionLegacyAlgorithms({
|
||||
hasSavedHost: false,
|
||||
temporaryConnectionsAllowLegacyAlgorithms,
|
||||
});
|
||||
if ((host.legacyAlgorithms === true) === legacyAlgorithms) return host;
|
||||
return { ...host, legacyAlgorithms };
|
||||
}
|
||||
@@ -183,6 +183,10 @@ export interface Host {
|
||||
// Runtime marker for in-memory-only hosts (e.g. password deep links).
|
||||
// Ephemeral hosts are never persisted to the vault or session restore.
|
||||
ephemeral?: boolean;
|
||||
// Runtime marker for an ephemeral host cloned from a saved vault host.
|
||||
// Those connections keep the saved host's own SSH settings. Pure temporary
|
||||
// launches (external command lines, quick connect) leave this unset.
|
||||
backedBySavedHost?: boolean;
|
||||
// Runtime hint for deep-link launches that target file transfer (e.g.
|
||||
// JumpServer sftp payloads): auto-open the SFTP side panel on connect.
|
||||
autoOpenSftpPanel?: boolean;
|
||||
|
||||
@@ -143,6 +143,12 @@ export interface TerminalSettings {
|
||||
|
||||
// SSH Connection
|
||||
verifyHostKeys: boolean; // Verify SSH host keys before authenticating
|
||||
/**
|
||||
* Offer the per-host legacy SSH algorithm list for connections that have
|
||||
* no saved host (external launches and quick connect). Saved hosts ignore
|
||||
* this and keep their own setting. Off by default.
|
||||
*/
|
||||
temporaryConnectionsAllowLegacyAlgorithms: boolean;
|
||||
keepaliveInterval: number; // Seconds between SSH-level keepalive packets (0 = disabled)
|
||||
keepaliveCountMax: number; // Unanswered keepalives before declaring the connection dead
|
||||
sshAutoReconnectEnabled: boolean; // Automatically reconnect SSH sessions after unexpected disconnects
|
||||
@@ -468,6 +474,8 @@ export const normalizeTerminalSettings = (
|
||||
|
||||
return {
|
||||
...mergedSettings,
|
||||
temporaryConnectionsAllowLegacyAlgorithms:
|
||||
mergedSettings.temporaryConnectionsAllowLegacyAlgorithms === true,
|
||||
rendererType,
|
||||
autocompleteMaxSuggestions,
|
||||
multilinePasteConfirmMinLines: normalizeMultilinePasteConfirmMinLines(
|
||||
@@ -568,6 +576,7 @@ const DEFAULT_TERMINAL_SETTINGS: TerminalSettings = {
|
||||
// reply to keepalive@openssh.com (older routers/switches) should set their
|
||||
// own per-host keepaliveOverride and dial these values down.
|
||||
verifyHostKeys: true,
|
||||
temporaryConnectionsAllowLegacyAlgorithms: false,
|
||||
keepaliveInterval: 30,
|
||||
keepaliveCountMax: 10,
|
||||
// On by default: unexpected transport drops (VPN / Wi-Fi blips) schedule an
|
||||
|
||||
@@ -480,6 +480,14 @@ export const SETTINGS_SEARCH_CATALOG: readonly SettingsSearchEntry[] = [
|
||||
descriptionKey: "settings.terminal.connection.verifyHostKeys.desc",
|
||||
sectionKey: "settings.terminal.section.connection",
|
||||
},
|
||||
{
|
||||
id: "terminal-temporary-legacy-algorithms",
|
||||
tab: "terminal",
|
||||
labelKey: "settings.terminal.connection.temporaryLegacyAlgorithms",
|
||||
descriptionKey: "settings.terminal.connection.temporaryLegacyAlgorithms.desc",
|
||||
sectionKey: "settings.terminal.section.connection",
|
||||
keywords: ["legacy", "kex", "putty", "旧版算法", "演算法", "堡垒机"],
|
||||
},
|
||||
{
|
||||
id: "terminal-ssh-auto-reconnect",
|
||||
tab: "terminal",
|
||||
|
||||
@@ -118,6 +118,7 @@ test("buildSshDeepLinkEphemeralHostFromSaved keeps saved settings but overrides
|
||||
proxyProfileId: "proxy-1",
|
||||
hostChain: { hostIds: ["jump-1"] },
|
||||
charset: "utf8",
|
||||
legacyAlgorithms: true,
|
||||
moshEnabled: true,
|
||||
createdAt: 1,
|
||||
};
|
||||
@@ -141,6 +142,8 @@ test("buildSshDeepLinkEphemeralHostFromSaved keeps saved settings but overrides
|
||||
// Group is cleared so effective-host resolution cannot re-inherit
|
||||
// group credentials over the one-time password.
|
||||
assert.equal(ephemeral.group, "");
|
||||
assert.equal(ephemeral.backedBySavedHost, true);
|
||||
assert.equal(ephemeral.legacyAlgorithms, true);
|
||||
assert.equal(ephemeral.proxyProfileId, "proxy-1");
|
||||
assert.deepEqual(ephemeral.hostChain, { hostIds: ["jump-1"] });
|
||||
assert.equal(ephemeral.charset, "utf8");
|
||||
|
||||
@@ -146,6 +146,7 @@ export const buildSshDeepLinkEphemeralHostFromSaved = (
|
||||
savePassword: false,
|
||||
group: "",
|
||||
ephemeral: true,
|
||||
backedBySavedHost: true,
|
||||
protocol: "ssh",
|
||||
moshEnabled: false,
|
||||
etEnabled: false,
|
||||
|
||||
Reference in new issue
Block a user