feat(ssh): support proxy command connections
This commit is contained in:
@@ -2,7 +2,7 @@ import type { SftpFilenameEncoding } from './sftp';
|
||||
import type { KeywordHighlightRule } from './terminal';
|
||||
|
||||
// Proxy configuration for SSH connections
|
||||
type ProxyType = 'http' | 'socks5';
|
||||
type ProxyType = 'http' | 'socks5' | 'command';
|
||||
// UI locale identifier, stored in settings and used for i18n (e.g., "en", "zh-CN").
|
||||
export type UILanguage = string;
|
||||
|
||||
@@ -10,6 +10,7 @@ export interface ProxyConfig {
|
||||
type: ProxyType;
|
||||
host: string;
|
||||
port: number;
|
||||
command?: string;
|
||||
username?: string;
|
||||
password?: string;
|
||||
}
|
||||
|
||||
@@ -84,8 +84,40 @@ test("normalizeManualProxyConfig clears empty proxy drafts", () => {
|
||||
);
|
||||
});
|
||||
|
||||
test("normalizeManualProxyConfig trims command proxy drafts", () => {
|
||||
assert.deepEqual(
|
||||
normalizeManualProxyConfig({
|
||||
type: "command",
|
||||
host: "ignored.example.com",
|
||||
port: 8080,
|
||||
command: " cloudflared access ssh --hostname %h ",
|
||||
username: "ignored",
|
||||
password: "ignored",
|
||||
}),
|
||||
{
|
||||
type: "command",
|
||||
host: "",
|
||||
port: 0,
|
||||
command: "cloudflared access ssh --hostname %h",
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test("isCompleteProxyConfig requires host and a valid port", () => {
|
||||
assert.equal(isCompleteProxyConfig({ type: "http", host: "", port: 8080 }), false);
|
||||
assert.equal(isCompleteProxyConfig({ type: "http", host: "proxy.example.com", port: 0 }), false);
|
||||
assert.equal(isCompleteProxyConfig({ type: "http", host: "proxy.example.com", port: 3128 }), true);
|
||||
});
|
||||
|
||||
test("isCompleteProxyConfig accepts a non-empty command proxy", () => {
|
||||
assert.equal(isCompleteProxyConfig({ type: "command", host: "", port: 0, command: "" }), false);
|
||||
assert.equal(
|
||||
isCompleteProxyConfig({
|
||||
type: "command",
|
||||
host: "",
|
||||
port: 0,
|
||||
command: "cloudflared access ssh --hostname %h",
|
||||
}),
|
||||
true,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -9,12 +9,18 @@ export const isValidProxyPort = (port: unknown): boolean => {
|
||||
return Number.isInteger(value) && value >= 1 && value <= 65535;
|
||||
};
|
||||
|
||||
export const isProxyCommandConfig = (config: ProxyConfig | undefined): boolean => {
|
||||
return config?.type === "command";
|
||||
};
|
||||
|
||||
export const isEmptyProxyConfigDraft = (config: ProxyConfig | undefined): boolean => {
|
||||
if (!config) return true;
|
||||
if (isProxyCommandConfig(config)) return !config.command?.trim();
|
||||
return !config.host.trim() && !config.username?.trim() && !config.password?.trim();
|
||||
};
|
||||
|
||||
export const isCompleteProxyConfig = (config: ProxyConfig | undefined): boolean => {
|
||||
if (isProxyCommandConfig(config)) return Boolean(config?.command?.trim());
|
||||
return Boolean(config?.host.trim()) && isValidProxyPort(config?.port);
|
||||
};
|
||||
|
||||
@@ -22,6 +28,14 @@ export const normalizeManualProxyConfig = (
|
||||
config: ProxyConfig | undefined,
|
||||
): ProxyConfig | undefined => {
|
||||
if (!config || isEmptyProxyConfigDraft(config)) return undefined;
|
||||
if (isProxyCommandConfig(config)) {
|
||||
return {
|
||||
type: "command",
|
||||
host: "",
|
||||
port: 0,
|
||||
command: config.command?.trim(),
|
||||
};
|
||||
}
|
||||
return {
|
||||
...config,
|
||||
host: config.host.trim(),
|
||||
@@ -30,6 +44,16 @@ export const normalizeManualProxyConfig = (
|
||||
};
|
||||
};
|
||||
|
||||
export const hasUsableProxyConfig = (config: ProxyConfig | undefined): boolean => {
|
||||
return isCompleteProxyConfig(config);
|
||||
};
|
||||
|
||||
export const formatProxyConfigEndpoint = (config: ProxyConfig | undefined): string => {
|
||||
if (!config) return "";
|
||||
if (isProxyCommandConfig(config)) return config.command?.trim() || "";
|
||||
return `${config.host}:${config.port}`;
|
||||
};
|
||||
|
||||
export function findProxyProfile(
|
||||
proxyProfileId: string | undefined,
|
||||
proxyProfiles: ProxyProfile[],
|
||||
|
||||
Reference in New Issue
Block a user