Skip to content

Turnstile-protected contact page (reuses the mountain-infra ACE contact relay) - #38

Merged
git-cgallagher merged 1 commit into
mainfrom
feat/contact-form
Aug 13, 2026
Merged

git-cgallagher merged 1 commit into
mainfrom
feat/contact-form

Conversation

@git-cgallagher

Copy link
Copy Markdown
Owner

What

A standalone contact.html + contact.js for edulab.appalachiancloud.co — the site previously had no contact channel at all. No email address or mailto: appears anywhere (the inbox lives server-side in the relay).

  • Form: name / email / message, honeypot (company), Cloudflare Turnstile (implicit render, ACE widget's public site key — a root-domain widget hostname covers subdomains, so no new widget).
  • Submit: urlencoded POST (a CORS simple request, no preflight) to the shared relay https://bep3iwibed.execute-api.us-east-1.amazonaws.com/contact (mountain-infra contact_api.tf: honeypot + server-side siteverify + SES to the private inbox). Single-use Turnstile token reset on every attempt.
  • CSP (terraform/main.tf): gains its only third-party allowances — script-src/frame-src challenges.cloudflare.com, connect-src the relay origin. frame-src must be explicit (else falls back to default-src 'self' and the widget iframe is blocked).
  • ci.yml: the no-cache + ?v=<sha> cache-bust step now loops over both HTML pages (immutable-asset gotcha — see AGENTS.md).
  • Sidebar footer "Contact us" link, sitemap.xml entry, AGENTS/CHANGELOG updated.

Pairs with

git-cgallagher/mountain-infra#48 — the relay's CORS allow-list gains https://edulab.appalachiancloud.co.

Rollout order (operator)

  1. aws-vault exec + terraform apply in mountain-infra terraform/lightsail/ (#48 — CORS).
  2. aws-vault exec edulab-terraform + terraform apply in this repo's terraform/ (CSP headers policy — in-place update to the response-headers policy).
  3. Merge this PR → CI deploys the frontend.
  4. End-to-end test: submit the live form, confirm delivery to the ACE inbox.

Nothing to seed — no new SSM params, no new Turnstile widget.

🤖 Generated with Claude Code

… contact relay

- contact.html + contact.js: urlencoded POST (no preflight) to the shared
  relay; honeypot; single-use token reset; no email address or mailto:
  anywhere on the site.
- CSP (terraform/main.tf): the only third-party allowances —
  script-src/frame-src challenges.cloudflare.com, connect-src the relay
  origin. Apply BEFORE merging or the widget/POST are blocked.
- ci.yml: no-cache + ?v=<sha> cache-bust loop now covers both HTML pages.
- Sidebar footer link, sitemap.xml entry, AGENTS/CHANGELOG docs.

Pairs with mountain-infra#48 (CORS allow-list gains the edulab origin).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@git-cgallagher
git-cgallagher marked this pull request as ready for review August 13, 2026 20:57
@git-cgallagher
git-cgallagher merged commit 9247360 into main Aug 13, 2026
4 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.

1 participant