Skip to content

Implement IMAP IDLE with admin observability#124

Merged
tayyebi merged 2 commits into
mainfrom
copilot/implement-imap-idle-feature
Apr 21, 2026
Merged

Implement IMAP IDLE with admin observability#124
tayyebi merged 2 commits into
mainfrom
copilot/implement-imap-idle-feature

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 21, 2026

Summary

Implements IMAP IDLE (RFC 2177) for the webmail client using Server-Sent Events (SSE), and exposes active IDLE sessions in the admin area.

What is IMAP IDLE here?

The webmail reads mail directly from Maildir on disk without going through the IMAP protocol. IMAP IDLE is the mechanism where the server pushes new-mail notifications to the client instead of the client polling. The web equivalent is Server-Sent Events — a persistent HTTP connection over which the server streams events as they happen.

Changes

Backend

  • tokio-stream added as a dependency for bridging tokio::sync::mpsc receivers into async Streams required by axum's Sse type
  • ImapIdleSession struct and ImapIdleRegistry (Arc<Mutex<HashMap<String, ImapIdleSession>>>) added to AppState (in src/web/mod.rs)
  • GET /webmail/idle?account_id=X&folder=Y SSE endpoint (src/web/routes/webmail.rs):
    • Validates account and resolves Maildir path
    • Registers session in the in-memory registry
    • Spawns a background task that polls Maildir/new/ every 5 s (with MissedTickBehavior::Delay)
    • Emits a mailbox SSE event {"new_count": N} when the count changes
    • Automatically deregisters the session when the client disconnects (channel send error)
  • GET /imap-idle admin page (src/web/routes/imap_idle.rs): lists all currently active IDLE sessions with username, domain, folder, connected_at, last_ping_at

Frontend

  • Webmail inbox (templates/webmail/inbox.html) gains a JavaScript SSE client that:
    • Opens an EventSource to /webmail/idle when an account is selected
    • Shows a dismissible notification banner when new mail arrives
    • Reconnects automatically after 15 s on error
    • Reads account_id and folder from HTML data-* attributes (not direct JS template interpolation — avoids any XSS risk)
  • Navigation (templates/layout.html) gains an IMAP IDLE link under the Clients group
  • Dashboard (templates/dashboard.html + src/web/routes/dashboard.rs) shows a live IMAP IDLE counter card

Dovecot config

  • templates/config/dovecot.conf.txt gains imap_idle_notify_interval = 2 mins, explicitly configuring Dovecot's native IMAP IDLE notification interval for external IMAP clients

Copilot AI and others added 2 commits April 21, 2026 13:16
Copilot AI requested a review from tayyebi April 21, 2026 13:24
@tayyebi tayyebi marked this pull request as ready for review April 21, 2026 13:44
@tayyebi tayyebi merged commit 4c93113 into main Apr 21, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants