mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-29 22:55:24 +00:00
feat: store rdp, vnc and telnet logins in a generic per-protocol table
This commit is contained in:
1 parent
e0c30a4e6f
commit
bba06f7ff6
107 files changed
+18750
-1224
No files matched your search
@@ -1,8 +1,9 @@
|
||||
import type { AuthOverrideProtocol } from "../../../types/auth-protocols.js";
|
||||
import {
|
||||
parseSshOptions,
|
||||
type HostSshOptions,
|
||||
} from "../../hosts/ssh-options.js";
|
||||
import { listHostProtocols } from "../../hosts/protocol-auth/registry.js";
|
||||
import { sanitizeProtocolAuthForRecipient } from "../../hosts/protocol-auth/summary.js";
|
||||
|
||||
export function isNonEmptyString(value: unknown): value is string {
|
||||
return typeof value === "string" && value.trim().length > 0;
|
||||
@@ -41,6 +42,10 @@ export function normalizeProtocolEnableFields(
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* The owner's SSH authentication, which a shared editor may not change. A
|
||||
* plugin protocol's login is guarded in writeProtocolAuth instead.
|
||||
*/
|
||||
export const OWNER_PRIVATE_AUTH_FIELDS = {
|
||||
ssh: [
|
||||
"authType",
|
||||
@@ -54,21 +59,7 @@ export const OWNER_PRIVATE_AUTH_FIELDS = {
|
||||
"keyType",
|
||||
"sudoPassword",
|
||||
],
|
||||
rdp: [
|
||||
"rdpAuthType",
|
||||
"rdpCredentialId",
|
||||
"rdpUser",
|
||||
"rdpPassword",
|
||||
"rdpDomain",
|
||||
],
|
||||
vnc: ["vncAuthType", "vncCredentialId", "vncUser", "vncPassword"],
|
||||
telnet: [
|
||||
"telnetAuthType",
|
||||
"telnetCredentialId",
|
||||
"telnetUser",
|
||||
"telnetPassword",
|
||||
],
|
||||
} as const satisfies Record<AuthOverrideProtocol, readonly string[]>;
|
||||
} as const;
|
||||
|
||||
export const OWNER_PRIVATE_TERMINAL_CONFIG_FIELDS = [
|
||||
"sudoPassword",
|
||||
@@ -80,7 +71,7 @@ export const OWNER_PRIVATE_SSH_OPTION_FIELDS = ["agentSocketPath"] as const;
|
||||
|
||||
export function containsOwnerPrivateAuthUpdate(
|
||||
hostData: Record<string, unknown>,
|
||||
protocol: AuthOverrideProtocol,
|
||||
protocol: keyof typeof OWNER_PRIVATE_AUTH_FIELDS,
|
||||
): boolean {
|
||||
return OWNER_PRIVATE_AUTH_FIELDS[protocol].some((field) =>
|
||||
Object.prototype.hasOwnProperty.call(hostData, field),
|
||||
@@ -193,34 +184,41 @@ export type NormalizedImportedHost = Record<string, unknown> & {
|
||||
socks5ProxyChain?: unknown;
|
||||
portKnockSequence?: unknown;
|
||||
overrideCredentialUsername?: unknown;
|
||||
domain?: unknown;
|
||||
enableSsh: boolean;
|
||||
};
|
||||
|
||||
function legacyPrefix(protocolId: string): string {
|
||||
return protocolId.replace(/-([a-z0-9])/g, (_, c: string) => c.toUpperCase());
|
||||
}
|
||||
|
||||
function legacyKey(protocolId: string): string {
|
||||
const prefix = legacyPrefix(protocolId);
|
||||
return prefix.charAt(0).toUpperCase() + prefix.slice(1);
|
||||
}
|
||||
|
||||
export function normalizeImportedHost(
|
||||
hostData: Record<string, unknown>,
|
||||
): NormalizedImportedHost {
|
||||
const credentialAlias =
|
||||
asString(hostData.credentialAlias) || asString(hostData.credentialName);
|
||||
// A row with no connectionType names its protocol the way a 2.8 export
|
||||
// did: an "enable<Protocol>" flag and a "<protocol>Port".
|
||||
const flagged = listHostProtocols().find((protocol) =>
|
||||
asBoolean(hostData[`enable${legacyKey(protocol.id)}`]),
|
||||
);
|
||||
const connectionType =
|
||||
asString(hostData.connectionType) ||
|
||||
(asBoolean(hostData.enableRdp)
|
||||
? "rdp"
|
||||
: asBoolean(hostData.enableVnc)
|
||||
? "vnc"
|
||||
: asBoolean(hostData.enableTelnet)
|
||||
? "telnet"
|
||||
: "ssh");
|
||||
asString(hostData.connectionType) || flagged?.id || "ssh";
|
||||
const protocol = listHostProtocols().find(
|
||||
(entry) => entry.id === connectionType,
|
||||
);
|
||||
|
||||
const port =
|
||||
asPort(hostData.port) ||
|
||||
(connectionType === "rdp"
|
||||
? asPort(hostData.rdpPort) || 3389
|
||||
: connectionType === "vnc"
|
||||
? asPort(hostData.vncPort) || 5900
|
||||
: connectionType === "telnet"
|
||||
? asPort(hostData.telnetPort) || 23
|
||||
: asPort(hostData.sshPort) || 22);
|
||||
(protocol
|
||||
? asPort(hostData[`${legacyPrefix(protocol.id)}Port`]) ||
|
||||
protocol.defaultPort ||
|
||||
22
|
||||
: asPort(hostData.sshPort) || 22);
|
||||
|
||||
return {
|
||||
...hostData,
|
||||
@@ -260,9 +258,6 @@ const SENSITIVE_FIELDS = [
|
||||
"password",
|
||||
"sudoPassword",
|
||||
"socks5Password",
|
||||
"rdpPassword",
|
||||
"vncPassword",
|
||||
"telnetPassword",
|
||||
"autostartPassword",
|
||||
];
|
||||
|
||||
@@ -282,9 +277,6 @@ export function stripSensitiveFields(
|
||||
// 2.8 editors kept the sudo password inside terminal_config.
|
||||
result.hasSudoPassword =
|
||||
!!host.sudoPassword || !!terminalConfigForSudo?.sudoPassword;
|
||||
result.hasRdpPassword = !!host.rdpPassword;
|
||||
result.hasVncPassword = !!host.vncPassword;
|
||||
result.hasTelnetPassword = !!host.telnetPassword;
|
||||
for (const field of SENSITIVE_FIELDS) {
|
||||
delete result[field];
|
||||
}
|
||||
@@ -326,7 +318,7 @@ const CONNECT_LEVEL_FIELDS = new Set([
|
||||
"statusCheckInterval",
|
||||
"enableSsh",
|
||||
"sshPort",
|
||||
"rdpAuthType",
|
||||
"protocolAuth",
|
||||
"jumpHosts",
|
||||
"createdAt",
|
||||
"updatedAt",
|
||||
@@ -368,6 +360,12 @@ export function sanitizeHostForRecipient(
|
||||
!Array.isArray(authOverrides.ssh)
|
||||
? (authOverrides.ssh as Record<string, unknown>)
|
||||
: undefined;
|
||||
if (stripped.protocolAuth !== undefined) {
|
||||
stripped.protocolAuth = sanitizeProtocolAuthForRecipient(
|
||||
stripped.protocolAuth,
|
||||
permissionLevel,
|
||||
);
|
||||
}
|
||||
if (!sshOverride?.credentialId) {
|
||||
stripped.hasPassword = false;
|
||||
stripped.hasKey = false;
|
||||
@@ -468,10 +466,6 @@ export function transformHostResponse(
|
||||
shareSshAuth: !!host.shareSshAuth,
|
||||
enableSsh: !!host.enableSsh,
|
||||
sshPort: host.sshPort ?? host.port ?? 22,
|
||||
rdpUser: host.rdpUser || undefined,
|
||||
rdpDomain: host.rdpDomain || undefined,
|
||||
vncUser: host.vncUser || undefined,
|
||||
telnetUser: host.telnetUser || undefined,
|
||||
jumpHosts: host.jumpHosts ? JSON.parse(host.jumpHosts as string) : [],
|
||||
// Moved into a plugin's host settings; its hostPayloadLegacy puts it
|
||||
// back for 2.8 clients.
|
||||
@@ -490,6 +484,5 @@ export function transformHostResponse(
|
||||
portKnockSequence: host.portKnockSequence
|
||||
? JSON.parse(host.portKnockSequence as string)
|
||||
: [],
|
||||
domain: host.domain || undefined,
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user