mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
Compare commits
57 Commits
v0.18.2
...
feat/bette
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8b71f963cc | ||
|
|
1c5cc5a0db | ||
|
|
d233f2c764 | ||
|
|
1bbb4c9b64 | ||
|
|
6ec60b6bab | ||
|
|
55abac3f2f | ||
|
|
b6c29ccf05 | ||
|
|
ca217affe6 | ||
|
|
5c24281f72 | ||
|
|
bc901bcb25 | ||
|
|
7c0d223e17 | ||
|
|
74ee024cf9 | ||
|
|
140a871275 | ||
|
|
d1f72a2e20 | ||
|
|
0d525398a8 | ||
|
|
7c62408070 | ||
|
|
23f1ce17de | ||
|
|
60eee55f2d | ||
|
|
8f562eefc1 | ||
|
|
6179cef1ee | ||
|
|
b7112b89fd | ||
|
|
030c8a312d | ||
|
|
1db6ba94f4 | ||
|
|
afd3d2eea3 | ||
|
|
8bd72a8a34 | ||
|
|
fafc238e70 | ||
|
|
c04bf3c7e0 | ||
|
|
6b9fd596e5 | ||
|
|
7e36433144 | ||
|
|
0a6554c275 | ||
|
|
fcc55355f2 | ||
|
|
78e606876a | ||
|
|
7e99baa267 | ||
|
|
92c03bb7cc | ||
|
|
3a5ecb2f64 | ||
|
|
c0a00f4957 | ||
|
|
a8f94540f9 | ||
|
|
3e2cfe6eb8 | ||
|
|
b2d5090b36 | ||
|
|
0a0f53e9de | ||
|
|
17ce03e529 | ||
|
|
f44512a437 | ||
|
|
8379068fe3 | ||
|
|
a71de72a3c | ||
|
|
b024060eed | ||
|
|
56b26ce0d5 | ||
|
|
a9e3a65782 | ||
|
|
7a472df753 | ||
|
|
bd809c8dca | ||
|
|
48642979c5 | ||
|
|
46411a5f4e | ||
|
|
82cf0643d7 | ||
|
|
65780ee852 | ||
|
|
d424524d69 | ||
|
|
6f2148c060 | ||
|
|
79fca72d06 | ||
|
|
62a3707c10 |
BIN
.github/sponsors/openalternative.png
vendored
Normal file
BIN
.github/sponsors/openalternative.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.1 KiB |
@@ -93,6 +93,7 @@ For detailed documentation, visit [docs.dokploy.com](https://docs.dokploy.com).
|
|||||||
<a href="https://cloudblast.io/?ref=dokploy "><img src="https://cloudblast.io/img/logo-icon.193cf13e.svg" width="250px" alt="Cloudblast.io"/></a>
|
<a href="https://cloudblast.io/?ref=dokploy "><img src="https://cloudblast.io/img/logo-icon.193cf13e.svg" width="250px" alt="Cloudblast.io"/></a>
|
||||||
<a href="https://startupfa.me/?ref=dokploy "><img src=".github/sponsors/startupfame.png" width="65px" alt="Startupfame"/></a>
|
<a href="https://startupfa.me/?ref=dokploy "><img src=".github/sponsors/startupfame.png" width="65px" alt="Startupfame"/></a>
|
||||||
<a href="https://itsdb-center.com?ref=dokploy "><img src=".github/sponsors/its.png" width="65px" alt="Itsdb-center"/></a>
|
<a href="https://itsdb-center.com?ref=dokploy "><img src=".github/sponsors/its.png" width="65px" alt="Itsdb-center"/></a>
|
||||||
|
<a href="https://openalternative.co/?ref=dokploy "><img src=".github/sponsors/openalternative.png" width="65px" alt="Openalternative"/></a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
### Community Backers 🤝
|
### Community Backers 🤝
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import { useForm } from "react-hook-form";
|
|||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { validateAndFormatYAML } from "../../application/advanced/traefik/update-traefik-config";
|
import { validateAndFormatYAML } from "../../application/advanced/traefik/update-traefik-config";
|
||||||
import { RandomizeCompose } from "./randomize-compose";
|
import { ShowUtilities } from "./show-utilities";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
composeId: string;
|
composeId: string;
|
||||||
@@ -125,7 +125,7 @@ services:
|
|||||||
</Form>
|
</Form>
|
||||||
<div className="flex justify-between flex-col lg:flex-row gap-2">
|
<div className="flex justify-between flex-col lg:flex-row gap-2">
|
||||||
<div className="w-full flex flex-col lg:flex-row gap-4 items-end">
|
<div className="w-full flex flex-col lg:flex-row gap-4 items-end">
|
||||||
<RandomizeCompose composeId={composeId} />
|
<ShowUtilities composeId={composeId} />
|
||||||
</div>
|
</div>
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
|
|||||||
@@ -0,0 +1,191 @@
|
|||||||
|
import { AlertBlock } from "@/components/shared/alert-block";
|
||||||
|
import { CodeEditor } from "@/components/shared/code-editor";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import {
|
||||||
|
DialogDescription,
|
||||||
|
DialogHeader,
|
||||||
|
DialogTitle,
|
||||||
|
} from "@/components/ui/dialog";
|
||||||
|
import {
|
||||||
|
Form,
|
||||||
|
FormControl,
|
||||||
|
FormDescription,
|
||||||
|
FormField,
|
||||||
|
FormItem,
|
||||||
|
FormLabel,
|
||||||
|
} from "@/components/ui/form";
|
||||||
|
import { Label } from "@/components/ui/label";
|
||||||
|
import { Switch } from "@/components/ui/switch";
|
||||||
|
import { api } from "@/utils/api";
|
||||||
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
|
import { AlertTriangle } from "lucide-react";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { useForm } from "react-hook-form";
|
||||||
|
import { toast } from "sonner";
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
composeId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const schema = z.object({
|
||||||
|
isolatedDeployment: z.boolean().optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
type Schema = z.infer<typeof schema>;
|
||||||
|
|
||||||
|
export const IsolatedDeployment = ({ composeId }: Props) => {
|
||||||
|
const utils = api.useUtils();
|
||||||
|
const [compose, setCompose] = useState<string>("");
|
||||||
|
const { mutateAsync, error, isError } =
|
||||||
|
api.compose.isolatedDeployment.useMutation();
|
||||||
|
|
||||||
|
const { mutateAsync: updateCompose } = api.compose.update.useMutation();
|
||||||
|
|
||||||
|
const { data, refetch } = api.compose.one.useQuery(
|
||||||
|
{ composeId },
|
||||||
|
{ enabled: !!composeId },
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log(data);
|
||||||
|
|
||||||
|
const form = useForm<Schema>({
|
||||||
|
defaultValues: {
|
||||||
|
isolatedDeployment: false,
|
||||||
|
},
|
||||||
|
resolver: zodResolver(schema),
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
randomizeCompose();
|
||||||
|
if (data) {
|
||||||
|
form.reset({
|
||||||
|
isolatedDeployment: data?.isolatedDeployment || false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [form, form.reset, form.formState.isSubmitSuccessful, data]);
|
||||||
|
|
||||||
|
const onSubmit = async (formData: Schema) => {
|
||||||
|
await updateCompose({
|
||||||
|
composeId,
|
||||||
|
isolatedDeployment: formData?.isolatedDeployment || false,
|
||||||
|
})
|
||||||
|
.then(async (data) => {
|
||||||
|
randomizeCompose();
|
||||||
|
refetch();
|
||||||
|
toast.success("Compose updated");
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
toast.error("Error updating the compose");
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const randomizeCompose = async () => {
|
||||||
|
await mutateAsync({
|
||||||
|
composeId,
|
||||||
|
suffix: data?.appName || "",
|
||||||
|
})
|
||||||
|
.then(async (data) => {
|
||||||
|
await utils.project.all.invalidate();
|
||||||
|
setCompose(data);
|
||||||
|
toast.success("Compose Isolated");
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
toast.error("Error isolating the compose");
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle>Isolate Deployment</DialogTitle>
|
||||||
|
<DialogDescription>
|
||||||
|
Use this option to isolate the deployment of this compose file.
|
||||||
|
</DialogDescription>
|
||||||
|
</DialogHeader>
|
||||||
|
<div className="text-sm text-muted-foreground flex flex-col gap-2">
|
||||||
|
<span>
|
||||||
|
This feature creates an isolated environment for your deployment by
|
||||||
|
adding unique prefixes to all resources. It establishes a dedicated
|
||||||
|
network based on your compose file's name, ensuring your services run
|
||||||
|
in isolation. This prevents conflicts when running multiple instances
|
||||||
|
of the same template or services with identical names.
|
||||||
|
</span>
|
||||||
|
<div className="space-y-4">
|
||||||
|
<div>
|
||||||
|
<h4 className="font-medium mb-2">
|
||||||
|
Resources that will be isolated:
|
||||||
|
</h4>
|
||||||
|
<ul className="list-disc list-inside">
|
||||||
|
<li>Docker volumes</li>
|
||||||
|
<li>Docker networks</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{isError && <AlertBlock type="error">{error?.message}</AlertBlock>}
|
||||||
|
<Form {...form}>
|
||||||
|
<form
|
||||||
|
onSubmit={form.handleSubmit(onSubmit)}
|
||||||
|
id="hook-form-add-project"
|
||||||
|
className="grid w-full gap-4"
|
||||||
|
>
|
||||||
|
{isError && (
|
||||||
|
<div className="flex flex-row gap-4 rounded-lg items-center bg-red-50 p-2 dark:bg-red-950">
|
||||||
|
<AlertTriangle className="text-red-600 dark:text-red-400" />
|
||||||
|
<span className="text-sm text-red-600 dark:text-red-400">
|
||||||
|
{error?.message}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div className="flex flex-col lg:flex-col gap-4 w-full ">
|
||||||
|
<div>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="isolatedDeployment"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem className="mt-4 flex flex-row items-center justify-between rounded-lg border p-3 shadow-sm">
|
||||||
|
<div className="space-y-0.5">
|
||||||
|
<FormLabel>Enable Randomize ({data?.appName})</FormLabel>
|
||||||
|
<FormDescription>
|
||||||
|
Enable randomize to the compose file.
|
||||||
|
</FormDescription>
|
||||||
|
</div>
|
||||||
|
<FormControl>
|
||||||
|
<Switch
|
||||||
|
checked={field.value}
|
||||||
|
onCheckedChange={field.onChange}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex flex-col lg:flex-row gap-4 w-full items-end justify-end">
|
||||||
|
<Button
|
||||||
|
form="hook-form-add-project"
|
||||||
|
type="submit"
|
||||||
|
className="lg:w-fit"
|
||||||
|
>
|
||||||
|
Save
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col gap-4">
|
||||||
|
<Label>Preview</Label>
|
||||||
|
<pre>
|
||||||
|
<CodeEditor
|
||||||
|
value={compose || ""}
|
||||||
|
language="yaml"
|
||||||
|
readOnly
|
||||||
|
height="50rem"
|
||||||
|
/>
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</Form>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -1,14 +1,10 @@
|
|||||||
import { AlertBlock } from "@/components/shared/alert-block";
|
import { AlertBlock } from "@/components/shared/alert-block";
|
||||||
import { CodeEditor } from "@/components/shared/code-editor";
|
import { CodeEditor } from "@/components/shared/code-editor";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { CardTitle } from "@/components/ui/card";
|
|
||||||
import {
|
import {
|
||||||
Dialog,
|
|
||||||
DialogContent,
|
|
||||||
DialogDescription,
|
DialogDescription,
|
||||||
DialogHeader,
|
DialogHeader,
|
||||||
DialogTitle,
|
DialogTitle,
|
||||||
DialogTrigger,
|
|
||||||
} from "@/components/ui/dialog";
|
} from "@/components/ui/dialog";
|
||||||
import {
|
import {
|
||||||
Form,
|
Form,
|
||||||
@@ -20,11 +16,6 @@ import {
|
|||||||
FormMessage,
|
FormMessage,
|
||||||
} from "@/components/ui/form";
|
} from "@/components/ui/form";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import {
|
|
||||||
InputOTP,
|
|
||||||
InputOTPGroup,
|
|
||||||
InputOTPSlot,
|
|
||||||
} from "@/components/ui/input-otp";
|
|
||||||
import { Switch } from "@/components/ui/switch";
|
import { Switch } from "@/components/ui/switch";
|
||||||
import { api } from "@/utils/api";
|
import { api } from "@/utils/api";
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
@@ -70,6 +61,7 @@ export const RandomizeCompose = ({ composeId }: Props) => {
|
|||||||
const suffix = form.watch("suffix");
|
const suffix = form.watch("suffix");
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
randomizeCompose();
|
||||||
if (data) {
|
if (data) {
|
||||||
form.reset({
|
form.reset({
|
||||||
suffix: data?.suffix || "",
|
suffix: data?.suffix || "",
|
||||||
@@ -110,19 +102,12 @@ export const RandomizeCompose = ({ composeId }: Props) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog open={isOpen} onOpenChange={setIsOpen}>
|
<div className="w-full">
|
||||||
<DialogTrigger asChild onClick={() => randomizeCompose()}>
|
|
||||||
<Button className="max-lg:w-full" variant="outline">
|
|
||||||
<Dices className="h-4 w-4" />
|
|
||||||
Randomize Compose
|
|
||||||
</Button>
|
|
||||||
</DialogTrigger>
|
|
||||||
<DialogContent className="sm:max-w-6xl max-h-[50rem] overflow-y-auto">
|
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle>Randomize Compose (Experimental)</DialogTitle>
|
<DialogTitle>Randomize Compose (Experimental)</DialogTitle>
|
||||||
<DialogDescription>
|
<DialogDescription>
|
||||||
Use this in case you want to deploy the same compose file and you
|
Use this in case you want to deploy the same compose file and you have
|
||||||
have conflicts with some property like volumes, networks, etc.
|
conflicts with some property like volumes, networks, etc.
|
||||||
</DialogDescription>
|
</DialogDescription>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<div className="text-sm text-muted-foreground flex flex-col gap-2">
|
<div className="text-sm text-muted-foreground flex flex-col gap-2">
|
||||||
@@ -138,9 +123,8 @@ export const RandomizeCompose = ({ composeId }: Props) => {
|
|||||||
<li>secrets</li>
|
<li>secrets</li>
|
||||||
</ul>
|
</ul>
|
||||||
<AlertBlock type="info">
|
<AlertBlock type="info">
|
||||||
When you activate this option, we will include a env
|
When you activate this option, we will include a env `COMPOSE_PREFIX`
|
||||||
`COMPOSE_PREFIX` variable to the compose file so you can use it in
|
variable to the compose file so you can use it in your compose file.
|
||||||
your compose file.
|
|
||||||
</AlertBlock>
|
</AlertBlock>
|
||||||
</div>
|
</div>
|
||||||
{isError && <AlertBlock type="error">{error?.message}</AlertBlock>}
|
{isError && <AlertBlock type="error">{error?.message}</AlertBlock>}
|
||||||
@@ -165,7 +149,7 @@ export const RandomizeCompose = ({ composeId }: Props) => {
|
|||||||
control={form.control}
|
control={form.control}
|
||||||
name="suffix"
|
name="suffix"
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem className="flex flex-col justify-center max-sm:items-center w-full">
|
<FormItem className="flex flex-col justify-center max-sm:items-center w-full mt-4">
|
||||||
<FormLabel>Suffix</FormLabel>
|
<FormLabel>Suffix</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input
|
<Input
|
||||||
@@ -229,7 +213,6 @@ export const RandomizeCompose = ({ composeId }: Props) => {
|
|||||||
</pre>
|
</pre>
|
||||||
</form>
|
</form>
|
||||||
</Form>
|
</Form>
|
||||||
</DialogContent>
|
</div>
|
||||||
</Dialog>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogDescription,
|
||||||
|
DialogHeader,
|
||||||
|
DialogTitle,
|
||||||
|
DialogTrigger,
|
||||||
|
} from "@/components/ui/dialog";
|
||||||
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||||
|
import { useState } from "react";
|
||||||
|
import { IsolatedDeployment } from "./isolated-deployment";
|
||||||
|
import { RandomizeCompose } from "./randomize-compose";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
composeId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ShowUtilities = ({ composeId }: Props) => {
|
||||||
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
|
return (
|
||||||
|
<Dialog open={isOpen} onOpenChange={setIsOpen}>
|
||||||
|
<DialogTrigger asChild>
|
||||||
|
<Button variant="ghost">Show Utilities</Button>
|
||||||
|
</DialogTrigger>
|
||||||
|
<DialogContent className="max-h-screen overflow-y-auto sm:max-w-5xl">
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle>Utilities </DialogTitle>
|
||||||
|
<DialogDescription>Modify the application data</DialogDescription>
|
||||||
|
</DialogHeader>
|
||||||
|
<Tabs defaultValue="isolated">
|
||||||
|
<TabsList className="grid w-full grid-cols-2">
|
||||||
|
<TabsTrigger value="isolated">Isolated Deployment</TabsTrigger>
|
||||||
|
<TabsTrigger value="randomize">Randomize Compose</TabsTrigger>
|
||||||
|
</TabsList>
|
||||||
|
<TabsContent value="randomize" className="pt-5">
|
||||||
|
<RandomizeCompose composeId={composeId} />
|
||||||
|
</TabsContent>
|
||||||
|
<TabsContent value="isolated" className="pt-5">
|
||||||
|
<IsolatedDeployment composeId={composeId} />
|
||||||
|
</TabsContent>
|
||||||
|
</Tabs>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -21,6 +21,7 @@ import {
|
|||||||
|
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { Textarea } from "@/components/ui/textarea";
|
import { Textarea } from "@/components/ui/textarea";
|
||||||
|
import { authClient } from "@/lib/auth";
|
||||||
import { api } from "@/utils/api";
|
import { api } from "@/utils/api";
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
import { PlusIcon, SquarePen } from "lucide-react";
|
import { PlusIcon, SquarePen } from "lucide-react";
|
||||||
@@ -97,6 +98,18 @@ export const HandleProject = ({ projectId }: Props) => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
// useEffect(() => {
|
||||||
|
// const getUsers = async () => {
|
||||||
|
// const users = await authClient.admin.listUsers({
|
||||||
|
// query: {
|
||||||
|
// limit: 100,
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
// console.log(users);
|
||||||
|
// };
|
||||||
|
|
||||||
|
// getUsers();
|
||||||
|
// });
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog open={isOpen} onOpenChange={setIsOpen}>
|
<Dialog open={isOpen} onOpenChange={setIsOpen}>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { BreadcrumbSidebar } from "@/components/shared/breadcrumb-sidebar";
|
import { BreadcrumbSidebar } from "@/components/shared/breadcrumb-sidebar";
|
||||||
import { DateTooltip } from "@/components/shared/date-tooltip";
|
import { DateTooltip } from "@/components/shared/date-tooltip";
|
||||||
|
import { StatusTooltip } from "@/components/shared/status-tooltip";
|
||||||
import {
|
import {
|
||||||
AlertDialog,
|
AlertDialog,
|
||||||
AlertDialogAction,
|
AlertDialogAction,
|
||||||
@@ -56,7 +57,7 @@ export const ShowProjects = () => {
|
|||||||
authId: auth?.id || "",
|
authId: auth?.id || "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
enabled: !!auth?.id && auth?.rol === "user",
|
enabled: !!auth?.id && auth?.role === "member",
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
const { mutateAsync } = api.project.remove.useMutation();
|
const { mutateAsync } = api.project.remove.useMutation();
|
||||||
@@ -90,7 +91,7 @@ export const ShowProjects = () => {
|
|||||||
</CardDescription>
|
</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
|
|
||||||
{(auth?.rol === "admin" || user?.canCreateProjects) && (
|
{(auth?.role === "owner" || user?.canCreateProjects) && (
|
||||||
<div className="">
|
<div className="">
|
||||||
<HandleProject />
|
<HandleProject />
|
||||||
</div>
|
</div>
|
||||||
@@ -176,8 +177,11 @@ export const ShowProjects = () => {
|
|||||||
<div key={app.applicationId}>
|
<div key={app.applicationId}>
|
||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
<DropdownMenuGroup>
|
<DropdownMenuGroup>
|
||||||
<DropdownMenuLabel className="font-normal capitalize text-xs">
|
<DropdownMenuLabel className="font-normal capitalize text-xs flex items-center justify-between">
|
||||||
{app.name}
|
{app.name}
|
||||||
|
<StatusTooltip
|
||||||
|
status={app.applicationStatus}
|
||||||
|
/>
|
||||||
</DropdownMenuLabel>
|
</DropdownMenuLabel>
|
||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
{app.domains.map((domain) => (
|
{app.domains.map((domain) => (
|
||||||
@@ -209,8 +213,11 @@ export const ShowProjects = () => {
|
|||||||
<div key={comp.composeId}>
|
<div key={comp.composeId}>
|
||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
<DropdownMenuGroup>
|
<DropdownMenuGroup>
|
||||||
<DropdownMenuLabel className="font-normal capitalize text-xs">
|
<DropdownMenuLabel className="font-normal capitalize text-xs flex items-center justify-between">
|
||||||
{comp.name}
|
{comp.name}
|
||||||
|
<StatusTooltip
|
||||||
|
status={comp.composeStatus}
|
||||||
|
/>
|
||||||
</DropdownMenuLabel>
|
</DropdownMenuLabel>
|
||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
{comp.domains.map((domain) => (
|
{comp.domains.map((domain) => (
|
||||||
@@ -286,7 +293,7 @@ export const ShowProjects = () => {
|
|||||||
<div
|
<div
|
||||||
onClick={(e) => e.stopPropagation()}
|
onClick={(e) => e.stopPropagation()}
|
||||||
>
|
>
|
||||||
{(auth?.rol === "admin" ||
|
{(auth?.role === "owner" ||
|
||||||
user?.canDeleteProjects) && (
|
user?.canDeleteProjects) && (
|
||||||
<AlertDialog>
|
<AlertDialog>
|
||||||
<AlertDialogTrigger className="w-full">
|
<AlertDialogTrigger className="w-full">
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import {
|
|||||||
CommandList,
|
CommandList,
|
||||||
CommandSeparator,
|
CommandSeparator,
|
||||||
} from "@/components/ui/command";
|
} from "@/components/ui/command";
|
||||||
|
import { authClient } from "@/lib/auth";
|
||||||
import {
|
import {
|
||||||
type Services,
|
type Services,
|
||||||
extractServices,
|
extractServices,
|
||||||
@@ -35,8 +36,10 @@ export const SearchCommand = () => {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const [open, setOpen] = React.useState(false);
|
const [open, setOpen] = React.useState(false);
|
||||||
const [search, setSearch] = React.useState("");
|
const [search, setSearch] = React.useState("");
|
||||||
|
const { data: session } = authClient.getSession();
|
||||||
const { data } = api.project.all.useQuery();
|
const { data } = api.project.all.useQuery(undefined, {
|
||||||
|
enabled: !!session,
|
||||||
|
});
|
||||||
const { data: isCloud, isLoading } = api.settings.isCloud.useQuery();
|
const { data: isCloud, isLoading } = api.settings.isCloud.useQuery();
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export const ShowWelcomeDokploy = () => {
|
|||||||
|
|
||||||
const { data: isCloud, isLoading } = api.settings.isCloud.useQuery();
|
const { data: isCloud, isLoading } = api.settings.isCloud.useQuery();
|
||||||
|
|
||||||
if (!isCloud || data?.rol !== "admin") {
|
if (!isCloud || data?.role !== "admin") {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,14 +24,14 @@ export const ShowWelcomeDokploy = () => {
|
|||||||
!isLoading &&
|
!isLoading &&
|
||||||
isCloud &&
|
isCloud &&
|
||||||
!localStorage.getItem("hasSeenCloudWelcomeModal") &&
|
!localStorage.getItem("hasSeenCloudWelcomeModal") &&
|
||||||
data?.rol === "admin"
|
data?.role === "owner"
|
||||||
) {
|
) {
|
||||||
setOpen(true);
|
setOpen(true);
|
||||||
}
|
}
|
||||||
}, [isCloud, isLoading]);
|
}, [isCloud, isLoading]);
|
||||||
|
|
||||||
const handleClose = (isOpen: boolean) => {
|
const handleClose = (isOpen: boolean) => {
|
||||||
if (data?.rol === "admin") {
|
if (data?.role === "owner") {
|
||||||
setOpen(isOpen);
|
setOpen(isOpen);
|
||||||
if (!isOpen) {
|
if (!isOpen) {
|
||||||
localStorage.setItem("hasSeenCloudWelcomeModal", "true"); // Establece el flag al cerrar el modal
|
localStorage.setItem("hasSeenCloudWelcomeModal", "true"); // Establece el flag al cerrar el modal
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ export const GenerateToken = () => {
|
|||||||
<Label>Token</Label>
|
<Label>Token</Label>
|
||||||
<ToggleVisibilityInput
|
<ToggleVisibilityInput
|
||||||
placeholder="Token"
|
placeholder="Token"
|
||||||
value={data?.token || ""}
|
value={data?.user?.token || ""}
|
||||||
disabled
|
disabled
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -73,9 +73,9 @@ export const ProfileForm = () => {
|
|||||||
|
|
||||||
const form = useForm<Profile>({
|
const form = useForm<Profile>({
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
email: data?.email || "",
|
email: data?.user?.email || "",
|
||||||
password: "",
|
password: "",
|
||||||
image: data?.image || "",
|
image: data?.user?.image || "",
|
||||||
currentPassword: "",
|
currentPassword: "",
|
||||||
},
|
},
|
||||||
resolver: zodResolver(profileSchema),
|
resolver: zodResolver(profileSchema),
|
||||||
@@ -84,14 +84,14 @@ export const ProfileForm = () => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (data) {
|
if (data) {
|
||||||
form.reset({
|
form.reset({
|
||||||
email: data?.email || "",
|
email: data?.user?.email || "",
|
||||||
password: "",
|
password: "",
|
||||||
image: data?.image || "",
|
image: data?.user?.image || "",
|
||||||
currentPassword: "",
|
currentPassword: "",
|
||||||
});
|
});
|
||||||
|
|
||||||
if (data.email) {
|
if (data.user.email) {
|
||||||
generateSHA256Hash(data.email).then((hash) => {
|
generateSHA256Hash(data.user.email).then((hash) => {
|
||||||
setGravatarHash(hash);
|
setGravatarHash(hash);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ const MENU: Menu = {
|
|||||||
// Only enabled for admins and users with access to Traefik files in non-cloud environments
|
// Only enabled for admins and users with access to Traefik files in non-cloud environments
|
||||||
isEnabled: ({ auth, user, isCloud }) =>
|
isEnabled: ({ auth, user, isCloud }) =>
|
||||||
!!(
|
!!(
|
||||||
(auth?.rol === "admin" || user?.canAccessToTraefikFiles) &&
|
(auth?.role === "owner" || user?.canAccessToTraefikFiles) &&
|
||||||
!isCloud
|
!isCloud
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@@ -166,7 +166,7 @@ const MENU: Menu = {
|
|||||||
icon: BlocksIcon,
|
icon: BlocksIcon,
|
||||||
// Only enabled for admins and users with access to Docker in non-cloud environments
|
// Only enabled for admins and users with access to Docker in non-cloud environments
|
||||||
isEnabled: ({ auth, user, isCloud }) =>
|
isEnabled: ({ auth, user, isCloud }) =>
|
||||||
!!((auth?.rol === "admin" || user?.canAccessToDocker) && !isCloud),
|
!!((auth?.role === "owner" || user?.canAccessToDocker) && !isCloud),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
isSingle: true,
|
isSingle: true,
|
||||||
@@ -175,7 +175,7 @@ const MENU: Menu = {
|
|||||||
icon: PieChart,
|
icon: PieChart,
|
||||||
// Only enabled for admins and users with access to Docker in non-cloud environments
|
// Only enabled for admins and users with access to Docker in non-cloud environments
|
||||||
isEnabled: ({ auth, user, isCloud }) =>
|
isEnabled: ({ auth, user, isCloud }) =>
|
||||||
!!((auth?.rol === "admin" || user?.canAccessToDocker) && !isCloud),
|
!!((auth?.role === "owner" || user?.canAccessToDocker) && !isCloud),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
isSingle: true,
|
isSingle: true,
|
||||||
@@ -184,7 +184,7 @@ const MENU: Menu = {
|
|||||||
icon: Forward,
|
icon: Forward,
|
||||||
// Only enabled for admins and users with access to Docker in non-cloud environments
|
// Only enabled for admins and users with access to Docker in non-cloud environments
|
||||||
isEnabled: ({ auth, user, isCloud }) =>
|
isEnabled: ({ auth, user, isCloud }) =>
|
||||||
!!((auth?.rol === "admin" || user?.canAccessToDocker) && !isCloud),
|
!!((auth?.role === "owner" || user?.canAccessToDocker) && !isCloud),
|
||||||
},
|
},
|
||||||
|
|
||||||
// Legacy unused menu, adjusted to the new structure
|
// Legacy unused menu, adjusted to the new structure
|
||||||
@@ -252,7 +252,7 @@ const MENU: Menu = {
|
|||||||
icon: Activity,
|
icon: Activity,
|
||||||
// Only enabled for admins in non-cloud environments
|
// Only enabled for admins in non-cloud environments
|
||||||
isEnabled: ({ auth, user, isCloud }) =>
|
isEnabled: ({ auth, user, isCloud }) =>
|
||||||
!!(auth?.rol === "admin" && !isCloud),
|
!!(auth?.role === "owner" && !isCloud),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
isSingle: true,
|
isSingle: true,
|
||||||
@@ -266,7 +266,7 @@ const MENU: Menu = {
|
|||||||
url: "/dashboard/settings/servers",
|
url: "/dashboard/settings/servers",
|
||||||
icon: Server,
|
icon: Server,
|
||||||
// Only enabled for admins
|
// Only enabled for admins
|
||||||
isEnabled: ({ auth, user, isCloud }) => !!(auth?.rol === "admin"),
|
isEnabled: ({ auth, user, isCloud }) => !!(auth?.role === "owner"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
isSingle: true,
|
isSingle: true,
|
||||||
@@ -274,7 +274,7 @@ const MENU: Menu = {
|
|||||||
icon: Users,
|
icon: Users,
|
||||||
url: "/dashboard/settings/users",
|
url: "/dashboard/settings/users",
|
||||||
// Only enabled for admins
|
// Only enabled for admins
|
||||||
isEnabled: ({ auth, user, isCloud }) => !!(auth?.rol === "admin"),
|
isEnabled: ({ auth, user, isCloud }) => !!(auth?.role === "owner"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
isSingle: true,
|
isSingle: true,
|
||||||
@@ -283,7 +283,7 @@ const MENU: Menu = {
|
|||||||
url: "/dashboard/settings/ssh-keys",
|
url: "/dashboard/settings/ssh-keys",
|
||||||
// Only enabled for admins and users with access to SSH keys
|
// Only enabled for admins and users with access to SSH keys
|
||||||
isEnabled: ({ auth, user }) =>
|
isEnabled: ({ auth, user }) =>
|
||||||
!!(auth?.rol === "admin" || user?.canAccessToSSHKeys),
|
!!(auth?.role === "owner" || user?.canAccessToSSHKeys),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
isSingle: true,
|
isSingle: true,
|
||||||
@@ -292,7 +292,7 @@ const MENU: Menu = {
|
|||||||
icon: GitBranch,
|
icon: GitBranch,
|
||||||
// Only enabled for admins and users with access to Git providers
|
// Only enabled for admins and users with access to Git providers
|
||||||
isEnabled: ({ auth, user }) =>
|
isEnabled: ({ auth, user }) =>
|
||||||
!!(auth?.rol === "admin" || user?.canAccessToGitProviders),
|
!!(auth?.role === "owner" || user?.canAccessToGitProviders),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
isSingle: true,
|
isSingle: true,
|
||||||
@@ -300,7 +300,7 @@ const MENU: Menu = {
|
|||||||
url: "/dashboard/settings/registry",
|
url: "/dashboard/settings/registry",
|
||||||
icon: Package,
|
icon: Package,
|
||||||
// Only enabled for admins
|
// Only enabled for admins
|
||||||
isEnabled: ({ auth, user, isCloud }) => !!(auth?.rol === "admin"),
|
isEnabled: ({ auth, user, isCloud }) => !!(auth?.role === "owner"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
isSingle: true,
|
isSingle: true,
|
||||||
@@ -308,7 +308,7 @@ const MENU: Menu = {
|
|||||||
url: "/dashboard/settings/destinations",
|
url: "/dashboard/settings/destinations",
|
||||||
icon: Database,
|
icon: Database,
|
||||||
// Only enabled for admins
|
// Only enabled for admins
|
||||||
isEnabled: ({ auth, user, isCloud }) => !!(auth?.rol === "admin"),
|
isEnabled: ({ auth, user, isCloud }) => !!(auth?.role === "owner"),
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -317,7 +317,7 @@ const MENU: Menu = {
|
|||||||
url: "/dashboard/settings/certificates",
|
url: "/dashboard/settings/certificates",
|
||||||
icon: ShieldCheck,
|
icon: ShieldCheck,
|
||||||
// Only enabled for admins
|
// Only enabled for admins
|
||||||
isEnabled: ({ auth, user, isCloud }) => !!(auth?.rol === "admin"),
|
isEnabled: ({ auth, user, isCloud }) => !!(auth?.role === "owner"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
isSingle: true,
|
isSingle: true,
|
||||||
@@ -326,7 +326,7 @@ const MENU: Menu = {
|
|||||||
icon: Boxes,
|
icon: Boxes,
|
||||||
// Only enabled for admins in non-cloud environments
|
// Only enabled for admins in non-cloud environments
|
||||||
isEnabled: ({ auth, user, isCloud }) =>
|
isEnabled: ({ auth, user, isCloud }) =>
|
||||||
!!(auth?.rol === "admin" && !isCloud),
|
!!(auth?.role === "owner" && !isCloud),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
isSingle: true,
|
isSingle: true,
|
||||||
@@ -334,7 +334,7 @@ const MENU: Menu = {
|
|||||||
url: "/dashboard/settings/notifications",
|
url: "/dashboard/settings/notifications",
|
||||||
icon: Bell,
|
icon: Bell,
|
||||||
// Only enabled for admins
|
// Only enabled for admins
|
||||||
isEnabled: ({ auth, user, isCloud }) => !!(auth?.rol === "admin"),
|
isEnabled: ({ auth, user, isCloud }) => !!(auth?.role === "owner"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
isSingle: true,
|
isSingle: true,
|
||||||
@@ -343,7 +343,7 @@ const MENU: Menu = {
|
|||||||
icon: CreditCard,
|
icon: CreditCard,
|
||||||
// Only enabled for admins in cloud environments
|
// Only enabled for admins in cloud environments
|
||||||
isEnabled: ({ auth, user, isCloud }) =>
|
isEnabled: ({ auth, user, isCloud }) =>
|
||||||
!!(auth?.rol === "admin" && isCloud),
|
!!(auth?.role === "owner" && isCloud),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
||||||
@@ -537,7 +537,7 @@ export default function Page({ children }: Props) {
|
|||||||
authId: auth?.id || "",
|
authId: auth?.id || "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
enabled: !!auth?.id && auth?.rol === "user",
|
enabled: !!auth?.id && auth?.role === "member",
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -557,7 +557,7 @@ export default function Page({ children }: Props) {
|
|||||||
|
|
||||||
// const showProjectsButton =
|
// const showProjectsButton =
|
||||||
// currentPath === "/dashboard/projects" &&
|
// currentPath === "/dashboard/projects" &&
|
||||||
// (auth?.rol === "admin" || user?.canCreateProjects);
|
// (auth?.rol === "owner" || user?.canCreateProjects);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SidebarProvider
|
<SidebarProvider
|
||||||
@@ -783,7 +783,7 @@ export default function Page({ children }: Props) {
|
|||||||
</SidebarMenuButton>
|
</SidebarMenuButton>
|
||||||
</SidebarMenuItem>
|
</SidebarMenuItem>
|
||||||
))}
|
))}
|
||||||
{!isCloud && auth?.rol === "admin" && (
|
{!isCloud && auth?.role === "owner" && (
|
||||||
<SidebarMenuItem>
|
<SidebarMenuItem>
|
||||||
<SidebarMenuButton asChild>
|
<SidebarMenuButton asChild>
|
||||||
<UpdateServerButton />
|
<UpdateServerButton />
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import {
|
|||||||
SelectTrigger,
|
SelectTrigger,
|
||||||
SelectValue,
|
SelectValue,
|
||||||
} from "@/components/ui/select";
|
} from "@/components/ui/select";
|
||||||
|
import { authClient } from "@/lib/auth";
|
||||||
import { Languages } from "@/lib/languages";
|
import { Languages } from "@/lib/languages";
|
||||||
import { api } from "@/utils/api";
|
import { api } from "@/utils/api";
|
||||||
import useLocale from "@/utils/hooks/use-locale";
|
import useLocale from "@/utils/hooks/use-locale";
|
||||||
@@ -36,11 +37,11 @@ export const UserNav = () => {
|
|||||||
authId: data?.id || "",
|
authId: data?.id || "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
enabled: !!data?.id && data?.rol === "user",
|
enabled: !!data?.id && data?.role === "member",
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
const { locale, setLocale } = useLocale();
|
const { locale, setLocale } = useLocale();
|
||||||
const { mutateAsync } = api.auth.logout.useMutation();
|
// const { mutateAsync } = api.auth.logout.useMutation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DropdownMenu>
|
<DropdownMenu>
|
||||||
@@ -50,12 +51,15 @@ export const UserNav = () => {
|
|||||||
className="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground"
|
className="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground"
|
||||||
>
|
>
|
||||||
<Avatar className="h-8 w-8 rounded-lg">
|
<Avatar className="h-8 w-8 rounded-lg">
|
||||||
<AvatarImage src={data?.image || ""} alt={data?.image || ""} />
|
<AvatarImage
|
||||||
|
src={data?.user?.image || ""}
|
||||||
|
alt={data?.user?.image || ""}
|
||||||
|
/>
|
||||||
<AvatarFallback className="rounded-lg">CN</AvatarFallback>
|
<AvatarFallback className="rounded-lg">CN</AvatarFallback>
|
||||||
</Avatar>
|
</Avatar>
|
||||||
<div className="grid flex-1 text-left text-sm leading-tight">
|
<div className="grid flex-1 text-left text-sm leading-tight">
|
||||||
<span className="truncate font-semibold">Account</span>
|
<span className="truncate font-semibold">Account</span>
|
||||||
<span className="truncate text-xs">{data?.email}</span>
|
<span className="truncate text-xs">{data?.user?.email}</span>
|
||||||
</div>
|
</div>
|
||||||
<ChevronsUpDown className="ml-auto size-4" />
|
<ChevronsUpDown className="ml-auto size-4" />
|
||||||
</SidebarMenuButton>
|
</SidebarMenuButton>
|
||||||
@@ -70,7 +74,7 @@ export const UserNav = () => {
|
|||||||
<DropdownMenuLabel className="flex flex-col">
|
<DropdownMenuLabel className="flex flex-col">
|
||||||
My Account
|
My Account
|
||||||
<span className="text-xs font-normal text-muted-foreground">
|
<span className="text-xs font-normal text-muted-foreground">
|
||||||
{data?.email}
|
{data?.user?.email}
|
||||||
</span>
|
</span>
|
||||||
</DropdownMenuLabel>
|
</DropdownMenuLabel>
|
||||||
<ModeToggle />
|
<ModeToggle />
|
||||||
@@ -95,7 +99,7 @@ export const UserNav = () => {
|
|||||||
>
|
>
|
||||||
Monitoring
|
Monitoring
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
{(data?.rol === "admin" || user?.canAccessToTraefikFiles) && (
|
{(data?.role === "owner" || user?.canAccessToTraefikFiles) && (
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
className="cursor-pointer"
|
className="cursor-pointer"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@@ -105,7 +109,7 @@ export const UserNav = () => {
|
|||||||
Traefik
|
Traefik
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
)}
|
)}
|
||||||
{(data?.rol === "admin" || user?.canAccessToDocker) && (
|
{(data?.role === "owner" || user?.canAccessToDocker) && (
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
className="cursor-pointer"
|
className="cursor-pointer"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@@ -118,7 +122,7 @@ export const UserNav = () => {
|
|||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{data?.rol === "admin" && (
|
{data?.role === "owner" && (
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
className="cursor-pointer"
|
className="cursor-pointer"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@@ -139,7 +143,7 @@ export const UserNav = () => {
|
|||||||
>
|
>
|
||||||
Profile
|
Profile
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
{data?.rol === "admin" && (
|
{data?.role === "owner" && (
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
className="cursor-pointer"
|
className="cursor-pointer"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@@ -150,7 +154,7 @@ export const UserNav = () => {
|
|||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{data?.rol === "admin" && (
|
{data?.role === "owner" && (
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
className="cursor-pointer"
|
className="cursor-pointer"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@@ -163,7 +167,7 @@ export const UserNav = () => {
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</DropdownMenuGroup>
|
</DropdownMenuGroup>
|
||||||
{isCloud && data?.rol === "admin" && (
|
{isCloud && data?.role === "owner" && (
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
className="cursor-pointer"
|
className="cursor-pointer"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@@ -178,9 +182,12 @@ export const UserNav = () => {
|
|||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
className="cursor-pointer"
|
className="cursor-pointer"
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
await mutateAsync().then(() => {
|
await authClient.signOut().then(() => {
|
||||||
router.push("/");
|
router.push("/");
|
||||||
});
|
});
|
||||||
|
// await mutateAsync().then(() => {
|
||||||
|
// router.push("/");
|
||||||
|
// });
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Log out
|
Log out
|
||||||
|
|||||||
1
apps/dokploy/drizzle/0064_previous_agent_brand.sql
Normal file
1
apps/dokploy/drizzle/0064_previous_agent_brand.sql
Normal file
@@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE "compose" ADD COLUMN "deployable" boolean DEFAULT false NOT NULL;
|
||||||
1
apps/dokploy/drizzle/0065_daily_zaladane.sql
Normal file
1
apps/dokploy/drizzle/0065_daily_zaladane.sql
Normal file
@@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE "compose" RENAME COLUMN "deployable" TO "isolatedDeployment";
|
||||||
127
apps/dokploy/drizzle/0066_yielding_echo.sql
Normal file
127
apps/dokploy/drizzle/0066_yielding_echo.sql
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
CREATE TABLE "user_temp" (
|
||||||
|
"id" text PRIMARY KEY NOT NULL,
|
||||||
|
"name" text DEFAULT '' NOT NULL,
|
||||||
|
"token" text NOT NULL,
|
||||||
|
"isRegistered" boolean DEFAULT false NOT NULL,
|
||||||
|
"expirationDate" text NOT NULL,
|
||||||
|
"createdAt" text NOT NULL,
|
||||||
|
"canCreateProjects" boolean DEFAULT false NOT NULL,
|
||||||
|
"canAccessToSSHKeys" boolean DEFAULT false NOT NULL,
|
||||||
|
"canCreateServices" boolean DEFAULT false NOT NULL,
|
||||||
|
"canDeleteProjects" boolean DEFAULT false NOT NULL,
|
||||||
|
"canDeleteServices" boolean DEFAULT false NOT NULL,
|
||||||
|
"canAccessToDocker" boolean DEFAULT false NOT NULL,
|
||||||
|
"canAccessToAPI" boolean DEFAULT false NOT NULL,
|
||||||
|
"canAccessToGitProviders" boolean DEFAULT false NOT NULL,
|
||||||
|
"canAccessToTraefikFiles" boolean DEFAULT false NOT NULL,
|
||||||
|
"accesedProjects" text[] DEFAULT ARRAY[]::text[] NOT NULL,
|
||||||
|
"accesedServices" text[] DEFAULT ARRAY[]::text[] NOT NULL,
|
||||||
|
"email" text NOT NULL,
|
||||||
|
"email_verified" boolean NOT NULL,
|
||||||
|
"image" text,
|
||||||
|
"banned" boolean,
|
||||||
|
"ban_reason" text,
|
||||||
|
"ban_expires" timestamp,
|
||||||
|
"updated_at" timestamp NOT NULL,
|
||||||
|
"serverIp" text,
|
||||||
|
"certificateType" "certificateType" DEFAULT 'none' NOT NULL,
|
||||||
|
"host" text,
|
||||||
|
"letsEncryptEmail" text,
|
||||||
|
"sshPrivateKey" text,
|
||||||
|
"enableDockerCleanup" boolean DEFAULT false NOT NULL,
|
||||||
|
"enableLogRotation" boolean DEFAULT false NOT NULL,
|
||||||
|
"enablePaidFeatures" boolean DEFAULT false NOT NULL,
|
||||||
|
"metricsConfig" jsonb DEFAULT '{"server":{"type":"Dokploy","refreshRate":60,"port":4500,"token":"","retentionDays":2,"cronJob":"","urlCallback":"","thresholds":{"cpu":0,"memory":0}},"containers":{"refreshRate":60,"services":{"include":[],"exclude":[]}}}'::jsonb NOT NULL,
|
||||||
|
"cleanupCacheApplications" boolean DEFAULT false NOT NULL,
|
||||||
|
"cleanupCacheOnPreviews" boolean DEFAULT false NOT NULL,
|
||||||
|
"cleanupCacheOnCompose" boolean DEFAULT false NOT NULL,
|
||||||
|
"stripeCustomerId" text,
|
||||||
|
"stripeSubscriptionId" text,
|
||||||
|
"serversQuantity" integer DEFAULT 0 NOT NULL,
|
||||||
|
CONSTRAINT "user_temp_email_unique" UNIQUE("email")
|
||||||
|
);
|
||||||
|
--> statement-breakpoint
|
||||||
|
CREATE TABLE "session_temp" (
|
||||||
|
"id" text PRIMARY KEY NOT NULL,
|
||||||
|
"expires_at" timestamp NOT NULL,
|
||||||
|
"token" text NOT NULL,
|
||||||
|
"created_at" timestamp NOT NULL,
|
||||||
|
"updated_at" timestamp NOT NULL,
|
||||||
|
"ip_address" text,
|
||||||
|
"user_agent" text,
|
||||||
|
"user_id" text NOT NULL,
|
||||||
|
"impersonated_by" text,
|
||||||
|
"active_organization_id" text,
|
||||||
|
CONSTRAINT "session_temp_token_unique" UNIQUE("token")
|
||||||
|
);
|
||||||
|
--> statement-breakpoint
|
||||||
|
CREATE TABLE "account" (
|
||||||
|
"id" text PRIMARY KEY NOT NULL,
|
||||||
|
"account_id" text NOT NULL,
|
||||||
|
"provider_id" text NOT NULL,
|
||||||
|
"user_id" text NOT NULL,
|
||||||
|
"access_token" text,
|
||||||
|
"refresh_token" text,
|
||||||
|
"id_token" text,
|
||||||
|
"access_token_expires_at" timestamp,
|
||||||
|
"refresh_token_expires_at" timestamp,
|
||||||
|
"scope" text,
|
||||||
|
"password" text,
|
||||||
|
"is2FAEnabled" boolean DEFAULT false NOT NULL,
|
||||||
|
"created_at" timestamp NOT NULL,
|
||||||
|
"updated_at" timestamp NOT NULL,
|
||||||
|
"resetPasswordToken" text,
|
||||||
|
"resetPasswordExpiresAt" text,
|
||||||
|
"confirmationToken" text,
|
||||||
|
"confirmationExpiresAt" text
|
||||||
|
);
|
||||||
|
--> statement-breakpoint
|
||||||
|
CREATE TABLE "invitation" (
|
||||||
|
"id" text PRIMARY KEY NOT NULL,
|
||||||
|
"organization_id" text NOT NULL,
|
||||||
|
"email" text NOT NULL,
|
||||||
|
"role" text,
|
||||||
|
"status" text NOT NULL,
|
||||||
|
"expires_at" timestamp NOT NULL,
|
||||||
|
"inviter_id" text NOT NULL
|
||||||
|
);
|
||||||
|
--> statement-breakpoint
|
||||||
|
CREATE TABLE "member" (
|
||||||
|
"id" text PRIMARY KEY NOT NULL,
|
||||||
|
"organization_id" text NOT NULL,
|
||||||
|
"user_id" text NOT NULL,
|
||||||
|
"role" text NOT NULL,
|
||||||
|
"created_at" timestamp NOT NULL
|
||||||
|
);
|
||||||
|
--> statement-breakpoint
|
||||||
|
CREATE TABLE "organization" (
|
||||||
|
"id" text PRIMARY KEY NOT NULL,
|
||||||
|
"name" text NOT NULL,
|
||||||
|
"slug" text,
|
||||||
|
"logo" text,
|
||||||
|
"created_at" timestamp NOT NULL,
|
||||||
|
"metadata" text,
|
||||||
|
"owner_id" text NOT NULL,
|
||||||
|
CONSTRAINT "organization_slug_unique" UNIQUE("slug")
|
||||||
|
);
|
||||||
|
--> statement-breakpoint
|
||||||
|
CREATE TABLE "verification" (
|
||||||
|
"id" text PRIMARY KEY NOT NULL,
|
||||||
|
"identifier" text NOT NULL,
|
||||||
|
"value" text NOT NULL,
|
||||||
|
"expires_at" timestamp NOT NULL,
|
||||||
|
"created_at" timestamp,
|
||||||
|
"updated_at" timestamp
|
||||||
|
);
|
||||||
|
--> statement-breakpoint
|
||||||
|
ALTER TABLE "certificate" ALTER COLUMN "adminId" SET NOT NULL;--> statement-breakpoint
|
||||||
|
ALTER TABLE "notification" ALTER COLUMN "adminId" SET NOT NULL;--> statement-breakpoint
|
||||||
|
ALTER TABLE "ssh-key" ALTER COLUMN "adminId" SET NOT NULL;--> statement-breakpoint
|
||||||
|
ALTER TABLE "git_provider" ALTER COLUMN "adminId" SET NOT NULL;--> statement-breakpoint
|
||||||
|
ALTER TABLE "session_temp" ADD CONSTRAINT "session_temp_user_id_user_temp_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user_temp"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
||||||
|
ALTER TABLE "account" ADD CONSTRAINT "account_user_id_user_temp_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user_temp"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
||||||
|
ALTER TABLE "invitation" ADD CONSTRAINT "invitation_organization_id_organization_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organization"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
||||||
|
ALTER TABLE "invitation" ADD CONSTRAINT "invitation_inviter_id_user_temp_id_fk" FOREIGN KEY ("inviter_id") REFERENCES "public"."user_temp"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
||||||
|
ALTER TABLE "member" ADD CONSTRAINT "member_organization_id_organization_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organization"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
||||||
|
ALTER TABLE "member" ADD CONSTRAINT "member_user_id_user_temp_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user_temp"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
||||||
|
ALTER TABLE "organization" ADD CONSTRAINT "organization_owner_id_user_temp_id_fk" FOREIGN KEY ("owner_id") REFERENCES "public"."user_temp"("id") ON DELETE no action ON UPDATE no action;
|
||||||
211
apps/dokploy/drizzle/0067_migrate-data.sql
Normal file
211
apps/dokploy/drizzle/0067_migrate-data.sql
Normal file
@@ -0,0 +1,211 @@
|
|||||||
|
-- Custom SQL migration file, put your code below! --
|
||||||
|
|
||||||
|
WITH inserted_users AS (
|
||||||
|
-- Insertar usuarios desde admins
|
||||||
|
INSERT INTO user_temp (
|
||||||
|
id,
|
||||||
|
email,
|
||||||
|
token,
|
||||||
|
"email_verified",
|
||||||
|
"updated_at",
|
||||||
|
"serverIp",
|
||||||
|
image,
|
||||||
|
"certificateType",
|
||||||
|
host,
|
||||||
|
"letsEncryptEmail",
|
||||||
|
"sshPrivateKey",
|
||||||
|
"enableDockerCleanup",
|
||||||
|
"enableLogRotation",
|
||||||
|
"enablePaidFeatures",
|
||||||
|
"metricsConfig",
|
||||||
|
"cleanupCacheApplications",
|
||||||
|
"cleanupCacheOnPreviews",
|
||||||
|
"cleanupCacheOnCompose",
|
||||||
|
"stripeCustomerId",
|
||||||
|
"stripeSubscriptionId",
|
||||||
|
"serversQuantity",
|
||||||
|
"expirationDate",
|
||||||
|
"createdAt"
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
a."adminId",
|
||||||
|
auth.email,
|
||||||
|
COALESCE(auth.token, ''),
|
||||||
|
true,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
a."serverIp",
|
||||||
|
auth.image,
|
||||||
|
a."certificateType",
|
||||||
|
a.host,
|
||||||
|
a."letsEncryptEmail",
|
||||||
|
a."sshPrivateKey",
|
||||||
|
a."enableDockerCleanup",
|
||||||
|
a."enableLogRotation",
|
||||||
|
a."enablePaidFeatures",
|
||||||
|
a."metricsConfig",
|
||||||
|
a."cleanupCacheApplications",
|
||||||
|
a."cleanupCacheOnPreviews",
|
||||||
|
a."cleanupCacheOnCompose",
|
||||||
|
a."stripeCustomerId",
|
||||||
|
a."stripeSubscriptionId",
|
||||||
|
a."serversQuantity",
|
||||||
|
NOW() + INTERVAL '1 year',
|
||||||
|
NOW()
|
||||||
|
FROM admin a
|
||||||
|
JOIN auth ON auth.id = a."authId"
|
||||||
|
RETURNING *
|
||||||
|
),
|
||||||
|
inserted_accounts AS (
|
||||||
|
-- Insertar cuentas para los admins
|
||||||
|
INSERT INTO account (
|
||||||
|
id,
|
||||||
|
"account_id",
|
||||||
|
"provider_id",
|
||||||
|
"user_id",
|
||||||
|
password,
|
||||||
|
"is2FAEnabled",
|
||||||
|
"created_at",
|
||||||
|
"updated_at"
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
gen_random_uuid(),
|
||||||
|
gen_random_uuid(),
|
||||||
|
'credential',
|
||||||
|
a."adminId",
|
||||||
|
auth.password,
|
||||||
|
COALESCE(auth."is2FAEnabled", false),
|
||||||
|
NOW(),
|
||||||
|
NOW()
|
||||||
|
FROM admin a
|
||||||
|
JOIN auth ON auth.id = a."authId"
|
||||||
|
RETURNING *
|
||||||
|
),
|
||||||
|
inserted_orgs AS (
|
||||||
|
-- Crear organizaciones para cada admin
|
||||||
|
INSERT INTO organization (
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
slug,
|
||||||
|
"owner_id",
|
||||||
|
"created_at"
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
gen_random_uuid(),
|
||||||
|
'My Organization',
|
||||||
|
-- Generamos un slug único usando una función de hash
|
||||||
|
encode(sha256((a."adminId" || CURRENT_TIMESTAMP)::bytea), 'hex'),
|
||||||
|
a."adminId",
|
||||||
|
NOW()
|
||||||
|
FROM admin a
|
||||||
|
RETURNING *
|
||||||
|
),
|
||||||
|
inserted_members AS (
|
||||||
|
-- Insertar usuarios miembros
|
||||||
|
INSERT INTO user_temp (
|
||||||
|
id,
|
||||||
|
email,
|
||||||
|
token,
|
||||||
|
"email_verified",
|
||||||
|
"updated_at",
|
||||||
|
image,
|
||||||
|
"createdAt",
|
||||||
|
"canAccessToAPI",
|
||||||
|
"canAccessToDocker",
|
||||||
|
"canAccessToGitProviders",
|
||||||
|
"canAccessToSSHKeys",
|
||||||
|
"canAccessToTraefikFiles",
|
||||||
|
"canCreateProjects",
|
||||||
|
"canCreateServices",
|
||||||
|
"canDeleteProjects",
|
||||||
|
"canDeleteServices",
|
||||||
|
"accesedProjects",
|
||||||
|
"accesedServices",
|
||||||
|
"expirationDate"
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
u."userId",
|
||||||
|
auth.email,
|
||||||
|
COALESCE(u.token, ''),
|
||||||
|
true,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
auth.image,
|
||||||
|
NOW(),
|
||||||
|
COALESCE(u."canAccessToAPI", false),
|
||||||
|
COALESCE(u."canAccessToDocker", false),
|
||||||
|
COALESCE(u."canAccessToGitProviders", false),
|
||||||
|
COALESCE(u."canAccessToSSHKeys", false),
|
||||||
|
COALESCE(u."canAccessToTraefikFiles", false),
|
||||||
|
COALESCE(u."canCreateProjects", false),
|
||||||
|
COALESCE(u."canCreateServices", false),
|
||||||
|
COALESCE(u."canDeleteProjects", false),
|
||||||
|
COALESCE(u."canDeleteServices", false),
|
||||||
|
COALESCE(u."accesedProjects", '{}'),
|
||||||
|
COALESCE(u."accesedServices", '{}'),
|
||||||
|
NOW() + INTERVAL '1 year'
|
||||||
|
FROM "user" u
|
||||||
|
JOIN admin a ON u."adminId" = a."adminId"
|
||||||
|
JOIN auth ON auth.id = u."authId"
|
||||||
|
RETURNING *
|
||||||
|
),
|
||||||
|
inserted_member_accounts AS (
|
||||||
|
-- Insertar cuentas para los usuarios miembros
|
||||||
|
INSERT INTO account (
|
||||||
|
id,
|
||||||
|
"account_id",
|
||||||
|
"provider_id",
|
||||||
|
"user_id",
|
||||||
|
password,
|
||||||
|
"is2FAEnabled",
|
||||||
|
"created_at",
|
||||||
|
"updated_at"
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
gen_random_uuid(),
|
||||||
|
gen_random_uuid(),
|
||||||
|
'credential',
|
||||||
|
u."userId",
|
||||||
|
auth.password,
|
||||||
|
COALESCE(auth."is2FAEnabled", false),
|
||||||
|
NOW(),
|
||||||
|
NOW()
|
||||||
|
FROM "user" u
|
||||||
|
JOIN admin a ON u."adminId" = a."adminId"
|
||||||
|
JOIN auth ON auth.id = u."authId"
|
||||||
|
RETURNING *
|
||||||
|
),
|
||||||
|
inserted_admin_members AS (
|
||||||
|
-- Insertar miembros en las organizaciones (admins como owners)
|
||||||
|
INSERT INTO member (
|
||||||
|
id,
|
||||||
|
"organization_id",
|
||||||
|
"user_id",
|
||||||
|
role,
|
||||||
|
"created_at"
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
gen_random_uuid(),
|
||||||
|
o.id,
|
||||||
|
a."adminId",
|
||||||
|
'owner',
|
||||||
|
NOW()
|
||||||
|
FROM admin a
|
||||||
|
JOIN inserted_orgs o ON o."owner_id" = a."adminId"
|
||||||
|
RETURNING *
|
||||||
|
)
|
||||||
|
-- Insertar miembros regulares en las organizaciones
|
||||||
|
INSERT INTO member (
|
||||||
|
id,
|
||||||
|
"organization_id",
|
||||||
|
"user_id",
|
||||||
|
role,
|
||||||
|
"created_at"
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
gen_random_uuid(),
|
||||||
|
o.id,
|
||||||
|
u."userId",
|
||||||
|
'member',
|
||||||
|
NOW()
|
||||||
|
FROM "user" u
|
||||||
|
JOIN admin a ON u."adminId" = a."adminId"
|
||||||
|
JOIN inserted_orgs o ON o."owner_id" = a."adminId";
|
||||||
32
apps/dokploy/drizzle/0068_sour_professor_monster.sql
Normal file
32
apps/dokploy/drizzle/0068_sour_professor_monster.sql
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
ALTER TABLE "project" RENAME COLUMN "adminId" TO "userId";--> statement-breakpoint
|
||||||
|
ALTER TABLE "destination" RENAME COLUMN "adminId" TO "userId";--> statement-breakpoint
|
||||||
|
ALTER TABLE "certificate" RENAME COLUMN "adminId" TO "userId";--> statement-breakpoint
|
||||||
|
ALTER TABLE "registry" RENAME COLUMN "adminId" TO "userId";--> statement-breakpoint
|
||||||
|
ALTER TABLE "notification" RENAME COLUMN "adminId" TO "userId";--> statement-breakpoint
|
||||||
|
ALTER TABLE "ssh-key" RENAME COLUMN "adminId" TO "userId";--> statement-breakpoint
|
||||||
|
ALTER TABLE "git_provider" RENAME COLUMN "adminId" TO "userId";--> statement-breakpoint
|
||||||
|
ALTER TABLE "server" RENAME COLUMN "adminId" TO "userId";--> statement-breakpoint
|
||||||
|
ALTER TABLE "project" DROP CONSTRAINT "project_adminId_admin_adminId_fk";
|
||||||
|
--> statement-breakpoint
|
||||||
|
ALTER TABLE "destination" DROP CONSTRAINT "destination_adminId_admin_adminId_fk";
|
||||||
|
--> statement-breakpoint
|
||||||
|
ALTER TABLE "certificate" DROP CONSTRAINT "certificate_adminId_admin_adminId_fk";
|
||||||
|
--> statement-breakpoint
|
||||||
|
ALTER TABLE "registry" DROP CONSTRAINT "registry_adminId_admin_adminId_fk";
|
||||||
|
--> statement-breakpoint
|
||||||
|
ALTER TABLE "notification" DROP CONSTRAINT "notification_adminId_admin_adminId_fk";
|
||||||
|
--> statement-breakpoint
|
||||||
|
ALTER TABLE "ssh-key" DROP CONSTRAINT "ssh-key_adminId_admin_adminId_fk";
|
||||||
|
--> statement-breakpoint
|
||||||
|
ALTER TABLE "git_provider" DROP CONSTRAINT "git_provider_adminId_admin_adminId_fk";
|
||||||
|
--> statement-breakpoint
|
||||||
|
ALTER TABLE "server" DROP CONSTRAINT "server_adminId_admin_adminId_fk";
|
||||||
|
--> statement-breakpoint
|
||||||
|
ALTER TABLE "project" ADD CONSTRAINT "project_userId_user_temp_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."user_temp"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||||
|
ALTER TABLE "destination" ADD CONSTRAINT "destination_userId_user_temp_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."user_temp"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||||
|
ALTER TABLE "certificate" ADD CONSTRAINT "certificate_userId_user_temp_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."user_temp"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||||
|
ALTER TABLE "registry" ADD CONSTRAINT "registry_userId_user_temp_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."user_temp"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||||
|
ALTER TABLE "notification" ADD CONSTRAINT "notification_userId_user_temp_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."user_temp"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||||
|
ALTER TABLE "ssh-key" ADD CONSTRAINT "ssh-key_userId_user_temp_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."user_temp"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||||
|
ALTER TABLE "git_provider" ADD CONSTRAINT "git_provider_userId_user_temp_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."user_temp"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||||
|
ALTER TABLE "server" ADD CONSTRAINT "server_userId_user_temp_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."user_temp"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
2
apps/dokploy/drizzle/0069_broad_ken_ellis.sql
Normal file
2
apps/dokploy/drizzle/0069_broad_ken_ellis.sql
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
ALTER TABLE "user_temp" ALTER COLUMN "token" SET DEFAULT '';--> statement-breakpoint
|
||||||
|
ALTER TABLE "user_temp" ADD COLUMN "created_at" timestamp DEFAULT now();
|
||||||
4485
apps/dokploy/drizzle/meta/0064_snapshot.json
Normal file
4485
apps/dokploy/drizzle/meta/0064_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
4485
apps/dokploy/drizzle/meta/0065_snapshot.json
Normal file
4485
apps/dokploy/drizzle/meta/0065_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
5272
apps/dokploy/drizzle/meta/0066_snapshot.json
Normal file
5272
apps/dokploy/drizzle/meta/0066_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
5272
apps/dokploy/drizzle/meta/0067_snapshot.json
Normal file
5272
apps/dokploy/drizzle/meta/0067_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
5272
apps/dokploy/drizzle/meta/0068_snapshot.json
Normal file
5272
apps/dokploy/drizzle/meta/0068_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
5280
apps/dokploy/drizzle/meta/0069_snapshot.json
Normal file
5280
apps/dokploy/drizzle/meta/0069_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -449,6 +449,48 @@
|
|||||||
"when": 1738522845992,
|
"when": 1738522845992,
|
||||||
"tag": "0063_panoramic_dreadnoughts",
|
"tag": "0063_panoramic_dreadnoughts",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 64,
|
||||||
|
"version": "7",
|
||||||
|
"when": 1738564387043,
|
||||||
|
"tag": "0064_previous_agent_brand",
|
||||||
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 65,
|
||||||
|
"version": "7",
|
||||||
|
"when": 1739087857244,
|
||||||
|
"tag": "0065_daily_zaladane",
|
||||||
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 66,
|
||||||
|
"version": "7",
|
||||||
|
"when": 1739426913392,
|
||||||
|
"tag": "0066_yielding_echo",
|
||||||
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 67,
|
||||||
|
"version": "7",
|
||||||
|
"when": 1739427057545,
|
||||||
|
"tag": "0067_migrate-data",
|
||||||
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 68,
|
||||||
|
"version": "7",
|
||||||
|
"when": 1739428942964,
|
||||||
|
"tag": "0068_sour_professor_monster",
|
||||||
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 69,
|
||||||
|
"version": "7",
|
||||||
|
"when": 1739664410814,
|
||||||
|
"tag": "0069_broad_ken_ellis",
|
||||||
|
"breakpoints": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
7
apps/dokploy/lib/auth.ts
Normal file
7
apps/dokploy/lib/auth.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import { organizationClient } from "better-auth/client/plugins";
|
||||||
|
import { createAuthClient } from "better-auth/react";
|
||||||
|
|
||||||
|
export const authClient = createAuthClient({
|
||||||
|
baseURL: "http://localhost:3000", // the base url of your auth server
|
||||||
|
plugins: [organizationClient()],
|
||||||
|
});
|
||||||
126
apps/dokploy/migrate.ts
Normal file
126
apps/dokploy/migrate.ts
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
import { drizzle } from "drizzle-orm/postgres-js";
|
||||||
|
import { migrate } from "drizzle-orm/postgres-js/migrator";
|
||||||
|
import { nanoid } from "nanoid";
|
||||||
|
import postgres from "postgres";
|
||||||
|
import * as schema from "./server/db/schema";
|
||||||
|
|
||||||
|
const connectionString = process.env.DATABASE_URL!;
|
||||||
|
|
||||||
|
const sql = postgres(connectionString, { max: 1 });
|
||||||
|
const db = drizzle(sql, {
|
||||||
|
schema,
|
||||||
|
});
|
||||||
|
|
||||||
|
await db
|
||||||
|
.transaction(async (db) => {
|
||||||
|
const admins = await db.query.admins.findMany({
|
||||||
|
with: {
|
||||||
|
auth: true,
|
||||||
|
users: {
|
||||||
|
with: {
|
||||||
|
auth: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
for (const admin of admins) {
|
||||||
|
const user = await db
|
||||||
|
.insert(schema.users_temp)
|
||||||
|
.values({
|
||||||
|
id: admin.adminId,
|
||||||
|
email: admin.auth.email,
|
||||||
|
token: admin.auth.token || "",
|
||||||
|
emailVerified: true,
|
||||||
|
updatedAt: new Date(),
|
||||||
|
role: "admin",
|
||||||
|
serverIp: admin.serverIp,
|
||||||
|
image: admin.auth.image,
|
||||||
|
certificateType: admin.certificateType,
|
||||||
|
host: admin.host,
|
||||||
|
letsEncryptEmail: admin.letsEncryptEmail,
|
||||||
|
sshPrivateKey: admin.sshPrivateKey,
|
||||||
|
enableDockerCleanup: admin.enableDockerCleanup,
|
||||||
|
enableLogRotation: admin.enableLogRotation,
|
||||||
|
enablePaidFeatures: admin.enablePaidFeatures,
|
||||||
|
metricsConfig: admin.metricsConfig,
|
||||||
|
cleanupCacheApplications: admin.cleanupCacheApplications,
|
||||||
|
cleanupCacheOnPreviews: admin.cleanupCacheOnPreviews,
|
||||||
|
cleanupCacheOnCompose: admin.cleanupCacheOnCompose,
|
||||||
|
stripeCustomerId: admin.stripeCustomerId,
|
||||||
|
stripeSubscriptionId: admin.stripeSubscriptionId,
|
||||||
|
serversQuantity: admin.serversQuantity,
|
||||||
|
})
|
||||||
|
.returning()
|
||||||
|
.then((user) => user[0]);
|
||||||
|
|
||||||
|
await db.insert(schema.account).values({
|
||||||
|
providerId: "credential",
|
||||||
|
userId: user?.id || "",
|
||||||
|
password: admin.auth.password,
|
||||||
|
is2FAEnabled: admin.auth.is2FAEnabled || false,
|
||||||
|
createdAt: new Date(admin.auth.createdAt) || new Date(),
|
||||||
|
updatedAt: new Date(admin.auth.createdAt) || new Date(),
|
||||||
|
});
|
||||||
|
|
||||||
|
const organization = await db
|
||||||
|
.insert(schema.organization)
|
||||||
|
.values({
|
||||||
|
name: "My Organization",
|
||||||
|
slug: nanoid(),
|
||||||
|
ownerId: user?.id || "",
|
||||||
|
createdAt: new Date(admin.createdAt) || new Date(),
|
||||||
|
})
|
||||||
|
.returning()
|
||||||
|
.then((organization) => organization[0]);
|
||||||
|
|
||||||
|
for (const member of admin.users) {
|
||||||
|
const userTemp = await db
|
||||||
|
.insert(schema.users_temp)
|
||||||
|
.values({
|
||||||
|
id: member.userId,
|
||||||
|
email: member.auth.email,
|
||||||
|
token: member.token || "",
|
||||||
|
emailVerified: true,
|
||||||
|
updatedAt: new Date(admin.createdAt) || new Date(),
|
||||||
|
role: "user",
|
||||||
|
image: member.auth.image,
|
||||||
|
createdAt: admin.createdAt,
|
||||||
|
canAccessToAPI: member.canAccessToAPI || false,
|
||||||
|
canAccessToDocker: member.canAccessToDocker || false,
|
||||||
|
canAccessToGitProviders: member.canAccessToGitProviders || false,
|
||||||
|
canAccessToSSHKeys: member.canAccessToSSHKeys || false,
|
||||||
|
canAccessToTraefikFiles: member.canAccessToTraefikFiles || false,
|
||||||
|
canCreateProjects: member.canCreateProjects || false,
|
||||||
|
canCreateServices: member.canCreateServices || false,
|
||||||
|
canDeleteProjects: member.canDeleteProjects || false,
|
||||||
|
canDeleteServices: member.canDeleteServices || false,
|
||||||
|
accessedProjects: member.accessedProjects || [],
|
||||||
|
accessedServices: member.accessedServices || [],
|
||||||
|
})
|
||||||
|
.returning()
|
||||||
|
.then((userTemp) => userTemp[0]);
|
||||||
|
|
||||||
|
await db.insert(schema.account).values({
|
||||||
|
providerId: "credential",
|
||||||
|
userId: member?.userId || "",
|
||||||
|
password: member.auth.password,
|
||||||
|
is2FAEnabled: member.auth.is2FAEnabled || false,
|
||||||
|
createdAt: new Date(member.auth.createdAt) || new Date(),
|
||||||
|
updatedAt: new Date(member.auth.createdAt) || new Date(),
|
||||||
|
});
|
||||||
|
|
||||||
|
await db.insert(schema.member).values({
|
||||||
|
organizationId: organization?.id || "",
|
||||||
|
userId: userTemp?.id || "",
|
||||||
|
role: "admin",
|
||||||
|
createdAt: new Date(member.createdAt) || new Date(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
console.log("Migration finished");
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error(error);
|
||||||
|
});
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
"studio": "drizzle-kit studio --config ./server/db/drizzle.config.ts",
|
"studio": "drizzle-kit studio --config ./server/db/drizzle.config.ts",
|
||||||
"migration:generate": "drizzle-kit generate --config ./server/db/drizzle.config.ts",
|
"migration:generate": "drizzle-kit generate --config ./server/db/drizzle.config.ts",
|
||||||
"migration:run": "tsx -r dotenv/config migration.ts",
|
"migration:run": "tsx -r dotenv/config migration.ts",
|
||||||
|
"manual-migration:run": "tsx -r dotenv/config migrate.ts",
|
||||||
"migration:up": "drizzle-kit up --config ./server/db/drizzle.config.ts",
|
"migration:up": "drizzle-kit up --config ./server/db/drizzle.config.ts",
|
||||||
"migration:drop": "drizzle-kit drop --config ./server/db/drizzle.config.ts",
|
"migration:drop": "drizzle-kit drop --config ./server/db/drizzle.config.ts",
|
||||||
"db:push": "drizzle-kit push --config ./server/db/drizzle.config.ts",
|
"db:push": "drizzle-kit push --config ./server/db/drizzle.config.ts",
|
||||||
@@ -35,6 +36,7 @@
|
|||||||
"test": "vitest --config __test__/vitest.config.ts"
|
"test": "vitest --config __test__/vitest.config.ts"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"better-auth": "1.1.16",
|
||||||
"bl": "6.0.11",
|
"bl": "6.0.11",
|
||||||
"rotating-file-stream": "3.2.3",
|
"rotating-file-stream": "3.2.3",
|
||||||
"qrcode": "^1.5.3",
|
"qrcode": "^1.5.3",
|
||||||
|
|||||||
7
apps/dokploy/pages/api/auth/[...all].ts
Normal file
7
apps/dokploy/pages/api/auth/[...all].ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import { auth } from "@dokploy/server/index";
|
||||||
|
import { toNodeHandler } from "better-auth/node";
|
||||||
|
|
||||||
|
// Disallow body parsing, we will parse it manually
|
||||||
|
export const config = { api: { bodyParser: false } };
|
||||||
|
|
||||||
|
export default toNodeHandler(auth.handler);
|
||||||
@@ -42,7 +42,7 @@ export default async function handler(
|
|||||||
const auth = await findAuthById(value as string);
|
const auth = await findAuthById(value as string);
|
||||||
|
|
||||||
let adminId = "";
|
let adminId = "";
|
||||||
if (auth.rol === "admin") {
|
if (auth.role === "owner") {
|
||||||
const admin = await findAdminByAuthId(auth.id);
|
const admin = await findAdminByAuthId(auth.id);
|
||||||
adminId = admin.adminId;
|
adminId = admin.adminId;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { buffer } from "node:stream/consumers";
|
import { buffer } from "node:stream/consumers";
|
||||||
import { db } from "@/server/db";
|
import { db } from "@/server/db";
|
||||||
import { admins, server } from "@/server/db/schema";
|
import { admins, server, users_temp } from "@/server/db/schema";
|
||||||
import { findAdminById } from "@dokploy/server";
|
import { findAdminById, findUserById } from "@dokploy/server";
|
||||||
import { asc, eq } from "drizzle-orm";
|
import { asc, eq } from "drizzle-orm";
|
||||||
import type { NextApiRequest, NextApiResponse } from "next";
|
import type { NextApiRequest, NextApiResponse } from "next";
|
||||||
import Stripe from "stripe";
|
import Stripe from "stripe";
|
||||||
@@ -64,33 +64,35 @@ export default async function handler(
|
|||||||
session.subscription as string,
|
session.subscription as string,
|
||||||
);
|
);
|
||||||
await db
|
await db
|
||||||
.update(admins)
|
.update(users_temp)
|
||||||
.set({
|
.set({
|
||||||
stripeCustomerId: session.customer as string,
|
stripeCustomerId: session.customer as string,
|
||||||
stripeSubscriptionId: session.subscription as string,
|
stripeSubscriptionId: session.subscription as string,
|
||||||
serversQuantity: subscription?.items?.data?.[0]?.quantity ?? 0,
|
serversQuantity: subscription?.items?.data?.[0]?.quantity ?? 0,
|
||||||
})
|
})
|
||||||
.where(eq(admins.adminId, adminId))
|
.where(eq(users_temp.id, adminId))
|
||||||
.returning();
|
.returning();
|
||||||
|
|
||||||
const admin = await findAdminById(adminId);
|
const admin = await findUserById(adminId);
|
||||||
if (!admin) {
|
if (!admin) {
|
||||||
return res.status(400).send("Webhook Error: Admin not found");
|
return res.status(400).send("Webhook Error: Admin not found");
|
||||||
}
|
}
|
||||||
const newServersQuantity = admin.serversQuantity;
|
const newServersQuantity = admin.serversQuantity;
|
||||||
await updateServersBasedOnQuantity(admin.adminId, newServersQuantity);
|
await updateServersBasedOnQuantity(admin.id, newServersQuantity);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "customer.subscription.created": {
|
case "customer.subscription.created": {
|
||||||
const newSubscription = event.data.object as Stripe.Subscription;
|
const newSubscription = event.data.object as Stripe.Subscription;
|
||||||
|
|
||||||
await db
|
await db
|
||||||
.update(admins)
|
.update(users_temp)
|
||||||
.set({
|
.set({
|
||||||
stripeSubscriptionId: newSubscription.id,
|
stripeSubscriptionId: newSubscription.id,
|
||||||
stripeCustomerId: newSubscription.customer as string,
|
stripeCustomerId: newSubscription.customer as string,
|
||||||
})
|
})
|
||||||
.where(eq(admins.stripeCustomerId, newSubscription.customer as string))
|
.where(
|
||||||
|
eq(users_temp.stripeCustomerId, newSubscription.customer as string),
|
||||||
|
)
|
||||||
.returning();
|
.returning();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -100,14 +102,16 @@ export default async function handler(
|
|||||||
const newSubscription = event.data.object as Stripe.Subscription;
|
const newSubscription = event.data.object as Stripe.Subscription;
|
||||||
|
|
||||||
await db
|
await db
|
||||||
.update(admins)
|
.update(users_temp)
|
||||||
.set({
|
.set({
|
||||||
stripeSubscriptionId: null,
|
stripeSubscriptionId: null,
|
||||||
serversQuantity: 0,
|
serversQuantity: 0,
|
||||||
})
|
})
|
||||||
.where(eq(admins.stripeCustomerId, newSubscription.customer as string));
|
.where(
|
||||||
|
eq(users_temp.stripeCustomerId, newSubscription.customer as string),
|
||||||
|
);
|
||||||
|
|
||||||
const admin = await findAdminByStripeCustomerId(
|
const admin = await findUserByStripeCustomerId(
|
||||||
newSubscription.customer as string,
|
newSubscription.customer as string,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -115,13 +119,13 @@ export default async function handler(
|
|||||||
return res.status(400).send("Webhook Error: Admin not found");
|
return res.status(400).send("Webhook Error: Admin not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
await disableServers(admin.adminId);
|
await disableServers(admin.id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "customer.subscription.updated": {
|
case "customer.subscription.updated": {
|
||||||
const newSubscription = event.data.object as Stripe.Subscription;
|
const newSubscription = event.data.object as Stripe.Subscription;
|
||||||
|
|
||||||
const admin = await findAdminByStripeCustomerId(
|
const admin = await findUserByStripeCustomerId(
|
||||||
newSubscription.customer as string,
|
newSubscription.customer as string,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -131,23 +135,23 @@ export default async function handler(
|
|||||||
|
|
||||||
if (newSubscription.status === "active") {
|
if (newSubscription.status === "active") {
|
||||||
await db
|
await db
|
||||||
.update(admins)
|
.update(users_temp)
|
||||||
.set({
|
.set({
|
||||||
serversQuantity: newSubscription?.items?.data?.[0]?.quantity ?? 0,
|
serversQuantity: newSubscription?.items?.data?.[0]?.quantity ?? 0,
|
||||||
})
|
})
|
||||||
.where(
|
.where(
|
||||||
eq(admins.stripeCustomerId, newSubscription.customer as string),
|
eq(users_temp.stripeCustomerId, newSubscription.customer as string),
|
||||||
);
|
);
|
||||||
|
|
||||||
const newServersQuantity = admin.serversQuantity;
|
const newServersQuantity = admin.serversQuantity;
|
||||||
await updateServersBasedOnQuantity(admin.adminId, newServersQuantity);
|
await updateServersBasedOnQuantity(admin.id, newServersQuantity);
|
||||||
} else {
|
} else {
|
||||||
await disableServers(admin.adminId);
|
await disableServers(admin.id);
|
||||||
await db
|
await db
|
||||||
.update(admins)
|
.update(users_temp)
|
||||||
.set({ serversQuantity: 0 })
|
.set({ serversQuantity: 0 })
|
||||||
.where(
|
.where(
|
||||||
eq(admins.stripeCustomerId, newSubscription.customer as string),
|
eq(users_temp.stripeCustomerId, newSubscription.customer as string),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,7 +178,7 @@ export default async function handler(
|
|||||||
})
|
})
|
||||||
.where(eq(admins.stripeCustomerId, suscription.customer as string));
|
.where(eq(admins.stripeCustomerId, suscription.customer as string));
|
||||||
|
|
||||||
const admin = await findAdminByStripeCustomerId(
|
const admin = await findUserByStripeCustomerId(
|
||||||
suscription.customer as string,
|
suscription.customer as string,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -182,7 +186,7 @@ export default async function handler(
|
|||||||
return res.status(400).send("Webhook Error: Admin not found");
|
return res.status(400).send("Webhook Error: Admin not found");
|
||||||
}
|
}
|
||||||
const newServersQuantity = admin.serversQuantity;
|
const newServersQuantity = admin.serversQuantity;
|
||||||
await updateServersBasedOnQuantity(admin.adminId, newServersQuantity);
|
await updateServersBasedOnQuantity(admin.id, newServersQuantity);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "invoice.payment_failed": {
|
case "invoice.payment_failed": {
|
||||||
@@ -193,7 +197,7 @@ export default async function handler(
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (subscription.status !== "active") {
|
if (subscription.status !== "active") {
|
||||||
const admin = await findAdminByStripeCustomerId(
|
const admin = await findUserByStripeCustomerId(
|
||||||
newInvoice.customer as string,
|
newInvoice.customer as string,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -207,7 +211,7 @@ export default async function handler(
|
|||||||
})
|
})
|
||||||
.where(eq(admins.stripeCustomerId, newInvoice.customer as string));
|
.where(eq(admins.stripeCustomerId, newInvoice.customer as string));
|
||||||
|
|
||||||
await disableServers(admin.adminId);
|
await disableServers(admin.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -216,20 +220,20 @@ export default async function handler(
|
|||||||
case "customer.deleted": {
|
case "customer.deleted": {
|
||||||
const customer = event.data.object as Stripe.Customer;
|
const customer = event.data.object as Stripe.Customer;
|
||||||
|
|
||||||
const admin = await findAdminByStripeCustomerId(customer.id);
|
const admin = await findUserByStripeCustomerId(customer.id);
|
||||||
if (!admin) {
|
if (!admin) {
|
||||||
return res.status(400).send("Webhook Error: Admin not found");
|
return res.status(400).send("Webhook Error: Admin not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
await disableServers(admin.adminId);
|
await disableServers(admin.id);
|
||||||
await db
|
await db
|
||||||
.update(admins)
|
.update(users_temp)
|
||||||
.set({
|
.set({
|
||||||
stripeCustomerId: null,
|
stripeCustomerId: null,
|
||||||
stripeSubscriptionId: null,
|
stripeSubscriptionId: null,
|
||||||
serversQuantity: 0,
|
serversQuantity: 0,
|
||||||
})
|
})
|
||||||
.where(eq(admins.stripeCustomerId, customer.id));
|
.where(eq(users_temp.stripeCustomerId, customer.id));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -240,20 +244,20 @@ export default async function handler(
|
|||||||
return res.status(200).json({ received: true });
|
return res.status(200).json({ received: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
const disableServers = async (adminId: string) => {
|
const disableServers = async (userId: string) => {
|
||||||
await db
|
await db
|
||||||
.update(server)
|
.update(server)
|
||||||
.set({
|
.set({
|
||||||
serverStatus: "inactive",
|
serverStatus: "inactive",
|
||||||
})
|
})
|
||||||
.where(eq(server.adminId, adminId));
|
.where(eq(server.userId, userId));
|
||||||
};
|
};
|
||||||
|
|
||||||
const findAdminByStripeCustomerId = async (stripeCustomerId: string) => {
|
const findUserByStripeCustomerId = async (stripeCustomerId: string) => {
|
||||||
const admin = db.query.admins.findFirst({
|
const user = db.query.users_temp.findFirst({
|
||||||
where: eq(admins.stripeCustomerId, stripeCustomerId),
|
where: eq(users_temp.stripeCustomerId, stripeCustomerId),
|
||||||
});
|
});
|
||||||
return admin;
|
return user;
|
||||||
};
|
};
|
||||||
|
|
||||||
const activateServer = async (serverId: string) => {
|
const activateServer = async (serverId: string) => {
|
||||||
@@ -270,19 +274,19 @@ const deactivateServer = async (serverId: string) => {
|
|||||||
.where(eq(server.serverId, serverId));
|
.where(eq(server.serverId, serverId));
|
||||||
};
|
};
|
||||||
|
|
||||||
export const findServersByAdminIdSorted = async (adminId: string) => {
|
export const findServersByUserIdSorted = async (userId: string) => {
|
||||||
const servers = await db.query.server.findMany({
|
const servers = await db.query.server.findMany({
|
||||||
where: eq(server.adminId, adminId),
|
where: eq(server.userId, userId),
|
||||||
orderBy: asc(server.createdAt),
|
orderBy: asc(server.createdAt),
|
||||||
});
|
});
|
||||||
|
|
||||||
return servers;
|
return servers;
|
||||||
};
|
};
|
||||||
export const updateServersBasedOnQuantity = async (
|
export const updateServersBasedOnQuantity = async (
|
||||||
adminId: string,
|
userId: string,
|
||||||
newServersQuantity: number,
|
newServersQuantity: number,
|
||||||
) => {
|
) => {
|
||||||
const servers = await findServersByAdminIdSorted(adminId);
|
const servers = await findServersByUserIdSorted(userId);
|
||||||
|
|
||||||
if (servers.length > newServersQuantity) {
|
if (servers.length > newServersQuantity) {
|
||||||
for (const [index, server] of servers.entries()) {
|
for (const [index, server] of servers.entries()) {
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ export async function getServerSideProps(
|
|||||||
await helpers.project.all.prefetch();
|
await helpers.project.all.prefetch();
|
||||||
const auth = await helpers.auth.get.fetch();
|
const auth = await helpers.auth.get.fetch();
|
||||||
|
|
||||||
if (auth.rol === "user") {
|
if (auth.role === "member") {
|
||||||
const user = await helpers.user.byAuthId.fetch({
|
const user = await helpers.user.byAuthId.fetch({
|
||||||
authId: auth.id,
|
authId: auth.id,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import {
|
|||||||
import { ProjectLayout } from "@/components/layouts/project-layout";
|
import { ProjectLayout } from "@/components/layouts/project-layout";
|
||||||
import { BreadcrumbSidebar } from "@/components/shared/breadcrumb-sidebar";
|
import { BreadcrumbSidebar } from "@/components/shared/breadcrumb-sidebar";
|
||||||
import { DateTooltip } from "@/components/shared/date-tooltip";
|
import { DateTooltip } from "@/components/shared/date-tooltip";
|
||||||
|
import { DialogAction } from "@/components/shared/dialog-action";
|
||||||
import { StatusTooltip } from "@/components/shared/status-tooltip";
|
import { StatusTooltip } from "@/components/shared/status-tooltip";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import {
|
import {
|
||||||
@@ -23,6 +24,7 @@ import {
|
|||||||
CardHeader,
|
CardHeader,
|
||||||
CardTitle,
|
CardTitle,
|
||||||
} from "@/components/ui/card";
|
} from "@/components/ui/card";
|
||||||
|
import { Checkbox } from "@/components/ui/checkbox";
|
||||||
import {
|
import {
|
||||||
Command,
|
Command,
|
||||||
CommandEmpty,
|
CommandEmpty,
|
||||||
@@ -50,21 +52,26 @@ import type { findProjectById } from "@dokploy/server";
|
|||||||
import { validateRequest } from "@dokploy/server";
|
import { validateRequest } from "@dokploy/server";
|
||||||
import { createServerSideHelpers } from "@trpc/react-query/server";
|
import { createServerSideHelpers } from "@trpc/react-query/server";
|
||||||
import {
|
import {
|
||||||
|
Ban,
|
||||||
|
Check,
|
||||||
|
CheckCircle2,
|
||||||
|
ChevronsUpDown,
|
||||||
CircuitBoard,
|
CircuitBoard,
|
||||||
FolderInput,
|
FolderInput,
|
||||||
GlobeIcon,
|
GlobeIcon,
|
||||||
Loader2,
|
Loader2,
|
||||||
PlusIcon,
|
PlusIcon,
|
||||||
Search,
|
Search,
|
||||||
|
X,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import { Check, ChevronsUpDown, X } from "lucide-react";
|
|
||||||
import type {
|
import type {
|
||||||
GetServerSidePropsContext,
|
GetServerSidePropsContext,
|
||||||
InferGetServerSidePropsType,
|
InferGetServerSidePropsType,
|
||||||
} from "next";
|
} from "next";
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import React, { useMemo, useState, type ReactElement } from "react";
|
import { type ReactElement, useMemo, useState } from "react";
|
||||||
|
import { toast } from "sonner";
|
||||||
import superjson from "superjson";
|
import superjson from "superjson";
|
||||||
|
|
||||||
export type Services = {
|
export type Services = {
|
||||||
@@ -191,6 +198,7 @@ export const extractServices = (data: Project | undefined) => {
|
|||||||
const Project = (
|
const Project = (
|
||||||
props: InferGetServerSidePropsType<typeof getServerSideProps>,
|
props: InferGetServerSidePropsType<typeof getServerSideProps>,
|
||||||
) => {
|
) => {
|
||||||
|
const [isBulkActionLoading, setIsBulkActionLoading] = useState(false);
|
||||||
const { projectId } = props;
|
const { projectId } = props;
|
||||||
const { data: auth } = api.auth.get.useQuery();
|
const { data: auth } = api.auth.get.useQuery();
|
||||||
const { data: user } = api.user.byAuthId.useQuery(
|
const { data: user } = api.user.byAuthId.useQuery(
|
||||||
@@ -198,10 +206,10 @@ const Project = (
|
|||||||
authId: auth?.id || "",
|
authId: auth?.id || "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
enabled: !!auth?.id && auth?.rol === "user",
|
enabled: !!auth?.id && auth?.role === "member",
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
const { data, isLoading } = api.project.one.useQuery({ projectId });
|
const { data, isLoading, refetch } = api.project.one.useQuery({ projectId });
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const emptyServices =
|
const emptyServices =
|
||||||
@@ -228,6 +236,70 @@ const Project = (
|
|||||||
|
|
||||||
const [selectedTypes, setSelectedTypes] = useState<string[]>([]);
|
const [selectedTypes, setSelectedTypes] = useState<string[]>([]);
|
||||||
const [openCombobox, setOpenCombobox] = useState(false);
|
const [openCombobox, setOpenCombobox] = useState(false);
|
||||||
|
const [selectedServices, setSelectedServices] = useState<string[]>([]);
|
||||||
|
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
|
||||||
|
|
||||||
|
const handleSelectAll = () => {
|
||||||
|
if (selectedServices.length === filteredServices.length) {
|
||||||
|
setSelectedServices([]);
|
||||||
|
} else {
|
||||||
|
setSelectedServices(filteredServices.map((service) => service.id));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleServiceSelect = (serviceId: string, event: React.MouseEvent) => {
|
||||||
|
event.stopPropagation();
|
||||||
|
setSelectedServices((prev) =>
|
||||||
|
prev.includes(serviceId)
|
||||||
|
? prev.filter((id) => id !== serviceId)
|
||||||
|
: [...prev, serviceId],
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const composeActions = {
|
||||||
|
start: api.compose.start.useMutation(),
|
||||||
|
stop: api.compose.stop.useMutation(),
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleBulkStart = async () => {
|
||||||
|
let success = 0;
|
||||||
|
setIsBulkActionLoading(true);
|
||||||
|
for (const serviceId of selectedServices) {
|
||||||
|
try {
|
||||||
|
await composeActions.start.mutateAsync({ composeId: serviceId });
|
||||||
|
success++;
|
||||||
|
} catch (error) {
|
||||||
|
toast.error(`Error starting service ${serviceId}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (success > 0) {
|
||||||
|
toast.success(`${success} services started successfully`);
|
||||||
|
refetch();
|
||||||
|
}
|
||||||
|
setIsBulkActionLoading(false);
|
||||||
|
setSelectedServices([]);
|
||||||
|
setIsDropdownOpen(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleBulkStop = async () => {
|
||||||
|
let success = 0;
|
||||||
|
setIsBulkActionLoading(true);
|
||||||
|
for (const serviceId of selectedServices) {
|
||||||
|
try {
|
||||||
|
await composeActions.stop.mutateAsync({ composeId: serviceId });
|
||||||
|
success++;
|
||||||
|
} catch (error) {
|
||||||
|
toast.error(`Error stopping service ${serviceId}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (success > 0) {
|
||||||
|
toast.success(`${success} services stopped successfully`);
|
||||||
|
refetch();
|
||||||
|
}
|
||||||
|
setSelectedServices([]);
|
||||||
|
setIsDropdownOpen(false);
|
||||||
|
setIsBulkActionLoading(false);
|
||||||
|
};
|
||||||
|
|
||||||
const filteredServices = useMemo(() => {
|
const filteredServices = useMemo(() => {
|
||||||
if (!applications) return [];
|
if (!applications) return [];
|
||||||
@@ -263,7 +335,7 @@ const Project = (
|
|||||||
</CardTitle>
|
</CardTitle>
|
||||||
<CardDescription>{data?.description}</CardDescription>
|
<CardDescription>{data?.description}</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
{(auth?.rol === "admin" || user?.canCreateServices) && (
|
{(auth?.role === "owner" || user?.canCreateServices) && (
|
||||||
<div className="flex flex-row gap-4 flex-wrap">
|
<div className="flex flex-row gap-4 flex-wrap">
|
||||||
<ProjectEnvironment projectId={projectId}>
|
<ProjectEnvironment projectId={projectId}>
|
||||||
<Button variant="outline">Project Environment</Button>
|
<Button variant="outline">Project Environment</Button>
|
||||||
@@ -309,7 +381,76 @@ const Project = (
|
|||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<div className="flex flex-row gap-2 items-center">
|
<div className="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
|
||||||
|
<div className="flex items-center gap-4">
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<Checkbox
|
||||||
|
checked={selectedServices.length > 0}
|
||||||
|
className={cn(
|
||||||
|
"data-[state=checked]:bg-primary",
|
||||||
|
selectedServices.length > 0 &&
|
||||||
|
selectedServices.length <
|
||||||
|
filteredServices.length &&
|
||||||
|
"bg-primary/50",
|
||||||
|
)}
|
||||||
|
onCheckedChange={handleSelectAll}
|
||||||
|
/>
|
||||||
|
<span className="text-sm">
|
||||||
|
Select All{" "}
|
||||||
|
{selectedServices.length > 0 &&
|
||||||
|
`(${selectedServices.length}/${filteredServices.length})`}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<DropdownMenu
|
||||||
|
open={isDropdownOpen}
|
||||||
|
onOpenChange={setIsDropdownOpen}
|
||||||
|
>
|
||||||
|
<DropdownMenuTrigger asChild>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
disabled={selectedServices.length === 0}
|
||||||
|
isLoading={isBulkActionLoading}
|
||||||
|
>
|
||||||
|
Bulk Actions
|
||||||
|
</Button>
|
||||||
|
</DropdownMenuTrigger>
|
||||||
|
<DropdownMenuContent align="end">
|
||||||
|
<DropdownMenuLabel>Actions</DropdownMenuLabel>
|
||||||
|
<DropdownMenuSeparator />
|
||||||
|
<DialogAction
|
||||||
|
title="Start Services"
|
||||||
|
description={`Are you sure you want to start ${selectedServices.length} services?`}
|
||||||
|
type="default"
|
||||||
|
onClick={handleBulkStart}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
className="w-full justify-start"
|
||||||
|
>
|
||||||
|
<CheckCircle2 className="mr-2 h-4 w-4" />
|
||||||
|
Start
|
||||||
|
</Button>
|
||||||
|
</DialogAction>
|
||||||
|
<DialogAction
|
||||||
|
title="Stop Services"
|
||||||
|
description={`Are you sure you want to stop ${selectedServices.length} services?`}
|
||||||
|
type="destructive"
|
||||||
|
onClick={handleBulkStop}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
className="w-full justify-start text-destructive"
|
||||||
|
>
|
||||||
|
<Ban className="mr-2 h-4 w-4" />
|
||||||
|
Stop
|
||||||
|
</Button>
|
||||||
|
</DialogAction>
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex flex-col gap-2 sm:flex-row sm:gap-4 sm:items-center">
|
||||||
<div className="w-full relative">
|
<div className="w-full relative">
|
||||||
<Input
|
<Input
|
||||||
placeholder="Filter services..."
|
placeholder="Filter services..."
|
||||||
@@ -319,7 +460,10 @@ const Project = (
|
|||||||
/>
|
/>
|
||||||
<Search className="absolute right-3 top-1/2 -translate-y-1/2 size-4 text-muted-foreground" />
|
<Search className="absolute right-3 top-1/2 -translate-y-1/2 size-4 text-muted-foreground" />
|
||||||
</div>
|
</div>
|
||||||
<Popover open={openCombobox} onOpenChange={setOpenCombobox}>
|
<Popover
|
||||||
|
open={openCombobox}
|
||||||
|
onOpenChange={setOpenCombobox}
|
||||||
|
>
|
||||||
<PopoverTrigger asChild>
|
<PopoverTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
@@ -382,6 +526,7 @@ const Project = (
|
|||||||
</PopoverContent>
|
</PopoverContent>
|
||||||
</Popover>
|
</Popover>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="flex w-full gap-8">
|
<div className="flex w-full gap-8">
|
||||||
{emptyServices ? (
|
{emptyServices ? (
|
||||||
@@ -418,6 +563,27 @@ const Project = (
|
|||||||
<StatusTooltip status={service.status} />
|
<StatusTooltip status={service.status} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
"absolute -left-3 -bottom-3 size-9 translate-y-1 rounded-full p-0 transition-all duration-200 z-10 bg-background border",
|
||||||
|
selectedServices.includes(service.id)
|
||||||
|
? "opacity-100 translate-y-0"
|
||||||
|
: "opacity-0 group-hover:translate-y-0 group-hover:opacity-100",
|
||||||
|
)}
|
||||||
|
onClick={(e) =>
|
||||||
|
handleServiceSelect(service.id, e)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<div className="h-full w-full flex items-center justify-center">
|
||||||
|
<Checkbox
|
||||||
|
checked={selectedServices.includes(
|
||||||
|
service.id,
|
||||||
|
)}
|
||||||
|
className="data-[state=checked]:bg-primary"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="flex items-center justify-between">
|
<CardTitle className="flex items-center justify-between">
|
||||||
<div className="flex flex-row items-center gap-2 justify-between w-full">
|
<div className="flex flex-row items-center gap-2 justify-between w-full">
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ const Service = (
|
|||||||
authId: auth?.id || "",
|
authId: auth?.id || "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
enabled: !!auth?.id && auth?.rol === "user",
|
enabled: !!auth?.id && auth?.role === "member",
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -186,7 +186,7 @@ const Service = (
|
|||||||
|
|
||||||
<div className="flex flex-row gap-2 justify-end">
|
<div className="flex flex-row gap-2 justify-end">
|
||||||
<UpdateApplication applicationId={applicationId} />
|
<UpdateApplication applicationId={applicationId} />
|
||||||
{(auth?.rol === "admin" || user?.canDeleteServices) && (
|
{(auth?.role === "owner" || user?.canDeleteServices) && (
|
||||||
<DeleteService id={applicationId} type="application" />
|
<DeleteService id={applicationId} type="application" />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ const Service = (
|
|||||||
authId: auth?.id || "",
|
authId: auth?.id || "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
enabled: !!auth?.id && auth?.rol === "user",
|
enabled: !!auth?.id && auth?.role === "member",
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -181,7 +181,7 @@ const Service = (
|
|||||||
<div className="flex flex-row gap-2 justify-end">
|
<div className="flex flex-row gap-2 justify-end">
|
||||||
<UpdateCompose composeId={composeId} />
|
<UpdateCompose composeId={composeId} />
|
||||||
|
|
||||||
{(auth?.rol === "admin" || user?.canDeleteServices) && (
|
{(auth?.role === "owner" || user?.canDeleteServices) && (
|
||||||
<DeleteService id={composeId} type="compose" />
|
<DeleteService id={composeId} type="compose" />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ const Mariadb = (
|
|||||||
authId: auth?.id || "",
|
authId: auth?.id || "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
enabled: !!auth?.id && auth?.rol === "user",
|
enabled: !!auth?.id && auth?.role === "member",
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
const { data: isCloud } = api.settings.isCloud.useQuery();
|
const { data: isCloud } = api.settings.isCloud.useQuery();
|
||||||
@@ -154,7 +154,7 @@ const Mariadb = (
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex flex-row gap-2 justify-end">
|
<div className="flex flex-row gap-2 justify-end">
|
||||||
<UpdateMariadb mariadbId={mariadbId} />
|
<UpdateMariadb mariadbId={mariadbId} />
|
||||||
{(auth?.rol === "admin" || user?.canDeleteServices) && (
|
{(auth?.role === "owner" || user?.canDeleteServices) && (
|
||||||
<DeleteService id={mariadbId} type="mariadb" />
|
<DeleteService id={mariadbId} type="mariadb" />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ const Mongo = (
|
|||||||
authId: auth?.id || "",
|
authId: auth?.id || "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
enabled: !!auth?.id && auth?.rol === "user",
|
enabled: !!auth?.id && auth?.role === "member",
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -156,7 +156,7 @@ const Mongo = (
|
|||||||
|
|
||||||
<div className="flex flex-row gap-2 justify-end">
|
<div className="flex flex-row gap-2 justify-end">
|
||||||
<UpdateMongo mongoId={mongoId} />
|
<UpdateMongo mongoId={mongoId} />
|
||||||
{(auth?.rol === "admin" || user?.canDeleteServices) && (
|
{(auth?.role === "owner" || user?.canDeleteServices) && (
|
||||||
<DeleteService id={mongoId} type="mongo" />
|
<DeleteService id={mongoId} type="mongo" />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ const MySql = (
|
|||||||
authId: auth?.id || "",
|
authId: auth?.id || "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
enabled: !!auth?.id && auth?.rol === "user",
|
enabled: !!auth?.id && auth?.role === "member",
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -156,7 +156,7 @@ const MySql = (
|
|||||||
|
|
||||||
<div className="flex flex-row gap-2 justify-end">
|
<div className="flex flex-row gap-2 justify-end">
|
||||||
<UpdateMysql mysqlId={mysqlId} />
|
<UpdateMysql mysqlId={mysqlId} />
|
||||||
{(auth?.rol === "admin" || user?.canDeleteServices) && (
|
{(auth?.role === "owner" || user?.canDeleteServices) && (
|
||||||
<DeleteService id={mysqlId} type="mysql" />
|
<DeleteService id={mysqlId} type="mysql" />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ const Postgresql = (
|
|||||||
authId: auth?.id || "",
|
authId: auth?.id || "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
enabled: !!auth?.id && auth?.rol === "user",
|
enabled: !!auth?.id && auth?.role === "member",
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
const { data: monitoring } = api.admin.getMetricsToken.useQuery();
|
const { data: monitoring } = api.admin.getMetricsToken.useQuery();
|
||||||
@@ -154,7 +154,7 @@ const Postgresql = (
|
|||||||
|
|
||||||
<div className="flex flex-row gap-2 justify-end">
|
<div className="flex flex-row gap-2 justify-end">
|
||||||
<UpdatePostgres postgresId={postgresId} />
|
<UpdatePostgres postgresId={postgresId} />
|
||||||
{(auth?.rol === "admin" || user?.canDeleteServices) && (
|
{(auth?.role === "owner" || user?.canDeleteServices) && (
|
||||||
<DeleteService id={postgresId} type="postgres" />
|
<DeleteService id={postgresId} type="postgres" />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ const Redis = (
|
|||||||
authId: auth?.id || "",
|
authId: auth?.id || "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
enabled: !!auth?.id && auth?.rol === "user",
|
enabled: !!auth?.id && auth?.role === "member",
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -155,7 +155,7 @@ const Redis = (
|
|||||||
|
|
||||||
<div className="flex flex-row gap-2 justify-end">
|
<div className="flex flex-row gap-2 justify-end">
|
||||||
<UpdateRedis redisId={redisId} />
|
<UpdateRedis redisId={redisId} />
|
||||||
{(auth?.rol === "admin" || user?.canDeleteServices) && (
|
{(auth?.role === "owner" || user?.canDeleteServices) && (
|
||||||
<DeleteService id={redisId} type="redis" />
|
<DeleteService id={redisId} type="redis" />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ export async function getServerSideProps(
|
|||||||
}
|
}
|
||||||
const { req, res } = ctx;
|
const { req, res } = ctx;
|
||||||
const { user, session } = await validateRequest(req, res);
|
const { user, session } = await validateRequest(req, res);
|
||||||
if (!user || user.rol === "user") {
|
if (!user || user.role === "member") {
|
||||||
return {
|
return {
|
||||||
redirect: {
|
redirect: {
|
||||||
permanent: true,
|
permanent: true,
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ export async function getServerSideProps(
|
|||||||
) {
|
) {
|
||||||
const { req, res } = ctx;
|
const { req, res } = ctx;
|
||||||
const { user, session } = await validateRequest(req, res);
|
const { user, session } = await validateRequest(req, res);
|
||||||
if (!user || user.rol === "user") {
|
if (!user || user.role === "member") {
|
||||||
return {
|
return {
|
||||||
redirect: {
|
redirect: {
|
||||||
permanent: true,
|
permanent: true,
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ export async function getServerSideProps(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
const { user, session } = await validateRequest(ctx.req, ctx.res);
|
const { user, session } = await validateRequest(ctx.req, ctx.res);
|
||||||
if (!user || user.rol === "user") {
|
if (!user || user.role === "member") {
|
||||||
return {
|
return {
|
||||||
redirect: {
|
redirect: {
|
||||||
permanent: true,
|
permanent: true,
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ export async function getServerSideProps(
|
|||||||
) {
|
) {
|
||||||
const { req, res } = ctx;
|
const { req, res } = ctx;
|
||||||
const { user, session } = await validateRequest(req, res);
|
const { user, session } = await validateRequest(req, res);
|
||||||
if (!user || user.rol === "user") {
|
if (!user || user.role === "member") {
|
||||||
return {
|
return {
|
||||||
redirect: {
|
redirect: {
|
||||||
permanent: true,
|
permanent: true,
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ export async function getServerSideProps(
|
|||||||
await helpers.settings.isCloud.prefetch();
|
await helpers.settings.isCloud.prefetch();
|
||||||
const auth = await helpers.auth.get.fetch();
|
const auth = await helpers.auth.get.fetch();
|
||||||
|
|
||||||
if (auth.rol === "user") {
|
if (auth.role === "member") {
|
||||||
const user = await helpers.user.byAuthId.fetch({
|
const user = await helpers.user.byAuthId.fetch({
|
||||||
authId: auth.id,
|
authId: auth.id,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -190,7 +190,7 @@ export async function getServerSideProps(
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (user.rol === "user") {
|
if (user.role === "member") {
|
||||||
return {
|
return {
|
||||||
redirect: {
|
redirect: {
|
||||||
permanent: true,
|
permanent: true,
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ export async function getServerSideProps(
|
|||||||
) {
|
) {
|
||||||
const { req, res } = ctx;
|
const { req, res } = ctx;
|
||||||
const { user, session } = await validateRequest(req, res);
|
const { user, session } = await validateRequest(req, res);
|
||||||
if (!user || user.rol === "user") {
|
if (!user || user.role === "member") {
|
||||||
return {
|
return {
|
||||||
redirect: {
|
redirect: {
|
||||||
permanent: true,
|
permanent: true,
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ const Page = () => {
|
|||||||
authId: data?.id || "",
|
authId: data?.id || "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
enabled: !!data?.id && data?.rol === "user",
|
enabled: !!data?.id && data?.role === "user",
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -28,7 +28,7 @@ const Page = () => {
|
|||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
<div className="h-full rounded-xl max-w-5xl mx-auto flex flex-col gap-4">
|
<div className="h-full rounded-xl max-w-5xl mx-auto flex flex-col gap-4">
|
||||||
<ProfileForm />
|
<ProfileForm />
|
||||||
{(user?.canAccessToAPI || data?.rol === "admin") && <GenerateToken />}
|
{(user?.canAccessToAPI || data?.role === "owner") && <GenerateToken />}
|
||||||
|
|
||||||
{isCloud && <RemoveSelfAccount />}
|
{isCloud && <RemoveSelfAccount />}
|
||||||
</div>
|
</div>
|
||||||
@@ -62,7 +62,7 @@ export async function getServerSideProps(
|
|||||||
|
|
||||||
await helpers.settings.isCloud.prefetch();
|
await helpers.settings.isCloud.prefetch();
|
||||||
await helpers.auth.get.prefetch();
|
await helpers.auth.get.prefetch();
|
||||||
if (user?.rol === "user") {
|
if (user?.role === "user") {
|
||||||
await helpers.user.byAuthId.prefetch({
|
await helpers.user.byAuthId.prefetch({
|
||||||
authId: user.authId,
|
authId: user.authId,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ export async function getServerSideProps(
|
|||||||
) {
|
) {
|
||||||
const { req, res } = ctx;
|
const { req, res } = ctx;
|
||||||
const { user, session } = await validateRequest(req, res);
|
const { user, session } = await validateRequest(req, res);
|
||||||
if (!user || user.rol === "user") {
|
if (!user || user.role === "member") {
|
||||||
return {
|
return {
|
||||||
redirect: {
|
redirect: {
|
||||||
permanent: true,
|
permanent: true,
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ export async function getServerSideProps(
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (user.rol === "user") {
|
if (user.role === "member") {
|
||||||
return {
|
return {
|
||||||
redirect: {
|
redirect: {
|
||||||
permanent: true,
|
permanent: true,
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ export async function getServerSideProps(
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (user.rol === "user") {
|
if (user.role === "member") {
|
||||||
return {
|
return {
|
||||||
redirect: {
|
redirect: {
|
||||||
permanent: true,
|
permanent: true,
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ export async function getServerSideProps(
|
|||||||
const auth = await helpers.auth.get.fetch();
|
const auth = await helpers.auth.get.fetch();
|
||||||
await helpers.settings.isCloud.prefetch();
|
await helpers.settings.isCloud.prefetch();
|
||||||
|
|
||||||
if (auth.rol === "user") {
|
if (auth.role === "member") {
|
||||||
const user = await helpers.user.byAuthId.fetch({
|
const user = await helpers.user.byAuthId.fetch({
|
||||||
authId: auth.id,
|
authId: auth.id,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ export async function getServerSideProps(
|
|||||||
) {
|
) {
|
||||||
const { req, res } = ctx;
|
const { req, res } = ctx;
|
||||||
const { user, session } = await validateRequest(req, res);
|
const { user, session } = await validateRequest(req, res);
|
||||||
if (!user || user.rol === "user") {
|
if (!user || user.role === "member") {
|
||||||
return {
|
return {
|
||||||
redirect: {
|
redirect: {
|
||||||
permanent: true,
|
permanent: true,
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ export async function getServerSideProps(
|
|||||||
await helpers.project.all.prefetch();
|
await helpers.project.all.prefetch();
|
||||||
const auth = await helpers.auth.get.fetch();
|
const auth = await helpers.auth.get.fetch();
|
||||||
|
|
||||||
if (auth.rol === "user") {
|
if (auth.role === "member") {
|
||||||
const user = await helpers.user.byAuthId.fetch({
|
const user = await helpers.user.byAuthId.fetch({
|
||||||
authId: auth.id,
|
authId: auth.id,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ export async function getServerSideProps(
|
|||||||
await helpers.project.all.prefetch();
|
await helpers.project.all.prefetch();
|
||||||
const auth = await helpers.auth.get.fetch();
|
const auth = await helpers.auth.get.fetch();
|
||||||
|
|
||||||
if (auth.rol === "user") {
|
if (auth.role === "member") {
|
||||||
const user = await helpers.user.byAuthId.fetch({
|
const user = await helpers.user.byAuthId.fetch({
|
||||||
authId: auth.id,
|
authId: auth.id,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -13,10 +13,14 @@ import {
|
|||||||
FormMessage,
|
FormMessage,
|
||||||
} from "@/components/ui/form";
|
} from "@/components/ui/form";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
|
import { authClient } from "@/lib/auth";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import { api } from "@/utils/api";
|
import { api } from "@/utils/api";
|
||||||
import { IS_CLOUD, isAdminPresent, validateRequest } from "@dokploy/server";
|
import { IS_CLOUD, auth, isAdminPresent } from "@dokploy/server";
|
||||||
|
import { validateRequest } from "@dokploy/server/lib/auth";
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
|
import { Session, getSessionCookie } from "better-auth";
|
||||||
|
import { betterFetch } from "better-auth/react";
|
||||||
import type { GetServerSidePropsContext } from "next";
|
import type { GetServerSidePropsContext } from "next";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
@@ -56,17 +60,18 @@ interface Props {
|
|||||||
IS_CLOUD: boolean;
|
IS_CLOUD: boolean;
|
||||||
}
|
}
|
||||||
export default function Home({ IS_CLOUD }: Props) {
|
export default function Home({ IS_CLOUD }: Props) {
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
const [isError, setIsError] = useState(false);
|
||||||
|
const [error, setError] = useState<string | null>(null);
|
||||||
const [temp, setTemp] = useState<AuthResponse>({
|
const [temp, setTemp] = useState<AuthResponse>({
|
||||||
is2FAEnabled: false,
|
is2FAEnabled: false,
|
||||||
authId: "",
|
authId: "",
|
||||||
});
|
});
|
||||||
const { mutateAsync, isLoading, error, isError } =
|
|
||||||
api.auth.login.useMutation();
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const form = useForm<Login>({
|
const form = useForm<Login>({
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
email: "",
|
email: "siumauricio@hotmail.com",
|
||||||
password: "",
|
password: "Password123",
|
||||||
},
|
},
|
||||||
resolver: zodResolver(loginSchema),
|
resolver: zodResolver(loginSchema),
|
||||||
});
|
});
|
||||||
@@ -76,25 +81,49 @@ export default function Home({ IS_CLOUD }: Props) {
|
|||||||
}, [form, form.reset, form.formState.isSubmitSuccessful]);
|
}, [form, form.reset, form.formState.isSubmitSuccessful]);
|
||||||
|
|
||||||
const onSubmit = async (values: Login) => {
|
const onSubmit = async (values: Login) => {
|
||||||
await mutateAsync({
|
setIsLoading(true);
|
||||||
email: values.email.toLowerCase(),
|
const { data, error } = await authClient.signIn.email({
|
||||||
|
email: values.email,
|
||||||
password: values.password,
|
password: values.password,
|
||||||
})
|
});
|
||||||
.then((data) => {
|
|
||||||
if (data.is2FAEnabled) {
|
if (!error) {
|
||||||
setTemp(data);
|
// if (data) {
|
||||||
} else {
|
// setTemp(data);
|
||||||
|
// } else {
|
||||||
toast.success("Successfully signed in", {
|
toast.success("Successfully signed in", {
|
||||||
duration: 2000,
|
duration: 2000,
|
||||||
});
|
});
|
||||||
router.push("/dashboard/projects");
|
router.push("/dashboard/projects");
|
||||||
|
// }
|
||||||
|
} else {
|
||||||
|
setIsError(true);
|
||||||
|
setError(error.message ?? "Error to signup");
|
||||||
|
toast.error("Error to sign up", {
|
||||||
|
description: error.message,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
})
|
|
||||||
.catch(() => {
|
setIsLoading(false);
|
||||||
toast.error("Signin failed", {
|
// await mutateAsync({
|
||||||
duration: 2000,
|
// email: values.email.toLowerCase(),
|
||||||
});
|
// password: values.password,
|
||||||
});
|
// })
|
||||||
|
// .then((data) => {
|
||||||
|
// if (data.is2FAEnabled) {
|
||||||
|
// setTemp(data);
|
||||||
|
// } else {
|
||||||
|
// toast.success("Successfully signed in", {
|
||||||
|
// duration: 2000,
|
||||||
|
// });
|
||||||
|
// router.push("/dashboard/projects");
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// .catch(() => {
|
||||||
|
// toast.error("Signin failed", {
|
||||||
|
// duration: 2000,
|
||||||
|
// });
|
||||||
|
// });
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -111,7 +140,7 @@ export default function Home({ IS_CLOUD }: Props) {
|
|||||||
</div>
|
</div>
|
||||||
{isError && (
|
{isError && (
|
||||||
<AlertBlock type="error" className="my-2">
|
<AlertBlock type="error" className="my-2">
|
||||||
<span>{error?.message}</span>
|
<span>{error}</span>
|
||||||
</AlertBlock>
|
</AlertBlock>
|
||||||
)}
|
)}
|
||||||
<CardContent className="p-0">
|
<CardContent className="p-0">
|
||||||
@@ -203,8 +232,7 @@ Home.getLayout = (page: ReactElement) => {
|
|||||||
export async function getServerSideProps(context: GetServerSidePropsContext) {
|
export async function getServerSideProps(context: GetServerSidePropsContext) {
|
||||||
if (IS_CLOUD) {
|
if (IS_CLOUD) {
|
||||||
try {
|
try {
|
||||||
const { user } = await validateRequest(context.req, context.res);
|
const { user } = await validateRequest(context.req);
|
||||||
|
|
||||||
if (user) {
|
if (user) {
|
||||||
return {
|
return {
|
||||||
redirect: {
|
redirect: {
|
||||||
@@ -232,7 +260,7 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const { user } = await validateRequest(context.req, context.res);
|
const { user } = await validateRequest(context.req);
|
||||||
|
|
||||||
if (user) {
|
if (user) {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import {
|
|||||||
FormMessage,
|
FormMessage,
|
||||||
} from "@/components/ui/form";
|
} from "@/components/ui/form";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
|
import { authClient } from "@/lib/auth";
|
||||||
import { api } from "@/utils/api";
|
import { api } from "@/utils/api";
|
||||||
import { IS_CLOUD, isAdminPresent, validateRequest } from "@dokploy/server";
|
import { IS_CLOUD, isAdminPresent, validateRequest } from "@dokploy/server";
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
@@ -31,6 +32,9 @@ import { z } from "zod";
|
|||||||
|
|
||||||
const registerSchema = z
|
const registerSchema = z
|
||||||
.object({
|
.object({
|
||||||
|
name: z.string().min(1, {
|
||||||
|
message: "Name is required",
|
||||||
|
}),
|
||||||
email: z
|
email: z
|
||||||
.string()
|
.string()
|
||||||
.min(1, {
|
.min(1, {
|
||||||
@@ -79,9 +83,10 @@ const Register = ({ isCloud }: Props) => {
|
|||||||
|
|
||||||
const form = useForm<Register>({
|
const form = useForm<Register>({
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
email: "",
|
name: "Mauricio Siu",
|
||||||
password: "",
|
email: "user5@yopmail.com",
|
||||||
confirmPassword: "",
|
password: "Password1234",
|
||||||
|
confirmPassword: "Password1234",
|
||||||
},
|
},
|
||||||
resolver: zodResolver(registerSchema),
|
resolver: zodResolver(registerSchema),
|
||||||
});
|
});
|
||||||
@@ -91,19 +96,33 @@ const Register = ({ isCloud }: Props) => {
|
|||||||
}, [form, form.reset, form.formState.isSubmitSuccessful]);
|
}, [form, form.reset, form.formState.isSubmitSuccessful]);
|
||||||
|
|
||||||
const onSubmit = async (values: Register) => {
|
const onSubmit = async (values: Register) => {
|
||||||
await mutateAsync({
|
const { data, error } = await authClient.signUp.email({
|
||||||
email: values.email.toLowerCase(),
|
email: values.email,
|
||||||
password: values.password,
|
password: values.password,
|
||||||
})
|
name: values.name,
|
||||||
.then(() => {
|
|
||||||
toast.success("User registered successfuly", {
|
|
||||||
duration: 2000,
|
|
||||||
});
|
});
|
||||||
if (!isCloud) {
|
|
||||||
router.push("/");
|
// const { data, error } = await authClient.admin.createUser({
|
||||||
}
|
// name: values.name,
|
||||||
})
|
// email: values.email,
|
||||||
.catch((e) => e);
|
// password: values.password,
|
||||||
|
// role: "superAdmin",
|
||||||
|
// });
|
||||||
|
|
||||||
|
// consol/e.log(data, error);
|
||||||
|
// await mutateAsync({
|
||||||
|
// email: values.email.toLowerCase(),
|
||||||
|
// password: values.password,
|
||||||
|
// })
|
||||||
|
// .then(() => {
|
||||||
|
// toast.success("User registered successfuly", {
|
||||||
|
// duration: 2000,
|
||||||
|
// });
|
||||||
|
// if (!isCloud) {
|
||||||
|
// router.push("/");
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// .catch((e) => e);
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<div className="">
|
<div className="">
|
||||||
@@ -147,6 +166,19 @@ const Register = ({ isCloud }: Props) => {
|
|||||||
className="grid gap-4"
|
className="grid gap-4"
|
||||||
>
|
>
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="name"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>Name</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input placeholder="name" {...field} />
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name="email"
|
name="email"
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
|
|||||||
},
|
},
|
||||||
transformer: superjson,
|
transformer: superjson,
|
||||||
});
|
});
|
||||||
if (user.rol === "user") {
|
if (user.role === "member") {
|
||||||
const result = await helpers.user.byAuthId.fetch({
|
const result = await helpers.user.byAuthId.fetch({
|
||||||
authId: user.id,
|
authId: user.id,
|
||||||
});
|
});
|
||||||
|
|||||||
5
apps/dokploy/public/templates/frappe-hr.svg
Normal file
5
apps/dokploy/public/templates/frappe-hr.svg
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<svg width="101" height="101" viewBox="0 0 101 101" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M72.2667 0.422852H29.4096C13.63 0.422852 0.838135 13.2147 0.838135 28.9943V71.8514C0.838135 87.631 13.63 100.423 29.4096 100.423H72.2667C88.0463 100.423 100.838 87.631 100.838 71.8514V28.9943C100.838 13.2147 88.0463 0.422852 72.2667 0.422852Z" fill="#06B58B"/>
|
||||||
|
<path d="M31.1592 78.9948L26.3379 73.7091C33.0879 67.602 41.7664 64.209 50.8021 64.209C59.8378 64.209 68.5522 67.5662 75.2665 73.7091L70.4449 78.9948C65.0164 74.0662 58.0521 71.3518 50.8021 71.3518C43.5521 71.3518 36.5523 74.0662 31.1237 78.9948H31.1592Z" fill="white"/>
|
||||||
|
<path d="M54.1236 21.8516H33.1948V28.9944H54.1236C58.0521 28.9944 61.2664 32.2087 61.2664 36.1373V42.7801C61.2664 46.7087 58.0521 49.9229 54.1236 49.9229H47.4805C43.552 49.9229 40.3377 46.7087 40.3377 42.7801V38.28H33.1948V42.7801C33.1948 50.6729 39.5877 57.0658 47.4805 57.0658H54.1236C62.0164 57.0658 68.4093 50.6729 68.4093 42.7801V36.1373C68.4093 28.2444 62.0164 21.8516 54.1236 21.8516Z" fill="white"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.0 KiB |
@@ -6,19 +6,17 @@ import {
|
|||||||
apiRemoveUser,
|
apiRemoveUser,
|
||||||
apiUpdateAdmin,
|
apiUpdateAdmin,
|
||||||
apiUpdateWebServerMonitoring,
|
apiUpdateWebServerMonitoring,
|
||||||
users,
|
|
||||||
} from "@/server/db/schema";
|
} from "@/server/db/schema";
|
||||||
import {
|
import {
|
||||||
IS_CLOUD,
|
IS_CLOUD,
|
||||||
createInvitation,
|
createInvitation,
|
||||||
findAdminById,
|
|
||||||
findUserByAuthId,
|
findUserByAuthId,
|
||||||
findUserById,
|
findUserById,
|
||||||
getUserByToken,
|
getUserByToken,
|
||||||
removeUserByAuthId,
|
removeUserById,
|
||||||
setupWebMonitoring,
|
setupWebMonitoring,
|
||||||
updateAdmin,
|
|
||||||
updateAdminById,
|
updateAdminById,
|
||||||
|
updateUser,
|
||||||
} from "@dokploy/server";
|
} from "@dokploy/server";
|
||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import { eq } from "drizzle-orm";
|
import { eq } from "drizzle-orm";
|
||||||
@@ -32,7 +30,7 @@ import {
|
|||||||
|
|
||||||
export const adminRouter = createTRPCRouter({
|
export const adminRouter = createTRPCRouter({
|
||||||
one: adminProcedure.query(async ({ ctx }) => {
|
one: adminProcedure.query(async ({ ctx }) => {
|
||||||
const { sshPrivateKey, ...rest } = await findAdminById(ctx.user.adminId);
|
const { sshPrivateKey, ...rest } = await findUserById(ctx.user.id);
|
||||||
return {
|
return {
|
||||||
haveSSH: !!sshPrivateKey,
|
haveSSH: !!sshPrivateKey,
|
||||||
...rest,
|
...rest,
|
||||||
@@ -41,21 +39,21 @@ export const adminRouter = createTRPCRouter({
|
|||||||
update: adminProcedure
|
update: adminProcedure
|
||||||
.input(apiUpdateAdmin)
|
.input(apiUpdateAdmin)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
if (ctx.user.rol === "user") {
|
if (ctx.user.rol === "member") {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not allowed to update this admin",
|
message: "You are not allowed to update this admin",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const { authId } = await findAdminById(ctx.user.adminId);
|
const { id } = await findUserById(ctx.user.id);
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return updateAdmin(authId, input);
|
return updateAdmin(id, input);
|
||||||
}),
|
}),
|
||||||
createUserInvitation: adminProcedure
|
createUserInvitation: adminProcedure
|
||||||
.input(apiCreateUserInvitation)
|
.input(apiCreateUserInvitation)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
try {
|
try {
|
||||||
await createInvitation(input, ctx.user.adminId);
|
await createInvitation(input, ctx.user.id);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "BAD_REQUEST",
|
code: "BAD_REQUEST",
|
||||||
@@ -69,15 +67,16 @@ export const adminRouter = createTRPCRouter({
|
|||||||
.input(apiRemoveUser)
|
.input(apiRemoveUser)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
try {
|
try {
|
||||||
const user = await findUserByAuthId(input.authId);
|
const user = await findUserById(input.id);
|
||||||
|
|
||||||
if (user.adminId !== ctx.user.adminId) {
|
if (user.id !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not allowed to delete this user",
|
message: "You are not allowed to delete this user",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return await removeUserByAuthId(input.authId);
|
|
||||||
|
return await removeUserById(input.id);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "BAD_REQUEST",
|
code: "BAD_REQUEST",
|
||||||
@@ -95,20 +94,23 @@ export const adminRouter = createTRPCRouter({
|
|||||||
.input(apiAssignPermissions)
|
.input(apiAssignPermissions)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
try {
|
try {
|
||||||
const user = await findUserById(input.userId);
|
const user = await findUserById(input.id);
|
||||||
|
|
||||||
if (user.adminId !== ctx.user.adminId) {
|
if (user.id !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not allowed to assign permissions",
|
message: "You are not allowed to assign permissions",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
await db
|
await updateUser(user.id, {
|
||||||
.update(users)
|
|
||||||
.set({
|
|
||||||
...input,
|
...input,
|
||||||
})
|
});
|
||||||
.where(eq(users.userId, input.userId));
|
// await db
|
||||||
|
// .update(users)
|
||||||
|
// .set({
|
||||||
|
// ...input,
|
||||||
|
// })
|
||||||
|
// .where(eq(users.userId, input.userId));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
@@ -124,15 +126,15 @@ export const adminRouter = createTRPCRouter({
|
|||||||
message: "Feature disabled on cloud",
|
message: "Feature disabled on cloud",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const admin = await findAdminById(ctx.user.adminId);
|
const user = await findUserById(ctx.user.ownerId);
|
||||||
if (admin.adminId !== ctx.user.adminId) {
|
if (user.id !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to setup this server",
|
message: "You are not authorized to setup this server",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
await updateAdminById(admin.adminId, {
|
await updateUser(user.id, {
|
||||||
metricsConfig: {
|
metricsConfig: {
|
||||||
server: {
|
server: {
|
||||||
type: "Dokploy",
|
type: "Dokploy",
|
||||||
@@ -156,18 +158,19 @@ export const adminRouter = createTRPCRouter({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const currentServer = await setupWebMonitoring(admin.adminId);
|
|
||||||
|
const currentServer = await setupWebMonitoring(user.id);
|
||||||
return currentServer;
|
return currentServer;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
getMetricsToken: protectedProcedure.query(async ({ ctx }) => {
|
getMetricsToken: protectedProcedure.query(async ({ ctx }) => {
|
||||||
const admin = await findAdminById(ctx.user.adminId);
|
const user = await findUserById(ctx.user.ownerId);
|
||||||
return {
|
return {
|
||||||
serverIp: admin.serverIp,
|
serverIp: user.serverIp,
|
||||||
enabledFeatures: admin.enablePaidFeatures,
|
enabledFeatures: user.enablePaidFeatures,
|
||||||
metricsConfig: admin?.metricsConfig,
|
metricsConfig: user?.metricsConfig,
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|||||||
@@ -60,8 +60,8 @@ export const applicationRouter = createTRPCRouter({
|
|||||||
.input(apiCreateApplication)
|
.input(apiCreateApplication)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
try {
|
try {
|
||||||
if (ctx.user.rol === "user") {
|
if (ctx.user.rol === "member") {
|
||||||
await checkServiceAccess(ctx.user.authId, input.projectId, "create");
|
await checkServiceAccess(ctx.user.id, input.projectId, "create");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_CLOUD && !input.serverId) {
|
if (IS_CLOUD && !input.serverId) {
|
||||||
@@ -72,7 +72,7 @@ export const applicationRouter = createTRPCRouter({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const project = await findProjectById(input.projectId);
|
const project = await findProjectById(input.projectId);
|
||||||
if (project.adminId !== ctx.user.adminId) {
|
if (project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to access this project",
|
message: "You are not authorized to access this project",
|
||||||
@@ -80,8 +80,8 @@ export const applicationRouter = createTRPCRouter({
|
|||||||
}
|
}
|
||||||
const newApplication = await createApplication(input);
|
const newApplication = await createApplication(input);
|
||||||
|
|
||||||
if (ctx.user.rol === "user") {
|
if (ctx.user.rol === "member") {
|
||||||
await addNewService(ctx.user.authId, newApplication.applicationId);
|
await addNewService(ctx.user.id, newApplication.applicationId);
|
||||||
}
|
}
|
||||||
return newApplication;
|
return newApplication;
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
@@ -98,15 +98,11 @@ export const applicationRouter = createTRPCRouter({
|
|||||||
one: protectedProcedure
|
one: protectedProcedure
|
||||||
.input(apiFindOneApplication)
|
.input(apiFindOneApplication)
|
||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
if (ctx.user.rol === "user") {
|
if (ctx.user.rol === "member") {
|
||||||
await checkServiceAccess(
|
await checkServiceAccess(ctx.user.id, input.applicationId, "access");
|
||||||
ctx.user.authId,
|
|
||||||
input.applicationId,
|
|
||||||
"access",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
const application = await findApplicationById(input.applicationId);
|
const application = await findApplicationById(input.applicationId);
|
||||||
if (application.project.adminId !== ctx.user.adminId) {
|
if (application.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to access this application",
|
message: "You are not authorized to access this application",
|
||||||
@@ -119,7 +115,7 @@ export const applicationRouter = createTRPCRouter({
|
|||||||
.input(apiReloadApplication)
|
.input(apiReloadApplication)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const application = await findApplicationById(input.applicationId);
|
const application = await findApplicationById(input.applicationId);
|
||||||
if (application.project.adminId !== ctx.user.adminId) {
|
if (application.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to reload this application",
|
message: "You are not authorized to reload this application",
|
||||||
@@ -144,16 +140,12 @@ export const applicationRouter = createTRPCRouter({
|
|||||||
delete: protectedProcedure
|
delete: protectedProcedure
|
||||||
.input(apiFindOneApplication)
|
.input(apiFindOneApplication)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
if (ctx.user.rol === "user") {
|
if (ctx.user.rol === "member") {
|
||||||
await checkServiceAccess(
|
await checkServiceAccess(ctx.user.id, input.applicationId, "delete");
|
||||||
ctx.user.authId,
|
|
||||||
input.applicationId,
|
|
||||||
"delete",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
const application = await findApplicationById(input.applicationId);
|
const application = await findApplicationById(input.applicationId);
|
||||||
|
|
||||||
if (application.project.adminId !== ctx.user.adminId) {
|
if (application.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to delete this application",
|
message: "You are not authorized to delete this application",
|
||||||
@@ -194,7 +186,7 @@ export const applicationRouter = createTRPCRouter({
|
|||||||
.input(apiFindOneApplication)
|
.input(apiFindOneApplication)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const service = await findApplicationById(input.applicationId);
|
const service = await findApplicationById(input.applicationId);
|
||||||
if (service.project.adminId !== ctx.user.adminId) {
|
if (service.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to stop this application",
|
message: "You are not authorized to stop this application",
|
||||||
@@ -214,7 +206,7 @@ export const applicationRouter = createTRPCRouter({
|
|||||||
.input(apiFindOneApplication)
|
.input(apiFindOneApplication)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const service = await findApplicationById(input.applicationId);
|
const service = await findApplicationById(input.applicationId);
|
||||||
if (service.project.adminId !== ctx.user.adminId) {
|
if (service.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to start this application",
|
message: "You are not authorized to start this application",
|
||||||
@@ -235,7 +227,7 @@ export const applicationRouter = createTRPCRouter({
|
|||||||
.input(apiFindOneApplication)
|
.input(apiFindOneApplication)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const application = await findApplicationById(input.applicationId);
|
const application = await findApplicationById(input.applicationId);
|
||||||
if (application.project.adminId !== ctx.user.adminId) {
|
if (application.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to redeploy this application",
|
message: "You are not authorized to redeploy this application",
|
||||||
@@ -268,7 +260,7 @@ export const applicationRouter = createTRPCRouter({
|
|||||||
.input(apiSaveEnvironmentVariables)
|
.input(apiSaveEnvironmentVariables)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const application = await findApplicationById(input.applicationId);
|
const application = await findApplicationById(input.applicationId);
|
||||||
if (application.project.adminId !== ctx.user.adminId) {
|
if (application.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to save this environment",
|
message: "You are not authorized to save this environment",
|
||||||
@@ -284,7 +276,7 @@ export const applicationRouter = createTRPCRouter({
|
|||||||
.input(apiSaveBuildType)
|
.input(apiSaveBuildType)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const application = await findApplicationById(input.applicationId);
|
const application = await findApplicationById(input.applicationId);
|
||||||
if (application.project.adminId !== ctx.user.adminId) {
|
if (application.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to save this build type",
|
message: "You are not authorized to save this build type",
|
||||||
@@ -305,7 +297,7 @@ export const applicationRouter = createTRPCRouter({
|
|||||||
.input(apiSaveGithubProvider)
|
.input(apiSaveGithubProvider)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const application = await findApplicationById(input.applicationId);
|
const application = await findApplicationById(input.applicationId);
|
||||||
if (application.project.adminId !== ctx.user.adminId) {
|
if (application.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to save this github provider",
|
message: "You are not authorized to save this github provider",
|
||||||
@@ -327,7 +319,7 @@ export const applicationRouter = createTRPCRouter({
|
|||||||
.input(apiSaveGitlabProvider)
|
.input(apiSaveGitlabProvider)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const application = await findApplicationById(input.applicationId);
|
const application = await findApplicationById(input.applicationId);
|
||||||
if (application.project.adminId !== ctx.user.adminId) {
|
if (application.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to save this gitlab provider",
|
message: "You are not authorized to save this gitlab provider",
|
||||||
@@ -351,7 +343,7 @@ export const applicationRouter = createTRPCRouter({
|
|||||||
.input(apiSaveBitbucketProvider)
|
.input(apiSaveBitbucketProvider)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const application = await findApplicationById(input.applicationId);
|
const application = await findApplicationById(input.applicationId);
|
||||||
if (application.project.adminId !== ctx.user.adminId) {
|
if (application.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to save this bitbucket provider",
|
message: "You are not authorized to save this bitbucket provider",
|
||||||
@@ -373,7 +365,7 @@ export const applicationRouter = createTRPCRouter({
|
|||||||
.input(apiSaveDockerProvider)
|
.input(apiSaveDockerProvider)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const application = await findApplicationById(input.applicationId);
|
const application = await findApplicationById(input.applicationId);
|
||||||
if (application.project.adminId !== ctx.user.adminId) {
|
if (application.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to save this docker provider",
|
message: "You are not authorized to save this docker provider",
|
||||||
@@ -394,7 +386,7 @@ export const applicationRouter = createTRPCRouter({
|
|||||||
.input(apiSaveGitProvider)
|
.input(apiSaveGitProvider)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const application = await findApplicationById(input.applicationId);
|
const application = await findApplicationById(input.applicationId);
|
||||||
if (application.project.adminId !== ctx.user.adminId) {
|
if (application.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to save this git provider",
|
message: "You are not authorized to save this git provider",
|
||||||
@@ -415,7 +407,7 @@ export const applicationRouter = createTRPCRouter({
|
|||||||
.input(apiFindOneApplication)
|
.input(apiFindOneApplication)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const application = await findApplicationById(input.applicationId);
|
const application = await findApplicationById(input.applicationId);
|
||||||
if (application.project.adminId !== ctx.user.adminId) {
|
if (application.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to mark this application as running",
|
message: "You are not authorized to mark this application as running",
|
||||||
@@ -427,7 +419,7 @@ export const applicationRouter = createTRPCRouter({
|
|||||||
.input(apiUpdateApplication)
|
.input(apiUpdateApplication)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const application = await findApplicationById(input.applicationId);
|
const application = await findApplicationById(input.applicationId);
|
||||||
if (application.project.adminId !== ctx.user.adminId) {
|
if (application.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to update this application",
|
message: "You are not authorized to update this application",
|
||||||
@@ -451,7 +443,7 @@ export const applicationRouter = createTRPCRouter({
|
|||||||
.input(apiFindOneApplication)
|
.input(apiFindOneApplication)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const application = await findApplicationById(input.applicationId);
|
const application = await findApplicationById(input.applicationId);
|
||||||
if (application.project.adminId !== ctx.user.adminId) {
|
if (application.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to refresh this application",
|
message: "You are not authorized to refresh this application",
|
||||||
@@ -466,7 +458,7 @@ export const applicationRouter = createTRPCRouter({
|
|||||||
.input(apiFindOneApplication)
|
.input(apiFindOneApplication)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const application = await findApplicationById(input.applicationId);
|
const application = await findApplicationById(input.applicationId);
|
||||||
if (application.project.adminId !== ctx.user.adminId) {
|
if (application.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to deploy this application",
|
message: "You are not authorized to deploy this application",
|
||||||
@@ -500,7 +492,7 @@ export const applicationRouter = createTRPCRouter({
|
|||||||
.input(apiFindOneApplication)
|
.input(apiFindOneApplication)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const application = await findApplicationById(input.applicationId);
|
const application = await findApplicationById(input.applicationId);
|
||||||
if (application.project.adminId !== ctx.user.adminId) {
|
if (application.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to clean this application",
|
message: "You are not authorized to clean this application",
|
||||||
@@ -513,7 +505,7 @@ export const applicationRouter = createTRPCRouter({
|
|||||||
.input(apiFindOneApplication)
|
.input(apiFindOneApplication)
|
||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
const application = await findApplicationById(input.applicationId);
|
const application = await findApplicationById(input.applicationId);
|
||||||
if (application.project.adminId !== ctx.user.adminId) {
|
if (application.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to read this application",
|
message: "You are not authorized to read this application",
|
||||||
@@ -548,7 +540,7 @@ export const applicationRouter = createTRPCRouter({
|
|||||||
|
|
||||||
const app = await findApplicationById(input.applicationId as string);
|
const app = await findApplicationById(input.applicationId as string);
|
||||||
|
|
||||||
if (app.project.adminId !== ctx.user.adminId) {
|
if (app.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to deploy this application",
|
message: "You are not authorized to deploy this application",
|
||||||
@@ -590,7 +582,7 @@ export const applicationRouter = createTRPCRouter({
|
|||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const application = await findApplicationById(input.applicationId);
|
const application = await findApplicationById(input.applicationId);
|
||||||
|
|
||||||
if (application.project.adminId !== ctx.user.adminId) {
|
if (application.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to update this application",
|
message: "You are not authorized to update this application",
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
apiVerify2FA,
|
apiVerify2FA,
|
||||||
apiVerifyLogin2FA,
|
apiVerifyLogin2FA,
|
||||||
auth,
|
auth,
|
||||||
|
member,
|
||||||
} from "@/server/db/schema";
|
} from "@/server/db/schema";
|
||||||
import { WEBSITE_URL } from "@/server/utils/stripe";
|
import { WEBSITE_URL } from "@/server/utils/stripe";
|
||||||
import {
|
import {
|
||||||
@@ -16,22 +17,23 @@ import {
|
|||||||
createUser,
|
createUser,
|
||||||
findAuthByEmail,
|
findAuthByEmail,
|
||||||
findAuthById,
|
findAuthById,
|
||||||
|
findUserById,
|
||||||
generate2FASecret,
|
generate2FASecret,
|
||||||
getUserByToken,
|
getUserByToken,
|
||||||
lucia,
|
lucia,
|
||||||
luciaToken,
|
luciaToken,
|
||||||
removeAdminByAuthId,
|
removeAdminByAuthId,
|
||||||
removeUserByAuthId,
|
|
||||||
sendDiscordNotification,
|
sendDiscordNotification,
|
||||||
sendEmailNotification,
|
sendEmailNotification,
|
||||||
updateAuthById,
|
updateAuthById,
|
||||||
|
updateUser,
|
||||||
validateRequest,
|
validateRequest,
|
||||||
verify2FA,
|
verify2FA,
|
||||||
} from "@dokploy/server";
|
} from "@dokploy/server";
|
||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import * as bcrypt from "bcrypt";
|
import * as bcrypt from "bcrypt";
|
||||||
import { isBefore } from "date-fns";
|
import { isBefore } from "date-fns";
|
||||||
import { eq } from "drizzle-orm";
|
import { and, eq } from "drizzle-orm";
|
||||||
import { nanoid } from "nanoid";
|
import { nanoid } from "nanoid";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { db } from "../../db";
|
import { db } from "../../db";
|
||||||
@@ -169,8 +171,17 @@ export const authRouter = createTRPCRouter({
|
|||||||
}),
|
}),
|
||||||
|
|
||||||
get: protectedProcedure.query(async ({ ctx }) => {
|
get: protectedProcedure.query(async ({ ctx }) => {
|
||||||
const auth = await findAuthById(ctx.user.authId);
|
const memberResult = await db.query.member.findFirst({
|
||||||
return auth;
|
where: and(
|
||||||
|
eq(member.userId, ctx.user.id),
|
||||||
|
eq(member.organizationId, ctx.session?.activeOrganizationId || ""),
|
||||||
|
),
|
||||||
|
with: {
|
||||||
|
user: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return memberResult;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
logout: protectedProcedure.mutation(async ({ ctx }) => {
|
logout: protectedProcedure.mutation(async ({ ctx }) => {
|
||||||
@@ -243,7 +254,7 @@ export const authRouter = createTRPCRouter({
|
|||||||
await lucia.invalidateSession(session.id);
|
await lucia.invalidateSession(session.id);
|
||||||
res.setHeader("Set-Cookie", lucia.createBlankSessionCookie().serialize());
|
res.setHeader("Set-Cookie", lucia.createBlankSessionCookie().serialize());
|
||||||
|
|
||||||
if (ctx.user.rol === "admin") {
|
if (ctx.user.rol === "owner") {
|
||||||
await removeAdminByAuthId(ctx.user.authId);
|
await removeAdminByAuthId(ctx.user.authId);
|
||||||
} else {
|
} else {
|
||||||
await removeUserByAuthId(ctx.user.authId);
|
await removeUserByAuthId(ctx.user.authId);
|
||||||
@@ -253,19 +264,18 @@ export const authRouter = createTRPCRouter({
|
|||||||
}),
|
}),
|
||||||
|
|
||||||
generateToken: protectedProcedure.mutation(async ({ ctx, input }) => {
|
generateToken: protectedProcedure.mutation(async ({ ctx, input }) => {
|
||||||
const auth = await findAuthById(ctx.user.authId);
|
const auth = await findUserById(ctx.user.id);
|
||||||
|
console.log(auth);
|
||||||
|
|
||||||
if (auth.token) {
|
if (auth.token) {
|
||||||
await luciaToken.invalidateSession(auth.token);
|
await luciaToken.invalidateSession(auth.token);
|
||||||
}
|
}
|
||||||
const session = await luciaToken.createSession(auth?.id || "", {
|
// const session = await luciaToken.createSession(auth?.id || "", {
|
||||||
expiresIn: 60 * 60 * 24 * 30,
|
// expiresIn: 60 * 60 * 24 * 30,
|
||||||
});
|
// });
|
||||||
|
// await updateUser(auth.id, {
|
||||||
await updateAuthById(auth.id, {
|
// token: session.id,
|
||||||
token: session.id,
|
// });
|
||||||
});
|
|
||||||
|
|
||||||
return auth;
|
return auth;
|
||||||
}),
|
}),
|
||||||
verifyToken: protectedProcedure.mutation(async () => {
|
verifyToken: protectedProcedure.mutation(async () => {
|
||||||
@@ -277,7 +287,7 @@ export const authRouter = createTRPCRouter({
|
|||||||
}),
|
}),
|
||||||
|
|
||||||
generate2FASecret: protectedProcedure.query(async ({ ctx }) => {
|
generate2FASecret: protectedProcedure.query(async ({ ctx }) => {
|
||||||
return await generate2FASecret(ctx.user.authId);
|
return await generate2FASecret(ctx.user.id);
|
||||||
}),
|
}),
|
||||||
verify2FASetup: protectedProcedure
|
verify2FASetup: protectedProcedure
|
||||||
.input(apiVerify2FA)
|
.input(apiVerify2FA)
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ export const bitbucketRouter = createTRPCRouter({
|
|||||||
.input(apiCreateBitbucket)
|
.input(apiCreateBitbucket)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
try {
|
try {
|
||||||
return await createBitbucket(input, ctx.user.adminId);
|
return await createBitbucket(input, ctx.user.ownerId);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "BAD_REQUEST",
|
code: "BAD_REQUEST",
|
||||||
@@ -38,7 +38,7 @@ export const bitbucketRouter = createTRPCRouter({
|
|||||||
const bitbucketProvider = await findBitbucketById(input.bitbucketId);
|
const bitbucketProvider = await findBitbucketById(input.bitbucketId);
|
||||||
if (
|
if (
|
||||||
IS_CLOUD &&
|
IS_CLOUD &&
|
||||||
bitbucketProvider.gitProvider.adminId !== ctx.user.adminId
|
bitbucketProvider.gitProvider.userId !== ctx.user.ownerId
|
||||||
) {
|
) {
|
||||||
//TODO: Remove this line when the cloud version is ready
|
//TODO: Remove this line when the cloud version is ready
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
@@ -61,7 +61,7 @@ export const bitbucketRouter = createTRPCRouter({
|
|||||||
if (IS_CLOUD) {
|
if (IS_CLOUD) {
|
||||||
// TODO: mAyBe a rEfaCtoR 🤫
|
// TODO: mAyBe a rEfaCtoR 🤫
|
||||||
result = result.filter(
|
result = result.filter(
|
||||||
(provider) => provider.gitProvider.adminId === ctx.user.adminId,
|
(provider) => provider.gitProvider.userId === ctx.user.ownerId,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@@ -73,7 +73,7 @@ export const bitbucketRouter = createTRPCRouter({
|
|||||||
const bitbucketProvider = await findBitbucketById(input.bitbucketId);
|
const bitbucketProvider = await findBitbucketById(input.bitbucketId);
|
||||||
if (
|
if (
|
||||||
IS_CLOUD &&
|
IS_CLOUD &&
|
||||||
bitbucketProvider.gitProvider.adminId !== ctx.user.adminId
|
bitbucketProvider.gitProvider.userId !== ctx.user.ownerId
|
||||||
) {
|
) {
|
||||||
//TODO: Remove this line when the cloud version is ready
|
//TODO: Remove this line when the cloud version is ready
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
@@ -91,7 +91,7 @@ export const bitbucketRouter = createTRPCRouter({
|
|||||||
);
|
);
|
||||||
if (
|
if (
|
||||||
IS_CLOUD &&
|
IS_CLOUD &&
|
||||||
bitbucketProvider.gitProvider.adminId !== ctx.user.adminId
|
bitbucketProvider.gitProvider.userId !== ctx.user.ownerId
|
||||||
) {
|
) {
|
||||||
//TODO: Remove this line when the cloud version is ready
|
//TODO: Remove this line when the cloud version is ready
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
@@ -108,7 +108,7 @@ export const bitbucketRouter = createTRPCRouter({
|
|||||||
const bitbucketProvider = await findBitbucketById(input.bitbucketId);
|
const bitbucketProvider = await findBitbucketById(input.bitbucketId);
|
||||||
if (
|
if (
|
||||||
IS_CLOUD &&
|
IS_CLOUD &&
|
||||||
bitbucketProvider.gitProvider.adminId !== ctx.user.adminId
|
bitbucketProvider.gitProvider.userId !== ctx.user.ownerId
|
||||||
) {
|
) {
|
||||||
//TODO: Remove this line when the cloud version is ready
|
//TODO: Remove this line when the cloud version is ready
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
@@ -132,7 +132,7 @@ export const bitbucketRouter = createTRPCRouter({
|
|||||||
const bitbucketProvider = await findBitbucketById(input.bitbucketId);
|
const bitbucketProvider = await findBitbucketById(input.bitbucketId);
|
||||||
if (
|
if (
|
||||||
IS_CLOUD &&
|
IS_CLOUD &&
|
||||||
bitbucketProvider.gitProvider.adminId !== ctx.user.adminId
|
bitbucketProvider.gitProvider.userId !== ctx.user.ownerId
|
||||||
) {
|
) {
|
||||||
//TODO: Remove this line when the cloud version is ready
|
//TODO: Remove this line when the cloud version is ready
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
@@ -142,7 +142,7 @@ export const bitbucketRouter = createTRPCRouter({
|
|||||||
}
|
}
|
||||||
return await updateBitbucket(input.bitbucketId, {
|
return await updateBitbucket(input.bitbucketId, {
|
||||||
...input,
|
...input,
|
||||||
adminId: ctx.user.adminId,
|
userId: ctx.user.ownerId,
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -25,14 +25,14 @@ export const certificateRouter = createTRPCRouter({
|
|||||||
message: "Please set a server to create a certificate",
|
message: "Please set a server to create a certificate",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return await createCertificate(input, ctx.user.adminId);
|
return await createCertificate(input, ctx.user.ownerId);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
one: adminProcedure
|
one: adminProcedure
|
||||||
.input(apiFindCertificate)
|
.input(apiFindCertificate)
|
||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
const certificates = await findCertificateById(input.certificateId);
|
const certificates = await findCertificateById(input.certificateId);
|
||||||
if (IS_CLOUD && certificates.adminId !== ctx.user.adminId) {
|
if (IS_CLOUD && certificates.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not allowed to access this certificate",
|
message: "You are not allowed to access this certificate",
|
||||||
@@ -44,7 +44,7 @@ export const certificateRouter = createTRPCRouter({
|
|||||||
.input(apiFindCertificate)
|
.input(apiFindCertificate)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const certificates = await findCertificateById(input.certificateId);
|
const certificates = await findCertificateById(input.certificateId);
|
||||||
if (IS_CLOUD && certificates.adminId !== ctx.user.adminId) {
|
if (IS_CLOUD && certificates.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not allowed to delete this certificate",
|
message: "You are not allowed to delete this certificate",
|
||||||
@@ -56,7 +56,7 @@ export const certificateRouter = createTRPCRouter({
|
|||||||
all: adminProcedure.query(async ({ ctx }) => {
|
all: adminProcedure.query(async ({ ctx }) => {
|
||||||
return await db.query.certificates.findMany({
|
return await db.query.certificates.findMany({
|
||||||
// TODO: Remove this line when the cloud version is ready
|
// TODO: Remove this line when the cloud version is ready
|
||||||
...(IS_CLOUD && { where: eq(certificates.adminId, ctx.user.adminId) }),
|
...(IS_CLOUD && { where: eq(certificates.userId, ctx.user.ownerId) }),
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -44,8 +44,10 @@ import {
|
|||||||
findDomainsByComposeId,
|
findDomainsByComposeId,
|
||||||
findProjectById,
|
findProjectById,
|
||||||
findServerById,
|
findServerById,
|
||||||
|
findUserById,
|
||||||
loadServices,
|
loadServices,
|
||||||
randomizeComposeFile,
|
randomizeComposeFile,
|
||||||
|
randomizeIsolatedDeploymentComposeFile,
|
||||||
removeCompose,
|
removeCompose,
|
||||||
removeComposeDirectory,
|
removeComposeDirectory,
|
||||||
removeDeploymentsByComposeId,
|
removeDeploymentsByComposeId,
|
||||||
@@ -59,8 +61,8 @@ export const composeRouter = createTRPCRouter({
|
|||||||
.input(apiCreateCompose)
|
.input(apiCreateCompose)
|
||||||
.mutation(async ({ ctx, input }) => {
|
.mutation(async ({ ctx, input }) => {
|
||||||
try {
|
try {
|
||||||
if (ctx.user.rol === "user") {
|
if (ctx.user.rol === "member") {
|
||||||
await checkServiceAccess(ctx.user.authId, input.projectId, "create");
|
await checkServiceAccess(ctx.user.id, input.projectId, "create");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_CLOUD && !input.serverId) {
|
if (IS_CLOUD && !input.serverId) {
|
||||||
@@ -70,7 +72,7 @@ export const composeRouter = createTRPCRouter({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
const project = await findProjectById(input.projectId);
|
const project = await findProjectById(input.projectId);
|
||||||
if (project.adminId !== ctx.user.adminId) {
|
if (project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to access this project",
|
message: "You are not authorized to access this project",
|
||||||
@@ -78,8 +80,8 @@ export const composeRouter = createTRPCRouter({
|
|||||||
}
|
}
|
||||||
const newService = await createCompose(input);
|
const newService = await createCompose(input);
|
||||||
|
|
||||||
if (ctx.user.rol === "user") {
|
if (ctx.user.rol === "member") {
|
||||||
await addNewService(ctx.user.authId, newService.composeId);
|
await addNewService(ctx.user.id, newService.composeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return newService;
|
return newService;
|
||||||
@@ -91,12 +93,12 @@ export const composeRouter = createTRPCRouter({
|
|||||||
one: protectedProcedure
|
one: protectedProcedure
|
||||||
.input(apiFindCompose)
|
.input(apiFindCompose)
|
||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
if (ctx.user.rol === "user") {
|
if (ctx.user.rol === "member") {
|
||||||
await checkServiceAccess(ctx.user.authId, input.composeId, "access");
|
await checkServiceAccess(ctx.user.id, input.composeId, "access");
|
||||||
}
|
}
|
||||||
|
|
||||||
const compose = await findComposeById(input.composeId);
|
const compose = await findComposeById(input.composeId);
|
||||||
if (compose.project.adminId !== ctx.user.adminId) {
|
if (compose.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to access this compose",
|
message: "You are not authorized to access this compose",
|
||||||
@@ -109,7 +111,7 @@ export const composeRouter = createTRPCRouter({
|
|||||||
.input(apiUpdateCompose)
|
.input(apiUpdateCompose)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const compose = await findComposeById(input.composeId);
|
const compose = await findComposeById(input.composeId);
|
||||||
if (compose.project.adminId !== ctx.user.adminId) {
|
if (compose.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to update this compose",
|
message: "You are not authorized to update this compose",
|
||||||
@@ -120,12 +122,12 @@ export const composeRouter = createTRPCRouter({
|
|||||||
delete: protectedProcedure
|
delete: protectedProcedure
|
||||||
.input(apiDeleteCompose)
|
.input(apiDeleteCompose)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
if (ctx.user.rol === "user") {
|
if (ctx.user.rol === "member") {
|
||||||
await checkServiceAccess(ctx.user.authId, input.composeId, "delete");
|
await checkServiceAccess(ctx.user.id, input.composeId, "delete");
|
||||||
}
|
}
|
||||||
const composeResult = await findComposeById(input.composeId);
|
const composeResult = await findComposeById(input.composeId);
|
||||||
|
|
||||||
if (composeResult.project.adminId !== ctx.user.adminId) {
|
if (composeResult.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to delete this compose",
|
message: "You are not authorized to delete this compose",
|
||||||
@@ -156,7 +158,7 @@ export const composeRouter = createTRPCRouter({
|
|||||||
.input(apiFindCompose)
|
.input(apiFindCompose)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const compose = await findComposeById(input.composeId);
|
const compose = await findComposeById(input.composeId);
|
||||||
if (compose.project.adminId !== ctx.user.adminId) {
|
if (compose.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to clean this compose",
|
message: "You are not authorized to clean this compose",
|
||||||
@@ -169,7 +171,7 @@ export const composeRouter = createTRPCRouter({
|
|||||||
.input(apiFetchServices)
|
.input(apiFetchServices)
|
||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
const compose = await findComposeById(input.composeId);
|
const compose = await findComposeById(input.composeId);
|
||||||
if (compose.project.adminId !== ctx.user.adminId) {
|
if (compose.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to load this compose",
|
message: "You are not authorized to load this compose",
|
||||||
@@ -183,7 +185,7 @@ export const composeRouter = createTRPCRouter({
|
|||||||
try {
|
try {
|
||||||
const compose = await findComposeById(input.composeId);
|
const compose = await findComposeById(input.composeId);
|
||||||
|
|
||||||
if (compose.project.adminId !== ctx.user.adminId) {
|
if (compose.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to fetch this compose",
|
message: "You are not authorized to fetch this compose",
|
||||||
@@ -208,7 +210,7 @@ export const composeRouter = createTRPCRouter({
|
|||||||
.input(apiRandomizeCompose)
|
.input(apiRandomizeCompose)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const compose = await findComposeById(input.composeId);
|
const compose = await findComposeById(input.composeId);
|
||||||
if (compose.project.adminId !== ctx.user.adminId) {
|
if (compose.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to randomize this compose",
|
message: "You are not authorized to randomize this compose",
|
||||||
@@ -216,11 +218,26 @@ export const composeRouter = createTRPCRouter({
|
|||||||
}
|
}
|
||||||
return await randomizeComposeFile(input.composeId, input.suffix);
|
return await randomizeComposeFile(input.composeId, input.suffix);
|
||||||
}),
|
}),
|
||||||
|
isolatedDeployment: protectedProcedure
|
||||||
|
.input(apiRandomizeCompose)
|
||||||
|
.mutation(async ({ input, ctx }) => {
|
||||||
|
const compose = await findComposeById(input.composeId);
|
||||||
|
if (compose.project.userId !== ctx.user.ownerId) {
|
||||||
|
throw new TRPCError({
|
||||||
|
code: "UNAUTHORIZED",
|
||||||
|
message: "You are not authorized to randomize this compose",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return await randomizeIsolatedDeploymentComposeFile(
|
||||||
|
input.composeId,
|
||||||
|
input.suffix,
|
||||||
|
);
|
||||||
|
}),
|
||||||
getConvertedCompose: protectedProcedure
|
getConvertedCompose: protectedProcedure
|
||||||
.input(apiFindCompose)
|
.input(apiFindCompose)
|
||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
const compose = await findComposeById(input.composeId);
|
const compose = await findComposeById(input.composeId);
|
||||||
if (compose.project.adminId !== ctx.user.adminId) {
|
if (compose.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to get this compose",
|
message: "You are not authorized to get this compose",
|
||||||
@@ -238,7 +255,7 @@ export const composeRouter = createTRPCRouter({
|
|||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const compose = await findComposeById(input.composeId);
|
const compose = await findComposeById(input.composeId);
|
||||||
|
|
||||||
if (compose.project.adminId !== ctx.user.adminId) {
|
if (compose.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to deploy this compose",
|
message: "You are not authorized to deploy this compose",
|
||||||
@@ -271,7 +288,7 @@ export const composeRouter = createTRPCRouter({
|
|||||||
.input(apiFindCompose)
|
.input(apiFindCompose)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const compose = await findComposeById(input.composeId);
|
const compose = await findComposeById(input.composeId);
|
||||||
if (compose.project.adminId !== ctx.user.adminId) {
|
if (compose.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to redeploy this compose",
|
message: "You are not authorized to redeploy this compose",
|
||||||
@@ -303,7 +320,7 @@ export const composeRouter = createTRPCRouter({
|
|||||||
.input(apiFindCompose)
|
.input(apiFindCompose)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const compose = await findComposeById(input.composeId);
|
const compose = await findComposeById(input.composeId);
|
||||||
if (compose.project.adminId !== ctx.user.adminId) {
|
if (compose.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to stop this compose",
|
message: "You are not authorized to stop this compose",
|
||||||
@@ -317,7 +334,7 @@ export const composeRouter = createTRPCRouter({
|
|||||||
.input(apiFindCompose)
|
.input(apiFindCompose)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const compose = await findComposeById(input.composeId);
|
const compose = await findComposeById(input.composeId);
|
||||||
if (compose.project.adminId !== ctx.user.adminId) {
|
if (compose.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to stop this compose",
|
message: "You are not authorized to stop this compose",
|
||||||
@@ -332,7 +349,7 @@ export const composeRouter = createTRPCRouter({
|
|||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
const compose = await findComposeById(input.composeId);
|
const compose = await findComposeById(input.composeId);
|
||||||
|
|
||||||
if (compose.project.adminId !== ctx.user.adminId) {
|
if (compose.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to get this compose",
|
message: "You are not authorized to get this compose",
|
||||||
@@ -345,7 +362,7 @@ export const composeRouter = createTRPCRouter({
|
|||||||
.input(apiFindCompose)
|
.input(apiFindCompose)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const compose = await findComposeById(input.composeId);
|
const compose = await findComposeById(input.composeId);
|
||||||
if (compose.project.adminId !== ctx.user.adminId) {
|
if (compose.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to refresh this compose",
|
message: "You are not authorized to refresh this compose",
|
||||||
@@ -359,8 +376,8 @@ export const composeRouter = createTRPCRouter({
|
|||||||
deployTemplate: protectedProcedure
|
deployTemplate: protectedProcedure
|
||||||
.input(apiCreateComposeByTemplate)
|
.input(apiCreateComposeByTemplate)
|
||||||
.mutation(async ({ ctx, input }) => {
|
.mutation(async ({ ctx, input }) => {
|
||||||
if (ctx.user.rol === "user") {
|
if (ctx.user.rol === "member") {
|
||||||
await checkServiceAccess(ctx.user.authId, input.projectId, "create");
|
await checkServiceAccess(ctx.user.id, input.projectId, "create");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_CLOUD && !input.serverId) {
|
if (IS_CLOUD && !input.serverId) {
|
||||||
@@ -374,7 +391,7 @@ export const composeRouter = createTRPCRouter({
|
|||||||
|
|
||||||
const generate = await loadTemplateModule(input.id as TemplatesKeys);
|
const generate = await loadTemplateModule(input.id as TemplatesKeys);
|
||||||
|
|
||||||
const admin = await findAdminById(ctx.user.adminId);
|
const admin = await findUserById(ctx.user.ownerId);
|
||||||
let serverIp = admin.serverIp || "127.0.0.1";
|
let serverIp = admin.serverIp || "127.0.0.1";
|
||||||
|
|
||||||
const project = await findProjectById(input.projectId);
|
const project = await findProjectById(input.projectId);
|
||||||
@@ -399,10 +416,11 @@ export const composeRouter = createTRPCRouter({
|
|||||||
name: input.id,
|
name: input.id,
|
||||||
sourceType: "raw",
|
sourceType: "raw",
|
||||||
appName: `${projectName}-${generatePassword(6)}`,
|
appName: `${projectName}-${generatePassword(6)}`,
|
||||||
|
isolatedDeployment: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (ctx.user.rol === "user") {
|
if (ctx.user.rol === "member") {
|
||||||
await addNewService(ctx.user.authId, compose.composeId);
|
await addNewService(ctx.user.id, compose.composeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mounts && mounts?.length > 0) {
|
if (mounts && mounts?.length > 0) {
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export const deploymentRouter = createTRPCRouter({
|
|||||||
.input(apiFindAllByApplication)
|
.input(apiFindAllByApplication)
|
||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
const application = await findApplicationById(input.applicationId);
|
const application = await findApplicationById(input.applicationId);
|
||||||
if (application.project.adminId !== ctx.user.adminId) {
|
if (application.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to access this application",
|
message: "You are not authorized to access this application",
|
||||||
@@ -32,7 +32,7 @@ export const deploymentRouter = createTRPCRouter({
|
|||||||
.input(apiFindAllByCompose)
|
.input(apiFindAllByCompose)
|
||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
const compose = await findComposeById(input.composeId);
|
const compose = await findComposeById(input.composeId);
|
||||||
if (compose.project.adminId !== ctx.user.adminId) {
|
if (compose.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to access this compose",
|
message: "You are not authorized to access this compose",
|
||||||
@@ -44,7 +44,7 @@ export const deploymentRouter = createTRPCRouter({
|
|||||||
.input(apiFindAllByServer)
|
.input(apiFindAllByServer)
|
||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
const server = await findServerById(input.serverId);
|
const server = await findServerById(input.serverId);
|
||||||
if (server.adminId !== ctx.user.adminId) {
|
if (server.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to access this server",
|
message: "You are not authorized to access this server",
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ export const destinationRouter = createTRPCRouter({
|
|||||||
.input(apiCreateDestination)
|
.input(apiCreateDestination)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
try {
|
try {
|
||||||
return await createDestintation(input, ctx.user.adminId);
|
return await createDestintation(input, ctx.user.ownerId);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "BAD_REQUEST",
|
code: "BAD_REQUEST",
|
||||||
@@ -84,7 +84,7 @@ export const destinationRouter = createTRPCRouter({
|
|||||||
.input(apiFindOneDestination)
|
.input(apiFindOneDestination)
|
||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
const destination = await findDestinationById(input.destinationId);
|
const destination = await findDestinationById(input.destinationId);
|
||||||
if (destination.adminId !== ctx.user.adminId) {
|
if (destination.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not allowed to access this destination",
|
message: "You are not allowed to access this destination",
|
||||||
@@ -94,7 +94,7 @@ export const destinationRouter = createTRPCRouter({
|
|||||||
}),
|
}),
|
||||||
all: protectedProcedure.query(async ({ ctx }) => {
|
all: protectedProcedure.query(async ({ ctx }) => {
|
||||||
return await db.query.destinations.findMany({
|
return await db.query.destinations.findMany({
|
||||||
where: eq(destinations.adminId, ctx.user.adminId),
|
where: eq(destinations.userId, ctx.user.ownerId),
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
remove: adminProcedure
|
remove: adminProcedure
|
||||||
@@ -103,7 +103,7 @@ export const destinationRouter = createTRPCRouter({
|
|||||||
try {
|
try {
|
||||||
const destination = await findDestinationById(input.destinationId);
|
const destination = await findDestinationById(input.destinationId);
|
||||||
|
|
||||||
if (destination.adminId !== ctx.user.adminId) {
|
if (destination.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not allowed to delete this destination",
|
message: "You are not allowed to delete this destination",
|
||||||
@@ -111,7 +111,7 @@ export const destinationRouter = createTRPCRouter({
|
|||||||
}
|
}
|
||||||
return await removeDestinationById(
|
return await removeDestinationById(
|
||||||
input.destinationId,
|
input.destinationId,
|
||||||
ctx.user.adminId,
|
ctx.user.ownerId,
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw error;
|
throw error;
|
||||||
@@ -122,7 +122,7 @@ export const destinationRouter = createTRPCRouter({
|
|||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
try {
|
try {
|
||||||
const destination = await findDestinationById(input.destinationId);
|
const destination = await findDestinationById(input.destinationId);
|
||||||
if (destination.adminId !== ctx.user.adminId) {
|
if (destination.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not allowed to update this destination",
|
message: "You are not allowed to update this destination",
|
||||||
@@ -130,7 +130,7 @@ export const destinationRouter = createTRPCRouter({
|
|||||||
}
|
}
|
||||||
return await updateDestinationById(input.destinationId, {
|
return await updateDestinationById(input.destinationId, {
|
||||||
...input,
|
...input,
|
||||||
adminId: ctx.user.adminId,
|
userId: ctx.user.ownerId,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw error;
|
throw error;
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ export const domainRouter = createTRPCRouter({
|
|||||||
try {
|
try {
|
||||||
if (input.domainType === "compose" && input.composeId) {
|
if (input.domainType === "compose" && input.composeId) {
|
||||||
const compose = await findComposeById(input.composeId);
|
const compose = await findComposeById(input.composeId);
|
||||||
if (compose.project.adminId !== ctx.user.adminId) {
|
if (compose.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to access this compose",
|
message: "You are not authorized to access this compose",
|
||||||
@@ -38,7 +38,7 @@ export const domainRouter = createTRPCRouter({
|
|||||||
}
|
}
|
||||||
} else if (input.domainType === "application" && input.applicationId) {
|
} else if (input.domainType === "application" && input.applicationId) {
|
||||||
const application = await findApplicationById(input.applicationId);
|
const application = await findApplicationById(input.applicationId);
|
||||||
if (application.project.adminId !== ctx.user.adminId) {
|
if (application.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to access this application",
|
message: "You are not authorized to access this application",
|
||||||
@@ -58,7 +58,7 @@ export const domainRouter = createTRPCRouter({
|
|||||||
.input(apiFindOneApplication)
|
.input(apiFindOneApplication)
|
||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
const application = await findApplicationById(input.applicationId);
|
const application = await findApplicationById(input.applicationId);
|
||||||
if (application.project.adminId !== ctx.user.adminId) {
|
if (application.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to access this application",
|
message: "You are not authorized to access this application",
|
||||||
@@ -70,7 +70,7 @@ export const domainRouter = createTRPCRouter({
|
|||||||
.input(apiFindCompose)
|
.input(apiFindCompose)
|
||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
const compose = await findComposeById(input.composeId);
|
const compose = await findComposeById(input.composeId);
|
||||||
if (compose.project.adminId !== ctx.user.adminId) {
|
if (compose.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to access this compose",
|
message: "You are not authorized to access this compose",
|
||||||
@@ -83,7 +83,7 @@ export const domainRouter = createTRPCRouter({
|
|||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
return generateTraefikMeDomain(
|
return generateTraefikMeDomain(
|
||||||
input.appName,
|
input.appName,
|
||||||
ctx.user.adminId,
|
ctx.user.ownerId,
|
||||||
input.serverId,
|
input.serverId,
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
@@ -95,7 +95,7 @@ export const domainRouter = createTRPCRouter({
|
|||||||
|
|
||||||
if (currentDomain.applicationId) {
|
if (currentDomain.applicationId) {
|
||||||
const newApp = await findApplicationById(currentDomain.applicationId);
|
const newApp = await findApplicationById(currentDomain.applicationId);
|
||||||
if (newApp.project.adminId !== ctx.user.adminId) {
|
if (newApp.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to access this application",
|
message: "You are not authorized to access this application",
|
||||||
@@ -103,7 +103,7 @@ export const domainRouter = createTRPCRouter({
|
|||||||
}
|
}
|
||||||
} else if (currentDomain.composeId) {
|
} else if (currentDomain.composeId) {
|
||||||
const newCompose = await findComposeById(currentDomain.composeId);
|
const newCompose = await findComposeById(currentDomain.composeId);
|
||||||
if (newCompose.project.adminId !== ctx.user.adminId) {
|
if (newCompose.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to access this compose",
|
message: "You are not authorized to access this compose",
|
||||||
@@ -114,7 +114,7 @@ export const domainRouter = createTRPCRouter({
|
|||||||
currentDomain.previewDeploymentId,
|
currentDomain.previewDeploymentId,
|
||||||
);
|
);
|
||||||
if (
|
if (
|
||||||
newPreviewDeployment.application.project.adminId !== ctx.user.adminId
|
newPreviewDeployment.application.project.userId !== ctx.user.ownerId
|
||||||
) {
|
) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
@@ -143,7 +143,7 @@ export const domainRouter = createTRPCRouter({
|
|||||||
const domain = await findDomainById(input.domainId);
|
const domain = await findDomainById(input.domainId);
|
||||||
if (domain.applicationId) {
|
if (domain.applicationId) {
|
||||||
const application = await findApplicationById(domain.applicationId);
|
const application = await findApplicationById(domain.applicationId);
|
||||||
if (application.project.adminId !== ctx.user.adminId) {
|
if (application.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to access this application",
|
message: "You are not authorized to access this application",
|
||||||
@@ -151,7 +151,7 @@ export const domainRouter = createTRPCRouter({
|
|||||||
}
|
}
|
||||||
} else if (domain.composeId) {
|
} else if (domain.composeId) {
|
||||||
const compose = await findComposeById(domain.composeId);
|
const compose = await findComposeById(domain.composeId);
|
||||||
if (compose.project.adminId !== ctx.user.adminId) {
|
if (compose.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to access this compose",
|
message: "You are not authorized to access this compose",
|
||||||
@@ -166,7 +166,7 @@ export const domainRouter = createTRPCRouter({
|
|||||||
const domain = await findDomainById(input.domainId);
|
const domain = await findDomainById(input.domainId);
|
||||||
if (domain.applicationId) {
|
if (domain.applicationId) {
|
||||||
const application = await findApplicationById(domain.applicationId);
|
const application = await findApplicationById(domain.applicationId);
|
||||||
if (application.project.adminId !== ctx.user.adminId) {
|
if (application.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to access this application",
|
message: "You are not authorized to access this application",
|
||||||
@@ -174,7 +174,7 @@ export const domainRouter = createTRPCRouter({
|
|||||||
}
|
}
|
||||||
} else if (domain.composeId) {
|
} else if (domain.composeId) {
|
||||||
const compose = await findComposeById(domain.composeId);
|
const compose = await findComposeById(domain.composeId);
|
||||||
if (compose.project.adminId !== ctx.user.adminId) {
|
if (compose.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to access this compose",
|
message: "You are not authorized to access this compose",
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ export const gitProviderRouter = createTRPCRouter({
|
|||||||
github: true,
|
github: true,
|
||||||
},
|
},
|
||||||
orderBy: desc(gitProvider.createdAt),
|
orderBy: desc(gitProvider.createdAt),
|
||||||
...(IS_CLOUD && { where: eq(gitProvider.adminId, ctx.user.adminId) }),
|
...(IS_CLOUD && { where: eq(gitProvider.userId, ctx.user.ownerId) }),
|
||||||
//TODO: Remove this line when the cloud version is ready
|
//TODO: Remove this line when the cloud version is ready
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
@@ -28,7 +28,7 @@ export const gitProviderRouter = createTRPCRouter({
|
|||||||
try {
|
try {
|
||||||
const gitProvider = await findGitProviderById(input.gitProviderId);
|
const gitProvider = await findGitProviderById(input.gitProviderId);
|
||||||
|
|
||||||
if (IS_CLOUD && gitProvider.adminId !== ctx.user.adminId) {
|
if (IS_CLOUD && gitProvider.userId !== ctx.user.ownerId) {
|
||||||
// TODO: Remove isCloud in the next versions of dokploy
|
// TODO: Remove isCloud in the next versions of dokploy
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ export const githubRouter = createTRPCRouter({
|
|||||||
.input(apiFindOneGithub)
|
.input(apiFindOneGithub)
|
||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
const githubProvider = await findGithubById(input.githubId);
|
const githubProvider = await findGithubById(input.githubId);
|
||||||
if (IS_CLOUD && githubProvider.gitProvider.adminId !== ctx.user.adminId) {
|
if (IS_CLOUD && githubProvider.gitProvider.userId !== ctx.user.ownerId) {
|
||||||
//TODO: Remove this line when the cloud version is ready
|
//TODO: Remove this line when the cloud version is ready
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
@@ -33,7 +33,7 @@ export const githubRouter = createTRPCRouter({
|
|||||||
.input(apiFindOneGithub)
|
.input(apiFindOneGithub)
|
||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
const githubProvider = await findGithubById(input.githubId);
|
const githubProvider = await findGithubById(input.githubId);
|
||||||
if (IS_CLOUD && githubProvider.gitProvider.adminId !== ctx.user.adminId) {
|
if (IS_CLOUD && githubProvider.gitProvider.userId !== ctx.user.ownerId) {
|
||||||
//TODO: Remove this line when the cloud version is ready
|
//TODO: Remove this line when the cloud version is ready
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
@@ -46,7 +46,7 @@ export const githubRouter = createTRPCRouter({
|
|||||||
.input(apiFindGithubBranches)
|
.input(apiFindGithubBranches)
|
||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
const githubProvider = await findGithubById(input.githubId || "");
|
const githubProvider = await findGithubById(input.githubId || "");
|
||||||
if (IS_CLOUD && githubProvider.gitProvider.adminId !== ctx.user.adminId) {
|
if (IS_CLOUD && githubProvider.gitProvider.userId !== ctx.user.ownerId) {
|
||||||
//TODO: Remove this line when the cloud version is ready
|
//TODO: Remove this line when the cloud version is ready
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
@@ -65,7 +65,7 @@ export const githubRouter = createTRPCRouter({
|
|||||||
if (IS_CLOUD) {
|
if (IS_CLOUD) {
|
||||||
// TODO: mAyBe a rEfaCtoR 🤫
|
// TODO: mAyBe a rEfaCtoR 🤫
|
||||||
result = result.filter(
|
result = result.filter(
|
||||||
(provider) => provider.gitProvider.adminId === ctx.user.adminId,
|
(provider) => provider.gitProvider.userId === ctx.user.ownerId,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,7 +90,7 @@ export const githubRouter = createTRPCRouter({
|
|||||||
const githubProvider = await findGithubById(input.githubId);
|
const githubProvider = await findGithubById(input.githubId);
|
||||||
if (
|
if (
|
||||||
IS_CLOUD &&
|
IS_CLOUD &&
|
||||||
githubProvider.gitProvider.adminId !== ctx.user.adminId
|
githubProvider.gitProvider.userId !== ctx.user.ownerId
|
||||||
) {
|
) {
|
||||||
//TODO: Remove this line when the cloud version is ready
|
//TODO: Remove this line when the cloud version is ready
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
@@ -111,7 +111,7 @@ export const githubRouter = createTRPCRouter({
|
|||||||
.input(apiUpdateGithub)
|
.input(apiUpdateGithub)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const githubProvider = await findGithubById(input.githubId);
|
const githubProvider = await findGithubById(input.githubId);
|
||||||
if (IS_CLOUD && githubProvider.gitProvider.adminId !== ctx.user.adminId) {
|
if (IS_CLOUD && githubProvider.gitProvider.userId !== ctx.user.ownerId) {
|
||||||
//TODO: Remove this line when the cloud version is ready
|
//TODO: Remove this line when the cloud version is ready
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
@@ -120,7 +120,7 @@ export const githubRouter = createTRPCRouter({
|
|||||||
}
|
}
|
||||||
await updateGitProvider(input.gitProviderId, {
|
await updateGitProvider(input.gitProviderId, {
|
||||||
name: input.name,
|
name: input.name,
|
||||||
adminId: ctx.user.adminId,
|
userId: ctx.user.ownerId,
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ export const gitlabRouter = createTRPCRouter({
|
|||||||
.input(apiCreateGitlab)
|
.input(apiCreateGitlab)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
try {
|
try {
|
||||||
return await createGitlab(input, ctx.user.adminId);
|
return await createGitlab(input, ctx.user.ownerId);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "BAD_REQUEST",
|
code: "BAD_REQUEST",
|
||||||
@@ -39,7 +39,7 @@ export const gitlabRouter = createTRPCRouter({
|
|||||||
.input(apiFindOneGitlab)
|
.input(apiFindOneGitlab)
|
||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
const gitlabProvider = await findGitlabById(input.gitlabId);
|
const gitlabProvider = await findGitlabById(input.gitlabId);
|
||||||
if (IS_CLOUD && gitlabProvider.gitProvider.adminId !== ctx.user.adminId) {
|
if (IS_CLOUD && gitlabProvider.gitProvider.userId !== ctx.user.ownerId) {
|
||||||
//TODO: Remove this line when the cloud version is ready
|
//TODO: Remove this line when the cloud version is ready
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
@@ -58,7 +58,7 @@ export const gitlabRouter = createTRPCRouter({
|
|||||||
if (IS_CLOUD) {
|
if (IS_CLOUD) {
|
||||||
// TODO: mAyBe a rEfaCtoR 🤫
|
// TODO: mAyBe a rEfaCtoR 🤫
|
||||||
result = result.filter(
|
result = result.filter(
|
||||||
(provider) => provider.gitProvider.adminId === ctx.user.adminId,
|
(provider) => provider.gitProvider.userId === ctx.user.ownerId,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const filtered = result
|
const filtered = result
|
||||||
@@ -78,7 +78,7 @@ export const gitlabRouter = createTRPCRouter({
|
|||||||
.input(apiFindOneGitlab)
|
.input(apiFindOneGitlab)
|
||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
const gitlabProvider = await findGitlabById(input.gitlabId);
|
const gitlabProvider = await findGitlabById(input.gitlabId);
|
||||||
if (IS_CLOUD && gitlabProvider.gitProvider.adminId !== ctx.user.adminId) {
|
if (IS_CLOUD && gitlabProvider.gitProvider.userId !== ctx.user.ownerId) {
|
||||||
//TODO: Remove this line when the cloud version is ready
|
//TODO: Remove this line when the cloud version is ready
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
@@ -92,7 +92,7 @@ export const gitlabRouter = createTRPCRouter({
|
|||||||
.input(apiFindGitlabBranches)
|
.input(apiFindGitlabBranches)
|
||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
const gitlabProvider = await findGitlabById(input.gitlabId || "");
|
const gitlabProvider = await findGitlabById(input.gitlabId || "");
|
||||||
if (IS_CLOUD && gitlabProvider.gitProvider.adminId !== ctx.user.adminId) {
|
if (IS_CLOUD && gitlabProvider.gitProvider.userId !== ctx.user.ownerId) {
|
||||||
//TODO: Remove this line when the cloud version is ready
|
//TODO: Remove this line when the cloud version is ready
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
@@ -108,7 +108,7 @@ export const gitlabRouter = createTRPCRouter({
|
|||||||
const gitlabProvider = await findGitlabById(input.gitlabId || "");
|
const gitlabProvider = await findGitlabById(input.gitlabId || "");
|
||||||
if (
|
if (
|
||||||
IS_CLOUD &&
|
IS_CLOUD &&
|
||||||
gitlabProvider.gitProvider.adminId !== ctx.user.adminId
|
gitlabProvider.gitProvider.userId !== ctx.user.ownerId
|
||||||
) {
|
) {
|
||||||
//TODO: Remove this line when the cloud version is ready
|
//TODO: Remove this line when the cloud version is ready
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
@@ -130,7 +130,7 @@ export const gitlabRouter = createTRPCRouter({
|
|||||||
.input(apiUpdateGitlab)
|
.input(apiUpdateGitlab)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const gitlabProvider = await findGitlabById(input.gitlabId);
|
const gitlabProvider = await findGitlabById(input.gitlabId);
|
||||||
if (IS_CLOUD && gitlabProvider.gitProvider.adminId !== ctx.user.adminId) {
|
if (IS_CLOUD && gitlabProvider.gitProvider.userId !== ctx.user.ownerId) {
|
||||||
//TODO: Remove this line when the cloud version is ready
|
//TODO: Remove this line when the cloud version is ready
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
@@ -140,7 +140,7 @@ export const gitlabRouter = createTRPCRouter({
|
|||||||
if (input.name) {
|
if (input.name) {
|
||||||
await updateGitProvider(input.gitProviderId, {
|
await updateGitProvider(input.gitProviderId, {
|
||||||
name: input.name,
|
name: input.name,
|
||||||
adminId: ctx.user.adminId,
|
userId: ctx.user.ownerId,
|
||||||
});
|
});
|
||||||
|
|
||||||
await updateGitlab(input.gitlabId, {
|
await updateGitlab(input.gitlabId, {
|
||||||
|
|||||||
@@ -37,8 +37,8 @@ export const mariadbRouter = createTRPCRouter({
|
|||||||
.input(apiCreateMariaDB)
|
.input(apiCreateMariaDB)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
try {
|
try {
|
||||||
if (ctx.user.rol === "user") {
|
if (ctx.user.rol === "member") {
|
||||||
await checkServiceAccess(ctx.user.authId, input.projectId, "create");
|
await checkServiceAccess(ctx.user.id, input.projectId, "create");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_CLOUD && !input.serverId) {
|
if (IS_CLOUD && !input.serverId) {
|
||||||
@@ -49,15 +49,15 @@ export const mariadbRouter = createTRPCRouter({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const project = await findProjectById(input.projectId);
|
const project = await findProjectById(input.projectId);
|
||||||
if (project.adminId !== ctx.user.adminId) {
|
if (project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to access this project",
|
message: "You are not authorized to access this project",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const newMariadb = await createMariadb(input);
|
const newMariadb = await createMariadb(input);
|
||||||
if (ctx.user.rol === "user") {
|
if (ctx.user.rol === "member") {
|
||||||
await addNewService(ctx.user.authId, newMariadb.mariadbId);
|
await addNewService(ctx.user.id, newMariadb.mariadbId);
|
||||||
}
|
}
|
||||||
|
|
||||||
await createMount({
|
await createMount({
|
||||||
@@ -79,11 +79,11 @@ export const mariadbRouter = createTRPCRouter({
|
|||||||
one: protectedProcedure
|
one: protectedProcedure
|
||||||
.input(apiFindOneMariaDB)
|
.input(apiFindOneMariaDB)
|
||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
if (ctx.user.rol === "user") {
|
if (ctx.user.rol === "member") {
|
||||||
await checkServiceAccess(ctx.user.authId, input.mariadbId, "access");
|
await checkServiceAccess(ctx.user.id, input.mariadbId, "access");
|
||||||
}
|
}
|
||||||
const mariadb = await findMariadbById(input.mariadbId);
|
const mariadb = await findMariadbById(input.mariadbId);
|
||||||
if (mariadb.project.adminId !== ctx.user.adminId) {
|
if (mariadb.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to access this Mariadb",
|
message: "You are not authorized to access this Mariadb",
|
||||||
@@ -96,7 +96,7 @@ export const mariadbRouter = createTRPCRouter({
|
|||||||
.input(apiFindOneMariaDB)
|
.input(apiFindOneMariaDB)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const service = await findMariadbById(input.mariadbId);
|
const service = await findMariadbById(input.mariadbId);
|
||||||
if (service.project.adminId !== ctx.user.adminId) {
|
if (service.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to start this Mariadb",
|
message: "You are not authorized to start this Mariadb",
|
||||||
@@ -133,7 +133,7 @@ export const mariadbRouter = createTRPCRouter({
|
|||||||
.input(apiSaveExternalPortMariaDB)
|
.input(apiSaveExternalPortMariaDB)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const mongo = await findMariadbById(input.mariadbId);
|
const mongo = await findMariadbById(input.mariadbId);
|
||||||
if (mongo.project.adminId !== ctx.user.adminId) {
|
if (mongo.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to save this external port",
|
message: "You are not authorized to save this external port",
|
||||||
@@ -149,7 +149,7 @@ export const mariadbRouter = createTRPCRouter({
|
|||||||
.input(apiDeployMariaDB)
|
.input(apiDeployMariaDB)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const mariadb = await findMariadbById(input.mariadbId);
|
const mariadb = await findMariadbById(input.mariadbId);
|
||||||
if (mariadb.project.adminId !== ctx.user.adminId) {
|
if (mariadb.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to deploy this Mariadb",
|
message: "You are not authorized to deploy this Mariadb",
|
||||||
@@ -170,7 +170,7 @@ export const mariadbRouter = createTRPCRouter({
|
|||||||
.input(apiDeployMariaDB)
|
.input(apiDeployMariaDB)
|
||||||
.subscription(async ({ input, ctx }) => {
|
.subscription(async ({ input, ctx }) => {
|
||||||
const mariadb = await findMariadbById(input.mariadbId);
|
const mariadb = await findMariadbById(input.mariadbId);
|
||||||
if (mariadb.project.adminId !== ctx.user.adminId) {
|
if (mariadb.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to deploy this Mariadb",
|
message: "You are not authorized to deploy this Mariadb",
|
||||||
@@ -187,7 +187,7 @@ export const mariadbRouter = createTRPCRouter({
|
|||||||
.input(apiChangeMariaDBStatus)
|
.input(apiChangeMariaDBStatus)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const mongo = await findMariadbById(input.mariadbId);
|
const mongo = await findMariadbById(input.mariadbId);
|
||||||
if (mongo.project.adminId !== ctx.user.adminId) {
|
if (mongo.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to change this Mariadb status",
|
message: "You are not authorized to change this Mariadb status",
|
||||||
@@ -201,12 +201,12 @@ export const mariadbRouter = createTRPCRouter({
|
|||||||
remove: protectedProcedure
|
remove: protectedProcedure
|
||||||
.input(apiFindOneMariaDB)
|
.input(apiFindOneMariaDB)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
if (ctx.user.rol === "user") {
|
if (ctx.user.rol === "member") {
|
||||||
await checkServiceAccess(ctx.user.authId, input.mariadbId, "delete");
|
await checkServiceAccess(ctx.user.id, input.mariadbId, "delete");
|
||||||
}
|
}
|
||||||
|
|
||||||
const mongo = await findMariadbById(input.mariadbId);
|
const mongo = await findMariadbById(input.mariadbId);
|
||||||
if (mongo.project.adminId !== ctx.user.adminId) {
|
if (mongo.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to delete this Mariadb",
|
message: "You are not authorized to delete this Mariadb",
|
||||||
@@ -232,7 +232,7 @@ export const mariadbRouter = createTRPCRouter({
|
|||||||
.input(apiSaveEnvironmentVariablesMariaDB)
|
.input(apiSaveEnvironmentVariablesMariaDB)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const mariadb = await findMariadbById(input.mariadbId);
|
const mariadb = await findMariadbById(input.mariadbId);
|
||||||
if (mariadb.project.adminId !== ctx.user.adminId) {
|
if (mariadb.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to save this environment",
|
message: "You are not authorized to save this environment",
|
||||||
@@ -255,7 +255,7 @@ export const mariadbRouter = createTRPCRouter({
|
|||||||
.input(apiResetMariadb)
|
.input(apiResetMariadb)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const mariadb = await findMariadbById(input.mariadbId);
|
const mariadb = await findMariadbById(input.mariadbId);
|
||||||
if (mariadb.project.adminId !== ctx.user.adminId) {
|
if (mariadb.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to reload this Mariadb",
|
message: "You are not authorized to reload this Mariadb",
|
||||||
@@ -285,7 +285,7 @@ export const mariadbRouter = createTRPCRouter({
|
|||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const { mariadbId, ...rest } = input;
|
const { mariadbId, ...rest } = input;
|
||||||
const mariadb = await findMariadbById(mariadbId);
|
const mariadb = await findMariadbById(mariadbId);
|
||||||
if (mariadb.project.adminId !== ctx.user.adminId) {
|
if (mariadb.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to update this Mariadb",
|
message: "You are not authorized to update this Mariadb",
|
||||||
|
|||||||
@@ -36,8 +36,8 @@ export const mongoRouter = createTRPCRouter({
|
|||||||
.input(apiCreateMongo)
|
.input(apiCreateMongo)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
try {
|
try {
|
||||||
if (ctx.user.rol === "user") {
|
if (ctx.user.rol === "member") {
|
||||||
await checkServiceAccess(ctx.user.authId, input.projectId, "create");
|
await checkServiceAccess(ctx.user.id, input.projectId, "create");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_CLOUD && !input.serverId) {
|
if (IS_CLOUD && !input.serverId) {
|
||||||
@@ -48,15 +48,15 @@ export const mongoRouter = createTRPCRouter({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const project = await findProjectById(input.projectId);
|
const project = await findProjectById(input.projectId);
|
||||||
if (project.adminId !== ctx.user.adminId) {
|
if (project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to access this project",
|
message: "You are not authorized to access this project",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const newMongo = await createMongo(input);
|
const newMongo = await createMongo(input);
|
||||||
if (ctx.user.rol === "user") {
|
if (ctx.user.rol === "member") {
|
||||||
await addNewService(ctx.user.authId, newMongo.mongoId);
|
await addNewService(ctx.user.id, newMongo.mongoId);
|
||||||
}
|
}
|
||||||
|
|
||||||
await createMount({
|
await createMount({
|
||||||
@@ -82,12 +82,12 @@ export const mongoRouter = createTRPCRouter({
|
|||||||
one: protectedProcedure
|
one: protectedProcedure
|
||||||
.input(apiFindOneMongo)
|
.input(apiFindOneMongo)
|
||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
if (ctx.user.rol === "user") {
|
if (ctx.user.rol === "member") {
|
||||||
await checkServiceAccess(ctx.user.authId, input.mongoId, "access");
|
await checkServiceAccess(ctx.user.id, input.mongoId, "access");
|
||||||
}
|
}
|
||||||
|
|
||||||
const mongo = await findMongoById(input.mongoId);
|
const mongo = await findMongoById(input.mongoId);
|
||||||
if (mongo.project.adminId !== ctx.user.adminId) {
|
if (mongo.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to access this mongo",
|
message: "You are not authorized to access this mongo",
|
||||||
@@ -101,7 +101,7 @@ export const mongoRouter = createTRPCRouter({
|
|||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const service = await findMongoById(input.mongoId);
|
const service = await findMongoById(input.mongoId);
|
||||||
|
|
||||||
if (service.project.adminId !== ctx.user.adminId) {
|
if (service.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to start this mongo",
|
message: "You are not authorized to start this mongo",
|
||||||
@@ -124,7 +124,7 @@ export const mongoRouter = createTRPCRouter({
|
|||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const mongo = await findMongoById(input.mongoId);
|
const mongo = await findMongoById(input.mongoId);
|
||||||
|
|
||||||
if (mongo.project.adminId !== ctx.user.adminId) {
|
if (mongo.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to stop this mongo",
|
message: "You are not authorized to stop this mongo",
|
||||||
@@ -146,7 +146,7 @@ export const mongoRouter = createTRPCRouter({
|
|||||||
.input(apiSaveExternalPortMongo)
|
.input(apiSaveExternalPortMongo)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const mongo = await findMongoById(input.mongoId);
|
const mongo = await findMongoById(input.mongoId);
|
||||||
if (mongo.project.adminId !== ctx.user.adminId) {
|
if (mongo.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to save this external port",
|
message: "You are not authorized to save this external port",
|
||||||
@@ -162,7 +162,7 @@ export const mongoRouter = createTRPCRouter({
|
|||||||
.input(apiDeployMongo)
|
.input(apiDeployMongo)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const mongo = await findMongoById(input.mongoId);
|
const mongo = await findMongoById(input.mongoId);
|
||||||
if (mongo.project.adminId !== ctx.user.adminId) {
|
if (mongo.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to deploy this mongo",
|
message: "You are not authorized to deploy this mongo",
|
||||||
@@ -182,7 +182,7 @@ export const mongoRouter = createTRPCRouter({
|
|||||||
.input(apiDeployMongo)
|
.input(apiDeployMongo)
|
||||||
.subscription(async ({ input, ctx }) => {
|
.subscription(async ({ input, ctx }) => {
|
||||||
const mongo = await findMongoById(input.mongoId);
|
const mongo = await findMongoById(input.mongoId);
|
||||||
if (mongo.project.adminId !== ctx.user.adminId) {
|
if (mongo.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to deploy this mongo",
|
message: "You are not authorized to deploy this mongo",
|
||||||
@@ -199,7 +199,7 @@ export const mongoRouter = createTRPCRouter({
|
|||||||
.input(apiChangeMongoStatus)
|
.input(apiChangeMongoStatus)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const mongo = await findMongoById(input.mongoId);
|
const mongo = await findMongoById(input.mongoId);
|
||||||
if (mongo.project.adminId !== ctx.user.adminId) {
|
if (mongo.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to change this mongo status",
|
message: "You are not authorized to change this mongo status",
|
||||||
@@ -214,7 +214,7 @@ export const mongoRouter = createTRPCRouter({
|
|||||||
.input(apiResetMongo)
|
.input(apiResetMongo)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const mongo = await findMongoById(input.mongoId);
|
const mongo = await findMongoById(input.mongoId);
|
||||||
if (mongo.project.adminId !== ctx.user.adminId) {
|
if (mongo.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to reload this mongo",
|
message: "You are not authorized to reload this mongo",
|
||||||
@@ -242,13 +242,13 @@ export const mongoRouter = createTRPCRouter({
|
|||||||
remove: protectedProcedure
|
remove: protectedProcedure
|
||||||
.input(apiFindOneMongo)
|
.input(apiFindOneMongo)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
if (ctx.user.rol === "user") {
|
if (ctx.user.rol === "member") {
|
||||||
await checkServiceAccess(ctx.user.authId, input.mongoId, "delete");
|
await checkServiceAccess(ctx.user.id, input.mongoId, "delete");
|
||||||
}
|
}
|
||||||
|
|
||||||
const mongo = await findMongoById(input.mongoId);
|
const mongo = await findMongoById(input.mongoId);
|
||||||
|
|
||||||
if (mongo.project.adminId !== ctx.user.adminId) {
|
if (mongo.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to delete this mongo",
|
message: "You are not authorized to delete this mongo",
|
||||||
@@ -274,7 +274,7 @@ export const mongoRouter = createTRPCRouter({
|
|||||||
.input(apiSaveEnvironmentVariablesMongo)
|
.input(apiSaveEnvironmentVariablesMongo)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const mongo = await findMongoById(input.mongoId);
|
const mongo = await findMongoById(input.mongoId);
|
||||||
if (mongo.project.adminId !== ctx.user.adminId) {
|
if (mongo.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to save this environment",
|
message: "You are not authorized to save this environment",
|
||||||
@@ -298,7 +298,7 @@ export const mongoRouter = createTRPCRouter({
|
|||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const { mongoId, ...rest } = input;
|
const { mongoId, ...rest } = input;
|
||||||
const mongo = await findMongoById(mongoId);
|
const mongo = await findMongoById(mongoId);
|
||||||
if (mongo.project.adminId !== ctx.user.adminId) {
|
if (mongo.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to update this mongo",
|
message: "You are not authorized to update this mongo",
|
||||||
|
|||||||
@@ -38,8 +38,8 @@ export const mysqlRouter = createTRPCRouter({
|
|||||||
.input(apiCreateMySql)
|
.input(apiCreateMySql)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
try {
|
try {
|
||||||
if (ctx.user.rol === "user") {
|
if (ctx.user.rol === "member") {
|
||||||
await checkServiceAccess(ctx.user.authId, input.projectId, "create");
|
await checkServiceAccess(ctx.user.id, input.projectId, "create");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_CLOUD && !input.serverId) {
|
if (IS_CLOUD && !input.serverId) {
|
||||||
@@ -50,7 +50,7 @@ export const mysqlRouter = createTRPCRouter({
|
|||||||
}
|
}
|
||||||
1;
|
1;
|
||||||
const project = await findProjectById(input.projectId);
|
const project = await findProjectById(input.projectId);
|
||||||
if (project.adminId !== ctx.user.adminId) {
|
if (project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to access this project",
|
message: "You are not authorized to access this project",
|
||||||
@@ -58,8 +58,8 @@ export const mysqlRouter = createTRPCRouter({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const newMysql = await createMysql(input);
|
const newMysql = await createMysql(input);
|
||||||
if (ctx.user.rol === "user") {
|
if (ctx.user.rol === "member") {
|
||||||
await addNewService(ctx.user.authId, newMysql.mysqlId);
|
await addNewService(ctx.user.id, newMysql.mysqlId);
|
||||||
}
|
}
|
||||||
|
|
||||||
await createMount({
|
await createMount({
|
||||||
@@ -85,11 +85,11 @@ export const mysqlRouter = createTRPCRouter({
|
|||||||
one: protectedProcedure
|
one: protectedProcedure
|
||||||
.input(apiFindOneMySql)
|
.input(apiFindOneMySql)
|
||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
if (ctx.user.rol === "user") {
|
if (ctx.user.rol === "member") {
|
||||||
await checkServiceAccess(ctx.user.authId, input.mysqlId, "access");
|
await checkServiceAccess(ctx.user.id, input.mysqlId, "access");
|
||||||
}
|
}
|
||||||
const mysql = await findMySqlById(input.mysqlId);
|
const mysql = await findMySqlById(input.mysqlId);
|
||||||
if (mysql.project.adminId !== ctx.user.adminId) {
|
if (mysql.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to access this MySQL",
|
message: "You are not authorized to access this MySQL",
|
||||||
@@ -102,7 +102,7 @@ export const mysqlRouter = createTRPCRouter({
|
|||||||
.input(apiFindOneMySql)
|
.input(apiFindOneMySql)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const service = await findMySqlById(input.mysqlId);
|
const service = await findMySqlById(input.mysqlId);
|
||||||
if (service.project.adminId !== ctx.user.adminId) {
|
if (service.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to start this MySQL",
|
message: "You are not authorized to start this MySQL",
|
||||||
@@ -124,7 +124,7 @@ export const mysqlRouter = createTRPCRouter({
|
|||||||
.input(apiFindOneMySql)
|
.input(apiFindOneMySql)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const mongo = await findMySqlById(input.mysqlId);
|
const mongo = await findMySqlById(input.mysqlId);
|
||||||
if (mongo.project.adminId !== ctx.user.adminId) {
|
if (mongo.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to stop this MySQL",
|
message: "You are not authorized to stop this MySQL",
|
||||||
@@ -145,7 +145,7 @@ export const mysqlRouter = createTRPCRouter({
|
|||||||
.input(apiSaveExternalPortMySql)
|
.input(apiSaveExternalPortMySql)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const mongo = await findMySqlById(input.mysqlId);
|
const mongo = await findMySqlById(input.mysqlId);
|
||||||
if (mongo.project.adminId !== ctx.user.adminId) {
|
if (mongo.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to save this external port",
|
message: "You are not authorized to save this external port",
|
||||||
@@ -161,7 +161,7 @@ export const mysqlRouter = createTRPCRouter({
|
|||||||
.input(apiDeployMySql)
|
.input(apiDeployMySql)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const mysql = await findMySqlById(input.mysqlId);
|
const mysql = await findMySqlById(input.mysqlId);
|
||||||
if (mysql.project.adminId !== ctx.user.adminId) {
|
if (mysql.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to deploy this MySQL",
|
message: "You are not authorized to deploy this MySQL",
|
||||||
@@ -181,7 +181,7 @@ export const mysqlRouter = createTRPCRouter({
|
|||||||
.input(apiDeployMySql)
|
.input(apiDeployMySql)
|
||||||
.subscription(async ({ input, ctx }) => {
|
.subscription(async ({ input, ctx }) => {
|
||||||
const mysql = await findMySqlById(input.mysqlId);
|
const mysql = await findMySqlById(input.mysqlId);
|
||||||
if (mysql.project.adminId !== ctx.user.adminId) {
|
if (mysql.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to deploy this MySQL",
|
message: "You are not authorized to deploy this MySQL",
|
||||||
@@ -198,7 +198,7 @@ export const mysqlRouter = createTRPCRouter({
|
|||||||
.input(apiChangeMySqlStatus)
|
.input(apiChangeMySqlStatus)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const mongo = await findMySqlById(input.mysqlId);
|
const mongo = await findMySqlById(input.mysqlId);
|
||||||
if (mongo.project.adminId !== ctx.user.adminId) {
|
if (mongo.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to change this MySQL status",
|
message: "You are not authorized to change this MySQL status",
|
||||||
@@ -213,7 +213,7 @@ export const mysqlRouter = createTRPCRouter({
|
|||||||
.input(apiResetMysql)
|
.input(apiResetMysql)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const mysql = await findMySqlById(input.mysqlId);
|
const mysql = await findMySqlById(input.mysqlId);
|
||||||
if (mysql.project.adminId !== ctx.user.adminId) {
|
if (mysql.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to reload this MySQL",
|
message: "You are not authorized to reload this MySQL",
|
||||||
@@ -240,11 +240,11 @@ export const mysqlRouter = createTRPCRouter({
|
|||||||
remove: protectedProcedure
|
remove: protectedProcedure
|
||||||
.input(apiFindOneMySql)
|
.input(apiFindOneMySql)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
if (ctx.user.rol === "user") {
|
if (ctx.user.rol === "member") {
|
||||||
await checkServiceAccess(ctx.user.authId, input.mysqlId, "delete");
|
await checkServiceAccess(ctx.user.id, input.mysqlId, "delete");
|
||||||
}
|
}
|
||||||
const mongo = await findMySqlById(input.mysqlId);
|
const mongo = await findMySqlById(input.mysqlId);
|
||||||
if (mongo.project.adminId !== ctx.user.adminId) {
|
if (mongo.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to delete this MySQL",
|
message: "You are not authorized to delete this MySQL",
|
||||||
@@ -270,7 +270,7 @@ export const mysqlRouter = createTRPCRouter({
|
|||||||
.input(apiSaveEnvironmentVariablesMySql)
|
.input(apiSaveEnvironmentVariablesMySql)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const mysql = await findMySqlById(input.mysqlId);
|
const mysql = await findMySqlById(input.mysqlId);
|
||||||
if (mysql.project.adminId !== ctx.user.adminId) {
|
if (mysql.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to save this environment",
|
message: "You are not authorized to save this environment",
|
||||||
@@ -294,7 +294,7 @@ export const mysqlRouter = createTRPCRouter({
|
|||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const { mysqlId, ...rest } = input;
|
const { mysqlId, ...rest } = input;
|
||||||
const mysql = await findMySqlById(mysqlId);
|
const mysql = await findMySqlById(mysqlId);
|
||||||
if (mysql.project.adminId !== ctx.user.adminId) {
|
if (mysql.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to update this MySQL",
|
message: "You are not authorized to update this MySQL",
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import {
|
|||||||
} from "@/server/api/trpc";
|
} from "@/server/api/trpc";
|
||||||
import { db } from "@/server/db";
|
import { db } from "@/server/db";
|
||||||
import {
|
import {
|
||||||
admins,
|
|
||||||
apiCreateDiscord,
|
apiCreateDiscord,
|
||||||
apiCreateEmail,
|
apiCreateEmail,
|
||||||
apiCreateGotify,
|
apiCreateGotify,
|
||||||
@@ -25,6 +24,7 @@ import {
|
|||||||
apiUpdateTelegram,
|
apiUpdateTelegram,
|
||||||
notifications,
|
notifications,
|
||||||
server,
|
server,
|
||||||
|
users_temp,
|
||||||
} from "@/server/db/schema";
|
} from "@/server/db/schema";
|
||||||
import {
|
import {
|
||||||
IS_CLOUD,
|
IS_CLOUD,
|
||||||
@@ -57,7 +57,7 @@ export const notificationRouter = createTRPCRouter({
|
|||||||
.input(apiCreateSlack)
|
.input(apiCreateSlack)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
try {
|
try {
|
||||||
return await createSlackNotification(input, ctx.user.adminId);
|
return await createSlackNotification(input, ctx.user.ownerId);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "BAD_REQUEST",
|
code: "BAD_REQUEST",
|
||||||
@@ -71,7 +71,7 @@ export const notificationRouter = createTRPCRouter({
|
|||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
try {
|
try {
|
||||||
const notification = await findNotificationById(input.notificationId);
|
const notification = await findNotificationById(input.notificationId);
|
||||||
if (IS_CLOUD && notification.adminId !== ctx.user.adminId) {
|
if (IS_CLOUD && notification.userId !== ctx.user.ownerId) {
|
||||||
// TODO: Remove isCloud in the next versions of dokploy
|
// TODO: Remove isCloud in the next versions of dokploy
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
@@ -80,7 +80,7 @@ export const notificationRouter = createTRPCRouter({
|
|||||||
}
|
}
|
||||||
return await updateSlackNotification({
|
return await updateSlackNotification({
|
||||||
...input,
|
...input,
|
||||||
adminId: ctx.user.adminId,
|
userId: ctx.user.ownerId,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw error;
|
throw error;
|
||||||
@@ -107,7 +107,7 @@ export const notificationRouter = createTRPCRouter({
|
|||||||
.input(apiCreateTelegram)
|
.input(apiCreateTelegram)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
try {
|
try {
|
||||||
return await createTelegramNotification(input, ctx.user.adminId);
|
return await createTelegramNotification(input, ctx.user.ownerId);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "BAD_REQUEST",
|
code: "BAD_REQUEST",
|
||||||
@@ -122,7 +122,7 @@ export const notificationRouter = createTRPCRouter({
|
|||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
try {
|
try {
|
||||||
const notification = await findNotificationById(input.notificationId);
|
const notification = await findNotificationById(input.notificationId);
|
||||||
if (IS_CLOUD && notification.adminId !== ctx.user.adminId) {
|
if (IS_CLOUD && notification.userId !== ctx.user.ownerId) {
|
||||||
// TODO: Remove isCloud in the next versions of dokploy
|
// TODO: Remove isCloud in the next versions of dokploy
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
@@ -131,7 +131,7 @@ export const notificationRouter = createTRPCRouter({
|
|||||||
}
|
}
|
||||||
return await updateTelegramNotification({
|
return await updateTelegramNotification({
|
||||||
...input,
|
...input,
|
||||||
adminId: ctx.user.adminId,
|
userId: ctx.user.ownerId,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
@@ -159,7 +159,7 @@ export const notificationRouter = createTRPCRouter({
|
|||||||
.input(apiCreateDiscord)
|
.input(apiCreateDiscord)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
try {
|
try {
|
||||||
return await createDiscordNotification(input, ctx.user.adminId);
|
return await createDiscordNotification(input, ctx.user.ownerId);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "BAD_REQUEST",
|
code: "BAD_REQUEST",
|
||||||
@@ -174,7 +174,7 @@ export const notificationRouter = createTRPCRouter({
|
|||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
try {
|
try {
|
||||||
const notification = await findNotificationById(input.notificationId);
|
const notification = await findNotificationById(input.notificationId);
|
||||||
if (IS_CLOUD && notification.adminId !== ctx.user.adminId) {
|
if (IS_CLOUD && notification.userId !== ctx.user.ownerId) {
|
||||||
// TODO: Remove isCloud in the next versions of dokploy
|
// TODO: Remove isCloud in the next versions of dokploy
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
@@ -183,7 +183,7 @@ export const notificationRouter = createTRPCRouter({
|
|||||||
}
|
}
|
||||||
return await updateDiscordNotification({
|
return await updateDiscordNotification({
|
||||||
...input,
|
...input,
|
||||||
adminId: ctx.user.adminId,
|
userId: ctx.user.ownerId,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
@@ -220,7 +220,7 @@ export const notificationRouter = createTRPCRouter({
|
|||||||
.input(apiCreateEmail)
|
.input(apiCreateEmail)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
try {
|
try {
|
||||||
return await createEmailNotification(input, ctx.user.adminId);
|
return await createEmailNotification(input, ctx.user.ownerId);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "BAD_REQUEST",
|
code: "BAD_REQUEST",
|
||||||
@@ -234,7 +234,7 @@ export const notificationRouter = createTRPCRouter({
|
|||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
try {
|
try {
|
||||||
const notification = await findNotificationById(input.notificationId);
|
const notification = await findNotificationById(input.notificationId);
|
||||||
if (IS_CLOUD && notification.adminId !== ctx.user.adminId) {
|
if (IS_CLOUD && notification.userId !== ctx.user.ownerId) {
|
||||||
// TODO: Remove isCloud in the next versions of dokploy
|
// TODO: Remove isCloud in the next versions of dokploy
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
@@ -243,7 +243,7 @@ export const notificationRouter = createTRPCRouter({
|
|||||||
}
|
}
|
||||||
return await updateEmailNotification({
|
return await updateEmailNotification({
|
||||||
...input,
|
...input,
|
||||||
adminId: ctx.user.adminId,
|
userId: ctx.user.ownerId,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
@@ -276,7 +276,7 @@ export const notificationRouter = createTRPCRouter({
|
|||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
try {
|
try {
|
||||||
const notification = await findNotificationById(input.notificationId);
|
const notification = await findNotificationById(input.notificationId);
|
||||||
if (IS_CLOUD && notification.adminId !== ctx.user.adminId) {
|
if (IS_CLOUD && notification.userId !== ctx.user.ownerId) {
|
||||||
// TODO: Remove isCloud in the next versions of dokploy
|
// TODO: Remove isCloud in the next versions of dokploy
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
@@ -295,7 +295,7 @@ export const notificationRouter = createTRPCRouter({
|
|||||||
.input(apiFindOneNotification)
|
.input(apiFindOneNotification)
|
||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
const notification = await findNotificationById(input.notificationId);
|
const notification = await findNotificationById(input.notificationId);
|
||||||
if (IS_CLOUD && notification.adminId !== ctx.user.adminId) {
|
if (IS_CLOUD && notification.userId !== ctx.user.ownerId) {
|
||||||
// TODO: Remove isCloud in the next versions of dokploy
|
// TODO: Remove isCloud in the next versions of dokploy
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
@@ -314,7 +314,7 @@ export const notificationRouter = createTRPCRouter({
|
|||||||
gotify: true,
|
gotify: true,
|
||||||
},
|
},
|
||||||
orderBy: desc(notifications.createdAt),
|
orderBy: desc(notifications.createdAt),
|
||||||
...(IS_CLOUD && { where: eq(notifications.adminId, ctx.user.adminId) }),
|
...(IS_CLOUD && { where: eq(notifications.userId, ctx.user.ownerId) }),
|
||||||
// TODO: Remove this line when the cloud version is ready
|
// TODO: Remove this line when the cloud version is ready
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
@@ -332,24 +332,24 @@ export const notificationRouter = createTRPCRouter({
|
|||||||
)
|
)
|
||||||
.mutation(async ({ input }) => {
|
.mutation(async ({ input }) => {
|
||||||
try {
|
try {
|
||||||
let adminId = "";
|
let userId = "";
|
||||||
let ServerName = "";
|
let ServerName = "";
|
||||||
if (input.ServerType === "Dokploy") {
|
if (input.ServerType === "Dokploy") {
|
||||||
const result = await db
|
const result = await db
|
||||||
.select()
|
.select()
|
||||||
.from(admins)
|
.from(users_temp)
|
||||||
.where(
|
.where(
|
||||||
sql`${admins.metricsConfig}::jsonb -> 'server' ->> 'token' = ${input.Token}`,
|
sql`${users_temp.metricsConfig}::jsonb -> 'server' ->> 'token' = ${input.Token}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!result?.[0]?.adminId) {
|
if (!result?.[0]?.id) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "BAD_REQUEST",
|
code: "BAD_REQUEST",
|
||||||
message: "Token not found",
|
message: "Token not found",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
adminId = result?.[0]?.adminId;
|
userId = result?.[0]?.id;
|
||||||
ServerName = "Dokploy";
|
ServerName = "Dokploy";
|
||||||
} else {
|
} else {
|
||||||
const result = await db
|
const result = await db
|
||||||
@@ -359,18 +359,18 @@ export const notificationRouter = createTRPCRouter({
|
|||||||
sql`${server.metricsConfig}::jsonb -> 'server' ->> 'token' = ${input.Token}`,
|
sql`${server.metricsConfig}::jsonb -> 'server' ->> 'token' = ${input.Token}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!result?.[0]?.adminId) {
|
if (!result?.[0]?.userId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "BAD_REQUEST",
|
code: "BAD_REQUEST",
|
||||||
message: "Token not found",
|
message: "Token not found",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
adminId = result?.[0]?.adminId;
|
userId = result?.[0]?.userId;
|
||||||
ServerName = "Remote";
|
ServerName = "Remote";
|
||||||
}
|
}
|
||||||
|
|
||||||
await sendServerThresholdNotifications(adminId, {
|
await sendServerThresholdNotifications(userId, {
|
||||||
...input,
|
...input,
|
||||||
ServerName,
|
ServerName,
|
||||||
});
|
});
|
||||||
@@ -386,7 +386,7 @@ export const notificationRouter = createTRPCRouter({
|
|||||||
.input(apiCreateGotify)
|
.input(apiCreateGotify)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
try {
|
try {
|
||||||
return await createGotifyNotification(input, ctx.user.adminId);
|
return await createGotifyNotification(input, ctx.user.ownerId);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "BAD_REQUEST",
|
code: "BAD_REQUEST",
|
||||||
@@ -400,7 +400,7 @@ export const notificationRouter = createTRPCRouter({
|
|||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
try {
|
try {
|
||||||
const notification = await findNotificationById(input.notificationId);
|
const notification = await findNotificationById(input.notificationId);
|
||||||
if (IS_CLOUD && notification.adminId !== ctx.user.adminId) {
|
if (IS_CLOUD && notification.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to update this notification",
|
message: "You are not authorized to update this notification",
|
||||||
@@ -408,7 +408,7 @@ export const notificationRouter = createTRPCRouter({
|
|||||||
}
|
}
|
||||||
return await updateGotifyNotification({
|
return await updateGotifyNotification({
|
||||||
...input,
|
...input,
|
||||||
adminId: ctx.user.adminId,
|
userId: ctx.user.ownerId,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw error;
|
throw error;
|
||||||
|
|||||||
@@ -44,8 +44,8 @@ export const postgresRouter = createTRPCRouter({
|
|||||||
.input(apiCreatePostgres)
|
.input(apiCreatePostgres)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
try {
|
try {
|
||||||
if (ctx.user.rol === "user") {
|
if (ctx.user.rol === "member") {
|
||||||
await checkServiceAccess(ctx.user.authId, input.projectId, "create");
|
await checkServiceAccess(ctx.user.id, input.projectId, "create");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_CLOUD && !input.serverId) {
|
if (IS_CLOUD && !input.serverId) {
|
||||||
@@ -56,15 +56,15 @@ export const postgresRouter = createTRPCRouter({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const project = await findProjectById(input.projectId);
|
const project = await findProjectById(input.projectId);
|
||||||
if (project.adminId !== ctx.user.adminId) {
|
if (project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to access this project",
|
message: "You are not authorized to access this project",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const newPostgres = await createPostgres(input);
|
const newPostgres = await createPostgres(input);
|
||||||
if (ctx.user.rol === "user") {
|
if (ctx.user.rol === "member") {
|
||||||
await addNewService(ctx.user.authId, newPostgres.postgresId);
|
await addNewService(ctx.user.id, newPostgres.postgresId);
|
||||||
}
|
}
|
||||||
|
|
||||||
await createMount({
|
await createMount({
|
||||||
@@ -90,12 +90,12 @@ export const postgresRouter = createTRPCRouter({
|
|||||||
one: protectedProcedure
|
one: protectedProcedure
|
||||||
.input(apiFindOnePostgres)
|
.input(apiFindOnePostgres)
|
||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
if (ctx.user.rol === "user") {
|
if (ctx.user.rol === "member") {
|
||||||
await checkServiceAccess(ctx.user.authId, input.postgresId, "access");
|
await checkServiceAccess(ctx.user.id, input.postgresId, "access");
|
||||||
}
|
}
|
||||||
|
|
||||||
const postgres = await findPostgresById(input.postgresId);
|
const postgres = await findPostgresById(input.postgresId);
|
||||||
if (postgres.project.adminId !== ctx.user.adminId) {
|
if (postgres.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to access this Postgres",
|
message: "You are not authorized to access this Postgres",
|
||||||
@@ -109,7 +109,7 @@ export const postgresRouter = createTRPCRouter({
|
|||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const service = await findPostgresById(input.postgresId);
|
const service = await findPostgresById(input.postgresId);
|
||||||
|
|
||||||
if (service.project.adminId !== ctx.user.adminId) {
|
if (service.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to start this Postgres",
|
message: "You are not authorized to start this Postgres",
|
||||||
@@ -131,7 +131,7 @@ export const postgresRouter = createTRPCRouter({
|
|||||||
.input(apiFindOnePostgres)
|
.input(apiFindOnePostgres)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const postgres = await findPostgresById(input.postgresId);
|
const postgres = await findPostgresById(input.postgresId);
|
||||||
if (postgres.project.adminId !== ctx.user.adminId) {
|
if (postgres.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to stop this Postgres",
|
message: "You are not authorized to stop this Postgres",
|
||||||
@@ -153,7 +153,7 @@ export const postgresRouter = createTRPCRouter({
|
|||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const postgres = await findPostgresById(input.postgresId);
|
const postgres = await findPostgresById(input.postgresId);
|
||||||
|
|
||||||
if (postgres.project.adminId !== ctx.user.adminId) {
|
if (postgres.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to save this external port",
|
message: "You are not authorized to save this external port",
|
||||||
@@ -169,7 +169,7 @@ export const postgresRouter = createTRPCRouter({
|
|||||||
.input(apiDeployPostgres)
|
.input(apiDeployPostgres)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const postgres = await findPostgresById(input.postgresId);
|
const postgres = await findPostgresById(input.postgresId);
|
||||||
if (postgres.project.adminId !== ctx.user.adminId) {
|
if (postgres.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to deploy this Postgres",
|
message: "You are not authorized to deploy this Postgres",
|
||||||
@@ -190,7 +190,7 @@ export const postgresRouter = createTRPCRouter({
|
|||||||
.input(apiDeployPostgres)
|
.input(apiDeployPostgres)
|
||||||
.subscription(async ({ input, ctx }) => {
|
.subscription(async ({ input, ctx }) => {
|
||||||
const postgres = await findPostgresById(input.postgresId);
|
const postgres = await findPostgresById(input.postgresId);
|
||||||
if (postgres.project.adminId !== ctx.user.adminId) {
|
if (postgres.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to deploy this Postgres",
|
message: "You are not authorized to deploy this Postgres",
|
||||||
@@ -207,7 +207,7 @@ export const postgresRouter = createTRPCRouter({
|
|||||||
.input(apiChangePostgresStatus)
|
.input(apiChangePostgresStatus)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const postgres = await findPostgresById(input.postgresId);
|
const postgres = await findPostgresById(input.postgresId);
|
||||||
if (postgres.project.adminId !== ctx.user.adminId) {
|
if (postgres.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to change this Postgres status",
|
message: "You are not authorized to change this Postgres status",
|
||||||
@@ -221,12 +221,12 @@ export const postgresRouter = createTRPCRouter({
|
|||||||
remove: protectedProcedure
|
remove: protectedProcedure
|
||||||
.input(apiFindOnePostgres)
|
.input(apiFindOnePostgres)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
if (ctx.user.rol === "user") {
|
if (ctx.user.rol === "member") {
|
||||||
await checkServiceAccess(ctx.user.authId, input.postgresId, "delete");
|
await checkServiceAccess(ctx.user.id, input.postgresId, "delete");
|
||||||
}
|
}
|
||||||
const postgres = await findPostgresById(input.postgresId);
|
const postgres = await findPostgresById(input.postgresId);
|
||||||
|
|
||||||
if (postgres.project.adminId !== ctx.user.adminId) {
|
if (postgres.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to delete this Postgres",
|
message: "You are not authorized to delete this Postgres",
|
||||||
@@ -249,7 +249,7 @@ export const postgresRouter = createTRPCRouter({
|
|||||||
.input(apiSaveEnvironmentVariablesPostgres)
|
.input(apiSaveEnvironmentVariablesPostgres)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const postgres = await findPostgresById(input.postgresId);
|
const postgres = await findPostgresById(input.postgresId);
|
||||||
if (postgres.project.adminId !== ctx.user.adminId) {
|
if (postgres.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to save this environment",
|
message: "You are not authorized to save this environment",
|
||||||
@@ -272,7 +272,7 @@ export const postgresRouter = createTRPCRouter({
|
|||||||
.input(apiResetPostgres)
|
.input(apiResetPostgres)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const postgres = await findPostgresById(input.postgresId);
|
const postgres = await findPostgresById(input.postgresId);
|
||||||
if (postgres.project.adminId !== ctx.user.adminId) {
|
if (postgres.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to reload this Postgres",
|
message: "You are not authorized to reload this Postgres",
|
||||||
@@ -302,7 +302,7 @@ export const postgresRouter = createTRPCRouter({
|
|||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const { postgresId, ...rest } = input;
|
const { postgresId, ...rest } = input;
|
||||||
const postgres = await findPostgresById(postgresId);
|
const postgres = await findPostgresById(postgresId);
|
||||||
if (postgres.project.adminId !== ctx.user.adminId) {
|
if (postgres.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to update this Postgres",
|
message: "You are not authorized to update this Postgres",
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export const previewDeploymentRouter = createTRPCRouter({
|
|||||||
.input(apiFindAllByApplication)
|
.input(apiFindAllByApplication)
|
||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
const application = await findApplicationById(input.applicationId);
|
const application = await findApplicationById(input.applicationId);
|
||||||
if (application.project.adminId !== ctx.user.adminId) {
|
if (application.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to access this application",
|
message: "You are not authorized to access this application",
|
||||||
@@ -28,7 +28,7 @@ export const previewDeploymentRouter = createTRPCRouter({
|
|||||||
const previewDeployment = await findPreviewDeploymentById(
|
const previewDeployment = await findPreviewDeploymentById(
|
||||||
input.previewDeploymentId,
|
input.previewDeploymentId,
|
||||||
);
|
);
|
||||||
if (previewDeployment.application.project.adminId !== ctx.user.adminId) {
|
if (previewDeployment.application.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to delete this preview deployment",
|
message: "You are not authorized to delete this preview deployment",
|
||||||
@@ -43,7 +43,7 @@ export const previewDeploymentRouter = createTRPCRouter({
|
|||||||
const previewDeployment = await findPreviewDeploymentById(
|
const previewDeployment = await findPreviewDeploymentById(
|
||||||
input.previewDeploymentId,
|
input.previewDeploymentId,
|
||||||
);
|
);
|
||||||
if (previewDeployment.application.project.adminId !== ctx.user.adminId) {
|
if (previewDeployment.application.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to access this preview deployment",
|
message: "You are not authorized to access this preview deployment",
|
||||||
|
|||||||
@@ -25,9 +25,9 @@ import {
|
|||||||
checkProjectAccess,
|
checkProjectAccess,
|
||||||
createProject,
|
createProject,
|
||||||
deleteProject,
|
deleteProject,
|
||||||
findAdminById,
|
|
||||||
findProjectById,
|
findProjectById,
|
||||||
findUserByAuthId,
|
findUserByAuthId,
|
||||||
|
findUserById,
|
||||||
updateProjectById,
|
updateProjectById,
|
||||||
} from "@dokploy/server";
|
} from "@dokploy/server";
|
||||||
|
|
||||||
@@ -36,11 +36,11 @@ export const projectRouter = createTRPCRouter({
|
|||||||
.input(apiCreateProject)
|
.input(apiCreateProject)
|
||||||
.mutation(async ({ ctx, input }) => {
|
.mutation(async ({ ctx, input }) => {
|
||||||
try {
|
try {
|
||||||
if (ctx.user.rol === "user") {
|
if (ctx.user.rol === "member") {
|
||||||
await checkProjectAccess(ctx.user.authId, "create");
|
await checkProjectAccess(ctx.user.id, "create");
|
||||||
}
|
}
|
||||||
|
|
||||||
const admin = await findAdminById(ctx.user.adminId);
|
const admin = await findUserById(ctx.user.ownerId);
|
||||||
|
|
||||||
if (admin.serversQuantity === 0 && IS_CLOUD) {
|
if (admin.serversQuantity === 0 && IS_CLOUD) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
@@ -49,9 +49,9 @@ export const projectRouter = createTRPCRouter({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const project = await createProject(input, ctx.user.adminId);
|
const project = await createProject(input, ctx.user.ownerId);
|
||||||
if (ctx.user.rol === "user") {
|
if (ctx.user.rol === "member") {
|
||||||
await addNewProject(ctx.user.authId, project.projectId);
|
await addNewProject(ctx.user.id, project.projectId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return project;
|
return project;
|
||||||
@@ -67,15 +67,15 @@ export const projectRouter = createTRPCRouter({
|
|||||||
one: protectedProcedure
|
one: protectedProcedure
|
||||||
.input(apiFindOneProject)
|
.input(apiFindOneProject)
|
||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
if (ctx.user.rol === "user") {
|
if (ctx.user.rol === "member") {
|
||||||
const { accessedServices } = await findUserByAuthId(ctx.user.authId);
|
const { accessedServices } = await findUserByAuthId(ctx.user.id);
|
||||||
|
|
||||||
await checkProjectAccess(ctx.user.authId, "access", input.projectId);
|
await checkProjectAccess(ctx.user.id, "access", input.projectId);
|
||||||
|
|
||||||
const project = await db.query.projects.findFirst({
|
const project = await db.query.projects.findFirst({
|
||||||
where: and(
|
where: and(
|
||||||
eq(projects.projectId, input.projectId),
|
eq(projects.projectId, input.projectId),
|
||||||
eq(projects.adminId, ctx.user.adminId),
|
eq(projects.userId, ctx.user.ownerId),
|
||||||
),
|
),
|
||||||
with: {
|
with: {
|
||||||
compose: {
|
compose: {
|
||||||
@@ -115,7 +115,7 @@ export const projectRouter = createTRPCRouter({
|
|||||||
}
|
}
|
||||||
const project = await findProjectById(input.projectId);
|
const project = await findProjectById(input.projectId);
|
||||||
|
|
||||||
if (project.adminId !== ctx.user.adminId) {
|
if (project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to access this project",
|
message: "You are not authorized to access this project",
|
||||||
@@ -124,9 +124,10 @@ export const projectRouter = createTRPCRouter({
|
|||||||
return project;
|
return project;
|
||||||
}),
|
}),
|
||||||
all: protectedProcedure.query(async ({ ctx }) => {
|
all: protectedProcedure.query(async ({ ctx }) => {
|
||||||
if (ctx.user.rol === "user") {
|
// console.log(ctx.user);
|
||||||
const { accessedProjects, accessedServices } = await findUserByAuthId(
|
if (ctx.user.rol === "member") {
|
||||||
ctx.user.authId,
|
const { accessedProjects, accessedServices } = await findUserById(
|
||||||
|
ctx.user.id,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (accessedProjects.length === 0) {
|
if (accessedProjects.length === 0) {
|
||||||
@@ -139,7 +140,7 @@ export const projectRouter = createTRPCRouter({
|
|||||||
accessedProjects.map((projectId) => sql`${projectId}`),
|
accessedProjects.map((projectId) => sql`${projectId}`),
|
||||||
sql`, `,
|
sql`, `,
|
||||||
)})`,
|
)})`,
|
||||||
eq(projects.adminId, ctx.user.adminId),
|
eq(projects.userId, ctx.user.id),
|
||||||
),
|
),
|
||||||
with: {
|
with: {
|
||||||
applications: {
|
applications: {
|
||||||
@@ -193,7 +194,7 @@ export const projectRouter = createTRPCRouter({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
where: eq(projects.adminId, ctx.user.adminId),
|
where: eq(projects.userId, ctx.user.id),
|
||||||
orderBy: desc(projects.createdAt),
|
orderBy: desc(projects.createdAt),
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
@@ -202,11 +203,11 @@ export const projectRouter = createTRPCRouter({
|
|||||||
.input(apiRemoveProject)
|
.input(apiRemoveProject)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
try {
|
try {
|
||||||
if (ctx.user.rol === "user") {
|
if (ctx.user.rol === "member") {
|
||||||
await checkProjectAccess(ctx.user.authId, "delete");
|
await checkProjectAccess(ctx.user.id, "delete");
|
||||||
}
|
}
|
||||||
const currentProject = await findProjectById(input.projectId);
|
const currentProject = await findProjectById(input.projectId);
|
||||||
if (currentProject.adminId !== ctx.user.adminId) {
|
if (currentProject.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to delete this project",
|
message: "You are not authorized to delete this project",
|
||||||
@@ -224,7 +225,7 @@ export const projectRouter = createTRPCRouter({
|
|||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
try {
|
try {
|
||||||
const currentProject = await findProjectById(input.projectId);
|
const currentProject = await findProjectById(input.projectId);
|
||||||
if (currentProject.adminId !== ctx.user.adminId) {
|
if (currentProject.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to update this project",
|
message: "You are not authorized to update this project",
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ export const redirectsRouter = createTRPCRouter({
|
|||||||
.input(apiCreateRedirect)
|
.input(apiCreateRedirect)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const application = await findApplicationById(input.applicationId);
|
const application = await findApplicationById(input.applicationId);
|
||||||
if (application.project.adminId !== ctx.user.adminId) {
|
if (application.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to access this application",
|
message: "You are not authorized to access this application",
|
||||||
@@ -31,7 +31,7 @@ export const redirectsRouter = createTRPCRouter({
|
|||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
const redirect = await findRedirectById(input.redirectId);
|
const redirect = await findRedirectById(input.redirectId);
|
||||||
const application = await findApplicationById(redirect.applicationId);
|
const application = await findApplicationById(redirect.applicationId);
|
||||||
if (application.project.adminId !== ctx.user.adminId) {
|
if (application.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to access this application",
|
message: "You are not authorized to access this application",
|
||||||
@@ -44,7 +44,7 @@ export const redirectsRouter = createTRPCRouter({
|
|||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const redirect = await findRedirectById(input.redirectId);
|
const redirect = await findRedirectById(input.redirectId);
|
||||||
const application = await findApplicationById(redirect.applicationId);
|
const application = await findApplicationById(redirect.applicationId);
|
||||||
if (application.project.adminId !== ctx.user.adminId) {
|
if (application.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to access this application",
|
message: "You are not authorized to access this application",
|
||||||
@@ -57,7 +57,7 @@ export const redirectsRouter = createTRPCRouter({
|
|||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const redirect = await findRedirectById(input.redirectId);
|
const redirect = await findRedirectById(input.redirectId);
|
||||||
const application = await findApplicationById(redirect.applicationId);
|
const application = await findApplicationById(redirect.applicationId);
|
||||||
if (application.project.adminId !== ctx.user.adminId) {
|
if (application.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to access this application",
|
message: "You are not authorized to access this application",
|
||||||
|
|||||||
@@ -36,8 +36,8 @@ export const redisRouter = createTRPCRouter({
|
|||||||
.input(apiCreateRedis)
|
.input(apiCreateRedis)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
try {
|
try {
|
||||||
if (ctx.user.rol === "user") {
|
if (ctx.user.rol === "member") {
|
||||||
await checkServiceAccess(ctx.user.authId, input.projectId, "create");
|
await checkServiceAccess(ctx.user.id, input.projectId, "create");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_CLOUD && !input.serverId) {
|
if (IS_CLOUD && !input.serverId) {
|
||||||
@@ -48,15 +48,15 @@ export const redisRouter = createTRPCRouter({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const project = await findProjectById(input.projectId);
|
const project = await findProjectById(input.projectId);
|
||||||
if (project.adminId !== ctx.user.adminId) {
|
if (project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to access this project",
|
message: "You are not authorized to access this project",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const newRedis = await createRedis(input);
|
const newRedis = await createRedis(input);
|
||||||
if (ctx.user.rol === "user") {
|
if (ctx.user.rol === "member") {
|
||||||
await addNewService(ctx.user.authId, newRedis.redisId);
|
await addNewService(ctx.user.id, newRedis.redisId);
|
||||||
}
|
}
|
||||||
|
|
||||||
await createMount({
|
await createMount({
|
||||||
@@ -75,12 +75,12 @@ export const redisRouter = createTRPCRouter({
|
|||||||
one: protectedProcedure
|
one: protectedProcedure
|
||||||
.input(apiFindOneRedis)
|
.input(apiFindOneRedis)
|
||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
if (ctx.user.rol === "user") {
|
if (ctx.user.rol === "member") {
|
||||||
await checkServiceAccess(ctx.user.authId, input.redisId, "access");
|
await checkServiceAccess(ctx.user.id, input.redisId, "access");
|
||||||
}
|
}
|
||||||
|
|
||||||
const redis = await findRedisById(input.redisId);
|
const redis = await findRedisById(input.redisId);
|
||||||
if (redis.project.adminId !== ctx.user.adminId) {
|
if (redis.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to access this Redis",
|
message: "You are not authorized to access this Redis",
|
||||||
@@ -93,7 +93,7 @@ export const redisRouter = createTRPCRouter({
|
|||||||
.input(apiFindOneRedis)
|
.input(apiFindOneRedis)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const redis = await findRedisById(input.redisId);
|
const redis = await findRedisById(input.redisId);
|
||||||
if (redis.project.adminId !== ctx.user.adminId) {
|
if (redis.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to start this Redis",
|
message: "You are not authorized to start this Redis",
|
||||||
@@ -115,7 +115,7 @@ export const redisRouter = createTRPCRouter({
|
|||||||
.input(apiResetRedis)
|
.input(apiResetRedis)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const redis = await findRedisById(input.redisId);
|
const redis = await findRedisById(input.redisId);
|
||||||
if (redis.project.adminId !== ctx.user.adminId) {
|
if (redis.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to reload this Redis",
|
message: "You are not authorized to reload this Redis",
|
||||||
@@ -145,7 +145,7 @@ export const redisRouter = createTRPCRouter({
|
|||||||
.input(apiFindOneRedis)
|
.input(apiFindOneRedis)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const redis = await findRedisById(input.redisId);
|
const redis = await findRedisById(input.redisId);
|
||||||
if (redis.project.adminId !== ctx.user.adminId) {
|
if (redis.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to stop this Redis",
|
message: "You are not authorized to stop this Redis",
|
||||||
@@ -166,7 +166,7 @@ export const redisRouter = createTRPCRouter({
|
|||||||
.input(apiSaveExternalPortRedis)
|
.input(apiSaveExternalPortRedis)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const mongo = await findRedisById(input.redisId);
|
const mongo = await findRedisById(input.redisId);
|
||||||
if (mongo.project.adminId !== ctx.user.adminId) {
|
if (mongo.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to save this external port",
|
message: "You are not authorized to save this external port",
|
||||||
@@ -182,7 +182,7 @@ export const redisRouter = createTRPCRouter({
|
|||||||
.input(apiDeployRedis)
|
.input(apiDeployRedis)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const redis = await findRedisById(input.redisId);
|
const redis = await findRedisById(input.redisId);
|
||||||
if (redis.project.adminId !== ctx.user.adminId) {
|
if (redis.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to deploy this Redis",
|
message: "You are not authorized to deploy this Redis",
|
||||||
@@ -202,7 +202,7 @@ export const redisRouter = createTRPCRouter({
|
|||||||
.input(apiDeployRedis)
|
.input(apiDeployRedis)
|
||||||
.subscription(async ({ input, ctx }) => {
|
.subscription(async ({ input, ctx }) => {
|
||||||
const redis = await findRedisById(input.redisId);
|
const redis = await findRedisById(input.redisId);
|
||||||
if (redis.project.adminId !== ctx.user.adminId) {
|
if (redis.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to deploy this Redis",
|
message: "You are not authorized to deploy this Redis",
|
||||||
@@ -218,7 +218,7 @@ export const redisRouter = createTRPCRouter({
|
|||||||
.input(apiChangeRedisStatus)
|
.input(apiChangeRedisStatus)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const mongo = await findRedisById(input.redisId);
|
const mongo = await findRedisById(input.redisId);
|
||||||
if (mongo.project.adminId !== ctx.user.adminId) {
|
if (mongo.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to change this Redis status",
|
message: "You are not authorized to change this Redis status",
|
||||||
@@ -232,13 +232,13 @@ export const redisRouter = createTRPCRouter({
|
|||||||
remove: protectedProcedure
|
remove: protectedProcedure
|
||||||
.input(apiFindOneRedis)
|
.input(apiFindOneRedis)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
if (ctx.user.rol === "user") {
|
if (ctx.user.rol === "member") {
|
||||||
await checkServiceAccess(ctx.user.authId, input.redisId, "delete");
|
await checkServiceAccess(ctx.user.id, input.redisId, "delete");
|
||||||
}
|
}
|
||||||
|
|
||||||
const redis = await findRedisById(input.redisId);
|
const redis = await findRedisById(input.redisId);
|
||||||
|
|
||||||
if (redis.project.adminId !== ctx.user.adminId) {
|
if (redis.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to delete this Redis",
|
message: "You are not authorized to delete this Redis",
|
||||||
@@ -261,7 +261,7 @@ export const redisRouter = createTRPCRouter({
|
|||||||
.input(apiSaveEnvironmentVariablesRedis)
|
.input(apiSaveEnvironmentVariablesRedis)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const redis = await findRedisById(input.redisId);
|
const redis = await findRedisById(input.redisId);
|
||||||
if (redis.project.adminId !== ctx.user.adminId) {
|
if (redis.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to save this environment",
|
message: "You are not authorized to save this environment",
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import {
|
|||||||
createRegistry,
|
createRegistry,
|
||||||
execAsync,
|
execAsync,
|
||||||
execAsyncRemote,
|
execAsyncRemote,
|
||||||
findAllRegistryByAdminId,
|
findAllRegistryByUserId,
|
||||||
findRegistryById,
|
findRegistryById,
|
||||||
removeRegistry,
|
removeRegistry,
|
||||||
updateRegistry,
|
updateRegistry,
|
||||||
@@ -22,13 +22,13 @@ export const registryRouter = createTRPCRouter({
|
|||||||
create: adminProcedure
|
create: adminProcedure
|
||||||
.input(apiCreateRegistry)
|
.input(apiCreateRegistry)
|
||||||
.mutation(async ({ ctx, input }) => {
|
.mutation(async ({ ctx, input }) => {
|
||||||
return await createRegistry(input, ctx.user.adminId);
|
return await createRegistry(input, ctx.user.ownerId);
|
||||||
}),
|
}),
|
||||||
remove: adminProcedure
|
remove: adminProcedure
|
||||||
.input(apiRemoveRegistry)
|
.input(apiRemoveRegistry)
|
||||||
.mutation(async ({ ctx, input }) => {
|
.mutation(async ({ ctx, input }) => {
|
||||||
const registry = await findRegistryById(input.registryId);
|
const registry = await findRegistryById(input.registryId);
|
||||||
if (registry.adminId !== ctx.user.adminId) {
|
if (registry.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not allowed to delete this registry",
|
message: "You are not allowed to delete this registry",
|
||||||
@@ -41,7 +41,7 @@ export const registryRouter = createTRPCRouter({
|
|||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const { registryId, ...rest } = input;
|
const { registryId, ...rest } = input;
|
||||||
const registry = await findRegistryById(registryId);
|
const registry = await findRegistryById(registryId);
|
||||||
if (registry.adminId !== ctx.user.adminId) {
|
if (registry.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not allowed to update this registry",
|
message: "You are not allowed to update this registry",
|
||||||
@@ -61,13 +61,13 @@ export const registryRouter = createTRPCRouter({
|
|||||||
return true;
|
return true;
|
||||||
}),
|
}),
|
||||||
all: protectedProcedure.query(async ({ ctx }) => {
|
all: protectedProcedure.query(async ({ ctx }) => {
|
||||||
return await findAllRegistryByAdminId(ctx.user.adminId);
|
return await findAllRegistryByUserId(ctx.user.ownerId);
|
||||||
}),
|
}),
|
||||||
one: adminProcedure
|
one: adminProcedure
|
||||||
.input(apiFindOneRegistry)
|
.input(apiFindOneRegistry)
|
||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
const registry = await findRegistryById(input.registryId);
|
const registry = await findRegistryById(input.registryId);
|
||||||
if (registry.adminId !== ctx.user.adminId) {
|
if (registry.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not allowed to access this registry",
|
message: "You are not allowed to access this registry",
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ export const securityRouter = createTRPCRouter({
|
|||||||
.input(apiCreateSecurity)
|
.input(apiCreateSecurity)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const application = await findApplicationById(input.applicationId);
|
const application = await findApplicationById(input.applicationId);
|
||||||
if (application.project.adminId !== ctx.user.adminId) {
|
if (application.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to access this application",
|
message: "You are not authorized to access this application",
|
||||||
@@ -31,7 +31,7 @@ export const securityRouter = createTRPCRouter({
|
|||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
const security = await findSecurityById(input.securityId);
|
const security = await findSecurityById(input.securityId);
|
||||||
const application = await findApplicationById(security.applicationId);
|
const application = await findApplicationById(security.applicationId);
|
||||||
if (application.project.adminId !== ctx.user.adminId) {
|
if (application.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to access this application",
|
message: "You are not authorized to access this application",
|
||||||
@@ -44,7 +44,7 @@ export const securityRouter = createTRPCRouter({
|
|||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const security = await findSecurityById(input.securityId);
|
const security = await findSecurityById(input.securityId);
|
||||||
const application = await findApplicationById(security.applicationId);
|
const application = await findApplicationById(security.applicationId);
|
||||||
if (application.project.adminId !== ctx.user.adminId) {
|
if (application.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to access this application",
|
message: "You are not authorized to access this application",
|
||||||
@@ -57,7 +57,7 @@ export const securityRouter = createTRPCRouter({
|
|||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const security = await findSecurityById(input.securityId);
|
const security = await findSecurityById(input.securityId);
|
||||||
const application = await findApplicationById(security.applicationId);
|
const application = await findApplicationById(security.applicationId);
|
||||||
if (application.project.adminId !== ctx.user.adminId) {
|
if (application.project.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to access this application",
|
message: "You are not authorized to access this application",
|
||||||
|
|||||||
@@ -21,9 +21,9 @@ import {
|
|||||||
createServer,
|
createServer,
|
||||||
defaultCommand,
|
defaultCommand,
|
||||||
deleteServer,
|
deleteServer,
|
||||||
findAdminById,
|
|
||||||
findServerById,
|
findServerById,
|
||||||
findServersByAdminId,
|
findServersByUserId,
|
||||||
|
findUserById,
|
||||||
getPublicIpWithFallback,
|
getPublicIpWithFallback,
|
||||||
haveActiveServices,
|
haveActiveServices,
|
||||||
removeDeploymentsByServerId,
|
removeDeploymentsByServerId,
|
||||||
@@ -42,15 +42,15 @@ export const serverRouter = createTRPCRouter({
|
|||||||
.input(apiCreateServer)
|
.input(apiCreateServer)
|
||||||
.mutation(async ({ ctx, input }) => {
|
.mutation(async ({ ctx, input }) => {
|
||||||
try {
|
try {
|
||||||
const admin = await findAdminById(ctx.user.adminId);
|
const user = await findUserById(ctx.user.ownerId);
|
||||||
const servers = await findServersByAdminId(admin.adminId);
|
const servers = await findServersByUserId(user.id);
|
||||||
if (IS_CLOUD && servers.length >= admin.serversQuantity) {
|
if (IS_CLOUD && servers.length >= user.serversQuantity) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "BAD_REQUEST",
|
code: "BAD_REQUEST",
|
||||||
message: "You cannot create more servers",
|
message: "You cannot create more servers",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const project = await createServer(input, ctx.user.adminId);
|
const project = await createServer(input, ctx.user.ownerId);
|
||||||
return project;
|
return project;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
@@ -65,7 +65,7 @@ export const serverRouter = createTRPCRouter({
|
|||||||
.input(apiFindOneServer)
|
.input(apiFindOneServer)
|
||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
const server = await findServerById(input.serverId);
|
const server = await findServerById(input.serverId);
|
||||||
if (server.adminId !== ctx.user.adminId) {
|
if (server.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to access this server",
|
message: "You are not authorized to access this server",
|
||||||
@@ -93,7 +93,7 @@ export const serverRouter = createTRPCRouter({
|
|||||||
.leftJoin(mongo, eq(mongo.serverId, server.serverId))
|
.leftJoin(mongo, eq(mongo.serverId, server.serverId))
|
||||||
.leftJoin(mysql, eq(mysql.serverId, server.serverId))
|
.leftJoin(mysql, eq(mysql.serverId, server.serverId))
|
||||||
.leftJoin(postgres, eq(postgres.serverId, server.serverId))
|
.leftJoin(postgres, eq(postgres.serverId, server.serverId))
|
||||||
.where(eq(server.adminId, ctx.user.adminId))
|
.where(eq(server.userId, ctx.user.ownerId))
|
||||||
.orderBy(desc(server.createdAt))
|
.orderBy(desc(server.createdAt))
|
||||||
.groupBy(server.serverId);
|
.groupBy(server.serverId);
|
||||||
|
|
||||||
@@ -105,10 +105,10 @@ export const serverRouter = createTRPCRouter({
|
|||||||
where: IS_CLOUD
|
where: IS_CLOUD
|
||||||
? and(
|
? and(
|
||||||
isNotNull(server.sshKeyId),
|
isNotNull(server.sshKeyId),
|
||||||
eq(server.adminId, ctx.user.adminId),
|
eq(server.userId, ctx.user.ownerId),
|
||||||
eq(server.serverStatus, "active"),
|
eq(server.serverStatus, "active"),
|
||||||
)
|
)
|
||||||
: and(isNotNull(server.sshKeyId), eq(server.adminId, ctx.user.adminId)),
|
: and(isNotNull(server.sshKeyId), eq(server.userId, ctx.user.ownerId)),
|
||||||
});
|
});
|
||||||
return result;
|
return result;
|
||||||
}),
|
}),
|
||||||
@@ -117,7 +117,7 @@ export const serverRouter = createTRPCRouter({
|
|||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
try {
|
try {
|
||||||
const server = await findServerById(input.serverId);
|
const server = await findServerById(input.serverId);
|
||||||
if (server.adminId !== ctx.user.adminId) {
|
if (server.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to setup this server",
|
message: "You are not authorized to setup this server",
|
||||||
@@ -142,7 +142,7 @@ export const serverRouter = createTRPCRouter({
|
|||||||
.subscription(async ({ input, ctx }) => {
|
.subscription(async ({ input, ctx }) => {
|
||||||
try {
|
try {
|
||||||
const server = await findServerById(input.serverId);
|
const server = await findServerById(input.serverId);
|
||||||
if (server.adminId !== ctx.user.adminId) {
|
if (server.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to setup this server",
|
message: "You are not authorized to setup this server",
|
||||||
@@ -162,7 +162,7 @@ export const serverRouter = createTRPCRouter({
|
|||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
try {
|
try {
|
||||||
const server = await findServerById(input.serverId);
|
const server = await findServerById(input.serverId);
|
||||||
if (server.adminId !== ctx.user.adminId) {
|
if (server.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to validate this server",
|
message: "You are not authorized to validate this server",
|
||||||
@@ -204,7 +204,7 @@ export const serverRouter = createTRPCRouter({
|
|||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
try {
|
try {
|
||||||
const server = await findServerById(input.serverId);
|
const server = await findServerById(input.serverId);
|
||||||
if (server.adminId !== ctx.user.adminId) {
|
if (server.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to validate this server",
|
message: "You are not authorized to validate this server",
|
||||||
@@ -254,7 +254,7 @@ export const serverRouter = createTRPCRouter({
|
|||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
try {
|
try {
|
||||||
const server = await findServerById(input.serverId);
|
const server = await findServerById(input.serverId);
|
||||||
if (server.adminId !== ctx.user.adminId) {
|
if (server.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to setup this server",
|
message: "You are not authorized to setup this server",
|
||||||
@@ -296,7 +296,7 @@ export const serverRouter = createTRPCRouter({
|
|||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
try {
|
try {
|
||||||
const server = await findServerById(input.serverId);
|
const server = await findServerById(input.serverId);
|
||||||
if (server.adminId !== ctx.user.adminId) {
|
if (server.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to delete this server",
|
message: "You are not authorized to delete this server",
|
||||||
@@ -315,12 +315,9 @@ export const serverRouter = createTRPCRouter({
|
|||||||
await deleteServer(input.serverId);
|
await deleteServer(input.serverId);
|
||||||
|
|
||||||
if (IS_CLOUD) {
|
if (IS_CLOUD) {
|
||||||
const admin = await findAdminById(ctx.user.adminId);
|
const admin = await findUserById(ctx.user.ownerId);
|
||||||
|
|
||||||
await updateServersBasedOnQuantity(
|
await updateServersBasedOnQuantity(admin.id, admin.serversQuantity);
|
||||||
admin.adminId,
|
|
||||||
admin.serversQuantity,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return currentServer;
|
return currentServer;
|
||||||
@@ -333,7 +330,7 @@ export const serverRouter = createTRPCRouter({
|
|||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
try {
|
try {
|
||||||
const server = await findServerById(input.serverId);
|
const server = await findServerById(input.serverId);
|
||||||
if (server.adminId !== ctx.user.adminId) {
|
if (server.userId !== ctx.user.ownerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
message: "You are not authorized to update this server",
|
message: "You are not authorized to update this server",
|
||||||
|
|||||||
@@ -47,7 +47,6 @@ import {
|
|||||||
startServiceRemote,
|
startServiceRemote,
|
||||||
stopService,
|
stopService,
|
||||||
stopServiceRemote,
|
stopServiceRemote,
|
||||||
updateAdmin,
|
|
||||||
updateLetsEncryptEmail,
|
updateLetsEncryptEmail,
|
||||||
updateServerById,
|
updateServerById,
|
||||||
updateServerTraefik,
|
updateServerTraefik,
|
||||||
@@ -383,7 +382,7 @@ export const settingsRouter = createTRPCRouter({
|
|||||||
.input(apiServerSchema)
|
.input(apiServerSchema)
|
||||||
.query(async ({ ctx, input }) => {
|
.query(async ({ ctx, input }) => {
|
||||||
try {
|
try {
|
||||||
if (ctx.user.rol === "user") {
|
if (ctx.user.rol === "member") {
|
||||||
const canAccess = await canAccessToTraefikFiles(ctx.user.authId);
|
const canAccess = await canAccessToTraefikFiles(ctx.user.authId);
|
||||||
|
|
||||||
if (!canAccess) {
|
if (!canAccess) {
|
||||||
@@ -401,7 +400,7 @@ export const settingsRouter = createTRPCRouter({
|
|||||||
updateTraefikFile: protectedProcedure
|
updateTraefikFile: protectedProcedure
|
||||||
.input(apiModifyTraefikConfig)
|
.input(apiModifyTraefikConfig)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
if (ctx.user.rol === "user") {
|
if (ctx.user.rol === "member") {
|
||||||
const canAccess = await canAccessToTraefikFiles(ctx.user.authId);
|
const canAccess = await canAccessToTraefikFiles(ctx.user.authId);
|
||||||
|
|
||||||
if (!canAccess) {
|
if (!canAccess) {
|
||||||
@@ -419,7 +418,7 @@ export const settingsRouter = createTRPCRouter({
|
|||||||
readTraefikFile: protectedProcedure
|
readTraefikFile: protectedProcedure
|
||||||
.input(apiReadTraefikConfig)
|
.input(apiReadTraefikConfig)
|
||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
if (ctx.user.rol === "user") {
|
if (ctx.user.rol === "member") {
|
||||||
const canAccess = await canAccessToTraefikFiles(ctx.user.authId);
|
const canAccess = await canAccessToTraefikFiles(ctx.user.authId);
|
||||||
|
|
||||||
if (!canAccess) {
|
if (!canAccess) {
|
||||||
@@ -655,7 +654,7 @@ export const settingsRouter = createTRPCRouter({
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}),
|
}),
|
||||||
isCloud: protectedProcedure.query(async () => {
|
isCloud: publicProcedure.query(async () => {
|
||||||
return IS_CLOUD;
|
return IS_CLOUD;
|
||||||
}),
|
}),
|
||||||
health: publicProcedure.query(async () => {
|
health: publicProcedure.query(async () => {
|
||||||
|
|||||||
@@ -24,9 +24,10 @@ export const sshRouter = createTRPCRouter({
|
|||||||
.input(apiCreateSshKey)
|
.input(apiCreateSshKey)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
try {
|
try {
|
||||||
|
console.log(ctx.user.ownerId);
|
||||||
await createSshKey({
|
await createSshKey({
|
||||||
...input,
|
...input,
|
||||||
adminId: ctx.user.adminId,
|
userId: ctx.user.ownerId,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
@@ -41,7 +42,7 @@ export const sshRouter = createTRPCRouter({
|
|||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
try {
|
try {
|
||||||
const sshKey = await findSSHKeyById(input.sshKeyId);
|
const sshKey = await findSSHKeyById(input.sshKeyId);
|
||||||
if (IS_CLOUD && sshKey.adminId !== ctx.user.adminId) {
|
if (IS_CLOUD && sshKey.userId !== ctx.user.ownerId) {
|
||||||
// TODO: Remove isCloud in the next versions of dokploy
|
// TODO: Remove isCloud in the next versions of dokploy
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
@@ -59,7 +60,7 @@ export const sshRouter = createTRPCRouter({
|
|||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
const sshKey = await findSSHKeyById(input.sshKeyId);
|
const sshKey = await findSSHKeyById(input.sshKeyId);
|
||||||
|
|
||||||
if (IS_CLOUD && sshKey.adminId !== ctx.user.adminId) {
|
if (IS_CLOUD && sshKey.userId !== ctx.user.ownerId) {
|
||||||
// TODO: Remove isCloud in the next versions of dokploy
|
// TODO: Remove isCloud in the next versions of dokploy
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
@@ -70,7 +71,7 @@ export const sshRouter = createTRPCRouter({
|
|||||||
}),
|
}),
|
||||||
all: protectedProcedure.query(async ({ ctx }) => {
|
all: protectedProcedure.query(async ({ ctx }) => {
|
||||||
return await db.query.sshKeys.findMany({
|
return await db.query.sshKeys.findMany({
|
||||||
...(IS_CLOUD && { where: eq(sshKeys.adminId, ctx.user.adminId) }),
|
...(IS_CLOUD && { where: eq(sshKeys.userId, ctx.user.ownerId) }),
|
||||||
orderBy: desc(sshKeys.createdAt),
|
orderBy: desc(sshKeys.createdAt),
|
||||||
});
|
});
|
||||||
// TODO: Remove this line when the cloud version is ready
|
// TODO: Remove this line when the cloud version is ready
|
||||||
@@ -85,7 +86,7 @@ export const sshRouter = createTRPCRouter({
|
|||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
try {
|
try {
|
||||||
const sshKey = await findSSHKeyById(input.sshKeyId);
|
const sshKey = await findSSHKeyById(input.sshKeyId);
|
||||||
if (IS_CLOUD && sshKey.adminId !== ctx.user.adminId) {
|
if (IS_CLOUD && sshKey.userId !== ctx.user.ownerId) {
|
||||||
// TODO: Remove isCloud in the next versions of dokploy
|
// TODO: Remove isCloud in the next versions of dokploy
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "UNAUTHORIZED",
|
code: "UNAUTHORIZED",
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { WEBSITE_URL, getStripeItems } from "@/server/utils/stripe";
|
import { WEBSITE_URL, getStripeItems } from "@/server/utils/stripe";
|
||||||
import {
|
import {
|
||||||
IS_CLOUD,
|
IS_CLOUD,
|
||||||
findAdminById,
|
findServersByUserId,
|
||||||
findServersByAdminId,
|
findUserById,
|
||||||
updateAdmin,
|
updateUser,
|
||||||
} from "@dokploy/server";
|
} from "@dokploy/server";
|
||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import Stripe from "stripe";
|
import Stripe from "stripe";
|
||||||
@@ -12,8 +12,8 @@ import { adminProcedure, createTRPCRouter } from "../trpc";
|
|||||||
|
|
||||||
export const stripeRouter = createTRPCRouter({
|
export const stripeRouter = createTRPCRouter({
|
||||||
getProducts: adminProcedure.query(async ({ ctx }) => {
|
getProducts: adminProcedure.query(async ({ ctx }) => {
|
||||||
const admin = await findAdminById(ctx.user.adminId);
|
const user = await findUserById(ctx.user.ownerId);
|
||||||
const stripeCustomerId = admin.stripeCustomerId;
|
const stripeCustomerId = user.stripeCustomerId;
|
||||||
|
|
||||||
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
|
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
|
||||||
apiVersion: "2024-09-30.acacia",
|
apiVersion: "2024-09-30.acacia",
|
||||||
@@ -56,15 +56,15 @@ export const stripeRouter = createTRPCRouter({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const items = getStripeItems(input.serverQuantity, input.isAnnual);
|
const items = getStripeItems(input.serverQuantity, input.isAnnual);
|
||||||
const admin = await findAdminById(ctx.user.adminId);
|
const user = await findUserById(ctx.user.ownerId);
|
||||||
|
|
||||||
let stripeCustomerId = admin.stripeCustomerId;
|
let stripeCustomerId = user.stripeCustomerId;
|
||||||
|
|
||||||
if (stripeCustomerId) {
|
if (stripeCustomerId) {
|
||||||
const customer = await stripe.customers.retrieve(stripeCustomerId);
|
const customer = await stripe.customers.retrieve(stripeCustomerId);
|
||||||
|
|
||||||
if (customer.deleted) {
|
if (customer.deleted) {
|
||||||
await updateAdmin(admin.authId, {
|
await updateUser(user.id, {
|
||||||
stripeCustomerId: null,
|
stripeCustomerId: null,
|
||||||
});
|
});
|
||||||
stripeCustomerId = null;
|
stripeCustomerId = null;
|
||||||
@@ -78,7 +78,7 @@ export const stripeRouter = createTRPCRouter({
|
|||||||
customer: stripeCustomerId,
|
customer: stripeCustomerId,
|
||||||
}),
|
}),
|
||||||
metadata: {
|
metadata: {
|
||||||
adminId: admin.adminId,
|
ownerId: user.id,
|
||||||
},
|
},
|
||||||
allow_promotion_codes: true,
|
allow_promotion_codes: true,
|
||||||
success_url: `${WEBSITE_URL}/dashboard/settings/servers?success=true`,
|
success_url: `${WEBSITE_URL}/dashboard/settings/servers?success=true`,
|
||||||
@@ -89,15 +89,15 @@ export const stripeRouter = createTRPCRouter({
|
|||||||
}),
|
}),
|
||||||
createCustomerPortalSession: adminProcedure.mutation(
|
createCustomerPortalSession: adminProcedure.mutation(
|
||||||
async ({ ctx, input }) => {
|
async ({ ctx, input }) => {
|
||||||
const admin = await findAdminById(ctx.user.adminId);
|
const user = await findUserById(ctx.user.ownerId);
|
||||||
|
|
||||||
if (!admin.stripeCustomerId) {
|
if (!user.stripeCustomerId) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "BAD_REQUEST",
|
code: "BAD_REQUEST",
|
||||||
message: "Stripe Customer ID not found",
|
message: "Stripe Customer ID not found",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const stripeCustomerId = admin.stripeCustomerId;
|
const stripeCustomerId = user.stripeCustomerId;
|
||||||
|
|
||||||
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
|
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
|
||||||
apiVersion: "2024-09-30.acacia",
|
apiVersion: "2024-09-30.acacia",
|
||||||
@@ -119,13 +119,13 @@ export const stripeRouter = createTRPCRouter({
|
|||||||
),
|
),
|
||||||
|
|
||||||
canCreateMoreServers: adminProcedure.query(async ({ ctx }) => {
|
canCreateMoreServers: adminProcedure.query(async ({ ctx }) => {
|
||||||
const admin = await findAdminById(ctx.user.adminId);
|
const user = await findUserById(ctx.user.ownerId);
|
||||||
const servers = await findServersByAdminId(admin.adminId);
|
const servers = await findServersByUserId(user.id);
|
||||||
|
|
||||||
if (!IS_CLOUD) {
|
if (!IS_CLOUD) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return servers.length < admin.serversQuantity;
|
return servers.length < user.serversQuantity;
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -9,7 +9,8 @@
|
|||||||
|
|
||||||
// import { getServerAuthSession } from "@/server/auth";
|
// import { getServerAuthSession } from "@/server/auth";
|
||||||
import { db } from "@/server/db";
|
import { db } from "@/server/db";
|
||||||
import { validateBearerToken, validateRequest } from "@dokploy/server";
|
import { validateBearerToken } from "@dokploy/server";
|
||||||
|
import { validateRequest } from "@dokploy/server/lib/auth";
|
||||||
import type { OpenApiMeta } from "@dokploy/trpc-openapi";
|
import type { OpenApiMeta } from "@dokploy/trpc-openapi";
|
||||||
import { TRPCError, initTRPC } from "@trpc/server";
|
import { TRPCError, initTRPC } from "@trpc/server";
|
||||||
import type { CreateNextContextOptions } from "@trpc/server/adapters/next";
|
import type { CreateNextContextOptions } from "@trpc/server/adapters/next";
|
||||||
@@ -18,7 +19,7 @@ import {
|
|||||||
experimental_isMultipartFormDataRequest,
|
experimental_isMultipartFormDataRequest,
|
||||||
experimental_parseMultipartFormData,
|
experimental_parseMultipartFormData,
|
||||||
} from "@trpc/server/adapters/node-http/content-type/form-data";
|
} from "@trpc/server/adapters/node-http/content-type/form-data";
|
||||||
import type { Session, User } from "lucia";
|
import type { Session, User } from "better-auth";
|
||||||
import superjson from "superjson";
|
import superjson from "superjson";
|
||||||
import { ZodError } from "zod";
|
import { ZodError } from "zod";
|
||||||
/**
|
/**
|
||||||
@@ -30,8 +31,8 @@ import { ZodError } from "zod";
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
interface CreateContextOptions {
|
interface CreateContextOptions {
|
||||||
user: (User & { authId: string; adminId: string }) | null;
|
user: (User & { rol: "member" | "admin" | "owner"; ownerId: string }) | null;
|
||||||
session: Session | null;
|
session: (Session & { activeOrganizationId?: string }) | null;
|
||||||
req: CreateNextContextOptions["req"];
|
req: CreateNextContextOptions["req"];
|
||||||
res: CreateNextContextOptions["res"];
|
res: CreateNextContextOptions["res"];
|
||||||
}
|
}
|
||||||
@@ -65,30 +66,36 @@ const createInnerTRPCContext = (opts: CreateContextOptions) => {
|
|||||||
export const createTRPCContext = async (opts: CreateNextContextOptions) => {
|
export const createTRPCContext = async (opts: CreateNextContextOptions) => {
|
||||||
const { req, res } = opts;
|
const { req, res } = opts;
|
||||||
|
|
||||||
let { session, user } = await validateBearerToken(req);
|
// Get from the request
|
||||||
|
const { session, user } = await validateRequest(req);
|
||||||
|
|
||||||
if (!session) {
|
// if (!session) {
|
||||||
const cookieResult = await validateRequest(req, res);
|
// const cookieResult = await validateRequest(req);
|
||||||
session = cookieResult.session;
|
// session = cookieResult.session;
|
||||||
user = cookieResult.user;
|
// user = cookieResult.user;
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
console.log("session", session);
|
||||||
|
console.log("user", user);
|
||||||
|
|
||||||
return createInnerTRPCContext({
|
return createInnerTRPCContext({
|
||||||
req,
|
req,
|
||||||
res,
|
res,
|
||||||
session: session,
|
session: session
|
||||||
...((user && {
|
? {
|
||||||
user: {
|
...session,
|
||||||
authId: user.id,
|
activeOrganizationId: session.activeOrganizationId ?? undefined,
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
user: user
|
||||||
|
? {
|
||||||
|
...user,
|
||||||
email: user.email,
|
email: user.email,
|
||||||
rol: user.rol,
|
rol: user.role as "owner" | "member" | "admin",
|
||||||
id: user.id,
|
id: user.id,
|
||||||
secret: user.secret,
|
ownerId: user.ownerId,
|
||||||
adminId: user.adminId,
|
}
|
||||||
},
|
: null,
|
||||||
}) || {
|
|
||||||
user: null,
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -181,7 +188,7 @@ export const uploadProcedure = async (opts: any) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const cliProcedure = t.procedure.use(({ ctx, next }) => {
|
export const cliProcedure = t.procedure.use(({ ctx, next }) => {
|
||||||
if (!ctx.session || !ctx.user || ctx.user.rol !== "admin") {
|
if (!ctx.session || !ctx.user || ctx.user.rol !== "owner") {
|
||||||
throw new TRPCError({ code: "UNAUTHORIZED" });
|
throw new TRPCError({ code: "UNAUTHORIZED" });
|
||||||
}
|
}
|
||||||
return next({
|
return next({
|
||||||
@@ -195,7 +202,7 @@ export const cliProcedure = t.procedure.use(({ ctx, next }) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const adminProcedure = t.procedure.use(({ ctx, next }) => {
|
export const adminProcedure = t.procedure.use(({ ctx, next }) => {
|
||||||
if (!ctx.session || !ctx.user || ctx.user.rol !== "admin") {
|
if (!ctx.session || !ctx.user || ctx.user.rol !== "owner") {
|
||||||
throw new TRPCError({ code: "UNAUTHORIZED" });
|
throw new TRPCError({ code: "UNAUTHORIZED" });
|
||||||
}
|
}
|
||||||
return next({
|
return next({
|
||||||
|
|||||||
@@ -34,14 +34,14 @@ void app.prepare().then(async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// WEBSOCKET
|
// WEBSOCKET
|
||||||
setupDrawerLogsWebSocketServer(server);
|
// setupDrawerLogsWebSocketServer(server);
|
||||||
setupDeploymentLogsWebSocketServer(server);
|
// setupDeploymentLogsWebSocketServer(server);
|
||||||
setupDockerContainerLogsWebSocketServer(server);
|
// setupDockerContainerLogsWebSocketServer(server);
|
||||||
setupDockerContainerTerminalWebSocketServer(server);
|
// setupDockerContainerTerminalWebSocketServer(server);
|
||||||
setupTerminalWebSocketServer(server);
|
// setupTerminalWebSocketServer(server);
|
||||||
if (!IS_CLOUD) {
|
// if (!IS_CLOUD) {
|
||||||
setupDockerStatsMonitoringSocketServer(server);
|
// setupDockerStatsMonitoringSocketServer(server);
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (process.env.NODE_ENV === "production" && !IS_CLOUD) {
|
if (process.env.NODE_ENV === "production" && !IS_CLOUD) {
|
||||||
setupDirectories();
|
setupDirectories();
|
||||||
|
|||||||
@@ -4,8 +4,7 @@ services:
|
|||||||
activepieces:
|
activepieces:
|
||||||
image: activepieces/activepieces:0.35.0
|
image: activepieces/activepieces:0.35.0
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
networks:
|
|
||||||
- dokploy-network
|
|
||||||
depends_on:
|
depends_on:
|
||||||
postgres:
|
postgres:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
@@ -35,8 +34,7 @@ services:
|
|||||||
postgres:
|
postgres:
|
||||||
image: postgres:14
|
image: postgres:14
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
networks:
|
|
||||||
- dokploy-network
|
|
||||||
environment:
|
environment:
|
||||||
POSTGRES_DB: activepieces
|
POSTGRES_DB: activepieces
|
||||||
POSTGRES_PASSWORD: ${AP_POSTGRES_PASSWORD}
|
POSTGRES_PASSWORD: ${AP_POSTGRES_PASSWORD}
|
||||||
@@ -52,8 +50,7 @@ services:
|
|||||||
redis:
|
redis:
|
||||||
image: redis:7
|
image: redis:7
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
networks:
|
|
||||||
- dokploy-network
|
|
||||||
volumes:
|
volumes:
|
||||||
- redis_data:/data
|
- redis_data:/data
|
||||||
healthcheck:
|
healthcheck:
|
||||||
|
|||||||
@@ -17,8 +17,7 @@ services:
|
|||||||
interval: 5s
|
interval: 5s
|
||||||
timeout: 5s
|
timeout: 5s
|
||||||
retries: 5
|
retries: 5
|
||||||
networks:
|
|
||||||
- dokploy-network
|
|
||||||
volumes:
|
volumes:
|
||||||
- db-data:/var/lib/postgresql/data
|
- db-data:/var/lib/postgresql/data
|
||||||
environment:
|
environment:
|
||||||
|
|||||||
@@ -7,8 +7,7 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
POSTGRES_USER: aptabase
|
POSTGRES_USER: aptabase
|
||||||
POSTGRES_PASSWORD: sTr0NGp4ssw0rd
|
POSTGRES_PASSWORD: sTr0NGp4ssw0rd
|
||||||
networks:
|
|
||||||
- dokploy-network
|
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD-SHELL", "pg_isready -U aptabase"]
|
test: ["CMD-SHELL", "pg_isready -U aptabase"]
|
||||||
interval: 10s
|
interval: 10s
|
||||||
@@ -27,8 +26,7 @@ services:
|
|||||||
nofile:
|
nofile:
|
||||||
soft: 262144
|
soft: 262144
|
||||||
hard: 262144
|
hard: 262144
|
||||||
networks:
|
|
||||||
- dokploy-network
|
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD-SHELL", "curl -f http://localhost:8123 || exit 1"]
|
test: ["CMD-SHELL", "curl -f http://localhost:8123 || exit 1"]
|
||||||
interval: 10s
|
interval: 10s
|
||||||
|
|||||||
@@ -2,8 +2,7 @@ services:
|
|||||||
apps:
|
apps:
|
||||||
image: budibase.docker.scarf.sh/budibase/apps:3.2.25
|
image: budibase.docker.scarf.sh/budibase/apps:3.2.25
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
networks:
|
|
||||||
- dokploy-network
|
|
||||||
environment:
|
environment:
|
||||||
SELF_HOSTED: 1
|
SELF_HOSTED: 1
|
||||||
LOG_LEVEL: info
|
LOG_LEVEL: info
|
||||||
@@ -43,8 +42,7 @@ services:
|
|||||||
worker:
|
worker:
|
||||||
image: budibase.docker.scarf.sh/budibase/worker:3.2.25
|
image: budibase.docker.scarf.sh/budibase/worker:3.2.25
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
networks:
|
|
||||||
- dokploy-network
|
|
||||||
environment:
|
environment:
|
||||||
SELF_HOSTED: 1
|
SELF_HOSTED: 1
|
||||||
LOG_LEVEL: info
|
LOG_LEVEL: info
|
||||||
@@ -83,8 +81,7 @@ services:
|
|||||||
minio:
|
minio:
|
||||||
image: minio/minio:RELEASE.2024-11-07T00-52-20Z
|
image: minio/minio:RELEASE.2024-11-07T00-52-20Z
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
networks:
|
|
||||||
- dokploy-network
|
|
||||||
volumes:
|
volumes:
|
||||||
- 'minio_data:/data'
|
- 'minio_data:/data'
|
||||||
environment:
|
environment:
|
||||||
@@ -104,8 +101,7 @@ services:
|
|||||||
proxy:
|
proxy:
|
||||||
image: budibase/proxy:3.2.25
|
image: budibase/proxy:3.2.25
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
networks:
|
|
||||||
- dokploy-network
|
|
||||||
environment:
|
environment:
|
||||||
PROXY_RATE_LIMIT_WEBHOOKS_PER_SECOND: 10
|
PROXY_RATE_LIMIT_WEBHOOKS_PER_SECOND: 10
|
||||||
PROXY_RATE_LIMIT_API_PER_SECOND: 20
|
PROXY_RATE_LIMIT_API_PER_SECOND: 20
|
||||||
@@ -137,8 +133,7 @@ services:
|
|||||||
couchdb:
|
couchdb:
|
||||||
image: budibase/couchdb:v3.3.3
|
image: budibase/couchdb:v3.3.3
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
networks:
|
|
||||||
- dokploy-network
|
|
||||||
environment:
|
environment:
|
||||||
COUCHDB_USER: budibase
|
COUCHDB_USER: budibase
|
||||||
COUCHDB_PASSWORD: ${BB_COUCHDB_PASSWORD}
|
COUCHDB_PASSWORD: ${BB_COUCHDB_PASSWORD}
|
||||||
@@ -157,8 +152,7 @@ services:
|
|||||||
- 'couchdb3_data:/opt/couchdb/data'
|
- 'couchdb3_data:/opt/couchdb/data'
|
||||||
redis:
|
redis:
|
||||||
image: redis:7.2-alpine
|
image: redis:7.2-alpine
|
||||||
networks:
|
|
||||||
- dokploy-network
|
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
command: 'redis-server --requirepass "${BB_REDIS_PASSWORD}"'
|
command: 'redis-server --requirepass "${BB_REDIS_PASSWORD}"'
|
||||||
volumes:
|
volumes:
|
||||||
@@ -176,8 +170,7 @@ services:
|
|||||||
start_period: 10s
|
start_period: 10s
|
||||||
watchtower:
|
watchtower:
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
networks:
|
|
||||||
- dokploy-network
|
|
||||||
image: containrrr/watchtower:1.7.1
|
image: containrrr/watchtower:1.7.1
|
||||||
volumes:
|
volumes:
|
||||||
- '/var/run/docker.sock:/var/run/docker.sock'
|
- '/var/run/docker.sock:/var/run/docker.sock'
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
services:
|
services:
|
||||||
postgres:
|
postgres:
|
||||||
image: postgres:16-alpine
|
image: postgres:16-alpine
|
||||||
networks:
|
|
||||||
- dokploy-network
|
|
||||||
volumes:
|
volumes:
|
||||||
- calcom-data:/var/lib/postgresql/data
|
- calcom-data:/var/lib/postgresql/data
|
||||||
environment:
|
environment:
|
||||||
|
|||||||
@@ -51,8 +51,7 @@ services:
|
|||||||
restart: always
|
restart: always
|
||||||
volumes:
|
volumes:
|
||||||
- chatwoot-postgres-data:/var/lib/postgresql/data
|
- chatwoot-postgres-data:/var/lib/postgresql/data
|
||||||
networks:
|
|
||||||
- dokploy-network
|
|
||||||
environment:
|
environment:
|
||||||
- POSTGRES_DB=${POSTGRES_DATABASE}
|
- POSTGRES_DB=${POSTGRES_DATABASE}
|
||||||
- POSTGRES_USER=${POSTGRES_USERNAME}
|
- POSTGRES_USER=${POSTGRES_USERNAME}
|
||||||
@@ -63,8 +62,7 @@ services:
|
|||||||
restart: always
|
restart: always
|
||||||
volumes:
|
volumes:
|
||||||
- chatwoot-redis-data:/data
|
- chatwoot-redis-data:/data
|
||||||
networks:
|
|
||||||
- dokploy-network
|
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
dokploy-network:
|
dokploy-network:
|
||||||
|
|||||||
@@ -9,8 +9,7 @@ services:
|
|||||||
- 443
|
- 443
|
||||||
depends_on:
|
depends_on:
|
||||||
- server
|
- server
|
||||||
networks:
|
|
||||||
- dokploy-network
|
|
||||||
server:
|
server:
|
||||||
image: bluewaveuptime/uptime_server:latest
|
image: bluewaveuptime/uptime_server:latest
|
||||||
restart: always
|
restart: always
|
||||||
@@ -22,8 +21,7 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
- DB_CONNECTION_STRING=mongodb://mongodb:27017/uptime_db
|
- DB_CONNECTION_STRING=mongodb://mongodb:27017/uptime_db
|
||||||
- REDIS_HOST=redis
|
- REDIS_HOST=redis
|
||||||
networks:
|
|
||||||
- dokploy-network
|
|
||||||
# volumes:
|
# volumes:
|
||||||
# - /var/run/docker.sock:/var/run/docker.sock:ro
|
# - /var/run/docker.sock:/var/run/docker.sock:ro
|
||||||
redis:
|
redis:
|
||||||
@@ -33,8 +31,7 @@ services:
|
|||||||
- 6379
|
- 6379
|
||||||
volumes:
|
volumes:
|
||||||
- ../files/redis/data:/data
|
- ../files/redis/data:/data
|
||||||
networks:
|
|
||||||
- dokploy-network
|
|
||||||
mongodb:
|
mongodb:
|
||||||
image: bluewaveuptime/uptime_database_mongo:latest
|
image: bluewaveuptime/uptime_database_mongo:latest
|
||||||
restart: always
|
restart: always
|
||||||
@@ -43,5 +40,3 @@ services:
|
|||||||
command: ["mongod", "--quiet"]
|
command: ["mongod", "--quiet"]
|
||||||
ports:
|
ports:
|
||||||
- 27017
|
- 27017
|
||||||
networks:
|
|
||||||
- dokploy-network
|
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
services:
|
services:
|
||||||
coder:
|
coder:
|
||||||
image: ghcr.io/coder/coder:v2.15.3
|
image: ghcr.io/coder/coder:v2.15.3
|
||||||
networks:
|
|
||||||
- dokploy-network
|
|
||||||
volumes:
|
volumes:
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
group_add:
|
group_add:
|
||||||
@@ -17,8 +16,7 @@ services:
|
|||||||
|
|
||||||
db:
|
db:
|
||||||
image: postgres:17
|
image: postgres:17
|
||||||
networks:
|
|
||||||
- dokploy-network
|
|
||||||
environment:
|
environment:
|
||||||
- POSTGRES_PASSWORD
|
- POSTGRES_PASSWORD
|
||||||
- POSTGRES_USER
|
- POSTGRES_USER
|
||||||
|
|||||||
@@ -3,8 +3,7 @@ services:
|
|||||||
image: postgis/postgis:13-master
|
image: postgis/postgis:13-master
|
||||||
volumes:
|
volumes:
|
||||||
- directus_database:/var/lib/postgresql/data
|
- directus_database:/var/lib/postgresql/data
|
||||||
networks:
|
|
||||||
- dokploy-network
|
|
||||||
environment:
|
environment:
|
||||||
POSTGRES_USER: "directus"
|
POSTGRES_USER: "directus"
|
||||||
POSTGRES_PASSWORD: ${DATABASE_PASSWORD}
|
POSTGRES_PASSWORD: ${DATABASE_PASSWORD}
|
||||||
@@ -26,8 +25,7 @@ services:
|
|||||||
retries: 5
|
retries: 5
|
||||||
start_interval: 5s
|
start_interval: 5s
|
||||||
start_period: 30s
|
start_period: 30s
|
||||||
networks:
|
|
||||||
- dokploy-network
|
|
||||||
|
|
||||||
directus:
|
directus:
|
||||||
image: directus/directus:11.0.2
|
image: directus/directus:11.0.2
|
||||||
|
|||||||
@@ -4,8 +4,7 @@ services:
|
|||||||
tickets-postgres:
|
tickets-postgres:
|
||||||
image: mysql:8
|
image: mysql:8
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
networks:
|
|
||||||
- dokploy-network
|
|
||||||
volumes:
|
volumes:
|
||||||
- tickets-mysql-data:/var/lib/mysql
|
- tickets-mysql-data:/var/lib/mysql
|
||||||
environment:
|
environment:
|
||||||
@@ -25,8 +24,7 @@ services:
|
|||||||
tickets-postgres:
|
tickets-postgres:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
networks:
|
|
||||||
- dokploy-network
|
|
||||||
volumes:
|
volumes:
|
||||||
- tickets-app-data:/home/container/user
|
- tickets-app-data:/home/container/user
|
||||||
- /etc/timezone:/etc/timezone:ro
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user