mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
refactor(cloud): add validation to prevent access to shared resources
This commit is contained in:
@@ -17,7 +17,6 @@ import { useEffect, useState } from "react";
|
|||||||
|
|
||||||
export const AddGithubProvider = () => {
|
export const AddGithubProvider = () => {
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const url = useUrl();
|
|
||||||
const { data } = api.auth.get.useQuery();
|
const { data } = api.auth.get.useQuery();
|
||||||
const [manifest, setManifest] = useState("");
|
const [manifest, setManifest] = useState("");
|
||||||
const [isOrganization, setIsOrganization] = useState(false);
|
const [isOrganization, setIsOrganization] = useState(false);
|
||||||
|
|||||||
@@ -2,11 +2,11 @@ import { createTRPCRouter, protectedProcedure } from "@/server/api/trpc";
|
|||||||
import { db } from "@/server/db";
|
import { db } from "@/server/db";
|
||||||
import { apiRemoveGitProvider, gitProvider } from "@/server/db/schema";
|
import { apiRemoveGitProvider, gitProvider } from "@/server/db/schema";
|
||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import { desc } from "drizzle-orm";
|
import { desc, eq } from "drizzle-orm";
|
||||||
import { removeGitProvider } from "@dokploy/builders";
|
import { findGitProviderById, removeGitProvider } from "@dokploy/builders";
|
||||||
|
|
||||||
export const gitProviderRouter = createTRPCRouter({
|
export const gitProviderRouter = createTRPCRouter({
|
||||||
getAll: protectedProcedure.query(async () => {
|
getAll: protectedProcedure.query(async ({ ctx }) => {
|
||||||
return await db.query.gitProvider.findMany({
|
return await db.query.gitProvider.findMany({
|
||||||
with: {
|
with: {
|
||||||
gitlab: true,
|
gitlab: true,
|
||||||
@@ -14,12 +14,21 @@ export const gitProviderRouter = createTRPCRouter({
|
|||||||
github: true,
|
github: true,
|
||||||
},
|
},
|
||||||
orderBy: desc(gitProvider.createdAt),
|
orderBy: desc(gitProvider.createdAt),
|
||||||
|
// where: eq(gitProvider.adminId, ctx.user.adminId), //TODO: Remove this line when the cloud version is ready
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
remove: protectedProcedure
|
remove: protectedProcedure
|
||||||
.input(apiRemoveGitProvider)
|
.input(apiRemoveGitProvider)
|
||||||
.mutation(async ({ input }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
try {
|
try {
|
||||||
|
const gitProvider = await findGitProviderById(input.gitProviderId);
|
||||||
|
|
||||||
|
// if (gitProvider.adminId !== ctx.user.adminId) {
|
||||||
|
// throw new TRPCError({
|
||||||
|
// code: "UNAUTHORIZED",
|
||||||
|
// message: "You are not allowed to delete this git provider",
|
||||||
|
// });
|
||||||
|
// }
|
||||||
return await removeGitProvider(input.gitProviderId);
|
return await removeGitProvider(input.gitProviderId);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
|
|||||||
@@ -13,10 +13,11 @@ import {
|
|||||||
execAsync,
|
execAsync,
|
||||||
manageRegistry,
|
manageRegistry,
|
||||||
createRegistry,
|
createRegistry,
|
||||||
findAllRegistry,
|
findAllRegistryByAdminId,
|
||||||
findRegistryById,
|
findRegistryById,
|
||||||
removeRegistry,
|
removeRegistry,
|
||||||
updateRegistry,
|
updateRegistry,
|
||||||
|
IS_CLOUD,
|
||||||
} from "@dokploy/builders";
|
} from "@dokploy/builders";
|
||||||
import { adminProcedure, createTRPCRouter, protectedProcedure } from "../trpc";
|
import { adminProcedure, createTRPCRouter, protectedProcedure } from "../trpc";
|
||||||
|
|
||||||
@@ -24,17 +25,31 @@ export const registryRouter = createTRPCRouter({
|
|||||||
create: adminProcedure
|
create: adminProcedure
|
||||||
.input(apiCreateRegistry)
|
.input(apiCreateRegistry)
|
||||||
.mutation(async ({ ctx, input }) => {
|
.mutation(async ({ ctx, input }) => {
|
||||||
return await createRegistry(input);
|
return await createRegistry(input, ctx.user.adminId);
|
||||||
}),
|
}),
|
||||||
remove: adminProcedure
|
remove: adminProcedure
|
||||||
.input(apiRemoveRegistry)
|
.input(apiRemoveRegistry)
|
||||||
.mutation(async ({ ctx, input }) => {
|
.mutation(async ({ ctx, input }) => {
|
||||||
|
const registry = await findRegistryById(input.registryId);
|
||||||
|
if (registry.adminId !== ctx.user.adminId) {
|
||||||
|
throw new TRPCError({
|
||||||
|
code: "UNAUTHORIZED",
|
||||||
|
message: "You are not allowed to delete this registry",
|
||||||
|
});
|
||||||
|
}
|
||||||
return await removeRegistry(input.registryId);
|
return await removeRegistry(input.registryId);
|
||||||
}),
|
}),
|
||||||
update: protectedProcedure
|
update: protectedProcedure
|
||||||
.input(apiUpdateRegistry)
|
.input(apiUpdateRegistry)
|
||||||
.mutation(async ({ input }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const { registryId, ...rest } = input;
|
const { registryId, ...rest } = input;
|
||||||
|
const registry = await findRegistryById(registryId);
|
||||||
|
if (registry.adminId !== ctx.user.adminId) {
|
||||||
|
throw new TRPCError({
|
||||||
|
code: "UNAUTHORIZED",
|
||||||
|
message: "You are not allowed to update this registry",
|
||||||
|
});
|
||||||
|
}
|
||||||
const application = await updateRegistry(registryId, {
|
const application = await updateRegistry(registryId, {
|
||||||
...rest,
|
...rest,
|
||||||
});
|
});
|
||||||
@@ -48,12 +63,21 @@ export const registryRouter = createTRPCRouter({
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}),
|
}),
|
||||||
all: protectedProcedure.query(async () => {
|
all: protectedProcedure.query(async ({ ctx }) => {
|
||||||
return await findAllRegistry();
|
return await findAllRegistryByAdminId(ctx.user.adminId);
|
||||||
}),
|
|
||||||
one: adminProcedure.input(apiFindOneRegistry).query(async ({ input }) => {
|
|
||||||
return await findRegistryById(input.registryId);
|
|
||||||
}),
|
}),
|
||||||
|
one: adminProcedure
|
||||||
|
.input(apiFindOneRegistry)
|
||||||
|
.query(async ({ input, ctx }) => {
|
||||||
|
const registry = await findRegistryById(input.registryId);
|
||||||
|
if (registry.adminId !== ctx.user.adminId) {
|
||||||
|
throw new TRPCError({
|
||||||
|
code: "UNAUTHORIZED",
|
||||||
|
message: "You are not allowed to access this registry",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return registry;
|
||||||
|
}),
|
||||||
testRegistry: protectedProcedure
|
testRegistry: protectedProcedure
|
||||||
.input(apiTestRegistry)
|
.input(apiTestRegistry)
|
||||||
.mutation(async ({ input }) => {
|
.mutation(async ({ input }) => {
|
||||||
@@ -75,18 +99,27 @@ export const registryRouter = createTRPCRouter({
|
|||||||
|
|
||||||
enableSelfHostedRegistry: adminProcedure
|
enableSelfHostedRegistry: adminProcedure
|
||||||
.input(apiEnableSelfHostedRegistry)
|
.input(apiEnableSelfHostedRegistry)
|
||||||
.mutation(async ({ input }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const selfHostedRegistry = await createRegistry({
|
if (IS_CLOUD) {
|
||||||
...input,
|
throw new TRPCError({
|
||||||
registryName: "Self Hosted Registry",
|
code: "UNAUTHORIZED",
|
||||||
registryType: "selfHosted",
|
message: "Self Hosted Registry is not available in the cloud version",
|
||||||
registryUrl:
|
});
|
||||||
process.env.NODE_ENV === "production"
|
}
|
||||||
? input.registryUrl
|
const selfHostedRegistry = await createRegistry(
|
||||||
: "dokploy-registry.docker.localhost",
|
{
|
||||||
imagePrefix: null,
|
...input,
|
||||||
serverId: undefined,
|
registryName: "Self Hosted Registry",
|
||||||
});
|
registryType: "selfHosted",
|
||||||
|
registryUrl:
|
||||||
|
process.env.NODE_ENV === "production"
|
||||||
|
? input.registryUrl
|
||||||
|
: "dokploy-registry.docker.localhost",
|
||||||
|
imagePrefix: null,
|
||||||
|
serverId: undefined,
|
||||||
|
},
|
||||||
|
ctx.user.adminId,
|
||||||
|
);
|
||||||
|
|
||||||
await manageRegistry(selfHostedRegistry);
|
await manageRegistry(selfHostedRegistry);
|
||||||
await initializeRegistry(input.username, input.password);
|
await initializeRegistry(input.username, input.password);
|
||||||
@@ -94,17 +127,3 @@ export const registryRouter = createTRPCRouter({
|
|||||||
return selfHostedRegistry;
|
return selfHostedRegistry;
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
const shellEscape = (str: string) => {
|
|
||||||
const ret = [];
|
|
||||||
let s = str;
|
|
||||||
if (/[^A-Za-z0-9_\/:=-]/.test(s)) {
|
|
||||||
s = `'${s.replace(/'/g, "'\\''")}'`;
|
|
||||||
s = s
|
|
||||||
.replace(/^(?:'')+/g, "") // unduplicate single-quote at the beginning
|
|
||||||
.replace(/\\'''/g, "\\'"); // remove non-escaped single-quote if there are enclosed between 2 escaped
|
|
||||||
}
|
|
||||||
ret.push(s);
|
|
||||||
|
|
||||||
return ret.join(" ");
|
|
||||||
};
|
|
||||||
|
|||||||
Reference in New Issue
Block a user