feat: per-store Cloudflare Turnstile bot protection for checkout - #107
Merged
Conversation
…eckout - cod-shared: store_turnstile_config table + queries (secret never returned to clients), verifyTurnstileToken siteverify client, scopes and error codes - cod-server: migration 0024, storefront turnstile gate on order placement (fail-open on provider outage), per-store config endpoints with scope checks and OpenAPI schemas - cod-client-astro: Turnstile settings card with AR/FR/EN locale parity - theme01: interaction-only managed widget on the order form, pre-submit token guard with localized wait message, retry auto + success/expired/error/timeout callbacks, content keys in all packs - docs: TURNSTILE.md, README and CHANGELOG entries
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds optional, per-store Cloudflare Turnstile bot protection to the COD checkout flow. Merchants configure their widget keys in dashboard Settings; when enabled, the storefront order form carries a Turnstile token that cod-server verifies against Cloudflare siteverify before accepting the order. Stores without a config are unaffected (Turnstile disabled by default).
Changes
cod-shared
store_turnstile_configtable queries with a safe/raw read split — the secret key is never returned to a clientverifyTurnstileTokensiteverify client: zero dependencies, in-band failure reporting (success: false+ error codes),TRANSIENTerror class for transport-level failurescod-server
0024_store_turnstile_config.sql(one row per store, no row = disabled)cod-client-astro (dashboard)
cod-astro/theme01 (storefront)
interaction-only: invisible during normal checkout, a challenge only when Cloudflare's risk engine demands oneretry: autoplus success/expired/error/timeout callbacks so transient widget failures and challenge timeouts self-healDocs
docs/TURNSTILE.md, README and CHANGELOG entriesTesting
npm run typecheckclean,npm test1896/1896 pass (135 files)npm run typecheckclean,npm test143/143 pass (33 files)astro check0 errors,npm test18/18 pass,npm run validate(string/style validators + build) cleanDeploy notes
0024_store_turnstile_configto D1