mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-29 22:55:24 +00:00
feat: move snippets backend and tables into a plugin (B2)
This commit is contained in:
1 parent
fdedca39fd
commit
e07221eaf3
51 files changed
+28426
-3553
No files matched your search
@@ -1,79 +0,0 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
createSnippetExecutionResult,
|
||||
getSnippetExecutionTimeoutMs,
|
||||
resolveSnippetCommand,
|
||||
} from "../../../database/routes/snippets-execution.js";
|
||||
|
||||
describe("snippet execution", () => {
|
||||
it("treats stderr as diagnostic output when the command succeeds", () => {
|
||||
expect(createSnippetExecutionResult(0, "done\n", "warning\n")).toEqual({
|
||||
success: true,
|
||||
output: "done\n",
|
||||
error: "warning\n",
|
||||
});
|
||||
});
|
||||
|
||||
it("uses the exit code to report command failure", () => {
|
||||
expect(createSnippetExecutionResult(1, "", "failed\n")).toEqual({
|
||||
success: false,
|
||||
output: "",
|
||||
error: "failed\n",
|
||||
});
|
||||
});
|
||||
|
||||
it("preserves the previous fallback when no exit code is available", () => {
|
||||
expect(createSnippetExecutionResult(null, "done\n", "")).toEqual({
|
||||
success: true,
|
||||
output: "done\n",
|
||||
});
|
||||
expect(createSnippetExecutionResult(null, "", "failed\n").success).toBe(
|
||||
false,
|
||||
);
|
||||
});
|
||||
|
||||
it("disables the command timeout by default", () => {
|
||||
expect(getSnippetExecutionTimeoutMs(undefined)).toBeUndefined();
|
||||
});
|
||||
|
||||
it("converts a configured timeout from seconds to milliseconds", () => {
|
||||
expect(getSnippetExecutionTimeoutMs("45")).toBe(45_000);
|
||||
});
|
||||
|
||||
it.each(["", "0", "-1", "invalid"])(
|
||||
"ignores invalid timeout value %j",
|
||||
(value) => {
|
||||
expect(getSnippetExecutionTimeoutMs(value)).toBeUndefined();
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
describe("resolveSnippetCommand", () => {
|
||||
const host = { ip: "10.0.0.5", username: "root", port: 22, name: "web-01" };
|
||||
|
||||
it("substitutes host variables per target host", () => {
|
||||
expect(
|
||||
resolveSnippetCommand("ssh $USER@$HOST -p $PORT # $NAME", host),
|
||||
).toBe("ssh root@10.0.0.5 -p 22 # web-01");
|
||||
});
|
||||
|
||||
it("supports brace syntax for host variables", () => {
|
||||
expect(resolveSnippetCommand("ping ${HOST}", host)).toBe("ping 10.0.0.5");
|
||||
});
|
||||
|
||||
it("substitutes input placeholders from inputValues", () => {
|
||||
expect(
|
||||
resolveSnippetCommand("nc -zv $HOST ${INPUT_1:Port}", host, {
|
||||
INPUT_1: "8080",
|
||||
}),
|
||||
).toBe("nc -zv 10.0.0.5 8080");
|
||||
});
|
||||
|
||||
it("leaves host variables literal when no host context is given", () => {
|
||||
expect(resolveSnippetCommand("ping $HOST", null)).toBe("ping $HOST");
|
||||
});
|
||||
|
||||
it("leaves input placeholders literal when no value was supplied", () => {
|
||||
expect(resolveSnippetCommand("echo $INPUT_1", null)).toBe("echo $INPUT_1");
|
||||
});
|
||||
});
|
||||
@@ -1,20 +0,0 @@
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
describe("snippet execution host access", () => {
|
||||
it("uses the shared-host-aware resolver", () => {
|
||||
const source = fs.readFileSync(
|
||||
path.resolve(__dirname, "../../../database/routes/snippets.ts"),
|
||||
"utf8",
|
||||
);
|
||||
const executeRoute = source.slice(
|
||||
source.indexOf('router.post(\n "/execute"'),
|
||||
);
|
||||
|
||||
expect(executeRoute).toContain(
|
||||
"const host = await resolveHostById(parseInt(hostId), userId)",
|
||||
);
|
||||
expect(executeRoute).not.toContain("host.userId !== userId");
|
||||
});
|
||||
});
|
||||
@@ -33,8 +33,6 @@ describe("isValidEntityType", () => {
|
||||
"hosts",
|
||||
"sshCredentials",
|
||||
"sshFolders",
|
||||
"snippets",
|
||||
"snippetFolders",
|
||||
"vaultProfiles",
|
||||
"dashboardServiceLinks",
|
||||
"homepageItems",
|
||||
@@ -88,7 +86,7 @@ describe("stripWritePayload", () => {
|
||||
|
||||
it("does not mutate the original payload object", () => {
|
||||
const payload = { id: 1, userId: "user-1", syncId: "abc", name: "x" };
|
||||
stripWritePayload("snippets", payload);
|
||||
stripWritePayload("sshFolders", payload);
|
||||
expect(payload).toEqual({
|
||||
id: 1,
|
||||
userId: "user-1",
|
||||
|
||||
@@ -6,6 +6,7 @@ const calls = vi.hoisted(() => ({
|
||||
deletedFor: [] as string[],
|
||||
rotatedFor: [] as string[],
|
||||
legacyWrapsDeletedFor: [] as string[],
|
||||
dataWipedEvents: [] as Array<{ userId: string }>,
|
||||
}));
|
||||
|
||||
function deletingRepo(label: string) {
|
||||
@@ -29,11 +30,19 @@ vi.mock("../../../database/repositories/factory.js", () => ({
|
||||
createCurrentFileManagerBookmarkRepository: deletingRepo("bookmarks"),
|
||||
createCurrentRecentActivityRepository: deletingRepo("activity"),
|
||||
createCurrentDismissedAlertRepository: deletingRepo("alerts"),
|
||||
createCurrentSnippetRepository: deletingRepo("snippets"),
|
||||
createCurrentHostRepository: deletingRepo("hosts"),
|
||||
createCurrentCredentialRepository: deletingRepo("credentials"),
|
||||
}));
|
||||
|
||||
vi.mock("../../../plugins/events.js", () => ({
|
||||
pluginEvents: {
|
||||
emit: (_topic: string, payload: { userId: string }) => {
|
||||
calls.dataWipedEvents.push(payload);
|
||||
},
|
||||
},
|
||||
TOPICS: { userDataWiped: "user.data_wiped" },
|
||||
}));
|
||||
|
||||
vi.mock("../../../utils/user-keys.js", () => ({
|
||||
UserKeyManager: {
|
||||
getInstance: () => ({
|
||||
@@ -65,6 +74,7 @@ beforeEach(() => {
|
||||
calls.deletedFor = [];
|
||||
calls.rotatedFor = [];
|
||||
calls.legacyWrapsDeletedFor = [];
|
||||
calls.dataWipedEvents = [];
|
||||
});
|
||||
|
||||
describe("resetUserPassword", () => {
|
||||
@@ -110,10 +120,10 @@ describe("resetUserPassword", () => {
|
||||
"bookmarks:user-1",
|
||||
"activity:user-1",
|
||||
"alerts:user-1",
|
||||
"snippets:user-1",
|
||||
"hosts:user-1",
|
||||
"credentials:user-1",
|
||||
]);
|
||||
expect(calls.dataWipedEvents).toEqual([{ userId: "user-1" }]);
|
||||
expect(calls.rotatedFor).toEqual(["user-1"]);
|
||||
expect(calls.legacyWrapsDeletedFor).toEqual(["user-1"]);
|
||||
expect(
|
||||
|
||||
Reference in new issue
Block a user