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 ee03123ff..2fd33843f 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 @@ -2,6 +2,7 @@ import { overrideEnvironmentConfigOverride } from "@/lib/config"; import { DEFAULT_EMAIL_THEMES } from "@/lib/email-themes"; 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 { adaptSchema, yupArray, yupNumber, yupObject, yupString } from "@stackframe/stack-shared/dist/schema-fields"; import { generateUuid } from "@stackframe/stack-shared/dist/utils/uuids"; @@ -68,7 +69,26 @@ export const GET = createSmartRouteHandler({ }).defined(), }), async handler({ auth: { tenancy } }) { - const themes = Object.entries(tenancy.completeConfig.emails.themeList).map(([id, theme]) => ({ + const themeList = tenancy.completeConfig.emails.themeList; + const currentActiveTheme = tenancy.completeConfig.emails.theme; + if (!(currentActiveTheme in themeList)) { + let newActiveTheme: string; + if (DEFAULT_EMAIL_THEME_ID in themeList) { + newActiveTheme = DEFAULT_EMAIL_THEME_ID; + } else { + newActiveTheme = Object.keys(themeList)[0]; + } + await overrideEnvironmentConfigOverride({ + tx: globalPrismaClient, + projectId: tenancy.project.id, + branchId: tenancy.branchId, + environmentConfigOverrideOverride: { + "emails.theme": newActiveTheme, + }, + }); + } + + const themes = Object.entries(themeList).map(([id, theme]) => ({ id, display_name: theme.displayName, })); diff --git a/apps/e2e/tests/backend/endpoints/api/v1/email-themes.test.ts b/apps/e2e/tests/backend/endpoints/api/v1/email-themes.test.ts index 0ebde1e08..a00632976 100644 --- a/apps/e2e/tests/backend/endpoints/api/v1/email-themes.test.ts +++ b/apps/e2e/tests/backend/endpoints/api/v1/email-themes.test.ts @@ -3,7 +3,7 @@ import { describe } from "vitest"; import { it } from "../../../../helpers"; import { niceBackendFetch, Project } from "../../../backend-helpers"; -const validThemeId = "1df07ae6-abf3-4a40-83a5-a1a2cbe336ac"; // default-light theme +const validThemeId = "1df07ae6-abf3-4a40-83a5-a1a2cbe336ac"; // Default Light theme const invalidThemeId = randomUUID(); const validTsxSource = `import { Html, Tailwind, Body } from '@react-email/components'; @@ -89,7 +89,7 @@ describe("get email theme", () => { NiceResponse { "status": 200, "body": { - "display_name": "default-light", + "display_name": "Default Light", "tsx_source": deindent\` import { Html, Tailwind, Body } from '@react-email/components'; function EmailTheme({ children }: { children: React.ReactNode }) { @@ -188,7 +188,7 @@ describe("update email theme", () => { NiceResponse { "status": 200, "body": { - "display_name": "default-light", + "display_name": "Default Light", "rendered_html": deindent\`
Mock api key detected, themeComponent: import { Html, Tailwind, Body } from '@react-email/components'; function EmailTheme({ children }: { children: React.ReactNode }) { @@ -240,7 +240,7 @@ describe("update email theme", () => { NiceResponse { "status": 200, "body": { - "display_name": "default-light", + "display_name": "Default Light", "tsx_source": deindent\` import { Html, Tailwind, Body } from '@react-email/components'; function EmailTheme({ children }: { children: React.ReactNode }) { @@ -284,11 +284,11 @@ describe("create email theme", () => { "body": { "themes": [ { - "display_name": "default-light", + "display_name": "Default Light", "id": "", }, { - "display_name": "default-dark", + "display_name": "Default Dark", "id": "", }, ], @@ -304,7 +304,7 @@ describe("create email theme", () => { method: "POST", accessType: "admin", body: { - display_name: "default-light", + display_name: "Default Light", }, } ); diff --git a/packages/stack-shared/src/helpers/emails.ts b/packages/stack-shared/src/helpers/emails.ts index c20ccb6f4..652d14ac1 100644 --- a/packages/stack-shared/src/helpers/emails.ts +++ b/packages/stack-shared/src/helpers/emails.ts @@ -33,11 +33,11 @@ export const DEFAULT_EMAIL_THEME_ID = "1df07ae6-abf3-4a40-83a5-a1a2cbe336ac"; export const DEFAULT_EMAIL_THEMES = { [DEFAULT_EMAIL_THEME_ID]: { - displayName: 'default-light', + displayName: 'Default Light', tsxSource: LightEmailTheme, }, "a0172b5d-cff0-463b-83bb-85124697373a": { - displayName: 'default-dark', + displayName: 'Default Dark', tsxSource: DarkEmailTheme, }, }; diff --git a/packages/stack-shared/src/schema-fields.ts b/packages/stack-shared/src/schema-fields.ts index 969a1e139..5c0d730b4 100644 --- a/packages/stack-shared/src/schema-fields.ts +++ b/packages/stack-shared/src/schema-fields.ts @@ -368,7 +368,7 @@ export const emailThemeSchema = yupString().meta({ openapiField: { description: export const emailThemeListSchema = yupRecord( yupString().uuid(), yupObject({ - displayName: yupString().meta({ openapiField: { description: 'Email theme name', exampleValue: 'default-light' } }).defined(), + displayName: yupString().meta({ openapiField: { description: 'Email theme name', exampleValue: 'Default Light' } }).defined(), tsxSource: yupString().meta({ openapiField: { description: 'Email theme source code tsx component' } }).defined(), }) ).meta({ openapiField: { description: 'Record of email theme IDs to their display name and source code' } });