fix: add fallback for crypto.randomUUID() on older WebViews

crypto.randomUUID() is not available on older systems (macOS < 12.3,
Safari < 15.4). This caused "crypto.randomUUID is not a function"
error when adding providers.

- Add generateUUID() utility with getRandomValues() fallback
- Provide user-friendly error message if crypto API unavailable
This commit is contained in:
Jason
2025-12-04 17:01:17 +08:00
parent 420b5d4389
commit bf9228093b
2 changed files with 39 additions and 1 deletions
+2 -1
View File
@@ -4,6 +4,7 @@ import { toast } from "sonner";
import { providersApi, settingsApi, type AppId } from "@/lib/api";
import type { Provider, Settings } from "@/types";
import { extractErrorMessage } from "@/utils/errorUtils";
import { generateUUID } from "@/utils/uuid";
export const useAddProviderMutation = (appId: AppId) => {
const queryClient = useQueryClient();
@@ -13,7 +14,7 @@ export const useAddProviderMutation = (appId: AppId) => {
mutationFn: async (providerInput: Omit<Provider, "id">) => {
const newProvider: Provider = {
...providerInput,
id: crypto.randomUUID(),
id: generateUUID(),
createdAt: Date.now(),
};
await providersApi.add(newProvider, appId);
+37
View File
@@ -0,0 +1,37 @@
/**
* 生成 UUID v4
*
* 优先使用 crypto.randomUUID(),不可用时使用 crypto.getRandomValues() 实现
*
* 兼容性:
* - crypto.randomUUID(): Chrome 92+, Safari 15.4+, Firefox 95+
* - crypto.getRandomValues(): Chrome 11+, Safari 5+, Firefox 21+
*/
export function generateUUID(): string {
const cryptoApi = globalThis.crypto;
// 优先使用原生 API
if (typeof cryptoApi?.randomUUID === "function") {
return cryptoApi.randomUUID();
}
// Fallback: 使用 crypto.getRandomValues 实现 UUID v4
if (!cryptoApi?.getRandomValues) {
throw new Error(
"crypto API not available - please update your operating system",
);
}
const bytes = new Uint8Array(16);
cryptoApi.getRandomValues(bytes);
// 设置版本 (4) 和变体 (RFC 4122)
bytes[6] = (bytes[6] & 0x0f) | 0x40;
bytes[8] = (bytes[8] & 0x3f) | 0x80;
const hex = Array.from(bytes)
.map((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)}`;
}