diff --git a/apps/dokploy/server/api/routers/mount.ts b/apps/dokploy/server/api/routers/mount.ts index 814d3d392..f19606236 100644 --- a/apps/dokploy/server/api/routers/mount.ts +++ b/apps/dokploy/server/api/routers/mount.ts @@ -1,22 +1,70 @@ import { + checkServiceAccess, createMount, deleteMount, findApplicationById, + findComposeById, + findMariadbById, + findMongoById, findMountById, findMountOrganizationId, + findMountsByApplicationId, + findMySqlById, + findPostgresById, + findRedisById, getServiceContainer, updateMount, } from "@dokploy/server"; +import type { ServiceType } from "@dokploy/server/db/schema/mount"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; import { apiCreateMount, + apiFindMountByApplicationId, apiFindOneMount, apiRemoveMount, apiUpdateMount, } from "@/server/db/schema"; import { createTRPCRouter, protectedProcedure } from "../trpc"; +async function getServiceOrganizationId( + serviceId: string, + serviceType: ServiceType, +): Promise { + switch (serviceType) { + case "application": { + const app = await findApplicationById(serviceId); + return app?.environment?.project?.organizationId ?? null; + } + case "postgres": { + const postgres = await findPostgresById(serviceId); + return postgres?.environment?.project?.organizationId ?? null; + } + case "mariadb": { + const mariadb = await findMariadbById(serviceId); + return mariadb?.environment?.project?.organizationId ?? null; + } + case "mongo": { + const mongo = await findMongoById(serviceId); + return mongo?.environment?.project?.organizationId ?? null; + } + case "mysql": { + const mysql = await findMySqlById(serviceId); + return mysql?.environment?.project?.organizationId ?? null; + } + case "redis": { + const redis = await findRedisById(serviceId); + return redis?.environment?.project?.organizationId ?? null; + } + case "compose": { + const compose = await findComposeById(serviceId); + return compose?.environment?.project?.organizationId ?? null; + } + default: + return null; + } +} + export const mountRouter = createTRPCRouter({ create: protectedProcedure .input(apiCreateMount) @@ -71,4 +119,35 @@ export const mountRouter = createTRPCRouter({ ); return mounts; }), + listByServiceId: protectedProcedure + .input(apiFindMountByApplicationId) + .query(async ({ input, ctx }) => { + console.log("input", input); + if (ctx.user.role === "member") { + await checkServiceAccess( + ctx.user.id, + input.serviceId, + ctx.session.activeOrganizationId, + "access", + ); + } + const organizationId = await getServiceOrganizationId( + input.serviceId, + input.serviceType, + ); + if ( + organizationId === null || + organizationId !== ctx.session.activeOrganizationId + ) { + throw new TRPCError({ + code: "UNAUTHORIZED", + message: + "You are not authorized to access this service or it does not exist", + }); + } + return await findMountsByApplicationId( + input.serviceId, + input.serviceType, + ); + }), }); diff --git a/packages/server/src/db/schema/mount.ts b/packages/server/src/db/schema/mount.ts index 6b909c689..bee8f9186 100644 --- a/packages/server/src/db/schema/mount.ts +++ b/packages/server/src/db/schema/mount.ts @@ -146,12 +146,20 @@ export const apiRemoveMount = createSchema export const apiFindMountByApplicationId = createSchema .extend({ serviceId: z.string().min(1), + serviceType: z.enum([ + "application", + "postgres", + "mysql", + "mariadb", + "mongo", + "redis", + "compose", + ]), }) .pick({ serviceId: true, serviceType: true, - }) - .required(); + }); export const apiUpdateMount = createSchema.partial().extend({ mountId: z.string().min(1), diff --git a/packages/server/src/services/mount.ts b/packages/server/src/services/mount.ts index 04e6e71cc..0d506a5d4 100644 --- a/packages/server/src/services/mount.ts +++ b/packages/server/src/services/mount.ts @@ -263,6 +263,9 @@ export const findMountsByApplicationId = async ( case "redis": sqlChunks.push(eq(mounts.redisId, serviceId)); break; + case "compose": + sqlChunks.push(eq(mounts.composeId, serviceId)); + break; default: throw new Error(`Unknown service type: ${serviceType}`); }