diff --git a/packages/shared-auth/src/adapters/device.ts b/packages/shared-auth/src/adapters/device.ts index c958dc1d1..a0c062297 100644 --- a/packages/shared-auth/src/adapters/device.ts +++ b/packages/shared-auth/src/adapters/device.ts @@ -2,6 +2,42 @@ import type { DeviceManagerAdapter, DeviceInfo } from '../types'; let deviceAdapter: DeviceManagerAdapter | null = null; +/** + * Generate a UUID with fallback for non-secure contexts (HTTP) + * crypto.randomUUID() requires HTTPS, so we fall back to crypto.getRandomValues() + */ +function generateUUID(): string { + // Try native randomUUID first (requires secure context) + if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') { + try { + return crypto.randomUUID(); + } catch { + // Falls through to fallback + } + } + + // Fallback: use crypto.getRandomValues() which works in insecure contexts + if (typeof crypto !== 'undefined' && typeof crypto.getRandomValues === 'function') { + const bytes = new Uint8Array(16); + crypto.getRandomValues(bytes); + + // Set version (4) and variant (RFC 4122) + bytes[6] = (bytes[6] & 0x0f) | 0x40; + bytes[8] = (bytes[8] & 0x3f) | 0x80; + + // Convert to hex string with dashes + const hex = Array.from(bytes, (b) => b.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)}`; + } + + // Last resort: Math.random() based UUID (not cryptographically secure, but works) + 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); + }); +} + /** * Set the device manager adapter for the auth service */ @@ -37,7 +73,7 @@ export function createWebDeviceAdapter(): DeviceManagerAdapter { const storageKey = '@manacore/deviceId'; let deviceId = localStorage.getItem(storageKey); if (!deviceId) { - deviceId = crypto.randomUUID(); + deviceId = generateUUID(); localStorage.setItem(storageKey, deviceId); } return deviceId;