Add optional first-party proof-of-work captcha to login - #41
Merged
Conversation
Layered bot defense on POST /login to stop spam magic-link signups: rate-limit (activates the dormant middleware), a honeypot field, and an optional self-hosted proof-of-work captcha. The captcha signs challenges with the existing CRYPTO_PEPPER (no third party, account, new secret, or CSP change) and is off unless CAPTCHA_ENABLED=true, so /login is unchanged by default. Ships a zero-dep client solver bundle and full test coverage. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The proof of work runs silently, so drop the visible "Verifying…/Verified." label that cluttered the login form. Kept as an sr-only aria-live region so assistive tech still gets feedback. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add the signup-spam defense (honeypot + rate limit + optional proof-of-work captcha) to the Security feature list, the environment variable table (CAPTCHA_ENABLED, CAPTCHA_DIFFICULTY), and a setup note. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
Adds layered bot defense to
POST /loginto stop spammers creating accounts with random emails (Billet is passwordless, so each junk submission both creates a user and fires a magic-link email at a random address). The guards run cheapest-first: per-IP rate limit (activating the previously-dormantmiddleware/rate-limit.ts), a honeypot field, then an optional self-hosted proof-of-work captcha that signs challenges with the existingCRYPTO_PEPPER— no third party, account, new secret, or CSP change. The captcha is off unlessCAPTCHA_ENABLED=true, so/loginis unchanged by default; when on, the server embeds a signed challenge that a zero-dependency client bundle solves and the server re-verifies (HMAC + proof + single-use replay). The three captcha files are kept dependency-free so they can later be extracted to a@alexpricedev/billet-captchamodule. Full test coverage added (340 pass), including a client↔server cross-check proving the hand-written SHA-256 matches Node's.🤖 Generated with Claude Code