From a317f0c4ccb4dff23ecf69b85f40be37f58744b8 Mon Sep 17 00:00:00 2001 From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com> Date: Fri, 21 Feb 2025 00:40:35 -0600 Subject: [PATCH] refactor: simplify user permission checks across application --- .../components/dashboard/projects/show.tsx | 4 +-- apps/dokploy/components/layouts/user-nav.tsx | 5 ++-- apps/dokploy/pages/dashboard/docker.tsx | 2 +- .../pages/dashboard/project/[projectId].tsx | 2 +- .../services/application/[applicationId].tsx | 3 +-- .../services/compose/[composeId].tsx | 3 +-- .../services/mariadb/[mariadbId].tsx | 3 +-- .../[projectId]/services/mongo/[mongoId].tsx | 3 +-- .../[projectId]/services/mysql/[mysqlId].tsx | 3 +-- .../services/postgres/[postgresId].tsx | 3 +-- .../[projectId]/services/redis/[redisId].tsx | 3 +-- .../dashboard/settings/git-providers.tsx | 2 +- .../pages/dashboard/settings/profile.tsx | 4 +-- .../pages/dashboard/settings/ssh-keys.tsx | 2 +- apps/dokploy/pages/dashboard/swarm.tsx | 2 +- apps/dokploy/pages/dashboard/traefik.tsx | 2 +- apps/dokploy/pages/swagger.tsx | 2 +- apps/dokploy/server/api/routers/project.ts | 11 +++++--- packages/server/src/services/user.ts | 27 +++++++++++++++++-- 19 files changed, 52 insertions(+), 34 deletions(-) diff --git a/apps/dokploy/components/dashboard/projects/show.tsx b/apps/dokploy/components/dashboard/projects/show.tsx index a8c3ed5c..188ee60d 100644 --- a/apps/dokploy/components/dashboard/projects/show.tsx +++ b/apps/dokploy/components/dashboard/projects/show.tsx @@ -83,7 +83,7 @@ export const ShowProjects = () => { - {(auth?.role === "owner" || auth?.user?.canCreateProjects) && ( + {(auth?.role === "owner" || auth?.canCreateProjects) && (
@@ -286,7 +286,7 @@ export const ShowProjects = () => { onClick={(e) => e.stopPropagation()} > {(auth?.role === "owner" || - auth?.user?.canDeleteProjects) && ( + auth?.canDeleteProjects) && ( { > Monitoring - {(data?.role === "owner" || - data?.user?.canAccessToTraefikFiles) && ( + {(data?.role === "owner" || data?.canAccessToTraefikFiles) && ( { @@ -103,7 +102,7 @@ export const UserNav = () => { Traefik )} - {(data?.role === "owner" || data?.user?.canAccessToDocker) && ( + {(data?.role === "owner" || data?.canAccessToDocker) && ( { diff --git a/apps/dokploy/pages/dashboard/docker.tsx b/apps/dokploy/pages/dashboard/docker.tsx index fee202fc..5685dcfc 100644 --- a/apps/dokploy/pages/dashboard/docker.tsx +++ b/apps/dokploy/pages/dashboard/docker.tsx @@ -58,7 +58,7 @@ export async function getServerSideProps( userId: user.id, }); - if (!userR.canAccessToDocker) { + if (!userR?.canAccessToDocker) { return { redirect: { permanent: true, diff --git a/apps/dokploy/pages/dashboard/project/[projectId].tsx b/apps/dokploy/pages/dashboard/project/[projectId].tsx index 4f42ad06..f85aa9ee 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId].tsx @@ -328,7 +328,7 @@ const Project = ( {data?.description} - {(auth?.role === "owner" || auth?.user?.canCreateServices) && ( + {(auth?.role === "owner" || auth?.canCreateServices) && (
diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/services/application/[applicationId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/services/application/[applicationId].tsx index b78e750c..7eebf708 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/services/application/[applicationId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/services/application/[applicationId].tsx @@ -178,8 +178,7 @@ const Service = (
- {(auth?.role === "owner" || - auth?.user?.canDeleteServices) && ( + {(auth?.role === "owner" || auth?.canDeleteServices) && ( )}
diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/services/compose/[composeId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/services/compose/[composeId].tsx index cceda885..46c9864b 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/services/compose/[composeId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/services/compose/[composeId].tsx @@ -173,8 +173,7 @@ const Service = (
- {(auth?.role === "owner" || - auth?.user?.canDeleteServices) && ( + {(auth?.role === "owner" || auth?.canDeleteServices) && ( )}
diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/services/mariadb/[mariadbId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/services/mariadb/[mariadbId].tsx index 788846e1..6aa7677a 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/services/mariadb/[mariadbId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/services/mariadb/[mariadbId].tsx @@ -147,8 +147,7 @@ const Mariadb = (
- {(auth?.role === "owner" || - auth?.user?.canDeleteServices) && ( + {(auth?.role === "owner" || auth?.canDeleteServices) && ( )}
diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/services/mongo/[mongoId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/services/mongo/[mongoId].tsx index f03c4dfc..2e3aae31 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/services/mongo/[mongoId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/services/mongo/[mongoId].tsx @@ -148,8 +148,7 @@ const Mongo = (
- {(auth?.role === "owner" || - auth?.user?.canDeleteServices) && ( + {(auth?.role === "owner" || auth?.canDeleteServices) && ( )}
diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/services/mysql/[mysqlId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/services/mysql/[mysqlId].tsx index 52e2cd07..3e75603d 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/services/mysql/[mysqlId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/services/mysql/[mysqlId].tsx @@ -148,8 +148,7 @@ const MySql = (
- {(auth?.role === "owner" || - auth?.user?.canDeleteServices) && ( + {(auth?.role === "owner" || auth?.canDeleteServices) && ( )}
diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/services/postgres/[postgresId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/services/postgres/[postgresId].tsx index 8ff2044b..dd0c312d 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/services/postgres/[postgresId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/services/postgres/[postgresId].tsx @@ -147,8 +147,7 @@ const Postgresql = (
- {(auth?.role === "owner" || - auth?.user?.canDeleteServices) && ( + {(auth?.role === "owner" || auth?.canDeleteServices) && ( )}
diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/services/redis/[redisId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/services/redis/[redisId].tsx index 9ad8d53c..c7e5643a 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/services/redis/[redisId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/services/redis/[redisId].tsx @@ -147,8 +147,7 @@ const Redis = (
- {(auth?.role === "owner" || - auth?.user?.canDeleteServices) && ( + {(auth?.role === "owner" || auth?.canDeleteServices) && ( )}
diff --git a/apps/dokploy/pages/dashboard/settings/git-providers.tsx b/apps/dokploy/pages/dashboard/settings/git-providers.tsx index cfded991..7bacde24 100644 --- a/apps/dokploy/pages/dashboard/settings/git-providers.tsx +++ b/apps/dokploy/pages/dashboard/settings/git-providers.tsx @@ -54,7 +54,7 @@ export async function getServerSideProps( userId: user.id, }); - if (!userR.canAccessToGitProviders) { + if (!userR?.canAccessToGitProviders) { return { redirect: { permanent: true, diff --git a/apps/dokploy/pages/dashboard/settings/profile.tsx b/apps/dokploy/pages/dashboard/settings/profile.tsx index da0dec72..79a3366d 100644 --- a/apps/dokploy/pages/dashboard/settings/profile.tsx +++ b/apps/dokploy/pages/dashboard/settings/profile.tsx @@ -20,9 +20,7 @@ const Page = () => {
- {(data?.user?.canAccessToAPI || data?.role === "owner") && ( - - )} + {(data?.canAccessToAPI || data?.role === "owner") && } {isCloud && }
diff --git a/apps/dokploy/pages/dashboard/settings/ssh-keys.tsx b/apps/dokploy/pages/dashboard/settings/ssh-keys.tsx index c97df7ba..8c5082e3 100644 --- a/apps/dokploy/pages/dashboard/settings/ssh-keys.tsx +++ b/apps/dokploy/pages/dashboard/settings/ssh-keys.tsx @@ -55,7 +55,7 @@ export async function getServerSideProps( userId: user.id, }); - if (!userR.canAccessToSSHKeys) { + if (!userR?.canAccessToSSHKeys) { return { redirect: { permanent: true, diff --git a/apps/dokploy/pages/dashboard/swarm.tsx b/apps/dokploy/pages/dashboard/swarm.tsx index 3b59c47b..c693fd8c 100644 --- a/apps/dokploy/pages/dashboard/swarm.tsx +++ b/apps/dokploy/pages/dashboard/swarm.tsx @@ -58,7 +58,7 @@ export async function getServerSideProps( userId: user.id, }); - if (!userR.canAccessToDocker) { + if (!userR?.canAccessToDocker) { return { redirect: { permanent: true, diff --git a/apps/dokploy/pages/dashboard/traefik.tsx b/apps/dokploy/pages/dashboard/traefik.tsx index 8dcd3f08..3153e80d 100644 --- a/apps/dokploy/pages/dashboard/traefik.tsx +++ b/apps/dokploy/pages/dashboard/traefik.tsx @@ -58,7 +58,7 @@ export async function getServerSideProps( userId: user.id, }); - if (!userR.canAccessToTraefikFiles) { + if (!userR?.canAccessToTraefikFiles) { return { redirect: { permanent: true, diff --git a/apps/dokploy/pages/swagger.tsx b/apps/dokploy/pages/swagger.tsx index e4a6fac8..3d8cc01d 100644 --- a/apps/dokploy/pages/swagger.tsx +++ b/apps/dokploy/pages/swagger.tsx @@ -63,7 +63,7 @@ export async function getServerSideProps(context: GetServerSidePropsContext) { userId: user.id, }); - if (!userR.canAccessToAPI) { + if (!userR?.canAccessToAPI) { return { redirect: { permanent: true, diff --git a/apps/dokploy/server/api/routers/project.ts b/apps/dokploy/server/api/routers/project.ts index 5fc79f43..e3c24e53 100644 --- a/apps/dokploy/server/api/routers/project.ts +++ b/apps/dokploy/server/api/routers/project.ts @@ -8,6 +8,7 @@ import { applications, compose, mariadb, + member, mongo, mysql, postgres, @@ -29,8 +30,8 @@ import { findUserByAuthId, findUserById, updateProjectById, + findMemberById, } from "@dokploy/server"; - export const projectRouter = createTRPCRouter({ create: protectedProcedure .input(apiCreateProject) @@ -71,7 +72,10 @@ export const projectRouter = createTRPCRouter({ .input(apiFindOneProject) .query(async ({ input, ctx }) => { if (ctx.user.rol === "member") { - const { accessedServices } = await findUserById(ctx.user.id); + const { accessedServices } = await findMemberById( + ctx.user.id, + ctx.session.activeOrganizationId, + ); await checkProjectAccess(ctx.user.id, "access", input.projectId); @@ -129,8 +133,9 @@ export const projectRouter = createTRPCRouter({ all: protectedProcedure.query(async ({ ctx }) => { // console.log(ctx.user); if (ctx.user.rol === "member") { - const { accessedProjects, accessedServices } = await findUserById( + const { accessedProjects, accessedServices } = await findMemberById( ctx.user.id, + ctx.session.activeOrganizationId, ); if (accessedProjects.length === 0) { diff --git a/packages/server/src/services/user.ts b/packages/server/src/services/user.ts index 170af908..9351a003 100644 --- a/packages/server/src/services/user.ts +++ b/packages/server/src/services/user.ts @@ -1,7 +1,7 @@ import { db } from "@dokploy/server/db"; -import type { users_temp } from "@dokploy/server/db/schema"; +import { type users_temp, member } from "@dokploy/server/db/schema"; import { TRPCError } from "@trpc/server"; -import { eq } from "drizzle-orm"; +import { and, eq } from "drizzle-orm"; import { findUserById } from "./admin"; export type User = typeof users_temp.$inferSelect; @@ -191,3 +191,26 @@ export const checkProjectAccess = async ( }); } }; + +export const findMemberById = async ( + userId: string, + organizationId: string, +) => { + const result = await db.query.member.findFirst({ + where: and( + eq(member.userId, userId), + eq(member.organizationId, organizationId), + ), + with: { + user: true, + }, + }); + + if (!result) { + throw new TRPCError({ + code: "UNAUTHORIZED", + message: "Permission denied", + }); + } + return result; +};