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

110 lines
5.6 KiB
Markdown

# 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.
## Folders & search
- [ ] **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.
- [x] **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
- [x] **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)
- [x] **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.
- [x] **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.
- [x] **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.