diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..d7e2cc5 --- /dev/null +++ b/.env.example @@ -0,0 +1,4 @@ +# Build-time public environment variable for the contact form's reCAPTCHA +# v2 checkbox widget. Not secret — this is the public site key, safe to +# expose client-side. See docs/SECURITY.md. +PUBLIC_RECAPTCHA_SITE_KEY= diff --git a/.github/workflows/preview-deploy.yml b/.github/workflows/preview-deploy.yml index fe6cb25..4dd0d75 100644 --- a/.github/workflows/preview-deploy.yml +++ b/.github/workflows/preview-deploy.yml @@ -21,6 +21,8 @@ jobs: cache: npm - run: npm ci - run: npm run build + env: + PUBLIC_RECAPTCHA_SITE_KEY: ${{ vars.PUBLIC_RECAPTCHA_SITE_KEY }} # Uploads a new Worker version (not a full deploy — never touches the # production/Active deployment) with a preview alias tied to this PR diff --git a/docs/SECURITY.md b/docs/SECURITY.md index 4cafaf9..ce1a2c5 100644 --- a/docs/SECURITY.md +++ b/docs/SECURITY.md @@ -89,15 +89,12 @@ relying on a filter to exclude private rows. at the point of choosing it, per the project conventions document, with a note to re-validate the choice when work in that area actually begins. -## Open Items - -* The contact form's KV namespace (`RATE_LIMIT`) and reCAPTCHA site/secret - key pair are not yet provisioned. Both require manual setup outside this - repository (Cloudflare KV namespace creation; reCAPTCHA site registration - in Google's admin console) before the contact form is functional in - production. The `EMAIL` send binding and `CONTACT_SENDER`/ - `CONTACT_RECIPIENT` secrets are configured in `wrangler.toml`, pointing at - an already-verified Email Routing destination address, so no further - manual provisioning is needed for email delivery itself. The code is - written against these as named bindings/secrets (see `wrangler.toml`, - `src/env.d.ts`) and will fail clearly, not silently, if they are unset. +## Provisioning Status + +* The contact form's `RATE_LIMIT` and `SESSION` KV namespaces, the + `CONTACT_SENDER`/`CONTACT_RECIPIENT`/`RECAPTCHA_SECRET` Worker secrets, + and the reCAPTCHA site/secret key pair (registered in Google's admin + console) are all provisioned in production as of 2026-08-13. The `EMAIL` + send binding and `CONTACT_SENDER`/`CONTACT_RECIPIENT` secrets point at an + already-verified Email Routing destination address. The contact form is + fully functional in production. diff --git a/wrangler.toml b/wrangler.toml index 21a6522..d704d84 100644 --- a/wrangler.toml +++ b/wrangler.toml @@ -38,13 +38,10 @@ destination_address = "blindtechmage+jwauthier@gmail.com" # database_name = "blindtechmage-resources" # database_id = "REPLACE_WITH_REAL_ID" -# Contact form rate limiting. Requires a real KV namespace, created via -# `wrangler kv namespace create RATE_LIMIT` before this is active — not yet -# provisioned. -# -# [[kv_namespaces]] -# binding = "RATE_LIMIT" -# id = "REPLACE_WITH_REAL_ID" +# Contact form rate limiting. +[[kv_namespaces]] +binding = "RATE_LIMIT" +id = "da26bfe7fe9a4154a77e4e290ada305e" # Contact form secrets (CONTACT_SENDER, CONTACT_RECIPIENT, RECAPTCHA_SECRET) # are set via `wrangler secret put `, never committed here. Neither