Block example.com emails and homesites under 10 #26

Merged
JoeBot merged 1 commits from feature/block-example-domain-and-min-homesites into main 2026-07-24 09:30:45 -04:00
Owner

Follow-up to #24 and #25. Spam was still coming through with placeholder content, so two more filters on the public form endpoints.

What this blocks

Reserved / documentation email domains. testing@example.com and anything at example.com/.org/.net/.edu (including subdomains like mail.example.com), plus the reserved TLDs .test, .example, .invalid, and localhost. These are never real leads.

Homesites under 10. Real associations are larger; the junk submissions use 0/1/2. The floor is 10.

How

  • security.validateEmail() gains a domain blocklist (email_blocked reason); new security.validateHomesites() enforces the floor.
  • Both mirrored client-side in app.js for immediate feedback; the server stays authoritative.
  • Homesites min attribute in the HTML goes 1 → 10.
  • Blocked submissions return 400 with a field hint (email / homesites) and store nothing.

Verification (24 assertions, all passing)

Blocked: testing@example.com, anything@example.com, user@example.org, user@mail.example.com, foo@bar.test, foo@host.invalid; homesites 0, 1, 9, 9.9, -5, abc, missing.

Still accepted: board@myhoa.org, chair@example-hoa.com (not example.com), a@notexample.com; homesites 10, 11, 150, "250".

🤖 Generated with Claude Code

Follow-up to #24 and #25. Spam was still coming through with placeholder content, so two more filters on the public form endpoints. ## What this blocks **Reserved / documentation email domains.** `testing@example.com` and anything at `example.com/.org/.net/.edu` (including subdomains like `mail.example.com`), plus the reserved TLDs `.test`, `.example`, `.invalid`, and `localhost`. These are never real leads. **Homesites under 10.** Real associations are larger; the junk submissions use `0`/`1`/`2`. The floor is 10. ## How - `security.validateEmail()` gains a domain blocklist (`email_blocked` reason); new `security.validateHomesites()` enforces the floor. - Both mirrored client-side in `app.js` for immediate feedback; the server stays authoritative. - Homesites `min` attribute in the HTML goes 1 → 10. - Blocked submissions return `400` with a `field` hint (`email` / `homesites`) and store nothing. ## Verification (24 assertions, all passing) Blocked: `testing@example.com`, `anything@example.com`, `user@example.org`, `user@mail.example.com`, `foo@bar.test`, `foo@host.invalid`; homesites `0`, `1`, `9`, `9.9`, `-5`, `abc`, missing. Still accepted: `board@myhoa.org`, `chair@example-hoa.com` (not `example.com`), `a@notexample.com`; homesites `10`, `11`, `150`, `"250"`. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
JoeBot added 1 commit 2026-07-24 09:30:34 -04:00
Spam submissions were still getting through with placeholder data. Two
more content filters on the public form endpoints:

- Reject emails from reserved documentation domains (example.com/.org/
  /.net/.edu and subdomains) and reserved TLDs (.test/.example/.invalid/
  localhost). testing@example.com and friends are never real leads.
- Reject a homesites count below 10. Real associations are larger; the
  junk uses 0/1/2.

Both are validated server-side in security.js (validateEmail gains a
domain blocklist, new validateHomesites) and mirrored client-side in
app.js for immediate feedback. The homesites input min attribute goes
from 1 to 10. Blocked submissions return 400 with a `field` hint and
store nothing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
JoeBot merged commit 614a0edfa1 into main 2026-07-24 09:30:45 -04:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: JoeBot/HOALedgerIQ_Website#26
No description provided.