Files
dokploy/apps/dokploy/server/api/routers/docker.ts
Mauricio Siu 8127dc4536 feat: add comprehensive permission tests and enhance permission checks in components
- Introduced new test files for permission checks, including `check-permission.test.ts`, `enterprise-only-resources.test.ts`, `resolve-permissions.test.ts`, and `service-access.test.ts`.
- Implemented permission checks in various components to ensure actions are gated by user permissions, including `ShowTraefikConfig`, `UpdateTraefikConfig`, `ShowVolumes`, `ShowDomains`, and others.
- Enhanced the logic for displaying UI elements based on user permissions, ensuring that only authorized users can access or modify resources.
2026-03-15 16:42:48 -06:00

153 lines
4.2 KiB
TypeScript

import {
containerRestart,
findServerById,
getConfig,
getContainers,
getContainersByAppLabel,
getContainersByAppNameMatch,
getServiceContainersByAppName,
getStackContainersByAppName,
} from "@dokploy/server";
import { TRPCError } from "@trpc/server";
import { z } from "zod";
import { audit } from "@/server/api/utils/audit";
import { createTRPCRouter, withPermission } from "../trpc";
export const containerIdRegex = /^[a-zA-Z0-9.\-_]+$/;
export const dockerRouter = createTRPCRouter({
getContainers: withPermission("docker", "read")
.input(
z.object({
serverId: z.string().optional(),
}),
)
.query(async ({ input, ctx }) => {
if (input.serverId) {
const server = await findServerById(input.serverId);
if (server.organizationId !== ctx.session?.activeOrganizationId) {
throw new TRPCError({ code: "UNAUTHORIZED" });
}
}
return await getContainers(input.serverId);
}),
restartContainer: withPermission("docker", "read")
.input(
z.object({
containerId: z
.string()
.min(1)
.regex(containerIdRegex, "Invalid container id."),
}),
)
.mutation(async ({ input, ctx }) => {
const result = await containerRestart(input.containerId);
await audit(ctx, {
action: "start",
resourceType: "docker",
resourceId: input.containerId,
resourceName: input.containerId,
});
return result;
}),
getConfig: withPermission("docker", "read")
.input(
z.object({
containerId: z
.string()
.min(1)
.regex(containerIdRegex, "Invalid container id."),
serverId: z.string().optional(),
}),
)
.query(async ({ input, ctx }) => {
if (input.serverId) {
const server = await findServerById(input.serverId);
if (server.organizationId !== ctx.session?.activeOrganizationId) {
throw new TRPCError({ code: "UNAUTHORIZED" });
}
}
return await getConfig(input.containerId, input.serverId);
}),
getContainersByAppNameMatch: withPermission("service", "read")
.input(
z.object({
appType: z.enum(["stack", "docker-compose"]).optional(),
appName: z.string().min(1).regex(containerIdRegex, "Invalid app name."),
serverId: z.string().optional(),
}),
)
.query(async ({ input, ctx }) => {
if (input.serverId) {
const server = await findServerById(input.serverId);
if (server.organizationId !== ctx.session?.activeOrganizationId) {
throw new TRPCError({ code: "UNAUTHORIZED" });
}
}
return await getContainersByAppNameMatch(
input.appName,
input.appType,
input.serverId,
);
}),
getContainersByAppLabel: withPermission("docker", "read")
.input(
z.object({
appName: z.string().min(1).regex(containerIdRegex, "Invalid app name."),
serverId: z.string().optional(),
type: z.enum(["standalone", "swarm"]),
}),
)
.query(async ({ input, ctx }) => {
if (input.serverId) {
const server = await findServerById(input.serverId);
if (server.organizationId !== ctx.session?.activeOrganizationId) {
throw new TRPCError({ code: "UNAUTHORIZED" });
}
}
return await getContainersByAppLabel(
input.appName,
input.type,
input.serverId,
);
}),
getStackContainersByAppName: withPermission("docker", "read")
.input(
z.object({
appName: z.string().min(1).regex(containerIdRegex, "Invalid app name."),
serverId: z.string().optional(),
}),
)
.query(async ({ input, ctx }) => {
if (input.serverId) {
const server = await findServerById(input.serverId);
if (server.organizationId !== ctx.session?.activeOrganizationId) {
throw new TRPCError({ code: "UNAUTHORIZED" });
}
}
return await getStackContainersByAppName(input.appName, input.serverId);
}),
getServiceContainersByAppName: withPermission("docker", "read")
.input(
z.object({
appName: z.string().min(1).regex(containerIdRegex, "Invalid app name."),
serverId: z.string().optional(),
}),
)
.query(async ({ input, ctx }) => {
if (input.serverId) {
const server = await findServerById(input.serverId);
if (server.organizationId !== ctx.session?.activeOrganizationId) {
throw new TRPCError({ code: "UNAUTHORIZED" });
}
}
return await getServiceContainersByAppName(input.appName, input.serverId);
}),
});