mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-08-29 18:31:33 +00:00
fix: preserve omitted host protocol settings (#1350)
This commit is contained in:
@@ -14,6 +14,25 @@ export function isOptionalBoolean(
|
|||||||
return value === undefined || typeof value === "boolean";
|
return value === undefined || typeof value === "boolean";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PROTOCOL_ENABLE_FIELDS = [
|
||||||
|
"enableSsh",
|
||||||
|
"enableRdp",
|
||||||
|
"enableVnc",
|
||||||
|
"enableTelnet",
|
||||||
|
] as const;
|
||||||
|
|
||||||
|
export function normalizeProtocolEnableFields(
|
||||||
|
values: Record<string, unknown>,
|
||||||
|
): Partial<Record<(typeof PROTOCOL_ENABLE_FIELDS)[number], 0 | 1>> {
|
||||||
|
return Object.fromEntries(
|
||||||
|
PROTOCOL_ENABLE_FIELDS.flatMap((field) =>
|
||||||
|
typeof values[field] === "boolean"
|
||||||
|
? [[field, values[field] ? 1 : 0]]
|
||||||
|
: [],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export const OWNER_PRIVATE_AUTH_FIELDS = {
|
export const OWNER_PRIVATE_AUTH_FIELDS = {
|
||||||
ssh: [
|
ssh: [
|
||||||
"authType",
|
"authType",
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ import {
|
|||||||
isNonEmptyString,
|
isNonEmptyString,
|
||||||
isOptionalBoolean,
|
isOptionalBoolean,
|
||||||
isValidPort,
|
isValidPort,
|
||||||
|
normalizeProtocolEnableFields,
|
||||||
OWNER_PRIVATE_AUTH_FIELDS,
|
OWNER_PRIVATE_AUTH_FIELDS,
|
||||||
OWNER_PRIVATE_TERMINAL_CONFIG_FIELDS,
|
OWNER_PRIVATE_TERMINAL_CONFIG_FIELDS,
|
||||||
sanitizeHostForRecipient,
|
sanitizeHostForRecipient,
|
||||||
@@ -267,7 +268,8 @@ router.post(
|
|||||||
!isNonEmptyString(userId) ||
|
!isNonEmptyString(userId) ||
|
||||||
!isNonEmptyString(ip) ||
|
!isNonEmptyString(ip) ||
|
||||||
!isValidPort(port) ||
|
!isValidPort(port) ||
|
||||||
!isOptionalBoolean(shareSshAuth)
|
!isOptionalBoolean(shareSshAuth) ||
|
||||||
|
![enableSsh, enableRdp, enableVnc, enableTelnet].every(isOptionalBoolean)
|
||||||
) {
|
) {
|
||||||
sshLogger.warn("Invalid SSH data input validation failed", {
|
sshLogger.warn("Invalid SSH data input validation failed", {
|
||||||
operation: "host_create",
|
operation: "host_create",
|
||||||
@@ -398,10 +400,7 @@ router.post(
|
|||||||
portKnockSequence: portKnockSequence
|
portKnockSequence: portKnockSequence
|
||||||
? JSON.stringify(portKnockSequence)
|
? JSON.stringify(portKnockSequence)
|
||||||
: null,
|
: null,
|
||||||
enableSsh: enableSsh ? 1 : 0,
|
...normalizeProtocolEnableFields(hostData),
|
||||||
enableRdp: enableRdp ? 1 : 0,
|
|
||||||
enableVnc: enableVnc ? 1 : 0,
|
|
||||||
enableTelnet: enableTelnet ? 1 : 0,
|
|
||||||
sshPort: sshPort || port || 22,
|
sshPort: sshPort || port || 22,
|
||||||
rdpPort: rdpPort || 3389,
|
rdpPort: rdpPort || 3389,
|
||||||
vncPort: vncPort || 5900,
|
vncPort: vncPort || 5900,
|
||||||
@@ -971,6 +970,9 @@ router.put(
|
|||||||
!isNonEmptyString(ip) ||
|
!isNonEmptyString(ip) ||
|
||||||
!isValidPort(port) ||
|
!isValidPort(port) ||
|
||||||
!isOptionalBoolean(shareSshAuth) ||
|
!isOptionalBoolean(shareSshAuth) ||
|
||||||
|
![enableSsh, enableRdp, enableVnc, enableTelnet].every(
|
||||||
|
isOptionalBoolean,
|
||||||
|
) ||
|
||||||
!hostId
|
!hostId
|
||||||
) {
|
) {
|
||||||
sshLogger.warn("Invalid SSH data input validation failed for update", {
|
sshLogger.warn("Invalid SSH data input validation failed for update", {
|
||||||
@@ -1102,10 +1104,7 @@ router.put(
|
|||||||
portKnockSequence: portKnockSequence
|
portKnockSequence: portKnockSequence
|
||||||
? JSON.stringify(portKnockSequence)
|
? JSON.stringify(portKnockSequence)
|
||||||
: null,
|
: null,
|
||||||
enableSsh: enableSsh ? 1 : 0,
|
...normalizeProtocolEnableFields(hostData),
|
||||||
enableRdp: enableRdp ? 1 : 0,
|
|
||||||
enableVnc: enableVnc ? 1 : 0,
|
|
||||||
enableTelnet: enableTelnet ? 1 : 0,
|
|
||||||
sshPort: sshPort || port || 22,
|
sshPort: sshPort || port || 22,
|
||||||
rdpPort: rdpPort || 3389,
|
rdpPort: rdpPort || 3389,
|
||||||
vncPort: vncPort || 5900,
|
vncPort: vncPort || 5900,
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {
|
|||||||
isOptionalBoolean,
|
isOptionalBoolean,
|
||||||
isValidPort,
|
isValidPort,
|
||||||
normalizeImportedHost,
|
normalizeImportedHost,
|
||||||
|
normalizeProtocolEnableFields,
|
||||||
renameFolderPath,
|
renameFolderPath,
|
||||||
sanitizeHostForRecipient,
|
sanitizeHostForRecipient,
|
||||||
stripSensitiveFields,
|
stripSensitiveFields,
|
||||||
@@ -80,6 +81,23 @@ describe("isOptionalBoolean", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("normalizeProtocolEnableFields", () => {
|
||||||
|
it("omits unspecified protocol fields so database defaults are preserved", () => {
|
||||||
|
expect(normalizeProtocolEnableFields({ name: "server" })).toEqual({});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("converts explicitly provided protocol booleans to database integers", () => {
|
||||||
|
expect(
|
||||||
|
normalizeProtocolEnableFields({
|
||||||
|
enableSsh: true,
|
||||||
|
enableRdp: false,
|
||||||
|
enableVnc: undefined,
|
||||||
|
enableTelnet: true,
|
||||||
|
}),
|
||||||
|
).toEqual({ enableSsh: 1, enableRdp: 0, enableTelnet: 1 });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("renameFolderPath", () => {
|
describe("renameFolderPath", () => {
|
||||||
it("renames an exact folder match", () => {
|
it("renames an exact folder match", () => {
|
||||||
expect(renameFolderPath("Production", "Production", "Prod")).toBe("Prod");
|
expect(renameFolderPath("Production", "Production", "Prod")).toBe("Prod");
|
||||||
|
|||||||
Reference in New Issue
Block a user