θΏ™ζ˜―indexlocζδΎ›ηš„ζœεŠ‘οΌŒδΈθ¦θΎ“ε…₯任何密码
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ function assembleConnectionString({
host = "",
port = "",
database = "",
encrypt = false,
}) {
if ([username, password, host, database].every((i) => !!i) === false)
return `Please fill out all the fields above.`;
Expand All @@ -20,7 +21,7 @@ function assembleConnectionString({
case "mysql":
return `mysql://${username}:${password}@${host}:${port}/${database}`;
case "sql-server":
return `mssql://${username}:${password}@${host}:${port}/${database}`;
return `mssql://${username}:${password}@${host}:${port}/${database}?encrypt=${encrypt}`;
default:
return null;
}
Expand All @@ -33,6 +34,7 @@ const DEFAULT_CONFIG = {
host: null,
port: null,
database: null,
encrypt: false,
};

export default function NewSQLConnection({ isOpen, closeModal, onSubmit }) {
Expand All @@ -54,6 +56,7 @@ export default function NewSQLConnection({ isOpen, closeModal, onSubmit }) {
host: form.get("host").trim(),
port: form.get("port").trim(),
database: form.get("database").trim(),
encrypt: form.get("encrypt") === "true",
});
}

Expand Down Expand Up @@ -226,6 +229,26 @@ export default function NewSQLConnection({ isOpen, closeModal, onSubmit }) {
spellCheck={false}
/>
</div>

{engine === "sql-server" && (
<div className="flex items-center justify-between">
<label className="relative inline-flex items-center cursor-pointer">
<input
type="checkbox"
name="encrypt"
value="true"
className="sr-only peer"
onChange={onFormChange}
checked={config.encrypt}
/>
<div className="w-11 h-6 bg-theme-settings-input-bg peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-800 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-blue-600"></div>
<span className="ml-3 text-sm font-medium text-white">
Enable Encryption
</span>
</label>
</div>
)}

<p className="text-theme-text-secondary text-sm">
{assembleConnectionString({ engine, ...config })}
</p>
Expand Down
178 changes: 178 additions & 0 deletions server/__tests__/utils/SQLConnectors/connectionParser.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
/* eslint-env jest */
const { ConnectionStringParser } = require("../../../utils/agents/aibitat/plugins/sql-agent/SQLConnectors/utils");

describe("ConnectionStringParser", () => {
describe("Basic Parsing", () => {
test("should parse a basic connection string without options", () => {
const parser = new ConnectionStringParser({ scheme: "mssql" });
const result = parser.parse("mssql://user:pass@localhost:1433/mydb");

expect(result).toEqual({
scheme: "mssql",
username: "user",
password: "pass",
hosts: [{ host: "localhost", port: 1433 }],
endpoint: "mydb",
options: undefined
});
});

test("should parse a connection string with options", () => {
const parser = new ConnectionStringParser({ scheme: "mssql" });
const result = parser.parse("mssql://user:pass@localhost:1433/mydb?encrypt=true&trustServerCertificate=true");

expect(result).toEqual({
scheme: "mssql",
username: "user",
password: "pass",
hosts: [{ host: "localhost", port: 1433 }],
endpoint: "mydb",
options: {
encrypt: "true",
trustServerCertificate: "true"
}
});
});

test("should handle empty passwords", () => {
const parser = new ConnectionStringParser({ scheme: "mssql" });
const result = parser.parse("mssql://user@localhost:1433/mydb");

expect(result).toEqual({
scheme: "mssql",
username: "user",
password: undefined,
hosts: [{ host: "localhost", port: 1433 }],
endpoint: "mydb",
options: undefined
});
});
});

describe("Error Handling", () => {
test("should throw error for invalid scheme", () => {
const parser = new ConnectionStringParser({ scheme: "mssql" });
expect(() => parser.parse("mysql://user:pass@localhost:3306/mydb"))
.toThrow("URI must start with 'mssql://'");
});

test("should throw error for missing scheme", () => {
const parser = new ConnectionStringParser({ scheme: "mssql" });
expect(() => parser.parse("user:pass@localhost:1433/mydb"))
.toThrow("No scheme found in URI");
});
});

describe("Special Characters", () => {
test("should handle special characters in username and password", () => {
const parser = new ConnectionStringParser({ scheme: "mssql" });
const result = parser.parse("mssql://user%40domain:p%40ssw%3Ard@localhost:1433/mydb");

expect(result).toEqual({
scheme: "mssql",
username: "user@domain",
password: "p@ssw:rd",
hosts: [{ host: "localhost", port: 1433 }],
endpoint: "mydb",
options: undefined
});
});

test("should handle special characters in database name", () => {
const parser = new ConnectionStringParser({ scheme: "mssql" });
const result = parser.parse("mssql://user:pass@localhost:1433/my%20db");

expect(result).toEqual({
scheme: "mssql",
username: "user",
password: "pass",
hosts: [{ host: "localhost", port: 1433 }],
endpoint: "my db",
options: undefined
});
});
});

describe("Multiple Hosts", () => {
test("should parse multiple hosts", () => {
const parser = new ConnectionStringParser({ scheme: "mssql" });
const result = parser.parse("mssql://user:pass@host1:1433,host2:1434/mydb");

expect(result).toEqual({
scheme: "mssql",
username: "user",
password: "pass",
hosts: [
{ host: "host1", port: 1433 },
{ host: "host2", port: 1434 }
],
endpoint: "mydb",
options: undefined
});
});

test("should handle hosts without ports", () => {
const parser = new ConnectionStringParser({ scheme: "mssql" });
const result = parser.parse("mssql://user:pass@host1,host2/mydb");

expect(result).toEqual({
scheme: "mssql",
username: "user",
password: "pass",
hosts: [
{ host: "host1" },
{ host: "host2" }
],
endpoint: "mydb",
options: undefined
});
});
});

describe("Provider-Specific Tests", () => {
test("should parse MySQL connection string", () => {
const parser = new ConnectionStringParser({ scheme: "mysql" });
const result = parser.parse("mysql://user:pass@localhost:3306/mydb?ssl=true");

expect(result).toEqual({
scheme: "mysql",
username: "user",
password: "pass",
hosts: [{ host: "localhost", port: 3306 }],
endpoint: "mydb",
options: { ssl: "true" }
});
});

test("should parse PostgreSQL connection string", () => {
const parser = new ConnectionStringParser({ scheme: "postgresql" });
const result = parser.parse("postgresql://user:pass@localhost:5432/mydb?sslmode=require");

expect(result).toEqual({
scheme: "postgresql",
username: "user",
password: "pass",
hosts: [{ host: "localhost", port: 5432 }],
endpoint: "mydb",
options: { sslmode: "require" }
});
});

test("should parse MSSQL connection string with encryption options", () => {
const parser = new ConnectionStringParser({ scheme: "mssql" });
const result = parser.parse("mssql://user:pass@localhost:1433/mydb?encrypt=true&trustServerCertificate=true");

expect(result).toEqual({
scheme: "mssql",
username: "user",
password: "pass",
hosts: [{ host: "localhost", port: 1433 }],
endpoint: "mydb",
options: {
encrypt: "true",
trustServerCertificate: "true"
}
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ class MSSQLConnector {
database: parsed?.endpoint,
server: parsed?.hosts?.[0]?.host,
port: parsed?.hosts?.[0]?.port,
options: {
...this.connectionConfig.options,
encrypt: parsed?.options?.encrypt === "true",
},
};
}

Expand Down