Skip to content

feat: Add Clerk webhooks and authentication protection#103

Merged
Jackson57279 merged 2 commits intoopen-lovable-v2from
feat/clerk-webhooks-and-auth
Oct 2, 2025
Merged

feat: Add Clerk webhooks and authentication protection#103
Jackson57279 merged 2 commits intoopen-lovable-v2from
feat/clerk-webhooks-and-auth

Conversation

@Jackson57279
Copy link
Owner

@Jackson57279 Jackson57279 commented Oct 2, 2025

Summary

  • Implemented Clerk webhook endpoint with Svix signature verification
  • Added authentication protection to home page - users must sign in to use ZapDev
  • Rounded button corners for better UI appearance
  • Syncs user data to Convex database automatically via webhooks

Changes Made

Webhook Implementation

  • Created /app/api/webhooks/clerk/route.ts endpoint
  • Handles user.created, user.updated, and user.deleted events
  • Verifies webhook signatures using Svix for security
  • Syncs user data to Convex database automatically

Database Mutations

  • Added syncUser mutation in convex/users.ts for webhook-triggered user sync
  • Added deleteUser mutation for handling user deletion events
  • Both mutations bypass authentication (called by verified webhooks)

Authentication Protection

  • Added auth check in home page's handleSubmit function
  • Users must sign in before using the product
  • Shows toast error "Please sign in to use ZapDev" for unauthenticated users

UI Improvements

  • Changed button corners from sharp (rounded) to rounded (rounded-md)
  • Updated:
    • Style selector buttons
    • Model dropdown
    • Additional instructions input field

Configuration

  • Added CLERK_WEBHOOK_SECRET to .env.example

Setup Instructions

  1. In Clerk Dashboard, go to Webhooks and create a new endpoint
  2. Set the endpoint URL to: https://yourdomain.com/api/webhooks/clerk
  3. Subscribe to these events: user.created, user.updated, user.deleted
  4. Copy the signing secret and add it to your .env.local as CLERK_WEBHOOK_SECRET

Security

✅ Webhook signatures verified using Svix
✅ Input sanitization in all user sync mutations
✅ Only authenticated users can use the product
✅ No sensitive data exposed in webhooks

Test Plan

  • Webhook endpoint created with proper signature verification
  • User sync mutations added to Convex
  • Auth protection added to home page
  • Button corners rounded
  • Test webhook delivery in production (requires Clerk Dashboard setup)
  • Verify user sync to Convex database works correctly
  • Confirm unauthenticated users cannot use the product

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added webhook-based user account sync and deletion to keep profiles up to date across services.
    • Enforced sign-in before submissions, preventing unauthenticated actions and showing a clear error message when not signed in.
  • Documentation
    • Updated environment configuration example with a new webhook secret variable.
  • Chores
    • Upgraded numerous dependencies (framework, auth, AI, and tooling packages) for improved compatibility, performance, and stability.

## Features
- Added Clerk webhook endpoint with Svix signature verification
- Implemented user sync to Convex database on user.created/user.updated events
- Added user deletion handling for user.deleted webhooks
- Added authentication protection to home page functionality

## Security
- Webhook signatures verified using Svix
- Only authenticated users can use the product
- Input sanitization in user sync mutations

## UI Improvements
- Rounded button corners (changed from sharp to rounded-md)
- Updated style selectors, model dropdown, and input fields

## Configuration
- Added CLERK_WEBHOOK_SECRET to .env.example

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@vercel
Copy link

vercel bot commented Oct 2, 2025

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

Project Deployment Preview Comments Updated (UTC)
zapdev Error Error Oct 2, 2025 6:24am

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 2, 2025

Walkthrough

Adds Clerk webhook handling via a new API route that verifies Svix signatures and syncs/deletes users in Convex. Introduces Convex mutations for user sync and delete with cascading cleanup. Gates app submission by Clerk sign‑in state. Adds CLERK_WEBHOOK_SECRET to .env.example. Updates numerous dependencies in package.json.

Changes

Cohort / File(s) Summary
Environment Config
/.env.example
Adds CLERK_WEBHOOK_SECRET placeholder for Clerk webhook verification.
Clerk Webhook Route
/app/api/webhooks/clerk/route.ts
New POST endpoint verifying Svix headers against CLERK_WEBHOOK_SECRET. On user.created/updated, syncs user to Convex; on user.deleted, removes user via Convex. Returns 400/500 on validation/errors, 200 on success.
Convex User Mutations
/convex/users.ts
Adds syncUser (upsert with sanitization) and deleteUser (cascading delete of related entities). updateUserAvatar now returns { success: true }.
App Auth Gating
/app/page.tsx
Uses Clerk useAuth to prevent submission when not signed in; shows toast and early-returns.
Dependencies
/package.json
Bumps multiple runtime/dev dependencies (Next/React, Clerk, AI SDKs, TRPC, Zod, Sentry, Stripe, etc.). No app code changes here.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Clerk as Clerk
  participant NextAPI as Next.js API Route (/api/webhooks/clerk)
  participant Svix as Svix Verifier
  participant Convex as ConvexHttpClient
  participant Users as convex/users.ts

  Clerk->>NextAPI: POST webhook (user.created|updated|deleted)
  NextAPI->>Svix: Verify (svix-id, svix-timestamp, svix-signature, body)
  alt Verification fails
    Svix-->>NextAPI: Invalid
    NextAPI-->>Clerk: 400/500
  else Verification ok
    Svix-->>NextAPI: Valid
    alt user.created or user.updated
      NextAPI->>Convex: users.syncUser({ id, email, fullName, avatarUrl, username })
      Convex->>Users: syncUser mutation
      Users-->>Convex: upsert result
      Convex-->>NextAPI: ok
      NextAPI-->>Clerk: 200
    else user.deleted
      NextAPI->>Convex: users.deleteUser({ id })
      Convex->>Users: deleteUser mutation (cascade cleanup)
      Users-->>Convex: delete result
      Convex-->>NextAPI: ok
      NextAPI-->>Clerk: 200
    end
  end
Loading
sequenceDiagram
  autonumber
  participant User as User
  participant App as app/page.tsx
  participant Clerk as Clerk Auth

  User->>App: Click Submit
  App->>Clerk: Check isSignedIn
  alt Not signed in
    App-->>User: Toast error + abort
  else Signed in
    App-->>User: Proceed with submission flow
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

scout

Poem

A whisk of ears, a webhook ping,
Svix sings truth, credentials ring.
Convex burrows, syncs the den,
Deletes the trails, cleans up again.
Gate the gate—only signed may pass—
Secrets tucked beneath the grass.
Thump-thump! Ship it, fast as glass. 🐇✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
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.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title succinctly summarizes the main new features—Clerk webhook integration and authentication protection—using clear phrasing and conventional commit style without unnecessary detail.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/clerk-webhooks-and-auth

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

@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: 2

🧹 Nitpick comments (1)
.env.example (1)

37-41: Keep env keys ordered to satisfy dotenv-linter

dotenv-linter expects CLERK_WEBHOOK_SECRET to appear before NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY. Reordering the block will silence the warning and keep the file tidy.

Apply this diff to fix the ordering:

-# Clerk Authentication configuration
-NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=
-CLERK_SECRET_KEY=
-CLERK_JWT_ISSUER_DOMAIN=
-CLERK_WEBHOOK_SECRET=
+# Clerk Authentication configuration
+CLERK_JWT_ISSUER_DOMAIN=
+CLERK_SECRET_KEY=
+CLERK_WEBHOOK_SECRET=
+NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between e4f153c and f45393f.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (5)
  • .env.example (1 hunks)
  • app/api/webhooks/clerk/route.ts (1 hunks)
  • app/page.tsx (6 hunks)
  • convex/users.ts (1 hunks)
  • package.json (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
convex/users.ts (2)
convex/_generated/server.js (2)
  • mutation (50-50)
  • mutation (50-50)
convex/_generated/server.d.ts (1)
  • MutationCtx (121-121)
🪛 dotenv-linter (3.3.0)
.env.example

[warning] 40-40: [UnorderedKey] The CLERK_WEBHOOK_SECRET key should go before the NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY key

(UnorderedKey)

@Jackson57279 Jackson57279 merged commit aeddc94 into open-lovable-v2 Oct 2, 2025
5 of 6 checks passed
@Jackson57279 Jackson57279 deleted the feat/clerk-webhooks-and-auth branch October 2, 2025 06:35
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.

1 participant