fix: polyfill crypto.randomUUID for insecure-context origins (#1)

crypto.randomUUID is restricted to secure contexts (HTTPS or localhost).
When RefBoard is served over plain HTTP on a LAN IP (e.g.
http://192.168.x.x:8000), the function is undefined and the editor crashes
on first ID generation with:

  Uncaught TypeError: crypto.randomUUID is not a function

The frontend calls crypto.randomUUID in ~20 places (uploadManager,
SceneManager, Editor, canvas tools, grouping, scene-format, etc.), so a
single polyfill at the entry point is the smallest fix.

The polyfill uses crypto.getRandomValues — available on insecure origins —
to build an RFC 4122 v4 UUID with the correct version/variant bits. It is
a no-op when the native function exists, so HTTPS and localhost paths are
unchanged.

No crypto.subtle usage exists in the source, so randomUUID is the only
secure-context API the frontend depends on today.
This commit is contained in:
Vivek Shukla
2026-05-20 18:58:35 +05:30
committed by GitHub
parent 8d4068e220
commit 9a02edd9dc
2 changed files with 22 additions and 0 deletions
+1
View File
@@ -1,3 +1,4 @@
import './polyfills';
import React from 'react'; import React from 'react';
import ReactDOM from 'react-dom/client'; import ReactDOM from 'react-dom/client';
import App from './App'; import App from './App';
+21
View File
@@ -0,0 +1,21 @@
// crypto.randomUUID is restricted to secure contexts (HTTPS or localhost).
// On LAN HTTP origins it's undefined, so polyfill via crypto.getRandomValues,
// which is available on insecure origins.
if (typeof crypto !== 'undefined' && typeof crypto.randomUUID !== 'function') {
(crypto as Crypto & { randomUUID: () => string }).randomUUID = function randomUUID() {
const bytes = new Uint8Array(16);
crypto.getRandomValues(bytes);
bytes[6] = (bytes[6] & 0x0f) | 0x40;
bytes[8] = (bytes[8] & 0x3f) | 0x80;
const hex: string[] = [];
for (let i = 0; i < 256; i++) hex.push((i + 0x100).toString(16).slice(1));
const b = bytes;
return (
hex[b[0]] + hex[b[1]] + hex[b[2]] + hex[b[3]] + '-' +
hex[b[4]] + hex[b[5]] + '-' +
hex[b[6]] + hex[b[7]] + '-' +
hex[b[8]] + hex[b[9]] + '-' +
hex[b[10]] + hex[b[11]] + hex[b[12]] + hex[b[13]] + hex[b[14]] + hex[b[15]]
) as `${string}-${string}-${string}-${string}-${string}`;
};
}