From 0445fdba198e5b6c33a579a025fef4822ef3ffd6 Mon Sep 17 00:00:00 2001 From: Woody Date: Mon, 18 May 2026 14:47:07 +0800 Subject: [PATCH] fix: UUID fallback for non-secure HTTP contexts crypto.randomUUID() is unavailable outside secure contexts (plain HTTP). Add generateUUID() helper with manual UUID v4 fallback (RFC 4122). --- frontend/src/lib/uuid.ts | 18 ++++++++++++++++++ frontend/src/pages/LTTPage.tsx | 5 +++-- 2 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 frontend/src/lib/uuid.ts diff --git a/frontend/src/lib/uuid.ts b/frontend/src/lib/uuid.ts new file mode 100644 index 0000000..1392396 --- /dev/null +++ b/frontend/src/lib/uuid.ts @@ -0,0 +1,18 @@ +/** + * Generate a UUID v4 string. + * + * Uses crypto.randomUUID() when available (secure contexts / HTTPS / localhost). + * Falls back to a manual UUID v4 generator for non-secure contexts (plain HTTP). + */ +export function generateUUID(): string { + if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') { + return crypto.randomUUID() + } + + // Manual UUID v4 fallback (RFC 4122) + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => { + const r = (Math.random() * 16) | 0 + const v = c === 'x' ? r : (r & 0x3) | 0x8 + return v.toString(16) + }) +} diff --git a/frontend/src/pages/LTTPage.tsx b/frontend/src/pages/LTTPage.tsx index a8f36b8..3683389 100644 --- a/frontend/src/pages/LTTPage.tsx +++ b/frontend/src/pages/LTTPage.tsx @@ -7,6 +7,7 @@ import { useSystemAudioASR } from '../hooks/useSystemAudioASR' import { useMicASR } from '../hooks/useMicASR' import { useFullTranscript } from '../hooks/useFullTranscript' import { getVideoUrl } from '../lib/api' +import { generateUUID } from '../lib/uuid' import { QueryInput } from '../components/QueryInput' import { ExtractedQuestionsDisplay } from '../components/ExtractedQuestionsDisplay' import { ResponsePanel } from '../components/ResponsePanel' @@ -39,12 +40,12 @@ export const LTTPage: React.FC = () => { const systemAudioWsUrl = useMemo(() => { const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:' const host = import.meta.env.VITE_WS_HOST ?? window.location.host - return `${protocol}//${host}/ws/asr/${crypto.randomUUID()}?language=yue&source=system-audio` + return `${protocol}//${host}/ws/asr/${generateUUID()}?language=yue&source=system-audio` }, []) const micWsUrl = useMemo(() => { const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:' const host = import.meta.env.VITE_WS_HOST ?? window.location.host - return `${protocol}//${host}/ws/asr/${crypto.randomUUID()}?language=yue&source=mic` + return `${protocol}//${host}/ws/asr/${generateUUID()}?language=yue&source=mic` }, []) const systemAudioASR = useSystemAudioASR({ wsUrl: systemAudioWsUrl })