feat(examples/hosted-checkout-demo): zero-supabase local dev mode - #186
feat(examples/hosted-checkout-demo): zero-supabase local dev mode#186dhruv-sanan wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit bcefa95. Configure here.
| */ | ||
| export const proxy = createSupabaseAuthMiddleware({ | ||
| publicRoutes: [], | ||
| publicRoutes: ['/api/create-checkout-session', '/api/create-customer-session'], |
There was a problem hiding this comment.
Public routes allow x-user-id header forgery in production
High Severity
Making /api/create-checkout-session and /api/create-customer-session unconditionally public (even in production) allows unauthenticated attackers to forge the x-user-id header. The middleware for public routes copies all incoming headers via new Headers(req.headers) but only sets x-user-id if a valid token is present — it never clears a client-supplied one. Downstream, getAuthenticatedUserCore trusts the x-user-id header unconditionally. An attacker can create checkout or customer sessions impersonating any user by simply including x-user-id: victim-id in the request.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit bcefa95. Configure here.
| // meaning no real Supabase project is wired up. | ||
| const isDevMode = | ||
| !process.env.NEXT_PUBLIC_SUPABASE_URL || | ||
| process.env.NEXT_PUBLIC_SUPABASE_URL.includes('placeholder') |
There was a problem hiding this comment.
Inconsistent dev-mode detection between client and server
Medium Severity
The isDevMode flag in route.ts only checks NEXT_PUBLIC_SUPABASE_URL, while isSupabaseConfigured in ClientLayout.tsx additionally checks NEXT_PUBLIC_SUPABASE_ANON_KEY. When the URL is real but the anon key is 'placeholder', the client renders in dev mode (no auth gate, no token sent) but the server takes the production path expecting authentication. This mismatch causes the checkout flow to silently fail with a 401.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit bcefa95. Configure here.
|
Thanks for this — the zero-supabase dev mode is a nice quality-of-life improvement for trying the demo. The branch is updated and CI is green, but I'm holding the merge because Bugbot flagged two issues that need addressing first (and since this example is something merchants copy-paste, the auth one matters): 1. High —
|


Description
Running
hosted-checkout-democurrently requires a Supabase account, ~20 minutes of project setup, and you still get a silent 401 on every API call with no hint why. This PR adds a zero-config dev mode: set placeholder Supabase env vars and the example works end-to-end with just a SolvaPay test key.Developers with a real Supabase project are unaffected — every production code path is identical to upstream. The changes branch on a single
isSupabaseConfigured/isDevModeflag derived from env vars.Type of Change
Changes Made
proxy.ts: added/api/create-checkout-sessionand/api/create-customer-sessiontopublicRoutes— middleware was blocking both routes entirely when no Supabase session existed; authenticated requests still havex-user-idset as beforeProviders.tsx: extended the Supabase adapter guard to also catch placeholder string values (e.g.https://placeholder.supabase.co), not just missing env vars — previously a dev copyingenv.exampleverbatim would silently initialise a broken adapterClientLayout.tsx: addedisSupabaseConfiguredflag; when false (no real Supabase project), skip the auth gate and render directly; when true, the originaluseEffect+ login screen behavior is preserved exactlyroute.ts: addedisDevModepath that uses a stub customer when nox-user-idheader is present; production path delegates tocreateCheckoutSessionfrom@solvapay/nextunchangedChangeset
Testing
pnpm test— unit tests passpnpm build— full monorepo build passesTo reproduce the dev-mode flow: