diff --git a/apps/dokploy/__test__/wss/container-ownership.test.ts b/apps/dokploy/__test__/wss/container-ownership.test.ts index 19b60c076..1dce706fc 100644 --- a/apps/dokploy/__test__/wss/container-ownership.test.ts +++ b/apps/dokploy/__test__/wss/container-ownership.test.ts @@ -1,38 +1,35 @@ import { beforeEach, describe, expect, it, vi } from "vitest"; -const mockFindApp = vi.hoisted(() => vi.fn()); -const mockFindLibsql = vi.hoisted(() => vi.fn()); +const mockRows = vi.hoisted(() => new Map()); const mockExec = vi.hoisted(() => vi.fn()); -vi.mock("@dokploy/server/db", () => { - const none = { findFirst: async () => undefined }; - return { - db: { - query: { - applications: { findFirst: mockFindApp }, - compose: none, - postgres: none, - mysql: none, - mariadb: none, - mongo: none, - redis: none, - libsql: { findFirst: mockFindLibsql }, - }, - }, - }; -}); +vi.mock("@dokploy/server/db", () => ({ + db: { + select: () => ({ + from: (table: unknown) => ({ + where: () => ({ + limit: async () => { + const row = mockRows.get(table); + return row ? [row] : []; + }, + }), + }), + }), + }, +})); vi.mock("@dokploy/server/utils/process/execAsync", () => ({ execAsync: mockExec, execAsyncRemote: mockExec, })); +import { applications, libsql } from "@dokploy/server/db/schema"; import { containerBelongsToService } from "@/server/wss/container-ownership"; const labels = (l: Record) => ({ stdout: JSON.stringify(l) }); beforeEach(() => { vi.clearAllMocks(); - mockFindApp.mockResolvedValue({ appName: "app-mine-abc123" }); - mockFindLibsql.mockResolvedValue(undefined); + mockRows.clear(); + mockRows.set(applications, { appName: "app-mine-abc123" }); }); describe("containerBelongsToService", () => { @@ -58,8 +55,8 @@ describe("containerBelongsToService", () => { }); it("resolves libsql services", async () => { - mockFindApp.mockResolvedValue(undefined); - mockFindLibsql.mockResolvedValue({ appName: "libsql-abc" }); + mockRows.clear(); + mockRows.set(libsql, { appName: "libsql-abc" }); mockExec.mockResolvedValue( labels({ "com.docker.swarm.service.name": "libsql-abc" }), ); @@ -67,7 +64,7 @@ describe("containerBelongsToService", () => { }); it("denies an unknown service", async () => { - mockFindApp.mockResolvedValue(undefined); + mockRows.clear(); expect(await containerBelongsToService("nope", "c1")).toBe(false); }); }); diff --git a/apps/dokploy/server/wss/container-ownership.ts b/apps/dokploy/server/wss/container-ownership.ts index 3bc16bb41..0c536a5e3 100644 --- a/apps/dokploy/server/wss/container-ownership.ts +++ b/apps/dokploy/server/wss/container-ownership.ts @@ -22,42 +22,26 @@ const OWNERSHIP_LABELS = [ "com.docker.stack.namespace", ]; +const SERVICE_TABLES = [ + { table: applications, id: applications.applicationId }, + { table: compose, id: compose.composeId }, + { table: postgres, id: postgres.postgresId }, + { table: mysql, id: mysql.mysqlId }, + { table: mariadb, id: mariadb.mariadbId }, + { table: mongo, id: mongo.mongoId }, + { table: redis, id: redis.redisId }, + { table: libsql, id: libsql.libsqlId }, +]; + const findServiceAppName = async (serviceId: string) => { - const [app, comp, pg, my, maria, mon, red, lib] = await Promise.all([ - db.query.applications.findFirst({ - where: eq(applications.applicationId, serviceId), - columns: { appName: true }, - }), - db.query.compose.findFirst({ - where: eq(compose.composeId, serviceId), - columns: { appName: true }, - }), - db.query.postgres.findFirst({ - where: eq(postgres.postgresId, serviceId), - columns: { appName: true }, - }), - db.query.mysql.findFirst({ - where: eq(mysql.mysqlId, serviceId), - columns: { appName: true }, - }), - db.query.mariadb.findFirst({ - where: eq(mariadb.mariadbId, serviceId), - columns: { appName: true }, - }), - db.query.mongo.findFirst({ - where: eq(mongo.mongoId, serviceId), - columns: { appName: true }, - }), - db.query.redis.findFirst({ - where: eq(redis.redisId, serviceId), - columns: { appName: true }, - }), - db.query.libsql.findFirst({ - where: eq(libsql.libsqlId, serviceId), - columns: { appName: true }, - }), - ]); - return (app ?? comp ?? pg ?? my ?? maria ?? mon ?? red ?? lib)?.appName; + for (const { table, id } of SERVICE_TABLES) { + const [row] = await db + .select({ appName: table.appName }) + .from(table) + .where(eq(id, serviceId)) + .limit(1); + if (row) return row.appName; + } }; // Service access alone must not allow `docker exec` into other tenants' containers.