Merge branch 'main' into ENG-3506-LDAP

This commit is contained in:
x032205
2025-09-15 11:52:18 -04:00
190 changed files with 7343 additions and 645 deletions
@@ -0,0 +1,150 @@
import { Knex } from "knex";
import { TableName } from "../schemas";
import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils";
export async function up(knex: Knex): Promise<void> {
if (!(await knex.schema.hasTable(TableName.InstanceRelayConfig))) {
await knex.schema.createTable(TableName.InstanceRelayConfig, (t) => {
t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid());
t.timestamps(true, true, true);
// Root CA for relay PKI
t.binary("encryptedRootRelayPkiCaPrivateKey").notNullable();
t.binary("encryptedRootRelayPkiCaCertificate").notNullable();
// Instance CA for relay PKI
t.binary("encryptedInstanceRelayPkiCaPrivateKey").notNullable();
t.binary("encryptedInstanceRelayPkiCaCertificate").notNullable();
t.binary("encryptedInstanceRelayPkiCaCertificateChain").notNullable();
// Instance client/server intermediates for relay PKI
t.binary("encryptedInstanceRelayPkiClientCaPrivateKey").notNullable();
t.binary("encryptedInstanceRelayPkiClientCaCertificate").notNullable();
t.binary("encryptedInstanceRelayPkiClientCaCertificateChain").notNullable();
t.binary("encryptedInstanceRelayPkiServerCaPrivateKey").notNullable();
t.binary("encryptedInstanceRelayPkiServerCaCertificate").notNullable();
t.binary("encryptedInstanceRelayPkiServerCaCertificateChain").notNullable();
// Org Parent CAs for relay
t.binary("encryptedOrgRelayPkiCaPrivateKey").notNullable();
t.binary("encryptedOrgRelayPkiCaCertificate").notNullable();
t.binary("encryptedOrgRelayPkiCaCertificateChain").notNullable();
// Instance SSH CAs for relay
t.binary("encryptedInstanceRelaySshClientCaPrivateKey").notNullable();
t.binary("encryptedInstanceRelaySshClientCaPublicKey").notNullable();
t.binary("encryptedInstanceRelaySshServerCaPrivateKey").notNullable();
t.binary("encryptedInstanceRelaySshServerCaPublicKey").notNullable();
});
await createOnUpdateTrigger(knex, TableName.InstanceRelayConfig);
}
// Org-level relay configuration (one-to-one with organization)
if (!(await knex.schema.hasTable(TableName.OrgRelayConfig))) {
await knex.schema.createTable(TableName.OrgRelayConfig, (t) => {
t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid());
t.timestamps(true, true, true);
t.uuid("orgId").notNullable().unique();
t.foreign("orgId").references("id").inTable(TableName.Organization).onDelete("CASCADE");
// Org-scoped relay PKI (client + server)
t.binary("encryptedRelayPkiClientCaPrivateKey").notNullable();
t.binary("encryptedRelayPkiClientCaCertificate").notNullable();
t.binary("encryptedRelayPkiClientCaCertificateChain").notNullable();
t.binary("encryptedRelayPkiServerCaPrivateKey").notNullable();
t.binary("encryptedRelayPkiServerCaCertificate").notNullable();
t.binary("encryptedRelayPkiServerCaCertificateChain").notNullable();
// Org-scoped relay SSH (client + server)
t.binary("encryptedRelaySshClientCaPrivateKey").notNullable();
t.binary("encryptedRelaySshClientCaPublicKey").notNullable();
t.binary("encryptedRelaySshServerCaPrivateKey").notNullable();
t.binary("encryptedRelaySshServerCaPublicKey").notNullable();
});
await createOnUpdateTrigger(knex, TableName.OrgRelayConfig);
}
if (!(await knex.schema.hasTable(TableName.OrgGatewayConfigV2))) {
await knex.schema.createTable(TableName.OrgGatewayConfigV2, (t) => {
t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid());
t.uuid("orgId").notNullable().unique();
t.foreign("orgId").references("id").inTable(TableName.Organization).onDelete("CASCADE");
t.timestamps(true, true, true);
t.binary("encryptedRootGatewayCaPrivateKey").notNullable();
t.binary("encryptedRootGatewayCaCertificate").notNullable();
t.binary("encryptedGatewayServerCaPrivateKey").notNullable();
t.binary("encryptedGatewayServerCaCertificate").notNullable();
t.binary("encryptedGatewayServerCaCertificateChain").notNullable();
t.binary("encryptedGatewayClientCaPrivateKey").notNullable();
t.binary("encryptedGatewayClientCaCertificate").notNullable();
t.binary("encryptedGatewayClientCaCertificateChain").notNullable();
});
await createOnUpdateTrigger(knex, TableName.OrgGatewayConfigV2);
}
if (!(await knex.schema.hasTable(TableName.Relay))) {
await knex.schema.createTable(TableName.Relay, (t) => {
t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid());
t.timestamps(true, true, true);
t.uuid("orgId");
t.foreign("orgId").references("id").inTable(TableName.Organization).onDelete("CASCADE");
t.uuid("identityId");
t.foreign("identityId").references("id").inTable(TableName.Identity).onDelete("CASCADE");
t.string("name").notNullable();
t.string("host").notNullable();
t.unique(["orgId", "name"]);
});
await createOnUpdateTrigger(knex, TableName.Relay);
}
if (!(await knex.schema.hasTable(TableName.GatewayV2))) {
await knex.schema.createTable(TableName.GatewayV2, (t) => {
t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid());
t.timestamps(true, true, true);
t.uuid("orgId").notNullable();
t.foreign("orgId").references("id").inTable(TableName.Organization).onDelete("CASCADE");
t.uuid("identityId").notNullable().unique();
t.foreign("identityId").references("id").inTable(TableName.Identity).onDelete("CASCADE");
t.uuid("relayId");
t.foreign("relayId").references("id").inTable(TableName.Relay).onDelete("SET NULL");
t.string("name").notNullable();
t.unique(["orgId", "name"]);
t.dateTime("heartbeat");
});
await createOnUpdateTrigger(knex, TableName.GatewayV2);
}
}
export async function down(knex: Knex): Promise<void> {
await dropOnUpdateTrigger(knex, TableName.OrgRelayConfig);
await knex.schema.dropTableIfExists(TableName.OrgRelayConfig);
await dropOnUpdateTrigger(knex, TableName.InstanceRelayConfig);
await knex.schema.dropTableIfExists(TableName.InstanceRelayConfig);
await dropOnUpdateTrigger(knex, TableName.OrgGatewayConfigV2);
await knex.schema.dropTableIfExists(TableName.OrgGatewayConfigV2);
await dropOnUpdateTrigger(knex, TableName.GatewayV2);
await knex.schema.dropTableIfExists(TableName.GatewayV2);
await dropOnUpdateTrigger(knex, TableName.Relay);
await knex.schema.dropTableIfExists(TableName.Relay);
}
@@ -0,0 +1,33 @@
import { Knex } from "knex";
import { TableName } from "../schemas";
export async function up(knex: Knex): Promise<void> {
if (!(await knex.schema.hasColumn(TableName.DynamicSecret, "gatewayV2Id"))) {
await knex.schema.alterTable(TableName.DynamicSecret, (table) => {
table.uuid("gatewayV2Id");
table.foreign("gatewayV2Id").references("id").inTable(TableName.GatewayV2).onDelete("SET NULL");
});
}
if (!(await knex.schema.hasColumn(TableName.IdentityKubernetesAuth, "gatewayV2Id"))) {
await knex.schema.alterTable(TableName.IdentityKubernetesAuth, (table) => {
table.uuid("gatewayV2Id");
table.foreign("gatewayV2Id").references("id").inTable(TableName.GatewayV2).onDelete("SET NULL");
});
}
}
export async function down(knex: Knex): Promise<void> {
if (await knex.schema.hasColumn(TableName.DynamicSecret, "gatewayV2Id")) {
await knex.schema.alterTable(TableName.DynamicSecret, (table) => {
table.dropColumn("gatewayV2Id");
});
}
if (await knex.schema.hasColumn(TableName.IdentityKubernetesAuth, "gatewayV2Id")) {
await knex.schema.alterTable(TableName.IdentityKubernetesAuth, (table) => {
table.dropColumn("gatewayV2Id");
});
}
}
@@ -0,0 +1,18 @@
import { Knex } from "knex";
import { TableName } from "../schemas";
export async function up(knex: Knex): Promise<void> {
if (!(await knex.schema.hasTable(TableName.KeyValueStore))) {
await knex.schema.createTable(TableName.KeyValueStore, (t) => {
t.text("key").primary();
t.bigint("integerValue");
t.datetime("expiresAt");
t.timestamps(true, true, true);
});
}
}
export async function down(knex: Knex): Promise<void> {
await knex.schema.dropTableIfExists(TableName.KeyValueStore);
}
@@ -0,0 +1,23 @@
import { Knex } from "knex";
import { TableName } from "../schemas";
export async function up(knex: Knex): Promise<void> {
const hasPayloadCol = await knex.schema.hasColumn(TableName.AuthTokens, "payload");
if (!hasPayloadCol) {
await knex.schema.alterTable(TableName.AuthTokens, (t) => {
t.text("payload").nullable();
});
}
}
export async function down(knex: Knex): Promise<void> {
const hasPayloadCol = await knex.schema.hasColumn(TableName.AuthTokens, "payload");
if (hasPayloadCol) {
await knex.schema.alterTable(TableName.AuthTokens, (t) => {
t.dropColumn("payload");
});
}
}
+2 -1
View File
@@ -18,7 +18,8 @@ export const AuthTokensSchema = z.object({
updatedAt: z.date(),
userId: z.string().uuid().nullable().optional(),
orgId: z.string().uuid().nullable().optional(),
aliasId: z.string().nullable().optional()
aliasId: z.string().nullable().optional(),
payload: z.string().nullable().optional()
});
export type TAuthTokens = z.infer<typeof AuthTokensSchema>;
+2 -1
View File
@@ -29,7 +29,8 @@ export const DynamicSecretsSchema = z.object({
encryptedInput: zodBuffer,
projectGatewayId: z.string().uuid().nullable().optional(),
gatewayId: z.string().uuid().nullable().optional(),
usernameTemplate: z.string().nullable().optional()
usernameTemplate: z.string().nullable().optional(),
gatewayV2Id: z.string().uuid().nullable().optional()
});
export type TDynamicSecrets = z.infer<typeof DynamicSecretsSchema>;
+23
View File
@@ -0,0 +1,23 @@
// Code generated by automation script, DO NOT EDIT.
// Automated by pulling database and generating zod schema
// To update. Just run npm run generate:schema
// Written by akhilmhdh.
import { z } from "zod";
import { TImmutableDBKeys } from "./models";
export const GatewaysV2Schema = z.object({
id: z.string().uuid(),
createdAt: z.date(),
updatedAt: z.date(),
orgId: z.string().uuid(),
identityId: z.string().uuid(),
relayId: z.string().uuid().nullable().optional(),
name: z.string(),
heartbeat: z.date().nullable().optional()
});
export type TGatewaysV2 = z.infer<typeof GatewaysV2Schema>;
export type TGatewaysV2Insert = Omit<z.input<typeof GatewaysV2Schema>, TImmutableDBKeys>;
export type TGatewaysV2Update = Partial<Omit<z.input<typeof GatewaysV2Schema>, TImmutableDBKeys>>;
@@ -32,7 +32,8 @@ export const IdentityKubernetesAuthsSchema = z.object({
encryptedKubernetesCaCertificate: zodBuffer.nullable().optional(),
gatewayId: z.string().uuid().nullable().optional(),
accessTokenPeriod: z.coerce.number().default(0),
tokenReviewMode: z.string().default("api")
tokenReviewMode: z.string().default("api"),
gatewayV2Id: z.string().uuid().nullable().optional()
});
export type TIdentityKubernetesAuths = z.infer<typeof IdentityKubernetesAuthsSchema>;
+6
View File
@@ -31,6 +31,7 @@ export * from "./folder-commits";
export * from "./folder-tree-checkpoint-resources";
export * from "./folder-tree-checkpoints";
export * from "./gateways";
export * from "./gateways-v2";
export * from "./git-app-install-sessions";
export * from "./git-app-org";
export * from "./github-org-sync-configs";
@@ -57,10 +58,12 @@ export * from "./identity-token-auths";
export * from "./identity-ua-client-secrets";
export * from "./identity-universal-auths";
export * from "./incident-contacts";
export * from "./instance-relay-config";
export * from "./integration-auths";
export * from "./integrations";
export * from "./internal-certificate-authorities";
export * from "./internal-kms";
export * from "./key-value-store";
export * from "./kmip-client-certificates";
export * from "./kmip-clients";
export * from "./kmip-org-configs";
@@ -75,7 +78,9 @@ export * from "./models";
export * from "./oidc-configs";
export * from "./org-bots";
export * from "./org-gateway-config";
export * from "./org-gateway-config-v2";
export * from "./org-memberships";
export * from "./org-relay-config";
export * from "./org-roles";
export * from "./organizations";
export * from "./pki-alerts";
@@ -96,6 +101,7 @@ export * from "./project-user-additional-privilege";
export * from "./project-user-membership-roles";
export * from "./projects";
export * from "./rate-limit";
export * from "./relays";
export * from "./resource-metadata";
export * from "./saml-configs";
export * from "./scim-tokens";
@@ -0,0 +1,38 @@
// Code generated by automation script, DO NOT EDIT.
// Automated by pulling database and generating zod schema
// To update. Just run npm run generate:schema
// Written by akhilmhdh.
import { z } from "zod";
import { zodBuffer } from "@app/lib/zod";
import { TImmutableDBKeys } from "./models";
export const InstanceRelayConfigSchema = z.object({
id: z.string().uuid(),
createdAt: z.date(),
updatedAt: z.date(),
encryptedRootRelayPkiCaPrivateKey: zodBuffer,
encryptedRootRelayPkiCaCertificate: zodBuffer,
encryptedInstanceRelayPkiCaPrivateKey: zodBuffer,
encryptedInstanceRelayPkiCaCertificate: zodBuffer,
encryptedInstanceRelayPkiCaCertificateChain: zodBuffer,
encryptedInstanceRelayPkiClientCaPrivateKey: zodBuffer,
encryptedInstanceRelayPkiClientCaCertificate: zodBuffer,
encryptedInstanceRelayPkiClientCaCertificateChain: zodBuffer,
encryptedInstanceRelayPkiServerCaPrivateKey: zodBuffer,
encryptedInstanceRelayPkiServerCaCertificate: zodBuffer,
encryptedInstanceRelayPkiServerCaCertificateChain: zodBuffer,
encryptedOrgRelayPkiCaPrivateKey: zodBuffer,
encryptedOrgRelayPkiCaCertificate: zodBuffer,
encryptedOrgRelayPkiCaCertificateChain: zodBuffer,
encryptedInstanceRelaySshClientCaPrivateKey: zodBuffer,
encryptedInstanceRelaySshClientCaPublicKey: zodBuffer,
encryptedInstanceRelaySshServerCaPrivateKey: zodBuffer,
encryptedInstanceRelaySshServerCaPublicKey: zodBuffer
});
export type TInstanceRelayConfig = z.infer<typeof InstanceRelayConfigSchema>;
export type TInstanceRelayConfigInsert = Omit<z.input<typeof InstanceRelayConfigSchema>, TImmutableDBKeys>;
export type TInstanceRelayConfigUpdate = Partial<Omit<z.input<typeof InstanceRelayConfigSchema>, TImmutableDBKeys>>;
+20
View File
@@ -0,0 +1,20 @@
// Code generated by automation script, DO NOT EDIT.
// Automated by pulling database and generating zod schema
// To update. Just run npm run generate:schema
// Written by akhilmhdh.
import { z } from "zod";
import { TImmutableDBKeys } from "./models";
export const KeyValueStoreSchema = z.object({
key: z.string(),
integerValue: z.coerce.number().nullable().optional(),
expiresAt: z.date().nullable().optional(),
createdAt: z.date(),
updatedAt: z.date()
});
export type TKeyValueStore = z.infer<typeof KeyValueStoreSchema>;
export type TKeyValueStoreInsert = Omit<z.input<typeof KeyValueStoreSchema>, TImmutableDBKeys>;
export type TKeyValueStoreUpdate = Partial<Omit<z.input<typeof KeyValueStoreSchema>, TImmutableDBKeys>>;
+10 -1
View File
@@ -179,7 +179,16 @@ export enum TableName {
SecretScanningConfig = "secret_scanning_configs",
// reminders
Reminder = "reminders",
ReminderRecipient = "reminders_recipients"
ReminderRecipient = "reminders_recipients",
// gateway v2
InstanceRelayConfig = "instance_relay_config",
OrgRelayConfig = "org_relay_config",
OrgGatewayConfigV2 = "org_gateway_config_v2",
Relay = "relays",
GatewayV2 = "gateways_v2",
KeyValueStore = "key_value_store"
}
export type TImmutableDBKeys = "id" | "createdAt" | "updatedAt" | "commitId";
@@ -0,0 +1,29 @@
// Code generated by automation script, DO NOT EDIT.
// Automated by pulling database and generating zod schema
// To update. Just run npm run generate:schema
// Written by akhilmhdh.
import { z } from "zod";
import { zodBuffer } from "@app/lib/zod";
import { TImmutableDBKeys } from "./models";
export const OrgGatewayConfigV2Schema = z.object({
id: z.string().uuid(),
orgId: z.string().uuid(),
createdAt: z.date(),
updatedAt: z.date(),
encryptedRootGatewayCaPrivateKey: zodBuffer,
encryptedRootGatewayCaCertificate: zodBuffer,
encryptedGatewayServerCaPrivateKey: zodBuffer,
encryptedGatewayServerCaCertificate: zodBuffer,
encryptedGatewayServerCaCertificateChain: zodBuffer,
encryptedGatewayClientCaPrivateKey: zodBuffer,
encryptedGatewayClientCaCertificate: zodBuffer,
encryptedGatewayClientCaCertificateChain: zodBuffer
});
export type TOrgGatewayConfigV2 = z.infer<typeof OrgGatewayConfigV2Schema>;
export type TOrgGatewayConfigV2Insert = Omit<z.input<typeof OrgGatewayConfigV2Schema>, TImmutableDBKeys>;
export type TOrgGatewayConfigV2Update = Partial<Omit<z.input<typeof OrgGatewayConfigV2Schema>, TImmutableDBKeys>>;
@@ -0,0 +1,31 @@
// Code generated by automation script, DO NOT EDIT.
// Automated by pulling database and generating zod schema
// To update. Just run npm run generate:schema
// Written by akhilmhdh.
import { z } from "zod";
import { zodBuffer } from "@app/lib/zod";
import { TImmutableDBKeys } from "./models";
export const OrgRelayConfigSchema = z.object({
id: z.string().uuid(),
createdAt: z.date(),
updatedAt: z.date(),
orgId: z.string().uuid(),
encryptedRelayPkiClientCaPrivateKey: zodBuffer,
encryptedRelayPkiClientCaCertificate: zodBuffer,
encryptedRelayPkiClientCaCertificateChain: zodBuffer,
encryptedRelayPkiServerCaPrivateKey: zodBuffer,
encryptedRelayPkiServerCaCertificate: zodBuffer,
encryptedRelayPkiServerCaCertificateChain: zodBuffer,
encryptedRelaySshClientCaPrivateKey: zodBuffer,
encryptedRelaySshClientCaPublicKey: zodBuffer,
encryptedRelaySshServerCaPrivateKey: zodBuffer,
encryptedRelaySshServerCaPublicKey: zodBuffer
});
export type TOrgRelayConfig = z.infer<typeof OrgRelayConfigSchema>;
export type TOrgRelayConfigInsert = Omit<z.input<typeof OrgRelayConfigSchema>, TImmutableDBKeys>;
export type TOrgRelayConfigUpdate = Partial<Omit<z.input<typeof OrgRelayConfigSchema>, TImmutableDBKeys>>;
+22
View File
@@ -0,0 +1,22 @@
// Code generated by automation script, DO NOT EDIT.
// Automated by pulling database and generating zod schema
// To update. Just run npm run generate:schema
// Written by akhilmhdh.
import { z } from "zod";
import { TImmutableDBKeys } from "./models";
export const RelaysSchema = z.object({
id: z.string().uuid(),
createdAt: z.date(),
updatedAt: z.date(),
orgId: z.string().uuid().nullable().optional(),
identityId: z.string().uuid().nullable().optional(),
name: z.string(),
host: z.string()
});
export type TRelays = z.infer<typeof RelaysSchema>;
export type TRelaysInsert = Omit<z.input<typeof RelaysSchema>, TImmutableDBKeys>;
export type TRelaysUpdate = Partial<Omit<z.input<typeof RelaysSchema>, TImmutableDBKeys>>;