import { describe, it, expect } from "vitest"; import { importedHostUsername, notifyImportedHosts, parseSSHConfig, } from "../../../database/routes/host-bulk-routes.js"; import { pluginEvents, TOPICS } from "../../../plugins/events.js"; describe("parseSSHConfig", () => { it("parses a basic Host block", () => { const config = ` Host myserver HostName 192.168.1.10 User alice Port 2222 `; const result = parseSSHConfig(config); expect(result).toHaveLength(1); expect(result[0]).toMatchObject({ name: "myserver", hostname: "192.168.1.10", user: "alice", port: 2222, }); }); it("parses multiple Host blocks", () => { const config = ` Host web HostName web.example.com User deploy Host db HostName db.example.com User postgres Port 5432 `; const result = parseSSHConfig(config); expect(result).toHaveLength(2); expect(result[0].name).toBe("web"); expect(result[1].name).toBe("db"); expect(result[1].port).toBe(5432); }); it("ignores comment lines", () => { const config = ` # This is a comment Host server # Another comment HostName 10.0.0.1 User root `; const result = parseSSHConfig(config); expect(result).toHaveLength(1); expect(result[0].hostname).toBe("10.0.0.1"); }); it("skips wildcard Host entries", () => { const config = ` Host * ServerAliveInterval 60 Host prod HostName prod.example.com User ubuntu `; const result = parseSSHConfig(config); expect(result).toHaveLength(1); expect(result[0].name).toBe("prod"); }); it("captures IdentityFile and ProxyJump", () => { const config = ` Host bastion HostName bastion.example.com User ec2-user IdentityFile ~/.ssh/id_rsa ProxyJump jumphost.example.com `; const result = parseSSHConfig(config); expect(result).toHaveLength(1); expect(result[0].identityFile).toBe("~/.ssh/id_rsa"); expect(result[0].proxyJump).toBe("jumphost.example.com"); }); it("skips Host blocks without a HostName", () => { const config = ` Host alias-only User foo `; const result = parseSSHConfig(config); expect(result).toHaveLength(0); }); it("accepts tabs and = between keywords and values", () => { const config = "Host\tweb\n\tHostName=10.0.0.5\n\tUser = deploy\n"; expect(parseSSHConfig(config)).toEqual([ { name: "web", hostname: "10.0.0.5", user: "deploy" }, ]); }); it("defaults port to undefined when not specified", () => { const config = ` Host server HostName 1.2.3.4 User root `; const result = parseSSHConfig(config); expect(result[0].port).toBeUndefined(); }); it("returns empty array for empty input", () => { expect(parseSSHConfig("")).toHaveLength(0); expect(parseSSHConfig(" \n\n ")).toHaveLength(0); }); }); describe("importedHostUsername", () => { it("lets credential-backed SSH hosts inherit the credential username", () => { expect(importedHostUsername("ssh", "credential", "")).toBe(""); }); it("keeps requiring usernames for other SSH authentication modes", () => { expect(importedHostUsername("ssh", "password", "")).toBeNull(); expect(importedHostUsername("ssh", "key", undefined)).toBeNull(); }); it("always returns a non-null database value for non-SSH hosts", () => { expect(importedHostUsername("rdp", "password", undefined)).toBe(""); }); it("preserves an explicitly configured host username", () => { expect(importedHostUsername("ssh", "credential", "guest-admin")).toBe( "guest-admin", ); }); }); describe("notifyImportedHosts", () => { it("sends a host update for every imported host", () => { const seen: unknown[] = []; const off = pluginEvents.on(TOPICS.hostUpdated, (payload) => { seen.push(payload); }); try { notifyImportedHosts("user-1", [4, 7]); } finally { off(); } expect(seen).toEqual([ { hostId: 4, userId: "user-1" }, { hostId: 7, userId: "user-1" }, ]); }); });