fix: replace crypto.randomUUID with polyfill for HTTP contexts

crypto.randomUUID() is only available in secure contexts (HTTPS/localhost).
Add uuid() utility with fallback for HTTP deployments.
This commit is contained in:
t8y2
2026-05-05 23:51:07 +08:00
parent 4e5a7cb40a
commit 0aa562f6ee
16 changed files with 48 additions and 23 deletions
@@ -1,5 +1,6 @@
<script setup lang="ts">
import { computed, nextTick, ref, watch } from "vue";
import { uuid } from "@/lib/utils";
import { useI18n } from "vue-i18n";
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
@@ -400,7 +401,7 @@ async function testConnection() {
isTesting.value = true;
testResult.value = null;
try {
const config: ConnectionConfig = { ...form.value, id: editingId.value || crypto.randomUUID() };
const config: ConnectionConfig = { ...form.value, id: editingId.value || uuid() };
const msg = await api.testConnection(config);
if (runId !== testRunId) return;
testResult.value = { ok: true, message: msg };
@@ -465,7 +466,7 @@ async function save() {
await store.updateConnection(updated);
store.stopEditing();
} else {
const config: ConnectionConfig = { ...form.value, id: crypto.randomUUID() };
const config: ConnectionConfig = { ...form.value, id: uuid() };
await store.addConnection(config);
open.value = false;
await nextTick();
+3 -2
View File
@@ -1,5 +1,6 @@
<script setup lang="ts">
import { computed, nextTick, onMounted, ref } from "vue";
import { uuid } from "@/lib/utils";
import { useI18n } from "vue-i18n";
import {
ArrowUp,
@@ -276,7 +277,7 @@ async function send() {
isGenerating.value = true;
messages.value.push({ role: "assistant", content: "" });
const assistantIdx = messages.value.length - 1;
const sessionId = crypto.randomUUID();
const sessionId = uuid();
currentSessionId.value = sessionId;
try {
const context = await buildAiContext(props.tab, props.connection);
@@ -344,7 +345,7 @@ function clearMessages() {
async function persistConversation() {
if (!messages.value.length || !props.connection) return;
if (!conversationId.value) conversationId.value = crypto.randomUUID();
if (!conversationId.value) conversationId.value = uuid();
const first = messages.value.find((m) => m.role === "user");
await saveAiConversation({
id: conversationId.value,
+2 -1
View File
@@ -1,5 +1,6 @@
<script setup lang="ts">
import { computed, ref, watch } from "vue";
import { uuid } from "@/lib/utils";
import { useI18n } from "vue-i18n";
import { isTauriRuntime } from "@/lib/tauriRuntime";
import { Dialog, DialogHeader, DialogTitle, DialogFooter, DialogScrollContent } from "@/components/ui/dialog";
@@ -165,7 +166,7 @@ async function startImport() {
running.value = true;
cancelling.value = false;
errorMessage.value = "";
importId.value = crypto.randomUUID();
importId.value = uuid();
progress.value = {
importId: importId.value,
status: "running",
+2 -1
View File
@@ -1,5 +1,6 @@
<script setup lang="ts">
import { computed, ref } from "vue";
import { uuid } from "@/lib/utils";
import { useI18n } from "vue-i18n";
import { Plus, Trash2 } from "lucide-vue-next";
import { Button } from "@/components/ui/button";
@@ -67,7 +68,7 @@ function fieldValueTone(value: string): string {
function createBlankNode(keyName: string, readonlyKey: boolean): EditNode {
return {
key: crypto.randomUUID(),
key: uuid(),
keyName,
kind: "value",
valueText: "",
+4 -3
View File
@@ -1,5 +1,6 @@
<script setup lang="ts">
import { computed, ref, onMounted } from "vue";
import { uuid } from "@/lib/utils";
import { useI18n } from "vue-i18n";
import { RefreshCw, Trash2, Plus, Save, ChevronLeft, ChevronRight } from "lucide-vue-next";
import { Button } from "@/components/ui/button";
@@ -130,7 +131,7 @@ function cancelEdit() {
function createEditNode(keyName: string, value: unknown, readonlyKey: boolean, readonlyValue: boolean): EditNode {
if (Array.isArray(value)) {
return {
key: crypto.randomUUID(),
key: uuid(),
keyName,
kind: "array",
valueText: "",
@@ -142,7 +143,7 @@ function createEditNode(keyName: string, value: unknown, readonlyKey: boolean, r
if (value && typeof value === "object") {
return {
key: crypto.randomUUID(),
key: uuid(),
keyName,
kind: "object",
valueText: "",
@@ -155,7 +156,7 @@ function createEditNode(keyName: string, value: unknown, readonlyKey: boolean, r
}
return {
key: crypto.randomUUID(),
key: uuid(),
keyName,
kind: "value",
valueText: formatForEdit(value),
@@ -1,5 +1,6 @@
<script setup lang="ts">
import { computed, ref, watch } from "vue";
import { uuid } from "@/lib/utils";
import { useI18n } from "vue-i18n";
import { AlertCircle, Loader2, Search, Square, Table2 } from "lucide-vue-next";
import { Badge } from "@/components/ui/badge";
@@ -129,7 +130,7 @@ function filterSearchSchemas(schemas: string[]): string[] {
}
function makeExecutionId(): string {
if (typeof crypto !== "undefined" && "randomUUID" in crypto) return `database-search-${crypto.randomUUID()}`;
if (typeof crypto !== "undefined" && "randomUUID" in crypto) return `database-search-${uuid()}`;
return `database-search-${Date.now()}-${Math.random().toString(16).slice(2)}`;
}
@@ -1,5 +1,6 @@
<script setup lang="ts">
import { computed, ref, watch } from "vue";
import { uuid } from "@/lib/utils";
import { useI18n } from "vue-i18n";
import { isTauriRuntime } from "@/lib/tauriRuntime";
import { Dialog, DialogFooter, DialogHeader, DialogScrollContent, DialogTitle } from "@/components/ui/dialog";
@@ -234,7 +235,7 @@ async function selectFile() {
async function startExecution() {
if (!canStart.value || !preview.value) return;
const id = crypto.randomUUID();
const id = uuid();
executionId.value = id;
running.value = true;
cancelling.value = false;
@@ -1,5 +1,6 @@
<script setup lang="ts">
import { computed, ref, watch } from "vue";
import { uuid } from "@/lib/utils";
import { useI18n } from "vue-i18n";
import { Dialog, DialogFooter, DialogHeader, DialogScrollContent, DialogTitle } from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
@@ -167,7 +168,7 @@ async function loadStructure() {
function addColumn() {
columns.value.push({
id: `new:${crypto.randomUUID()}`,
id: `new:${uuid()}`,
name: "",
dataType: "varchar(255)",
isNullable: true,
@@ -189,7 +190,7 @@ function toggleDropColumn(column: EditableStructureColumn) {
function addIndex() {
indexes.value.push({
id: `new:${crypto.randomUUID()}`,
id: `new:${uuid()}`,
name: "",
columns: [],
isUnique: false,
@@ -1,5 +1,6 @@
<script setup lang="ts">
import { computed, ref, watch } from "vue";
import { uuid } from "@/lib/utils";
import { useI18n } from "vue-i18n";
import { Dialog, DialogHeader, DialogTitle, DialogFooter, DialogScrollContent } from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
@@ -204,7 +205,7 @@ async function startTransfer() {
overallCancelled.value = false;
transferProgress.value.clear();
transferId.value = crypto.randomUUID();
transferId.value = uuid();
// Auto-detect target schema
const targetConfig = store.getConfig(targetConnectionId.value);