Rate limit, honeypot, minimum fill time and the content checks run ahead of the proof-of-work verification (cheapest first) through all three enforcement mechanisms alike - a target is checked the same way regardless of which path reaches it.
| Mechanism | Used for | Runs |
|---|---|---|
| Form validation | registration, contact, forgotten password, custom forms | After the regular constraints, so a form that is invalid for another reason does not consume a challenge. Live Component re-renders are skipped. |
| Route check | login, checkout sign-in, Shop API operations | On kernel.request after the locale is set, before the firewall |
| Event listener | support form, newsletter, and any target that declares events | On the other plugin's own rejectable event (storefront and API alike) |
A form rejection is added as a form error and also flashed, because Sylius' shop templates render fields individually and never a form's own errors.
src/
βββ Challenge/ # Challenge generation and signing
βββ Command/ # SetupCommand, PurgeCommand, UpdateDisposableDomainsCommand
βββ Controller/ # ChallengeController, BlockedDomainsController
βββ DependencyInjection/
βββ DisposableEmail/ # Disposable-mail guard, domain list, override entities
βββ Enforcement/ # Form type extension, route listener, event listener/registrar
βββ Entity/ # ChannelSettings, CustomTarget, DisposableDomainOverride, GibberishLogEntry, RateLimitHit, UsedChallenge
βββ Form/Type/ # Admin form types
βββ Gibberish/ # Scorer, trigram tables, build script
βββ Guard/ # SubmissionGuard orchestrating all checks, Rejection enum
βββ Menu/ # Admin sidebar entry
βββ Migrations/ # Six Doctrine migrations
βββ RateLimit/ # Rate limiter
βββ Request/
βββ Security/ # Secret cipher (libsodium)
βββ Settings/ # Channel settings provider/factory
βββ Submission/
βββ Target/ # ProtectionTarget, registry, built-in targets
βββ Twig/ # mmd_altcha_widget() function
βββ Validator/
config/
βββ grids/ # Four admin grids
βββ routes/ # admin.yaml, shop.yaml
βββ twig_hooks/ # Title-block and action hooks
ChannelSettings, CustomTarget, DisposableDomainOverride, GibberishLogEntry, RateLimitHit and UsedChallenge: six tables, six migrations, one per entity. The tables are named mmd_sylius_altcha_*.
framework.trusted_proxies (and trusted_headers), or every visitor shares one bucket and a burst from a single person locks the form for everybody.sylius_shop_json_login_check) posts through its own JavaScript, which cannot carry a proof. It is therefore only rate limited (target checkout_login), never asked for a proof. The limit counts every attempt, successful ones included, and is shared by everyone behind one IPv4 address: for customers behind a carrier-grade NAT or an office address, raise the rate limit or untick the target.X-Altcha-Payload header or an altcha field).