Skip to content

fix: production CORS 401, guarded bindSupabase, prod WISP_SECRET#62

Merged
creatorcluster merged 2 commits into
creatorcluster:mainfrom
Coder-soft:main
Jul 6, 2026
Merged

fix: production CORS 401, guarded bindSupabase, prod WISP_SECRET#62
creatorcluster merged 2 commits into
creatorcluster:mainfrom
Coder-soft:main

Conversation

@Coder-soft

@Coder-soft Coder-soft commented Jul 6, 2026

Copy link
Copy Markdown
  • Add CORS headers to 401 response in /ingest so browser shows real error instead of CORS failure
  • Guard bindSupabase in try/catch so it doesn't crash when wisp isn't initialized (e.g. VITE_CONVEX_URL not set)
  • Set WISP_SECRET on production convex deployment precious-crocodile-678
  • Deployed backend code to production deployment

Summary by CodeRabbit

  • Bug Fixes
    • Improved the /ingest endpoint’s unauthorized response so it now includes CORS headers, helping clients handle failed requests more consistently.
    • Made the app more resilient when analytics integration is unavailable, preventing startup/runtime issues and keeping authentication flows stable.

- Add CORS headers to 401 response in /ingest so browser shows real error instead of CORS failure
- Guard bindSupabase in try/catch so it doesn't crash when wisp isn't initialized (e.g. VITE_CONVEX_URL not set)
- Set WISP_SECRET on production convex deployment precious-crocodile-678
- Deployed backend code to production deployment
@vercel

vercel Bot commented Jul 6, 2026

Copy link
Copy Markdown

@Coder-soft is attempting to deploy a commit to the yamura3's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@Coder-soft, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 50 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 07d7075f-b370-4599-876a-09b7841dead6

📥 Commits

Reviewing files that changed from the base of the PR and between 1feb817 and d93525f.

📒 Files selected for processing (2)
  • convex/dashboard.ts
  • convex/schema.ts
📝 Walkthrough

Walkthrough

This PR contains two independent small fixes: the ingest HTTP endpoint's unauthorized response now includes CORS headers, and the AuthProvider component wraps its Wisp/Supabase analytics binding in a try/catch to fail gracefully when Wisp isn't initialized.

Changes

Ingest Endpoint CORS Fix

Layer / File(s) Summary
Add CORS headers to unauthorized response
convex/http.ts
The 401 unauthorized response now includes Access-Control-Allow-Origin, allowed methods, and allowed headers instead of a plain status-only response.

AuthProvider Wisp Binding Safety

Layer / File(s) Summary
Guard bindSupabase call with try/catch
src/providers/AuthProvider.tsx
Introduces a no-op default unsubscribeWisp, wraps bindSupabase in try/catch, and only overwrites the no-op on success, so cleanup always calls a safe function.

Estimated code review effort: 1 (Trivial) | ~5 minutes

Poem

Two tiny burrows, dug with care,
CORS headers now floating in the air,
Wisp may fail, but no more crash—
A safe no-op catches the dash.
Hop, hop, ship it — clean code, no scare! 🐇

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main production fixes: CORS for 401s, guarded bindSupabase, and setting the WISP secret.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@greptile-apps

greptile-apps Bot commented Jul 6, 2026

Copy link
Copy Markdown

Greptile Summary

This PR fixes two production issues: CORS headers are now included on the /ingest 401 response so browsers surface the real auth error rather than a generic CORS failure, and bindSupabase is guarded with a try/catch so the app doesn't crash when the Wisp analytics library is uninitialized.

  • convex/http.ts: Adds Access-Control-Allow-Origin: * (plus two redundant headers) to the 401 Unauthorized response; the success and preflight paths were already returning CORS headers correctly.
  • src/providers/AuthProvider.tsx: Wraps bindSupabase(supabase) in a try/catch with a no-op fallback unsubscribe function, preventing startup crashes when VITE_CONVEX_URL is absent; the catch is empty so non-initialization errors are silently dropped.

Confidence Score: 4/5

Both changes are small, targeted fixes with no impact on core auth or data paths; the main risk is the empty catch in AuthProvider silently hiding future Wisp errors.

The CORS header addition is straightforward and correct. The try/catch guard in AuthProvider is reasonable defensive code, but the completely silent catch means any real error from bindSupabase — not just uninitialized Wisp — will vanish without a trace, making future debugging harder. Neither change affects authentication, data integrity, or routing logic.

src/providers/AuthProvider.tsx — the empty catch block deserves a console.warn so unexpected bindSupabase failures don't disappear silently.

Important Files Changed

Filename Overview
convex/http.ts Adds CORS headers to the 401 Unauthorized response so browsers can read the actual error body; functionally correct but includes two redundant response headers (Allow-Methods, Allow-Headers) that are only meaningful on preflight responses.
src/providers/AuthProvider.tsx Wraps bindSupabase in try/catch to prevent crashes when Wisp is uninitialized; the empty catch swallows all errors silently, which could hide real failures from the Wisp library.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant Browser
    participant ConvexHTTP as Convex /ingest
    participant WispLib as Wisp (bindSupabase)

    Browser->>ConvexHTTP: OPTIONS /ingest (preflight)
    ConvexHTTP-->>Browser: 200 + CORS headers (pre-existing)

    Browser->>ConvexHTTP: POST /ingest (missing/bad x-wisp-token)
    alt Before this PR
        ConvexHTTP-->>Browser: 401 (no CORS headers)
        Browser--xBrowser: CORS error masks the 401
    else After this PR
        ConvexHTTP-->>Browser: 401 + Access-Control-Allow-Origin
        Browser-->>Browser: Reads real Unauthorized error body
    end

    Browser->>ConvexHTTP: POST /ingest (valid x-wisp-token)
    ConvexHTTP-->>Browser: 204 + Access-Control-Allow-Origin

    note over WispLib: AuthProvider mount
    alt Wisp initialized
        WispLib-->>WispLib: bindSupabase(supabase) succeeds
    else Wisp not initialized
        WispLib--xWispLib: throws
        WispLib-->>WispLib: "catch → unsubscribeWisp = no-op"
    end
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant Browser
    participant ConvexHTTP as Convex /ingest
    participant WispLib as Wisp (bindSupabase)

    Browser->>ConvexHTTP: OPTIONS /ingest (preflight)
    ConvexHTTP-->>Browser: 200 + CORS headers (pre-existing)

    Browser->>ConvexHTTP: POST /ingest (missing/bad x-wisp-token)
    alt Before this PR
        ConvexHTTP-->>Browser: 401 (no CORS headers)
        Browser--xBrowser: CORS error masks the 401
    else After this PR
        ConvexHTTP-->>Browser: 401 + Access-Control-Allow-Origin
        Browser-->>Browser: Reads real Unauthorized error body
    end

    Browser->>ConvexHTTP: POST /ingest (valid x-wisp-token)
    ConvexHTTP-->>Browser: 204 + Access-Control-Allow-Origin

    note over WispLib: AuthProvider mount
    alt Wisp initialized
        WispLib-->>WispLib: bindSupabase(supabase) succeeds
    else Wisp not initialized
        WispLib--xWispLib: throws
        WispLib-->>WispLib: "catch → unsubscribeWisp = no-op"
    end
Loading

Reviews (1): Last reviewed commit: "fix: production CORS 401, guarded bindSu..." | Re-trigger Greptile

Comment on lines +17 to +18
} catch {
// wisp not initialized — skip analytics identity binding

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Silent catch masks real bindSupabase errors

The empty catch block swallows any error thrown by bindSupabase, not just the "wisp not initialized" case. If the library is initialized but throws for a different reason (e.g., incompatible Supabase client version, internal assertion), the failure would disappear silently with no way to diagnose it. At minimum, logging the caught error as a warning preserves observability without breaking the fallback behaviour.

Comment thread convex/http.ts
Comment on lines +22 to +24
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "POST, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type, x-wisp-token",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Redundant CORS response headers on the 401 reply

Access-Control-Allow-Methods and Access-Control-Allow-Headers are only inspected by browsers on preflight (OPTIONS) responses; they have no effect on the actual POST 401 reply. Only Access-Control-Allow-Origin is needed here to let the browser read the response body. The extra headers are harmless, but they're dead weight on every unauthorized request.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/providers/AuthProvider.tsx (1)

13-19: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

LGTM — correctly guards bindSupabase and keeps cleanup safe.

The no-op default combined with try/catch cleanly avoids crashing when Wisp isn't initialized, and unsubscribeWisp() in cleanup is always safe to call.

One optional nit: the catch swallows all errors, not just "Wisp not initialized" ones. A console.warn would help distinguish an expected skip from an unexpected failure in bindSupabase itself.

♻️ Optional: log the caught error
         try {
             unsubscribeWisp = bindSupabase(supabase);
-        } catch {
-            // wisp not initialized — skip analytics identity binding
+        } catch (e) {
+            // wisp not initialized — skip analytics identity binding
+            console.warn('Wisp bindSupabase skipped:', e);
         }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/providers/AuthProvider.tsx` around lines 13 - 19, The try/catch around
bindSupabase in AuthProvider is swallowing all failures without any visibility,
so update the catch block to log the caught error with a warning before falling
back to the no-op unsubscribeWisp. Keep the existing safe cleanup behavior, but
make the message in AuthProvider clearly distinguish an expected
Wisp-not-initialized skip from an unexpected bindSupabase failure.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/providers/AuthProvider.tsx`:
- Around line 13-19: The try/catch around bindSupabase in AuthProvider is
swallowing all failures without any visibility, so update the catch block to log
the caught error with a warning before falling back to the no-op
unsubscribeWisp. Keep the existing safe cleanup behavior, but make the message
in AuthProvider clearly distinguish an expected Wisp-not-initialized skip from
an unexpected bindSupabase failure.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0adbfbfe-0a4d-4804-98be-4d9dacf6d085

📥 Commits

Reviewing files that changed from the base of the PR and between 34e4985 and 1feb817.

📒 Files selected for processing (2)
  • convex/http.ts
  • src/providers/AuthProvider.tsx

- Add by_machine_type_time composite index on events (machineId, type, timestamp)
- getMachineStats now uses the composite index for both error and pageview queries, removing the .filter() post-scan
@creatorcluster creatorcluster merged commit da93e41 into creatorcluster:main Jul 6, 2026
1 of 3 checks passed
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