diff --git a/apps/backend/src/app/api/latest/auth/oauth/callback/[provider_id]/route.tsx b/apps/backend/src/app/api/latest/auth/oauth/callback/[provider_id]/route.tsx index f68241b3b..d5b12f780 100644 --- a/apps/backend/src/app/api/latest/auth/oauth/callback/[provider_id]/route.tsx +++ b/apps/backend/src/app/api/latest/auth/oauth/callback/[provider_id]/route.tsx @@ -44,7 +44,7 @@ async function createProjectUserOAuthAccount(prisma: PrismaClient, params: { } const redirectOrThrowError = (error: KnownError, tenancy: Tenancy, errorRedirectUrl?: string) => { - if (!errorRedirectUrl || !validateRedirectUrl(errorRedirectUrl, Object.values(tenancy.config.domains), tenancy.config.domains.allowLocalhost)) { + if (!errorRedirectUrl || !validateRedirectUrl(errorRedirectUrl, tenancy)) { throw error; } diff --git a/apps/backend/src/app/api/latest/auth/password/sign-up/route.tsx b/apps/backend/src/app/api/latest/auth/password/sign-up/route.tsx index ca954beb9..7679af03c 100644 --- a/apps/backend/src/app/api/latest/auth/password/sign-up/route.tsx +++ b/apps/backend/src/app/api/latest/auth/password/sign-up/route.tsx @@ -36,15 +36,11 @@ export const POST = createSmartRouteHandler({ }).defined(), }), async handler({ auth: { tenancy }, body: { email, password, verification_callback_url: verificationCallbackUrl } }, fullReq) { - if (!tenancy.config.credential_enabled) { + if (!tenancy.config.auth.password.allowSignIn) { throw new KnownErrors.PasswordAuthenticationNotEnabled(); } - if (!validateRedirectUrl( - verificationCallbackUrl, - tenancy.config.domains, - tenancy.config.allow_localhost, - )) { + if (!validateRedirectUrl(verificationCallbackUrl, tenancy)) { throw new KnownErrors.RedirectUrlNotWhitelisted(); } @@ -53,7 +49,7 @@ export const POST = createSmartRouteHandler({ throw passwordError; } - if (!tenancy.config.sign_up_enabled) { + if (!tenancy.config.auth.allowSignUp) { throw new KnownErrors.SignUpNotEnabled(); } diff --git a/apps/backend/src/app/api/latest/emails/send-email/route.tsx b/apps/backend/src/app/api/latest/emails/send-email/route.tsx index fd2a6901f..7fc9aef4b 100644 --- a/apps/backend/src/app/api/latest/emails/send-email/route.tsx +++ b/apps/backend/src/app/api/latest/emails/send-email/route.tsx @@ -48,7 +48,7 @@ export const POST = createSmartRouteHandler({ if (!getEnvVariable("STACK_FREESTYLE_API_KEY")) { throw new StatusError(500, "STACK_FREESTYLE_API_KEY is not set"); } - if (auth.tenancy.config.email_config.type === "shared") { + if (auth.tenancy.config.emails.server.isShared) { throw new StatusError(400, "Cannot send custom emails when using shared email config"); } const emailConfig = await getEmailConfig(auth.tenancy); @@ -56,11 +56,11 @@ export const POST = createSmartRouteHandler({ if (!notificationCategory) { throw new StatusError(404, "Notification category not found"); } - const themeList = auth.tenancy.completeConfig.emails.themeList; - if (!Object.keys(themeList).includes(auth.tenancy.completeConfig.emails.theme)) { + const themeList = auth.tenancy.config.emails.themeList; + if (!Object.keys(themeList).includes(auth.tenancy.config.emails.theme)) { throw new StatusError(400, "No active theme found"); } - const activeTheme = themeList[auth.tenancy.completeConfig.emails.theme]; + const activeTheme = themeList[auth.tenancy.config.emails.theme]; const prisma = await getPrismaClientForTenancy(auth.tenancy); diff --git a/apps/backend/src/app/api/latest/internal/email-templates/[templateId]/route.tsx b/apps/backend/src/app/api/latest/internal/email-templates/[templateId]/route.tsx index c58af9871..24dc52743 100644 --- a/apps/backend/src/app/api/latest/internal/email-templates/[templateId]/route.tsx +++ b/apps/backend/src/app/api/latest/internal/email-templates/[templateId]/route.tsx @@ -1,10 +1,10 @@ import { overrideEnvironmentConfigOverride } from "@/lib/config"; +import { renderEmailWithTemplate } from "@/lib/email-rendering"; import { globalPrismaClient } from "@/prisma-client"; import { createSmartRouteHandler } from "@/route-handlers/smart-route-handler"; +import { KnownErrors } from "@stackframe/stack-shared/dist/known-errors"; import { adaptSchema, yupNumber, yupObject, yupString } from "@stackframe/stack-shared/dist/schema-fields"; import { StatusError } from "@stackframe/stack-shared/dist/utils/errors"; -import { renderEmailWithTemplate } from "@/lib/email-rendering"; -import { KnownErrors } from "@stackframe/stack-shared/dist/known-errors"; export const PATCH = createSmartRouteHandler({ @@ -31,11 +31,11 @@ export const PATCH = createSmartRouteHandler({ }).defined(), }), async handler({ auth: { tenancy }, params: { templateId }, body }) { - const templateList = tenancy.completeConfig.emails.templateList; + const templateList = tenancy.config.emails.templateList; if (!Object.keys(templateList).includes(templateId)) { throw new StatusError(StatusError.NotFound, "No template found with given id"); } - const theme = tenancy.completeConfig.emails.themeList[tenancy.completeConfig.emails.theme]; + const theme = tenancy.config.emails.themeList[tenancy.config.emails.theme]; const result = await renderEmailWithTemplate(body.tsx_source, theme.tsxSource, { projectDisplayName: tenancy.project.display_name }); if (result.status === "error") { throw new KnownErrors.EmailRenderingError(result.error); diff --git a/apps/backend/src/app/api/latest/internal/email-templates/route.tsx b/apps/backend/src/app/api/latest/internal/email-templates/route.tsx index 890162570..dc651219e 100644 --- a/apps/backend/src/app/api/latest/internal/email-templates/route.tsx +++ b/apps/backend/src/app/api/latest/internal/email-templates/route.tsx @@ -25,7 +25,7 @@ export const GET = createSmartRouteHandler({ }).defined(), }), async handler({ auth: { tenancy } }) { - const templates = Object.entries(tenancy.completeConfig.emails.templateList).map(([id, template]) => ({ + const templates = Object.entries(tenancy.config.emails.templateList).map(([id, template]) => ({ id, subject: template.subject, display_name: template.displayName, diff --git a/apps/backend/src/app/api/latest/internal/email-themes/[id]/route.tsx b/apps/backend/src/app/api/latest/internal/email-themes/[id]/route.tsx index 393c450e8..965761f17 100644 --- a/apps/backend/src/app/api/latest/internal/email-themes/[id]/route.tsx +++ b/apps/backend/src/app/api/latest/internal/email-themes/[id]/route.tsx @@ -1,8 +1,8 @@ import { overrideEnvironmentConfigOverride } from "@/lib/config"; -import { globalPrismaClient } from "@/prisma-client"; import { renderEmailWithTemplate } from "@/lib/email-rendering"; -import { previewTemplateSource } from "@stackframe/stack-shared/dist/helpers/emails"; +import { globalPrismaClient } from "@/prisma-client"; import { createSmartRouteHandler } from "@/route-handlers/smart-route-handler"; +import { previewTemplateSource } from "@stackframe/stack-shared/dist/helpers/emails"; import { KnownErrors } from "@stackframe/stack-shared/dist/known-errors"; import { adaptSchema, yupNumber, yupObject, yupString } from "@stackframe/stack-shared/dist/schema-fields"; import { StatusError } from "@stackframe/stack-shared/dist/utils/errors"; @@ -29,7 +29,7 @@ export const GET = createSmartRouteHandler({ }).defined(), }), async handler({ auth: { tenancy }, params: { id } }) { - const themeList = tenancy.completeConfig.emails.themeList; + const themeList = tenancy.config.emails.themeList; if (!Object.keys(themeList).includes(id)) { throw new StatusError(404, "No theme found with given id"); } @@ -69,7 +69,7 @@ export const PATCH = createSmartRouteHandler({ }).defined(), }), async handler({ auth: { tenancy }, params: { id }, body }) { - const themeList = tenancy.completeConfig.emails.themeList; + const themeList = tenancy.config.emails.themeList; if (!Object.keys(themeList).includes(id)) { throw new StatusError(404, "No theme found with given id"); } diff --git a/apps/backend/src/app/api/latest/internal/email-themes/route.tsx b/apps/backend/src/app/api/latest/internal/email-themes/route.tsx index b9be630f4..906cc9d3e 100644 --- a/apps/backend/src/app/api/latest/internal/email-themes/route.tsx +++ b/apps/backend/src/app/api/latest/internal/email-themes/route.tsx @@ -1,8 +1,7 @@ import { overrideEnvironmentConfigOverride } from "@/lib/config"; -import { LightEmailTheme } from "@stackframe/stack-shared/dist/helpers/emails"; import { globalPrismaClient } from "@/prisma-client"; import { createSmartRouteHandler } from "@/route-handlers/smart-route-handler"; -import { DEFAULT_EMAIL_THEME_ID } from "@stackframe/stack-shared/dist/helpers/emails"; +import { DEFAULT_EMAIL_THEME_ID, LightEmailTheme } from "@stackframe/stack-shared/dist/helpers/emails"; import { adaptSchema, yupArray, yupNumber, yupObject, yupString } from "@stackframe/stack-shared/dist/schema-fields"; import { generateUuid } from "@stackframe/stack-shared/dist/utils/uuids"; @@ -69,8 +68,8 @@ export const GET = createSmartRouteHandler({ }).defined(), }), async handler({ auth: { tenancy } }) { - const themeList = tenancy.completeConfig.emails.themeList; - const currentActiveTheme = tenancy.completeConfig.emails.theme; + const themeList = tenancy.config.emails.themeList; + const currentActiveTheme = tenancy.config.emails.theme; if (!(currentActiveTheme in themeList)) { let newActiveTheme: string; if (DEFAULT_EMAIL_THEME_ID in themeList) { diff --git a/apps/backend/src/app/api/latest/internal/environment-config/current/crud.tsx b/apps/backend/src/app/api/latest/internal/environment-config/current/crud.tsx index d251a3606..aa8fda02e 100644 --- a/apps/backend/src/app/api/latest/internal/environment-config/current/crud.tsx +++ b/apps/backend/src/app/api/latest/internal/environment-config/current/crud.tsx @@ -13,7 +13,7 @@ export const environmentConfigCrudHandlers = createLazyProxy(() => createCrudHan project_id: auth.project.id, branch_id: auth.tenancy.branchId, organization_id: auth.tenancy.organization?.id, - config: auth.tenancy.completeConfig, + config: auth.tenancy.config, }; }, onUpdate: async ({ auth, data }) => { @@ -33,7 +33,7 @@ export const environmentConfigCrudHandlers = createLazyProxy(() => createCrudHan project_id: auth.project.id, branch_id: auth.tenancy.branchId, organization_id: auth.tenancy.organization?.id, - config: auth.tenancy.completeConfig, + config: auth.tenancy.config, }; }, })); diff --git a/apps/backend/src/app/api/latest/internal/projects/current/crud.tsx b/apps/backend/src/app/api/latest/internal/projects/current/crud.tsx index 3975b4093..d52f26ebe 100644 --- a/apps/backend/src/app/api/latest/internal/projects/current/crud.tsx +++ b/apps/backend/src/app/api/latest/internal/projects/current/crud.tsx @@ -1,3 +1,4 @@ +import { renderedOrganizationConfigToProjectCrud } from "@/lib/config"; import { createOrUpdateProject } from "@/lib/projects"; import { getTenancy } from "@/lib/tenancies"; import { getPrismaClientForTenancy, globalPrismaClient } from "@/prisma-client"; @@ -12,7 +13,7 @@ export const projectsCrudHandlers = createLazyProxy(() => createCrudHandlers(pro onUpdate: async ({ auth, data }) => { if ( data.config?.email_theme && - !Object.keys(auth.tenancy.completeConfig.emails.themeList).includes(data.config.email_theme) + !Object.keys(auth.tenancy.config.emails.themeList).includes(data.config.email_theme) ) { throw new StatusError(400, "Invalid email theme"); } @@ -25,13 +26,13 @@ export const projectsCrudHandlers = createLazyProxy(() => createCrudHandlers(pro const tenancy = await getTenancy(auth.tenancy.id) ?? throwErr("Tenancy not found after project update?"); // since we updated the project, we need to re-fetch the new tenancy config return { ...project, - config: tenancy.config, + config: renderedOrganizationConfigToProjectCrud(tenancy.config), }; }, onRead: async ({ auth }) => { return { ...auth.project, - config: auth.tenancy.config, + config: renderedOrganizationConfigToProjectCrud(auth.tenancy.config), }; }, onDelete: async ({ auth }) => { diff --git a/apps/backend/src/app/api/latest/internal/send-sign-in-invitation/route.tsx b/apps/backend/src/app/api/latest/internal/send-sign-in-invitation/route.tsx index 2eb7c8dcf..ca1f18d49 100644 --- a/apps/backend/src/app/api/latest/internal/send-sign-in-invitation/route.tsx +++ b/apps/backend/src/app/api/latest/internal/send-sign-in-invitation/route.tsx @@ -28,7 +28,7 @@ export const POST = createSmartRouteHandler({ }).defined(), }), async handler({ auth, body }) { - if (!validateRedirectUrl(body.callback_url, auth.tenancy.config.domains, auth.tenancy.config.allow_localhost)) { + if (!validateRedirectUrl(body.callback_url, auth.tenancy)) { throw new KnownErrors.RedirectUrlNotWhitelisted(); } diff --git a/apps/backend/src/app/api/latest/oauth-providers/crud.tsx b/apps/backend/src/app/api/latest/oauth-providers/crud.tsx index 47202bc39..591355def 100644 --- a/apps/backend/src/app/api/latest/oauth-providers/crud.tsx +++ b/apps/backend/src/app/api/latest/oauth-providers/crud.tsx @@ -108,7 +108,7 @@ async function ensureProviderExists(tenancy: Tenancy, userId: string, providerId } function getProviderConfig(tenancy: Tenancy, providerConfigId: string) { - const config = tenancy.completeConfig; + const config = tenancy.config; let providerConfig: (typeof config.auth.oauth.providers)[number] & { id: string } | undefined; for (const [providerId, provider] of Object.entries(config.auth.oauth.providers)) { if (providerId === providerConfigId) { diff --git a/apps/backend/src/app/api/latest/users/crud.tsx b/apps/backend/src/app/api/latest/users/crud.tsx index fb5e28dba..0f97a3780 100644 --- a/apps/backend/src/app/api/latest/users/crud.tsx +++ b/apps/backend/src/app/api/latest/users/crud.tsx @@ -474,7 +474,7 @@ export const usersCrudHandlers = createLazyProxy(() => createCrudHandlers(usersC primaryEmailAuthEnabled: !!data.primary_email_auth_enabled, }); - const config = auth.tenancy.completeConfig; + const config = auth.tenancy.config; const newUser = await tx.projectUser.create({ data: { @@ -642,7 +642,7 @@ export const usersCrudHandlers = createLazyProxy(() => createCrudHandlers(usersC const result = await retryTransaction(prisma, async (tx) => { await ensureUserExists(tx, { tenancyId: auth.tenancy.id, userId: params.user_id }); - const config = auth.tenancy.completeConfig; + const config = auth.tenancy.config; if (data.selected_team_id !== undefined) { if (data.selected_team_id !== null) { diff --git a/apps/backend/src/lib/ai-chat/email-template-adapter.ts b/apps/backend/src/lib/ai-chat/email-template-adapter.ts index 2de77e527..8e172905d 100644 --- a/apps/backend/src/lib/ai-chat/email-template-adapter.ts +++ b/apps/backend/src/lib/ai-chat/email-template-adapter.ts @@ -21,7 +21,7 @@ export const emailTemplateAdapter = (context: ChatAdapterContext) => ({ const CREATE_EMAIL_TEMPLATE_TOOL_DESCRIPTION = (context: ChatAdapterContext) => { - const currentEmailTemplate = context.tenancy.completeConfig.emails.templateList[context.threadId]; + const currentEmailTemplate = context.tenancy.config.emails.templateList[context.threadId]; return ` Create a new email template. diff --git a/apps/backend/src/lib/ai-chat/email-theme-adapter.ts b/apps/backend/src/lib/ai-chat/email-theme-adapter.ts index b74432f62..5f5fb75e1 100644 --- a/apps/backend/src/lib/ai-chat/email-theme-adapter.ts +++ b/apps/backend/src/lib/ai-chat/email-theme-adapter.ts @@ -18,7 +18,7 @@ export const emailThemeAdapter = (context: ChatAdapterContext) => ({ }); const CREATE_EMAIL_THEME_TOOL_DESCRIPTION = (context: ChatAdapterContext) => { - const currentEmailTheme = context.tenancy.completeConfig.emails.themeList[context.threadId].tsxSource || ""; + const currentEmailTheme = context.tenancy.config.emails.themeList[context.threadId].tsxSource || ""; return ` Create a new email theme. diff --git a/apps/backend/src/lib/permissions.tsx b/apps/backend/src/lib/permissions.tsx index 1c541785b..d1ec8dcd2 100644 --- a/apps/backend/src/lib/permissions.tsx +++ b/apps/backend/src/lib/permissions.tsx @@ -103,7 +103,7 @@ export async function grantTeamPermission( } ) { // sanity check: make sure that the permission exists - const permissionDefinition = getOrUndefined(options.tenancy.completeConfig.rbac.permissions, options.permissionId); + const permissionDefinition = getOrUndefined(options.tenancy.config.rbac.permissions, options.permissionId); if (permissionDefinition === undefined) { if (!has(teamSystemPermissionMap, options.permissionId)) { throw new KnownErrors.PermissionNotFound(options.permissionId); @@ -164,7 +164,7 @@ export async function listPermissionDefinitions( tenancy: Tenancy, } ): Promise<(TeamPermissionDefinitionsCrud["Admin"]["Read"])[]> { - const renderedConfig = options.tenancy.completeConfig; + const renderedConfig = options.tenancy.config; const permissions = typedEntries(renderedConfig.rbac.permissions).filter(([_, p]) => p.scope === options.scope); @@ -194,7 +194,7 @@ export async function createPermissionDefinition( }, } ) { - const oldConfig = options.tenancy.completeConfig; + const oldConfig = options.tenancy.config; const existingPermission = oldConfig.rbac.permissions[options.data.id] as OrganizationRenderedConfig['rbac']['permissions'][string] | undefined; const allIds = Object.keys(oldConfig.rbac.permissions) @@ -256,7 +256,7 @@ export async function updatePermissionDefinition( } ) { const newId = options.data.id ?? options.oldId; - const oldConfig = options.tenancy.completeConfig; + const oldConfig = options.tenancy.config; const existingPermission = oldConfig.rbac.permissions[options.oldId] as OrganizationRenderedConfig['rbac']['permissions'][string] | undefined; @@ -351,7 +351,7 @@ export async function deletePermissionDefinition( permissionId: string, } ) { - const oldConfig = options.tenancy.completeConfig; + const oldConfig = options.tenancy.config; const existingPermission = oldConfig.rbac.permissions[options.permissionId] as OrganizationRenderedConfig['rbac']['permissions'][string] | undefined; @@ -414,7 +414,7 @@ export async function grantProjectPermission( } ) { // sanity check: make sure that the permission exists - const permissionDefinition = getOrUndefined(options.tenancy.completeConfig.rbac.permissions, options.permissionId); + const permissionDefinition = getOrUndefined(options.tenancy.config.rbac.permissions, options.permissionId); if (permissionDefinition === undefined) { throw new KnownErrors.PermissionNotFound(options.permissionId); } else if (permissionDefinition.scope !== "project") { @@ -473,7 +473,7 @@ export async function grantDefaultProjectPermissions( userId: string, } ) { - const config = options.tenancy.completeConfig; + const config = options.tenancy.config; for (const permissionId of Object.keys(config.rbac.defaultPermissions.signUp)) { await grantProjectPermission(tx, { @@ -501,7 +501,7 @@ export async function grantDefaultTeamPermissions( type: "creator" | "member", } ) { - const config = options.tenancy.completeConfig; + const config = options.tenancy.config; const defaultPermissions = config.rbac.defaultPermissions[options.type === "creator" ? "teamCreator" : "teamMember"]; diff --git a/apps/backend/src/lib/redirect-urls.tsx b/apps/backend/src/lib/redirect-urls.tsx index aa70255d1..33acfa813 100644 --- a/apps/backend/src/lib/redirect-urls.tsx +++ b/apps/backend/src/lib/redirect-urls.tsx @@ -1,13 +1,21 @@ import { StackAssertionError, captureError } from "@stackframe/stack-shared/dist/utils/errors"; import { createUrlIfValid, isLocalhost } from "@stackframe/stack-shared/dist/utils/urls"; +import { Tenancy } from "./tenancies"; -export function validateRedirectUrl(urlOrString: string | URL, domains: { baseUrl: string }[], allowLocalhost: boolean): boolean { +export function validateRedirectUrl( + urlOrString: string | URL, + tenancy: Tenancy, +): boolean { const url = createUrlIfValid(urlOrString); if (!url) return false; - if (allowLocalhost && isLocalhost(url)) { + if (tenancy.config.domains.allowLocalhost && isLocalhost(url)) { return true; } - return domains.some((domain) => { + return Object.values(tenancy.config.domains.trustedDomains).some((domain) => { + if (!domain.baseUrl) { + return false; + } + const testUrl = url; const baseUrl = createUrlIfValid(domain.baseUrl); if (!baseUrl) { diff --git a/apps/backend/src/lib/tenancies.tsx b/apps/backend/src/lib/tenancies.tsx index bb99f0f9d..a2b877340 100644 --- a/apps/backend/src/lib/tenancies.tsx +++ b/apps/backend/src/lib/tenancies.tsx @@ -26,7 +26,7 @@ export async function tenancyPrismaToCrud(prisma: Prisma.TenancyGetPayload<{}>) const projectCrud = await getProject(prisma.projectId) ?? throwErr("Project in tenancy not found"); - const completeConfig = await rawQuery(globalPrismaClient, getRenderedOrganizationConfigQuery({ + const config = await rawQuery(globalPrismaClient, getRenderedOrganizationConfigQuery({ projectId: projectCrud.id, branchId: prisma.branchId, organizationId: prisma.organizationId, @@ -34,7 +34,7 @@ export async function tenancyPrismaToCrud(prisma: Prisma.TenancyGetPayload<{}>) return { id: prisma.id, - config: completeConfig, + config, branchId: prisma.branchId, organization: prisma.organizationId === null ? null : { // TODO actual organization type diff --git a/apps/backend/src/oauth/model.tsx b/apps/backend/src/oauth/model.tsx index 3af89542b..178331f8a 100644 --- a/apps/backend/src/oauth/model.tsx +++ b/apps/backend/src/oauth/model.tsx @@ -52,8 +52,8 @@ export class OAuthModel implements AuthorizationCodeModel { let redirectUris: string[] = []; try { - redirectUris = tenancy.config.domains.map( - ({ domain, handler_path }) => new URL(handler_path, domain).toString() + redirectUris = Object.entries(tenancy.config.domains.trustedDomains).map( + ([_, domain]) => new URL(domain.handlerPath, domain.baseUrl).toString() ); } catch (e) { captureError("get redirect uris", { @@ -64,7 +64,7 @@ export class OAuthModel implements AuthorizationCodeModel { throw e; } - if (redirectUris.length === 0 && tenancy.config.allow_localhost) { + if (redirectUris.length === 0 && tenancy.config.domains.allowLocalhost) { redirectUris.push("http://localhost"); } @@ -267,7 +267,7 @@ export class OAuthModel implements AuthorizationCodeModel { assertScopeIsValid(code.scope); const tenancy = await getSoleTenancyFromProjectBranch(...getProjectBranchFromClientId(client.id)); - if (!validateRedirectUrl(code.redirectUri, tenancy.config.domains, tenancy.config.allow_localhost)) { + if (!validateRedirectUrl(code.redirectUri, tenancy)) { throw new KnownErrors.RedirectUrlNotWhitelisted(); } @@ -353,10 +353,6 @@ export class OAuthModel implements AuthorizationCodeModel { async validateRedirectUri(redirect_uri: string, client: Client): Promise { const tenancy = await getSoleTenancyFromProjectBranch(...getProjectBranchFromClientId(client.id)); - return validateRedirectUrl( - redirect_uri, - tenancy.config.domains, - tenancy.config.allow_localhost, - ); + return validateRedirectUrl(redirect_uri, tenancy); } } diff --git a/apps/backend/src/prisma-client.tsx b/apps/backend/src/prisma-client.tsx index 13218a24e..7933689e4 100644 --- a/apps/backend/src/prisma-client.tsx +++ b/apps/backend/src/prisma-client.tsx @@ -48,11 +48,11 @@ function getSchemaFromConnectionString(connectionString: string) { } export async function getPrismaClientForTenancy(tenancy: Tenancy) { - return await getPrismaClientForSourceOfTruth(tenancy.completeConfig.sourceOfTruth, tenancy.branchId); + return await getPrismaClientForSourceOfTruth(tenancy.config.sourceOfTruth, tenancy.branchId); } export function getPrismaSchemaForTenancy(tenancy: Tenancy) { - return getPrismaSchemaForSourceOfTruth(tenancy.completeConfig.sourceOfTruth, tenancy.branchId); + return getPrismaSchemaForSourceOfTruth(tenancy.config.sourceOfTruth, tenancy.branchId); } function getPostgresPrismaClient(connectionString: string) { diff --git a/apps/backend/src/route-handlers/verification-code-handler.tsx b/apps/backend/src/route-handlers/verification-code-handler.tsx index a1e26b264..cd01416d1 100644 --- a/apps/backend/src/route-handlers/verification-code-handler.tsx +++ b/apps/backend/src/route-handlers/verification-code-handler.tsx @@ -228,11 +228,7 @@ export function createVerificationCodeHandler< }); const tenancy = await getSoleTenancyFromProjectBranch(project.id, branchId); - if (callbackUrl !== undefined && !validateRedirectUrl( - callbackUrl, - tenancy.config.domains, - tenancy.config.allow_localhost, - )) { + if (callbackUrl !== undefined && !validateRedirectUrl(callbackUrl, tenancy)) { throw new KnownErrors.RedirectUrlNotWhitelisted(); }