mirror of
https://github.com/t8y2/dbx.git
synced 2026-10-19 16:16:45 +00:00
fix(mongodb): install legacy driver during connection test
This commit is contained in:
@@ -8249,7 +8249,7 @@ function openExternalUrl(url: string) {
|
||||
|
||||
<div v-if="agentInstallError" class="space-y-2">
|
||||
<div class="text-sm font-medium text-destructive">{{ t("connection.driverInstall.fullError") }}</div>
|
||||
<pre class="max-h-56 overflow-auto whitespace-pre-wrap break-words rounded-md border bg-muted/30 p-3 text-xs leading-5 text-destructive">{{ agentInstallError }}</pre>
|
||||
<pre class="max-h-56 min-w-0 max-w-full overflow-x-hidden overflow-y-auto whitespace-pre-wrap break-all [overflow-wrap:anywhere] rounded-md border bg-muted/30 p-3 text-xs leading-5 text-destructive">{{ agentInstallError }}</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -8266,14 +8266,14 @@ function openExternalUrl(url: string) {
|
||||
</Dialog>
|
||||
|
||||
<Dialog v-model:open="showConnectionErrorDialog">
|
||||
<DialogContent class="sm:max-w-[560px]">
|
||||
<DialogContent class="min-w-0 sm:max-w-[680px]">
|
||||
<DialogHeader>
|
||||
<DialogTitle>{{ t("connection.connectFailedTitle") }}</DialogTitle>
|
||||
</DialogHeader>
|
||||
|
||||
<div class="space-y-2">
|
||||
<div class="min-w-0 space-y-2">
|
||||
<div class="text-sm text-muted-foreground">{{ t("connection.fullErrorMessage") }}</div>
|
||||
<pre class="max-h-72 overflow-auto whitespace-pre-wrap break-words rounded-md border bg-muted/30 p-3 text-xs leading-5 text-destructive">{{ connectionErrorDetail }}</pre>
|
||||
<pre class="max-h-72 min-w-0 max-w-full overflow-x-hidden overflow-y-auto whitespace-pre-wrap break-all [overflow-wrap:anywhere] rounded-md border bg-muted/30 p-3 text-xs leading-5 text-destructive">{{ connectionErrorDetail }}</pre>
|
||||
</div>
|
||||
|
||||
<DialogFooter class="gap-2">
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
import { readFileSync } from "node:fs";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
const dialogSource = readFileSync(new URL("../../../components/connection/ConnectionDialog.vue", import.meta.url), "utf8");
|
||||
|
||||
describe("connection dialog error layout", () => {
|
||||
it("installs a required agent before running a connection test", () => {
|
||||
const installIndex = dialogSource.indexOf("await ensureRequiredAgentDriverInstalled(config);");
|
||||
const testIndex = dialogSource.indexOf("const result = await testConnectionWithTimeout(config, runId);");
|
||||
|
||||
expect(installIndex).toBeGreaterThan(-1);
|
||||
expect(testIndex).toBeGreaterThan(installIndex);
|
||||
});
|
||||
|
||||
it("wraps long connection and driver installation errors inside the dialog", () => {
|
||||
const wrappingClasses = "min-w-0 max-w-full overflow-x-hidden overflow-y-auto whitespace-pre-wrap break-all [overflow-wrap:anywhere]";
|
||||
|
||||
expect(dialogSource.split(wrappingClasses)).toHaveLength(3);
|
||||
expect(dialogSource).toContain('<DialogContent class="min-w-0 sm:max-w-[680px]">');
|
||||
});
|
||||
});
|
||||
@@ -37,15 +37,22 @@ export function agentDriverInstallKey(dbType: DatabaseType | undefined, driverPr
|
||||
return driverProfile && driverProfile !== dbType ? driverProfile : dbType;
|
||||
}
|
||||
|
||||
function usesManagedAgentDriver(dbType: DatabaseType | undefined, driverProfile?: string): boolean {
|
||||
if (supportsDriverManagement(dbType)) return true;
|
||||
if (dbType !== "mongodb") return false;
|
||||
const profile = driverProfile?.trim().toLowerCase();
|
||||
return profile === "mongodb-legacy" || profile === "mongodb_legacy" || profile === "legacy";
|
||||
}
|
||||
|
||||
export function showAgentDriverInstallHint(dbType: DatabaseType | undefined, drivers: readonly AgentDriverInstallState[], driverProfile?: string): boolean {
|
||||
if (!supportsDriverManagement(dbType)) return false;
|
||||
if (!usesManagedAgentDriver(dbType, driverProfile)) return false;
|
||||
const driverKey = agentDriverInstallKey(dbType, driverProfile);
|
||||
if (!driverKey) return false;
|
||||
return drivers.find((driver) => driver.db_type === driverKey)?.installed !== true;
|
||||
}
|
||||
|
||||
export function hasAgentDriverUpdate(dbType: DatabaseType | undefined, drivers: readonly AgentDriverInstallState[], driverProfile?: string): boolean {
|
||||
if (!supportsDriverManagement(dbType)) return false;
|
||||
if (!usesManagedAgentDriver(dbType, driverProfile)) return false;
|
||||
const driverKey = agentDriverInstallKey(dbType, driverProfile);
|
||||
return drivers.find((driver) => driver.db_type === driverKey)?.update_available === true;
|
||||
}
|
||||
|
||||
@@ -75,7 +75,10 @@ export function mongodbAuthFailureHint(message: string): string {
|
||||
const source = message.match(/source='([^']+)'/)?.[1];
|
||||
if (!source || !message.includes("Exception authenticating MongoCredential")) return message;
|
||||
|
||||
return `${message}\n\nCurrent authentication database: ${source}. If this user was created in admin, set Authentication database to admin or add authSource=admin to URL params.`;
|
||||
const verificationHint = `Current authentication database: ${source}. The server rejected these credentials. Verify the username and password, and confirm that the user was created in ${source}.`;
|
||||
if (source.toLowerCase() === "admin") return `${message}\n\n${verificationHint}`;
|
||||
|
||||
return `${message}\n\n${verificationHint} If the user was created in admin, set Authentication database to admin or add authSource=admin to URL params.`;
|
||||
}
|
||||
|
||||
function parseMongoUrlParams(urlParams: string | undefined): URLSearchParams {
|
||||
|
||||
@@ -260,9 +260,13 @@ pub fn mongo_legacy_error_with_auth_hint(err: &str) -> String {
|
||||
return err.to_string();
|
||||
};
|
||||
let source = &source[..source_end];
|
||||
format!(
|
||||
"{err}\n\nCurrent authentication database: {source}. If this user was created in admin, set Authentication database to admin or add authSource=admin to URL params."
|
||||
)
|
||||
let verification_hint = format!(
|
||||
"Current authentication database: {source}. The server rejected these credentials. Verify the username and password, and confirm that the user was created in {source}."
|
||||
);
|
||||
if source.eq_ignore_ascii_case("admin") {
|
||||
return format!("{err}\n\n{verification_hint}");
|
||||
}
|
||||
format!("{err}\n\n{verification_hint} If the user was created in admin, set Authentication database to admin or add authSource=admin to URL params.")
|
||||
}
|
||||
|
||||
pub fn mongo_uses_legacy_driver(config: &ConnectionConfig) -> bool {
|
||||
@@ -861,6 +865,8 @@ mod tests {
|
||||
|
||||
assert!(hinted.starts_with(err));
|
||||
assert!(hinted.contains("Current authentication database: admin"));
|
||||
assert!(hinted.contains("The server rejected these credentials"));
|
||||
assert!(!hinted.contains("add authSource=admin"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -5591,7 +5591,7 @@ mod tests {
|
||||
|
||||
assert_eq!(
|
||||
mongo_legacy_error_with_auth_hint(err),
|
||||
"Agent RPC error: Exception authenticating MongoCredential{mechanism=SCRAM-SHA-1, userName='rwuser', source='gray_lite_twin_fat'}\n\nCurrent authentication database: gray_lite_twin_fat. If this user was created in admin, set Authentication database to admin or add authSource=admin to URL params."
|
||||
"Agent RPC error: Exception authenticating MongoCredential{mechanism=SCRAM-SHA-1, userName='rwuser', source='gray_lite_twin_fat'}\n\nCurrent authentication database: gray_lite_twin_fat. The server rejected these credentials. Verify the username and password, and confirm that the user was created in gray_lite_twin_fat. If the user was created in admin, set Authentication database to admin or add authSource=admin to URL params."
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,13 @@ test("shows the agent driver install hint for Access when missing", () => {
|
||||
assert.equal(showAgentDriverInstallHint("access", [{ db_type: "access", installed: false }]), true);
|
||||
});
|
||||
|
||||
test("installs the MongoDB Legacy agent before testing a legacy MongoDB connection", () => {
|
||||
assert.equal(agentDriverInstallKey("mongodb", "mongodb-legacy"), "mongodb");
|
||||
assert.equal(showAgentDriverInstallHint("mongodb", [{ db_type: "mongodb", installed: false }], "mongodb-legacy"), true);
|
||||
assert.equal(showAgentDriverInstallHint("mongodb", [{ db_type: "mongodb", installed: true }], "mongodb-legacy"), false);
|
||||
assert.equal(showAgentDriverInstallHint("mongodb", [{ db_type: "mongodb", installed: false }], "mongodb"), false);
|
||||
});
|
||||
|
||||
test("does not show agent driver install hints for built-in database types", () => {
|
||||
assert.equal(showAgentDriverInstallHint("mysql", [{ db_type: "informix", installed: false }]), false);
|
||||
});
|
||||
|
||||
+9
-1
@@ -56,10 +56,18 @@ test("adds a MongoDB authSource hint for legacy authentication failures", () =>
|
||||
|
||||
assert.equal(
|
||||
mongodbAuthFailureHint(message),
|
||||
"Agent RPC error: Exception authenticating MongoCredential{mechanism=SCRAM-SHA-1, userName='rwuser', source='gray_lite_twin_fat'}\n\nCurrent authentication database: gray_lite_twin_fat. If this user was created in admin, set Authentication database to admin or add authSource=admin to URL params.",
|
||||
"Agent RPC error: Exception authenticating MongoCredential{mechanism=SCRAM-SHA-1, userName='rwuser', source='gray_lite_twin_fat'}\n\nCurrent authentication database: gray_lite_twin_fat. The server rejected these credentials. Verify the username and password, and confirm that the user was created in gray_lite_twin_fat. If the user was created in admin, set Authentication database to admin or add authSource=admin to URL params.",
|
||||
);
|
||||
});
|
||||
|
||||
test("does not suggest authSource=admin when MongoDB already authenticated against admin", () => {
|
||||
const message = "Agent RPC error: Exception authenticating MongoCredential{mechanism=SCRAM-SHA-1, userName='rwuser', source='admin'}";
|
||||
const hinted = mongodbAuthFailureHint(message);
|
||||
|
||||
assert.match(hinted, /The server rejected these credentials/);
|
||||
assert.doesNotMatch(hinted, /add authSource=admin/);
|
||||
});
|
||||
|
||||
test("adds a MongoDB URL encoding hint for reserved password characters", () => {
|
||||
const message = "MongoDB connection failed: Kind: An invalid argument was provided: password must be URL encoded";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user