Skip to content

Change realm download to not use in-memory blob#3944

Merged
backspace merged 9 commits intomainfrom
download-stream-cs-10145
Feb 4, 2026
Merged

Change realm download to not use in-memory blob#3944
backspace merged 9 commits intomainfrom
download-stream-cs-10145

Conversation

@backspace
Copy link
Contributor

@backspace backspace commented Feb 3, 2026

This changes the endpoint to support either a header or token so the UI can download via a link and not need to contain the entire realm in memory.

screencast 2026-02-03 19-47-31

I also added a Playwright test since this uses the endpoint in a slightly different way.

Previously, realm downloads used fetch() + response.blob() which loaded
the entire archive into JavaScript memory before triggering the download.
For large realms, this could cause memory issues.

Now the client uses native browser download streaming by:
- Adding support for auth token via query param on the server
- Creating an anchor element to trigger direct browser navigation
- Letting the browser handle the download natively (streams to disk)

Adds server-side tests for token query param auth and Playwright E2E test.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@github-actions
Copy link

github-actions bot commented Feb 3, 2026

Preview deployments

@github-actions
Copy link

github-actions bot commented Feb 3, 2026

Host Test Results

    1 files  ±0      1 suites  ±0   1h 44m 26s ⏱️ + 1m 49s
1 944 tests ±0  1 927 ✅ ±0  17 💤 ±0  0 ❌ ±0 
1 959 runs  ±0  1 942 ✅ ±0  17 💤 ±0  0 ❌ ±0 

Results for commit 24f413e. ± Comparison against base commit 4a90bd7.

♻️ This comment has been updated with latest results.

Simplifies the download implementation by using BoxelButton with
@as='anchor' and the download attribute, rather than programmatically
creating and clicking an anchor element via JavaScript.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@backspace backspace marked this pull request as ready for review February 4, 2026 04:22
@backspace backspace requested a review from a team February 4, 2026 04:23
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f4a6615042

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 105 to 109
private get downloadRealmURL() {
let downloadURL = new URL('/_download-realm', this.args.realmURL);
downloadURL.searchParams.set('realm', this.args.realmURL);
// Include token for authenticated streaming download (browser navigates directly)
let token = this.realm.token(this.args.realmURL);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reauth is bypassed for expired download tokens

This link now bakes the current realm token into the URL, which means downloads no longer go through network.authedFetch’s authorization middleware (see packages/runtime-common/authorization-middleware.ts) that retries on 401 by calling reauthenticate. When a user has been logged in long enough for the JWT to expire, clicking “Download” will yield a 401 and there’s no retry or recovery path, whereas the previous implementation would refresh the token and succeed. Consider using a short-lived download token minted on demand or a fetch-based flow that can reauthenticate before redirecting.

Useful? React with 👍 / 👎.

@backspace backspace added the enhancement New feature or request label Feb 4, 2026
let downloadURL = new URL('/_download-realm', this.args.realmURL);
downloadURL.searchParams.set('realm', this.args.realmURL);
// Include token for authenticated streaming download (browser navigates directly)
let token = this.realm.token(this.args.realmURL);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another approach could be to attach a signature obtained by hashing the token plus the URL, so that token only authorizes downloading the particular URL you are sending. Might be good in case we need to use this approach for anything else.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍🏻 that’s in bd465d6, thanks

backspace and others added 2 commits February 3, 2026 22:42
When authenticating via query param token, a signature is now required
that binds the token to the specific download URL. This prevents someone
from intercepting the URL and reusing the token for other API endpoints.

The signature is HMAC-SHA256(token, urlPath) computed by:
- Browser: Web Crypto API (async)
- Server: Node.js crypto module (sync)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@backspace backspace merged commit 55493d9 into main Feb 4, 2026
100 of 101 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants