From 73c795e15780b30cf8f86cc71f79ad0fdcfb0b80 Mon Sep 17 00:00:00 2001 From: Narciso Date: Wed, 21 Oct 2026 22:26:02 -0400 Subject: [PATCH] fix(wss): resolve libsql services when binding the container terminal --- .../dokploy/__test__/wss/container-ownership.test.ts | 12 ++++++++++++ apps/dokploy/server/wss/container-ownership.ts | 9 +++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/apps/dokploy/__test__/wss/container-ownership.test.ts b/apps/dokploy/__test__/wss/container-ownership.test.ts index 68102e1f6..19b60c076 100644 --- a/apps/dokploy/__test__/wss/container-ownership.test.ts +++ b/apps/dokploy/__test__/wss/container-ownership.test.ts @@ -1,6 +1,7 @@ import { beforeEach, describe, expect, it, vi } from "vitest"; const mockFindApp = vi.hoisted(() => vi.fn()); +const mockFindLibsql = vi.hoisted(() => vi.fn()); const mockExec = vi.hoisted(() => vi.fn()); vi.mock("@dokploy/server/db", () => { const none = { findFirst: async () => undefined }; @@ -14,6 +15,7 @@ vi.mock("@dokploy/server/db", () => { mariadb: none, mongo: none, redis: none, + libsql: { findFirst: mockFindLibsql }, }, }, }; @@ -30,6 +32,7 @@ const labels = (l: Record) => ({ stdout: JSON.stringify(l) }); beforeEach(() => { vi.clearAllMocks(); mockFindApp.mockResolvedValue({ appName: "app-mine-abc123" }); + mockFindLibsql.mockResolvedValue(undefined); }); describe("containerBelongsToService", () => { @@ -54,6 +57,15 @@ describe("containerBelongsToService", () => { expect(await containerBelongsToService("svc", "c1")).toBe(false); }); + it("resolves libsql services", async () => { + mockFindApp.mockResolvedValue(undefined); + mockFindLibsql.mockResolvedValue({ appName: "libsql-abc" }); + mockExec.mockResolvedValue( + labels({ "com.docker.swarm.service.name": "libsql-abc" }), + ); + expect(await containerBelongsToService("svc", "c1")).toBe(true); + }); + it("denies an unknown service", async () => { mockFindApp.mockResolvedValue(undefined); 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 9b43e3f66..3bc16bb41 100644 --- a/apps/dokploy/server/wss/container-ownership.ts +++ b/apps/dokploy/server/wss/container-ownership.ts @@ -2,6 +2,7 @@ import { db } from "@dokploy/server/db"; import { applications, compose, + libsql, mariadb, mongo, mysql, @@ -22,7 +23,7 @@ const OWNERSHIP_LABELS = [ ]; const findServiceAppName = async (serviceId: string) => { - const [app, comp, pg, my, maria, mon, red] = await Promise.all([ + const [app, comp, pg, my, maria, mon, red, lib] = await Promise.all([ db.query.applications.findFirst({ where: eq(applications.applicationId, serviceId), columns: { appName: true }, @@ -51,8 +52,12 @@ const findServiceAppName = async (serviceId: string) => { 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)?.appName; + return (app ?? comp ?? pg ?? my ?? maria ?? mon ?? red ?? lib)?.appName; }; // Service access alone must not allow `docker exec` into other tenants' containers.