feat: store rdp, vnc and telnet logins in a generic per-protocol table

This commit is contained in:
LukeGus committed 2026-09-29 12:33:09 -05:00
1 parent e0c30a4e6f
commit bba06f7ff6
107 files changed
+18750 -1224

No files matched your search

+42 -20
View File
@@ -202,25 +202,6 @@ export const hosts = sqliteTable(
sshPort: integer("ssh_port").default(22),
rdpCredentialId: integer("rdp_credential_id").references(() => sshCredentials.id, { onDelete: "set null" }),
rdpUser: text("rdp_user"),
rdpPassword: text("rdp_password"),
rdpDomain: text("rdp_domain"),
vncCredentialId: integer("vnc_credential_id").references(() => sshCredentials.id, { onDelete: "set null" }),
vncPassword: text("vnc_password"),
vncUser: text("vnc_user"),
telnetUser: text("telnet_user"),
telnetPassword: text("telnet_password"),
telnetCredentialId: integer("telnet_credential_id").references(() => sshCredentials.id, { onDelete: "set null" }),
rdpAuthType: text("rdp_auth_type"),
vncAuthType: text("vnc_auth_type"),
telnetAuthType: text("telnet_auth_type"),
domain: text("domain"),
useSocks5: integer("use_socks5", { mode: "boolean" }),
socks5Host: text("socks5_host"),
socks5Port: integer("socks5_port"),
@@ -231,7 +212,7 @@ export const hosts = sqliteTable(
// null = use the desktop app's global default; "local" | "remote" pins
// this specific host's SSH/Docker-console/Serial connections to originate
// from the embedded local backend or a connected remote sync server.
// Ignored for rdp/vnc/telnet, which always require the remote server.
// Ignored for plugin protocols, which always need the remote server.
connectionOrigin: text("connection_origin"),
portKnockSequence: text("port_knock_sequence"),
@@ -338,6 +319,45 @@ export const sshCredentialUsage = sqliteTable(
],
);
// A host's login for a protocol a plugin declares (contributes.protocols),
// owned and encrypted like the host itself. `fields` holds the protocol's
// non-secret declared fields as JSON, `secret_fields` its secret ones.
export const hostProtocolAuth = sqliteTable(
"host_protocol_auth",
{
id: integer("id").primaryKey({ autoIncrement: true }),
hostId: integer("host_id")
.notNull()
.references(() => hosts.id, { onDelete: "cascade" }),
userId: text("user_id")
.notNull()
.references(() => users.id, { onDelete: "cascade" }),
protocol: text("protocol").notNull(),
authType: text("auth_type").notNull().default("direct"),
credentialId: integer("credential_id").references(() => sshCredentials.id, {
onDelete: "set null",
}),
username: text("username"),
password: text("password"),
fields: text("fields"),
secretFields: text("secret_fields"),
createdAt: text("created_at")
.notNull()
.default(sql`CURRENT_TIMESTAMP`),
updatedAt: text("updated_at")
.notNull()
.default(sql`CURRENT_TIMESTAMP`),
},
(table) => [
uniqueIndex("idx_host_protocol_auth_host_protocol").on(
table.hostId,
table.protocol,
),
index("idx_host_protocol_auth_user").on(table.userId),
index("idx_host_protocol_auth_credential").on(table.credentialId),
],
);
export const sshFolders = sqliteTable(
"ssh_folders",
{
@@ -485,6 +505,8 @@ export const sharedHostSecrets = sqliteTable(
encryptedKeyPassword: text("encrypted_key_password"),
encryptedKeyType: text("encrypted_key_type"),
encryptedDomain: text("encrypted_domain"),
// A plugin protocol's declared credential fields, JSON, encrypted.
encryptedFields: text("encrypted_fields"),
createdAt: text("created_at")
.notNull()