fix(attachments): download/view attachments on cross-account All-Mail messages

Blobs are scoped per JMAP account, but the attachment download/preview path
always used the active account's client and accountId. Opening a message from a
different account in the unified / All-Mail view and downloading (or previewing)
an attachment therefore 404'd against the active account.

Route the blob fetch to the message's source instead:
- resolveBlobSource() picks the owning login's client
  (getClientForAccount(sourceClientAccountId)) and the owner accountId
  (sourceAccountId) for delegated/shared blobs, in the unified view;
- handleDownloadAttachment + the attachment-preview handlers use it;
- downloadBlob / fetchBlobAsObjectUrl / fetchBlobArrayBuffer gain an accountId
  param (getBlobDownloadUrl/fetchBlob already had one).

Adds 10-attachments: an attachment on another account's All-Mail message
downloads with the correct bytes (verified to fail without the routing).
This commit is contained in:
Stefan Hildebrandt
2026-07-11 21:15:43 +02:00
parent c3acb537d0
commit 26c3d07d56
7 changed files with 161 additions and 23 deletions
+3 -3
View File
@@ -222,9 +222,9 @@ export interface IJMAPClient {
): Promise<{ blobId: string; size: number; type: string }>;
getBlobDownloadUrl(blobId: string, name?: string, type?: string, accountId?: string): string;
fetchBlob(blobId: string, name?: string, type?: string, accountId?: string): Promise<Blob>;
fetchBlobAsObjectUrl(blobId: string, name?: string, type?: string): Promise<string>;
fetchBlobArrayBuffer(blobId: string, name?: string, type?: string): Promise<ArrayBuffer>;
downloadBlob(blobId: string, name?: string, type?: string): Promise<void>;
fetchBlobAsObjectUrl(blobId: string, name?: string, type?: string, accountId?: string): Promise<string>;
fetchBlobArrayBuffer(blobId: string, name?: string, type?: string, accountId?: string): Promise<ArrayBuffer>;
downloadBlob(blobId: string, name?: string, type?: string, accountId?: string): Promise<void>;
// ── Identities ────────────────────────────────────────────────
getIdentities(): Promise<Identity[]>;