diff --git a/apps/backend/src/app/api/latest/webhooks/svix-token/route.tsx b/apps/backend/src/app/api/latest/webhooks/svix-token/route.tsx index 3433cac4c..f07e2459f 100644 --- a/apps/backend/src/app/api/latest/webhooks/svix-token/route.tsx +++ b/apps/backend/src/app/api/latest/webhooks/svix-token/route.tsx @@ -2,15 +2,20 @@ import { getSvixClient } from "@/lib/webhooks"; import { createCrudHandlers } from "@/route-handlers/crud-handler"; import { svixTokenCrud } from "@stackframe/stack-shared/dist/interface/crud/svix-token"; import { yupObject } from "@stackframe/stack-shared/dist/schema-fields"; +import { getEnvVariable } from "@stackframe/stack-shared/dist/utils/env"; import { createLazyProxy } from "@stackframe/stack-shared/dist/utils/proxies"; +const svixServerUrl = getEnvVariable("STACK_SVIX_SERVER_URL", ""); + const appPortalCrudHandlers = createLazyProxy(() => createCrudHandlers(svixTokenCrud, { paramsSchema: yupObject({}), onCreate: async ({ auth }) => { const svix = getSvixClient(); await svix.application.getOrCreate({ uid: auth.project.id, name: auth.project.id }); const result = await svix.authentication.appPortalAccess(auth.project.id, {}); - return { token: result.token }; + // svix embedded app portal is only available on hosted svix. + const url = svixServerUrl ? undefined : result.url; + return { token: result.token, url }; }, })); diff --git a/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/webhooks/page-client.tsx b/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/webhooks/page-client.tsx index b34fe2187..d0dfe5128 100644 --- a/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/webhooks/page-client.tsx +++ b/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/webhooks/page-client.tsx @@ -17,6 +17,56 @@ import { PageLayout } from "../page-layout"; import { useAdminApp } from "../use-admin-app"; import { getSvixResult } from "./utils"; import { runAsynchronously } from "@stackframe/stack-shared/dist/utils/promises"; +import { useTheme } from "next-themes"; +import { AppPortal } from "svix-react"; +import "svix-react/style.css"; + + +export default function PageClient() { + const stackAdminApp = useAdminApp(); + const svixToken = stackAdminApp.useSvixToken(); + const { resolvedTheme } = useTheme(); + const [updateCounter, setUpdateCounter] = useState(0); + const [testDialogEndpoint, setTestDialogEndpoint] = useState(null); + + return ( + + + {svixToken.url ? ( +
+ +
+ ) : ( + + setUpdateCounter(x => x + 1)} + onTestRequested={(endpoint) => setTestDialogEndpoint(endpoint)} + /> + {testDialogEndpoint && ( + { + if (!open) { + setTestDialogEndpoint(null); + } + }} + /> + )} + + )} +
+
+ ); +} type Endpoint = { id: string, @@ -157,7 +207,7 @@ function CreateDialog(props: { ); } -export function EndpointEditDialog(props: { +function EndpointEditDialog(props: { open: boolean, onClose: () => void, endpoint: Endpoint, @@ -369,42 +419,3 @@ function Endpoints(props: { updateFn: () => void, onTestRequested: (endpoint: En ); } } - -export default function PageClient() { - const stackAdminApp = useAdminApp(); - const svixToken = stackAdminApp.useSvixToken(); - const [updateCounter, setUpdateCounter] = useState(0); - const [testDialogEndpoint, setTestDialogEndpoint] = useState(null); - - return ( - - - - setUpdateCounter(x => x + 1)} - onTestRequested={(endpoint) => setTestDialogEndpoint(endpoint)} - /> - {testDialogEndpoint && ( - { - if (!open) { - setTestDialogEndpoint(null); - } - }} - /> - )} - - - - ); -} diff --git a/packages/stack-shared/src/interface/crud/svix-token.ts b/packages/stack-shared/src/interface/crud/svix-token.ts index fbdff4e84..c113bfbb6 100644 --- a/packages/stack-shared/src/interface/crud/svix-token.ts +++ b/packages/stack-shared/src/interface/crud/svix-token.ts @@ -3,6 +3,7 @@ import { yupObject, yupString } from "../../schema-fields"; export const svixTokenAdminReadSchema = yupObject({ token: yupString().defined(), + url: yupString().optional(), }).defined(); export const svixTokenAdminCreateSchema = yupObject({}).defined(); diff --git a/packages/template/src/lib/stack-app/apps/implementations/admin-app-impl.ts b/packages/template/src/lib/stack-app/apps/implementations/admin-app-impl.ts index e5554c8a0..4c49dc285 100644 --- a/packages/template/src/lib/stack-app/apps/implementations/admin-app-impl.ts +++ b/packages/template/src/lib/stack-app/apps/implementations/admin-app-impl.ts @@ -416,9 +416,9 @@ export class _StackAdminAppImplIncomplete, deleteProjectPermissionDefinition(permissionId: string): Promise, - useSvixToken(): string, // THIS_LINE_PLATFORM react-like + useSvixToken(): { token: string, url: string | undefined }, // THIS_LINE_PLATFORM react-like sendTestEmail(options: { recipientEmail: string,