fix: crypto.randomUUID fallback for HTTP contexts

Chat page and ChatWidget used crypto.randomUUID() for conversation IDs,
which is only available in secure contexts (HTTPS). On HTTP, this throws
'crypto.randomUUID is not a function'. Added generateUUID() utility with
Math.random-based fallback.
This commit is contained in:
jlightner 2026-04-05 06:05:17 +00:00
parent 96491ac70a
commit 26a5d0e0ef
3 changed files with 18 additions and 2 deletions

View file

@ -11,6 +11,7 @@ import { Link } from "react-router-dom";
import { streamChat, type ChatSource } from "../api/chat"; import { streamChat, type ChatSource } from "../api/chat";
import { parseChatCitations } from "../utils/chatCitations"; import { parseChatCitations } from "../utils/chatCitations";
import { formatTime } from "../utils/formatTime"; import { formatTime } from "../utils/formatTime";
import { generateUUID } from "../utils/uuid";
import styles from "./ChatWidget.module.css"; import styles from "./ChatWidget.module.css";
interface Technique { interface Technique {
@ -133,7 +134,7 @@ export default function ChatWidget({ creatorName, techniques }: ChatWidgetProps)
abortRef.current?.abort(); abortRef.current?.abort();
// Generate conversation_id on first message // Generate conversation_id on first message
const cid = conversationId ?? crypto.randomUUID(); const cid = conversationId ?? generateUUID();
if (!conversationId) setConversationId(cid); if (!conversationId) setConversationId(cid);
const userMsg: Message = { role: "user", text: q, sources: [], done: true }; const userMsg: Message = { role: "user", text: q, sources: [], done: true };

View file

@ -12,6 +12,7 @@ import { Link } from "react-router-dom";
import { streamChat, type ChatSource } from "../api/chat"; import { streamChat, type ChatSource } from "../api/chat";
import { parseChatCitations } from "../utils/chatCitations"; import { parseChatCitations } from "../utils/chatCitations";
import { formatTime } from "../utils/formatTime"; import { formatTime } from "../utils/formatTime";
import { generateUUID } from "../utils/uuid";
import { useDocumentTitle } from "../hooks/useDocumentTitle"; import { useDocumentTitle } from "../hooks/useDocumentTitle";
import styles from "./ChatPage.module.css"; import styles from "./ChatPage.module.css";
@ -57,7 +58,7 @@ export default function ChatPage() {
abortRef.current?.abort(); abortRef.current?.abort();
// Generate conversation_id on first message // Generate conversation_id on first message
const cid = conversationId ?? crypto.randomUUID(); const cid = conversationId ?? generateUUID();
if (!conversationId) setConversationId(cid); if (!conversationId) setConversationId(cid);
const userMsg: Message = { const userMsg: Message = {

View file

@ -0,0 +1,14 @@
/** Generate a UUID v4, with fallback for non-secure contexts (HTTP).
*
* `crypto.randomUUID()` is only available in secure contexts (HTTPS).
* On HTTP, falls back to Math.random-based generation.
*/
export function generateUUID(): string {
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
return crypto.randomUUID();
}
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
const r = (Math.random() * 16) | 0;
return (c === "x" ? r : (r & 0x3) | 0x8).toString(16);
});
}