Skip to content

feat(demo-request): block personal email domains#3786

Merged
waleedlatif1 merged 1 commit intostagingfrom
fix/form
Mar 26, 2026
Merged

feat(demo-request): block personal email domains#3786
waleedlatif1 merged 1 commit intostagingfrom
fix/form

Conversation

@waleedlatif1
Copy link
Collaborator

Summary

  • Add personal/consumer email domain filtering to the demo request modal
  • Uses free-email-domains package (~3k domains, gmail/yahoo/hotmail/etc.)
  • Blocks at both client (form validation) and server (API route re-validates same schema)
  • Uses a Set for O(1) lookups at module load time

Type of Change

  • New feature

Testing

Tested manually

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

@vercel
Copy link

vercel bot commented Mar 26, 2026

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

Project Deployment Actions Updated (UTC)
docs Ready Ready Preview, Comment Mar 26, 2026 4:43pm

Request Review

@cursor
Copy link

cursor bot commented Mar 26, 2026

PR Summary

Medium Risk
Adds a new dependency-backed validation rule that rejects demo requests from free/personal email domains, which could inadvertently block legitimate users and reduce inbound leads if the domain list/normalization is imperfect.

Overview
Demo request submissions now enforce a work-email-only policy by adding a free-email-domains blacklist check to demoRequestSchema (lowercasing the address, extracting the domain, and rejecting matches with a new validation message).

The apps/sim package adds the free-email-domains dependency (and updates bun.lock) to support the domain list used for this validation.

Written by Cursor Bugbot for commit cdc8194. Configure here.

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Mar 26, 2026

Greptile Summary

This PR adds personal/consumer email domain filtering to the demo request form by integrating the free-email-domains package and extending the shared demoRequestSchema with an additional Zod .refine() check. Because the schema is imported by both the client modal (demo-request-modal.tsx) and the server API route (/api/demo-requests/route.ts), validation runs at both layers without duplicating logic — a clean design.

Key observations:

  • Logic is correct: the new refine runs after .transform() (which lowercases the value), so domain lookups are case-insensitive; the domain ? ... : true fallback is safe because the preceding quickValidateEmail refine already catches emails without a valid @domain part.
  • Server-side enforcement is solid: the API route already re-parses with demoRequestSchema.safeParse, so the domain block cannot be bypassed by calling the endpoint directly.
  • Bundle size trade-off: importing free-email-domains in consts.ts ships the ~3 000-domain list into the browser bundle (since consts.ts is consumed by a 'use client' component). This is intentional per the PR description, and acceptable for a low-traffic marketing modal, but worth tracking.
  • The Set construction at module load time is a good performance choice for repeated lookups.

Confidence Score: 4/5

Safe to merge; the domain-blocking logic is correct and server-side validation is preserved — one minor bundle-size trade-off worth acknowledging.

The implementation is clean and logically sound, dual validation is properly wired, no regressions are introduced, and the only concern (domain list in client bundle) is a deliberate design choice called out in the PR description rather than a bug.

apps/sim/app/(home)/components/demo-request/consts.ts — the free-email-domains import lands in the client bundle; consider splitting schema or lazy-loading if bundle size becomes a concern.

Important Files Changed

Filename Overview
apps/sim/app/(home)/components/demo-request/consts.ts Adds free-email-domains import and Set for O(1) lookups, plus a new Zod refine on companyEmail; logic is sound but imports the full domain list into the client bundle.
apps/sim/package.json Adds free-email-domains@1.2.25 as a runtime dependency; version is pinned, package has 0 runtime dependencies.
bun.lock Lock file updated to include free-email-domains@1.2.25 integrity hash; no issues.

Sequence Diagram

sequenceDiagram
    participant User
    participant Modal as DemoRequestModal (client)
    participant Schema as demoRequestSchema (shared)
    participant API as /api/demo-requests (server)

    User->>Modal: Types work email & submits form
    Modal->>Schema: safeParse(formData)
    Note over Schema: 1. quickValidateEmail refine<br/>2. FREE_EMAIL_DOMAINS.has(domain) refine
    alt Personal domain (e.g. gmail.com)
        Schema-->>Modal: Error: "Please use your work email address"
        Modal-->>User: Shows inline field error
    else Valid work email
        Schema-->>Modal: Parsed & lowercased data
        Modal->>API: POST /api/demo-requests (JSON)
        API->>Schema: safeParse(body) — re-validates server-side
        alt Domain slipped through client (direct API call)
            Schema-->>API: 400 Invalid request data
            API-->>Modal: 400 response
        else Valid
            API->>API: sendEmail(enterprise@sim.ai)
            API-->>Modal: 201 success
            Modal-->>User: Success state
        end
    end
Loading

Reviews (1): Last reviewed commit: "feat(demo-request): block personal email..." | Re-trigger Greptile

@waleedlatif1 waleedlatif1 merged commit 3597eac into staging Mar 26, 2026
12 checks passed
@waleedlatif1 waleedlatif1 deleted the fix/form branch March 26, 2026 16:47
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