fix(driver): support installation over insecure HTTP
This commit is contained in:
4 files changed
+48
-6
No files matched your search
@@ -13,6 +13,7 @@ import DriverInstallProgressCircle from "@/components/config/DriverInstallProgre
|
|||||||
import DatabaseIcon from "@/components/icons/DatabaseIcon.vue";
|
import DatabaseIcon from "@/components/icons/DatabaseIcon.vue";
|
||||||
import { useToast } from "@/composables/useToast";
|
import { useToast } from "@/composables/useToast";
|
||||||
import { isTauriRuntime } from "@/lib/backend/tauriRuntime";
|
import { isTauriRuntime } from "@/lib/backend/tauriRuntime";
|
||||||
|
import { uuid } from "@/lib/common/utils";
|
||||||
import { countAvailableDriverUpdates } from "@/lib/connection/agentDriverUpdateBadge";
|
import { countAvailableDriverUpdates } from "@/lib/connection/agentDriverUpdateBadge";
|
||||||
import type { JdbcDriverInfo, JdbcLocalBundleInfo, JdbcMavenBundleInfo, JdbcPluginStatus } from "@/types/database";
|
import type { JdbcDriverInfo, JdbcLocalBundleInfo, JdbcMavenBundleInfo, JdbcPluginStatus } from "@/types/database";
|
||||||
import * as api from "@/lib/backend/api";
|
import * as api from "@/lib/backend/api";
|
||||||
@@ -465,7 +466,7 @@ async function installDriver(dbType: string) {
|
|||||||
async function runDriverInstall(dbType: string) {
|
async function runDriverInstall(dbType: string) {
|
||||||
const label = driverLabel(dbType);
|
const label = driverLabel(dbType);
|
||||||
installing.value = dbType;
|
installing.value = dbType;
|
||||||
activeAgentOperationId.value = crypto.randomUUID();
|
activeAgentOperationId.value = uuid();
|
||||||
resetAgentInstallProgress();
|
resetAgentInstallProgress();
|
||||||
try {
|
try {
|
||||||
if (isPrestoSqlBuiltinDriver(dbType)) {
|
if (isPrestoSqlBuiltinDriver(dbType)) {
|
||||||
@@ -509,7 +510,7 @@ async function runQueuedDriverInstalls() {
|
|||||||
|
|
||||||
async function upgradeAll() {
|
async function upgradeAll() {
|
||||||
upgradingAll.value = true;
|
upgradingAll.value = true;
|
||||||
activeAgentOperationId.value = crypto.randomUUID();
|
activeAgentOperationId.value = uuid();
|
||||||
upgradingCompletedCount.value = 0;
|
upgradingCompletedCount.value = 0;
|
||||||
queuedDriverInstalls.value = [];
|
queuedDriverInstalls.value = [];
|
||||||
resetAgentInstallProgress();
|
resetAgentInstallProgress();
|
||||||
@@ -623,7 +624,7 @@ async function importOfflineZip() {
|
|||||||
}
|
}
|
||||||
if (!selected) return;
|
if (!selected) return;
|
||||||
importingZip.value = true;
|
importingZip.value = true;
|
||||||
activeAgentOperationId.value = crypto.randomUUID();
|
activeAgentOperationId.value = uuid();
|
||||||
resetAgentInstallProgress();
|
resetAgentInstallProgress();
|
||||||
try {
|
try {
|
||||||
const count = await api.importAgentsFromZip(selected, activeAgentOperationId.value);
|
const count = await api.importAgentsFromZip(selected, activeAgentOperationId.value);
|
||||||
@@ -655,7 +656,7 @@ async function importDriverFile(driver: AgentDriverInfo) {
|
|||||||
const isWindows = navigator.userAgent.toLowerCase().includes("windows");
|
const isWindows = navigator.userAgent.toLowerCase().includes("windows");
|
||||||
const installSelectedFile = async (selected: string | File) => {
|
const installSelectedFile = async (selected: string | File) => {
|
||||||
if (isOfflineDriverPackage(selected)) {
|
if (isOfflineDriverPackage(selected)) {
|
||||||
activeAgentOperationId.value = crypto.randomUUID();
|
activeAgentOperationId.value = uuid();
|
||||||
resetAgentInstallProgress();
|
resetAgentInstallProgress();
|
||||||
try {
|
try {
|
||||||
const count = await api.importAgentsFromZip(selected, activeAgentOperationId.value);
|
const count = await api.importAgentsFromZip(selected, activeAgentOperationId.value);
|
||||||
@@ -701,7 +702,7 @@ async function importDriverFile(driver: AgentDriverInfo) {
|
|||||||
|
|
||||||
async function reinstallJre(jreKey: string) {
|
async function reinstallJre(jreKey: string) {
|
||||||
reinstallingJre.value = jreKey;
|
reinstallingJre.value = jreKey;
|
||||||
activeAgentOperationId.value = crypto.randomUUID();
|
activeAgentOperationId.value = uuid();
|
||||||
resetAgentInstallProgress();
|
resetAgentInstallProgress();
|
||||||
try {
|
try {
|
||||||
await api.reinstallJre(jreKey, activeAgentOperationId.value);
|
await api.reinstallJre(jreKey, activeAgentOperationId.value);
|
||||||
|
|||||||
@@ -1482,7 +1482,7 @@ async function refreshLocalAgentDrivers(): Promise<AgentDriverInstallState[]> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function beginAgentDriverInstall(driverKey: string, label: string) {
|
function beginAgentDriverInstall(driverKey: string, label: string) {
|
||||||
agentInstallOperationId.value = crypto.randomUUID();
|
agentInstallOperationId.value = uuid();
|
||||||
agentInstallDriverKey.value = driverKey;
|
agentInstallDriverKey.value = driverKey;
|
||||||
agentInstallLabel.value = label;
|
agentInstallLabel.value = label;
|
||||||
agentInstallProgress.value = null;
|
agentInstallProgress.value = null;
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||||
|
import { uuid } from "@/lib/common/utils";
|
||||||
|
|
||||||
|
describe("uuid", () => {
|
||||||
|
afterEach(() => {
|
||||||
|
vi.unstubAllGlobals();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("uses crypto.randomUUID when available", () => {
|
||||||
|
const randomUUID = vi.fn(() => "123e4567-e89b-42d3-a456-426614174000");
|
||||||
|
vi.stubGlobal("crypto", { randomUUID });
|
||||||
|
|
||||||
|
expect(uuid()).toBe("123e4567-e89b-42d3-a456-426614174000");
|
||||||
|
expect(randomUUID).toHaveBeenCalledOnce();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("generates a UUID when crypto.randomUUID is unavailable", () => {
|
||||||
|
vi.stubGlobal("crypto", {});
|
||||||
|
|
||||||
|
expect(uuid()).toMatch(/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import assert from "node:assert/strict";
|
||||||
|
import { readFileSync } from "node:fs";
|
||||||
|
import path from "node:path";
|
||||||
|
import { test } from "vitest";
|
||||||
|
|
||||||
|
function source(relativePath: string): string {
|
||||||
|
return readFileSync(path.resolve(relativePath), "utf8");
|
||||||
|
}
|
||||||
|
|
||||||
|
test("driver installation operation IDs support insecure HTTP contexts", () => {
|
||||||
|
const driverStore = source("apps/desktop/src/components/config/DriverStoreDialog.vue");
|
||||||
|
const connectionDialog = source("apps/desktop/src/components/connection/ConnectionDialog.vue");
|
||||||
|
|
||||||
|
assert.match(driverStore, /import \{ uuid \} from "@\/lib\/common\/utils"/);
|
||||||
|
assert.doesNotMatch(driverStore, /crypto\.randomUUID\(\)/);
|
||||||
|
assert.match(driverStore, /activeAgentOperationId\.value = uuid\(\)/);
|
||||||
|
assert.doesNotMatch(connectionDialog, /crypto\.randomUUID\(\)/);
|
||||||
|
assert.match(connectionDialog, /agentInstallOperationId\.value = uuid\(\)/);
|
||||||
|
});
|
||||||
Reference in new issue
Block a user