mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-28 14:15:24 +00:00
feat: ssh transport providers, core ssh relay and plugin folders api
This commit is contained in:
1 parent
3caf6cca62
commit
901a235de4
20 files changed
+736
-77
No files matched your search
@@ -30,6 +30,8 @@ const h = vi.hoisted(() => ({
|
||||
existingAccess: [] as Array<{ id: number }>,
|
||||
revoked: [] as number[],
|
||||
protocolWrites: [] as Array<{ hostId: number; protocols: string[] }>,
|
||||
folderCalls: [] as Array<unknown[]>,
|
||||
folderEmpty: true,
|
||||
roles: [] as Array<{
|
||||
id: number;
|
||||
name: string;
|
||||
@@ -96,6 +98,15 @@ vi.mock("../../database/repositories/factory.js", () => ({
|
||||
createCurrentUserRepository: () => ({
|
||||
listAll: async () => h.users,
|
||||
}),
|
||||
createCurrentHostFolderRepository: () => ({
|
||||
upsertMetadata: async (...args: unknown[]) => {
|
||||
h.folderCalls.push(["ensure", ...args]);
|
||||
},
|
||||
deleteEmptyFolderRecords: async (...args: unknown[]) => {
|
||||
h.folderCalls.push(["remove", ...args]);
|
||||
return h.folderEmpty;
|
||||
},
|
||||
}),
|
||||
createCurrentHostRepository: () => ({
|
||||
createEncryptedForUser: async (
|
||||
userId: string,
|
||||
@@ -961,3 +972,45 @@ describe("ctx.hosts.locks", () => {
|
||||
expect(h.updates).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe("ctx.hosts.folders", () => {
|
||||
beforeEach(() => {
|
||||
h.granted = new Set(["hosts:write"]);
|
||||
h.actor = "user-1";
|
||||
h.folderCalls = [];
|
||||
h.folderEmpty = true;
|
||||
});
|
||||
|
||||
it("needs hosts:write", async () => {
|
||||
h.granted = new Set();
|
||||
const hosts = createPluginHosts({
|
||||
manifest: manifest(["hosts:write"]),
|
||||
audit: vi.fn(async () => {}),
|
||||
});
|
||||
await expect(hosts.folders.ensure("Site")).rejects.toThrow(
|
||||
PluginCapabilityError,
|
||||
);
|
||||
});
|
||||
|
||||
it("creates the folder row for the acting user with its style", async () => {
|
||||
const hosts = createPluginHosts({
|
||||
manifest: manifest(["hosts:write"]),
|
||||
audit: vi.fn(async () => {}),
|
||||
});
|
||||
await hosts.folders.ensure("Site", { icon: "cloud-cog" });
|
||||
expect(h.folderCalls).toEqual([
|
||||
["ensure", "user-1", "Site", null, "cloud-cog"],
|
||||
]);
|
||||
});
|
||||
|
||||
it("removes only an empty folder", async () => {
|
||||
const hosts = createPluginHosts({
|
||||
manifest: manifest(["hosts:write"]),
|
||||
audit: vi.fn(async () => {}),
|
||||
});
|
||||
expect(await hosts.folders.removeEmpty("Site")).toBe(true);
|
||||
h.folderEmpty = false;
|
||||
expect(await hosts.folders.removeEmpty("Site")).toBe(false);
|
||||
expect(h.folderCalls[0]).toEqual(["remove", "user-1", "Site"]);
|
||||
});
|
||||
});
|
||||
@@ -154,6 +154,26 @@ describe("ctx.ws routing", () => {
|
||||
if (result.outcome === "open") result.socket.close();
|
||||
});
|
||||
|
||||
it("serves a socket core owns without any plugin grant", async () => {
|
||||
state.granted = new Set();
|
||||
const seen: string[] = [];
|
||||
ws.registerCoreWsRoute("/relay", ({ userId }) => {
|
||||
seen.push(userId);
|
||||
});
|
||||
|
||||
const base = await startServer();
|
||||
const signedIn = await connect(
|
||||
`${base}/plugin-ws/core/relay`,
|
||||
authProtocols(state.validToken),
|
||||
);
|
||||
const anonymous = await connect(`${base}/plugin-ws/core/relay`);
|
||||
|
||||
expect(signedIn.outcome).toBe("open");
|
||||
expect(anonymous.outcome).toBe(401);
|
||||
expect(seen).toEqual([state.userId]);
|
||||
if (signedIn.outcome === "open") signedIn.socket.close();
|
||||
});
|
||||
|
||||
it("404s a path nothing registered", async () => {
|
||||
const base = await startServer();
|
||||
|
||||
|
||||
Reference in new issue
Block a user