Skip to content

Conversation

@BilalG1
Copy link
Contributor

@BilalG1 BilalG1 commented Nov 8, 2025

https://www.loom.com/share/ade557d34b674ecb9ae1d703b5332c9d

Summary by CodeRabbit

  • New Features

    • Added support for inline webhook configuration portal rendering when available
    • Enhanced webhooks page with improved theming support
  • Refactor

    • Updated webhook token API to return structured data including optional server URL alongside token

Note

Enables embedded Svix portal on the Webhooks page when available, updating the token API and shared types to return an optional portal URL and wiring it through the admin app.

  • Frontend (Dashboard Webhooks page):
    • Conditionally render Svix AppPortal when svixToken.url is provided; otherwise fall back to SvixProvider with token.
    • Integrate theme support (next-themes) for portal darkMode; import svix-react styles.
  • Backend (API):
    • Update POST /api/latest/webhooks/svix-token to return { token, url? }, deriving url only when no STACK_SVIX_SERVER_URL is set.
  • Shared Types/SDK:
    • Extend svixTokenAdminReadSchema to include optional url.
    • Change admin app useSvixToken() to return { token, url } and propagate through implementation.

Written by Cursor Bugbot for commit 9f5dc52. This will update automatically on new commits. Configure here.

@vercel
Copy link

vercel bot commented Nov 8, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
stack-backend Ready Ready Preview Comment Nov 11, 2025 11:40am
stack-dashboard Ready Ready Preview Comment Nov 11, 2025 11:40am
stack-demo Ready Ready Preview Comment Nov 11, 2025 11:40am
stack-docs Ready Ready Preview Comment Nov 11, 2025 11:40am

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 8, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

This pull request introduces support for optional Svix server URL configuration via environment variables. The webhook token endpoint now retrieves STACK_SVIX_SERVER_URL and returns both token and URL in its payload. The admin SDK's useSvixToken() method signature is updated to return an object containing token and URL. The dashboard webhooks page is modified to conditionally render an AppPortal when a URL is available, or fall back to the traditional SvixProvider approach.

Changes

Cohort / File(s) Summary
Backend Webhook Token Endpoint
apps/backend/src/app/api/latest/webhooks/svix-token/route.tsx
Added environment variable support for STACK_SVIX_SERVER_URL. URL handling logic now conditionally sets URL to undefined if server URL is configured, otherwise uses result.url. Extended response payload to return { token, url } instead of only token. Exposed POST handler as public export.
Schema Updates
packages/stack-shared/src/interface/crud/svix-token.ts
Added optional url?: string field to svixTokenAdminReadSchema to accommodate the extended token response structure.
Admin SDK Interface & Implementation
packages/template/src/lib/stack-app/apps/interfaces/admin-app.ts, packages/template/src/lib/stack-app/apps/implementations/admin-app-impl.ts
Updated useSvixToken() return type from string to { token: string, url: string | undefined }. Implementation now retrieves both token and URL from cache.
Dashboard Webhooks Page
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/webhooks/page-client.tsx
Introduced conditional rendering: if svixToken.url exists, renders AppPortal with theme-based dark mode; otherwise wraps endpoints UI in SvixProvider. Added theme hook and styling imports. Changed EndpointEditDialog from exported to private. Maintained existing endpoint flows (Endpoints, CreateDialog, TestEndpointDialog).

Sequence Diagram

sequenceDiagram
    participant Dashboard as Dashboard UI
    participant Backend as Backend API
    participant Env as Environment
    participant Svix as Svix Service

    Dashboard->>Backend: GET /webhooks/svix-token
    Backend->>Env: Check STACK_SVIX_SERVER_URL
    
    alt Server URL Configured
        Env-->>Backend: STACK_SVIX_SERVER_URL set
        Backend->>Svix: Generate token
        Svix-->>Backend: { token }
        Backend-->>Dashboard: { token, url: undefined }
        Dashboard->>Dashboard: Render AppPortal
    else No Server URL
        Env-->>Backend: STACK_SVIX_SERVER_URL not set
        Backend->>Svix: Generate token with URL
        Svix-->>Backend: { token, url: "https://..." }
        Backend-->>Dashboard: { token, url: "https://..." }
        Dashboard->>Dashboard: Render SvixProvider
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • useSvixToken() breaking change: This is a public API signature change that affects all consumers of the admin SDK. Verify all call sites are updated to handle the new object return type.
  • Conditional rendering logic in page-client.tsx: The AppPortal vs SvixProvider branching logic needs careful testing to ensure both paths function correctly.
  • Environment variable handling: Review the URL handling logic in route.tsx to ensure the conditional behavior (setting URL to undefined when server URL is configured) is intentional and correct.
  • Cross-layer consistency: Ensure schema validation, backend response, SDK interface, and UI consumption are all aligned with the new data structure.

Possibly related PRs

  • webhook testing #964: Modifies the same webhooks page-client.tsx file and related webhook UI components (PageClient, TestEndpointDialog, endpoint flows).

Suggested reviewers

  • N2D4

Poem

🐰 A token hops through the webhooks today,
With URLs tagging along on the way,
AppPortal renders when URLs appear,
Or SvixProvider keeps the old way near,
Configuration flows in the environment air! 🌿

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Description check ❓ Inconclusive PR description relies primarily on auto-generated Cursor summary rather than author-written details, making intent assessment difficult. Add explicit author description explaining the motivation, implementation details, and testing performed for this Svix embedded portal feature.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title 'svix embedded portal' is directly related to the main changes, which introduce embedded portal rendering via AppPortal and svixToken.url support.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch svix-iframe

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Greptile Overview

Greptile Summary

This PR adds support for Svix's embedded app portal, allowing the dashboard to conditionally render either the embedded portal UI or the existing custom endpoint management interface based on whether a self-hosted or cloud-hosted Svix instance is configured.

Key Changes:

  • Backend now returns both token and url (optional) from the svix-token endpoint
  • Dashboard conditionally renders AppPortal component when url is provided, otherwise falls back to existing SvixProvider implementation
  • The url is only returned when using hosted Svix (determined by absence of STACK_SVIX_SERVER_URL env var)

Issues Found:

  • URL from Svix is passed directly to AppPortal component without validation, which could pose a security risk if the Svix API were compromised or misconfigured

Confidence Score: 3/5

  • This PR is mostly safe but has a URL validation issue that should be addressed before merging
  • The implementation is straightforward and well-structured, but fails to validate the URL from the Svix API before passing it to a client-side component. While Svix is a trusted third-party service, the custom instructions mandate URL validation for redirect/navigation purposes to prevent potential open redirect vulnerabilities.
  • Pay close attention to apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/webhooks/page-client.tsx - the URL validation issue should be resolved

Important Files Changed

File Analysis

Filename Score Overview
apps/backend/src/app/api/latest/webhooks/svix-token/route.tsx 4/5 Added support for Svix embedded portal by conditionally returning URL based on server configuration
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/webhooks/page-client.tsx 2/5 Integrated Svix embedded portal with conditional rendering - URL from backend needs validation before use

Sequence Diagram

sequenceDiagram
    participant Client as Dashboard Client
    participant AdminApp as Stack Admin App
    participant Backend as Backend API
    participant Svix as Svix Service
    participant Portal as Svix Embedded Portal

    Client->>AdminApp: useSvixToken()
    AdminApp->>Backend: POST /api/latest/webhooks/svix-token
    Backend->>Svix: getOrCreate(projectId)
    Svix-->>Backend: Application created/retrieved
    Backend->>Svix: appPortalAccess(projectId)
    Svix-->>Backend: {token, url}
    Backend->>Backend: Check STACK_SVIX_SERVER_URL env
    alt Self-hosted Svix
        Backend-->>AdminApp: {token, url: undefined}
        AdminApp-->>Client: {token, url: undefined}
        Client->>Client: Render SvixProvider + Endpoints
    else Hosted Svix
        Backend-->>AdminApp: {token, url}
        AdminApp-->>Client: {token, url}
        Client->>Portal: <AppPortal url={url} />
        Portal-->>Client: Embedded portal rendered
    end
Loading

5 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a85932d and e7256cf.

📒 Files selected for processing (5)
  • apps/backend/src/app/api/latest/webhooks/svix-token/route.tsx (1 hunks)
  • apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/webhooks/page-client.tsx (2 hunks)
  • packages/stack-shared/src/interface/crud/svix-token.ts (1 hunks)
  • packages/template/src/lib/stack-app/apps/implementations/admin-app-impl.ts (1 hunks)
  • packages/template/src/lib/stack-app/apps/interfaces/admin-app.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (4)
packages/stack-shared/src/interface/crud/svix-token.ts (1)
packages/stack-shared/src/schema-fields.ts (1)
  • yupString (187-190)
packages/template/src/lib/stack-app/apps/implementations/admin-app-impl.ts (1)
packages/template/src/lib/stack-app/apps/implementations/common.ts (1)
  • useAsyncCache (162-213)
apps/backend/src/app/api/latest/webhooks/svix-token/route.tsx (2)
packages/stack-shared/src/utils/env.tsx (1)
  • getEnvVariable (16-58)
apps/backend/src/lib/webhooks.tsx (1)
  • getSvixClient (13-18)
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/webhooks/page-client.tsx (4)
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/webhooks/[endpointId]/page-client.tsx (1)
  • PageClient (107-129)
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/use-admin-app.tsx (1)
  • useAdminApp (29-44)
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/app-enabled-guard.tsx (1)
  • AppEnabledGuard (11-37)
apps/dashboard/src/lib/env.tsx (1)
  • getPublicEnvVar (69-79)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
  • GitHub Check: Vercel Agent Review
  • GitHub Check: lint_and_build (latest)
  • GitHub Check: restart-dev-and-test-with-custom-base-port
  • GitHub Check: build (22.x)
  • GitHub Check: build (22.x)
  • GitHub Check: setup-tests
  • GitHub Check: all-good
  • GitHub Check: build (22.x)
  • GitHub Check: restart-dev-and-test
  • GitHub Check: docker
  • GitHub Check: check_prisma_migrations (22.x)

@BilalG1 BilalG1 requested a review from N2D4 November 8, 2025 03:07
@BilalG1 BilalG1 assigned N2D4 and unassigned BilalG1 Nov 8, 2025
@github-actions github-actions bot assigned BilalG1 and unassigned N2D4 Nov 10, 2025
Copy link

@vercel vercel bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional Suggestion:

The endpoint page code attempts to concatenate svixToken with an empty string, but useSvixToken() now returns an object { token: string, url: string | undefined } instead of a string, causing it to convert to "[object Object]" and break authentication.

View Details
📝 Patch Details
diff --git a/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/webhooks/[endpointId]/page-client.tsx b/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/webhooks/[endpointId]/page-client.tsx
index ce2a97ee..1586c5ab 100644
--- a/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/webhooks/[endpointId]/page-client.tsx
+++ b/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/webhooks/[endpointId]/page-client.tsx
@@ -111,7 +111,7 @@ export default function PageClient(props: { endpointId: string }) {
 
   // This is a hack to make sure svix hooks update when content changes
   const svixTokenUpdated = useMemo(() => {
-    return svixToken + '';
+    return svixToken.token;
   // eslint-disable-next-line react-hooks/exhaustive-deps
   }, [svixToken, updateCounter]);
 

Analysis

Object concatenation in webhook endpoint page breaks authentication

What fails: The PageClient component in apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/webhooks/[endpointId]/page-client.tsx at line 114 concatenates the useSvixToken() object result with an empty string, producing "[object Object]" instead of the actual token value.

How to reproduce:

  1. Navigate to a webhook endpoint page in the dashboard
  2. The svixToken variable contains { token: "abc123", url: undefined }
  3. Line 114 executes: return svixToken + '';
  4. Result: "[object Object]" passed to SvixProvider

Result: SvixProvider receives "[object Object]" as token, causing authentication failure. Expected: Should receive the actual token string from svixToken.token.

Evidence: The useSvixToken() hook returns { token: string, url: string | undefined } per the interface definition in packages/template/src/lib/stack-app/apps/interfaces/admin-app.ts:52, but the endpoint page treats it as a string. Other webhook pages correctly use svixToken.token.

@BilalG1 BilalG1 merged commit e843a2b into dev Nov 11, 2025
22 checks passed
@BilalG1 BilalG1 deleted the svix-iframe branch November 11, 2025 19:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants