diff --git a/server/auth/actions.ts b/server/auth/actions.ts index 75caed82d..aed4cefe8 100644 --- a/server/auth/actions.ts +++ b/server/auth/actions.ts @@ -205,7 +205,12 @@ export enum ActionsEnum { deleteVirtualApiKey = "deleteVirtualApiKey", getVirtualApiKey = "getVirtualApiKey", listVirtualApiKeys = "listVirtualApiKeys", - updateVirtualApiKey = "updateVirtualApiKey" + updateVirtualApiKey = "updateVirtualApiKey", + createRedirect = "createRedirect", + deleteRedirect = "deleteRedirect", + getRedirect = "getRedirect", + listRedirects = "listRedirects", + updateRedirect = "updateRedirect" } export async function checkUserActionPermission( diff --git a/server/db/names.ts b/server/db/names.ts index 37e851379..d044f1406 100644 --- a/server/db/names.ts +++ b/server/db/names.ts @@ -4,6 +4,7 @@ import { aiProviders, clients, db, + redirects, resourcePolicies, resources, siteResources @@ -140,6 +141,30 @@ export async function getUniqueProviderName(orgId: string): Promise { } } +export async function getUniqueRedirectName(orgId: string): Promise { + let loops = 0; + while (true) { + if (loops > 100) { + throw new Error("Could not generate a unique name"); + } + + const name = generateName(); + + const redirectCount = await db + .select({ + niceId: redirects.niceId, + orgId: redirects.orgId + }) + .from(redirects) + .where(and(eq(redirects.niceId, name), eq(redirects.orgId, orgId))); + + if (redirectCount.length === 0) { + return name; + } + loops++; + } +} + export async function getUniqueResourcePolicyName( orgId: string ): Promise { diff --git a/server/db/pg/schema/schema.ts b/server/db/pg/schema/schema.ts index 2ab34e83d..38c617e0d 100644 --- a/server/db/pg/schema/schema.ts +++ b/server/db/pg/schema/schema.ts @@ -237,7 +237,7 @@ export const redirects = pgTable("redirects", { resourceId: integer("resourceId").references(() => resources.resourceId, { onDelete: "cascade" }), - domainId: integer("domainId").references(() => domains.domainId, { + domainId: varchar("domainId").references(() => domains.domainId, { onDelete: "cascade" }), niceId: text("niceId").notNull(), @@ -2086,6 +2086,7 @@ export type ResourcePolicy = InferSelectModel; export type RolePolicy = InferSelectModel; export type UserPolicy = InferSelectModel; export type ResourcePolicyRule = InferSelectModel; +export type Redirect = InferSelectModel; export type AiProvider = InferSelectModel; export type AiModel = InferSelectModel; export type AiBudget = InferSelectModel; diff --git a/server/db/sqlite/schema/schema.ts b/server/db/sqlite/schema/schema.ts index c38fc4b54..5fbabdb88 100644 --- a/server/db/sqlite/schema/schema.ts +++ b/server/db/sqlite/schema/schema.ts @@ -253,7 +253,7 @@ export const redirects = sqliteTable("redirects", { resourceId: integer("resourceId").references(() => resources.resourceId, { onDelete: "cascade" }), - domainId: integer("domainId").references(() => domains.domainId, { + domainId: text("domainId").references(() => domains.domainId, { onDelete: "cascade" }), niceId: text("niceId").notNull(), @@ -2127,6 +2127,7 @@ export type ResourcePolicyHeaderAuth = InferSelectModel< >; export type RolePolicy = InferSelectModel; export type UserPolicy = InferSelectModel; +export type Redirect = InferSelectModel; export type AiProvider = InferSelectModel; export type AiModel = InferSelectModel; export type AiBudget = InferSelectModel; diff --git a/server/openApi.ts b/server/openApi.ts index b4b7c1a7a..b1eabea79 100644 --- a/server/openApi.ts +++ b/server/openApi.ts @@ -32,7 +32,8 @@ export enum OpenAPITags { AiProvider = "AI Provider", AiModel = "AI Model", AiBudget = "AI Budget", - VirtualApiKey = "Virtual API Key" + VirtualApiKey = "Virtual API Key", + Redirect = "Redirect" } // Order here controls the order tags are displayed in Swagger UI