mirror of
https://github.com/fosrl/pangolin.git
synced 2026-09-01 08:51:35 +02:00
perf: add secondary FK indexes to core OSS schemas
Add 13 secondary indexes across 10 tables in the SQLite schema and 5 missing indexes to the PostgreSQL schema. All list endpoints (listSites, listResources, listClients, listRoles, listTargets, listUserOrgs) filter and join on these FK columns. In the SQLite schema, no secondary indexes existed at all on these foreign keys, forcing full sequential scans on every paginated request and session lookup. SQLite changes (13 new indexes): - sites.orgId - resources.orgId - targets.resourceId, targets.siteId - newt.siteId - clients.orgId, clients.userId - labels.orgId - olms.userId - session.userId - userOrgs.userId, userOrgs.orgId - roles.orgId PG changes (5 new indexes, rest already present): - labels.orgId - session.userId - userOrgs.userId, userOrgs.orgId - roles.orgId - olms.userId
This commit is contained in:
@@ -262,16 +262,20 @@ export const resourceAiModels = pgTable(
|
|||||||
(t) => [primaryKey({ columns: [t.resourceId, t.modelId] })]
|
(t) => [primaryKey({ columns: [t.resourceId, t.modelId] })]
|
||||||
);
|
);
|
||||||
|
|
||||||
export const labels = pgTable("labels", {
|
export const labels = pgTable(
|
||||||
labelId: serial("labelId").primaryKey(),
|
"labels",
|
||||||
name: varchar("name").notNull(),
|
{
|
||||||
color: varchar("color").notNull(),
|
labelId: serial("labelId").primaryKey(),
|
||||||
orgId: varchar("orgId")
|
name: varchar("name").notNull(),
|
||||||
.references(() => orgs.orgId, {
|
color: varchar("color").notNull(),
|
||||||
onDelete: "cascade"
|
orgId: varchar("orgId")
|
||||||
})
|
.references(() => orgs.orgId, {
|
||||||
.notNull()
|
onDelete: "cascade"
|
||||||
});
|
})
|
||||||
|
.notNull()
|
||||||
|
},
|
||||||
|
(t) => [index("idx_labels_orgid").on(t.orgId)]
|
||||||
|
);
|
||||||
|
|
||||||
export const launcherViews = pgTable("launcherViews", {
|
export const launcherViews = pgTable("launcherViews", {
|
||||||
viewId: serial("viewId").primaryKey(),
|
viewId: serial("viewId").primaryKey(),
|
||||||
@@ -693,15 +697,19 @@ export const twoFactorBackupCodes = pgTable("twoFactorBackupCodes", {
|
|||||||
codeHash: varchar("codeHash").notNull()
|
codeHash: varchar("codeHash").notNull()
|
||||||
});
|
});
|
||||||
|
|
||||||
export const sessions = pgTable("session", {
|
export const sessions = pgTable(
|
||||||
sessionId: varchar("id").primaryKey(),
|
"session",
|
||||||
userId: varchar("userId")
|
{
|
||||||
.notNull()
|
sessionId: varchar("id").primaryKey(),
|
||||||
.references(() => users.userId, { onDelete: "cascade" }),
|
userId: varchar("userId")
|
||||||
expiresAt: bigint("expiresAt", { mode: "number" }).notNull(),
|
.notNull()
|
||||||
issuedAt: bigint("issuedAt", { mode: "number" }),
|
.references(() => users.userId, { onDelete: "cascade" }),
|
||||||
deviceAuthUsed: boolean("deviceAuthUsed").notNull().default(false)
|
expiresAt: bigint("expiresAt", { mode: "number" }).notNull(),
|
||||||
});
|
issuedAt: bigint("issuedAt", { mode: "number" }),
|
||||||
|
deviceAuthUsed: boolean("deviceAuthUsed").notNull().default(false)
|
||||||
|
},
|
||||||
|
(t) => [index("idx_sessions_userid").on(t.userId)]
|
||||||
|
);
|
||||||
|
|
||||||
export const newtSessions = pgTable("newtSession", {
|
export const newtSessions = pgTable("newtSession", {
|
||||||
sessionId: varchar("id").primaryKey(),
|
sessionId: varchar("id").primaryKey(),
|
||||||
@@ -711,19 +719,26 @@ export const newtSessions = pgTable("newtSession", {
|
|||||||
expiresAt: bigint("expiresAt", { mode: "number" }).notNull()
|
expiresAt: bigint("expiresAt", { mode: "number" }).notNull()
|
||||||
});
|
});
|
||||||
|
|
||||||
export const userOrgs = pgTable("userOrgs", {
|
export const userOrgs = pgTable(
|
||||||
userId: varchar("userId")
|
"userOrgs",
|
||||||
.notNull()
|
{
|
||||||
.references(() => users.userId, { onDelete: "cascade" }),
|
userId: varchar("userId")
|
||||||
orgId: varchar("orgId")
|
.notNull()
|
||||||
.references(() => orgs.orgId, {
|
.references(() => users.userId, { onDelete: "cascade" }),
|
||||||
onDelete: "cascade"
|
orgId: varchar("orgId")
|
||||||
})
|
.references(() => orgs.orgId, {
|
||||||
.notNull(),
|
onDelete: "cascade"
|
||||||
isOwner: boolean("isOwner").notNull().default(false),
|
})
|
||||||
autoProvisioned: boolean("autoProvisioned").default(false),
|
.notNull(),
|
||||||
pamUsername: varchar("pamUsername") // cleaned username for ssh and such
|
isOwner: boolean("isOwner").notNull().default(false),
|
||||||
});
|
autoProvisioned: boolean("autoProvisioned").default(false),
|
||||||
|
pamUsername: varchar("pamUsername") // cleaned username for ssh and such
|
||||||
|
},
|
||||||
|
(t) => [
|
||||||
|
index("idx_userOrgs_userid").on(t.userId),
|
||||||
|
index("idx_userOrgs_orgid").on(t.orgId)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
export const emailVerificationCodes = pgTable("emailVerificationCodes", {
|
export const emailVerificationCodes = pgTable("emailVerificationCodes", {
|
||||||
codeId: serial("id").primaryKey(),
|
codeId: serial("id").primaryKey(),
|
||||||
@@ -751,22 +766,26 @@ export const actions = pgTable("actions", {
|
|||||||
description: varchar("description")
|
description: varchar("description")
|
||||||
});
|
});
|
||||||
|
|
||||||
export const roles = pgTable("roles", {
|
export const roles = pgTable(
|
||||||
roleId: serial("roleId").primaryKey(),
|
"roles",
|
||||||
orgId: varchar("orgId")
|
{
|
||||||
.references(() => orgs.orgId, {
|
roleId: serial("roleId").primaryKey(),
|
||||||
onDelete: "cascade"
|
orgId: varchar("orgId")
|
||||||
})
|
.references(() => orgs.orgId, {
|
||||||
.notNull(),
|
onDelete: "cascade"
|
||||||
isAdmin: boolean("isAdmin"),
|
})
|
||||||
name: varchar("name").notNull(),
|
.notNull(),
|
||||||
description: varchar("description"),
|
isAdmin: boolean("isAdmin"),
|
||||||
requireDeviceApproval: boolean("requireDeviceApproval").default(false),
|
name: varchar("name").notNull(),
|
||||||
sshSudoMode: varchar("sshSudoMode", { length: 32 }).default("full"), // "none" | "full" | "commands"
|
description: varchar("description"),
|
||||||
sshSudoCommands: text("sshSudoCommands").default("[]"),
|
requireDeviceApproval: boolean("requireDeviceApproval").default(false),
|
||||||
sshCreateHomeDir: boolean("sshCreateHomeDir").default(true),
|
sshSudoMode: varchar("sshSudoMode", { length: 32 }).default("full"), // "none" | "full" | "commands"
|
||||||
sshUnixGroups: text("sshUnixGroups").default("[]")
|
sshSudoCommands: text("sshSudoCommands").default("[]"),
|
||||||
});
|
sshCreateHomeDir: boolean("sshCreateHomeDir").default(true),
|
||||||
|
sshUnixGroups: text("sshUnixGroups").default("[]")
|
||||||
|
},
|
||||||
|
(t) => [index("idx_roles_orgid").on(t.orgId)]
|
||||||
|
);
|
||||||
|
|
||||||
export const userOrgRoles = pgTable(
|
export const userOrgRoles = pgTable(
|
||||||
"userOrgRoles",
|
"userOrgRoles",
|
||||||
@@ -1409,7 +1428,10 @@ export const olms = pgTable(
|
|||||||
}),
|
}),
|
||||||
archived: boolean("archived").notNull().default(false)
|
archived: boolean("archived").notNull().default(false)
|
||||||
},
|
},
|
||||||
(t) => [index("idx_olms_clientid").on(t.clientId)]
|
(t) => [
|
||||||
|
index("idx_olms_clientid").on(t.clientId),
|
||||||
|
index("idx_olms_userid").on(t.userId)
|
||||||
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
export const currentFingerprint = pgTable("currentFingerprint", {
|
export const currentFingerprint = pgTable("currentFingerprint", {
|
||||||
|
|||||||
+336
-267
@@ -99,131 +99,147 @@ export const orgDomains = sqliteTable("orgDomains", {
|
|||||||
.references(() => domains.domainId, { onDelete: "cascade" })
|
.references(() => domains.domainId, { onDelete: "cascade" })
|
||||||
});
|
});
|
||||||
|
|
||||||
export const sites = sqliteTable("sites", {
|
export const sites = sqliteTable(
|
||||||
siteId: integer("siteId").primaryKey({ autoIncrement: true }),
|
"sites",
|
||||||
orgId: text("orgId")
|
{
|
||||||
.references(() => orgs.orgId, {
|
siteId: integer("siteId").primaryKey({ autoIncrement: true }),
|
||||||
onDelete: "cascade"
|
orgId: text("orgId")
|
||||||
})
|
.references(() => orgs.orgId, {
|
||||||
.notNull(),
|
onDelete: "cascade"
|
||||||
niceId: text("niceId").notNull(),
|
})
|
||||||
exitNodeId: integer("exitNode").references(() => exitNodes.exitNodeId, {
|
.notNull(),
|
||||||
onDelete: "set null"
|
niceId: text("niceId").notNull(),
|
||||||
}),
|
exitNodeId: integer("exitNode").references(() => exitNodes.exitNodeId, {
|
||||||
networkId: integer("networkId").references(() => networks.networkId, {
|
onDelete: "set null"
|
||||||
onDelete: "set null"
|
}),
|
||||||
}),
|
networkId: integer("networkId").references(() => networks.networkId, {
|
||||||
name: text("name").notNull(),
|
onDelete: "set null"
|
||||||
pubKey: text("pubKey"),
|
}),
|
||||||
exitNodeSubnet: text("exitNodeSubnet"),
|
name: text("name").notNull(),
|
||||||
megabytesIn: integer("bytesIn").default(0),
|
pubKey: text("pubKey"),
|
||||||
megabytesOut: integer("bytesOut").default(0),
|
exitNodeSubnet: text("exitNodeSubnet"),
|
||||||
lastBandwidthUpdate: text("lastBandwidthUpdate"),
|
megabytesIn: integer("bytesIn").default(0),
|
||||||
type: text("type").notNull(), // "newt" or "wireguard"
|
megabytesOut: integer("bytesOut").default(0),
|
||||||
online: integer("online", { mode: "boolean" }).notNull().default(false),
|
lastBandwidthUpdate: text("lastBandwidthUpdate"),
|
||||||
lastPing: integer("lastPing"),
|
type: text("type").notNull(), // "newt" or "wireguard"
|
||||||
|
online: integer("online", { mode: "boolean" }).notNull().default(false),
|
||||||
|
lastPing: integer("lastPing"),
|
||||||
|
|
||||||
// exit node stuff that is how to connect to the site when it has a wg server
|
// exit node stuff that is how to connect to the site when it has a wg server
|
||||||
address: text("address"), // this is the address of the wireguard interface in newt
|
address: text("address"), // this is the address of the wireguard interface in newt
|
||||||
endpoint: text("endpoint"), // this is how to reach gerbil externally - gets put into the wireguard config
|
endpoint: text("endpoint"), // this is how to reach gerbil externally - gets put into the wireguard config
|
||||||
localEndpoints: text("localEndpoints"), // JSON encoded list of string ips on the local machine to try to connect to
|
localEndpoints: text("localEndpoints"), // JSON encoded list of string ips on the local machine to try to connect to
|
||||||
publicKey: text("publicKey"), // TODO: Fix typo in publicKey
|
publicKey: text("publicKey"), // TODO: Fix typo in publicKey
|
||||||
lastHolePunch: integer("lastHolePunch"),
|
lastHolePunch: integer("lastHolePunch"),
|
||||||
listenPort: integer("listenPort"),
|
listenPort: integer("listenPort"),
|
||||||
dockerSocketEnabled: integer("dockerSocketEnabled", { mode: "boolean" })
|
dockerSocketEnabled: integer("dockerSocketEnabled", { mode: "boolean" })
|
||||||
.notNull()
|
.notNull()
|
||||||
.default(true),
|
.default(true),
|
||||||
autoUpdateEnabled: integer("autoUpdateEnabled", { mode: "boolean" })
|
autoUpdateEnabled: integer("autoUpdateEnabled", { mode: "boolean" })
|
||||||
.notNull()
|
.notNull()
|
||||||
.default(false),
|
.default(false),
|
||||||
autoUpdateOverrideOrg: integer("autoUpdateOverrideOrg", {
|
autoUpdateOverrideOrg: integer("autoUpdateOverrideOrg", {
|
||||||
mode: "boolean"
|
mode: "boolean"
|
||||||
})
|
|
||||||
.notNull()
|
|
||||||
.default(false),
|
|
||||||
status: text("status").$type<"pending" | "approved">().default("approved")
|
|
||||||
});
|
|
||||||
|
|
||||||
export const resources = sqliteTable("resources", {
|
|
||||||
resourceId: integer("resourceId").primaryKey({ autoIncrement: true }),
|
|
||||||
resourcePolicyId: integer("resourcePolicyId").references(
|
|
||||||
() => resourcePolicies.resourcePolicyId,
|
|
||||||
{ onDelete: "set null" }
|
|
||||||
),
|
|
||||||
defaultResourcePolicyId: integer("defaultResourcePolicyId").references(
|
|
||||||
() => resourcePolicies.resourcePolicyId,
|
|
||||||
{
|
|
||||||
onDelete: "restrict"
|
|
||||||
}
|
|
||||||
),
|
|
||||||
resourceGuid: text("resourceGuid", { length: 36 })
|
|
||||||
.unique()
|
|
||||||
.notNull()
|
|
||||||
.$defaultFn(() => randomUUID()),
|
|
||||||
orgId: text("orgId")
|
|
||||||
.references(() => orgs.orgId, {
|
|
||||||
onDelete: "cascade"
|
|
||||||
})
|
})
|
||||||
.notNull(),
|
.notNull()
|
||||||
niceId: text("niceId").notNull(),
|
.default(false),
|
||||||
name: text("name").notNull(),
|
status: text("status")
|
||||||
subdomain: text("subdomain"),
|
.$type<"pending" | "approved">()
|
||||||
fullDomain: text("fullDomain"),
|
.default("approved")
|
||||||
domainId: text("domainId").references(() => domains.domainId, {
|
},
|
||||||
onDelete: "set null"
|
(table) => [
|
||||||
}),
|
index("idx_sites_orgId").on(table.orgId)
|
||||||
ssl: integer("ssl", { mode: "boolean" }).notNull().default(false),
|
]
|
||||||
blockAccess: integer("blockAccess", { mode: "boolean" })
|
);
|
||||||
.notNull()
|
|
||||||
.default(false),
|
export const resources = sqliteTable(
|
||||||
proxyPort: integer("proxyPort"),
|
"resources",
|
||||||
sso: integer("sso", { mode: "boolean" }),
|
{
|
||||||
emailWhitelistEnabled: integer("emailWhitelistEnabled", {
|
resourceId: integer("resourceId").primaryKey({ autoIncrement: true }),
|
||||||
mode: "boolean"
|
resourcePolicyId: integer("resourcePolicyId").references(
|
||||||
}),
|
() => resourcePolicies.resourcePolicyId,
|
||||||
applyRules: integer("applyRules", { mode: "boolean" }),
|
{ onDelete: "set null" }
|
||||||
enabled: integer("enabled", { mode: "boolean" }).notNull().default(true),
|
),
|
||||||
stickySession: integer("stickySession", { mode: "boolean" })
|
defaultResourcePolicyId: integer("defaultResourcePolicyId").references(
|
||||||
.notNull()
|
() => resourcePolicies.resourcePolicyId,
|
||||||
.default(false),
|
{
|
||||||
tlsServerName: text("tlsServerName"),
|
onDelete: "restrict"
|
||||||
setHostHeader: text("setHostHeader"),
|
}
|
||||||
enableProxy: integer("enableProxy", { mode: "boolean" }).default(true),
|
),
|
||||||
skipToIdpId: integer("skipToIdpId").references(() => idp.idpId, {
|
resourceGuid: text("resourceGuid", { length: 36 })
|
||||||
onDelete: "set null"
|
.unique()
|
||||||
}),
|
.notNull()
|
||||||
headers: text("headers"), // comma-separated list of headers to add to the request
|
.$defaultFn(() => randomUUID()),
|
||||||
proxyProtocol: integer("proxyProtocol", { mode: "boolean" })
|
orgId: text("orgId")
|
||||||
.notNull()
|
.references(() => orgs.orgId, {
|
||||||
.default(false),
|
onDelete: "cascade"
|
||||||
proxyProtocolVersion: integer("proxyProtocolVersion").default(1),
|
})
|
||||||
maintenanceModeEnabled: integer("maintenanceModeEnabled", {
|
.notNull(),
|
||||||
mode: "boolean"
|
niceId: text("niceId").notNull(),
|
||||||
})
|
name: text("name").notNull(),
|
||||||
.notNull()
|
subdomain: text("subdomain"),
|
||||||
.default(false),
|
fullDomain: text("fullDomain"),
|
||||||
maintenanceModeType: text("maintenanceModeType", {
|
domainId: text("domainId").references(() => domains.domainId, {
|
||||||
enum: ["forced", "automatic"]
|
onDelete: "set null"
|
||||||
}).default("forced"), // "forced" = always show, "automatic" = only when down
|
}),
|
||||||
maintenanceTitle: text("maintenanceTitle"),
|
ssl: integer("ssl", { mode: "boolean" }).notNull().default(false),
|
||||||
maintenanceMessage: text("maintenanceMessage"),
|
blockAccess: integer("blockAccess", { mode: "boolean" })
|
||||||
maintenanceEstimatedTime: text("maintenanceEstimatedTime"),
|
.notNull()
|
||||||
postAuthPath: text("postAuthPath"),
|
.default(false),
|
||||||
health: text("health").default("unknown"), // "healthy", "unhealthy", "unknown"
|
proxyPort: integer("proxyPort"),
|
||||||
wildcard: integer("wildcard", { mode: "boolean" }).notNull().default(false),
|
sso: integer("sso", { mode: "boolean" }),
|
||||||
mode: text("mode")
|
emailWhitelistEnabled: integer("emailWhitelistEnabled", {
|
||||||
.default("http")
|
mode: "boolean"
|
||||||
.$type<"rdp" | "ssh" | "http" | "vnc" | "inference" | "tcp" | "udp">()
|
}),
|
||||||
.notNull(), // rdp, ssh, http, vnc, inference
|
applyRules: integer("applyRules", { mode: "boolean" }),
|
||||||
pamMode: text("pamMode")
|
enabled: integer("enabled", { mode: "boolean" }).notNull().default(true),
|
||||||
.$type<"passthrough" | "push">()
|
stickySession: integer("stickySession", { mode: "boolean" })
|
||||||
.default("passthrough"),
|
.notNull()
|
||||||
authDaemonMode: text("authDaemonMode")
|
.default(false),
|
||||||
.$type<"site" | "remote" | "native">()
|
tlsServerName: text("tlsServerName"),
|
||||||
.default("site"),
|
setHostHeader: text("setHostHeader"),
|
||||||
authDaemonPort: integer("authDaemonPort").default(22123),
|
enableProxy: integer("enableProxy", { mode: "boolean" }).default(true),
|
||||||
status: text("status").$type<"pending" | "approved">().default("approved")
|
skipToIdpId: integer("skipToIdpId").references(() => idp.idpId, {
|
||||||
});
|
onDelete: "set null"
|
||||||
|
}),
|
||||||
|
headers: text("headers"), // comma-separated list of headers to add to the request
|
||||||
|
proxyProtocol: integer("proxyProtocol", { mode: "boolean" })
|
||||||
|
.notNull()
|
||||||
|
.default(false),
|
||||||
|
proxyProtocolVersion: integer("proxyProtocolVersion").default(1),
|
||||||
|
maintenanceModeEnabled: integer("maintenanceModeEnabled", {
|
||||||
|
mode: "boolean"
|
||||||
|
})
|
||||||
|
.notNull()
|
||||||
|
.default(false),
|
||||||
|
maintenanceModeType: text("maintenanceModeType", {
|
||||||
|
enum: ["forced", "automatic"]
|
||||||
|
}).default("forced"), // "forced" = always show, "automatic" = only when down
|
||||||
|
maintenanceTitle: text("maintenanceTitle"),
|
||||||
|
maintenanceMessage: text("maintenanceMessage"),
|
||||||
|
maintenanceEstimatedTime: text("maintenanceEstimatedTime"),
|
||||||
|
postAuthPath: text("postAuthPath"),
|
||||||
|
health: text("health").default("unknown"), // "healthy", "unhealthy", "unknown"
|
||||||
|
wildcard: integer("wildcard", { mode: "boolean" }).notNull().default(false),
|
||||||
|
mode: text("mode")
|
||||||
|
.default("http")
|
||||||
|
.$type<"rdp" | "ssh" | "http" | "vnc" | "inference" | "tcp" | "udp">()
|
||||||
|
.notNull(), // rdp, ssh, http, vnc, inference
|
||||||
|
pamMode: text("pamMode")
|
||||||
|
.$type<"passthrough" | "push">()
|
||||||
|
.default("passthrough"),
|
||||||
|
authDaemonMode: text("authDaemonMode")
|
||||||
|
.$type<"site" | "remote" | "native">()
|
||||||
|
.default("site"),
|
||||||
|
authDaemonPort: integer("authDaemonPort").default(22123),
|
||||||
|
status: text("status")
|
||||||
|
.$type<"pending" | "approved">()
|
||||||
|
.default("approved")
|
||||||
|
},
|
||||||
|
(table) => [
|
||||||
|
index("idx_resources_orgId").on(table.orgId)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
export const resourceAiProviders = sqliteTable(
|
export const resourceAiProviders = sqliteTable(
|
||||||
"resourceAiProviders",
|
"resourceAiProviders",
|
||||||
@@ -260,16 +276,22 @@ export const resourceAiModels = sqliteTable(
|
|||||||
(t) => [primaryKey({ columns: [t.resourceId, t.modelId] })]
|
(t) => [primaryKey({ columns: [t.resourceId, t.modelId] })]
|
||||||
);
|
);
|
||||||
|
|
||||||
export const labels = sqliteTable("labels", {
|
export const labels = sqliteTable(
|
||||||
labelId: integer("labelId").primaryKey({ autoIncrement: true }),
|
"labels",
|
||||||
name: text("name").notNull(),
|
{
|
||||||
color: text("color").notNull(),
|
labelId: integer("labelId").primaryKey({ autoIncrement: true }),
|
||||||
orgId: text("orgId")
|
name: text("name").notNull(),
|
||||||
.references(() => orgs.orgId, {
|
color: text("color").notNull(),
|
||||||
onDelete: "cascade"
|
orgId: text("orgId")
|
||||||
})
|
.references(() => orgs.orgId, {
|
||||||
.notNull()
|
onDelete: "cascade"
|
||||||
});
|
})
|
||||||
|
.notNull()
|
||||||
|
},
|
||||||
|
(table) => [
|
||||||
|
index("idx_labels_orgId").on(table.orgId)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
export const launcherViews = sqliteTable("launcherViews", {
|
export const launcherViews = sqliteTable("launcherViews", {
|
||||||
viewId: integer("viewId").primaryKey({ autoIncrement: true }),
|
viewId: integer("viewId").primaryKey({ autoIncrement: true }),
|
||||||
@@ -366,35 +388,44 @@ export const clientLabels = sqliteTable(
|
|||||||
(t) => [unique("client_label_uniq").on(t.clientId, t.labelId)]
|
(t) => [unique("client_label_uniq").on(t.clientId, t.labelId)]
|
||||||
);
|
);
|
||||||
|
|
||||||
export const targets = sqliteTable("targets", {
|
export const targets = sqliteTable(
|
||||||
targetId: integer("targetId").primaryKey({ autoIncrement: true }),
|
"targets",
|
||||||
resourceId: integer("resourceId").references(() => resources.resourceId, {
|
{
|
||||||
onDelete: "cascade"
|
targetId: integer("targetId").primaryKey({ autoIncrement: true }),
|
||||||
}),
|
resourceId: integer("resourceId").references(
|
||||||
providerId: integer("providerId").references(() => aiProviders.providerId, {
|
() => resources.resourceId,
|
||||||
onDelete: "cascade"
|
{ onDelete: "cascade" }
|
||||||
}),
|
),
|
||||||
siteId: integer("siteId")
|
providerId: integer("providerId").references(
|
||||||
.references(() => sites.siteId, {
|
() => aiProviders.providerId,
|
||||||
onDelete: "cascade"
|
{ onDelete: "cascade" }
|
||||||
})
|
),
|
||||||
.notNull(),
|
siteId: integer("siteId")
|
||||||
ip: text("ip").notNull(),
|
.references(() => sites.siteId, {
|
||||||
method: text("method"),
|
onDelete: "cascade"
|
||||||
port: integer("port").notNull(),
|
})
|
||||||
internalPort: integer("internalPort"),
|
.notNull(),
|
||||||
enabled: integer("enabled", { mode: "boolean" }).notNull().default(true),
|
ip: text("ip").notNull(),
|
||||||
path: text("path"),
|
method: text("method"),
|
||||||
pathMatchType: text("pathMatchType"), // exact, prefix, regex
|
port: integer("port").notNull(),
|
||||||
rewritePath: text("rewritePath"), // if set, rewrites the path to this value before sending to the target
|
internalPort: integer("internalPort"),
|
||||||
rewritePathType: text("rewritePathType"), // exact, prefix, regex, stripPrefix
|
enabled: integer("enabled", { mode: "boolean" }).notNull().default(true),
|
||||||
priority: integer("priority").notNull().default(100),
|
path: text("path"),
|
||||||
mode: text("mode")
|
pathMatchType: text("pathMatchType"), // exact, prefix, regex
|
||||||
.$type<"http" | "tcp" | "udp" | "ssh" | "rdp" | "vnc">()
|
rewritePath: text("rewritePath"), // if set, rewrites the path to this value before sending to the target
|
||||||
.notNull()
|
rewritePathType: text("rewritePathType"), // exact, prefix, regex, stripPrefix
|
||||||
.default("http"),
|
priority: integer("priority").notNull().default(100),
|
||||||
authToken: text("authToken")
|
mode: text("mode")
|
||||||
});
|
.$type<"http" | "tcp" | "udp" | "ssh" | "rdp" | "vnc">()
|
||||||
|
.notNull()
|
||||||
|
.default("http"),
|
||||||
|
authToken: text("authToken")
|
||||||
|
},
|
||||||
|
(table) => [
|
||||||
|
index("idx_targets_resourceId").on(table.resourceId),
|
||||||
|
index("idx_targets_siteId").on(table.siteId)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
export const targetHealthCheck = sqliteTable("targetHealthCheck", {
|
export const targetHealthCheck = sqliteTable("targetHealthCheck", {
|
||||||
targetHealthCheckId: integer("targetHealthCheckId").primaryKey({
|
targetHealthCheckId: integer("targetHealthCheckId").primaryKey({
|
||||||
@@ -663,50 +694,63 @@ export const setupTokens = sqliteTable("setupTokens", {
|
|||||||
dateUsed: text("dateUsed")
|
dateUsed: text("dateUsed")
|
||||||
});
|
});
|
||||||
|
|
||||||
export const newts = sqliteTable("newt", {
|
export const newts = sqliteTable(
|
||||||
newtId: text("id").primaryKey(),
|
"newt",
|
||||||
secretHash: text("secretHash").notNull(),
|
{
|
||||||
dateCreated: text("dateCreated").notNull(),
|
newtId: text("id").primaryKey(),
|
||||||
version: text("version"),
|
secretHash: text("secretHash").notNull(),
|
||||||
siteId: integer("siteId").references(() => sites.siteId, {
|
dateCreated: text("dateCreated").notNull(),
|
||||||
onDelete: "cascade"
|
version: text("version"),
|
||||||
})
|
siteId: integer("siteId").references(() => sites.siteId, {
|
||||||
});
|
|
||||||
|
|
||||||
export const clients = sqliteTable("clients", {
|
|
||||||
clientId: integer("clientId").primaryKey({ autoIncrement: true }),
|
|
||||||
orgId: text("orgId")
|
|
||||||
.references(() => orgs.orgId, {
|
|
||||||
onDelete: "cascade"
|
onDelete: "cascade"
|
||||||
})
|
})
|
||||||
.notNull(),
|
},
|
||||||
exitNodeId: integer("exitNode").references(() => exitNodes.exitNodeId, {
|
(table) => [
|
||||||
onDelete: "set null"
|
index("idx_newts_siteId").on(table.siteId)
|
||||||
}),
|
]
|
||||||
userId: text("userId").references(() => users.userId, {
|
);
|
||||||
// optionally tied to a user and in this case delete when the user deletes
|
|
||||||
onDelete: "cascade"
|
export const clients = sqliteTable(
|
||||||
}),
|
"clients",
|
||||||
niceId: text("niceId").notNull(),
|
{
|
||||||
name: text("name").notNull(),
|
clientId: integer("clientId").primaryKey({ autoIncrement: true }),
|
||||||
pubKey: text("pubKey"),
|
orgId: text("orgId")
|
||||||
olmId: text("olmId"), // to lock it to a specific olm optionally
|
.references(() => orgs.orgId, {
|
||||||
subnet: text("subnet").notNull(),
|
onDelete: "cascade"
|
||||||
exitNodeSubnet: text("exitNodeSubnet"), // this is the subnet when connecting to an exit node
|
})
|
||||||
megabytesIn: integer("bytesIn"),
|
.notNull(),
|
||||||
megabytesOut: integer("bytesOut"),
|
exitNodeId: integer("exitNode").references(() => exitNodes.exitNodeId, {
|
||||||
lastBandwidthUpdate: text("lastBandwidthUpdate"),
|
onDelete: "set null"
|
||||||
lastPing: integer("lastPing"),
|
}),
|
||||||
type: text("type").notNull(), // "olm"
|
userId: text("userId").references(() => users.userId, {
|
||||||
online: integer("online", { mode: "boolean" }).notNull().default(false),
|
// optionally tied to a user and in this case delete when the user deletes
|
||||||
// endpoint: text("endpoint"),
|
onDelete: "cascade"
|
||||||
lastHolePunch: integer("lastHolePunch"),
|
}),
|
||||||
archived: integer("archived", { mode: "boolean" }).notNull().default(false),
|
niceId: text("niceId").notNull(),
|
||||||
blocked: integer("blocked", { mode: "boolean" }).notNull().default(false),
|
name: text("name").notNull(),
|
||||||
approvalState: text("approvalState").$type<
|
pubKey: text("pubKey"),
|
||||||
"pending" | "approved" | "denied"
|
olmId: text("olmId"), // to lock it to a specific olm optionally
|
||||||
>()
|
subnet: text("subnet").notNull(),
|
||||||
});
|
exitNodeSubnet: text("exitNodeSubnet"), // this is the subnet when connecting to an exit node
|
||||||
|
megabytesIn: integer("bytesIn"),
|
||||||
|
megabytesOut: integer("bytesOut"),
|
||||||
|
lastBandwidthUpdate: text("lastBandwidthUpdate"),
|
||||||
|
lastPing: integer("lastPing"),
|
||||||
|
type: text("type").notNull(), // "olm"
|
||||||
|
online: integer("online", { mode: "boolean" }).notNull().default(false),
|
||||||
|
// endpoint: text("endpoint"),
|
||||||
|
lastHolePunch: integer("lastHolePunch"),
|
||||||
|
archived: integer("archived", { mode: "boolean" }).notNull().default(false),
|
||||||
|
blocked: integer("blocked", { mode: "boolean" }).notNull().default(false),
|
||||||
|
approvalState: text("approvalState").$type<
|
||||||
|
"pending" | "approved" | "denied"
|
||||||
|
>()
|
||||||
|
},
|
||||||
|
(table) => [
|
||||||
|
index("idx_clients_orgId").on(table.orgId),
|
||||||
|
index("idx_clients_userId").on(table.userId)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
export const clientSitesAssociationsCache = sqliteTable(
|
export const clientSitesAssociationsCache = sqliteTable(
|
||||||
"clientSitesAssociationsCache",
|
"clientSitesAssociationsCache",
|
||||||
@@ -734,23 +778,29 @@ export const clientSiteResourcesAssociationsCache = sqliteTable(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
export const olms = sqliteTable("olms", {
|
export const olms = sqliteTable(
|
||||||
olmId: text("id").primaryKey(),
|
"olms",
|
||||||
secretHash: text("secretHash").notNull(),
|
{
|
||||||
dateCreated: text("dateCreated").notNull(),
|
olmId: text("id").primaryKey(),
|
||||||
version: text("version"),
|
secretHash: text("secretHash").notNull(),
|
||||||
agent: text("agent"),
|
dateCreated: text("dateCreated").notNull(),
|
||||||
name: text("name"),
|
version: text("version"),
|
||||||
clientId: integer("clientId").references(() => clients.clientId, {
|
agent: text("agent"),
|
||||||
// we will switch this depending on the current org it wants to connect to
|
name: text("name"),
|
||||||
onDelete: "set null"
|
clientId: integer("clientId").references(() => clients.clientId, {
|
||||||
}),
|
// we will switch this depending on the current org it wants to connect to
|
||||||
userId: text("userId").references(() => users.userId, {
|
onDelete: "set null"
|
||||||
// optionally tied to a user and in this case delete when the user deletes
|
}),
|
||||||
onDelete: "cascade"
|
userId: text("userId").references(() => users.userId, {
|
||||||
}),
|
// optionally tied to a user and in this case delete when the user deletes
|
||||||
archived: integer("archived", { mode: "boolean" }).notNull().default(false)
|
onDelete: "cascade"
|
||||||
});
|
}),
|
||||||
|
archived: integer("archived", { mode: "boolean" }).notNull().default(false)
|
||||||
|
},
|
||||||
|
(table) => [
|
||||||
|
index("idx_olms_userId").on(table.userId)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
export const currentFingerprint = sqliteTable("currentFingerprint", {
|
export const currentFingerprint = sqliteTable("currentFingerprint", {
|
||||||
fingerprintId: integer("id").primaryKey({ autoIncrement: true }),
|
fingerprintId: integer("id").primaryKey({ autoIncrement: true }),
|
||||||
@@ -912,17 +962,23 @@ export const twoFactorBackupCodes = sqliteTable("twoFactorBackupCodes", {
|
|||||||
codeHash: text("codeHash").notNull()
|
codeHash: text("codeHash").notNull()
|
||||||
});
|
});
|
||||||
|
|
||||||
export const sessions = sqliteTable("session", {
|
export const sessions = sqliteTable(
|
||||||
sessionId: text("id").primaryKey(),
|
"session",
|
||||||
userId: text("userId")
|
{
|
||||||
.notNull()
|
sessionId: text("id").primaryKey(),
|
||||||
.references(() => users.userId, { onDelete: "cascade" }),
|
userId: text("userId")
|
||||||
expiresAt: integer("expiresAt").notNull(),
|
.notNull()
|
||||||
issuedAt: integer("issuedAt"),
|
.references(() => users.userId, { onDelete: "cascade" }),
|
||||||
deviceAuthUsed: integer("deviceAuthUsed", { mode: "boolean" })
|
expiresAt: integer("expiresAt").notNull(),
|
||||||
.notNull()
|
issuedAt: integer("issuedAt"),
|
||||||
.default(false)
|
deviceAuthUsed: integer("deviceAuthUsed", { mode: "boolean" })
|
||||||
});
|
.notNull()
|
||||||
|
.default(false)
|
||||||
|
},
|
||||||
|
(table) => [
|
||||||
|
index("idx_sessions_userId").on(table.userId)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
export const newtSessions = sqliteTable("newtSession", {
|
export const newtSessions = sqliteTable("newtSession", {
|
||||||
sessionId: text("id").primaryKey(),
|
sessionId: text("id").primaryKey(),
|
||||||
@@ -940,21 +996,28 @@ export const olmSessions = sqliteTable("clientSession", {
|
|||||||
expiresAt: integer("expiresAt").notNull()
|
expiresAt: integer("expiresAt").notNull()
|
||||||
});
|
});
|
||||||
|
|
||||||
export const userOrgs = sqliteTable("userOrgs", {
|
export const userOrgs = sqliteTable(
|
||||||
userId: text("userId")
|
"userOrgs",
|
||||||
.notNull()
|
{
|
||||||
.references(() => users.userId, { onDelete: "cascade" }),
|
userId: text("userId")
|
||||||
orgId: text("orgId")
|
.notNull()
|
||||||
.references(() => orgs.orgId, {
|
.references(() => users.userId, { onDelete: "cascade" }),
|
||||||
onDelete: "cascade"
|
orgId: text("orgId")
|
||||||
})
|
.references(() => orgs.orgId, {
|
||||||
.notNull(),
|
onDelete: "cascade"
|
||||||
isOwner: integer("isOwner", { mode: "boolean" }).notNull().default(false),
|
})
|
||||||
autoProvisioned: integer("autoProvisioned", {
|
.notNull(),
|
||||||
mode: "boolean"
|
isOwner: integer("isOwner", { mode: "boolean" }).notNull().default(false),
|
||||||
}).default(false),
|
autoProvisioned: integer("autoProvisioned", {
|
||||||
pamUsername: text("pamUsername") // cleaned username for ssh and such
|
mode: "boolean"
|
||||||
});
|
}).default(false),
|
||||||
|
pamUsername: text("pamUsername") // cleaned username for ssh and such
|
||||||
|
},
|
||||||
|
(table) => [
|
||||||
|
index("idx_userOrgs_userId").on(table.userId),
|
||||||
|
index("idx_userOrgs_orgId").on(table.orgId)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
export const emailVerificationCodes = sqliteTable("emailVerificationCodes", {
|
export const emailVerificationCodes = sqliteTable("emailVerificationCodes", {
|
||||||
codeId: integer("id").primaryKey({ autoIncrement: true }),
|
codeId: integer("id").primaryKey({ autoIncrement: true }),
|
||||||
@@ -982,26 +1045,32 @@ export const actions = sqliteTable("actions", {
|
|||||||
description: text("description")
|
description: text("description")
|
||||||
});
|
});
|
||||||
|
|
||||||
export const roles = sqliteTable("roles", {
|
export const roles = sqliteTable(
|
||||||
roleId: integer("roleId").primaryKey({ autoIncrement: true }),
|
"roles",
|
||||||
orgId: text("orgId")
|
{
|
||||||
.references(() => orgs.orgId, {
|
roleId: integer("roleId").primaryKey({ autoIncrement: true }),
|
||||||
onDelete: "cascade"
|
orgId: text("orgId")
|
||||||
})
|
.references(() => orgs.orgId, {
|
||||||
.notNull(),
|
onDelete: "cascade"
|
||||||
isAdmin: integer("isAdmin", { mode: "boolean" }),
|
})
|
||||||
name: text("name").notNull(),
|
.notNull(),
|
||||||
description: text("description"),
|
isAdmin: integer("isAdmin", { mode: "boolean" }),
|
||||||
requireDeviceApproval: integer("requireDeviceApproval", {
|
name: text("name").notNull(),
|
||||||
mode: "boolean"
|
description: text("description"),
|
||||||
}).default(false),
|
requireDeviceApproval: integer("requireDeviceApproval", {
|
||||||
sshSudoMode: text("sshSudoMode").default("full"), // "none" | "full" | "commands"
|
mode: "boolean"
|
||||||
sshSudoCommands: text("sshSudoCommands").default("[]"),
|
}).default(false),
|
||||||
sshCreateHomeDir: integer("sshCreateHomeDir", { mode: "boolean" }).default(
|
sshSudoMode: text("sshSudoMode").default("full"), // "none" | "full" | "commands"
|
||||||
true
|
sshSudoCommands: text("sshSudoCommands").default("[]"),
|
||||||
),
|
sshCreateHomeDir: integer("sshCreateHomeDir", { mode: "boolean" }).default(
|
||||||
sshUnixGroups: text("sshUnixGroups").default("[]")
|
true
|
||||||
});
|
),
|
||||||
|
sshUnixGroups: text("sshUnixGroups").default("[]")
|
||||||
|
},
|
||||||
|
(table) => [
|
||||||
|
index("idx_roles_orgId").on(table.orgId)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
export const userOrgRoles = sqliteTable(
|
export const userOrgRoles = sqliteTable(
|
||||||
"userOrgRoles",
|
"userOrgRoles",
|
||||||
|
|||||||
Reference in New Issue
Block a user