Files
dokploy/apps/dokploy/server/api/routers/port.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

115 lines
2.9 KiB
TypeScript

import {
createPort,
finPortById,
removePortById,
updatePortById,
} from "@dokploy/server";
import { checkServicePermissionAndAccess } from "@dokploy/server/services/permission";
import { TRPCError } from "@trpc/server";
import { createTRPCRouter, protectedProcedure } from "@/server/api/trpc";
import { audit } from "@/server/api/utils/audit";
import {
apiCreatePort,
apiFindOnePort,
apiUpdatePort,
} from "@/server/db/schema";
export const portRouter = createTRPCRouter({
create: protectedProcedure
.input(apiCreatePort)
.mutation(async ({ input, ctx }) => {
try {
await checkServicePermissionAndAccess(ctx, input.applicationId, {
service: ["create"],
});
const port = await createPort(input);
await audit(ctx, {
action: "create",
resourceType: "port",
resourceId: port.portId,
resourceName: `${port.publishedPort}:${port.targetPort}`,
});
return port;
} catch (error) {
throw new TRPCError({
code: "BAD_REQUEST",
message: "Error input: Inserting port",
cause: error,
});
}
}),
one: protectedProcedure
.input(apiFindOnePort)
.query(async ({ input, ctx }) => {
try {
const port = await finPortById(input.portId);
await checkServicePermissionAndAccess(
ctx,
port.application.applicationId,
{ service: ["read"] },
);
return port;
} catch (error) {
throw new TRPCError({
code: "BAD_REQUEST",
message: "Port not found",
cause: error,
});
}
}),
delete: protectedProcedure
.input(apiFindOnePort)
.mutation(async ({ input, ctx }) => {
const port = await finPortById(input.portId);
await checkServicePermissionAndAccess(
ctx,
port.application.applicationId,
{ service: ["delete"] },
);
try {
const result = await removePortById(input.portId);
await audit(ctx, {
action: "delete",
resourceType: "port",
resourceId: port.portId,
resourceName: `${port.publishedPort}:${port.targetPort}`,
});
return result;
} catch (error) {
const message =
error instanceof Error ? error.message : "Error input: Deleting port";
throw new TRPCError({
code: "BAD_REQUEST",
message,
});
}
}),
update: protectedProcedure
.input(apiUpdatePort)
.mutation(async ({ input, ctx }) => {
const port = await finPortById(input.portId);
await checkServicePermissionAndAccess(
ctx,
port.application.applicationId,
{ service: ["create"] },
);
try {
const result = await updatePortById(input.portId, input);
await audit(ctx, {
action: "update",
resourceType: "port",
resourceId: port.portId,
resourceName: `${port.publishedPort}:${port.targetPort}`,
});
return result;
} catch (error) {
const message =
error instanceof Error ? error.message : "Error updating the port";
throw new TRPCError({
code: "BAD_REQUEST",
message,
});
}
}),
});