Filterregeln aus Ordnerinhalten generieren #4

Merged
DasAoD merged 2 commits from feature/rule-generator-from-folders into main 2026-08-17 13:01:20 +02:00
Owner

Closes #3

Was

Neuer Button „🪄 Regeln aus Ordnern generieren" auf der Filterregeln-Seite:

  • Scannt alle IMAP-Ordner des Kontos (außer INBOX, dem Spam-Zielordner) und liest die Absenderdomains aus dem vorhandenen Ordnerinhalt.
  • Zeigt eine Vorschau mit einer Checkbox pro Ordner — vorausgewählt sind alle außer erkannten System-Ordnern (Gesendet/Sent, Papierkorb/Trash, Entwürfe/Drafts, Junk), aber frei umschaltbar.
  • ⚠️ markiert Domains, die schon anderswo verwendet werden — in einer anderen Regel, der Sperrliste, der Whitelist, oder in einem anderen Ordner-Vorschlag im selben Scan.
  • Bestätigt der User die Auswahl: neue Regeln werden angelegt, bestehende (gleicher Zielordner) um die neuen Domains ergänzt. Nichts wird geschrieben, bevor der User bestätigt.
  • Regelname/-pfad orientiert sich am Ordnerpfad (führendes „INBOX/" entfällt), neue Unterordner-Regeln werden automatisch vor der zugehörigen Root-Regel einsortiert (bestehende Reihenfolge-Anforderung der App).
  • Einmalige, manuell angestoßene Aktion — bewusst kein Dauer-Automatismus wie bei der Sperrliste, da eine falsche Regel hier künftig echte Mail in den falschen Ordner verschiebt statt nur Spam falsch einzuordnen.
  • Freemailer- vs. Domain-Unterscheidung ist explizit nicht automatisiert (v1) — wird bei Bedarf manuell in der Vorschau korrigiert bzw. die Regel danach im normalen Editor angepasst.

Wie

  • lib/rule_generator.php (neu): Scan-, Vorschlags- und Anwenden-Logik.
  • public/api/rule_generator.php (neu): GET ?action=preview (nur lesen) und POST ?action=apply (schreibt unter demselben rules.json.lock wie rules.php/lib/blacklist.php).
  • public/index.php, public/assets/app.js: Button + Vorschau-Modal.

Review

Zwei Runden code-reviewer + security-checker. Der code-reviewer hat einen echten Bug gefunden und im zweiten Commit behoben: INBOX wäre als Regel-Ziel wählbar gewesen, hätte aber die Lua-Generierung für den ganzen Account zum Absturz gebracht (lib/generate.php deklariert dafür keine Ordner-Variable). Außerdem behoben: fehlender Fallback für Accounts ohne bisherige rules.json, fehlende Cross-Ordner-Konflikterkennung im selben Scan, ungewollte Groß-/Kleinschreibungs-Normalisierung bestehender Regel-Einträge beim Ergänzen, sowie eine Obergrenze/Zeitlimit für den Scan über alle Ordner. Security-Review ohne kritische/mittlere Funde (sauberes Cross-User-Scoping, durchgängiges lua_str()-Escaping, Auth/CSRF wie bei den übrigen Endpunkten).

Getestet an einem zweiten Konto mit realem, bisher ungefiltertem Ordnerinhalt.

🤖 Generated with Claude Code

Closes #3 ## Was Neuer Button „🪄 Regeln aus Ordnern generieren" auf der Filterregeln-Seite: - Scannt alle IMAP-Ordner des Kontos (außer INBOX, dem Spam-Zielordner) und liest die Absenderdomains aus dem vorhandenen Ordnerinhalt. - Zeigt eine **Vorschau** mit einer Checkbox pro Ordner — vorausgewählt sind alle außer erkannten System-Ordnern (Gesendet/Sent, Papierkorb/Trash, Entwürfe/Drafts, Junk), aber frei umschaltbar. - ⚠️ markiert Domains, die schon anderswo verwendet werden — in einer anderen Regel, der Sperrliste, der Whitelist, oder in einem *anderen* Ordner-Vorschlag im selben Scan. - Bestätigt der User die Auswahl: neue Regeln werden angelegt, bestehende (gleicher Zielordner) um die neuen Domains ergänzt. **Nichts wird geschrieben, bevor der User bestätigt.** - Regelname/-pfad orientiert sich am Ordnerpfad (führendes „INBOX/" entfällt), neue Unterordner-Regeln werden automatisch vor der zugehörigen Root-Regel einsortiert (bestehende Reihenfolge-Anforderung der App). - **Einmalige, manuell angestoßene Aktion** — bewusst *kein* Dauer-Automatismus wie bei der Sperrliste, da eine falsche Regel hier künftig echte Mail in den falschen Ordner verschiebt statt nur Spam falsch einzuordnen. - Freemailer- vs. Domain-Unterscheidung ist explizit **nicht** automatisiert (v1) — wird bei Bedarf manuell in der Vorschau korrigiert bzw. die Regel danach im normalen Editor angepasst. ## Wie - `lib/rule_generator.php` (neu): Scan-, Vorschlags- und Anwenden-Logik. - `public/api/rule_generator.php` (neu): `GET ?action=preview` (nur lesen) und `POST ?action=apply` (schreibt unter demselben `rules.json.lock` wie `rules.php`/`lib/blacklist.php`). - `public/index.php`, `public/assets/app.js`: Button + Vorschau-Modal. ## Review Zwei Runden `code-reviewer` + `security-checker`. Der code-reviewer hat einen echten Bug gefunden und im zweiten Commit behoben: INBOX wäre als Regel-Ziel wählbar gewesen, hätte aber die Lua-Generierung für den ganzen Account zum Absturz gebracht (`lib/generate.php` deklariert dafür keine Ordner-Variable). Außerdem behoben: fehlender Fallback für Accounts ohne bisherige `rules.json`, fehlende Cross-Ordner-Konflikterkennung im selben Scan, ungewollte Groß-/Kleinschreibungs-Normalisierung bestehender Regel-Einträge beim Ergänzen, sowie eine Obergrenze/Zeitlimit für den Scan über alle Ordner. Security-Review ohne kritische/mittlere Funde (sauberes Cross-User-Scoping, durchgängiges `lua_str()`-Escaping, Auth/CSRF wie bei den übrigen Endpunkten). Getestet an einem zweiten Konto mit realem, bisher ungefiltertem Ordnerinhalt. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
- lib/rule_generator.php (new): scans IMAP folders (excluding a configurable
  default set — INBOX, the Spam target, Sent/Trash/Drafts-like system
  folders in German+English), extracts sender domains per folder, and
  builds a preview of new/updated rules against the current rules.json
  (flagging domains already used elsewhere: another rule, the blacklist,
  or the whitelist)
- One-time, manually triggered action — not a continuous auto-learn loop
  like the blacklist, since a wrong rule here silently misroutes real mail
  instead of just misclassifying spam
- Rule name/target derive from the folder path ("INBOX/" prefix stripped);
  new subfolder rules are auto-inserted before their ancestor folder's rule
  to satisfy the existing "subfolder rules before root rules" ordering
  requirement, regardless of processing order
- Domain extraction is validated against a plausible domain pattern before
  ever reaching the preview or generated Lua
- public/api/rule_generator.php (new): GET ?action=preview (scan + build
  suggestions, no writes) and POST ?action=apply (user-confirmed selections
  only), sharing the same rules.json.lock as rules.php/blacklist.php
- public/index.php, public/assets/app.js: "🪄 Regeln aus Ordnern
  generieren" button on the Filterregeln page opens a preview modal with a
  checkbox per suggestion (pre-selected per the exclusion heuristic,
  overridable) and a ⚠️ conflict marker per domain; nothing is written
  until the user confirms

Co-authored-by: Claude <claude@anthropic.com>
- Hard-exclude INBOX from scanning entirely (was only unchecked-by-default
  before) and reject it defensively in rulegen_apply() too — lib/generate.php
  never declares an INBOX folder variable for rule targets, so a selected
  INBOX suggestion would have broken Lua generation for the whole account
- apply now falls back to an empty rules structure instead of erroring when
  rules.json doesn't exist yet (account that never used the regular editor)
- Flag domains that show up as "new" in more than one folder's suggestion
  in the same scan (not just against already-saved rules/blacklist/whitelist)
- Merging into an existing rule now only appends genuinely new domains
  instead of rewriting the whole from_addresses array through mb_strtolower,
  which silently reformatted the user's original casing
- Cap per-folder scan at 5000 messages and raise the request time limit,
  since preview scans every folder in one request

Co-authored-by: Claude <claude@anthropic.com>
DasAoD merged commit a2681c8262 into main 2026-08-17 13:01:20 +02:00
Sign in to join this conversation.
No description provided.