fix(addon): authenticate teardown cleanup so the add-on removes orphaned upload parts#989
Open
aaspinwall wants to merge 2 commits into
Open
fix(addon): authenticate teardown cleanup so the add-on removes orphaned upload parts#989aaspinwall wants to merge 2 commits into
aaspinwall wants to merge 2 commits into
Conversation
…" stall) Rework the client-side upload path so large files start uploading promptly and no longer hit Firefox's 2 GB Blob limits. - Stream the source via blob.stream() from offset 0 and produce hashed, zipped parts lazily (streamZippedParts). Uploading now starts after the first 100 MB window instead of after the whole file is hashed (#980), and no high-offset slice/arrayBuffer read is issued, which is what fails on files >2 GB (#981). Each uploaded part blob is released after it lands so a multi-GB file doesn't stay fully resident. - Assemble zipBlob output from JSZip's streaming chunks so it never builds a single >2 GB Blob member — the "can't construct the Blob" crash in formatBlob for typeless >2 GB files (#981). The archive bytes are byte-identical to the previous generateAsync output, so there is no download/format change. - Add a dedicated 'hashing' ProcessStage + banner label so the UI reflects the real phase instead of overloading 'idle' as "Hashing…". Backwards compatible: identical wire format (per-part raw-bytes hash, zip parts, part numbering), no schema or API change. Covered by unit tests (streamZippedParts window/hash/round-trip, zipBlob byte-identical) and an end-to-end Firefox upload→download→checksum of 1/2/3 GB files. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…parts The best-effort pagehide cleanup that removes already-written multipart parts when the user closes the tab/popup mid-upload issued a raw keepalive fetch with cookie auth only. That works in the Send web app but not in the Thunderbird add-on, which authenticates via an OIDC Bearer token bridge and has no usable backend cookie — so the cleanup 401'd and orphaned parts were stranded in the add-on only. Pre-capture the OIDC access token at upload start (getAccessToken is async and can't be awaited at unload) via the same dynamic-import pattern api.ts uses, and attach it as a Bearer header on the teardown fetch, keeping credentials:'include' as the web cookie fallback. Now cancel/close cleanup behaves identically in both contexts. Adds a regression test asserting a pagehide during an in-flight multipart upload issues an authenticated keepalive POST to /api/uploads/cleanup. Rebased onto #984 (streaming large-file uploads); the test uses that PR's streamZippedParts producer model. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed?
The best-effort teardown cleanup that removes already-written multipart parts when a user closes the tab/popup mid-upload (
Uploader.teardownCleanupinpackages/send/frontend/src/lib/upload.ts) now authenticates with the OIDC Bearer token instead of relying on a cookie.doUploadpre-captures the access token at upload start (via the same dynamic-import-of-auth-storepatternlib/api.tsuses), becausegetAccessToken()is async and can't be awaited at thepagehideunload event.teardownCleanupattachesAuthorization: Bearer <token>on itskeepalivefetch, keepingcredentials: 'include'as the web cookie fallback.pagehideduring an in-flight multipart upload issues an authenticated keepalivePOST /api/uploads/cleanupwith the Bearer header.AI disclosure: Substantially agent-written by Claude Code (Anthropic, Opus 4.8) under human direction — the human set the scope, chose to base the change on #984, and reviewed the diff (including a senior-review pass whose findings were applied). ~2 files, +114/−7.
Why?
The Send web app authenticates with cookies, but the Thunderbird add-on authenticates via an OIDC Bearer token bridge and has no usable backend cookie in its extension-popup origin. So the cookie-only teardown fetch 401'd in the add-on — meaning the orphaned-part cleanup from #965 was effectively web-only, and cancel/tab-close mid-upload stranded bytes in the bucket for add-on users. This makes cancel/close cleanup behave identically in both surfaces, so we maintain one upload workflow.
Limitations and Notes
pagehide); the reaper covers that case.main: this branch targetsfix/stream-large-file-uploadsso the diff shows only this change. The test uses that PR'sstreamZippedPartsproducer model. Retarget tomainonce fix(send): stream large-file uploads (fix >2GB failures and "Hashing…" stall) #984 merges.Applicable Issues
Relates to #887 (multipart orphaned-storage cleanup).
Screenshots
No UI change.