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:
Parikshith
2026-08-22 22:57:23 +05:30
committed by Owen
parent 0dece5fef1
commit 41139f2fd0
2 changed files with 407 additions and 316 deletions
+71 -49
View File
@@ -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
View File
@@ -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",