mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-28 06:05:24 +00:00
fix(database): preserve RDP domain during startup backfill (#1497)
This commit is contained in:
1 parent
1f4b1ff6a4
commit
5b0423c8e0
3 files changed
+110
-1
No files matched your search
@@ -0,0 +1,67 @@
|
||||
import fs from "fs";
|
||||
import os from "os";
|
||||
import path from "path";
|
||||
import Database from "better-sqlite3";
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
describe("RDP domain across database boots", () => {
|
||||
let dataDir: string;
|
||||
|
||||
beforeEach(() => {
|
||||
dataDir = fs.mkdtempSync(path.join(os.tmpdir(), "termix-rdp-domain-"));
|
||||
vi.resetModules();
|
||||
vi.stubEnv("DATA_DIR", dataDir);
|
||||
vi.stubEnv("DB_FILE_ENCRYPTION", "false");
|
||||
vi.stubEnv("ALLOW_EMPTY_DATA_DIR", "true");
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.unstubAllEnvs();
|
||||
fs.rmSync(dataDir, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
it.each([
|
||||
{ saved: "CORP", legacy: null, expected: "CORP" },
|
||||
{ saved: "CORP", legacy: "OLD", expected: "CORP" },
|
||||
{ saved: "", legacy: "OLD", expected: "" },
|
||||
{ saved: null, legacy: "LEGACY", expected: null },
|
||||
])("preserves $saved with legacy domain $legacy across boots", async ({
|
||||
saved,
|
||||
legacy,
|
||||
expected,
|
||||
}) => {
|
||||
const seed = new Database(":memory:");
|
||||
seed.exec(
|
||||
fs.readFileSync(
|
||||
new URL("../../fixtures/sqlite-2.8-schema.sql", import.meta.url),
|
||||
"utf8",
|
||||
),
|
||||
);
|
||||
seed.exec(`
|
||||
INSERT INTO users (id, username, password_hash)
|
||||
VALUES ('owner', 'alice', 'hash');
|
||||
`);
|
||||
seed.prepare(`
|
||||
INSERT INTO ssh_data
|
||||
(id, user_id, ip, port, username, auth_type, connection_type,
|
||||
rdp_auth_type, rdp_user, rdp_password, rdp_domain, domain)
|
||||
VALUES (1, 'owner', '192.0.2.1', 3389, '', 'password', 'rdp',
|
||||
'credential', NULL, NULL, ?, ?)
|
||||
`).run(saved, legacy);
|
||||
fs.writeFileSync(path.join(dataDir, "db.sqlite"), seed.serialize());
|
||||
seed.close();
|
||||
|
||||
for (let boot = 0; boot < 2; boot++) {
|
||||
vi.resetModules();
|
||||
const db = await import("../../../database/db/index.js");
|
||||
await db.initializeDatabase();
|
||||
expect(
|
||||
db.getSqlite()
|
||||
.prepare("SELECT rdp_domain FROM ssh_data WHERE id = 1")
|
||||
.pluck()
|
||||
.get(),
|
||||
).toBe(expected);
|
||||
await db.saveMemoryDatabaseToFile();
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -35,6 +35,7 @@ vi.mock("../../utils/data-crypto.js", () => ({
|
||||
|
||||
import {
|
||||
copiedMarker,
|
||||
legacyLogin,
|
||||
runProtocolAuthMigration,
|
||||
} from "../../upgrade/protocol-auth-migration.js";
|
||||
import { createCurrentHostProtocolAuthRepository } from "../../database/repositories/factory.js";
|
||||
@@ -221,3 +222,43 @@ describe("runProtocolAuthMigration", () => {
|
||||
expect(await logins()).toHaveProperty("3:telnet");
|
||||
});
|
||||
});
|
||||
|
||||
describe("legacyLogin rdp domain", () => {
|
||||
const rdp = {
|
||||
id: "rdp",
|
||||
user: "rdp_user",
|
||||
password: "rdp_password",
|
||||
passwordField: "rdpPassword",
|
||||
credential: "rdp_credential_id",
|
||||
authType: "rdp_auth_type",
|
||||
domain: "rdp_domain",
|
||||
};
|
||||
|
||||
it.each([
|
||||
{ saved: "CORP", legacy: null, expected: { domain: "CORP" } },
|
||||
{ saved: "CORP", legacy: "OLD", expected: { domain: "CORP" } },
|
||||
{ saved: "", legacy: "OLD", expected: {} },
|
||||
{ saved: null, legacy: "LEGACY", expected: { domain: "LEGACY" } },
|
||||
])(
|
||||
"keeps saved domain $saved over legacy $legacy for a credential host",
|
||||
({ saved, legacy, expected }) => {
|
||||
const login = legacyLogin(
|
||||
{
|
||||
id: 1,
|
||||
user_id: "owner",
|
||||
connection_type: "rdp",
|
||||
rdp_auth_type: "credential",
|
||||
rdp_credential_id: 5,
|
||||
rdp_user: null,
|
||||
rdp_password: null,
|
||||
rdp_domain: saved,
|
||||
domain: legacy,
|
||||
},
|
||||
rdp,
|
||||
ownerKey,
|
||||
() => true,
|
||||
);
|
||||
expect(login?.fields).toEqual(expected);
|
||||
},
|
||||
);
|
||||
});
|
||||
@@ -139,7 +139,8 @@ export function legacyLogin(
|
||||
password = openLegacySecret(row.password, dek, recordId, ["password"]);
|
||||
domain = protocol.domain ? text(row.domain) : "";
|
||||
if (!username && !password && !domain) return null;
|
||||
} else if (protocol.domain && !domain) {
|
||||
} else if (protocol.domain && row[protocol.domain] == null) {
|
||||
// A saved empty domain was cleared on purpose, so only fill a missing one.
|
||||
domain = text(row.domain);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user