Skip to content

feat(e2e): exercise the turnstile challenge flow end to end - #77

Closed
fionera wants to merge 4 commits into
feat/captcha-webfrom
feat/captcha-integration
Closed

feat(e2e): exercise the turnstile challenge flow end to end#77
fionera wants to merge 4 commits into
feat/captcha-webfrom
feat/captcha-integration

Conversation

@fionera

@fionera fionera commented Jul 11, 2026

Copy link
Copy Markdown
Member

Summary

Last of the three captcha PRs (server #75 → web #76integration). Stacked on #76 and additionally merges #75's branch, since the e2e needs both the Go validator and the browser widget — the diff shown here includes #75's commits until it merges; the new work is the last commit.

  • SPOE agent split (examples/haproxy/berghain.cfg): the validate and challenge groups now run as separate agents — berghain keeps timeout processing 100ms for the hot per-request path, the new berghain_challenge agent gets 6s because captcha verification does an HTTPS round-trip to the provider. haproxy.cfg (example + e2e) references the new engine for the challenge backend.
  • Turnstile e2e: the e2e stack gains a second frontend (:18081) backed by a turnstile level using Cloudflare's official always-passing dummy keys, driven by the same chromedp flow as the existing POW test (challenge page → widget auto-solves → token verified against the real Turnstile siteverify → cookie → backend reached). Dummy keys report a fixed hostname: example.com, hence skip_hostname_check: true in the test config (flag added in feat: add turnstile, hcaptcha, and recaptcha challenge types #75).
  • Docs: README gains a captcha configuration section (egress requirement, fail-closed semantics, timeout split rationale, hostname binding, CSP note); the visitor help page documents the captcha challenge type and the third-party-script exception to its no-external-CDN statement.

Test plan

  • ./test/e2e/run.sh locally (HAProxy 3.4): both tests pass — TestBrowserSolvesChallenge (POW, 3.6s) and TestBrowserSolvesTurnstileChallenge (6.0s) against the real Turnstile endpoints.
  • haproxy -c -f examples/haproxy/haproxy.cfg validates.
  • go test ./..., web lint/test/build all green on the merged branch.

🤖 Generated with Claude Code

fionera and others added 4 commits July 11, 2026 03:05
Adds three new validation types alongside none and pow, backed by one
shared captcha validator. The challenge GET serves a static per-level
body carrying the sitekey; the POST exchanges the widget response token
for a cookie after verifying it against the provider siteverify
endpoint (fail closed) and binding the reported hostname to the request
identity, accepting subdomains since trusted_domains may collapse the
identity host to a suffix.

The web protocol type numbering skips t:2, which the challenge page
capability checks already reserve for a worker-based POW.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Provider test keys report a fixed hostname unrelated to the page, so
tests cannot pass the hostname binding. Adds an explicit opt-out for
captcha levels, documented as test-only.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Splits the example SPOE config into separate validate and challenge
agents: captcha verification does a network round-trip to the provider,
so the challenge group needs a 6s processing timeout while the
per-request validate path stays at 100ms.

The e2e stack gains a second frontend backed by a turnstile level using
Cloudflare's always-passing dummy keys, driven by the same browser flow
as the POW test. Documents captcha configuration in the README and the
visitor help page, including the third-party script exception.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@fionera

fionera commented Jul 11, 2026

Copy link
Copy Markdown
Member Author

Consolidated into #78 — the three-way split created hard sequential dependencies and CI didn't trigger on stacked bases.

@fionera fionera closed this Jul 11, 2026
@fionera
fionera deleted the feat/captcha-integration branch July 11, 2026 01: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