Skip to content

[BUG] crypto.randomUUID() unavailable when self-hosting locally over HTTP #385

Closed as not planned

Description

@zaMuffenMan

Describe the bug
When running via Docker for local-only hosting, the application can load successfully and users can log in, but parts of the UI fail with a 500 error due to crypto.randomUUID() not being available in the browser environment.

To Reproduce
Steps to reproduce the behavior:

  1. Deploy WorldWideView using Docker Compose on a local VM.
  2. Access the application from another machine on the LAN using an IP address, for example: http://192.168.1.5:3000
  3. Log in successfully.
  4. Open the browser developer console.
  5. Observe the error: TypeError: crypto.randomUUID is not a function

The issue can also be reproduced directly in the browser console: crypto.randomUUID() which returns: Uncaught TypeError: crypto.randomUUID is not a function

Expected behavior
The local/self-hosted edition should either:

  • Work correctly when hosted on a LAN HTTP address, or
  • Provide a clear error message explaining that HTTPS is required for browser APIs such as crypto.randomUUID().

A local Docker deployment should not fail after successful login without indicating the requirement for a secure context.

Screenshots/Logs
Browser console output:

TypeError: crypto.randomUUID is not a function
at: 9032.c6df48b4385f280d.js:18:31375

The failure appears after initial application startup.

Environment (please complete the following information):

  • OS: Linux VM running Docker, client machine Windows
  • Browser: Chrome-based browser
  • WorldWideView Edition: Local
  • Deployment: Docker Compose
  • Access method: LAN IP address over HTTP (http://192.168.1.5:3000)
    Build:
  • id=1785198461
  • built_at=2026-07-28T00:27:41.666Z

Activity

  1. github-actions commented on Jul 29, 2026

    @github-actions
    Contributor

    Issue Classification

    Field Value
    Target Repo repo:app
    Type bug
    Confidence high
    Reasoning The issue is a bug in the core globe UI application (app repo) where crypto.randomUUID() is used in a non-secure context, causing a TypeError. This is a clear bug, not an enhancement or plugin request.
  2. alexl83 commented on Aug 1, 2026

    @alexl83

    Confirmed on a native ARM64 self-hosted deployment and tested the following patch successfully.

    Environment:

    • Raspberry Pi 5, ARM64, Docker Compose
    • WorldwideView commit f3d7e00
    • Local edition accessed as http://porpolino.local:3000
    • Reproduced in Firefox and Chromium

    After authentication, the root page hit the Next.js global error screen. The browser console showed:

    TypeError: crypto.randomUUID is not a function
    

    The failure originates in src/core/globe/hooks/useSessionId.ts. crypto.randomUUID() is restricted to secure contexts in these browsers, while crypto.getRandomValues() remains available for this LAN HTTP deployment.

    This fallback fixed the 500 page while retaining native randomUUID() on secure origins:

    diff --git a/src/core/globe/hooks/useSessionId.ts b/src/core/globe/hooks/useSessionId.ts
    index 1c4cc3f..88aa42f 100644
    --- a/src/core/globe/hooks/useSessionId.ts
    +++ b/src/core/globe/hooks/useSessionId.ts
    @@ -2,6 +2,20 @@ import { useRef, useState, useEffect } from "react";
     
     const SESSION_ID_KEY = "wwv-globe-session-id";
     
    +function createSessionId(): string {
    +    if (typeof crypto.randomUUID === "function") return crypto.randomUUID();
    +
    +    // randomUUID is restricted to secure contexts in some browsers. WWV is
    +    // commonly self-hosted over HTTP on a LAN hostname, while getRandomValues
    +    // remains available there.
    +    const bytes = new Uint8Array(16);
    +    crypto.getRandomValues(bytes);
    +    bytes[6] = (bytes[6] & 0x0f) | 0x40;
    +    bytes[8] = (bytes[8] & 0x3f) | 0x80;
    +    const hex = Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
    +    return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
    +}
    +
     export function useSessionId(): string {
    @@ -13,7 +27,7 @@ export function useSessionId(): string {
             const existing = sessionStorage.getItem(SESSION_ID_KEY);
             const id = existing ?? (() => {
    -            const newId = crypto.randomUUID();
    +            const newId = createSessionId();
                 sessionStorage.setItem(SESSION_ID_KEY, newId);
                 return newId;
             })();

    Verification performed after rebuilding the ARM64 image:

    • authenticated homepage loads instead of the global 500 page;
    • globe UI initializes normally;
    • session ID is persisted in sessionStorage;
    • native crypto.randomUUID() remains the preferred path when available.

    I can also submit this as a PR if useful.

  3. alexl83 commented on Aug 4, 2026

    @alexl83

    A tested fallback is available in the public fork:

    alexl83@3af1c6e9

    The patch keeps crypto.randomUUID() as the preferred path and, when it is unavailable on an insecure LAN origin, generates an RFC 4122 version-4 UUID with crypto.getRandomValues(). It preserves sessionStorage behavior and was deployed successfully on a self-hosted LAN installation.

    HTTPS remains the recommended deployment mode, but this prevents the local edition from failing before an operator has configured a trusted local certificate.

  4. github-actions commented on Oct 4, 2026

    @github-actions
    Contributor

    This issue has been inactive for 60 days. If there is no further activity in the next 14 days it will be closed automatically.

  5. github-actions commented on Oct 19, 2026

    @github-actions
    Contributor

    Closing due to inactivity. Feel free to re-open if the issue is still relevant.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingrepo:appBelongs to the main worldwideview applicationstale

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions