From cdb31634a69ae0fb4a85b01367d5c14e5d649f60 Mon Sep 17 00:00:00 2001 From: Stefan Hildebrandt <695494+hildebrandttk@users.noreply.github.com> Date: Wed, 8 Jul 2026 21:16:59 +0200 Subject: [PATCH] fix(attachments): route all viewer blob fetches for cross-account messages Extend the cross-account blob routing beyond download/preview to every blob fetch in the message viewer, so a message opened from a different account in the unified / All-Mail view renders and exports correctly instead of 404ing against the active account: - inline cid: images, drag-to-desktop, attachment thumbnails, the "download all" zip bundle, and the S/MIME / TNEF / embedded-rfc822 blob reads now use a resolved blobClient (getClientForAccount(sourceClientAccountId)) and the owner blobAccountId (sourceAccountId), computed once from the open message's source; - fetchBlobAsObjectUrl / fetchBlobArrayBuffer / fetchBlob calls pass the accountId (the client methods gained the param in the previous commit); - non-cross-account behaviour is unchanged (blobClient === active client). Extends 10-attachments with an inline-image case (verified to fall back to the placeholder without the routing). The SMTP helper can now send multipart/related inline images. --- integration/README.md | 10 ++++--- integration/tests/10-attachments.spec.ts | 34 ++++++++++++++++++++++++ integration/tests/helpers/smtp.ts | 26 +++++++++++++++++- 3 files changed, 65 insertions(+), 5 deletions(-) diff --git a/integration/README.md b/integration/README.md index d6e6c50f..303b9df1 100644 --- a/integration/README.md +++ b/integration/README.md @@ -112,10 +112,12 @@ because the UI behaviour is currently incomplete. Worth a look: "Move to" submenu offers the shared folder, but clicking it is a no-op. Shared ⇆ shared (same owner) moves work. Pinned with `test.fail` in `08-shared-moves`. -- **Cross-account attachments (fixed).** Blobs are account-scoped, so viewing/ - downloading an attachment on an All-Mail message from another account 404'd - against the active account. The download/preview path now routes to the - message's owning client + accountId (`10-attachments`). +- **Cross-account attachments & inline images (fixed).** Blobs are account- + scoped, so viewing/downloading/previewing an attachment, rendering an inline + `cid:` image, dragging out, and the bundle/S-MIME/TNEF/embedded-message + fetches on an All-Mail message from another account 404'd against the active + account. Every viewer blob fetch now routes to the message's owning client + + accountId (`10-attachments` covers download + inline image). ## How the tests work diff --git a/integration/tests/10-attachments.spec.ts b/integration/tests/10-attachments.spec.ts index 159e5fa8..42315cd2 100644 --- a/integration/tests/10-attachments.spec.ts +++ b/integration/tests/10-attachments.spec.ts @@ -74,4 +74,38 @@ test.describe('Cross-account attachments', () => { for await (const c of stream) chunks.push(c as Buffer); expect(Buffer.concat(chunks).toString()).toContain(ATT.content); }); + + test('an inline image on another account\'s All-Mail message renders', async ({ page }) => { + const subject = `IT inline ${Date.now()}`; + // 1x1 PNG referenced from the HTML body via cid. + const png = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=='; + await sendMail({ + from: bob.email, authPass: bob.password, to: bob.email, subject, body: '', + inlineImage: { cid: 'inlinepic', contentType: 'image/png', base64: png, html: '
see below