# Abuse handling Reports land in one queue (`abuse_reports`, migration `0027_abuse_reports.sql`) from three sources: | Source | Entry point | Reporter identity (HMAC only) | | ------- | ------------------------------------------------------------------- | ---------------------------------------------- | | `web` | `/abuse` form (`submitAbuseReport`, `src/fns/abuse.ts`) | signed-in user, else client IP | | `site` | `POST /__gitfor/report` on any hosted site | client IP | | `email` | mail to `abuse@` routed to the Worker (`src/server/abuse-email.ts`) | sender **domain** (addresses are free to mint) | Each report is matched to a hosted site by URL: site label, preview label, then custom domain (`siteIdForUrl`). Reports about forge pages or other hosts are kept but not linked to a site. ## Auto-pause A site is paused (`sites.disabled_reason = 'Paused pending abuse review'`, `sites.paused_at` set, KV meta republished so the dispatcher returns 451) once enough distinct reporters have open reports against it within seven days: | Site | Any category | Phishing or malware | | ------- | ------------ | ------------------- | | Scratch | 3 | 2 | | Owned | 5 | 3 | One reporter counts once per site while their report is open. Sites already disabled for another reason (expiry, repository deleted) keep that reason and are never marked paused. ## Review Site admins (`users.is_admin`) get **Site admin** in the user menu: - `/admin`: users, orgs, repos, sites and abuse counters, organizations ranked by open reports, recent sign-ups. - `/admin/abuse`: the queue. **Pause site** and **Keep paused** mark every open report for the site actioned. **Restore site** lifts an abuse pause only and dismisses the site's open reports. **Dismiss** closes the report without touching the site. ## Email setup (Cloudflare Email Routing) 1. Enable Email Routing on the forge zone and verify the operator's destination address: `wrangler email routing addresses create you@example.com`. 2. Set `ABUSE_FORWARD_TO` in `wrangler.jsonc` to that address. The Worker forwards every abuse@ message there before filing reports, so nothing is lost if parsing fails. 3. After the Worker is deployed, route abuse@ to it: ```sh wrangler email routing rules create --name "abuse to worker" --match-type literal --match-field to \ --match-value abuse@ --action-type worker --action-value ``` Until then a plain forward rule to the operator works, but no reports are filed and nothing auto-pauses.