mirror of
https://github.com/coder/coder.git
synced 2026-10-31 11:02:50 +08:00
Fixes OSS-38: `crypto.randomUUID is not a function` when accessing Coder over plain HTTP. ### Root cause `crypto.randomUUID` is only defined in secure contexts (HTTPS or localhost). It is `undefined` when Coder is served over plain HTTP. The `uuid` package's `v4()` short-circuits to `crypto.randomUUID()` when it is truthy, and in the production bundle that path compiles down to a direct `crypto.randomUUID()` call, so `uuidv4()` throws over HTTP. Observed crash (Template Builder, in the `useMemo` that mints the telemetry session ID): ``` TypeError: crypto.randomUUID is not a function Rt/h<@.../assets/TemplateBuilderPage-*.js useMemo@... ``` The same `uuidv4()` path backed the Terminal reconnection token and the Agent chat tab IDs / reconnection tokens, so those flows were affected too. ### Fix Add a single `generateUUID` helper in `site/src/utils/random.ts` that derives the UUID from `crypto.getRandomValues` (the one `Crypto` member available in insecure contexts) and only calls `crypto.randomUUID` when it actually exists. Route all client-side UUID generation through it, so every call site is fixed at once and future ones stay safe. ### Changes | Change | Route | Human tested/verified | |---|---|---| | `utils/random.ts` — new `generateUUID()` helper | N/A | N/A | | `TemplateBuilderPage.tsx` — telemetry session ID | `/templates/new/builder` | [x] | | `TerminalPage.tsx` — reconnection token | `/:username/:workspace/terminal` | [x] | | `AgentChatPageView.tsx` — tab IDs + reconnection tokens | `/agents/:agentId` | [ ] | | `useChatDraftAttachments.ts` — draft client IDs | `/agents/:agentId` | [x] | | `TaskApps.stories.tsx` — mock app IDs (Storybook) | `/tasks/:username/:taskId` | [ ] | | `WorkspaceSharingIndicator.stories.tsx` — mock actor IDs (Storybook) | `/workspaces` | [ ] | | Removed unused `uuid` / `@types/uuid` direct deps | N/A | N/A | `uuid` is still pinned via a `pnpm.overrides` entry because `mermaid`/`streamdown` depend on it transitively. ### Tests - `random.test.ts` covers a valid UUID, uniqueness, and the insecure-context path (with `crypto.randomUUID` stubbed to `undefined`). - `TerminalPage.test.tsx` now mocks `#/utils/random` instead of the `uuid` module. ### Validation - `make fmt`, `biome check`, `tsc --noEmit` clean - `vitest run` green: `random.test.ts` (6), `TerminalPage.test.tsx` (16), `useChatDraftAttachments.test.ts` (17), both changed stories (12) - Reproduced the original crash over HTTP on a production build, top frame `uuidv4()` in Template Builder. --- _This PR was generated by Coder Agents on behalf of @phorcys420._