v1.7.2 #364

Merged
LukeGus merged 8 commits from dev-1.7.2 into main 2025-10-06 15:11:26 +00:00
5 changed files with 40 additions and 38 deletions
Showing only changes of commit 85fec49bd5 - Show all commits
+4 -4
View File
@@ -46,7 +46,7 @@ export const sshData = sqliteTable("ssh_data", {
password: text("password"), password: text("password"),
key: text("key", { length: 8192 }), key: text("key", { length: 8192 }),
keyPassword: text("key_password"), key_password: text("key_password"),
keyType: text("key_type"), keyType: text("key_type"),
gemini-code-assist[bot] commented 2025-10-06 15:13:58 +00:00 (Migrated from github.com)
Review

medium

I see you're changing some field names from camelCase to snake_case (e.g., keyPassword to key_password), which is great for consistency with typical SQL naming conventions. However, this change isn't applied consistently across the schema. For example, in the sshData table, fields like userId, authType, credentialId, autostartPassword, and keyType remain in camelCase. The sshCredentials table also has a mix of conventions (keyType, detectedKeyType, usageCount).

This mix of naming conventions can be confusing and lead to bugs. It would be best to choose one convention (preferably snake_case for database schemas) and apply it to all fields for better maintainability.

![medium](https://www.gstatic.com/codereviewagent/medium-priority.svg) I see you're changing some field names from camelCase to snake_case (e.g., `keyPassword` to `key_password`), which is great for consistency with typical SQL naming conventions. However, this change isn't applied consistently across the schema. For example, in the `sshData` table, fields like `userId`, `authType`, `credentialId`, `autostartPassword`, and `keyType` remain in camelCase. The `sshCredentials` table also has a mix of conventions (`keyType`, `detectedKeyType`, `usageCount`). This mix of naming conventions can be confusing and lead to bugs. It would be best to choose one convention (preferably snake_case for database schemas) and apply it to all fields for better maintainability.
autostartPassword: text("autostart_password"), autostartPassword: text("autostart_password"),
@@ -142,9 +142,9 @@ export const sshCredentials = sqliteTable("ssh_credentials", {
username: text("username").notNull(), username: text("username").notNull(),
password: text("password"), password: text("password"),
key: text("key", { length: 16384 }), key: text("key", { length: 16384 }),
privateKey: text("private_key", { length: 16384 }), private_key: text("private_key", { length: 16384 }),
publicKey: text("public_key", { length: 4096 }), public_key: text("public_key", { length: 4096 }),
keyPassword: text("key_password"), key_password: text("key_password"),
keyType: text("key_type"), keyType: text("key_type"),
detectedKeyType: text("detected_key_type"), detectedKeyType: text("detected_key_type"),
usageCount: integer("usage_count").notNull().default(0), usageCount: integer("usage_count").notNull().default(0),
+8 -8
View File
@@ -174,9 +174,9 @@ router.post(
username: username.trim(), username: username.trim(),
password: plainPassword, password: plainPassword,
key: plainKey, key: plainKey,
privateKey: keyInfo?.privateKey || plainKey, private_key: keyInfo?.privateKey || plainKey,
publicKey: keyInfo?.publicKey || null, public_key: keyInfo?.publicKey || null,
keyPassword: plainKeyPassword, key_password: plainKeyPassword,
keyType: keyType || null, keyType: keyType || null,
detectedKeyType: keyInfo?.keyType || null, detectedKeyType: keyInfo?.keyType || null,
usageCount: 0, usageCount: 0,
@@ -424,13 +424,13 @@ router.put(
error: `Invalid SSH key: ${keyInfo.error}`, error: `Invalid SSH key: ${keyInfo.error}`,
}); });
} }
updateFields.privateKey = keyInfo.privateKey; updateFields.private_key = keyInfo.privateKey;
updateFields.publicKey = keyInfo.publicKey; updateFields.public_key = keyInfo.publicKey;
updateFields.detectedKeyType = keyInfo.keyType; updateFields.detectedKeyType = keyInfo.keyType;
} }
} }
if (updateData.keyPassword !== undefined) { if (updateData.keyPassword !== undefined) {
updateFields.keyPassword = updateData.keyPassword || null; updateFields.key_password = updateData.keyPassword || null;
} }
if (Object.keys(updateFields).length === 0) { if (Object.keys(updateFields).length === 0) {
@@ -537,7 +537,7 @@ router.delete(
credentialId: null, credentialId: null,
password: null, password: null,
key: null, key: null,
keyPassword: null, key_password: null,
authType: "password", authType: "password",
}) })
.where( .where(
@@ -633,7 +633,7 @@ router.post(
authType: credential.auth_type || credential.authType, authType: credential.auth_type || credential.authType,
password: null, password: null,
key: null, key: null,
keyPassword: null, key_password: null,
keyType: null, keyType: null,
updatedAt: new Date().toISOString(), updatedAt: new Date().toISOString(),
}) })
+17 -17
View File
@@ -91,7 +91,7 @@ router.get("/db/host/internal", async (req: Request, res: Response) => {
username: host.username, username: host.username,
password: host.autostartPassword, password: host.autostartPassword,
key: host.autostartKey, key: host.autostartKey,
keyPassword: host.autostartKeyPassword, key_password: host.autostartKeyPassword,
autostartPassword: host.autostartPassword, autostartPassword: host.autostartPassword,
autostartKey: host.autostartKey, autostartKey: host.autostartKey,
autostartKeyPassword: host.autostartKeyPassword, autostartKeyPassword: host.autostartKeyPassword,
@@ -151,7 +151,7 @@ router.get("/db/host/internal/all", async (req: Request, res: Response) => {
username: host.username, username: host.username,
password: host.autostartPassword || host.password, password: host.autostartPassword || host.password,
key: host.autostartKey || host.key, key: host.autostartKey || host.key,
keyPassword: host.autostartKeyPassword || host.keyPassword, key_password: host.autostartKeyPassword || host.key_password,
autostartPassword: host.autostartPassword, autostartPassword: host.autostartPassword,
autostartKey: host.autostartKey, autostartKey: host.autostartKey,
autostartKeyPassword: host.autostartKeyPassword, autostartKeyPassword: host.autostartKeyPassword,
@@ -226,7 +226,7 @@ router.post(
authType, authType,
credentialId, credentialId,
key, key,
keyPassword, key_password,
keyType, keyType,
pin, pin,
enableTerminal, enableTerminal,
@@ -274,17 +274,17 @@ router.post(
if (effectiveAuthType === "password") { if (effectiveAuthType === "password") {
sshDataObj.password = password || null; sshDataObj.password = password || null;
sshDataObj.key = null; sshDataObj.key = null;
sshDataObj.keyPassword = null; sshDataObj.key_password = null;
sshDataObj.keyType = null; sshDataObj.keyType = null;
} else if (effectiveAuthType === "key") { } else if (effectiveAuthType === "key") {
sshDataObj.key = key || null; sshDataObj.key = key || null;
sshDataObj.keyPassword = keyPassword || null; sshDataObj.key_password = key_password || null;
sshDataObj.keyType = keyType; sshDataObj.keyType = keyType;
sshDataObj.password = null; sshDataObj.password = null;
} else { } else {
sshDataObj.password = null; sshDataObj.password = null;
sshDataObj.key = null; sshDataObj.key = null;
sshDataObj.keyPassword = null; sshDataObj.key_password = null;
sshDataObj.keyType = null; sshDataObj.keyType = null;
} }
@@ -407,7 +407,7 @@ router.put(
authType, authType,
credentialId, credentialId,
key, key,
keyPassword, key_password,
keyType, keyType,
pin, pin,
enableTerminal, enableTerminal,
@@ -458,14 +458,14 @@ router.put(
sshDataObj.password = password; sshDataObj.password = password;
} }
sshDataObj.key = null; sshDataObj.key = null;
sshDataObj.keyPassword = null; sshDataObj.key_password = null;
sshDataObj.keyType = null; sshDataObj.keyType = null;
} else if (effectiveAuthType === "key") { } else if (effectiveAuthType === "key") {
if (key) { if (key) {
sshDataObj.key = key; sshDataObj.key = key;
} }
if (keyPassword !== undefined) { if (key_password !== undefined) {
sshDataObj.keyPassword = keyPassword || null; sshDataObj.key_password = key_password || null;
} }
if (keyType) { if (keyType) {
sshDataObj.keyType = keyType; sshDataObj.keyType = keyType;
@@ -474,7 +474,7 @@ router.put(
} else { } else {
sshDataObj.password = null; sshDataObj.password = null;
sshDataObj.key = null; sshDataObj.key = null;
sshDataObj.keyPassword = null; sshDataObj.key_password = null;
sshDataObj.keyType = null; sshDataObj.keyType = null;
} }
@@ -711,7 +711,7 @@ router.get(
authType: resolvedHost.authType, authType: resolvedHost.authType,
password: resolvedHost.password || null, password: resolvedHost.password || null,
key: resolvedHost.key || null, key: resolvedHost.key || null,
keyPassword: resolvedHost.keyPassword || null, key_password: resolvedHost.key_password || null,
keyType: resolvedHost.keyType || null, keyType: resolvedHost.keyType || null,
folder: resolvedHost.folder, folder: resolvedHost.folder,
tags: tags:
@@ -1234,7 +1234,7 @@ async function resolveHostCredentials(host: any): Promise<any> {
authType: credential.auth_type || credential.authType, authType: credential.auth_type || credential.authType,
password: credential.password, password: credential.password,
key: credential.key, key: credential.key,
keyPassword: credential.key_password || credential.keyPassword, key_password: credential.key_password || credential.key_password,
keyType: credential.key_type || credential.keyType, keyType: credential.key_type || credential.keyType,
}; };
} }
1
@@ -1404,8 +1404,8 @@ router.post(
credentialId: credentialId:
hostData.authType === "credential" ? hostData.credentialId : null, hostData.authType === "credential" ? hostData.credentialId : null,
key: hostData.authType === "key" ? hostData.key : null, key: hostData.authType === "key" ? hostData.key : null,
keyPassword: key_password:
hostData.authType === "key" ? hostData.keyPassword : null, hostData.authType === "key" ? hostData.key_password : null,
keyType: keyType:
hostData.authType === "key" ? hostData.keyType || "auto" : null, hostData.authType === "key" ? hostData.keyType || "auto" : null,
pin: hostData.pin || false, pin: hostData.pin || false,
@@ -1540,7 +1540,7 @@ router.post(
...tunnel, ...tunnel,
endpointPassword: decryptedEndpoint.password || null, endpointPassword: decryptedEndpoint.password || null,
endpointKey: decryptedEndpoint.key || null, endpointKey: decryptedEndpoint.key || null,
endpointKeyPassword: decryptedEndpoint.keyPassword || null, endpointKeyPassword: decryptedEndpoint.key_password || null,
endpointAuthType: endpointHost.authType, endpointAuthType: endpointHost.authType,
}; };
} }
@@ -1563,7 +1563,7 @@ router.post(
.set({ .set({
autostartPassword: decryptedConfig.password || null, autostartPassword: decryptedConfig.password || null,
autostartKey: decryptedConfig.key || null, autostartKey: decryptedConfig.key || null,
autostartKeyPassword: decryptedConfig.keyPassword || null, autostartKeyPassword: decryptedConfig.key_password || null,
tunnelConnections: updatedTunnelConnections, tunnelConnections: updatedTunnelConnections,
}) })
.where(eq(sshData.id, sshConfigId)); .where(eq(sshData.id, sshConfigId));
+1 -9
View File
@@ -17,26 +17,18 @@ class FieldCrypto {
private static readonly ENCRYPTED_FIELDS = { private static readonly ENCRYPTED_FIELDS = {
users: new Set([ users: new Set([
"password_hash", "password_hash",
"passwordHash",
"client_secret", "client_secret",
"clientSecret",
"totp_secret", "totp_secret",
"totpSecret",
"totp_backup_codes", "totp_backup_codes",
"totpBackupCodes",
"oidc_identifier", "oidc_identifier",
"oidcIdentifier",
]), ]),
ssh_data: new Set(["password", "key", "key_password", "keyPassword"]), ssh_data: new Set(["password", "key", "key_password"]),
ssh_credentials: new Set([ ssh_credentials: new Set([
"password", "password",
"private_key", "private_key",
"privateKey",
"key_password", "key_password",
"keyPassword",
"key", "key",
"public_key", "public_key",
"publicKey",
]), ]),
}; };
@@ -6,10 +6,20 @@ export class LazyFieldEncryption {
key_password: "keyPassword", key_password: "keyPassword",
private_key: "privateKey", private_key: "privateKey",
public_key: "publicKey", public_key: "publicKey",
password_hash: "passwordHash",
client_secret: "clientSecret",
totp_secret: "totpSecret",
totp_backup_codes: "totpBackupCodes",
oidc_identifier: "oidcIdentifier",
keyPassword: "key_password", keyPassword: "key_password",
privateKey: "private_key", privateKey: "private_key",
publicKey: "public_key", publicKey: "public_key",
passwordHash: "password_hash",
clientSecret: "client_secret",
totpSecret: "totp_secret",
totpBackupCodes: "totp_backup_codes",
oidcIdentifier: "oidc_identifier",
}; };
static isPlaintextField(value: string): boolean { static isPlaintextField(value: string): boolean {