Web tool that extracts sender domains from spam emails and generates copy-paste-ready Migadu rules for spam/ban filtering.
  • HTML 89.2%
  • JavaScript 9.7%
  • Dockerfile 1.1%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-09-21 19:47:23 +02:00
.gitignore added .gitignore 2026-09-21 18:20:27 +02:00
Containerfile added base structure 2026-09-21 19:02:36 +02:00
index.html app works now and also have a merge tool 2026-09-21 19:45:40 +02:00
migaduSpamDomainExtractor.yaml added base structure 2026-09-21 19:02:36 +02:00
package-lock.json Add package-lock.json 2026-09-21 19:04:49 +02:00
package.json added base structure 2026-09-21 19:02:36 +02:00
README.md Changed Readme 2026-09-21 19:47:23 +02:00
server.js added base structure 2026-09-21 19:02:36 +02:00

Migadu Spam Domain Extractor

A small self-hosted web tool that logs into your Migadu mailbox over IMAP, scans the mailbox of your choice (e.g. Junk), extracts every sender domain, and turns them into ready-to-paste rules for Migadu's spam and deny filters.

Log in, pick the spam mailbox, get all mail domains in Migadu rule syntax (*@domain, one per line), copy them in one click, and paste them straight into the Migadu admin panel.

How it works

  • Small Node.js backend (server.js, Express + imapflow) that talks IMAP to imap.migadu.com:993 (TLS)
  • You enter your mailbox credentials in the web UI, pick a mailbox, and the server scans all messages and returns the unique sender domains
  • All domain processing (folding, validation, whitelist, merge) happens client-side in your browser
  • Credentials are used in-memory for a single IMAP session per action and are never stored or logged — self-host this and only you see them

Features

  • Login flow — enter your Migadu mailbox email + password, mailboxes are listed automatically (Junk pre-selected when detected)
  • Mailbox picker — extract from any mailbox: Junk, INBOX, Archive, anything
  • Domain extraction — scans the From envelope of every message
  • Subdomain folding (toggleable) — collapses news.spam.example down to spam.example, handling common two-level TLDs (co.uk, com.au, ...)
  • Migadu syntax check — every domain is validated against the rules the Migadu admin panel actually enforces before it ever reaches your output:
    • every label must start with a letter, then alphanumeric/hyphen only, 1–63 chars, no trailing hyphen (digit-leading domains like 0589.de are rejected by Migadu, so they are skipped here too)
    • the TLD must exist in the IANA root zone (cloud.rr-style garbage is dropped)
    • public-suffix awareness — never emits bare suffixes like ac.id, gov.br or net.ua that Migadu refuses; keeps the full registrable domain instead
    • skipped entries are counted and shown ("N not Migadu-valid skipped") so you always know something was left out
  • Whitelist — skips common legitimate senders (PayPal, GitHub, Apple, ...) so you don't ban real mail; edit the lists at the top of the script in index.html
  • Merge existing deny list — paste your current Migadu deny list (accepts *@domain, @domain or bare domain, one per line) and it is validated and merged with the extracted domains into one big list
  • Per-domain removal — click × on any domain to strike it from the output, click again to undo
  • Output formats:
    • Migadu custom deny rules (*@domain, one per line, wildcard before the @)
    • Sieve discard rules (for per-address filtering in Migadu)
    • Plain domain list
  • One-click copy — copy the whole rule list to your clipboard
  • Purple/pink themed UI — no build step, no JavaScript frameworks

How to use

  1. Open the website.
  2. Enter your Migadu mailbox address and password, click Log in & list mailboxes.
  3. Pick the mailbox to scan (your Junk/Spam folder is pre-selected when found) and click Extract domains. Domains that can never be valid Migadu rules are automatically skipped and counted.
  4. Optionally remove domains you don't want to ban.
  5. Optionally paste your existing deny list under Merge existing deny list and click Merge into list to build one combined list.
  6. Pick the output format and click Copy.
  7. In the Migadu admin panel, open your domain → Spam Filtering (or the per-address filter settings) and paste the rules.

Example

Spam mailbox contains messages from:

From: "Mega Deals" <deals@spammy-shop.example>
From: job.offers@totally-legit-jobs.example>
From: "Winner" <you-won@news.lottery-scam.example>

Output — Migadu deny rule syntax:

*@spammy-shop.example
*@totally-legit-jobs.example
*@lottery-scam.example

Output — Sieve rules:

require ["fileinto"];

if address :domain :is "from" "spammy-shop.example" { discard; }
if address :domain :is "from" "totally-legit-jobs.example" { discard; }
if address :domain :is "from" "lottery-scam.example" { discard; }

Repository layout

.
├── Containerfile                  # Podman/Docker image (node:22-alpine, non-root)
├── index.html                     # Web UI + all client-side logic (single file)
├── miaduSpamDomainExtractor.yaml  # Complete Kubernetes deployment in one manifest
├── package.json                   # Node dependencies
├── package-lock.json              # Pinned dependency tree (commit this!)
├── README.md
├── server.js                      # Express + imapflow backend
└── .gitignore

Only express and imapflow are dependencies — the whole app is three files (server.js, index.html, package.json) plus the lockfile and deployment artifacts.

Configuration

Environment variable Default Description
PORT 3000 HTTP listen port

The IMAP host is hardcoded to imap.migadu.com (TLS, port 993). The /api endpoints also accept an optional host field in the request body if you ever need to point at a different IMAP server.

Development

npm install
npm start
# open http://localhost:3000

Deployment

Build the image, push it to your registry, and apply the manifest:

# 1. Build and push (podman)
podman build -t your-registry.example.com/migadu-spam-domain-extractor:latest .
podman push your-registry.example.com/migadu-spam-domain-extractor:latest

# 2. Adjust the image reference and the hostname in miaduSpamDomainExtractor.yaml

# 3. Deploy
kubectl apply -f miaduSpamDomainExtractor.yaml

miaduSpamDomainExtractor.yaml contains all resources in one file, deployed into the migadu-spam-domain-extractor namespace:

  • Namespace
  • Deployment — 2 replicas, Node.js serving the app, liveness/readiness probes, small resource requests (10m CPU / 32Mi), non-root security context
  • Service — ClusterIP port 80 → container port 3000
  • Traefik Middleware — HSTS
  • Traefik IngressRoute — websecure entrypoint, TLS via the letsencrypt certResolver — set your hostname in the match rule before applying

To test locally without going through Traefik:

kubectl port-forward -n migadu-spam-domain-extractor svc/migadu-spam-domain-extractor 8080:80

Important: your mailbox password is sent to the instance on every action. Keep the IngressRoute on the websecure entrypoint (HTTPS via Let's Encrypt) and never expose the service over plain HTTP or host it somewhere you don't trust.

Podman / Docker (standalone)

podman build -t migadu-spam-domain-extractor .
podman run -p 8080:3000 migadu-spam-domain-extractor
# open http://localhost:8080

Any Node host

npm install --omit=dev
PORT=3000 node server.js

Privacy

Credentials are sent only to this self-hosted instance, held in memory for the duration of one IMAP session per action, and never stored, cached, or logged. The extracted domains, the syntax validation and the deny-list merge are processed entirely in your browser. Host it yourself so your mailbox password never leaves your infrastructure.