Skip to content

bugfix: support Trino over plain HTTP (secure-context UUID fallback) - #382

Open
F3l1x1vo wants to merge 3 commits into
mainfrom
bugfix/crypto-http
Open

F3l1x1vo wants to merge 3 commits into
mainfrom
bugfix/crypto-http

Conversation

@F3l1x1vo

Copy link
Copy Markdown
Collaborator

crypto.randomUUID() is only exposed in secure contexts. Over plain HTTP on a non-localhost host it is undefined, so every client-side call threw TypeError: crypto.randomUUID is not a function.

tabStore is built at module scope, so the throw happened during hydration of /trino: SSR succeeded (Node has a global crypto) and the browser received 200, but the page stayed blank and nothing rendered.

Add randomUUID() in $lib/utils/uuid.js, which keeps the native fast path and falls back to crypto.getRandomValues() (not secure-context gated), and use it at the four client-side call sites:

  • tab-store (fatal — module-scope init)
  • toast store
  • storage connection ids
  • upload entries

Server-side code keeps using node:crypto.

Adds unit tests for the fallback and a browser regression test that removes crypto.randomUUID, and documents the secure-context constraint in AGENTS.md.

Note: this only fixes the crash. HTTP-only deployment remains inadvisable — Trino credentials travel as Basic auth, and the cookie Secure flag and SvelteKit ORIGIN/CSRF settings still need configuring for plain HTTP.

`crypto.randomUUID()` is only exposed in secure contexts. Over plain HTTP on
a non-localhost host it is `undefined`, so every client-side call threw
`TypeError: crypto.randomUUID is not a function`.

`tabStore` is built at module scope, so the throw happened during hydration
of /trino: SSR succeeded (Node has a global crypto) and the browser received
200, but the page stayed blank and nothing rendered.

Add `randomUUID()` in `$lib/utils/uuid.js`, which keeps the native fast path
and falls back to `crypto.getRandomValues()` (not secure-context gated), and
use it at the four client-side call sites:

- tab-store (fatal — module-scope init)
- toast store
- storage connection ids
- upload entries

Server-side code keeps using `node:crypto`.

Adds unit tests for the fallback and a browser regression test that removes
`crypto.randomUUID`, and documents the secure-context constraint in AGENTS.md.

Note: this only fixes the crash. HTTP-only deployment remains inadvisable —
Trino credentials travel as Basic auth, and the cookie `Secure` flag and
SvelteKit `ORIGIN`/CSRF settings still need configuring for plain HTTP.
@F3l1x1vo
F3l1x1vo requested a review from Bohreromir October 15, 2026 09:16
@F3l1x1vo F3l1x1vo self-assigned this Oct 15, 2026
@github-actions

github-actions Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 64.92% 8530 / 13139
🔵 Statements 63.98% 11447 / 17890
🔵 Functions 66.41% 2721 / 4097
🔵 Branches 55.12% 4920 / 8925
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
src/lib/components/storage/modals/upload/UploadModal.svelte 74.22% 47.33% 79.23% 70.39% 97-98, 130, 141-143, 158-160, 167-169, 173-174, 201-203, 218-222, 282-335, 349-351, 364-392, 411, 533-536, 615-626
src/lib/storage/download.ts 96.77% 100% 85.71% 100% 40
src/lib/storage/state.svelte.ts 77.59% 65.82% 84.78% 78.71% 488-493, 702-732, 770-772, 812-819, 854-856, 996-998, 85, 96, 134, 173-176, 181, 186-189, 299, 318, 332-333, 342, 379, 391, 395, 407, 444, 448, 489-492, 522-523, 531-537, 540-541, 552-553, 556-561, 591, 604, 611-645, 649, 657, 665, 667, 683, 685, 693-730, 746-747, 764-771, 776, 785, 802, 803, 813-818, 855, 867, 894-896, 917-929, 953, 955, 956, 964, 969, 984, 987-988, 997, 1006
src/lib/storage/tabs.svelte.ts 85.51% 80.25% 93.33% 88.13% 186, 193, 249, 284, 297, 299, 312, 317, 332, 338, 372-373, 395, 415, 427-431, 439, 475-486, 524-525, 528, 533
src/lib/storage/transfer.ts 92.62% 79.22% 95.23% 93.68% 43, 47-49, 53-57, 65, 102, 244
src/lib/stores/tab-store.svelte.ts 85.82% 73.77% 94.59% 90% 58-70, 76, 80-86, 102, 111, 116, 121, 126, 143, 201, 231
src/lib/stores/toast.svelte.ts 90.9% 100% 75% 87.5% 17
src/lib/utils/uuid.ts 100% 100% 100% 100%
Generated in workflow #1098 for commit 45d4c33 by the Vitest Coverage Report Action

# Conflicts:
#	src/lib/storage/connection-storage.ts
#	src/lib/stores/tab-store.svelte.spec.ts
#	src/lib/stores/toast.svelte.ts
`crypto.randomUUID` is only exposed in secure contexts, so it is `undefined`
over plain HTTP on a non-localhost host. The S3 file browser added in #208 mints
ids on the client in four places that call it directly, which throws
`TypeError: crypto.randomUUID is not a function`:

- tabs: initial tab, added tab, restored tabs
- downloads: job id per file
- transfers: operation and job ids

Route them through `randomUUID()` from `$lib/utils/uuid.js`, which keeps the
native fast path and falls back to `crypto.getRandomValues()`. This is the same
fix as the Trino tab store, toast store and upload entries already use.

The existing storage specs use the real browser `crypto`, so they exercise the
fast path and would not catch a regression. Extend the insecure-context
regression spec to cover the new call sites.

Both insecure-context specs are now merged into one file on purpose:
browser-mode Vitest evaluates SvelteKit's SSR module runner once per run, and
its first evaluation races under full-suite parallelism. Two files triggering
that init gave the race two entry points, and the resulting `wrapDynamicImport`
failure left a Vite error overlay on the shared page that then failed ~100
unrelated UploadModal specs. The download case also spies on
`document.createElement`/`body.appendChild` instead of clicking a real anchor,
since that anchor pointed at a manifest route and made the dev server evaluate
its `+server.ts` module.

Verified: reverting the four files makes all five storage assertions fail with
the original TypeError. Full unit suite passes 2153/2153 across repeated runs.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant