Skip to content

fix(auth): remove captcha from login, fix signup captcha flow - #3753

Merged
waleedlatif1 merged 2 commits into
stagingfrom
fix/hcap
Mar 25, 2026
Merged

fix(auth): remove captcha from login, fix signup captcha flow#3753
waleedlatif1 merged 2 commits into
stagingfrom
fix/hcap

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

Summary

  • Remove Turnstile captcha from login entirely — captcha was blocking legitimate users with a 15s silent timeout due to Cloudflare's invisible widget silently erroring with no fallback. Login has credential verification; it doesn't need captcha.
  • Remove /sign-in/email from server-side captcha endpoints
  • Fix signup captcha flow: replace broken getResponsePromise() approach with canonical onSuccess/onError/onExpire callback pattern wired to resolve/reject refs — errors now fail immediately instead of waiting 15s
  • Fix memory leak: timeout in Promise.race is now cleared in finally
  • Note: also switch Cloudflare widget from Invisible → Managed mode in dashboard

Type of Change

  • Bug fix

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

vercelBot commented Mar 25, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
ProjectDeploymentActionsUpdated (UTC)
docsSkippedSkippedMar 25, 2026 3:29am

Request Review

@cursor

cursorBot commented Mar 25, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Touches authentication flows by removing captcha enforcement on /sign-in/email and changing signup captcha token acquisition; mistakes could impact sign-in availability or bot protection.

Overview
Removes Cloudflare Turnstile captcha from the login UI and no longer sends the x-captcha-response header on email sign-in.

Reworks signup captcha handling to use Turnstile onSuccess/onError/onExpire callbacks with an explicit timeout (cleared in finally) so failures surface immediately instead of silently hanging.

Updates server-side captcha configuration to only protect /sign-up/email (drops /sign-in/email from captcha-enforced endpoints).

Written by Cursor Bugbot for commit ec8e276. Configure here.

@greptile-apps

greptile-appsBot commented Mar 25, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes two related captcha issues in the auth flows: it completely removes Turnstile from the login page (where it was silently timing out and blocking legitimate users), and replaces the broken getResponsePromise-based approach on signup with the canonical onSuccess/onError/onExpire callback pattern wired to resolve/reject refs. The server-side captcha endpoint list is updated to match, keeping the bot-protection gate only on registration.

  • Login captcha removed: Turnstile widget, turnstileRef, turnstileSiteKey, token execution logic, and the x-captcha-response request header are all stripped from login-form.tsx. The login route is also removed from the server-side endpoints array in auth.ts, so the backend no longer rejects sign-in requests that lack a captcha token.
  • Signup captcha flow fixed: Promise.race replaces the getResponsePromise(15_000) call. A captchaResolveRef / captchaRejectRef pair is stored on the component and wired to the Turnstile onSuccess, onError, and onExpire callbacks so errors propagate immediately rather than silently waiting 15 seconds.
  • Memory leak fixed: clearTimeout(timeoutId) is called in the finally block, ensuring the 15-second timer is always cancelled once the race settles — regardless of which branch wins.
  • Widget mode updated: The size: 'invisible' Turnstile option is removed from the signup form (consistent with the planned Cloudflare dashboard switch to Managed mode), so the widget renders visibly inline in the form when executing.

Confidence Score: 5/5

  • Safe to merge — the changes are well-scoped bug fixes with no regressions; optional chaining correctly guards all out-of-band callback invocations.
  • All three files are narrow, targeted changes. The captcha removal from login is cleanly executed with no dangling references. The signup rewrite uses a correct and idiomatic Promise pattern; the finally block properly nulls refs and clears the timeout so there are no leaks or double-settle risks. The optional chaining on captchaResolveRef.current?.(token) / captchaRejectRef.current?.() handles out-of-band Turnstile events (e.g. a token expiring between attempts) safely as no-ops. Server-side endpoint list is consistent with the client change.
  • No files require special attention.

Important Files Changed

FilenameOverview
apps/sim/app/(auth)/login/login-form.tsxCleanly removes all Turnstile captcha code from login — widget, refs, token logic, and request header — leaving a simpler sign-in flow with no functional regressions.
apps/sim/app/(auth)/signup/signup-form.tsxReplaces the broken getResponsePromise approach with a Promise.race + onSuccess/onError/onExpire callback pattern; fixes the 15 s silent timeout and clears the timeout ID in finally to prevent the memory leak. One edge case worth understanding: onExpire can also fire outside an active attempt (token ageing), but the optional chaining on captchaRejectRef.current?.() makes it a safe no-op in that scenario.
apps/sim/lib/auth/auth.tsRemoves /sign-in/email from the server-side captcha endpoint list, correctly keeping the constraint only on /sign-up/email to match the new UI behaviour.

Sequence Diagram

sequenceDiagram
participant U as User
participant F as SignupForm
participant TW as Turnstile Widget
participant CF as Cloudflare
participant API as /sign-up/email
U->>F: Submit form
F->>TW: widget.reset()
F->>F: Start Promise.race (15s timeout)
F->>TW: widget.execute()
TW->>CF: Challenge request
CF-->>TW: Challenge response
alt Success
TW->>F: onSuccess(token)
F->>F: captchaResolveRef.current(token)
F->>API: POST with x-captcha-response header
API-->>F: 200 OK
F->>U: Redirect to /verify
else Error
TW->>F: onError()
F->>F: captchaRejectRef.current(Error)
F->>U: Show "Captcha verification failed"
else Expire
TW->>F: onExpire()
F->>F: captchaRejectRef.current(Error)
F->>U: Show "Captcha verification failed"
else Timeout (15s)
F->>F: setTimeout fires, reject
F->>U: Show "Captcha verification failed"
end
Note over F: finally: clearTimeout, null out refs
Note over F,API: Login: no captcha at all
U->>F: Submit login form
F->>API: POST /sign-in/email (no captcha header)
API-->>F: Response
Loading

Reviews (2): Last reviewed commit: "fix(auth): show Turnstile widget at norm..." | Re-trigger Greptile

@waleedlatif1

Copy link
Copy Markdown
CollaboratorAuthor

@greptile

@waleedlatif1

Copy link
Copy Markdown
CollaboratorAuthor

@cursor review

@cursorcursorBot 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.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

@waleedlatif1
waleedlatif1 merged commit 228578e into stagingMar 25, 2026
12 checks passed
@waleedlatif1
waleedlatif1 deleted the fix/hcap branch March 25, 2026 03:36
Sg312 pushed a commit that referenced this pull request Mar 25, 2026
* fix(auth): remove captcha from login, fix signup captcha flow
* fix(auth): show Turnstile widget at normal size for Managed mode challenges
waleedlatif1 added a commit that referenced this pull request Mar 27, 2026
* fix(auth): remove captcha from login, fix signup captcha flow
* fix(auth): show Turnstile widget at normal size for Managed mode challenges
waleedlatif1 added a commit that referenced this pull request Apr 4, 2026
* fix(auth): remove captcha from login, fix signup captcha flow
* fix(auth): show Turnstile widget at normal size for Managed mode challenges
Sign up for freeto 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

@waleedlatif1