feat: expose HTML email content and inline MIME parts via API#301
feat: expose HTML email content and inline MIME parts via API#301sarcasticbird wants to merge 2 commits intowesm:mainfrom
Conversation
Add GetMessageRaw to the query engine interface for raw MIME retrieval
with zlib decompression. When the engine is available, handleGetMessage
returns body_html alongside body for rich email rendering. Add inline
MIME parts endpoint (GET /messages/{id}/inline/{cid}) for serving
CID-referenced images embedded in HTML emails.
- Block SVG and non-image content types in inline MIME endpoint - Use normalized Content-Type in response header (strip MIME params) - Filter on IsInline to prevent serving regular attachments - Set Cache-Control: private (user-specific content) and Content-Disposition: inline - Wrap bare errors in getMessageRawShared with message ID context - Add tests: engine-path body_html, inline PNG, SVG/XHTML rejection, CID not found, no engine, message not found
roborev: Combined Review (
|
|
The inline endpoint is consistent with the existing `GetMessage` detail endpoint — neither filters on `deleted_from_source_at`. The `getMessageByQueryShared` function (used by `GetMessage(id)`) has no deleted-message filter; it uses a bare `WHERE m.id = ?`. The `deleted_from_source_at` filtering is applied at the list/search/aggregate query level (`MessageFilter.HideDeletedFromSource`), not on single-message lookups. This is intentional — if a client can view a message's detail, it should also be able to view its inline parts. Adding a deleted filter to the inline endpoint but not to `GetMessage` would be inconsistent and wouldn't actually prevent access to the message content. |
Summary
GetMessageRawto the query engine interface for raw MIME retrieval with zlib decompression (SQLite, DuckDB, remote stub, mock)GET /messages/{id}returnsbody_htmlalongsidebodyfor rich email renderingGET /messages/{id}/inline/{cid}endpoint for serving CID-referenced inline images embedded in HTML emailsCache-Control: private, and filters onIsInlineflagMotivation
query.MessageDetailalready has separateBodyTextandBodyHTMLfields, but the API collapses them into a singlebodyvia the store layer. Clients that want to render rich HTML emails need the HTML body and access to inline MIME parts (images referenced viacid:URLs). This adds both without touching the store layer — the engine path is preferred when available, with a clean fallback to the existing store path.Changed files
engine.go,shared.go,sqlite.go,duckdb.go,remote/engine.go,mock_engine.goGetMessageRawmethod + shared zlib decompressionhandlers.go,server.gobody_htmlin message detail, inline MIME endpointsqlite_crud_test.go,handlers_test.goGetMessageRawCRUD tests, inline endpoint tests (PNG, SVG rejection, XHTML rejection, CID not found, no engine, message not found), engine-pathbody_htmltest