-
Notifications
You must be signed in to change notification settings - Fork 500
svix embedded portal #1007
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
svix embedded portal #1007
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Note Other AI code review bot(s) detectedCodeRabbit 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. WalkthroughThis pull request introduces support for optional Svix server URL configuration via environment variables. The webhook token endpoint now retrieves Changes
Sequence DiagramsequenceDiagram
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
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this 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
tokenandurl(optional) from the svix-token endpoint - Dashboard conditionally renders
AppPortalcomponent whenurlis provided, otherwise falls back to existingSvixProviderimplementation - The
urlis only returned when using hosted Svix (determined by absence ofSTACK_SVIX_SERVER_URLenv var)
Issues Found:
- URL from Svix is passed directly to
AppPortalcomponent 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
5 files reviewed, 1 comment
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/webhooks/page-client.tsx
Show resolved
Hide resolved
There was a problem hiding this 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
📒 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)
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/webhooks/page-client.tsx
Show resolved
Hide resolved
There was a problem hiding this 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:
- Navigate to a webhook endpoint page in the dashboard
- The
svixTokenvariable contains{ token: "abc123", url: undefined } - Line 114 executes:
return svixToken + ''; - 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.
https://www.loom.com/share/ade557d34b674ecb9ae1d703b5332c9d
Summary by CodeRabbit
New Features
Refactor
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.
AppPortalwhensvixToken.urlis provided; otherwise fall back toSvixProviderwith token.next-themes) for portaldarkMode; importsvix-reactstyles.POST /api/latest/webhooks/svix-tokento return{ token, url? }, derivingurlonly when noSTACK_SVIX_SERVER_URLis set.svixTokenAdminReadSchemato include optionalurl.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.