/** * Retry identity for a selected attachment. A file picker returns a fresh File * object on reselection; metadata alone can also collide across different bytes. */ export async function getMessageFileIdentity(file: Pick) { const bytes = await file.arrayBuffer() const subtle = globalThis.crypto?.subtle // Self-hosted HTTP deployments may lack WebCrypto. Exact bytes provide a // collision-free in-memory fallback, rather than silently weakening the key. const digest = subtle ? await subtle.digest("SHA-256", bytes) : bytes const key = Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("") return JSON.stringify([file.name, file.type, subtle ? "sha256" : "bytes", key]) }