Public: anyone can read this; the crew can change it.

Mail the forge sends is capped per recipient and forge-wide #832

Merged opened this in answer to

Check · Review · Land · Live done — Landed and live in production.

Merged

Closes #784

shipped production is serving it for issue #784 — its issue is already done deploy 4db86a7

opened this

Closes #784

Verification links were limited per account only. Many accounts could still use the forge to mail one stranger many times, or to mail many strangers. Every message the forge sends now passes two caps:

  • Per recipient: at most RECIPIENT_DAILY (3) messages to one address in 24 hours, whatever account asks.
  • Forge-wide: at most mailDailyCap messages in 24 hours from the whole forge. It is set by FORGE_MAIL_DAILY and defaults to 200.

How it works:

  • One gate: sendCapped and mayMail in src/actions/mail.ts.

- sendVerification asks before it makes a link, so a capped send spends none of the account's own links. It asks again as the message goes. - A place is held before sending and released on failure, so two sends at once cannot both slip past a cap.

  • The counts survive a restart. They live in the mail_sent table, which stores a sha256 of the lowercased recipient, never the address itself. This is migration 57 and is kept last; the lead places it.
  • The person waiting is told plainly.

- The resend API answers 429 capped with "the forge has sent all the mail it may for now; try again tomorrow, or ask the forge's owner to verify you". - The settings page flashes the same.

  • The owner hears once.

- The first refusal at the ceiling in 24 hours appends one mail.ceiling event (audience: admins) and logs a warning. - The notifier wakes on it and sends the admin one line. The line's id is per UTC day, so it goes once (mailCeilingLines).

Tests are in test/mail-caps.test.ts, added to the gate list:

  • Many accounts take a stranger's address in turn and each asks; exactly 3 get through, and another address is unaffected.
  • A capped person gets a 429 with the words above.
  • Past the forge-wide ceiling no mail goes; there is one event and one owner line, and none for a non-admin.
  • A reopened forge still holds a capped address back.
  • With the caps disabled, all 4 tests fail.

🤖 Generated with Claude Code

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs