Skip to content

fix(email): body fetch retry, CID images, re-render fix#219

Merged
Systemsaholic merged 1 commit intomainfrom
feature/issue-196-email-reliability
Apr 16, 2026
Merged

fix(email): body fetch retry, CID images, re-render fix#219
Systemsaholic merged 1 commit intomainfrom
feature/issue-196-email-reliability

Conversation

@Systemsaholic
Copy link
Copy Markdown
Owner

@Systemsaholic Systemsaholic commented Apr 16, 2026

Summary

  • Body fetch retry: IMAP client.download() now retries up to 2 times on transient failures instead of silently returning null (Sentry: undefined Symbol.asyncIterator errors)
  • CID inline images: Embedded images (cid: references) are resolved to base64 data URIs during message parsing — Outlook/corporate emails now display images instead of gray placeholders
  • DOMPurify data URI: ALLOWED_URI_REGEXP updated to pass through data:image/* URIs for resolved CID images
  • Re-render fix: Stabilized trustedDomains array reference with useMemo to prevent sanitization re-running on every profile render cycle

Test plan

  • Open an email that previously showed "Email body unavailable" — should retry and load
  • Open an Outlook email with embedded images — should show actual images, not gray boxes
  • Check browser console on email reader — no excessive re-render logs
  • Image blocking banner still works (load images / trust domain)
  • Already-cached email bodies still load instantly (no IMAP round-trip)

Addresses critical items in #196

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Inline images in emails now display correctly instead of showing placeholders.
    • Improved email synchronization reliability with automatic retry on transient download failures.
    • Enhanced error reporting and handling for email account authentication failures.
  • Performance

    • Optimized email rendering for faster display.

- Add retry logic (up to 2 retries) for IMAP body download failures
  that previously failed silently, leaving emails permanently unloaded
- Resolve CID inline images to base64 data URIs during message parsing
  so embedded images (common in Outlook) display instead of placeholders
- Allow data:image/* URIs through DOMPurify for resolved CID images
- Stabilize trustedDomains memo reference to prevent re-render floods
  from unstable array identity on every profile re-render

Addresses critical items in #196

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 16, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
tailfire-client Building Building Preview, Comment Apr 16, 2026 2:29am
tailfire-ota Building Building Preview, Comment Apr 16, 2026 2:29am

Request Review

@Systemsaholic Systemsaholic merged commit f96c436 into main Apr 16, 2026
1 of 3 checks passed
@Systemsaholic Systemsaholic deleted the feature/issue-196-email-reliability branch April 16, 2026 02:29
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 16, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ea44a106-bfd9-4941-9331-c8f1c7b24457

📥 Commits

Reviewing files that changed from the base of the PR and between 02e3a09 and e26f7e0.

📒 Files selected for processing (3)
  • apps/admin/src/app/emails/inbox/_components/email-reader.tsx
  • apps/admin/src/lib/sanitize-email-html.ts
  • apps/api/src/email-accounts/imap-sync.service.ts

📝 Walkthrough

Walkthrough

These changes implement retry logic for IMAP body downloads with special handling for authentication failures, enable inline CID image resolution by converting them to base64 data URIs, and update frontend sanitization to permit and handle these data URIs in email HTML.

Changes

Cohort / File(s) Summary
IMAP Body Fetching & Parsing
apps/api/src/email-accounts/imap-sync.service.ts
Added retry loop (MAX_RETRIES = 2) to fetchEmailBody() with transient failure and empty download handling; skips retries on authentication failures. Enhanced parseMessageSource() to resolve inline cid: images by converting matched attachments to data: URIs and replacing HTML references.
Email HTML Sanitization
apps/admin/src/lib/sanitize-email-html.ts
Updated DOMPurify configuration to allow data:image/ URIs in sanitized output. Modified CID image placeholder handling to expect resolved data URIs; changed alt text from [Embedded image — not yet supported] to [Embedded image].
Email Reader Dependencies
apps/admin/src/app/emails/inbox/_components/email-reader.tsx
Memoized trustedDomains with dependency on profile.platformPreferences.trustedImageDomains. Added senderDomain to sanitizeEmailHtml dependency array to track sender domain changes for recomputation.

Sequence Diagram

sequenceDiagram
    participant Client as Email Reader<br/>(Frontend)
    participant IMAPService as IMAP Service
    participant Parser as Message Parser
    participant Sanitizer as HTML Sanitizer
    participant Renderer as Email Renderer

    Client->>IMAPService: fetchEmailBody(accountId, emailId)
    loop Retry up to MAX_RETRIES+1
        alt IMAP Success
            IMAPService->>IMAPService: Download IMAP body
            break on Authentication Failure
                IMAPService->>IMAPService: handleImapAuthFailure()
            end
        else Transient Failure / Empty
            IMAPService->>IMAPService: Log warning & retry
        end
    end
    IMAPService->>Parser: parseMessageSource(buffer)
    Parser->>Parser: Extract bodyHtml, attachments
    Parser->>Parser: For each cid: image in HTML<br/>Convert attachment to data: URI
    Parser-->>IMAPService: Return {bodyHtml, bodyText, snippet}
    IMAPService-->>Client: Return resolved email body
    Client->>Sanitizer: sanitizeEmailHtml(bodyHtml)
    Sanitizer->>Sanitizer: Purify HTML<br/>(allow data:image/ URIs)
    Sanitizer-->>Renderer: Return sanitized HTML
    Renderer->>Renderer: Render email with<br/>inline images
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

  • Email Module Reliability Overhaul #196: Addresses IMAP body download retries with transient failure handling and inline CID image resolution to data URIs, matching the exact requirements described in the issue.

Possibly related PRs

Poem

🐰 Hops of retry, images dance,
Data URIs get their chance,
CIDs transform to base64 streams,
Email renders in my dreams! 🖼️
No more broken, all flows sweet,
IMAP retries can't be beat!

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/issue-196-email-reliability

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

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.

1 participant