mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-28 14:15:24 +00:00
chore: merge dev-2.9.1 into dev-26.10.0
This commit is contained in:
commit
77bcbdb3d6
1310 files changed
+102834
-51010
No files matched your search
@@ -91,6 +91,18 @@ vi.mock("../../hosts/connect/connect-host.js", () => ({
|
||||
return { client, jumpClient: null, dispose: vi.fn(() => client.end()) };
|
||||
},
|
||||
}));
|
||||
vi.mock("../../hosts/host-resolver.js", () => ({
|
||||
resolveHostById: async (hostId: number, userId: string) => ({
|
||||
id: hostId,
|
||||
userId,
|
||||
ip: "10.0.0.5",
|
||||
port: 22,
|
||||
username: "root",
|
||||
authType: "password",
|
||||
password: "stored-secret",
|
||||
}),
|
||||
resolveHostBySyncId: async () => null,
|
||||
}));
|
||||
vi.mock("../../hosts/status/host-status-service.js", () => ({
|
||||
hostStatusService: {
|
||||
reportLogin: (hostId: number, outcome: unknown) =>
|
||||
@@ -253,6 +265,50 @@ describe("ctx.ssh", () => {
|
||||
expect(h.connects[0].target).toMatchObject({ userId: "caller" });
|
||||
});
|
||||
|
||||
it("connects a copied redacted host with its stored login", async () => {
|
||||
h.granted = new Set(["ssh:connect", "credentials:use"]);
|
||||
const ssh = createPluginSsh({
|
||||
manifest: manifest(["ssh:connect", "credentials:use"]),
|
||||
bag: new DisposableBag("fixture"),
|
||||
audit: vi.fn(async () => {}),
|
||||
});
|
||||
const host = (await ssh.resolveHost(5))!;
|
||||
expect((host as Record<string, unknown>).password).toBeUndefined();
|
||||
expect(JSON.stringify(host)).not.toContain("stored-secret");
|
||||
for (const symbol of Object.getOwnPropertySymbols(host)) {
|
||||
expect(JSON.stringify((host as never)[symbol])).not.toContain(
|
||||
"stored-secret",
|
||||
);
|
||||
}
|
||||
|
||||
await ssh.connect({ ...host, port: host.port || 22 });
|
||||
expect(h.connects[0].target).toMatchObject({ password: "stored-secret" });
|
||||
|
||||
await ssh.connect({ ...host, password: "typed", authType: "password" });
|
||||
expect(h.connects[1].target).toMatchObject({ password: "typed" });
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
expect(h.logins.map((login) => login.hostId)).toEqual([5, 5]);
|
||||
});
|
||||
|
||||
it("does not honor another plugin's resolved host", async () => {
|
||||
h.granted = new Set(["ssh:connect", "credentials:use"]);
|
||||
const deps = {
|
||||
manifest: manifest(["ssh:connect", "credentials:use"]),
|
||||
audit: vi.fn(async () => {}),
|
||||
};
|
||||
const first = createPluginSsh({
|
||||
...deps,
|
||||
bag: new DisposableBag("fixture"),
|
||||
});
|
||||
const second = createPluginSsh({
|
||||
...deps,
|
||||
bag: new DisposableBag("fixture"),
|
||||
});
|
||||
const host = (await first.resolveHost(5))!;
|
||||
await second.connect({ ...host });
|
||||
expect(h.connects[0].target).not.toHaveProperty("password");
|
||||
});
|
||||
|
||||
it("passes a given stream through to the pipeline, gated like any connect", async () => {
|
||||
const stream = { throughSource: true };
|
||||
const ssh = createPluginSsh({
|
||||
|
||||
@@ -117,6 +117,32 @@ describe("plugin user data", () => {
|
||||
expect(again).toMatchObject({ imported: 0, skipped: 1 });
|
||||
});
|
||||
|
||||
it("writes large tables in chunks and lets the event loop run between them", async () => {
|
||||
const insert = sqlite.prepare(
|
||||
"INSERT INTO p_fixture_bookmark (user_id, path) VALUES ('u1', ?)",
|
||||
);
|
||||
sqlite.transaction(() => {
|
||||
for (let i = 0; i < 4999; i++) insert.run(`/p/${i}`);
|
||||
})();
|
||||
const file = new Database(":memory:");
|
||||
file.exec("CREATE TABLE users (id TEXT PRIMARY KEY)");
|
||||
file.exec("CREATE TABLE ssh_data (id INTEGER PRIMARY KEY)");
|
||||
file.exec("INSERT INTO users (id) VALUES ('u1')");
|
||||
const transaction = vi.spyOn(file, "transaction");
|
||||
let ticks = 0;
|
||||
const ticker = setInterval(() => ticks++, 0);
|
||||
|
||||
const written = await writeUserPluginTables(file, "u1");
|
||||
clearInterval(ticker);
|
||||
|
||||
expect(written).toBe(5000);
|
||||
expect(transaction).toHaveBeenCalled();
|
||||
expect(ticks).toBeGreaterThan(0);
|
||||
expect(
|
||||
file.prepare("SELECT COUNT(*) AS n FROM p_fixture_bookmark").get(),
|
||||
).toEqual({ n: 5000 });
|
||||
});
|
||||
|
||||
it("reads a pre-2.9 export by the legacy table name", async () => {
|
||||
const file = new Database(":memory:");
|
||||
file.exec(
|
||||
|
||||
Reference in new issue
Block a user