mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
refactor: simplify user permission checks across application
This commit is contained in:
parent
24c9d3f7ad
commit
a317f0c4cc
@ -83,7 +83,7 @@ export const ShowProjects = () => {
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
|
||||
{(auth?.role === "owner" || auth?.user?.canCreateProjects) && (
|
||||
{(auth?.role === "owner" || auth?.canCreateProjects) && (
|
||||
<div className="">
|
||||
<HandleProject />
|
||||
</div>
|
||||
@ -286,7 +286,7 @@ export const ShowProjects = () => {
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
{(auth?.role === "owner" ||
|
||||
auth?.user?.canDeleteProjects) && (
|
||||
auth?.canDeleteProjects) && (
|
||||
<AlertDialog>
|
||||
<AlertDialogTrigger className="w-full">
|
||||
<DropdownMenuItem
|
||||
|
@ -92,8 +92,7 @@ export const UserNav = () => {
|
||||
>
|
||||
Monitoring
|
||||
</DropdownMenuItem>
|
||||
{(data?.role === "owner" ||
|
||||
data?.user?.canAccessToTraefikFiles) && (
|
||||
{(data?.role === "owner" || data?.canAccessToTraefikFiles) && (
|
||||
<DropdownMenuItem
|
||||
className="cursor-pointer"
|
||||
onClick={() => {
|
||||
@ -103,7 +102,7 @@ export const UserNav = () => {
|
||||
Traefik
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
{(data?.role === "owner" || data?.user?.canAccessToDocker) && (
|
||||
{(data?.role === "owner" || data?.canAccessToDocker) && (
|
||||
<DropdownMenuItem
|
||||
className="cursor-pointer"
|
||||
onClick={() => {
|
||||
|
@ -58,7 +58,7 @@ export async function getServerSideProps(
|
||||
userId: user.id,
|
||||
});
|
||||
|
||||
if (!userR.canAccessToDocker) {
|
||||
if (!userR?.canAccessToDocker) {
|
||||
return {
|
||||
redirect: {
|
||||
permanent: true,
|
||||
|
@ -328,7 +328,7 @@ const Project = (
|
||||
</CardTitle>
|
||||
<CardDescription>{data?.description}</CardDescription>
|
||||
</CardHeader>
|
||||
{(auth?.role === "owner" || auth?.user?.canCreateServices) && (
|
||||
{(auth?.role === "owner" || auth?.canCreateServices) && (
|
||||
<div className="flex flex-row gap-4 flex-wrap">
|
||||
<ProjectEnvironment projectId={projectId}>
|
||||
<Button variant="outline">Project Environment</Button>
|
||||
|
@ -178,8 +178,7 @@ const Service = (
|
||||
|
||||
<div className="flex flex-row gap-2 justify-end">
|
||||
<UpdateApplication applicationId={applicationId} />
|
||||
{(auth?.role === "owner" ||
|
||||
auth?.user?.canDeleteServices) && (
|
||||
{(auth?.role === "owner" || auth?.canDeleteServices) && (
|
||||
<DeleteService id={applicationId} type="application" />
|
||||
)}
|
||||
</div>
|
||||
|
@ -173,8 +173,7 @@ const Service = (
|
||||
<div className="flex flex-row gap-2 justify-end">
|
||||
<UpdateCompose composeId={composeId} />
|
||||
|
||||
{(auth?.role === "owner" ||
|
||||
auth?.user?.canDeleteServices) && (
|
||||
{(auth?.role === "owner" || auth?.canDeleteServices) && (
|
||||
<DeleteService id={composeId} type="compose" />
|
||||
)}
|
||||
</div>
|
||||
|
@ -147,8 +147,7 @@ const Mariadb = (
|
||||
</div>
|
||||
<div className="flex flex-row gap-2 justify-end">
|
||||
<UpdateMariadb mariadbId={mariadbId} />
|
||||
{(auth?.role === "owner" ||
|
||||
auth?.user?.canDeleteServices) && (
|
||||
{(auth?.role === "owner" || auth?.canDeleteServices) && (
|
||||
<DeleteService id={mariadbId} type="mariadb" />
|
||||
)}
|
||||
</div>
|
||||
|
@ -148,8 +148,7 @@ const Mongo = (
|
||||
|
||||
<div className="flex flex-row gap-2 justify-end">
|
||||
<UpdateMongo mongoId={mongoId} />
|
||||
{(auth?.role === "owner" ||
|
||||
auth?.user?.canDeleteServices) && (
|
||||
{(auth?.role === "owner" || auth?.canDeleteServices) && (
|
||||
<DeleteService id={mongoId} type="mongo" />
|
||||
)}
|
||||
</div>
|
||||
|
@ -148,8 +148,7 @@ const MySql = (
|
||||
|
||||
<div className="flex flex-row gap-2 justify-end">
|
||||
<UpdateMysql mysqlId={mysqlId} />
|
||||
{(auth?.role === "owner" ||
|
||||
auth?.user?.canDeleteServices) && (
|
||||
{(auth?.role === "owner" || auth?.canDeleteServices) && (
|
||||
<DeleteService id={mysqlId} type="mysql" />
|
||||
)}
|
||||
</div>
|
||||
|
@ -147,8 +147,7 @@ const Postgresql = (
|
||||
|
||||
<div className="flex flex-row gap-2 justify-end">
|
||||
<UpdatePostgres postgresId={postgresId} />
|
||||
{(auth?.role === "owner" ||
|
||||
auth?.user?.canDeleteServices) && (
|
||||
{(auth?.role === "owner" || auth?.canDeleteServices) && (
|
||||
<DeleteService id={postgresId} type="postgres" />
|
||||
)}
|
||||
</div>
|
||||
|
@ -147,8 +147,7 @@ const Redis = (
|
||||
|
||||
<div className="flex flex-row gap-2 justify-end">
|
||||
<UpdateRedis redisId={redisId} />
|
||||
{(auth?.role === "owner" ||
|
||||
auth?.user?.canDeleteServices) && (
|
||||
{(auth?.role === "owner" || auth?.canDeleteServices) && (
|
||||
<DeleteService id={redisId} type="redis" />
|
||||
)}
|
||||
</div>
|
||||
|
@ -54,7 +54,7 @@ export async function getServerSideProps(
|
||||
userId: user.id,
|
||||
});
|
||||
|
||||
if (!userR.canAccessToGitProviders) {
|
||||
if (!userR?.canAccessToGitProviders) {
|
||||
return {
|
||||
redirect: {
|
||||
permanent: true,
|
||||
|
@ -20,9 +20,7 @@ const Page = () => {
|
||||
<div className="w-full">
|
||||
<div className="h-full rounded-xl max-w-5xl mx-auto flex flex-col gap-4">
|
||||
<ProfileForm />
|
||||
{(data?.user?.canAccessToAPI || data?.role === "owner") && (
|
||||
<GenerateToken />
|
||||
)}
|
||||
{(data?.canAccessToAPI || data?.role === "owner") && <GenerateToken />}
|
||||
|
||||
{isCloud && <RemoveSelfAccount />}
|
||||
</div>
|
||||
|
@ -55,7 +55,7 @@ export async function getServerSideProps(
|
||||
userId: user.id,
|
||||
});
|
||||
|
||||
if (!userR.canAccessToSSHKeys) {
|
||||
if (!userR?.canAccessToSSHKeys) {
|
||||
return {
|
||||
redirect: {
|
||||
permanent: true,
|
||||
|
@ -58,7 +58,7 @@ export async function getServerSideProps(
|
||||
userId: user.id,
|
||||
});
|
||||
|
||||
if (!userR.canAccessToDocker) {
|
||||
if (!userR?.canAccessToDocker) {
|
||||
return {
|
||||
redirect: {
|
||||
permanent: true,
|
||||
|
@ -58,7 +58,7 @@ export async function getServerSideProps(
|
||||
userId: user.id,
|
||||
});
|
||||
|
||||
if (!userR.canAccessToTraefikFiles) {
|
||||
if (!userR?.canAccessToTraefikFiles) {
|
||||
return {
|
||||
redirect: {
|
||||
permanent: true,
|
||||
|
@ -63,7 +63,7 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
|
||||
userId: user.id,
|
||||
});
|
||||
|
||||
if (!userR.canAccessToAPI) {
|
||||
if (!userR?.canAccessToAPI) {
|
||||
return {
|
||||
redirect: {
|
||||
permanent: true,
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user