mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-28 14:15:24 +00:00
135 lines
4.6 KiB
TypeScript
135 lines
4.6 KiB
TypeScript
import { afterEach, describe, expect, it } from "vitest";
|
|
import { startServer, type TestServer } from "./helpers";
|
|
|
|
let server: TestServer | null = null;
|
|
|
|
afterEach(async () => {
|
|
await server?.close();
|
|
server = null;
|
|
});
|
|
|
|
const history = (s: TestServer) =>
|
|
s.db.sqlite
|
|
.prepare(
|
|
"SELECT user_id, host_id, command FROM p_ssh_terminal_command_history ORDER BY id",
|
|
)
|
|
.all();
|
|
|
|
describe("command history routes", () => {
|
|
it("saves, lists newest first without duplicates, deletes and clears", async () => {
|
|
server = await startServer();
|
|
for (const command of ["ls", "pwd", "ls"]) {
|
|
const saved = await server.request("POST", "/command-history", {
|
|
body: { hostId: 1, command },
|
|
});
|
|
expect(saved.status).toBe(201);
|
|
}
|
|
await server.request("POST", "/command-history", {
|
|
user: "user-2",
|
|
body: { hostId: 1, command: "whoami" },
|
|
});
|
|
|
|
const listed = await server.request("GET", "/command-history/1");
|
|
expect(listed.body).toEqual(["ls", "pwd"]);
|
|
|
|
await server.request("POST", "/command-history/delete", {
|
|
body: { hostId: 1, command: "pwd" },
|
|
});
|
|
expect((await server.request("GET", "/command-history/1")).body).toEqual([
|
|
"ls",
|
|
]);
|
|
|
|
await server.request("DELETE", "/command-history/1");
|
|
expect(history(server)).toEqual([
|
|
{ user_id: "user-2", host_id: 1, command: "whoami" },
|
|
]);
|
|
expect(server.db.persisted).toBeGreaterThan(0);
|
|
});
|
|
|
|
it("acknowledges but never stores a command that looks like a secret", async () => {
|
|
server = await startServer();
|
|
const saved = await server.request("POST", "/command-history", {
|
|
body: { hostId: 1, command: "export API_TOKEN=abc" },
|
|
});
|
|
expect(saved.status).toBe(201);
|
|
expect(history(server)).toEqual([]);
|
|
});
|
|
|
|
it("stores nothing while command history is off globally", async () => {
|
|
server = await startServer({ settings: { commandHistoryEnabled: false } });
|
|
await server.request("POST", "/command-history", {
|
|
body: { hostId: 1, command: "ls" },
|
|
});
|
|
expect(history(server)).toEqual([]);
|
|
});
|
|
|
|
it("stores nothing for a host that turned command history off", async () => {
|
|
server = await startServer();
|
|
await server.mock.ctx.settings.setHost(2, "enableCommandHistory", false);
|
|
await server.request("POST", "/command-history", {
|
|
body: { hostId: 2, command: "ls" },
|
|
});
|
|
await server.request("POST", "/command-history", {
|
|
body: { hostId: 1, command: "ls" },
|
|
});
|
|
expect(history(server)).toEqual([
|
|
{ user_id: "user-1", host_id: 1, command: "ls" },
|
|
]);
|
|
});
|
|
|
|
it("rejects a request missing its fields", async () => {
|
|
server = await startServer();
|
|
const saved = await server.request("POST", "/command-history", {
|
|
body: { hostId: 1 },
|
|
});
|
|
expect(saved.status).toBe(400);
|
|
});
|
|
|
|
it("needs hosts.view for the recent list", async () => {
|
|
server = await startServer({ permissions: [] });
|
|
const denied = await server.request("GET", "/command-history/1/recent");
|
|
expect(denied.status).toBe(403);
|
|
});
|
|
|
|
it("lists recent commands with duplicates for a hosts.view holder", async () => {
|
|
server = await startServer({ permissions: ["hosts.view"] });
|
|
for (const command of ["uptime", "uptime"]) {
|
|
await server.request("POST", "/command-history", {
|
|
body: { hostId: 1, command },
|
|
});
|
|
}
|
|
const allowed = await server.request("GET", "/command-history/1/recent");
|
|
expect(allowed.body).toEqual(["uptime", "uptime"]);
|
|
});
|
|
});
|
|
|
|
describe("client settings and image storage", () => {
|
|
it("serves the terminal's settings to any signed-in user", async () => {
|
|
server = await startServer({
|
|
settings: { sessionTimeoutMinutes: 45, sessionPersistence: false },
|
|
});
|
|
const { body } = await server.request("GET", "/client-settings");
|
|
expect(body.sessionTimeoutMinutes).toBe(45);
|
|
expect(body.sessionPersistence).toBe(false);
|
|
expect(body.commandHistoryEnabled).toBe(true);
|
|
expect(body.touchInput.enabled).toBe(true);
|
|
});
|
|
|
|
it("refuses the image storage test to a non-admin", async () => {
|
|
server = await startServer({ permissions: [] });
|
|
const denied = await server.request("POST", "/image-storage/test", {
|
|
body: { instanceId: "tab-1" },
|
|
});
|
|
expect(denied.status).toBe(403);
|
|
});
|
|
|
|
it("reports an unconnected session to an admin", async () => {
|
|
server = await startServer({ permissions: ["admin.plugins.manage"] });
|
|
const result = await server.request("POST", "/image-storage/test", {
|
|
body: { instanceId: "tab-1" },
|
|
});
|
|
expect(result.status).toBe(200);
|
|
expect(result.body.connected).toBe(false);
|
|
});
|
|
});
|