Files
2026-04-10 10:42:18 +02:00

5.6 KiB

email plugin — deferred features

Note: Account management lives in the main settings overlay under "mail" (added via hyprcrd.settings.registerTab). The email overlay shows a welcome screen with a "configure accounts" button when no accounts are set up — that button switches to the settings tab.

This is the MVP scope. The following are intentionally not implemented yet and can be added later as plugin-only changes (no core touch needed):

Protocol

  • SMTP / sending — currently read-only. Add SmtpClient.php + a compose view in the overlay. Reuse account credentials (most providers use the same login for IMAP + SMTP, just different host/port).
  • STARTTLS on port 143 — only direct SSL on 993 works today. Need to send STLS command after the greeting and wrap the socket via stream_socket_enable_crypto.
  • IDLE / push — currently each loadMessages() is a fresh poll. IDLE would let the server notify on new mail. Tricky with PHP request model; probably needs a small daemon or long-poll endpoint.
  • OAuth2 (XOAUTH2) — Gmail/O365 require OAuth instead of app passwords for full functionality. Big chunk of work: token exchange, refresh, storage.
  • Multiple folders — schema has folder column but UI exposes only one. Add folder list pane (like Thunderbird's left sidebar) using LIST "" *.
  • Server-side search — UID SEARCH FROM "...", SUBJECT "...", SINCE date, etc. Currently the UI shows the latest 30 only.
  • Threading — group messages by In-Reply-To / References headers.
  • Mark as read / unread — UID STORE +FLAGS (\Seen).
  • Move to folder — UID COPY <folder> + delete from current.
  • Delete on server — implemented: multi-select checkboxes in list pane, "delete" button in selection bar, calls UID STORE +FLAGS (\Deleted) + EXPUNGE (see ImapClient::deleteUids()).

Body & attachments

  • HTML email rendering — implemented: opt-in "view as html" button per message renders the HTML in a sandboxed iframe (srcdoc + DOMPurify). External images are blocked by default; "load images (N)" button reveals them on demand. CSS background-image url() declarations are also stripped from inline styles. cid: refs aren't loaded (would need a separate route).
  • Inline images — cid: references inside HTML need to fetch multipart/related parts and serve them via a data: URL.
  • Attachments list + download — parse Content-Disposition: attachment parts, expose them in the message header bar, route through a backend endpoint that streams the decoded part to the browser.

UI / UX

  • Pagination — currently hard limit of 30 newest messages.
  • Per-account folder + signature settings — extend the form.
  • Notification on new mail — needs IDLE or polling daemon.
  • Drag-extract — drag a message onto the board to create a card at that position.
  • Reply / forward — needs SMTP first.
  • Address book / autocomplete — pull historic sender addresses.

Spam detection (current state)

  • Multi-signal heuristic scorer (SpamDetector.php): header signals (X-Spam-*, SPF/DKIM/DMARC), subject heuristics (CAPS, punctuation, EN+DE keyword phrases, Cyrillic homoglyphs), sender heuristics (suspicious TLDs, digit-heavy domains, Reply-To mismatch, display-name impersonation), bulk-mail signal. Three levels: clean / suspicious / spam.
  • Visual marking in message list: red row + badge for spam, yellow row + badge for suspicious. Hover tooltip shows reasons.
  • Body-content scoring — SpamDetector::score() already accepts a body parameter; wire it up in the message-open route to refine the score with link density / short URL detection. Currently the list view scores headers only.
  • User feedback loop — implemented: email_spam_rules table holds block/allow rules per sender email or domain. UI has "select spam" bulk-select button + "spam" / "not spam" buttons in the selection bar. Free email providers (gmail, gmx, etc.) get email-only rules to avoid blocking entire providers; other domains get domain-level rules. Block adds +15, allow subtracts -15 in SpamDetector.
  • Bayesian classifier — collect tokens from user-marked spam vs ham; train a per-account model. SQLite-backed, no external deps.
  • Spam rules management UI — currently rules are write-only via mark buttons. A list view in settings would let users see and remove stale rules.

Hardening

  • Rate limiting on the test endpoint to prevent credential brute force.
  • Better error messages — currently raw IMAP server errors leak through. Should map common ones (auth failed, connection refused, cert error) to friendly text.
  • Cert pinning option for users on self-hosted mail servers.
  • Connection reuse — every API call opens + closes IMAP. A short session cache (per account, 30s) would be much faster.

Why these were deferred

The scope of "build an email plugin" is essentially "build a mail client", which is a multi-month project on its own. The MVP proves the plugin system can host a non-trivial feature with a backend, schema, encrypted credentials, custom API routes, and a complex UI — all without touching the hyprcrd core. Each item above can be added as an isolated patch to this plugin directory, and the plugin can still be disabled in settings to fully remove the feature.