Feature: preview .eml (message/rfc822) attachments like an email

Clicking an embedded email attachment (bounce/DSN, forward-as-attachment, ...)
opened only a download. Add an 'eml' preview kind: FilePreviewModal parses the
blob with postal-mime (dynamic-imported, off the bundle) and renders it via a
new EmlPreview component - header (from/to/subject/date) + body + the message's
own attachments.

The body is sanitized with DOMPurify (sanitizeEmailHtmlForIframe) AND rendered
in a fully-locked sandbox iframe (sandbox="" - no scripts, no same-origin), so a
script-bearing .eml can never execute in-origin. Reuses the email_viewer locale
namespace (no new keys).
This commit is contained in:
dealerweb
2026-06-01 17:25:14 +02:00
committed by Linus Rath
parent 26ccf9e3b4
commit 2e4d3d4bc6
3 changed files with 130 additions and 1 deletions
+7 -1
View File
@@ -1,4 +1,4 @@
export type FilePreviewKind = 'image' | 'html' | 'text' | 'markdown' | 'pdf' | 'audio' | 'video' | 'unsupported';
export type FilePreviewKind = 'image' | 'html' | 'eml' | 'text' | 'markdown' | 'pdf' | 'audio' | 'video' | 'unsupported';
const IMAGE_EXTENSIONS = new Set(['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg', 'avif', 'bmp', 'ico']);
const AUDIO_EXTENSIONS = new Set(['mp3', 'wav', 'ogg', 'm4a', 'flac', 'aac', 'opus']);
@@ -38,6 +38,12 @@ export function getFilePreviewKind(name?: string, type?: string): FilePreviewKin
return 'html';
}
// Embedded email message (e.g. a bounce/DSN, or forward-as-attachment).
// Rendered by parsing it and showing it like an email, not as a blob.
if (mimeType === 'message/rfc822' || ext === 'eml') {
return 'eml';
}
if (mimeType === 'application/pdf' || ext === 'pdf') {
return 'pdf';
}