105 lines
5.5 KiB
TypeScript
Vendored
105 lines
5.5 KiB
TypeScript
Vendored
import { strict as assert } from "node:assert";
|
|
import { test } from "vitest";
|
|
import { mongoUrlParam, mongoUrlParamIsTrue, normalizeMongoTlsFormState, setMongoUrlParam, setMongoUrlParamBoolean, mongodbAuthFailureHint } from "../../apps/desktop/src/lib/mongo/mongoConnectionOptions.ts";
|
|
|
|
test("reads MongoDB authSource from URL params", () => {
|
|
assert.equal(mongoUrlParam("?replicaSet=rs0&authSource=admin", "authSource"), "admin");
|
|
});
|
|
|
|
test("sets MongoDB authSource while preserving other URL params", () => {
|
|
assert.equal(setMongoUrlParam("replicaSet=rs0", "authSource", "admin"), "replicaSet=rs0&authSource=admin");
|
|
});
|
|
|
|
test("removes empty MongoDB authSource from URL params", () => {
|
|
assert.equal(setMongoUrlParam("replicaSet=rs0&authSource=admin", "authSource", ""), "replicaSet=rs0");
|
|
});
|
|
|
|
test("reads MongoDB boolean URL params", () => {
|
|
assert.equal(mongoUrlParamIsTrue("tlsAllowInvalidCertificates=true", "tlsAllowInvalidCertificates"), true);
|
|
assert.equal(mongoUrlParamIsTrue("retryWrites=false", "retryWrites", true), false);
|
|
assert.equal(mongoUrlParamIsTrue("", "retryWrites", true), true);
|
|
});
|
|
|
|
test("sets MongoDB boolean URL params", () => {
|
|
assert.equal(setMongoUrlParamBoolean("replicaSet=rs0", "retryWrites", false, true), "replicaSet=rs0&retryWrites=false");
|
|
assert.equal(setMongoUrlParamBoolean("replicaSet=rs0&retryWrites=false", "retryWrites", true, true), "replicaSet=rs0");
|
|
assert.equal(setMongoUrlParamBoolean("", "tlsAllowInvalidCertificates", true), "tlsAllowInvalidCertificates=true");
|
|
});
|
|
|
|
test("clears MongoDB TLS form state when SSL is disabled", () => {
|
|
assert.deepEqual(
|
|
normalizeMongoTlsFormState(false, "replicaSet=rs0&tlsAllowInvalidCertificates=true&tlsAllowInvalidHostnames=true&tlsCAFile=%2Ftmp%2Fca.pem", "/tmp/ca.pem"),
|
|
{ urlParams: "replicaSet=rs0", caCertPath: "" },
|
|
);
|
|
assert.deepEqual(normalizeMongoTlsFormState(true, "replicaSet=rs0", " /tmp/ca.pem "), {
|
|
urlParams: "replicaSet=rs0",
|
|
caCertPath: "/tmp/ca.pem",
|
|
});
|
|
});
|
|
|
|
test("preserves MongoDB tlsCAFile in URL params when caCertPath is empty", () => {
|
|
assert.deepEqual(normalizeMongoTlsFormState(true, "replicaSet=rs0&tlsCAFile=%2Ftmp%2Flegacy-ca.pem", ""), {
|
|
urlParams: "replicaSet=rs0&tlsCAFile=%2Ftmp%2Flegacy-ca.pem",
|
|
caCertPath: "",
|
|
});
|
|
});
|
|
|
|
test("form caCertPath overrides tlsCAFile in URL params when set", () => {
|
|
assert.deepEqual(normalizeMongoTlsFormState(true, "replicaSet=rs0&tlsCAFile=%2Ftmp%2Flegacy-ca.pem", "/tmp/explicit-ca.pem"), {
|
|
urlParams: "replicaSet=rs0",
|
|
caCertPath: "/tmp/explicit-ca.pem",
|
|
});
|
|
});
|
|
|
|
test("adds a MongoDB authSource hint for legacy authentication failures", () => {
|
|
const message = "Agent RPC error: Exception authenticating MongoCredential{mechanism=SCRAM-SHA-1, userName='rwuser', source='gray_lite_twin_fat'}";
|
|
|
|
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.",
|
|
);
|
|
});
|
|
|
|
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";
|
|
|
|
assert.match(mongodbAuthFailureHint(message), /@ becomes %40/);
|
|
});
|
|
|
|
test("adds a MongoDB directConnection multi-host hint", () => {
|
|
const message = "MongoDB connection failed: Kind: An invalid argument was provided: cannot specify multiple seeds with directConnection=true";
|
|
|
|
assert.match(mongodbAuthFailureHint(message), /Remove directConnection=true when using a multi-host replica set URL/);
|
|
});
|
|
|
|
test("adds a MongoDB SRV DNS hint for IP endpoints", () => {
|
|
const message = 'MongoDB connection failed: Kind: An error occurred during DNS resolution: DNS error: no records found for Query { name: Name("_mongodb._tcp.172.17.0.1."), query_type: SRV }';
|
|
|
|
assert.match(mongodbAuthFailureHint(message), /use mongodb:\/\/host:port instead of mongodb\+srv:\/\/host/);
|
|
});
|
|
|
|
test("adds a MongoDB replica set localhost advertisement hint", () => {
|
|
const message = "MongoDB connection failed: Kind: Server selection timeout: No available servers. Topology: { Type: ReplicaSetNoPrimary, Set Name: LIMLIU, Servers: [ { Address: 127.0.0.1:27017, Type: Unknown, Error: Kind: I/O error: Connection refused (os error 111) } ] }";
|
|
|
|
assert.match(mongodbAuthFailureHint(message), /Add directConnection=true/);
|
|
});
|
|
|
|
test("adds a MongoDB listDatabases permission hint", () => {
|
|
const message = "Command failed with error 13 (Unauthorized): not authorized on admin to execute command { listDatabases: 1 }";
|
|
|
|
assert.match(mongodbAuthFailureHint(message), /does not have permission to run listDatabases/);
|
|
});
|
|
|
|
test("adds a MongoDB rustls hint for tlsAllowInvalidHostnames", () => {
|
|
const message = "MongoDB connection failed: Kind: An invalid argument was provided: tlsAllowInvalidHostnames is an invalid option";
|
|
|
|
assert.match(mongodbAuthFailureHint(message), /tlsAllowInvalidCertificates=true/);
|
|
});
|
|
|
|
test("adds a MongoDB DocumentDB SSH tunnel hostname hint", () => {
|
|
const message =
|
|
'MongoDB connection failed: Kind: Server selection timeout: invalid peer certificate: certificate not valid for name "127.0.0.1"; certificate is only valid for DnsName("docdb-2023-06-13-09-23-15.ctofbpmjm2lc.ap-northeast-1.docdb.amazonaws.com")';
|
|
|
|
assert.match(mongodbAuthFailureHint(message), /tlsAllowInvalidCertificates=true/);
|
|
});
|