mirror of
https://github.com/Dokploy/dokploy.git
synced 2026-10-18 22:51:36 +00:00
Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8b71f963cc | |||
| 1c5cc5a0db | |||
| d233f2c764 | |||
| 1bbb4c9b64 | |||
| 6ec60b6bab | |||
| 55abac3f2f | |||
| b6c29ccf05 | |||
| ca217affe6 | |||
| 5c24281f72 | |||
| bc901bcb25 | |||
| 7c0d223e17 | |||
| 74ee024cf9 | |||
| 140a871275 | |||
| d1f72a2e20 | |||
| 0d525398a8 | |||
| 7c62408070 | |||
| 23f1ce17de | |||
| 60eee55f2d | |||
| 8f562eefc1 | |||
| 6179cef1ee | |||
| b7112b89fd | |||
| 1db6ba94f4 | |||
| afd3d2eea3 | |||
| 8bd72a8a34 | |||
| fafc238e70 | |||
| c04bf3c7e0 |
@@ -21,6 +21,7 @@ import {
|
||||
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { authClient } from "@/lib/auth";
|
||||
import { api } from "@/utils/api";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
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 (
|
||||
<Dialog open={isOpen} onOpenChange={setIsOpen}>
|
||||
|
||||
@@ -57,7 +57,7 @@ export const ShowProjects = () => {
|
||||
authId: auth?.id || "",
|
||||
},
|
||||
{
|
||||
enabled: !!auth?.id && auth?.rol === "user",
|
||||
enabled: !!auth?.id && auth?.role === "member",
|
||||
},
|
||||
);
|
||||
const { mutateAsync } = api.project.remove.useMutation();
|
||||
@@ -91,7 +91,7 @@ export const ShowProjects = () => {
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
|
||||
{(auth?.rol === "admin" || user?.canCreateProjects) && (
|
||||
{(auth?.role === "owner" || user?.canCreateProjects) && (
|
||||
<div className="">
|
||||
<HandleProject />
|
||||
</div>
|
||||
@@ -293,7 +293,7 @@ export const ShowProjects = () => {
|
||||
<div
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
{(auth?.rol === "admin" ||
|
||||
{(auth?.role === "owner" ||
|
||||
user?.canDeleteProjects) && (
|
||||
<AlertDialog>
|
||||
<AlertDialogTrigger className="w-full">
|
||||
|
||||
@@ -18,6 +18,7 @@ import {
|
||||
CommandList,
|
||||
CommandSeparator,
|
||||
} from "@/components/ui/command";
|
||||
import { authClient } from "@/lib/auth";
|
||||
import {
|
||||
type Services,
|
||||
extractServices,
|
||||
@@ -35,8 +36,10 @@ export const SearchCommand = () => {
|
||||
const router = useRouter();
|
||||
const [open, setOpen] = React.useState(false);
|
||||
const [search, setSearch] = React.useState("");
|
||||
|
||||
const { data } = api.project.all.useQuery();
|
||||
const { data: session } = authClient.getSession();
|
||||
const { data } = api.project.all.useQuery(undefined, {
|
||||
enabled: !!session,
|
||||
});
|
||||
const { data: isCloud, isLoading } = api.settings.isCloud.useQuery();
|
||||
|
||||
React.useEffect(() => {
|
||||
|
||||
@@ -15,7 +15,7 @@ export const ShowWelcomeDokploy = () => {
|
||||
|
||||
const { data: isCloud, isLoading } = api.settings.isCloud.useQuery();
|
||||
|
||||
if (!isCloud || data?.rol !== "admin") {
|
||||
if (!isCloud || data?.role !== "admin") {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -24,14 +24,14 @@ export const ShowWelcomeDokploy = () => {
|
||||
!isLoading &&
|
||||
isCloud &&
|
||||
!localStorage.getItem("hasSeenCloudWelcomeModal") &&
|
||||
data?.rol === "admin"
|
||||
data?.role === "owner"
|
||||
) {
|
||||
setOpen(true);
|
||||
}
|
||||
}, [isCloud, isLoading]);
|
||||
|
||||
const handleClose = (isOpen: boolean) => {
|
||||
if (data?.rol === "admin") {
|
||||
if (data?.role === "owner") {
|
||||
setOpen(isOpen);
|
||||
if (!isOpen) {
|
||||
localStorage.setItem("hasSeenCloudWelcomeModal", "true"); // Establece el flag al cerrar el modal
|
||||
|
||||
@@ -51,7 +51,7 @@ export const GenerateToken = () => {
|
||||
<Label>Token</Label>
|
||||
<ToggleVisibilityInput
|
||||
placeholder="Token"
|
||||
value={data?.token || ""}
|
||||
value={data?.user?.token || ""}
|
||||
disabled
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -73,9 +73,9 @@ export const ProfileForm = () => {
|
||||
|
||||
const form = useForm<Profile>({
|
||||
defaultValues: {
|
||||
email: data?.email || "",
|
||||
email: data?.user?.email || "",
|
||||
password: "",
|
||||
image: data?.image || "",
|
||||
image: data?.user?.image || "",
|
||||
currentPassword: "",
|
||||
},
|
||||
resolver: zodResolver(profileSchema),
|
||||
@@ -84,14 +84,14 @@ export const ProfileForm = () => {
|
||||
useEffect(() => {
|
||||
if (data) {
|
||||
form.reset({
|
||||
email: data?.email || "",
|
||||
email: data?.user?.email || "",
|
||||
password: "",
|
||||
image: data?.image || "",
|
||||
image: data?.user?.image || "",
|
||||
currentPassword: "",
|
||||
});
|
||||
|
||||
if (data.email) {
|
||||
generateSHA256Hash(data.email).then((hash) => {
|
||||
if (data.user.email) {
|
||||
generateSHA256Hash(data.user.email).then((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
|
||||
isEnabled: ({ auth, user, isCloud }) =>
|
||||
!!(
|
||||
(auth?.rol === "admin" || user?.canAccessToTraefikFiles) &&
|
||||
(auth?.role === "owner" || user?.canAccessToTraefikFiles) &&
|
||||
!isCloud
|
||||
),
|
||||
},
|
||||
@@ -166,7 +166,7 @@ const MENU: Menu = {
|
||||
icon: BlocksIcon,
|
||||
// Only enabled for admins and users with access to Docker in non-cloud environments
|
||||
isEnabled: ({ auth, user, isCloud }) =>
|
||||
!!((auth?.rol === "admin" || user?.canAccessToDocker) && !isCloud),
|
||||
!!((auth?.role === "owner" || user?.canAccessToDocker) && !isCloud),
|
||||
},
|
||||
{
|
||||
isSingle: true,
|
||||
@@ -175,7 +175,7 @@ const MENU: Menu = {
|
||||
icon: PieChart,
|
||||
// Only enabled for admins and users with access to Docker in non-cloud environments
|
||||
isEnabled: ({ auth, user, isCloud }) =>
|
||||
!!((auth?.rol === "admin" || user?.canAccessToDocker) && !isCloud),
|
||||
!!((auth?.role === "owner" || user?.canAccessToDocker) && !isCloud),
|
||||
},
|
||||
{
|
||||
isSingle: true,
|
||||
@@ -184,7 +184,7 @@ const MENU: Menu = {
|
||||
icon: Forward,
|
||||
// Only enabled for admins and users with access to Docker in non-cloud environments
|
||||
isEnabled: ({ auth, user, isCloud }) =>
|
||||
!!((auth?.rol === "admin" || user?.canAccessToDocker) && !isCloud),
|
||||
!!((auth?.role === "owner" || user?.canAccessToDocker) && !isCloud),
|
||||
},
|
||||
|
||||
// Legacy unused menu, adjusted to the new structure
|
||||
@@ -252,7 +252,7 @@ const MENU: Menu = {
|
||||
icon: Activity,
|
||||
// Only enabled for admins in non-cloud environments
|
||||
isEnabled: ({ auth, user, isCloud }) =>
|
||||
!!(auth?.rol === "admin" && !isCloud),
|
||||
!!(auth?.role === "owner" && !isCloud),
|
||||
},
|
||||
{
|
||||
isSingle: true,
|
||||
@@ -266,7 +266,7 @@ const MENU: Menu = {
|
||||
url: "/dashboard/settings/servers",
|
||||
icon: Server,
|
||||
// Only enabled for admins
|
||||
isEnabled: ({ auth, user, isCloud }) => !!(auth?.rol === "admin"),
|
||||
isEnabled: ({ auth, user, isCloud }) => !!(auth?.role === "owner"),
|
||||
},
|
||||
{
|
||||
isSingle: true,
|
||||
@@ -274,7 +274,7 @@ const MENU: Menu = {
|
||||
icon: Users,
|
||||
url: "/dashboard/settings/users",
|
||||
// Only enabled for admins
|
||||
isEnabled: ({ auth, user, isCloud }) => !!(auth?.rol === "admin"),
|
||||
isEnabled: ({ auth, user, isCloud }) => !!(auth?.role === "owner"),
|
||||
},
|
||||
{
|
||||
isSingle: true,
|
||||
@@ -283,7 +283,7 @@ const MENU: Menu = {
|
||||
url: "/dashboard/settings/ssh-keys",
|
||||
// Only enabled for admins and users with access to SSH keys
|
||||
isEnabled: ({ auth, user }) =>
|
||||
!!(auth?.rol === "admin" || user?.canAccessToSSHKeys),
|
||||
!!(auth?.role === "owner" || user?.canAccessToSSHKeys),
|
||||
},
|
||||
{
|
||||
isSingle: true,
|
||||
@@ -292,7 +292,7 @@ const MENU: Menu = {
|
||||
icon: GitBranch,
|
||||
// Only enabled for admins and users with access to Git providers
|
||||
isEnabled: ({ auth, user }) =>
|
||||
!!(auth?.rol === "admin" || user?.canAccessToGitProviders),
|
||||
!!(auth?.role === "owner" || user?.canAccessToGitProviders),
|
||||
},
|
||||
{
|
||||
isSingle: true,
|
||||
@@ -300,7 +300,7 @@ const MENU: Menu = {
|
||||
url: "/dashboard/settings/registry",
|
||||
icon: Package,
|
||||
// Only enabled for admins
|
||||
isEnabled: ({ auth, user, isCloud }) => !!(auth?.rol === "admin"),
|
||||
isEnabled: ({ auth, user, isCloud }) => !!(auth?.role === "owner"),
|
||||
},
|
||||
{
|
||||
isSingle: true,
|
||||
@@ -308,7 +308,7 @@ const MENU: Menu = {
|
||||
url: "/dashboard/settings/destinations",
|
||||
icon: Database,
|
||||
// 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",
|
||||
icon: ShieldCheck,
|
||||
// Only enabled for admins
|
||||
isEnabled: ({ auth, user, isCloud }) => !!(auth?.rol === "admin"),
|
||||
isEnabled: ({ auth, user, isCloud }) => !!(auth?.role === "owner"),
|
||||
},
|
||||
{
|
||||
isSingle: true,
|
||||
@@ -326,7 +326,7 @@ const MENU: Menu = {
|
||||
icon: Boxes,
|
||||
// Only enabled for admins in non-cloud environments
|
||||
isEnabled: ({ auth, user, isCloud }) =>
|
||||
!!(auth?.rol === "admin" && !isCloud),
|
||||
!!(auth?.role === "owner" && !isCloud),
|
||||
},
|
||||
{
|
||||
isSingle: true,
|
||||
@@ -334,7 +334,7 @@ const MENU: Menu = {
|
||||
url: "/dashboard/settings/notifications",
|
||||
icon: Bell,
|
||||
// Only enabled for admins
|
||||
isEnabled: ({ auth, user, isCloud }) => !!(auth?.rol === "admin"),
|
||||
isEnabled: ({ auth, user, isCloud }) => !!(auth?.role === "owner"),
|
||||
},
|
||||
{
|
||||
isSingle: true,
|
||||
@@ -343,7 +343,7 @@ const MENU: Menu = {
|
||||
icon: CreditCard,
|
||||
// Only enabled for admins in cloud environments
|
||||
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 || "",
|
||||
},
|
||||
{
|
||||
enabled: !!auth?.id && auth?.rol === "user",
|
||||
enabled: !!auth?.id && auth?.role === "member",
|
||||
},
|
||||
);
|
||||
|
||||
@@ -557,7 +557,7 @@ export default function Page({ children }: Props) {
|
||||
|
||||
// const showProjectsButton =
|
||||
// currentPath === "/dashboard/projects" &&
|
||||
// (auth?.rol === "admin" || user?.canCreateProjects);
|
||||
// (auth?.rol === "owner" || user?.canCreateProjects);
|
||||
|
||||
return (
|
||||
<SidebarProvider
|
||||
@@ -783,7 +783,7 @@ export default function Page({ children }: Props) {
|
||||
</SidebarMenuButton>
|
||||
</SidebarMenuItem>
|
||||
))}
|
||||
{!isCloud && auth?.rol === "admin" && (
|
||||
{!isCloud && auth?.role === "owner" && (
|
||||
<SidebarMenuItem>
|
||||
<SidebarMenuButton asChild>
|
||||
<UpdateServerButton />
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
import { authClient } from "@/lib/auth";
|
||||
import { Languages } from "@/lib/languages";
|
||||
import { api } from "@/utils/api";
|
||||
import useLocale from "@/utils/hooks/use-locale";
|
||||
@@ -36,11 +37,11 @@ export const UserNav = () => {
|
||||
authId: data?.id || "",
|
||||
},
|
||||
{
|
||||
enabled: !!data?.id && data?.rol === "user",
|
||||
enabled: !!data?.id && data?.role === "member",
|
||||
},
|
||||
);
|
||||
const { locale, setLocale } = useLocale();
|
||||
const { mutateAsync } = api.auth.logout.useMutation();
|
||||
// const { mutateAsync } = api.auth.logout.useMutation();
|
||||
|
||||
return (
|
||||
<DropdownMenu>
|
||||
@@ -50,12 +51,15 @@ export const UserNav = () => {
|
||||
className="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground"
|
||||
>
|
||||
<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>
|
||||
</Avatar>
|
||||
<div className="grid flex-1 text-left text-sm leading-tight">
|
||||
<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>
|
||||
<ChevronsUpDown className="ml-auto size-4" />
|
||||
</SidebarMenuButton>
|
||||
@@ -70,7 +74,7 @@ export const UserNav = () => {
|
||||
<DropdownMenuLabel className="flex flex-col">
|
||||
My Account
|
||||
<span className="text-xs font-normal text-muted-foreground">
|
||||
{data?.email}
|
||||
{data?.user?.email}
|
||||
</span>
|
||||
</DropdownMenuLabel>
|
||||
<ModeToggle />
|
||||
@@ -95,7 +99,7 @@ export const UserNav = () => {
|
||||
>
|
||||
Monitoring
|
||||
</DropdownMenuItem>
|
||||
{(data?.rol === "admin" || user?.canAccessToTraefikFiles) && (
|
||||
{(data?.role === "owner" || user?.canAccessToTraefikFiles) && (
|
||||
<DropdownMenuItem
|
||||
className="cursor-pointer"
|
||||
onClick={() => {
|
||||
@@ -105,7 +109,7 @@ export const UserNav = () => {
|
||||
Traefik
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
{(data?.rol === "admin" || user?.canAccessToDocker) && (
|
||||
{(data?.role === "owner" || user?.canAccessToDocker) && (
|
||||
<DropdownMenuItem
|
||||
className="cursor-pointer"
|
||||
onClick={() => {
|
||||
@@ -118,7 +122,7 @@ export const UserNav = () => {
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
|
||||
{data?.rol === "admin" && (
|
||||
{data?.role === "owner" && (
|
||||
<DropdownMenuItem
|
||||
className="cursor-pointer"
|
||||
onClick={() => {
|
||||
@@ -139,7 +143,7 @@ export const UserNav = () => {
|
||||
>
|
||||
Profile
|
||||
</DropdownMenuItem>
|
||||
{data?.rol === "admin" && (
|
||||
{data?.role === "owner" && (
|
||||
<DropdownMenuItem
|
||||
className="cursor-pointer"
|
||||
onClick={() => {
|
||||
@@ -150,7 +154,7 @@ export const UserNav = () => {
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
|
||||
{data?.rol === "admin" && (
|
||||
{data?.role === "owner" && (
|
||||
<DropdownMenuItem
|
||||
className="cursor-pointer"
|
||||
onClick={() => {
|
||||
@@ -163,7 +167,7 @@ export const UserNav = () => {
|
||||
</>
|
||||
)}
|
||||
</DropdownMenuGroup>
|
||||
{isCloud && data?.rol === "admin" && (
|
||||
{isCloud && data?.role === "owner" && (
|
||||
<DropdownMenuItem
|
||||
className="cursor-pointer"
|
||||
onClick={() => {
|
||||
@@ -178,9 +182,12 @@ export const UserNav = () => {
|
||||
<DropdownMenuItem
|
||||
className="cursor-pointer"
|
||||
onClick={async () => {
|
||||
await mutateAsync().then(() => {
|
||||
await authClient.signOut().then(() => {
|
||||
router.push("/");
|
||||
});
|
||||
// await mutateAsync().then(() => {
|
||||
// router.push("/");
|
||||
// });
|
||||
}}
|
||||
>
|
||||
Log out
|
||||
|
||||
@@ -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;
|
||||
@@ -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";
|
||||
@@ -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;
|
||||
@@ -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();
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -463,6 +463,34 @@
|
||||
"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
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -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()],
|
||||
});
|
||||
@@ -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);
|
||||
});
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "dokploy",
|
||||
"version": "v0.18.3",
|
||||
"version": "v0.18.2",
|
||||
"private": true,
|
||||
"license": "Apache-2.0",
|
||||
"type": "module",
|
||||
@@ -16,6 +16,7 @@
|
||||
"studio": "drizzle-kit studio --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",
|
||||
"manual-migration:run": "tsx -r dotenv/config migrate.ts",
|
||||
"migration:up": "drizzle-kit up --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",
|
||||
@@ -35,6 +36,7 @@
|
||||
"test": "vitest --config __test__/vitest.config.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"better-auth": "1.1.16",
|
||||
"bl": "6.0.11",
|
||||
"rotating-file-stream": "3.2.3",
|
||||
"qrcode": "^1.5.3",
|
||||
|
||||
@@ -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);
|
||||
|
||||
let adminId = "";
|
||||
if (auth.rol === "admin") {
|
||||
if (auth.role === "owner") {
|
||||
const admin = await findAdminByAuthId(auth.id);
|
||||
adminId = admin.adminId;
|
||||
} else {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { buffer } from "node:stream/consumers";
|
||||
import { db } from "@/server/db";
|
||||
import { admins, server } from "@/server/db/schema";
|
||||
import { findAdminById } from "@dokploy/server";
|
||||
import { admins, server, users_temp } from "@/server/db/schema";
|
||||
import { findAdminById, findUserById } from "@dokploy/server";
|
||||
import { asc, eq } from "drizzle-orm";
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import Stripe from "stripe";
|
||||
@@ -64,33 +64,35 @@ export default async function handler(
|
||||
session.subscription as string,
|
||||
);
|
||||
await db
|
||||
.update(admins)
|
||||
.update(users_temp)
|
||||
.set({
|
||||
stripeCustomerId: session.customer as string,
|
||||
stripeSubscriptionId: session.subscription as string,
|
||||
serversQuantity: subscription?.items?.data?.[0]?.quantity ?? 0,
|
||||
})
|
||||
.where(eq(admins.adminId, adminId))
|
||||
.where(eq(users_temp.id, adminId))
|
||||
.returning();
|
||||
|
||||
const admin = await findAdminById(adminId);
|
||||
const admin = await findUserById(adminId);
|
||||
if (!admin) {
|
||||
return res.status(400).send("Webhook Error: Admin not found");
|
||||
}
|
||||
const newServersQuantity = admin.serversQuantity;
|
||||
await updateServersBasedOnQuantity(admin.adminId, newServersQuantity);
|
||||
await updateServersBasedOnQuantity(admin.id, newServersQuantity);
|
||||
break;
|
||||
}
|
||||
case "customer.subscription.created": {
|
||||
const newSubscription = event.data.object as Stripe.Subscription;
|
||||
|
||||
await db
|
||||
.update(admins)
|
||||
.update(users_temp)
|
||||
.set({
|
||||
stripeSubscriptionId: newSubscription.id,
|
||||
stripeCustomerId: newSubscription.customer as string,
|
||||
})
|
||||
.where(eq(admins.stripeCustomerId, newSubscription.customer as string))
|
||||
.where(
|
||||
eq(users_temp.stripeCustomerId, newSubscription.customer as string),
|
||||
)
|
||||
.returning();
|
||||
|
||||
break;
|
||||
@@ -100,14 +102,16 @@ export default async function handler(
|
||||
const newSubscription = event.data.object as Stripe.Subscription;
|
||||
|
||||
await db
|
||||
.update(admins)
|
||||
.update(users_temp)
|
||||
.set({
|
||||
stripeSubscriptionId: null,
|
||||
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,
|
||||
);
|
||||
|
||||
@@ -115,13 +119,13 @@ export default async function handler(
|
||||
return res.status(400).send("Webhook Error: Admin not found");
|
||||
}
|
||||
|
||||
await disableServers(admin.adminId);
|
||||
await disableServers(admin.id);
|
||||
break;
|
||||
}
|
||||
case "customer.subscription.updated": {
|
||||
const newSubscription = event.data.object as Stripe.Subscription;
|
||||
|
||||
const admin = await findAdminByStripeCustomerId(
|
||||
const admin = await findUserByStripeCustomerId(
|
||||
newSubscription.customer as string,
|
||||
);
|
||||
|
||||
@@ -131,23 +135,23 @@ export default async function handler(
|
||||
|
||||
if (newSubscription.status === "active") {
|
||||
await db
|
||||
.update(admins)
|
||||
.update(users_temp)
|
||||
.set({
|
||||
serversQuantity: newSubscription?.items?.data?.[0]?.quantity ?? 0,
|
||||
})
|
||||
.where(
|
||||
eq(admins.stripeCustomerId, newSubscription.customer as string),
|
||||
eq(users_temp.stripeCustomerId, newSubscription.customer as string),
|
||||
);
|
||||
|
||||
const newServersQuantity = admin.serversQuantity;
|
||||
await updateServersBasedOnQuantity(admin.adminId, newServersQuantity);
|
||||
await updateServersBasedOnQuantity(admin.id, newServersQuantity);
|
||||
} else {
|
||||
await disableServers(admin.adminId);
|
||||
await disableServers(admin.id);
|
||||
await db
|
||||
.update(admins)
|
||||
.update(users_temp)
|
||||
.set({ serversQuantity: 0 })
|
||||
.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));
|
||||
|
||||
const admin = await findAdminByStripeCustomerId(
|
||||
const admin = await findUserByStripeCustomerId(
|
||||
suscription.customer as string,
|
||||
);
|
||||
|
||||
@@ -182,7 +186,7 @@ export default async function handler(
|
||||
return res.status(400).send("Webhook Error: Admin not found");
|
||||
}
|
||||
const newServersQuantity = admin.serversQuantity;
|
||||
await updateServersBasedOnQuantity(admin.adminId, newServersQuantity);
|
||||
await updateServersBasedOnQuantity(admin.id, newServersQuantity);
|
||||
break;
|
||||
}
|
||||
case "invoice.payment_failed": {
|
||||
@@ -193,7 +197,7 @@ export default async function handler(
|
||||
);
|
||||
|
||||
if (subscription.status !== "active") {
|
||||
const admin = await findAdminByStripeCustomerId(
|
||||
const admin = await findUserByStripeCustomerId(
|
||||
newInvoice.customer as string,
|
||||
);
|
||||
|
||||
@@ -207,7 +211,7 @@ export default async function handler(
|
||||
})
|
||||
.where(eq(admins.stripeCustomerId, newInvoice.customer as string));
|
||||
|
||||
await disableServers(admin.adminId);
|
||||
await disableServers(admin.id);
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -216,20 +220,20 @@ export default async function handler(
|
||||
case "customer.deleted": {
|
||||
const customer = event.data.object as Stripe.Customer;
|
||||
|
||||
const admin = await findAdminByStripeCustomerId(customer.id);
|
||||
const admin = await findUserByStripeCustomerId(customer.id);
|
||||
if (!admin) {
|
||||
return res.status(400).send("Webhook Error: Admin not found");
|
||||
}
|
||||
|
||||
await disableServers(admin.adminId);
|
||||
await disableServers(admin.id);
|
||||
await db
|
||||
.update(admins)
|
||||
.update(users_temp)
|
||||
.set({
|
||||
stripeCustomerId: null,
|
||||
stripeSubscriptionId: null,
|
||||
serversQuantity: 0,
|
||||
})
|
||||
.where(eq(admins.stripeCustomerId, customer.id));
|
||||
.where(eq(users_temp.stripeCustomerId, customer.id));
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -240,20 +244,20 @@ export default async function handler(
|
||||
return res.status(200).json({ received: true });
|
||||
}
|
||||
|
||||
const disableServers = async (adminId: string) => {
|
||||
const disableServers = async (userId: string) => {
|
||||
await db
|
||||
.update(server)
|
||||
.set({
|
||||
serverStatus: "inactive",
|
||||
})
|
||||
.where(eq(server.adminId, adminId));
|
||||
.where(eq(server.userId, userId));
|
||||
};
|
||||
|
||||
const findAdminByStripeCustomerId = async (stripeCustomerId: string) => {
|
||||
const admin = db.query.admins.findFirst({
|
||||
where: eq(admins.stripeCustomerId, stripeCustomerId),
|
||||
const findUserByStripeCustomerId = async (stripeCustomerId: string) => {
|
||||
const user = db.query.users_temp.findFirst({
|
||||
where: eq(users_temp.stripeCustomerId, stripeCustomerId),
|
||||
});
|
||||
return admin;
|
||||
return user;
|
||||
};
|
||||
|
||||
const activateServer = async (serverId: string) => {
|
||||
@@ -270,19 +274,19 @@ const deactivateServer = async (serverId: string) => {
|
||||
.where(eq(server.serverId, serverId));
|
||||
};
|
||||
|
||||
export const findServersByAdminIdSorted = async (adminId: string) => {
|
||||
export const findServersByUserIdSorted = async (userId: string) => {
|
||||
const servers = await db.query.server.findMany({
|
||||
where: eq(server.adminId, adminId),
|
||||
where: eq(server.userId, userId),
|
||||
orderBy: asc(server.createdAt),
|
||||
});
|
||||
|
||||
return servers;
|
||||
};
|
||||
export const updateServersBasedOnQuantity = async (
|
||||
adminId: string,
|
||||
userId: string,
|
||||
newServersQuantity: number,
|
||||
) => {
|
||||
const servers = await findServersByAdminIdSorted(adminId);
|
||||
const servers = await findServersByUserIdSorted(userId);
|
||||
|
||||
if (servers.length > newServersQuantity) {
|
||||
for (const [index, server] of servers.entries()) {
|
||||
|
||||
@@ -53,7 +53,7 @@ export async function getServerSideProps(
|
||||
await helpers.project.all.prefetch();
|
||||
const auth = await helpers.auth.get.fetch();
|
||||
|
||||
if (auth.rol === "user") {
|
||||
if (auth.role === "member") {
|
||||
const user = await helpers.user.byAuthId.fetch({
|
||||
authId: auth.id,
|
||||
});
|
||||
|
||||
@@ -70,9 +70,9 @@ import type {
|
||||
} from "next";
|
||||
import Head from "next/head";
|
||||
import { useRouter } from "next/router";
|
||||
import { useMemo, useState, type ReactElement } from "react";
|
||||
import superjson from "superjson";
|
||||
import { type ReactElement, useMemo, useState } from "react";
|
||||
import { toast } from "sonner";
|
||||
import superjson from "superjson";
|
||||
|
||||
export type Services = {
|
||||
appName: string;
|
||||
@@ -206,7 +206,7 @@ const Project = (
|
||||
authId: auth?.id || "",
|
||||
},
|
||||
{
|
||||
enabled: !!auth?.id && auth?.rol === "user",
|
||||
enabled: !!auth?.id && auth?.role === "member",
|
||||
},
|
||||
);
|
||||
const { data, isLoading, refetch } = api.project.one.useQuery({ projectId });
|
||||
@@ -335,7 +335,7 @@ const Project = (
|
||||
</CardTitle>
|
||||
<CardDescription>{data?.description}</CardDescription>
|
||||
</CardHeader>
|
||||
{(auth?.rol === "admin" || user?.canCreateServices) && (
|
||||
{(auth?.role === "owner" || user?.canCreateServices) && (
|
||||
<div className="flex flex-row gap-4 flex-wrap">
|
||||
<ProjectEnvironment projectId={projectId}>
|
||||
<Button variant="outline">Project Environment</Button>
|
||||
|
||||
+2
-2
@@ -93,7 +93,7 @@ const Service = (
|
||||
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">
|
||||
<UpdateApplication applicationId={applicationId} />
|
||||
{(auth?.rol === "admin" || user?.canDeleteServices) && (
|
||||
{(auth?.role === "owner" || user?.canDeleteServices) && (
|
||||
<DeleteService id={applicationId} type="application" />
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -87,7 +87,7 @@ const Service = (
|
||||
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">
|
||||
<UpdateCompose composeId={composeId} />
|
||||
|
||||
{(auth?.rol === "admin" || user?.canDeleteServices) && (
|
||||
{(auth?.role === "owner" || user?.canDeleteServices) && (
|
||||
<DeleteService id={composeId} type="compose" />
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -68,7 +68,7 @@ const Mariadb = (
|
||||
authId: auth?.id || "",
|
||||
},
|
||||
{
|
||||
enabled: !!auth?.id && auth?.rol === "user",
|
||||
enabled: !!auth?.id && auth?.role === "member",
|
||||
},
|
||||
);
|
||||
const { data: isCloud } = api.settings.isCloud.useQuery();
|
||||
@@ -154,7 +154,7 @@ const Mariadb = (
|
||||
</div>
|
||||
<div className="flex flex-row gap-2 justify-end">
|
||||
<UpdateMariadb mariadbId={mariadbId} />
|
||||
{(auth?.rol === "admin" || user?.canDeleteServices) && (
|
||||
{(auth?.role === "owner" || user?.canDeleteServices) && (
|
||||
<DeleteService id={mariadbId} type="mariadb" />
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -68,7 +68,7 @@ const Mongo = (
|
||||
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">
|
||||
<UpdateMongo mongoId={mongoId} />
|
||||
{(auth?.rol === "admin" || user?.canDeleteServices) && (
|
||||
{(auth?.role === "owner" || user?.canDeleteServices) && (
|
||||
<DeleteService id={mongoId} type="mongo" />
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -67,7 +67,7 @@ const MySql = (
|
||||
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">
|
||||
<UpdateMysql mysqlId={mysqlId} />
|
||||
{(auth?.rol === "admin" || user?.canDeleteServices) && (
|
||||
{(auth?.role === "owner" || user?.canDeleteServices) && (
|
||||
<DeleteService id={mysqlId} type="mysql" />
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -66,7 +66,7 @@ const Postgresql = (
|
||||
authId: auth?.id || "",
|
||||
},
|
||||
{
|
||||
enabled: !!auth?.id && auth?.rol === "user",
|
||||
enabled: !!auth?.id && auth?.role === "member",
|
||||
},
|
||||
);
|
||||
const { data: monitoring } = api.admin.getMetricsToken.useQuery();
|
||||
@@ -154,7 +154,7 @@ const Postgresql = (
|
||||
|
||||
<div className="flex flex-row gap-2 justify-end">
|
||||
<UpdatePostgres postgresId={postgresId} />
|
||||
{(auth?.rol === "admin" || user?.canDeleteServices) && (
|
||||
{(auth?.role === "owner" || user?.canDeleteServices) && (
|
||||
<DeleteService id={postgresId} type="postgres" />
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -67,7 +67,7 @@ const Redis = (
|
||||
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">
|
||||
<UpdateRedis redisId={redisId} />
|
||||
{(auth?.rol === "admin" || user?.canDeleteServices) && (
|
||||
{(auth?.role === "owner" || user?.canDeleteServices) && (
|
||||
<DeleteService id={redisId} type="redis" />
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -30,7 +30,7 @@ export async function getServerSideProps(
|
||||
}
|
||||
const { req, res } = ctx;
|
||||
const { user, session } = await validateRequest(req, res);
|
||||
if (!user || user.rol === "user") {
|
||||
if (!user || user.role === "member") {
|
||||
return {
|
||||
redirect: {
|
||||
permanent: true,
|
||||
|
||||
@@ -25,7 +25,7 @@ export async function getServerSideProps(
|
||||
) {
|
||||
const { req, res } = ctx;
|
||||
const { user, session } = await validateRequest(req, res);
|
||||
if (!user || user.rol === "user") {
|
||||
if (!user || user.role === "member") {
|
||||
return {
|
||||
redirect: {
|
||||
permanent: true,
|
||||
|
||||
@@ -34,7 +34,7 @@ export async function getServerSideProps(
|
||||
};
|
||||
}
|
||||
const { user, session } = await validateRequest(ctx.req, ctx.res);
|
||||
if (!user || user.rol === "user") {
|
||||
if (!user || user.role === "member") {
|
||||
return {
|
||||
redirect: {
|
||||
permanent: true,
|
||||
|
||||
@@ -26,7 +26,7 @@ export async function getServerSideProps(
|
||||
) {
|
||||
const { req, res } = ctx;
|
||||
const { user, session } = await validateRequest(req, res);
|
||||
if (!user || user.rol === "user") {
|
||||
if (!user || user.role === "member") {
|
||||
return {
|
||||
redirect: {
|
||||
permanent: true,
|
||||
|
||||
@@ -51,7 +51,7 @@ export async function getServerSideProps(
|
||||
await helpers.settings.isCloud.prefetch();
|
||||
const auth = await helpers.auth.get.fetch();
|
||||
|
||||
if (auth.rol === "user") {
|
||||
if (auth.role === "member") {
|
||||
const user = await helpers.user.byAuthId.fetch({
|
||||
authId: auth.id,
|
||||
});
|
||||
|
||||
@@ -190,7 +190,7 @@ export async function getServerSideProps(
|
||||
},
|
||||
};
|
||||
}
|
||||
if (user.rol === "user") {
|
||||
if (user.role === "member") {
|
||||
return {
|
||||
redirect: {
|
||||
permanent: true,
|
||||
|
||||
@@ -26,7 +26,7 @@ export async function getServerSideProps(
|
||||
) {
|
||||
const { req, res } = ctx;
|
||||
const { user, session } = await validateRequest(req, res);
|
||||
if (!user || user.rol === "user") {
|
||||
if (!user || user.role === "member") {
|
||||
return {
|
||||
redirect: {
|
||||
permanent: true,
|
||||
|
||||
@@ -19,7 +19,7 @@ const Page = () => {
|
||||
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="h-full rounded-xl max-w-5xl mx-auto flex flex-col gap-4">
|
||||
<ProfileForm />
|
||||
{(user?.canAccessToAPI || data?.rol === "admin") && <GenerateToken />}
|
||||
{(user?.canAccessToAPI || data?.role === "owner") && <GenerateToken />}
|
||||
|
||||
{isCloud && <RemoveSelfAccount />}
|
||||
</div>
|
||||
@@ -62,7 +62,7 @@ export async function getServerSideProps(
|
||||
|
||||
await helpers.settings.isCloud.prefetch();
|
||||
await helpers.auth.get.prefetch();
|
||||
if (user?.rol === "user") {
|
||||
if (user?.role === "user") {
|
||||
await helpers.user.byAuthId.prefetch({
|
||||
authId: user.authId,
|
||||
});
|
||||
|
||||
@@ -26,7 +26,7 @@ export async function getServerSideProps(
|
||||
) {
|
||||
const { req, res } = ctx;
|
||||
const { user, session } = await validateRequest(req, res);
|
||||
if (!user || user.rol === "user") {
|
||||
if (!user || user.role === "member") {
|
||||
return {
|
||||
redirect: {
|
||||
permanent: true,
|
||||
|
||||
@@ -107,7 +107,7 @@ export async function getServerSideProps(
|
||||
},
|
||||
};
|
||||
}
|
||||
if (user.rol === "user") {
|
||||
if (user.role === "member") {
|
||||
return {
|
||||
redirect: {
|
||||
permanent: true,
|
||||
|
||||
@@ -36,7 +36,7 @@ export async function getServerSideProps(
|
||||
},
|
||||
};
|
||||
}
|
||||
if (user.rol === "user") {
|
||||
if (user.role === "member") {
|
||||
return {
|
||||
redirect: {
|
||||
permanent: true,
|
||||
|
||||
@@ -51,7 +51,7 @@ export async function getServerSideProps(
|
||||
const auth = await helpers.auth.get.fetch();
|
||||
await helpers.settings.isCloud.prefetch();
|
||||
|
||||
if (auth.rol === "user") {
|
||||
if (auth.role === "member") {
|
||||
const user = await helpers.user.byAuthId.fetch({
|
||||
authId: auth.id,
|
||||
});
|
||||
|
||||
@@ -26,7 +26,7 @@ export async function getServerSideProps(
|
||||
) {
|
||||
const { req, res } = ctx;
|
||||
const { user, session } = await validateRequest(req, res);
|
||||
if (!user || user.rol === "user") {
|
||||
if (!user || user.role === "member") {
|
||||
return {
|
||||
redirect: {
|
||||
permanent: true,
|
||||
|
||||
@@ -53,7 +53,7 @@ export async function getServerSideProps(
|
||||
await helpers.project.all.prefetch();
|
||||
const auth = await helpers.auth.get.fetch();
|
||||
|
||||
if (auth.rol === "user") {
|
||||
if (auth.role === "member") {
|
||||
const user = await helpers.user.byAuthId.fetch({
|
||||
authId: auth.id,
|
||||
});
|
||||
|
||||
@@ -53,7 +53,7 @@ export async function getServerSideProps(
|
||||
await helpers.project.all.prefetch();
|
||||
const auth = await helpers.auth.get.fetch();
|
||||
|
||||
if (auth.rol === "user") {
|
||||
if (auth.role === "member") {
|
||||
const user = await helpers.user.byAuthId.fetch({
|
||||
authId: auth.id,
|
||||
});
|
||||
|
||||
@@ -13,10 +13,14 @@ import {
|
||||
FormMessage,
|
||||
} from "@/components/ui/form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { authClient } from "@/lib/auth";
|
||||
import { cn } from "@/lib/utils";
|
||||
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 { Session, getSessionCookie } from "better-auth";
|
||||
import { betterFetch } from "better-auth/react";
|
||||
import type { GetServerSidePropsContext } from "next";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/router";
|
||||
@@ -56,17 +60,18 @@ interface Props {
|
||||
IS_CLOUD: boolean;
|
||||
}
|
||||
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>({
|
||||
is2FAEnabled: false,
|
||||
authId: "",
|
||||
});
|
||||
const { mutateAsync, isLoading, error, isError } =
|
||||
api.auth.login.useMutation();
|
||||
const router = useRouter();
|
||||
const form = useForm<Login>({
|
||||
defaultValues: {
|
||||
email: "",
|
||||
password: "",
|
||||
email: "siumauricio@hotmail.com",
|
||||
password: "Password123",
|
||||
},
|
||||
resolver: zodResolver(loginSchema),
|
||||
});
|
||||
@@ -76,25 +81,49 @@ export default function Home({ IS_CLOUD }: Props) {
|
||||
}, [form, form.reset, form.formState.isSubmitSuccessful]);
|
||||
|
||||
const onSubmit = async (values: Login) => {
|
||||
await mutateAsync({
|
||||
email: values.email.toLowerCase(),
|
||||
setIsLoading(true);
|
||||
const { data, error } = await authClient.signIn.email({
|
||||
email: values.email,
|
||||
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,
|
||||
});
|
||||
});
|
||||
|
||||
if (!error) {
|
||||
// if (data) {
|
||||
// setTemp(data);
|
||||
// } else {
|
||||
toast.success("Successfully signed in", {
|
||||
duration: 2000,
|
||||
});
|
||||
router.push("/dashboard/projects");
|
||||
// }
|
||||
} else {
|
||||
setIsError(true);
|
||||
setError(error.message ?? "Error to signup");
|
||||
toast.error("Error to sign up", {
|
||||
description: error.message,
|
||||
});
|
||||
}
|
||||
|
||||
setIsLoading(false);
|
||||
// await mutateAsync({
|
||||
// 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 (
|
||||
<>
|
||||
@@ -111,7 +140,7 @@ export default function Home({ IS_CLOUD }: Props) {
|
||||
</div>
|
||||
{isError && (
|
||||
<AlertBlock type="error" className="my-2">
|
||||
<span>{error?.message}</span>
|
||||
<span>{error}</span>
|
||||
</AlertBlock>
|
||||
)}
|
||||
<CardContent className="p-0">
|
||||
@@ -203,8 +232,7 @@ Home.getLayout = (page: ReactElement) => {
|
||||
export async function getServerSideProps(context: GetServerSidePropsContext) {
|
||||
if (IS_CLOUD) {
|
||||
try {
|
||||
const { user } = await validateRequest(context.req, context.res);
|
||||
|
||||
const { user } = await validateRequest(context.req);
|
||||
if (user) {
|
||||
return {
|
||||
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) {
|
||||
return {
|
||||
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
FormMessage,
|
||||
} from "@/components/ui/form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { authClient } from "@/lib/auth";
|
||||
import { api } from "@/utils/api";
|
||||
import { IS_CLOUD, isAdminPresent, validateRequest } from "@dokploy/server";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
@@ -31,6 +32,9 @@ import { z } from "zod";
|
||||
|
||||
const registerSchema = z
|
||||
.object({
|
||||
name: z.string().min(1, {
|
||||
message: "Name is required",
|
||||
}),
|
||||
email: z
|
||||
.string()
|
||||
.min(1, {
|
||||
@@ -79,9 +83,10 @@ const Register = ({ isCloud }: Props) => {
|
||||
|
||||
const form = useForm<Register>({
|
||||
defaultValues: {
|
||||
email: "",
|
||||
password: "",
|
||||
confirmPassword: "",
|
||||
name: "Mauricio Siu",
|
||||
email: "user5@yopmail.com",
|
||||
password: "Password1234",
|
||||
confirmPassword: "Password1234",
|
||||
},
|
||||
resolver: zodResolver(registerSchema),
|
||||
});
|
||||
@@ -91,19 +96,33 @@ const Register = ({ isCloud }: Props) => {
|
||||
}, [form, form.reset, form.formState.isSubmitSuccessful]);
|
||||
|
||||
const onSubmit = async (values: Register) => {
|
||||
await mutateAsync({
|
||||
email: values.email.toLowerCase(),
|
||||
const { data, error } = await authClient.signUp.email({
|
||||
email: values.email,
|
||||
password: values.password,
|
||||
})
|
||||
.then(() => {
|
||||
toast.success("User registered successfuly", {
|
||||
duration: 2000,
|
||||
});
|
||||
if (!isCloud) {
|
||||
router.push("/");
|
||||
}
|
||||
})
|
||||
.catch((e) => e);
|
||||
name: values.name,
|
||||
});
|
||||
|
||||
// const { data, error } = await authClient.admin.createUser({
|
||||
// name: values.name,
|
||||
// email: values.email,
|
||||
// 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 (
|
||||
<div className="">
|
||||
@@ -147,6 +166,19 @@ const Register = ({ isCloud }: Props) => {
|
||||
className="grid gap-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
|
||||
control={form.control}
|
||||
name="email"
|
||||
|
||||
@@ -58,7 +58,7 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
|
||||
},
|
||||
transformer: superjson,
|
||||
});
|
||||
if (user.rol === "user") {
|
||||
if (user.role === "member") {
|
||||
const result = await helpers.user.byAuthId.fetch({
|
||||
authId: user.id,
|
||||
});
|
||||
|
||||
@@ -6,19 +6,17 @@ import {
|
||||
apiRemoveUser,
|
||||
apiUpdateAdmin,
|
||||
apiUpdateWebServerMonitoring,
|
||||
users,
|
||||
} from "@/server/db/schema";
|
||||
import {
|
||||
IS_CLOUD,
|
||||
createInvitation,
|
||||
findAdminById,
|
||||
findUserByAuthId,
|
||||
findUserById,
|
||||
getUserByToken,
|
||||
removeUserByAuthId,
|
||||
removeUserById,
|
||||
setupWebMonitoring,
|
||||
updateAdmin,
|
||||
updateAdminById,
|
||||
updateUser,
|
||||
} from "@dokploy/server";
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import { eq } from "drizzle-orm";
|
||||
@@ -32,7 +30,7 @@ import {
|
||||
|
||||
export const adminRouter = createTRPCRouter({
|
||||
one: adminProcedure.query(async ({ ctx }) => {
|
||||
const { sshPrivateKey, ...rest } = await findAdminById(ctx.user.adminId);
|
||||
const { sshPrivateKey, ...rest } = await findUserById(ctx.user.id);
|
||||
return {
|
||||
haveSSH: !!sshPrivateKey,
|
||||
...rest,
|
||||
@@ -41,21 +39,21 @@ export const adminRouter = createTRPCRouter({
|
||||
update: adminProcedure
|
||||
.input(apiUpdateAdmin)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
if (ctx.user.rol === "user") {
|
||||
if (ctx.user.rol === "member") {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
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
|
||||
return updateAdmin(authId, input);
|
||||
return updateAdmin(id, input);
|
||||
}),
|
||||
createUserInvitation: adminProcedure
|
||||
.input(apiCreateUserInvitation)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
await createInvitation(input, ctx.user.adminId);
|
||||
await createInvitation(input, ctx.user.id);
|
||||
} catch (error) {
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
@@ -69,15 +67,16 @@ export const adminRouter = createTRPCRouter({
|
||||
.input(apiRemoveUser)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
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({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not allowed to delete this user",
|
||||
});
|
||||
}
|
||||
return await removeUserByAuthId(input.authId);
|
||||
|
||||
return await removeUserById(input.id);
|
||||
} catch (error) {
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
@@ -95,20 +94,23 @@ export const adminRouter = createTRPCRouter({
|
||||
.input(apiAssignPermissions)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
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({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not allowed to assign permissions",
|
||||
});
|
||||
}
|
||||
await db
|
||||
.update(users)
|
||||
.set({
|
||||
...input,
|
||||
})
|
||||
.where(eq(users.userId, input.userId));
|
||||
await updateUser(user.id, {
|
||||
...input,
|
||||
});
|
||||
// await db
|
||||
// .update(users)
|
||||
// .set({
|
||||
// ...input,
|
||||
// })
|
||||
// .where(eq(users.userId, input.userId));
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
@@ -124,15 +126,15 @@ export const adminRouter = createTRPCRouter({
|
||||
message: "Feature disabled on cloud",
|
||||
});
|
||||
}
|
||||
const admin = await findAdminById(ctx.user.adminId);
|
||||
if (admin.adminId !== ctx.user.adminId) {
|
||||
const user = await findUserById(ctx.user.ownerId);
|
||||
if (user.id !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to setup this server",
|
||||
});
|
||||
}
|
||||
|
||||
await updateAdminById(admin.adminId, {
|
||||
await updateUser(user.id, {
|
||||
metricsConfig: {
|
||||
server: {
|
||||
type: "Dokploy",
|
||||
@@ -156,18 +158,19 @@ export const adminRouter = createTRPCRouter({
|
||||
},
|
||||
},
|
||||
});
|
||||
const currentServer = await setupWebMonitoring(admin.adminId);
|
||||
|
||||
const currentServer = await setupWebMonitoring(user.id);
|
||||
return currentServer;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
}),
|
||||
getMetricsToken: protectedProcedure.query(async ({ ctx }) => {
|
||||
const admin = await findAdminById(ctx.user.adminId);
|
||||
const user = await findUserById(ctx.user.ownerId);
|
||||
return {
|
||||
serverIp: admin.serverIp,
|
||||
enabledFeatures: admin.enablePaidFeatures,
|
||||
metricsConfig: admin?.metricsConfig,
|
||||
serverIp: user.serverIp,
|
||||
enabledFeatures: user.enablePaidFeatures,
|
||||
metricsConfig: user?.metricsConfig,
|
||||
};
|
||||
}),
|
||||
|
||||
|
||||
@@ -60,8 +60,8 @@ export const applicationRouter = createTRPCRouter({
|
||||
.input(apiCreateApplication)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
if (ctx.user.rol === "user") {
|
||||
await checkServiceAccess(ctx.user.authId, input.projectId, "create");
|
||||
if (ctx.user.rol === "member") {
|
||||
await checkServiceAccess(ctx.user.id, input.projectId, "create");
|
||||
}
|
||||
|
||||
if (IS_CLOUD && !input.serverId) {
|
||||
@@ -72,7 +72,7 @@ export const applicationRouter = createTRPCRouter({
|
||||
}
|
||||
|
||||
const project = await findProjectById(input.projectId);
|
||||
if (project.adminId !== ctx.user.adminId) {
|
||||
if (project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to access this project",
|
||||
@@ -80,8 +80,8 @@ export const applicationRouter = createTRPCRouter({
|
||||
}
|
||||
const newApplication = await createApplication(input);
|
||||
|
||||
if (ctx.user.rol === "user") {
|
||||
await addNewService(ctx.user.authId, newApplication.applicationId);
|
||||
if (ctx.user.rol === "member") {
|
||||
await addNewService(ctx.user.id, newApplication.applicationId);
|
||||
}
|
||||
return newApplication;
|
||||
} catch (error: unknown) {
|
||||
@@ -98,15 +98,11 @@ export const applicationRouter = createTRPCRouter({
|
||||
one: protectedProcedure
|
||||
.input(apiFindOneApplication)
|
||||
.query(async ({ input, ctx }) => {
|
||||
if (ctx.user.rol === "user") {
|
||||
await checkServiceAccess(
|
||||
ctx.user.authId,
|
||||
input.applicationId,
|
||||
"access",
|
||||
);
|
||||
if (ctx.user.rol === "member") {
|
||||
await checkServiceAccess(ctx.user.id, input.applicationId, "access");
|
||||
}
|
||||
const application = await findApplicationById(input.applicationId);
|
||||
if (application.project.adminId !== ctx.user.adminId) {
|
||||
if (application.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to access this application",
|
||||
@@ -119,7 +115,7 @@ export const applicationRouter = createTRPCRouter({
|
||||
.input(apiReloadApplication)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const application = await findApplicationById(input.applicationId);
|
||||
if (application.project.adminId !== ctx.user.adminId) {
|
||||
if (application.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to reload this application",
|
||||
@@ -144,16 +140,12 @@ export const applicationRouter = createTRPCRouter({
|
||||
delete: protectedProcedure
|
||||
.input(apiFindOneApplication)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
if (ctx.user.rol === "user") {
|
||||
await checkServiceAccess(
|
||||
ctx.user.authId,
|
||||
input.applicationId,
|
||||
"delete",
|
||||
);
|
||||
if (ctx.user.rol === "member") {
|
||||
await checkServiceAccess(ctx.user.id, input.applicationId, "delete");
|
||||
}
|
||||
const application = await findApplicationById(input.applicationId);
|
||||
|
||||
if (application.project.adminId !== ctx.user.adminId) {
|
||||
if (application.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to delete this application",
|
||||
@@ -194,7 +186,7 @@ export const applicationRouter = createTRPCRouter({
|
||||
.input(apiFindOneApplication)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const service = await findApplicationById(input.applicationId);
|
||||
if (service.project.adminId !== ctx.user.adminId) {
|
||||
if (service.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to stop this application",
|
||||
@@ -214,7 +206,7 @@ export const applicationRouter = createTRPCRouter({
|
||||
.input(apiFindOneApplication)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const service = await findApplicationById(input.applicationId);
|
||||
if (service.project.adminId !== ctx.user.adminId) {
|
||||
if (service.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to start this application",
|
||||
@@ -235,7 +227,7 @@ export const applicationRouter = createTRPCRouter({
|
||||
.input(apiFindOneApplication)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const application = await findApplicationById(input.applicationId);
|
||||
if (application.project.adminId !== ctx.user.adminId) {
|
||||
if (application.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to redeploy this application",
|
||||
@@ -268,7 +260,7 @@ export const applicationRouter = createTRPCRouter({
|
||||
.input(apiSaveEnvironmentVariables)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const application = await findApplicationById(input.applicationId);
|
||||
if (application.project.adminId !== ctx.user.adminId) {
|
||||
if (application.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to save this environment",
|
||||
@@ -284,7 +276,7 @@ export const applicationRouter = createTRPCRouter({
|
||||
.input(apiSaveBuildType)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const application = await findApplicationById(input.applicationId);
|
||||
if (application.project.adminId !== ctx.user.adminId) {
|
||||
if (application.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to save this build type",
|
||||
@@ -305,7 +297,7 @@ export const applicationRouter = createTRPCRouter({
|
||||
.input(apiSaveGithubProvider)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const application = await findApplicationById(input.applicationId);
|
||||
if (application.project.adminId !== ctx.user.adminId) {
|
||||
if (application.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to save this github provider",
|
||||
@@ -327,7 +319,7 @@ export const applicationRouter = createTRPCRouter({
|
||||
.input(apiSaveGitlabProvider)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const application = await findApplicationById(input.applicationId);
|
||||
if (application.project.adminId !== ctx.user.adminId) {
|
||||
if (application.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to save this gitlab provider",
|
||||
@@ -351,7 +343,7 @@ export const applicationRouter = createTRPCRouter({
|
||||
.input(apiSaveBitbucketProvider)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const application = await findApplicationById(input.applicationId);
|
||||
if (application.project.adminId !== ctx.user.adminId) {
|
||||
if (application.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to save this bitbucket provider",
|
||||
@@ -373,7 +365,7 @@ export const applicationRouter = createTRPCRouter({
|
||||
.input(apiSaveDockerProvider)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const application = await findApplicationById(input.applicationId);
|
||||
if (application.project.adminId !== ctx.user.adminId) {
|
||||
if (application.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to save this docker provider",
|
||||
@@ -394,7 +386,7 @@ export const applicationRouter = createTRPCRouter({
|
||||
.input(apiSaveGitProvider)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const application = await findApplicationById(input.applicationId);
|
||||
if (application.project.adminId !== ctx.user.adminId) {
|
||||
if (application.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to save this git provider",
|
||||
@@ -415,7 +407,7 @@ export const applicationRouter = createTRPCRouter({
|
||||
.input(apiFindOneApplication)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const application = await findApplicationById(input.applicationId);
|
||||
if (application.project.adminId !== ctx.user.adminId) {
|
||||
if (application.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to mark this application as running",
|
||||
@@ -427,7 +419,7 @@ export const applicationRouter = createTRPCRouter({
|
||||
.input(apiUpdateApplication)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const application = await findApplicationById(input.applicationId);
|
||||
if (application.project.adminId !== ctx.user.adminId) {
|
||||
if (application.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to update this application",
|
||||
@@ -451,7 +443,7 @@ export const applicationRouter = createTRPCRouter({
|
||||
.input(apiFindOneApplication)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const application = await findApplicationById(input.applicationId);
|
||||
if (application.project.adminId !== ctx.user.adminId) {
|
||||
if (application.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to refresh this application",
|
||||
@@ -466,7 +458,7 @@ export const applicationRouter = createTRPCRouter({
|
||||
.input(apiFindOneApplication)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const application = await findApplicationById(input.applicationId);
|
||||
if (application.project.adminId !== ctx.user.adminId) {
|
||||
if (application.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to deploy this application",
|
||||
@@ -500,7 +492,7 @@ export const applicationRouter = createTRPCRouter({
|
||||
.input(apiFindOneApplication)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const application = await findApplicationById(input.applicationId);
|
||||
if (application.project.adminId !== ctx.user.adminId) {
|
||||
if (application.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to clean this application",
|
||||
@@ -513,7 +505,7 @@ export const applicationRouter = createTRPCRouter({
|
||||
.input(apiFindOneApplication)
|
||||
.query(async ({ input, ctx }) => {
|
||||
const application = await findApplicationById(input.applicationId);
|
||||
if (application.project.adminId !== ctx.user.adminId) {
|
||||
if (application.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
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);
|
||||
|
||||
if (app.project.adminId !== ctx.user.adminId) {
|
||||
if (app.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to deploy this application",
|
||||
@@ -590,7 +582,7 @@ export const applicationRouter = createTRPCRouter({
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const application = await findApplicationById(input.applicationId);
|
||||
|
||||
if (application.project.adminId !== ctx.user.adminId) {
|
||||
if (application.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to update this application",
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
apiVerify2FA,
|
||||
apiVerifyLogin2FA,
|
||||
auth,
|
||||
member,
|
||||
} from "@/server/db/schema";
|
||||
import { WEBSITE_URL } from "@/server/utils/stripe";
|
||||
import {
|
||||
@@ -16,22 +17,23 @@ import {
|
||||
createUser,
|
||||
findAuthByEmail,
|
||||
findAuthById,
|
||||
findUserById,
|
||||
generate2FASecret,
|
||||
getUserByToken,
|
||||
lucia,
|
||||
luciaToken,
|
||||
removeAdminByAuthId,
|
||||
removeUserByAuthId,
|
||||
sendDiscordNotification,
|
||||
sendEmailNotification,
|
||||
updateAuthById,
|
||||
updateUser,
|
||||
validateRequest,
|
||||
verify2FA,
|
||||
} from "@dokploy/server";
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import * as bcrypt from "bcrypt";
|
||||
import { isBefore } from "date-fns";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { and, eq } from "drizzle-orm";
|
||||
import { nanoid } from "nanoid";
|
||||
import { z } from "zod";
|
||||
import { db } from "../../db";
|
||||
@@ -169,8 +171,17 @@ export const authRouter = createTRPCRouter({
|
||||
}),
|
||||
|
||||
get: protectedProcedure.query(async ({ ctx }) => {
|
||||
const auth = await findAuthById(ctx.user.authId);
|
||||
return auth;
|
||||
const memberResult = await db.query.member.findFirst({
|
||||
where: and(
|
||||
eq(member.userId, ctx.user.id),
|
||||
eq(member.organizationId, ctx.session?.activeOrganizationId || ""),
|
||||
),
|
||||
with: {
|
||||
user: true,
|
||||
},
|
||||
});
|
||||
|
||||
return memberResult;
|
||||
}),
|
||||
|
||||
logout: protectedProcedure.mutation(async ({ ctx }) => {
|
||||
@@ -243,7 +254,7 @@ export const authRouter = createTRPCRouter({
|
||||
await lucia.invalidateSession(session.id);
|
||||
res.setHeader("Set-Cookie", lucia.createBlankSessionCookie().serialize());
|
||||
|
||||
if (ctx.user.rol === "admin") {
|
||||
if (ctx.user.rol === "owner") {
|
||||
await removeAdminByAuthId(ctx.user.authId);
|
||||
} else {
|
||||
await removeUserByAuthId(ctx.user.authId);
|
||||
@@ -253,19 +264,18 @@ export const authRouter = createTRPCRouter({
|
||||
}),
|
||||
|
||||
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) {
|
||||
await luciaToken.invalidateSession(auth.token);
|
||||
}
|
||||
const session = await luciaToken.createSession(auth?.id || "", {
|
||||
expiresIn: 60 * 60 * 24 * 30,
|
||||
});
|
||||
|
||||
await updateAuthById(auth.id, {
|
||||
token: session.id,
|
||||
});
|
||||
|
||||
// const session = await luciaToken.createSession(auth?.id || "", {
|
||||
// expiresIn: 60 * 60 * 24 * 30,
|
||||
// });
|
||||
// await updateUser(auth.id, {
|
||||
// token: session.id,
|
||||
// });
|
||||
return auth;
|
||||
}),
|
||||
verifyToken: protectedProcedure.mutation(async () => {
|
||||
@@ -277,7 +287,7 @@ export const authRouter = createTRPCRouter({
|
||||
}),
|
||||
|
||||
generate2FASecret: protectedProcedure.query(async ({ ctx }) => {
|
||||
return await generate2FASecret(ctx.user.authId);
|
||||
return await generate2FASecret(ctx.user.id);
|
||||
}),
|
||||
verify2FASetup: protectedProcedure
|
||||
.input(apiVerify2FA)
|
||||
|
||||
@@ -23,7 +23,7 @@ export const bitbucketRouter = createTRPCRouter({
|
||||
.input(apiCreateBitbucket)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
return await createBitbucket(input, ctx.user.adminId);
|
||||
return await createBitbucket(input, ctx.user.ownerId);
|
||||
} catch (error) {
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
@@ -38,7 +38,7 @@ export const bitbucketRouter = createTRPCRouter({
|
||||
const bitbucketProvider = await findBitbucketById(input.bitbucketId);
|
||||
if (
|
||||
IS_CLOUD &&
|
||||
bitbucketProvider.gitProvider.adminId !== ctx.user.adminId
|
||||
bitbucketProvider.gitProvider.userId !== ctx.user.ownerId
|
||||
) {
|
||||
//TODO: Remove this line when the cloud version is ready
|
||||
throw new TRPCError({
|
||||
@@ -61,7 +61,7 @@ export const bitbucketRouter = createTRPCRouter({
|
||||
if (IS_CLOUD) {
|
||||
// TODO: mAyBe a rEfaCtoR 🤫
|
||||
result = result.filter(
|
||||
(provider) => provider.gitProvider.adminId === ctx.user.adminId,
|
||||
(provider) => provider.gitProvider.userId === ctx.user.ownerId,
|
||||
);
|
||||
}
|
||||
return result;
|
||||
@@ -73,7 +73,7 @@ export const bitbucketRouter = createTRPCRouter({
|
||||
const bitbucketProvider = await findBitbucketById(input.bitbucketId);
|
||||
if (
|
||||
IS_CLOUD &&
|
||||
bitbucketProvider.gitProvider.adminId !== ctx.user.adminId
|
||||
bitbucketProvider.gitProvider.userId !== ctx.user.ownerId
|
||||
) {
|
||||
//TODO: Remove this line when the cloud version is ready
|
||||
throw new TRPCError({
|
||||
@@ -91,7 +91,7 @@ export const bitbucketRouter = createTRPCRouter({
|
||||
);
|
||||
if (
|
||||
IS_CLOUD &&
|
||||
bitbucketProvider.gitProvider.adminId !== ctx.user.adminId
|
||||
bitbucketProvider.gitProvider.userId !== ctx.user.ownerId
|
||||
) {
|
||||
//TODO: Remove this line when the cloud version is ready
|
||||
throw new TRPCError({
|
||||
@@ -108,7 +108,7 @@ export const bitbucketRouter = createTRPCRouter({
|
||||
const bitbucketProvider = await findBitbucketById(input.bitbucketId);
|
||||
if (
|
||||
IS_CLOUD &&
|
||||
bitbucketProvider.gitProvider.adminId !== ctx.user.adminId
|
||||
bitbucketProvider.gitProvider.userId !== ctx.user.ownerId
|
||||
) {
|
||||
//TODO: Remove this line when the cloud version is ready
|
||||
throw new TRPCError({
|
||||
@@ -132,7 +132,7 @@ export const bitbucketRouter = createTRPCRouter({
|
||||
const bitbucketProvider = await findBitbucketById(input.bitbucketId);
|
||||
if (
|
||||
IS_CLOUD &&
|
||||
bitbucketProvider.gitProvider.adminId !== ctx.user.adminId
|
||||
bitbucketProvider.gitProvider.userId !== ctx.user.ownerId
|
||||
) {
|
||||
//TODO: Remove this line when the cloud version is ready
|
||||
throw new TRPCError({
|
||||
@@ -142,7 +142,7 @@ export const bitbucketRouter = createTRPCRouter({
|
||||
}
|
||||
return await updateBitbucket(input.bitbucketId, {
|
||||
...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",
|
||||
});
|
||||
}
|
||||
return await createCertificate(input, ctx.user.adminId);
|
||||
return await createCertificate(input, ctx.user.ownerId);
|
||||
}),
|
||||
|
||||
one: adminProcedure
|
||||
.input(apiFindCertificate)
|
||||
.query(async ({ input, ctx }) => {
|
||||
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({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not allowed to access this certificate",
|
||||
@@ -44,7 +44,7 @@ export const certificateRouter = createTRPCRouter({
|
||||
.input(apiFindCertificate)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
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({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not allowed to delete this certificate",
|
||||
@@ -56,7 +56,7 @@ export const certificateRouter = createTRPCRouter({
|
||||
all: adminProcedure.query(async ({ ctx }) => {
|
||||
return await db.query.certificates.findMany({
|
||||
// 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,6 +44,7 @@ import {
|
||||
findDomainsByComposeId,
|
||||
findProjectById,
|
||||
findServerById,
|
||||
findUserById,
|
||||
loadServices,
|
||||
randomizeComposeFile,
|
||||
randomizeIsolatedDeploymentComposeFile,
|
||||
@@ -60,8 +61,8 @@ export const composeRouter = createTRPCRouter({
|
||||
.input(apiCreateCompose)
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
try {
|
||||
if (ctx.user.rol === "user") {
|
||||
await checkServiceAccess(ctx.user.authId, input.projectId, "create");
|
||||
if (ctx.user.rol === "member") {
|
||||
await checkServiceAccess(ctx.user.id, input.projectId, "create");
|
||||
}
|
||||
|
||||
if (IS_CLOUD && !input.serverId) {
|
||||
@@ -71,7 +72,7 @@ export const composeRouter = createTRPCRouter({
|
||||
});
|
||||
}
|
||||
const project = await findProjectById(input.projectId);
|
||||
if (project.adminId !== ctx.user.adminId) {
|
||||
if (project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to access this project",
|
||||
@@ -79,8 +80,8 @@ export const composeRouter = createTRPCRouter({
|
||||
}
|
||||
const newService = await createCompose(input);
|
||||
|
||||
if (ctx.user.rol === "user") {
|
||||
await addNewService(ctx.user.authId, newService.composeId);
|
||||
if (ctx.user.rol === "member") {
|
||||
await addNewService(ctx.user.id, newService.composeId);
|
||||
}
|
||||
|
||||
return newService;
|
||||
@@ -92,12 +93,12 @@ export const composeRouter = createTRPCRouter({
|
||||
one: protectedProcedure
|
||||
.input(apiFindCompose)
|
||||
.query(async ({ input, ctx }) => {
|
||||
if (ctx.user.rol === "user") {
|
||||
await checkServiceAccess(ctx.user.authId, input.composeId, "access");
|
||||
if (ctx.user.rol === "member") {
|
||||
await checkServiceAccess(ctx.user.id, input.composeId, "access");
|
||||
}
|
||||
|
||||
const compose = await findComposeById(input.composeId);
|
||||
if (compose.project.adminId !== ctx.user.adminId) {
|
||||
if (compose.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to access this compose",
|
||||
@@ -110,7 +111,7 @@ export const composeRouter = createTRPCRouter({
|
||||
.input(apiUpdateCompose)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const compose = await findComposeById(input.composeId);
|
||||
if (compose.project.adminId !== ctx.user.adminId) {
|
||||
if (compose.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to update this compose",
|
||||
@@ -121,12 +122,12 @@ export const composeRouter = createTRPCRouter({
|
||||
delete: protectedProcedure
|
||||
.input(apiDeleteCompose)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
if (ctx.user.rol === "user") {
|
||||
await checkServiceAccess(ctx.user.authId, input.composeId, "delete");
|
||||
if (ctx.user.rol === "member") {
|
||||
await checkServiceAccess(ctx.user.id, input.composeId, "delete");
|
||||
}
|
||||
const composeResult = await findComposeById(input.composeId);
|
||||
|
||||
if (composeResult.project.adminId !== ctx.user.adminId) {
|
||||
if (composeResult.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to delete this compose",
|
||||
@@ -157,7 +158,7 @@ export const composeRouter = createTRPCRouter({
|
||||
.input(apiFindCompose)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const compose = await findComposeById(input.composeId);
|
||||
if (compose.project.adminId !== ctx.user.adminId) {
|
||||
if (compose.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to clean this compose",
|
||||
@@ -170,7 +171,7 @@ export const composeRouter = createTRPCRouter({
|
||||
.input(apiFetchServices)
|
||||
.query(async ({ input, ctx }) => {
|
||||
const compose = await findComposeById(input.composeId);
|
||||
if (compose.project.adminId !== ctx.user.adminId) {
|
||||
if (compose.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to load this compose",
|
||||
@@ -184,7 +185,7 @@ export const composeRouter = createTRPCRouter({
|
||||
try {
|
||||
const compose = await findComposeById(input.composeId);
|
||||
|
||||
if (compose.project.adminId !== ctx.user.adminId) {
|
||||
if (compose.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to fetch this compose",
|
||||
@@ -209,7 +210,7 @@ export const composeRouter = createTRPCRouter({
|
||||
.input(apiRandomizeCompose)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const compose = await findComposeById(input.composeId);
|
||||
if (compose.project.adminId !== ctx.user.adminId) {
|
||||
if (compose.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to randomize this compose",
|
||||
@@ -221,7 +222,7 @@ export const composeRouter = createTRPCRouter({
|
||||
.input(apiRandomizeCompose)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const compose = await findComposeById(input.composeId);
|
||||
if (compose.project.adminId !== ctx.user.adminId) {
|
||||
if (compose.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to randomize this compose",
|
||||
@@ -236,7 +237,7 @@ export const composeRouter = createTRPCRouter({
|
||||
.input(apiFindCompose)
|
||||
.query(async ({ input, ctx }) => {
|
||||
const compose = await findComposeById(input.composeId);
|
||||
if (compose.project.adminId !== ctx.user.adminId) {
|
||||
if (compose.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to get this compose",
|
||||
@@ -254,7 +255,7 @@ export const composeRouter = createTRPCRouter({
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const compose = await findComposeById(input.composeId);
|
||||
|
||||
if (compose.project.adminId !== ctx.user.adminId) {
|
||||
if (compose.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to deploy this compose",
|
||||
@@ -287,7 +288,7 @@ export const composeRouter = createTRPCRouter({
|
||||
.input(apiFindCompose)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const compose = await findComposeById(input.composeId);
|
||||
if (compose.project.adminId !== ctx.user.adminId) {
|
||||
if (compose.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to redeploy this compose",
|
||||
@@ -319,7 +320,7 @@ export const composeRouter = createTRPCRouter({
|
||||
.input(apiFindCompose)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const compose = await findComposeById(input.composeId);
|
||||
if (compose.project.adminId !== ctx.user.adminId) {
|
||||
if (compose.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to stop this compose",
|
||||
@@ -333,7 +334,7 @@ export const composeRouter = createTRPCRouter({
|
||||
.input(apiFindCompose)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const compose = await findComposeById(input.composeId);
|
||||
if (compose.project.adminId !== ctx.user.adminId) {
|
||||
if (compose.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to stop this compose",
|
||||
@@ -348,7 +349,7 @@ export const composeRouter = createTRPCRouter({
|
||||
.query(async ({ input, ctx }) => {
|
||||
const compose = await findComposeById(input.composeId);
|
||||
|
||||
if (compose.project.adminId !== ctx.user.adminId) {
|
||||
if (compose.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to get this compose",
|
||||
@@ -361,7 +362,7 @@ export const composeRouter = createTRPCRouter({
|
||||
.input(apiFindCompose)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const compose = await findComposeById(input.composeId);
|
||||
if (compose.project.adminId !== ctx.user.adminId) {
|
||||
if (compose.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to refresh this compose",
|
||||
@@ -375,8 +376,8 @@ export const composeRouter = createTRPCRouter({
|
||||
deployTemplate: protectedProcedure
|
||||
.input(apiCreateComposeByTemplate)
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
if (ctx.user.rol === "user") {
|
||||
await checkServiceAccess(ctx.user.authId, input.projectId, "create");
|
||||
if (ctx.user.rol === "member") {
|
||||
await checkServiceAccess(ctx.user.id, input.projectId, "create");
|
||||
}
|
||||
|
||||
if (IS_CLOUD && !input.serverId) {
|
||||
@@ -390,7 +391,7 @@ export const composeRouter = createTRPCRouter({
|
||||
|
||||
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";
|
||||
|
||||
const project = await findProjectById(input.projectId);
|
||||
@@ -418,8 +419,8 @@ export const composeRouter = createTRPCRouter({
|
||||
isolatedDeployment: true,
|
||||
});
|
||||
|
||||
if (ctx.user.rol === "user") {
|
||||
await addNewService(ctx.user.authId, compose.composeId);
|
||||
if (ctx.user.rol === "member") {
|
||||
await addNewService(ctx.user.id, compose.composeId);
|
||||
}
|
||||
|
||||
if (mounts && mounts?.length > 0) {
|
||||
|
||||
@@ -19,7 +19,7 @@ export const deploymentRouter = createTRPCRouter({
|
||||
.input(apiFindAllByApplication)
|
||||
.query(async ({ input, ctx }) => {
|
||||
const application = await findApplicationById(input.applicationId);
|
||||
if (application.project.adminId !== ctx.user.adminId) {
|
||||
if (application.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to access this application",
|
||||
@@ -32,7 +32,7 @@ export const deploymentRouter = createTRPCRouter({
|
||||
.input(apiFindAllByCompose)
|
||||
.query(async ({ input, ctx }) => {
|
||||
const compose = await findComposeById(input.composeId);
|
||||
if (compose.project.adminId !== ctx.user.adminId) {
|
||||
if (compose.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to access this compose",
|
||||
@@ -44,7 +44,7 @@ export const deploymentRouter = createTRPCRouter({
|
||||
.input(apiFindAllByServer)
|
||||
.query(async ({ input, ctx }) => {
|
||||
const server = await findServerById(input.serverId);
|
||||
if (server.adminId !== ctx.user.adminId) {
|
||||
if (server.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to access this server",
|
||||
|
||||
@@ -28,7 +28,7 @@ export const destinationRouter = createTRPCRouter({
|
||||
.input(apiCreateDestination)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
return await createDestintation(input, ctx.user.adminId);
|
||||
return await createDestintation(input, ctx.user.ownerId);
|
||||
} catch (error) {
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
@@ -84,7 +84,7 @@ export const destinationRouter = createTRPCRouter({
|
||||
.input(apiFindOneDestination)
|
||||
.query(async ({ input, ctx }) => {
|
||||
const destination = await findDestinationById(input.destinationId);
|
||||
if (destination.adminId !== ctx.user.adminId) {
|
||||
if (destination.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not allowed to access this destination",
|
||||
@@ -94,7 +94,7 @@ export const destinationRouter = createTRPCRouter({
|
||||
}),
|
||||
all: protectedProcedure.query(async ({ ctx }) => {
|
||||
return await db.query.destinations.findMany({
|
||||
where: eq(destinations.adminId, ctx.user.adminId),
|
||||
where: eq(destinations.userId, ctx.user.ownerId),
|
||||
});
|
||||
}),
|
||||
remove: adminProcedure
|
||||
@@ -103,7 +103,7 @@ export const destinationRouter = createTRPCRouter({
|
||||
try {
|
||||
const destination = await findDestinationById(input.destinationId);
|
||||
|
||||
if (destination.adminId !== ctx.user.adminId) {
|
||||
if (destination.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not allowed to delete this destination",
|
||||
@@ -111,7 +111,7 @@ export const destinationRouter = createTRPCRouter({
|
||||
}
|
||||
return await removeDestinationById(
|
||||
input.destinationId,
|
||||
ctx.user.adminId,
|
||||
ctx.user.ownerId,
|
||||
);
|
||||
} catch (error) {
|
||||
throw error;
|
||||
@@ -122,7 +122,7 @@ export const destinationRouter = createTRPCRouter({
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
const destination = await findDestinationById(input.destinationId);
|
||||
if (destination.adminId !== ctx.user.adminId) {
|
||||
if (destination.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not allowed to update this destination",
|
||||
@@ -130,7 +130,7 @@ export const destinationRouter = createTRPCRouter({
|
||||
}
|
||||
return await updateDestinationById(input.destinationId, {
|
||||
...input,
|
||||
adminId: ctx.user.adminId,
|
||||
userId: ctx.user.ownerId,
|
||||
});
|
||||
} catch (error) {
|
||||
throw error;
|
||||
|
||||
@@ -30,7 +30,7 @@ export const domainRouter = createTRPCRouter({
|
||||
try {
|
||||
if (input.domainType === "compose" && 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({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to access this compose",
|
||||
@@ -38,7 +38,7 @@ export const domainRouter = createTRPCRouter({
|
||||
}
|
||||
} else if (input.domainType === "application" && 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({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to access this application",
|
||||
@@ -58,7 +58,7 @@ export const domainRouter = createTRPCRouter({
|
||||
.input(apiFindOneApplication)
|
||||
.query(async ({ input, ctx }) => {
|
||||
const application = await findApplicationById(input.applicationId);
|
||||
if (application.project.adminId !== ctx.user.adminId) {
|
||||
if (application.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to access this application",
|
||||
@@ -70,7 +70,7 @@ export const domainRouter = createTRPCRouter({
|
||||
.input(apiFindCompose)
|
||||
.query(async ({ input, ctx }) => {
|
||||
const compose = await findComposeById(input.composeId);
|
||||
if (compose.project.adminId !== ctx.user.adminId) {
|
||||
if (compose.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to access this compose",
|
||||
@@ -83,7 +83,7 @@ export const domainRouter = createTRPCRouter({
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
return generateTraefikMeDomain(
|
||||
input.appName,
|
||||
ctx.user.adminId,
|
||||
ctx.user.ownerId,
|
||||
input.serverId,
|
||||
);
|
||||
}),
|
||||
@@ -95,7 +95,7 @@ export const domainRouter = createTRPCRouter({
|
||||
|
||||
if (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({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to access this application",
|
||||
@@ -103,7 +103,7 @@ export const domainRouter = createTRPCRouter({
|
||||
}
|
||||
} else if (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({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to access this compose",
|
||||
@@ -114,7 +114,7 @@ export const domainRouter = createTRPCRouter({
|
||||
currentDomain.previewDeploymentId,
|
||||
);
|
||||
if (
|
||||
newPreviewDeployment.application.project.adminId !== ctx.user.adminId
|
||||
newPreviewDeployment.application.project.userId !== ctx.user.ownerId
|
||||
) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
@@ -143,7 +143,7 @@ export const domainRouter = createTRPCRouter({
|
||||
const domain = await findDomainById(input.domainId);
|
||||
if (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({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to access this application",
|
||||
@@ -151,7 +151,7 @@ export const domainRouter = createTRPCRouter({
|
||||
}
|
||||
} else if (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({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to access this compose",
|
||||
@@ -166,7 +166,7 @@ export const domainRouter = createTRPCRouter({
|
||||
const domain = await findDomainById(input.domainId);
|
||||
if (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({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to access this application",
|
||||
@@ -174,7 +174,7 @@ export const domainRouter = createTRPCRouter({
|
||||
}
|
||||
} else if (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({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to access this compose",
|
||||
|
||||
@@ -18,7 +18,7 @@ export const gitProviderRouter = createTRPCRouter({
|
||||
github: true,
|
||||
},
|
||||
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
|
||||
});
|
||||
}),
|
||||
@@ -28,7 +28,7 @@ export const gitProviderRouter = createTRPCRouter({
|
||||
try {
|
||||
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
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
|
||||
@@ -20,7 +20,7 @@ export const githubRouter = createTRPCRouter({
|
||||
.input(apiFindOneGithub)
|
||||
.query(async ({ input, ctx }) => {
|
||||
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
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
@@ -33,7 +33,7 @@ export const githubRouter = createTRPCRouter({
|
||||
.input(apiFindOneGithub)
|
||||
.query(async ({ input, ctx }) => {
|
||||
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
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
@@ -46,7 +46,7 @@ export const githubRouter = createTRPCRouter({
|
||||
.input(apiFindGithubBranches)
|
||||
.query(async ({ input, ctx }) => {
|
||||
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
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
@@ -65,7 +65,7 @@ export const githubRouter = createTRPCRouter({
|
||||
if (IS_CLOUD) {
|
||||
// TODO: mAyBe a rEfaCtoR 🤫
|
||||
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);
|
||||
if (
|
||||
IS_CLOUD &&
|
||||
githubProvider.gitProvider.adminId !== ctx.user.adminId
|
||||
githubProvider.gitProvider.userId !== ctx.user.ownerId
|
||||
) {
|
||||
//TODO: Remove this line when the cloud version is ready
|
||||
throw new TRPCError({
|
||||
@@ -111,7 +111,7 @@ export const githubRouter = createTRPCRouter({
|
||||
.input(apiUpdateGithub)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
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
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
@@ -120,7 +120,7 @@ export const githubRouter = createTRPCRouter({
|
||||
}
|
||||
await updateGitProvider(input.gitProviderId, {
|
||||
name: input.name,
|
||||
adminId: ctx.user.adminId,
|
||||
userId: ctx.user.ownerId,
|
||||
});
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -26,7 +26,7 @@ export const gitlabRouter = createTRPCRouter({
|
||||
.input(apiCreateGitlab)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
return await createGitlab(input, ctx.user.adminId);
|
||||
return await createGitlab(input, ctx.user.ownerId);
|
||||
} catch (error) {
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
@@ -39,7 +39,7 @@ export const gitlabRouter = createTRPCRouter({
|
||||
.input(apiFindOneGitlab)
|
||||
.query(async ({ input, ctx }) => {
|
||||
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
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
@@ -58,7 +58,7 @@ export const gitlabRouter = createTRPCRouter({
|
||||
if (IS_CLOUD) {
|
||||
// TODO: mAyBe a rEfaCtoR 🤫
|
||||
result = result.filter(
|
||||
(provider) => provider.gitProvider.adminId === ctx.user.adminId,
|
||||
(provider) => provider.gitProvider.userId === ctx.user.ownerId,
|
||||
);
|
||||
}
|
||||
const filtered = result
|
||||
@@ -78,7 +78,7 @@ export const gitlabRouter = createTRPCRouter({
|
||||
.input(apiFindOneGitlab)
|
||||
.query(async ({ input, ctx }) => {
|
||||
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
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
@@ -92,7 +92,7 @@ export const gitlabRouter = createTRPCRouter({
|
||||
.input(apiFindGitlabBranches)
|
||||
.query(async ({ input, ctx }) => {
|
||||
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
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
@@ -108,7 +108,7 @@ export const gitlabRouter = createTRPCRouter({
|
||||
const gitlabProvider = await findGitlabById(input.gitlabId || "");
|
||||
if (
|
||||
IS_CLOUD &&
|
||||
gitlabProvider.gitProvider.adminId !== ctx.user.adminId
|
||||
gitlabProvider.gitProvider.userId !== ctx.user.ownerId
|
||||
) {
|
||||
//TODO: Remove this line when the cloud version is ready
|
||||
throw new TRPCError({
|
||||
@@ -130,7 +130,7 @@ export const gitlabRouter = createTRPCRouter({
|
||||
.input(apiUpdateGitlab)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
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
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
@@ -140,7 +140,7 @@ export const gitlabRouter = createTRPCRouter({
|
||||
if (input.name) {
|
||||
await updateGitProvider(input.gitProviderId, {
|
||||
name: input.name,
|
||||
adminId: ctx.user.adminId,
|
||||
userId: ctx.user.ownerId,
|
||||
});
|
||||
|
||||
await updateGitlab(input.gitlabId, {
|
||||
|
||||
@@ -37,8 +37,8 @@ export const mariadbRouter = createTRPCRouter({
|
||||
.input(apiCreateMariaDB)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
if (ctx.user.rol === "user") {
|
||||
await checkServiceAccess(ctx.user.authId, input.projectId, "create");
|
||||
if (ctx.user.rol === "member") {
|
||||
await checkServiceAccess(ctx.user.id, input.projectId, "create");
|
||||
}
|
||||
|
||||
if (IS_CLOUD && !input.serverId) {
|
||||
@@ -49,15 +49,15 @@ export const mariadbRouter = createTRPCRouter({
|
||||
}
|
||||
|
||||
const project = await findProjectById(input.projectId);
|
||||
if (project.adminId !== ctx.user.adminId) {
|
||||
if (project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to access this project",
|
||||
});
|
||||
}
|
||||
const newMariadb = await createMariadb(input);
|
||||
if (ctx.user.rol === "user") {
|
||||
await addNewService(ctx.user.authId, newMariadb.mariadbId);
|
||||
if (ctx.user.rol === "member") {
|
||||
await addNewService(ctx.user.id, newMariadb.mariadbId);
|
||||
}
|
||||
|
||||
await createMount({
|
||||
@@ -79,11 +79,11 @@ export const mariadbRouter = createTRPCRouter({
|
||||
one: protectedProcedure
|
||||
.input(apiFindOneMariaDB)
|
||||
.query(async ({ input, ctx }) => {
|
||||
if (ctx.user.rol === "user") {
|
||||
await checkServiceAccess(ctx.user.authId, input.mariadbId, "access");
|
||||
if (ctx.user.rol === "member") {
|
||||
await checkServiceAccess(ctx.user.id, input.mariadbId, "access");
|
||||
}
|
||||
const mariadb = await findMariadbById(input.mariadbId);
|
||||
if (mariadb.project.adminId !== ctx.user.adminId) {
|
||||
if (mariadb.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to access this Mariadb",
|
||||
@@ -96,7 +96,7 @@ export const mariadbRouter = createTRPCRouter({
|
||||
.input(apiFindOneMariaDB)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const service = await findMariadbById(input.mariadbId);
|
||||
if (service.project.adminId !== ctx.user.adminId) {
|
||||
if (service.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to start this Mariadb",
|
||||
@@ -133,7 +133,7 @@ export const mariadbRouter = createTRPCRouter({
|
||||
.input(apiSaveExternalPortMariaDB)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const mongo = await findMariadbById(input.mariadbId);
|
||||
if (mongo.project.adminId !== ctx.user.adminId) {
|
||||
if (mongo.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to save this external port",
|
||||
@@ -149,7 +149,7 @@ export const mariadbRouter = createTRPCRouter({
|
||||
.input(apiDeployMariaDB)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const mariadb = await findMariadbById(input.mariadbId);
|
||||
if (mariadb.project.adminId !== ctx.user.adminId) {
|
||||
if (mariadb.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to deploy this Mariadb",
|
||||
@@ -170,7 +170,7 @@ export const mariadbRouter = createTRPCRouter({
|
||||
.input(apiDeployMariaDB)
|
||||
.subscription(async ({ input, ctx }) => {
|
||||
const mariadb = await findMariadbById(input.mariadbId);
|
||||
if (mariadb.project.adminId !== ctx.user.adminId) {
|
||||
if (mariadb.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to deploy this Mariadb",
|
||||
@@ -187,7 +187,7 @@ export const mariadbRouter = createTRPCRouter({
|
||||
.input(apiChangeMariaDBStatus)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const mongo = await findMariadbById(input.mariadbId);
|
||||
if (mongo.project.adminId !== ctx.user.adminId) {
|
||||
if (mongo.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to change this Mariadb status",
|
||||
@@ -201,12 +201,12 @@ export const mariadbRouter = createTRPCRouter({
|
||||
remove: protectedProcedure
|
||||
.input(apiFindOneMariaDB)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
if (ctx.user.rol === "user") {
|
||||
await checkServiceAccess(ctx.user.authId, input.mariadbId, "delete");
|
||||
if (ctx.user.rol === "member") {
|
||||
await checkServiceAccess(ctx.user.id, input.mariadbId, "delete");
|
||||
}
|
||||
|
||||
const mongo = await findMariadbById(input.mariadbId);
|
||||
if (mongo.project.adminId !== ctx.user.adminId) {
|
||||
if (mongo.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to delete this Mariadb",
|
||||
@@ -232,7 +232,7 @@ export const mariadbRouter = createTRPCRouter({
|
||||
.input(apiSaveEnvironmentVariablesMariaDB)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const mariadb = await findMariadbById(input.mariadbId);
|
||||
if (mariadb.project.adminId !== ctx.user.adminId) {
|
||||
if (mariadb.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to save this environment",
|
||||
@@ -255,7 +255,7 @@ export const mariadbRouter = createTRPCRouter({
|
||||
.input(apiResetMariadb)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const mariadb = await findMariadbById(input.mariadbId);
|
||||
if (mariadb.project.adminId !== ctx.user.adminId) {
|
||||
if (mariadb.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to reload this Mariadb",
|
||||
@@ -285,7 +285,7 @@ export const mariadbRouter = createTRPCRouter({
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const { mariadbId, ...rest } = input;
|
||||
const mariadb = await findMariadbById(mariadbId);
|
||||
if (mariadb.project.adminId !== ctx.user.adminId) {
|
||||
if (mariadb.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to update this Mariadb",
|
||||
|
||||
@@ -36,8 +36,8 @@ export const mongoRouter = createTRPCRouter({
|
||||
.input(apiCreateMongo)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
if (ctx.user.rol === "user") {
|
||||
await checkServiceAccess(ctx.user.authId, input.projectId, "create");
|
||||
if (ctx.user.rol === "member") {
|
||||
await checkServiceAccess(ctx.user.id, input.projectId, "create");
|
||||
}
|
||||
|
||||
if (IS_CLOUD && !input.serverId) {
|
||||
@@ -48,15 +48,15 @@ export const mongoRouter = createTRPCRouter({
|
||||
}
|
||||
|
||||
const project = await findProjectById(input.projectId);
|
||||
if (project.adminId !== ctx.user.adminId) {
|
||||
if (project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to access this project",
|
||||
});
|
||||
}
|
||||
const newMongo = await createMongo(input);
|
||||
if (ctx.user.rol === "user") {
|
||||
await addNewService(ctx.user.authId, newMongo.mongoId);
|
||||
if (ctx.user.rol === "member") {
|
||||
await addNewService(ctx.user.id, newMongo.mongoId);
|
||||
}
|
||||
|
||||
await createMount({
|
||||
@@ -82,12 +82,12 @@ export const mongoRouter = createTRPCRouter({
|
||||
one: protectedProcedure
|
||||
.input(apiFindOneMongo)
|
||||
.query(async ({ input, ctx }) => {
|
||||
if (ctx.user.rol === "user") {
|
||||
await checkServiceAccess(ctx.user.authId, input.mongoId, "access");
|
||||
if (ctx.user.rol === "member") {
|
||||
await checkServiceAccess(ctx.user.id, input.mongoId, "access");
|
||||
}
|
||||
|
||||
const mongo = await findMongoById(input.mongoId);
|
||||
if (mongo.project.adminId !== ctx.user.adminId) {
|
||||
if (mongo.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to access this mongo",
|
||||
@@ -101,7 +101,7 @@ export const mongoRouter = createTRPCRouter({
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const service = await findMongoById(input.mongoId);
|
||||
|
||||
if (service.project.adminId !== ctx.user.adminId) {
|
||||
if (service.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to start this mongo",
|
||||
@@ -124,7 +124,7 @@ export const mongoRouter = createTRPCRouter({
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const mongo = await findMongoById(input.mongoId);
|
||||
|
||||
if (mongo.project.adminId !== ctx.user.adminId) {
|
||||
if (mongo.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to stop this mongo",
|
||||
@@ -146,7 +146,7 @@ export const mongoRouter = createTRPCRouter({
|
||||
.input(apiSaveExternalPortMongo)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const mongo = await findMongoById(input.mongoId);
|
||||
if (mongo.project.adminId !== ctx.user.adminId) {
|
||||
if (mongo.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to save this external port",
|
||||
@@ -162,7 +162,7 @@ export const mongoRouter = createTRPCRouter({
|
||||
.input(apiDeployMongo)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const mongo = await findMongoById(input.mongoId);
|
||||
if (mongo.project.adminId !== ctx.user.adminId) {
|
||||
if (mongo.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to deploy this mongo",
|
||||
@@ -182,7 +182,7 @@ export const mongoRouter = createTRPCRouter({
|
||||
.input(apiDeployMongo)
|
||||
.subscription(async ({ input, ctx }) => {
|
||||
const mongo = await findMongoById(input.mongoId);
|
||||
if (mongo.project.adminId !== ctx.user.adminId) {
|
||||
if (mongo.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to deploy this mongo",
|
||||
@@ -199,7 +199,7 @@ export const mongoRouter = createTRPCRouter({
|
||||
.input(apiChangeMongoStatus)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const mongo = await findMongoById(input.mongoId);
|
||||
if (mongo.project.adminId !== ctx.user.adminId) {
|
||||
if (mongo.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to change this mongo status",
|
||||
@@ -214,7 +214,7 @@ export const mongoRouter = createTRPCRouter({
|
||||
.input(apiResetMongo)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const mongo = await findMongoById(input.mongoId);
|
||||
if (mongo.project.adminId !== ctx.user.adminId) {
|
||||
if (mongo.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to reload this mongo",
|
||||
@@ -242,13 +242,13 @@ export const mongoRouter = createTRPCRouter({
|
||||
remove: protectedProcedure
|
||||
.input(apiFindOneMongo)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
if (ctx.user.rol === "user") {
|
||||
await checkServiceAccess(ctx.user.authId, input.mongoId, "delete");
|
||||
if (ctx.user.rol === "member") {
|
||||
await checkServiceAccess(ctx.user.id, input.mongoId, "delete");
|
||||
}
|
||||
|
||||
const mongo = await findMongoById(input.mongoId);
|
||||
|
||||
if (mongo.project.adminId !== ctx.user.adminId) {
|
||||
if (mongo.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to delete this mongo",
|
||||
@@ -274,7 +274,7 @@ export const mongoRouter = createTRPCRouter({
|
||||
.input(apiSaveEnvironmentVariablesMongo)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const mongo = await findMongoById(input.mongoId);
|
||||
if (mongo.project.adminId !== ctx.user.adminId) {
|
||||
if (mongo.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to save this environment",
|
||||
@@ -298,7 +298,7 @@ export const mongoRouter = createTRPCRouter({
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const { mongoId, ...rest } = input;
|
||||
const mongo = await findMongoById(mongoId);
|
||||
if (mongo.project.adminId !== ctx.user.adminId) {
|
||||
if (mongo.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to update this mongo",
|
||||
|
||||
@@ -38,8 +38,8 @@ export const mysqlRouter = createTRPCRouter({
|
||||
.input(apiCreateMySql)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
if (ctx.user.rol === "user") {
|
||||
await checkServiceAccess(ctx.user.authId, input.projectId, "create");
|
||||
if (ctx.user.rol === "member") {
|
||||
await checkServiceAccess(ctx.user.id, input.projectId, "create");
|
||||
}
|
||||
|
||||
if (IS_CLOUD && !input.serverId) {
|
||||
@@ -50,7 +50,7 @@ export const mysqlRouter = createTRPCRouter({
|
||||
}
|
||||
1;
|
||||
const project = await findProjectById(input.projectId);
|
||||
if (project.adminId !== ctx.user.adminId) {
|
||||
if (project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to access this project",
|
||||
@@ -58,8 +58,8 @@ export const mysqlRouter = createTRPCRouter({
|
||||
}
|
||||
|
||||
const newMysql = await createMysql(input);
|
||||
if (ctx.user.rol === "user") {
|
||||
await addNewService(ctx.user.authId, newMysql.mysqlId);
|
||||
if (ctx.user.rol === "member") {
|
||||
await addNewService(ctx.user.id, newMysql.mysqlId);
|
||||
}
|
||||
|
||||
await createMount({
|
||||
@@ -85,11 +85,11 @@ export const mysqlRouter = createTRPCRouter({
|
||||
one: protectedProcedure
|
||||
.input(apiFindOneMySql)
|
||||
.query(async ({ input, ctx }) => {
|
||||
if (ctx.user.rol === "user") {
|
||||
await checkServiceAccess(ctx.user.authId, input.mysqlId, "access");
|
||||
if (ctx.user.rol === "member") {
|
||||
await checkServiceAccess(ctx.user.id, input.mysqlId, "access");
|
||||
}
|
||||
const mysql = await findMySqlById(input.mysqlId);
|
||||
if (mysql.project.adminId !== ctx.user.adminId) {
|
||||
if (mysql.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to access this MySQL",
|
||||
@@ -102,7 +102,7 @@ export const mysqlRouter = createTRPCRouter({
|
||||
.input(apiFindOneMySql)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const service = await findMySqlById(input.mysqlId);
|
||||
if (service.project.adminId !== ctx.user.adminId) {
|
||||
if (service.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to start this MySQL",
|
||||
@@ -124,7 +124,7 @@ export const mysqlRouter = createTRPCRouter({
|
||||
.input(apiFindOneMySql)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const mongo = await findMySqlById(input.mysqlId);
|
||||
if (mongo.project.adminId !== ctx.user.adminId) {
|
||||
if (mongo.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to stop this MySQL",
|
||||
@@ -145,7 +145,7 @@ export const mysqlRouter = createTRPCRouter({
|
||||
.input(apiSaveExternalPortMySql)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const mongo = await findMySqlById(input.mysqlId);
|
||||
if (mongo.project.adminId !== ctx.user.adminId) {
|
||||
if (mongo.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to save this external port",
|
||||
@@ -161,7 +161,7 @@ export const mysqlRouter = createTRPCRouter({
|
||||
.input(apiDeployMySql)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const mysql = await findMySqlById(input.mysqlId);
|
||||
if (mysql.project.adminId !== ctx.user.adminId) {
|
||||
if (mysql.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to deploy this MySQL",
|
||||
@@ -181,7 +181,7 @@ export const mysqlRouter = createTRPCRouter({
|
||||
.input(apiDeployMySql)
|
||||
.subscription(async ({ input, ctx }) => {
|
||||
const mysql = await findMySqlById(input.mysqlId);
|
||||
if (mysql.project.adminId !== ctx.user.adminId) {
|
||||
if (mysql.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to deploy this MySQL",
|
||||
@@ -198,7 +198,7 @@ export const mysqlRouter = createTRPCRouter({
|
||||
.input(apiChangeMySqlStatus)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const mongo = await findMySqlById(input.mysqlId);
|
||||
if (mongo.project.adminId !== ctx.user.adminId) {
|
||||
if (mongo.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to change this MySQL status",
|
||||
@@ -213,7 +213,7 @@ export const mysqlRouter = createTRPCRouter({
|
||||
.input(apiResetMysql)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const mysql = await findMySqlById(input.mysqlId);
|
||||
if (mysql.project.adminId !== ctx.user.adminId) {
|
||||
if (mysql.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to reload this MySQL",
|
||||
@@ -240,11 +240,11 @@ export const mysqlRouter = createTRPCRouter({
|
||||
remove: protectedProcedure
|
||||
.input(apiFindOneMySql)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
if (ctx.user.rol === "user") {
|
||||
await checkServiceAccess(ctx.user.authId, input.mysqlId, "delete");
|
||||
if (ctx.user.rol === "member") {
|
||||
await checkServiceAccess(ctx.user.id, input.mysqlId, "delete");
|
||||
}
|
||||
const mongo = await findMySqlById(input.mysqlId);
|
||||
if (mongo.project.adminId !== ctx.user.adminId) {
|
||||
if (mongo.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to delete this MySQL",
|
||||
@@ -270,7 +270,7 @@ export const mysqlRouter = createTRPCRouter({
|
||||
.input(apiSaveEnvironmentVariablesMySql)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const mysql = await findMySqlById(input.mysqlId);
|
||||
if (mysql.project.adminId !== ctx.user.adminId) {
|
||||
if (mysql.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to save this environment",
|
||||
@@ -294,7 +294,7 @@ export const mysqlRouter = createTRPCRouter({
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const { mysqlId, ...rest } = input;
|
||||
const mysql = await findMySqlById(mysqlId);
|
||||
if (mysql.project.adminId !== ctx.user.adminId) {
|
||||
if (mysql.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to update this MySQL",
|
||||
|
||||
@@ -6,7 +6,6 @@ import {
|
||||
} from "@/server/api/trpc";
|
||||
import { db } from "@/server/db";
|
||||
import {
|
||||
admins,
|
||||
apiCreateDiscord,
|
||||
apiCreateEmail,
|
||||
apiCreateGotify,
|
||||
@@ -25,6 +24,7 @@ import {
|
||||
apiUpdateTelegram,
|
||||
notifications,
|
||||
server,
|
||||
users_temp,
|
||||
} from "@/server/db/schema";
|
||||
import {
|
||||
IS_CLOUD,
|
||||
@@ -57,7 +57,7 @@ export const notificationRouter = createTRPCRouter({
|
||||
.input(apiCreateSlack)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
return await createSlackNotification(input, ctx.user.adminId);
|
||||
return await createSlackNotification(input, ctx.user.ownerId);
|
||||
} catch (error) {
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
@@ -71,7 +71,7 @@ export const notificationRouter = createTRPCRouter({
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
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
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
@@ -80,7 +80,7 @@ export const notificationRouter = createTRPCRouter({
|
||||
}
|
||||
return await updateSlackNotification({
|
||||
...input,
|
||||
adminId: ctx.user.adminId,
|
||||
userId: ctx.user.ownerId,
|
||||
});
|
||||
} catch (error) {
|
||||
throw error;
|
||||
@@ -107,7 +107,7 @@ export const notificationRouter = createTRPCRouter({
|
||||
.input(apiCreateTelegram)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
return await createTelegramNotification(input, ctx.user.adminId);
|
||||
return await createTelegramNotification(input, ctx.user.ownerId);
|
||||
} catch (error) {
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
@@ -122,7 +122,7 @@ export const notificationRouter = createTRPCRouter({
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
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
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
@@ -131,7 +131,7 @@ export const notificationRouter = createTRPCRouter({
|
||||
}
|
||||
return await updateTelegramNotification({
|
||||
...input,
|
||||
adminId: ctx.user.adminId,
|
||||
userId: ctx.user.ownerId,
|
||||
});
|
||||
} catch (error) {
|
||||
throw new TRPCError({
|
||||
@@ -159,7 +159,7 @@ export const notificationRouter = createTRPCRouter({
|
||||
.input(apiCreateDiscord)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
return await createDiscordNotification(input, ctx.user.adminId);
|
||||
return await createDiscordNotification(input, ctx.user.ownerId);
|
||||
} catch (error) {
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
@@ -174,7 +174,7 @@ export const notificationRouter = createTRPCRouter({
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
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
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
@@ -183,7 +183,7 @@ export const notificationRouter = createTRPCRouter({
|
||||
}
|
||||
return await updateDiscordNotification({
|
||||
...input,
|
||||
adminId: ctx.user.adminId,
|
||||
userId: ctx.user.ownerId,
|
||||
});
|
||||
} catch (error) {
|
||||
throw new TRPCError({
|
||||
@@ -220,7 +220,7 @@ export const notificationRouter = createTRPCRouter({
|
||||
.input(apiCreateEmail)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
return await createEmailNotification(input, ctx.user.adminId);
|
||||
return await createEmailNotification(input, ctx.user.ownerId);
|
||||
} catch (error) {
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
@@ -234,7 +234,7 @@ export const notificationRouter = createTRPCRouter({
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
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
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
@@ -243,7 +243,7 @@ export const notificationRouter = createTRPCRouter({
|
||||
}
|
||||
return await updateEmailNotification({
|
||||
...input,
|
||||
adminId: ctx.user.adminId,
|
||||
userId: ctx.user.ownerId,
|
||||
});
|
||||
} catch (error) {
|
||||
throw new TRPCError({
|
||||
@@ -276,7 +276,7 @@ export const notificationRouter = createTRPCRouter({
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
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
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
@@ -295,7 +295,7 @@ export const notificationRouter = createTRPCRouter({
|
||||
.input(apiFindOneNotification)
|
||||
.query(async ({ input, ctx }) => {
|
||||
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
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
@@ -314,7 +314,7 @@ export const notificationRouter = createTRPCRouter({
|
||||
gotify: true,
|
||||
},
|
||||
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
|
||||
});
|
||||
}),
|
||||
@@ -332,24 +332,24 @@ export const notificationRouter = createTRPCRouter({
|
||||
)
|
||||
.mutation(async ({ input }) => {
|
||||
try {
|
||||
let adminId = "";
|
||||
let userId = "";
|
||||
let ServerName = "";
|
||||
if (input.ServerType === "Dokploy") {
|
||||
const result = await db
|
||||
.select()
|
||||
.from(admins)
|
||||
.from(users_temp)
|
||||
.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({
|
||||
code: "BAD_REQUEST",
|
||||
message: "Token not found",
|
||||
});
|
||||
}
|
||||
|
||||
adminId = result?.[0]?.adminId;
|
||||
userId = result?.[0]?.id;
|
||||
ServerName = "Dokploy";
|
||||
} else {
|
||||
const result = await db
|
||||
@@ -359,18 +359,18 @@ export const notificationRouter = createTRPCRouter({
|
||||
sql`${server.metricsConfig}::jsonb -> 'server' ->> 'token' = ${input.Token}`,
|
||||
);
|
||||
|
||||
if (!result?.[0]?.adminId) {
|
||||
if (!result?.[0]?.userId) {
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "Token not found",
|
||||
});
|
||||
}
|
||||
|
||||
adminId = result?.[0]?.adminId;
|
||||
userId = result?.[0]?.userId;
|
||||
ServerName = "Remote";
|
||||
}
|
||||
|
||||
await sendServerThresholdNotifications(adminId, {
|
||||
await sendServerThresholdNotifications(userId, {
|
||||
...input,
|
||||
ServerName,
|
||||
});
|
||||
@@ -386,7 +386,7 @@ export const notificationRouter = createTRPCRouter({
|
||||
.input(apiCreateGotify)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
return await createGotifyNotification(input, ctx.user.adminId);
|
||||
return await createGotifyNotification(input, ctx.user.ownerId);
|
||||
} catch (error) {
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
@@ -400,7 +400,7 @@ export const notificationRouter = createTRPCRouter({
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
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({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to update this notification",
|
||||
@@ -408,7 +408,7 @@ export const notificationRouter = createTRPCRouter({
|
||||
}
|
||||
return await updateGotifyNotification({
|
||||
...input,
|
||||
adminId: ctx.user.adminId,
|
||||
userId: ctx.user.ownerId,
|
||||
});
|
||||
} catch (error) {
|
||||
throw error;
|
||||
|
||||
@@ -44,8 +44,8 @@ export const postgresRouter = createTRPCRouter({
|
||||
.input(apiCreatePostgres)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
if (ctx.user.rol === "user") {
|
||||
await checkServiceAccess(ctx.user.authId, input.projectId, "create");
|
||||
if (ctx.user.rol === "member") {
|
||||
await checkServiceAccess(ctx.user.id, input.projectId, "create");
|
||||
}
|
||||
|
||||
if (IS_CLOUD && !input.serverId) {
|
||||
@@ -56,15 +56,15 @@ export const postgresRouter = createTRPCRouter({
|
||||
}
|
||||
|
||||
const project = await findProjectById(input.projectId);
|
||||
if (project.adminId !== ctx.user.adminId) {
|
||||
if (project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to access this project",
|
||||
});
|
||||
}
|
||||
const newPostgres = await createPostgres(input);
|
||||
if (ctx.user.rol === "user") {
|
||||
await addNewService(ctx.user.authId, newPostgres.postgresId);
|
||||
if (ctx.user.rol === "member") {
|
||||
await addNewService(ctx.user.id, newPostgres.postgresId);
|
||||
}
|
||||
|
||||
await createMount({
|
||||
@@ -90,12 +90,12 @@ export const postgresRouter = createTRPCRouter({
|
||||
one: protectedProcedure
|
||||
.input(apiFindOnePostgres)
|
||||
.query(async ({ input, ctx }) => {
|
||||
if (ctx.user.rol === "user") {
|
||||
await checkServiceAccess(ctx.user.authId, input.postgresId, "access");
|
||||
if (ctx.user.rol === "member") {
|
||||
await checkServiceAccess(ctx.user.id, input.postgresId, "access");
|
||||
}
|
||||
|
||||
const postgres = await findPostgresById(input.postgresId);
|
||||
if (postgres.project.adminId !== ctx.user.adminId) {
|
||||
if (postgres.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to access this Postgres",
|
||||
@@ -109,7 +109,7 @@ export const postgresRouter = createTRPCRouter({
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const service = await findPostgresById(input.postgresId);
|
||||
|
||||
if (service.project.adminId !== ctx.user.adminId) {
|
||||
if (service.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to start this Postgres",
|
||||
@@ -131,7 +131,7 @@ export const postgresRouter = createTRPCRouter({
|
||||
.input(apiFindOnePostgres)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const postgres = await findPostgresById(input.postgresId);
|
||||
if (postgres.project.adminId !== ctx.user.adminId) {
|
||||
if (postgres.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to stop this Postgres",
|
||||
@@ -153,7 +153,7 @@ export const postgresRouter = createTRPCRouter({
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const postgres = await findPostgresById(input.postgresId);
|
||||
|
||||
if (postgres.project.adminId !== ctx.user.adminId) {
|
||||
if (postgres.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to save this external port",
|
||||
@@ -169,7 +169,7 @@ export const postgresRouter = createTRPCRouter({
|
||||
.input(apiDeployPostgres)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const postgres = await findPostgresById(input.postgresId);
|
||||
if (postgres.project.adminId !== ctx.user.adminId) {
|
||||
if (postgres.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to deploy this Postgres",
|
||||
@@ -190,7 +190,7 @@ export const postgresRouter = createTRPCRouter({
|
||||
.input(apiDeployPostgres)
|
||||
.subscription(async ({ input, ctx }) => {
|
||||
const postgres = await findPostgresById(input.postgresId);
|
||||
if (postgres.project.adminId !== ctx.user.adminId) {
|
||||
if (postgres.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to deploy this Postgres",
|
||||
@@ -207,7 +207,7 @@ export const postgresRouter = createTRPCRouter({
|
||||
.input(apiChangePostgresStatus)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const postgres = await findPostgresById(input.postgresId);
|
||||
if (postgres.project.adminId !== ctx.user.adminId) {
|
||||
if (postgres.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to change this Postgres status",
|
||||
@@ -221,12 +221,12 @@ export const postgresRouter = createTRPCRouter({
|
||||
remove: protectedProcedure
|
||||
.input(apiFindOnePostgres)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
if (ctx.user.rol === "user") {
|
||||
await checkServiceAccess(ctx.user.authId, input.postgresId, "delete");
|
||||
if (ctx.user.rol === "member") {
|
||||
await checkServiceAccess(ctx.user.id, input.postgresId, "delete");
|
||||
}
|
||||
const postgres = await findPostgresById(input.postgresId);
|
||||
|
||||
if (postgres.project.adminId !== ctx.user.adminId) {
|
||||
if (postgres.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to delete this Postgres",
|
||||
@@ -249,7 +249,7 @@ export const postgresRouter = createTRPCRouter({
|
||||
.input(apiSaveEnvironmentVariablesPostgres)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const postgres = await findPostgresById(input.postgresId);
|
||||
if (postgres.project.adminId !== ctx.user.adminId) {
|
||||
if (postgres.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to save this environment",
|
||||
@@ -272,7 +272,7 @@ export const postgresRouter = createTRPCRouter({
|
||||
.input(apiResetPostgres)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const postgres = await findPostgresById(input.postgresId);
|
||||
if (postgres.project.adminId !== ctx.user.adminId) {
|
||||
if (postgres.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to reload this Postgres",
|
||||
@@ -302,7 +302,7 @@ export const postgresRouter = createTRPCRouter({
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const { postgresId, ...rest } = input;
|
||||
const postgres = await findPostgresById(postgresId);
|
||||
if (postgres.project.adminId !== ctx.user.adminId) {
|
||||
if (postgres.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to update this Postgres",
|
||||
|
||||
@@ -14,7 +14,7 @@ export const previewDeploymentRouter = createTRPCRouter({
|
||||
.input(apiFindAllByApplication)
|
||||
.query(async ({ input, ctx }) => {
|
||||
const application = await findApplicationById(input.applicationId);
|
||||
if (application.project.adminId !== ctx.user.adminId) {
|
||||
if (application.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to access this application",
|
||||
@@ -28,7 +28,7 @@ export const previewDeploymentRouter = createTRPCRouter({
|
||||
const previewDeployment = await findPreviewDeploymentById(
|
||||
input.previewDeploymentId,
|
||||
);
|
||||
if (previewDeployment.application.project.adminId !== ctx.user.adminId) {
|
||||
if (previewDeployment.application.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to delete this preview deployment",
|
||||
@@ -43,7 +43,7 @@ export const previewDeploymentRouter = createTRPCRouter({
|
||||
const previewDeployment = await findPreviewDeploymentById(
|
||||
input.previewDeploymentId,
|
||||
);
|
||||
if (previewDeployment.application.project.adminId !== ctx.user.adminId) {
|
||||
if (previewDeployment.application.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to access this preview deployment",
|
||||
|
||||
@@ -25,9 +25,9 @@ import {
|
||||
checkProjectAccess,
|
||||
createProject,
|
||||
deleteProject,
|
||||
findAdminById,
|
||||
findProjectById,
|
||||
findUserByAuthId,
|
||||
findUserById,
|
||||
updateProjectById,
|
||||
} from "@dokploy/server";
|
||||
|
||||
@@ -36,11 +36,11 @@ export const projectRouter = createTRPCRouter({
|
||||
.input(apiCreateProject)
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
try {
|
||||
if (ctx.user.rol === "user") {
|
||||
await checkProjectAccess(ctx.user.authId, "create");
|
||||
if (ctx.user.rol === "member") {
|
||||
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) {
|
||||
throw new TRPCError({
|
||||
@@ -49,9 +49,9 @@ export const projectRouter = createTRPCRouter({
|
||||
});
|
||||
}
|
||||
|
||||
const project = await createProject(input, ctx.user.adminId);
|
||||
if (ctx.user.rol === "user") {
|
||||
await addNewProject(ctx.user.authId, project.projectId);
|
||||
const project = await createProject(input, ctx.user.ownerId);
|
||||
if (ctx.user.rol === "member") {
|
||||
await addNewProject(ctx.user.id, project.projectId);
|
||||
}
|
||||
|
||||
return project;
|
||||
@@ -67,15 +67,15 @@ export const projectRouter = createTRPCRouter({
|
||||
one: protectedProcedure
|
||||
.input(apiFindOneProject)
|
||||
.query(async ({ input, ctx }) => {
|
||||
if (ctx.user.rol === "user") {
|
||||
const { accessedServices } = await findUserByAuthId(ctx.user.authId);
|
||||
if (ctx.user.rol === "member") {
|
||||
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({
|
||||
where: and(
|
||||
eq(projects.projectId, input.projectId),
|
||||
eq(projects.adminId, ctx.user.adminId),
|
||||
eq(projects.userId, ctx.user.ownerId),
|
||||
),
|
||||
with: {
|
||||
compose: {
|
||||
@@ -115,7 +115,7 @@ export const projectRouter = createTRPCRouter({
|
||||
}
|
||||
const project = await findProjectById(input.projectId);
|
||||
|
||||
if (project.adminId !== ctx.user.adminId) {
|
||||
if (project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to access this project",
|
||||
@@ -124,9 +124,10 @@ export const projectRouter = createTRPCRouter({
|
||||
return project;
|
||||
}),
|
||||
all: protectedProcedure.query(async ({ ctx }) => {
|
||||
if (ctx.user.rol === "user") {
|
||||
const { accessedProjects, accessedServices } = await findUserByAuthId(
|
||||
ctx.user.authId,
|
||||
// console.log(ctx.user);
|
||||
if (ctx.user.rol === "member") {
|
||||
const { accessedProjects, accessedServices } = await findUserById(
|
||||
ctx.user.id,
|
||||
);
|
||||
|
||||
if (accessedProjects.length === 0) {
|
||||
@@ -139,7 +140,7 @@ export const projectRouter = createTRPCRouter({
|
||||
accessedProjects.map((projectId) => sql`${projectId}`),
|
||||
sql`, `,
|
||||
)})`,
|
||||
eq(projects.adminId, ctx.user.adminId),
|
||||
eq(projects.userId, ctx.user.id),
|
||||
),
|
||||
with: {
|
||||
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),
|
||||
});
|
||||
}),
|
||||
@@ -202,11 +203,11 @@ export const projectRouter = createTRPCRouter({
|
||||
.input(apiRemoveProject)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
if (ctx.user.rol === "user") {
|
||||
await checkProjectAccess(ctx.user.authId, "delete");
|
||||
if (ctx.user.rol === "member") {
|
||||
await checkProjectAccess(ctx.user.id, "delete");
|
||||
}
|
||||
const currentProject = await findProjectById(input.projectId);
|
||||
if (currentProject.adminId !== ctx.user.adminId) {
|
||||
if (currentProject.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to delete this project",
|
||||
@@ -224,7 +225,7 @@ export const projectRouter = createTRPCRouter({
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
const currentProject = await findProjectById(input.projectId);
|
||||
if (currentProject.adminId !== ctx.user.adminId) {
|
||||
if (currentProject.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to update this project",
|
||||
|
||||
@@ -18,7 +18,7 @@ export const redirectsRouter = createTRPCRouter({
|
||||
.input(apiCreateRedirect)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const application = await findApplicationById(input.applicationId);
|
||||
if (application.project.adminId !== ctx.user.adminId) {
|
||||
if (application.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to access this application",
|
||||
@@ -31,7 +31,7 @@ export const redirectsRouter = createTRPCRouter({
|
||||
.query(async ({ input, ctx }) => {
|
||||
const redirect = await findRedirectById(input.redirectId);
|
||||
const application = await findApplicationById(redirect.applicationId);
|
||||
if (application.project.adminId !== ctx.user.adminId) {
|
||||
if (application.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to access this application",
|
||||
@@ -44,7 +44,7 @@ export const redirectsRouter = createTRPCRouter({
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const redirect = await findRedirectById(input.redirectId);
|
||||
const application = await findApplicationById(redirect.applicationId);
|
||||
if (application.project.adminId !== ctx.user.adminId) {
|
||||
if (application.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to access this application",
|
||||
@@ -57,7 +57,7 @@ export const redirectsRouter = createTRPCRouter({
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const redirect = await findRedirectById(input.redirectId);
|
||||
const application = await findApplicationById(redirect.applicationId);
|
||||
if (application.project.adminId !== ctx.user.adminId) {
|
||||
if (application.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to access this application",
|
||||
|
||||
@@ -36,8 +36,8 @@ export const redisRouter = createTRPCRouter({
|
||||
.input(apiCreateRedis)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
if (ctx.user.rol === "user") {
|
||||
await checkServiceAccess(ctx.user.authId, input.projectId, "create");
|
||||
if (ctx.user.rol === "member") {
|
||||
await checkServiceAccess(ctx.user.id, input.projectId, "create");
|
||||
}
|
||||
|
||||
if (IS_CLOUD && !input.serverId) {
|
||||
@@ -48,15 +48,15 @@ export const redisRouter = createTRPCRouter({
|
||||
}
|
||||
|
||||
const project = await findProjectById(input.projectId);
|
||||
if (project.adminId !== ctx.user.adminId) {
|
||||
if (project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to access this project",
|
||||
});
|
||||
}
|
||||
const newRedis = await createRedis(input);
|
||||
if (ctx.user.rol === "user") {
|
||||
await addNewService(ctx.user.authId, newRedis.redisId);
|
||||
if (ctx.user.rol === "member") {
|
||||
await addNewService(ctx.user.id, newRedis.redisId);
|
||||
}
|
||||
|
||||
await createMount({
|
||||
@@ -75,12 +75,12 @@ export const redisRouter = createTRPCRouter({
|
||||
one: protectedProcedure
|
||||
.input(apiFindOneRedis)
|
||||
.query(async ({ input, ctx }) => {
|
||||
if (ctx.user.rol === "user") {
|
||||
await checkServiceAccess(ctx.user.authId, input.redisId, "access");
|
||||
if (ctx.user.rol === "member") {
|
||||
await checkServiceAccess(ctx.user.id, input.redisId, "access");
|
||||
}
|
||||
|
||||
const redis = await findRedisById(input.redisId);
|
||||
if (redis.project.adminId !== ctx.user.adminId) {
|
||||
if (redis.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to access this Redis",
|
||||
@@ -93,7 +93,7 @@ export const redisRouter = createTRPCRouter({
|
||||
.input(apiFindOneRedis)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const redis = await findRedisById(input.redisId);
|
||||
if (redis.project.adminId !== ctx.user.adminId) {
|
||||
if (redis.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to start this Redis",
|
||||
@@ -115,7 +115,7 @@ export const redisRouter = createTRPCRouter({
|
||||
.input(apiResetRedis)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const redis = await findRedisById(input.redisId);
|
||||
if (redis.project.adminId !== ctx.user.adminId) {
|
||||
if (redis.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to reload this Redis",
|
||||
@@ -145,7 +145,7 @@ export const redisRouter = createTRPCRouter({
|
||||
.input(apiFindOneRedis)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const redis = await findRedisById(input.redisId);
|
||||
if (redis.project.adminId !== ctx.user.adminId) {
|
||||
if (redis.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to stop this Redis",
|
||||
@@ -166,7 +166,7 @@ export const redisRouter = createTRPCRouter({
|
||||
.input(apiSaveExternalPortRedis)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const mongo = await findRedisById(input.redisId);
|
||||
if (mongo.project.adminId !== ctx.user.adminId) {
|
||||
if (mongo.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to save this external port",
|
||||
@@ -182,7 +182,7 @@ export const redisRouter = createTRPCRouter({
|
||||
.input(apiDeployRedis)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const redis = await findRedisById(input.redisId);
|
||||
if (redis.project.adminId !== ctx.user.adminId) {
|
||||
if (redis.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to deploy this Redis",
|
||||
@@ -202,7 +202,7 @@ export const redisRouter = createTRPCRouter({
|
||||
.input(apiDeployRedis)
|
||||
.subscription(async ({ input, ctx }) => {
|
||||
const redis = await findRedisById(input.redisId);
|
||||
if (redis.project.adminId !== ctx.user.adminId) {
|
||||
if (redis.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to deploy this Redis",
|
||||
@@ -218,7 +218,7 @@ export const redisRouter = createTRPCRouter({
|
||||
.input(apiChangeRedisStatus)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const mongo = await findRedisById(input.redisId);
|
||||
if (mongo.project.adminId !== ctx.user.adminId) {
|
||||
if (mongo.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to change this Redis status",
|
||||
@@ -232,13 +232,13 @@ export const redisRouter = createTRPCRouter({
|
||||
remove: protectedProcedure
|
||||
.input(apiFindOneRedis)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
if (ctx.user.rol === "user") {
|
||||
await checkServiceAccess(ctx.user.authId, input.redisId, "delete");
|
||||
if (ctx.user.rol === "member") {
|
||||
await checkServiceAccess(ctx.user.id, input.redisId, "delete");
|
||||
}
|
||||
|
||||
const redis = await findRedisById(input.redisId);
|
||||
|
||||
if (redis.project.adminId !== ctx.user.adminId) {
|
||||
if (redis.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to delete this Redis",
|
||||
@@ -261,7 +261,7 @@ export const redisRouter = createTRPCRouter({
|
||||
.input(apiSaveEnvironmentVariablesRedis)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const redis = await findRedisById(input.redisId);
|
||||
if (redis.project.adminId !== ctx.user.adminId) {
|
||||
if (redis.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to save this environment",
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
createRegistry,
|
||||
execAsync,
|
||||
execAsyncRemote,
|
||||
findAllRegistryByAdminId,
|
||||
findAllRegistryByUserId,
|
||||
findRegistryById,
|
||||
removeRegistry,
|
||||
updateRegistry,
|
||||
@@ -22,13 +22,13 @@ export const registryRouter = createTRPCRouter({
|
||||
create: adminProcedure
|
||||
.input(apiCreateRegistry)
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
return await createRegistry(input, ctx.user.adminId);
|
||||
return await createRegistry(input, ctx.user.ownerId);
|
||||
}),
|
||||
remove: adminProcedure
|
||||
.input(apiRemoveRegistry)
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
const registry = await findRegistryById(input.registryId);
|
||||
if (registry.adminId !== ctx.user.adminId) {
|
||||
if (registry.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not allowed to delete this registry",
|
||||
@@ -41,7 +41,7 @@ export const registryRouter = createTRPCRouter({
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const { registryId, ...rest } = input;
|
||||
const registry = await findRegistryById(registryId);
|
||||
if (registry.adminId !== ctx.user.adminId) {
|
||||
if (registry.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not allowed to update this registry",
|
||||
@@ -61,13 +61,13 @@ export const registryRouter = createTRPCRouter({
|
||||
return true;
|
||||
}),
|
||||
all: protectedProcedure.query(async ({ ctx }) => {
|
||||
return await findAllRegistryByAdminId(ctx.user.adminId);
|
||||
return await findAllRegistryByUserId(ctx.user.ownerId);
|
||||
}),
|
||||
one: adminProcedure
|
||||
.input(apiFindOneRegistry)
|
||||
.query(async ({ input, ctx }) => {
|
||||
const registry = await findRegistryById(input.registryId);
|
||||
if (registry.adminId !== ctx.user.adminId) {
|
||||
if (registry.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not allowed to access this registry",
|
||||
|
||||
@@ -18,7 +18,7 @@ export const securityRouter = createTRPCRouter({
|
||||
.input(apiCreateSecurity)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const application = await findApplicationById(input.applicationId);
|
||||
if (application.project.adminId !== ctx.user.adminId) {
|
||||
if (application.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to access this application",
|
||||
@@ -31,7 +31,7 @@ export const securityRouter = createTRPCRouter({
|
||||
.query(async ({ input, ctx }) => {
|
||||
const security = await findSecurityById(input.securityId);
|
||||
const application = await findApplicationById(security.applicationId);
|
||||
if (application.project.adminId !== ctx.user.adminId) {
|
||||
if (application.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to access this application",
|
||||
@@ -44,7 +44,7 @@ export const securityRouter = createTRPCRouter({
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const security = await findSecurityById(input.securityId);
|
||||
const application = await findApplicationById(security.applicationId);
|
||||
if (application.project.adminId !== ctx.user.adminId) {
|
||||
if (application.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to access this application",
|
||||
@@ -57,7 +57,7 @@ export const securityRouter = createTRPCRouter({
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const security = await findSecurityById(input.securityId);
|
||||
const application = await findApplicationById(security.applicationId);
|
||||
if (application.project.adminId !== ctx.user.adminId) {
|
||||
if (application.project.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to access this application",
|
||||
|
||||
@@ -21,9 +21,9 @@ import {
|
||||
createServer,
|
||||
defaultCommand,
|
||||
deleteServer,
|
||||
findAdminById,
|
||||
findServerById,
|
||||
findServersByAdminId,
|
||||
findServersByUserId,
|
||||
findUserById,
|
||||
getPublicIpWithFallback,
|
||||
haveActiveServices,
|
||||
removeDeploymentsByServerId,
|
||||
@@ -42,15 +42,15 @@ export const serverRouter = createTRPCRouter({
|
||||
.input(apiCreateServer)
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
try {
|
||||
const admin = await findAdminById(ctx.user.adminId);
|
||||
const servers = await findServersByAdminId(admin.adminId);
|
||||
if (IS_CLOUD && servers.length >= admin.serversQuantity) {
|
||||
const user = await findUserById(ctx.user.ownerId);
|
||||
const servers = await findServersByUserId(user.id);
|
||||
if (IS_CLOUD && servers.length >= user.serversQuantity) {
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "You cannot create more servers",
|
||||
});
|
||||
}
|
||||
const project = await createServer(input, ctx.user.adminId);
|
||||
const project = await createServer(input, ctx.user.ownerId);
|
||||
return project;
|
||||
} catch (error) {
|
||||
throw new TRPCError({
|
||||
@@ -65,7 +65,7 @@ export const serverRouter = createTRPCRouter({
|
||||
.input(apiFindOneServer)
|
||||
.query(async ({ input, ctx }) => {
|
||||
const server = await findServerById(input.serverId);
|
||||
if (server.adminId !== ctx.user.adminId) {
|
||||
if (server.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
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(mysql, eq(mysql.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))
|
||||
.groupBy(server.serverId);
|
||||
|
||||
@@ -105,10 +105,10 @@ export const serverRouter = createTRPCRouter({
|
||||
where: IS_CLOUD
|
||||
? and(
|
||||
isNotNull(server.sshKeyId),
|
||||
eq(server.adminId, ctx.user.adminId),
|
||||
eq(server.userId, ctx.user.ownerId),
|
||||
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;
|
||||
}),
|
||||
@@ -117,7 +117,7 @@ export const serverRouter = createTRPCRouter({
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
const server = await findServerById(input.serverId);
|
||||
if (server.adminId !== ctx.user.adminId) {
|
||||
if (server.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to setup this server",
|
||||
@@ -142,7 +142,7 @@ export const serverRouter = createTRPCRouter({
|
||||
.subscription(async ({ input, ctx }) => {
|
||||
try {
|
||||
const server = await findServerById(input.serverId);
|
||||
if (server.adminId !== ctx.user.adminId) {
|
||||
if (server.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to setup this server",
|
||||
@@ -162,7 +162,7 @@ export const serverRouter = createTRPCRouter({
|
||||
.query(async ({ input, ctx }) => {
|
||||
try {
|
||||
const server = await findServerById(input.serverId);
|
||||
if (server.adminId !== ctx.user.adminId) {
|
||||
if (server.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to validate this server",
|
||||
@@ -204,7 +204,7 @@ export const serverRouter = createTRPCRouter({
|
||||
.query(async ({ input, ctx }) => {
|
||||
try {
|
||||
const server = await findServerById(input.serverId);
|
||||
if (server.adminId !== ctx.user.adminId) {
|
||||
if (server.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to validate this server",
|
||||
@@ -254,7 +254,7 @@ export const serverRouter = createTRPCRouter({
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
const server = await findServerById(input.serverId);
|
||||
if (server.adminId !== ctx.user.adminId) {
|
||||
if (server.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to setup this server",
|
||||
@@ -296,7 +296,7 @@ export const serverRouter = createTRPCRouter({
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
const server = await findServerById(input.serverId);
|
||||
if (server.adminId !== ctx.user.adminId) {
|
||||
if (server.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to delete this server",
|
||||
@@ -315,12 +315,9 @@ export const serverRouter = createTRPCRouter({
|
||||
await deleteServer(input.serverId);
|
||||
|
||||
if (IS_CLOUD) {
|
||||
const admin = await findAdminById(ctx.user.adminId);
|
||||
const admin = await findUserById(ctx.user.ownerId);
|
||||
|
||||
await updateServersBasedOnQuantity(
|
||||
admin.adminId,
|
||||
admin.serversQuantity,
|
||||
);
|
||||
await updateServersBasedOnQuantity(admin.id, admin.serversQuantity);
|
||||
}
|
||||
|
||||
return currentServer;
|
||||
@@ -333,7 +330,7 @@ export const serverRouter = createTRPCRouter({
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
const server = await findServerById(input.serverId);
|
||||
if (server.adminId !== ctx.user.adminId) {
|
||||
if (server.userId !== ctx.user.ownerId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to update this server",
|
||||
|
||||
@@ -47,7 +47,6 @@ import {
|
||||
startServiceRemote,
|
||||
stopService,
|
||||
stopServiceRemote,
|
||||
updateAdmin,
|
||||
updateLetsEncryptEmail,
|
||||
updateServerById,
|
||||
updateServerTraefik,
|
||||
@@ -383,7 +382,7 @@ export const settingsRouter = createTRPCRouter({
|
||||
.input(apiServerSchema)
|
||||
.query(async ({ ctx, input }) => {
|
||||
try {
|
||||
if (ctx.user.rol === "user") {
|
||||
if (ctx.user.rol === "member") {
|
||||
const canAccess = await canAccessToTraefikFiles(ctx.user.authId);
|
||||
|
||||
if (!canAccess) {
|
||||
@@ -401,7 +400,7 @@ export const settingsRouter = createTRPCRouter({
|
||||
updateTraefikFile: protectedProcedure
|
||||
.input(apiModifyTraefikConfig)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
if (ctx.user.rol === "user") {
|
||||
if (ctx.user.rol === "member") {
|
||||
const canAccess = await canAccessToTraefikFiles(ctx.user.authId);
|
||||
|
||||
if (!canAccess) {
|
||||
@@ -419,7 +418,7 @@ export const settingsRouter = createTRPCRouter({
|
||||
readTraefikFile: protectedProcedure
|
||||
.input(apiReadTraefikConfig)
|
||||
.query(async ({ input, ctx }) => {
|
||||
if (ctx.user.rol === "user") {
|
||||
if (ctx.user.rol === "member") {
|
||||
const canAccess = await canAccessToTraefikFiles(ctx.user.authId);
|
||||
|
||||
if (!canAccess) {
|
||||
@@ -655,7 +654,7 @@ export const settingsRouter = createTRPCRouter({
|
||||
|
||||
return true;
|
||||
}),
|
||||
isCloud: protectedProcedure.query(async () => {
|
||||
isCloud: publicProcedure.query(async () => {
|
||||
return IS_CLOUD;
|
||||
}),
|
||||
health: publicProcedure.query(async () => {
|
||||
|
||||
@@ -24,9 +24,10 @@ export const sshRouter = createTRPCRouter({
|
||||
.input(apiCreateSshKey)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
console.log(ctx.user.ownerId);
|
||||
await createSshKey({
|
||||
...input,
|
||||
adminId: ctx.user.adminId,
|
||||
userId: ctx.user.ownerId,
|
||||
});
|
||||
} catch (error) {
|
||||
throw new TRPCError({
|
||||
@@ -41,7 +42,7 @@ export const sshRouter = createTRPCRouter({
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
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
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
@@ -59,7 +60,7 @@ export const sshRouter = createTRPCRouter({
|
||||
.query(async ({ input, ctx }) => {
|
||||
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
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
@@ -70,7 +71,7 @@ export const sshRouter = createTRPCRouter({
|
||||
}),
|
||||
all: protectedProcedure.query(async ({ ctx }) => {
|
||||
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),
|
||||
});
|
||||
// TODO: Remove this line when the cloud version is ready
|
||||
@@ -85,7 +86,7 @@ export const sshRouter = createTRPCRouter({
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
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
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { WEBSITE_URL, getStripeItems } from "@/server/utils/stripe";
|
||||
import {
|
||||
IS_CLOUD,
|
||||
findAdminById,
|
||||
findServersByAdminId,
|
||||
updateAdmin,
|
||||
findServersByUserId,
|
||||
findUserById,
|
||||
updateUser,
|
||||
} from "@dokploy/server";
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import Stripe from "stripe";
|
||||
@@ -12,8 +12,8 @@ import { adminProcedure, createTRPCRouter } from "../trpc";
|
||||
|
||||
export const stripeRouter = createTRPCRouter({
|
||||
getProducts: adminProcedure.query(async ({ ctx }) => {
|
||||
const admin = await findAdminById(ctx.user.adminId);
|
||||
const stripeCustomerId = admin.stripeCustomerId;
|
||||
const user = await findUserById(ctx.user.ownerId);
|
||||
const stripeCustomerId = user.stripeCustomerId;
|
||||
|
||||
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
|
||||
apiVersion: "2024-09-30.acacia",
|
||||
@@ -56,15 +56,15 @@ export const stripeRouter = createTRPCRouter({
|
||||
});
|
||||
|
||||
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) {
|
||||
const customer = await stripe.customers.retrieve(stripeCustomerId);
|
||||
|
||||
if (customer.deleted) {
|
||||
await updateAdmin(admin.authId, {
|
||||
await updateUser(user.id, {
|
||||
stripeCustomerId: null,
|
||||
});
|
||||
stripeCustomerId = null;
|
||||
@@ -78,7 +78,7 @@ export const stripeRouter = createTRPCRouter({
|
||||
customer: stripeCustomerId,
|
||||
}),
|
||||
metadata: {
|
||||
adminId: admin.adminId,
|
||||
ownerId: user.id,
|
||||
},
|
||||
allow_promotion_codes: true,
|
||||
success_url: `${WEBSITE_URL}/dashboard/settings/servers?success=true`,
|
||||
@@ -89,15 +89,15 @@ export const stripeRouter = createTRPCRouter({
|
||||
}),
|
||||
createCustomerPortalSession: adminProcedure.mutation(
|
||||
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({
|
||||
code: "BAD_REQUEST",
|
||||
message: "Stripe Customer ID not found",
|
||||
});
|
||||
}
|
||||
const stripeCustomerId = admin.stripeCustomerId;
|
||||
const stripeCustomerId = user.stripeCustomerId;
|
||||
|
||||
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
|
||||
apiVersion: "2024-09-30.acacia",
|
||||
@@ -119,13 +119,13 @@ export const stripeRouter = createTRPCRouter({
|
||||
),
|
||||
|
||||
canCreateMoreServers: adminProcedure.query(async ({ ctx }) => {
|
||||
const admin = await findAdminById(ctx.user.adminId);
|
||||
const servers = await findServersByAdminId(admin.adminId);
|
||||
const user = await findUserById(ctx.user.ownerId);
|
||||
const servers = await findServersByUserId(user.id);
|
||||
|
||||
if (!IS_CLOUD) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return servers.length < admin.serversQuantity;
|
||||
return servers.length < user.serversQuantity;
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
|
||||
// import { getServerAuthSession } from "@/server/auth";
|
||||
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 { TRPCError, initTRPC } from "@trpc/server";
|
||||
import type { CreateNextContextOptions } from "@trpc/server/adapters/next";
|
||||
@@ -18,7 +19,7 @@ import {
|
||||
experimental_isMultipartFormDataRequest,
|
||||
experimental_parseMultipartFormData,
|
||||
} 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 { ZodError } from "zod";
|
||||
/**
|
||||
@@ -30,8 +31,8 @@ import { ZodError } from "zod";
|
||||
*/
|
||||
|
||||
interface CreateContextOptions {
|
||||
user: (User & { authId: string; adminId: string }) | null;
|
||||
session: Session | null;
|
||||
user: (User & { rol: "member" | "admin" | "owner"; ownerId: string }) | null;
|
||||
session: (Session & { activeOrganizationId?: string }) | null;
|
||||
req: CreateNextContextOptions["req"];
|
||||
res: CreateNextContextOptions["res"];
|
||||
}
|
||||
@@ -65,30 +66,36 @@ const createInnerTRPCContext = (opts: CreateContextOptions) => {
|
||||
export const createTRPCContext = async (opts: CreateNextContextOptions) => {
|
||||
const { req, res } = opts;
|
||||
|
||||
let { session, user } = await validateBearerToken(req);
|
||||
// Get from the request
|
||||
const { session, user } = await validateRequest(req);
|
||||
|
||||
if (!session) {
|
||||
const cookieResult = await validateRequest(req, res);
|
||||
session = cookieResult.session;
|
||||
user = cookieResult.user;
|
||||
}
|
||||
// if (!session) {
|
||||
// const cookieResult = await validateRequest(req);
|
||||
// session = cookieResult.session;
|
||||
// user = cookieResult.user;
|
||||
// }
|
||||
|
||||
console.log("session", session);
|
||||
console.log("user", user);
|
||||
|
||||
return createInnerTRPCContext({
|
||||
req,
|
||||
res,
|
||||
session: session,
|
||||
...((user && {
|
||||
user: {
|
||||
authId: user.id,
|
||||
email: user.email,
|
||||
rol: user.rol,
|
||||
id: user.id,
|
||||
secret: user.secret,
|
||||
adminId: user.adminId,
|
||||
},
|
||||
}) || {
|
||||
user: null,
|
||||
}),
|
||||
session: session
|
||||
? {
|
||||
...session,
|
||||
activeOrganizationId: session.activeOrganizationId ?? undefined,
|
||||
}
|
||||
: null,
|
||||
user: user
|
||||
? {
|
||||
...user,
|
||||
email: user.email,
|
||||
rol: user.role as "owner" | "member" | "admin",
|
||||
id: user.id,
|
||||
ownerId: user.ownerId,
|
||||
}
|
||||
: null,
|
||||
});
|
||||
};
|
||||
|
||||
@@ -181,7 +188,7 @@ export const uploadProcedure = async (opts: any) => {
|
||||
};
|
||||
|
||||
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" });
|
||||
}
|
||||
return next({
|
||||
@@ -195,7 +202,7 @@ export const cliProcedure = 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" });
|
||||
}
|
||||
return next({
|
||||
|
||||
@@ -34,14 +34,14 @@ void app.prepare().then(async () => {
|
||||
});
|
||||
|
||||
// WEBSOCKET
|
||||
setupDrawerLogsWebSocketServer(server);
|
||||
setupDeploymentLogsWebSocketServer(server);
|
||||
setupDockerContainerLogsWebSocketServer(server);
|
||||
setupDockerContainerTerminalWebSocketServer(server);
|
||||
setupTerminalWebSocketServer(server);
|
||||
if (!IS_CLOUD) {
|
||||
setupDockerStatsMonitoringSocketServer(server);
|
||||
}
|
||||
// setupDrawerLogsWebSocketServer(server);
|
||||
// setupDeploymentLogsWebSocketServer(server);
|
||||
// setupDockerContainerLogsWebSocketServer(server);
|
||||
// setupDockerContainerTerminalWebSocketServer(server);
|
||||
// setupTerminalWebSocketServer(server);
|
||||
// if (!IS_CLOUD) {
|
||||
// setupDockerStatsMonitoringSocketServer(server);
|
||||
// }
|
||||
|
||||
if (process.env.NODE_ENV === "production" && !IS_CLOUD) {
|
||||
setupDirectories();
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
import {
|
||||
boolean,
|
||||
integer,
|
||||
pgTable,
|
||||
text,
|
||||
timestamp,
|
||||
} from "drizzle-orm/pg-core";
|
||||
|
||||
export const user = pgTable("user", {
|
||||
id: text("id").primaryKey(),
|
||||
name: text("name").notNull(),
|
||||
email: text("email").notNull().unique(),
|
||||
emailVerified: boolean("email_verified").notNull(),
|
||||
image: text("image"),
|
||||
createdAt: timestamp("created_at").notNull(),
|
||||
updatedAt: timestamp("updated_at").notNull(),
|
||||
});
|
||||
|
||||
export const session = pgTable("session", {
|
||||
id: text("id").primaryKey(),
|
||||
expiresAt: timestamp("expires_at").notNull(),
|
||||
token: text("token").notNull().unique(),
|
||||
createdAt: timestamp("created_at").notNull(),
|
||||
updatedAt: timestamp("updated_at").notNull(),
|
||||
ipAddress: text("ip_address"),
|
||||
userAgent: text("user_agent"),
|
||||
userId: text("user_id")
|
||||
.notNull()
|
||||
.references(() => user.id),
|
||||
activeOrganizationId: text("active_organization_id"),
|
||||
});
|
||||
|
||||
export const account = pgTable("account", {
|
||||
id: text("id").primaryKey(),
|
||||
accountId: text("account_id").notNull(),
|
||||
providerId: text("provider_id").notNull(),
|
||||
userId: text("user_id")
|
||||
.notNull()
|
||||
.references(() => user.id),
|
||||
accessToken: text("access_token"),
|
||||
refreshToken: text("refresh_token"),
|
||||
idToken: text("id_token"),
|
||||
accessTokenExpiresAt: timestamp("access_token_expires_at"),
|
||||
refreshTokenExpiresAt: timestamp("refresh_token_expires_at"),
|
||||
scope: text("scope"),
|
||||
password: text("password"),
|
||||
createdAt: timestamp("created_at").notNull(),
|
||||
updatedAt: timestamp("updated_at").notNull(),
|
||||
});
|
||||
|
||||
export const verification = pgTable("verification", {
|
||||
id: text("id").primaryKey(),
|
||||
identifier: text("identifier").notNull(),
|
||||
value: text("value").notNull(),
|
||||
expiresAt: timestamp("expires_at").notNull(),
|
||||
createdAt: timestamp("created_at"),
|
||||
updatedAt: timestamp("updated_at"),
|
||||
});
|
||||
|
||||
export const organization = pgTable("organization", {
|
||||
id: text("id").primaryKey(),
|
||||
name: text("name").notNull(),
|
||||
slug: text("slug").unique(),
|
||||
logo: text("logo"),
|
||||
createdAt: timestamp("created_at").notNull(),
|
||||
metadata: text("metadata"),
|
||||
ownerId: text("owner_id")
|
||||
.notNull()
|
||||
.references(() => user.userId),
|
||||
});
|
||||
|
||||
export const member = pgTable("member", {
|
||||
id: text("id").primaryKey(),
|
||||
organizationId: text("organization_id")
|
||||
.notNull()
|
||||
.references(() => organization.id),
|
||||
userId: text("user_id")
|
||||
.notNull()
|
||||
.references(() => user.userId),
|
||||
role: text("role").notNull(),
|
||||
createdAt: timestamp("created_at").notNull(),
|
||||
});
|
||||
|
||||
export const invitation = pgTable("invitation", {
|
||||
id: text("id").primaryKey(),
|
||||
organizationId: text("organization_id")
|
||||
.notNull()
|
||||
.references(() => organization.id),
|
||||
email: text("email").notNull(),
|
||||
role: text("role"),
|
||||
status: text("status").notNull(),
|
||||
expiresAt: timestamp("expires_at").notNull(),
|
||||
inviterId: text("inviter_id")
|
||||
.notNull()
|
||||
.references(() => user.userId),
|
||||
});
|
||||
@@ -28,6 +28,10 @@
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@oslojs/encoding":"1.1.0",
|
||||
"@oslojs/crypto":"1.0.1",
|
||||
"drizzle-dbml-generator":"0.10.0",
|
||||
"better-auth":"1.1.16",
|
||||
"rotating-file-stream": "3.2.3",
|
||||
"@faker-js/faker": "^8.4.1",
|
||||
"@lucia-auth/adapter-drizzle": "1.0.7",
|
||||
|
||||
@@ -6,9 +6,9 @@ import { TimeSpan } from "lucia";
|
||||
import { Lucia } from "lucia/dist/core.js";
|
||||
import type { Session, User } from "lucia/dist/core.js";
|
||||
import { db } from "../db";
|
||||
import { type DatabaseUser, auth, sessionTable } from "../db/schema";
|
||||
import { type DatabaseUser, auth, session } from "../db/schema";
|
||||
|
||||
export const adapter = new DrizzlePostgreSQLAdapter(db, sessionTable, auth);
|
||||
export const adapter = new DrizzlePostgreSQLAdapter(db, session, auth);
|
||||
|
||||
export const lucia = new Lucia(adapter, {
|
||||
sessionCookie: {
|
||||
@@ -16,6 +16,7 @@ export const lucia = new Lucia(adapter, {
|
||||
secure: false,
|
||||
},
|
||||
},
|
||||
|
||||
sessionExpiresIn: new TimeSpan(1, "d"),
|
||||
getUserAttributes: (attributes) => {
|
||||
return {
|
||||
@@ -46,6 +47,7 @@ export async function validateRequest(
|
||||
req: IncomingMessage,
|
||||
res: ServerResponse,
|
||||
): ReturnValidateToken {
|
||||
console.log(session);
|
||||
const sessionId = lucia.readSessionCookie(req.headers.cookie ?? "");
|
||||
|
||||
if (!sessionId) {
|
||||
@@ -69,10 +71,10 @@ export async function validateRequest(
|
||||
}
|
||||
if (result.user) {
|
||||
try {
|
||||
if (result.user?.rol === "admin") {
|
||||
if (result.user?.rol === "owner") {
|
||||
const admin = await findAdminByAuthId(result.user.id);
|
||||
result.user.adminId = admin.adminId;
|
||||
} else if (result.user?.rol === "user") {
|
||||
} else if (result.user?.rol === "member") {
|
||||
const userResult = await findUserByAuthId(result.user.id);
|
||||
result.user.adminId = userResult.adminId;
|
||||
}
|
||||
|
||||
@@ -35,10 +35,10 @@ export const validateBearerToken = async (
|
||||
const result = await luciaToken.validateSession(sessionId);
|
||||
|
||||
if (result.user) {
|
||||
if (result.user?.rol === "admin") {
|
||||
if (result.user?.rol === "owner") {
|
||||
const admin = await findAdminByAuthId(result.user.id);
|
||||
result.user.adminId = admin.adminId;
|
||||
} else if (result.user?.rol === "user") {
|
||||
} else if (result.user?.rol === "member") {
|
||||
const userResult = await findUserByAuthId(result.user.id);
|
||||
result.user.adminId = userResult.adminId;
|
||||
}
|
||||
@@ -73,10 +73,10 @@ export const validateBearerTokenAPI = async (
|
||||
const result = await luciaToken.validateSession(sessionId);
|
||||
|
||||
if (result.user) {
|
||||
if (result.user?.rol === "admin") {
|
||||
if (result.user?.rol === "owner") {
|
||||
const admin = await findAdminByAuthId(result.user.id);
|
||||
result.user.adminId = admin.adminId;
|
||||
} else if (result.user?.rol === "user") {
|
||||
} else if (result.user?.rol === "member") {
|
||||
const userResult = await findUserByAuthId(result.user.id);
|
||||
result.user.adminId = userResult.adminId;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
import { relations } from "drizzle-orm";
|
||||
import { boolean, pgTable, text, timestamp } from "drizzle-orm/pg-core";
|
||||
import { nanoid } from "nanoid";
|
||||
import { users_temp } from "./user";
|
||||
|
||||
export const account = pgTable("account", {
|
||||
id: text("id")
|
||||
.primaryKey()
|
||||
.$defaultFn(() => nanoid()),
|
||||
accountId: text("account_id")
|
||||
.notNull()
|
||||
.$defaultFn(() => nanoid()),
|
||||
providerId: text("provider_id").notNull(),
|
||||
userId: text("user_id")
|
||||
.notNull()
|
||||
.references(() => users_temp.id),
|
||||
accessToken: text("access_token"),
|
||||
refreshToken: text("refresh_token"),
|
||||
idToken: text("id_token"),
|
||||
accessTokenExpiresAt: timestamp("access_token_expires_at"),
|
||||
refreshTokenExpiresAt: timestamp("refresh_token_expires_at"),
|
||||
scope: text("scope"),
|
||||
password: text("password"),
|
||||
is2FAEnabled: boolean("is2FAEnabled").notNull().default(false),
|
||||
createdAt: timestamp("created_at").notNull(),
|
||||
updatedAt: timestamp("updated_at").notNull(),
|
||||
resetPasswordToken: text("resetPasswordToken"),
|
||||
resetPasswordExpiresAt: text("resetPasswordExpiresAt"),
|
||||
confirmationToken: text("confirmationToken"),
|
||||
confirmationExpiresAt: text("confirmationExpiresAt"),
|
||||
});
|
||||
|
||||
export const accountRelations = relations(account, ({ one }) => ({
|
||||
user: one(users_temp, {
|
||||
fields: [account.userId],
|
||||
references: [users_temp.id],
|
||||
}),
|
||||
}));
|
||||
|
||||
export const verification = pgTable("verification", {
|
||||
id: text("id").primaryKey(),
|
||||
identifier: text("identifier").notNull(),
|
||||
value: text("value").notNull(),
|
||||
expiresAt: timestamp("expires_at").notNull(),
|
||||
createdAt: timestamp("created_at"),
|
||||
updatedAt: timestamp("updated_at"),
|
||||
});
|
||||
|
||||
export const organization = pgTable("organization", {
|
||||
id: text("id")
|
||||
.primaryKey()
|
||||
.$defaultFn(() => nanoid()),
|
||||
name: text("name").notNull(),
|
||||
slug: text("slug").unique(),
|
||||
logo: text("logo"),
|
||||
createdAt: timestamp("created_at").notNull(),
|
||||
metadata: text("metadata"),
|
||||
ownerId: text("owner_id")
|
||||
.notNull()
|
||||
.references(() => users_temp.id),
|
||||
});
|
||||
|
||||
export const organizationRelations = relations(organization, ({ one }) => ({
|
||||
owner: one(users_temp, {
|
||||
fields: [organization.ownerId],
|
||||
references: [users_temp.id],
|
||||
}),
|
||||
}));
|
||||
|
||||
export const member = pgTable("member", {
|
||||
id: text("id")
|
||||
.primaryKey()
|
||||
.$defaultFn(() => nanoid()),
|
||||
organizationId: text("organization_id")
|
||||
.notNull()
|
||||
.references(() => organization.id),
|
||||
userId: text("user_id")
|
||||
.notNull()
|
||||
.references(() => users_temp.id),
|
||||
role: text("role").notNull().$type<"owner" | "member" | "admin">(),
|
||||
createdAt: timestamp("created_at").notNull(),
|
||||
});
|
||||
|
||||
export const memberRelations = relations(member, ({ one }) => ({
|
||||
organization: one(organization, {
|
||||
fields: [member.organizationId],
|
||||
references: [organization.id],
|
||||
}),
|
||||
user: one(users_temp, {
|
||||
fields: [member.userId],
|
||||
references: [users_temp.id],
|
||||
}),
|
||||
}));
|
||||
|
||||
export const invitation = pgTable("invitation", {
|
||||
id: text("id").primaryKey(),
|
||||
organizationId: text("organization_id")
|
||||
.notNull()
|
||||
.references(() => organization.id),
|
||||
email: text("email").notNull(),
|
||||
role: text("role").$type<"owner" | "member" | "admin">(),
|
||||
status: text("status").notNull(),
|
||||
expiresAt: timestamp("expires_at").notNull(),
|
||||
inviterId: text("inviter_id")
|
||||
.notNull()
|
||||
.references(() => users_temp.id),
|
||||
});
|
||||
|
||||
export const invitationRelations = relations(invitation, ({ one }) => ({
|
||||
organization: one(organization, {
|
||||
fields: [invitation.organizationId],
|
||||
references: [organization.id],
|
||||
}),
|
||||
}));
|
||||
@@ -4,7 +4,7 @@ import { boolean, pgEnum, pgTable, text } from "drizzle-orm/pg-core";
|
||||
import { createInsertSchema } from "drizzle-zod";
|
||||
import { nanoid } from "nanoid";
|
||||
import { z } from "zod";
|
||||
import { admins } from "./admin";
|
||||
// import { admins } from "./admin";
|
||||
import { users } from "./user";
|
||||
|
||||
const randomImages = [
|
||||
@@ -55,7 +55,7 @@ export const auth = pgTable("auth", {
|
||||
});
|
||||
|
||||
export const authRelations = relations(auth, ({ many }) => ({
|
||||
admins: many(admins),
|
||||
// admins: many(admins),
|
||||
users: many(users),
|
||||
}));
|
||||
const createSchema = createInsertSchema(auth, {
|
||||
|
||||
@@ -61,5 +61,5 @@ export const apiUpdateBitbucket = createSchema.extend({
|
||||
name: z.string().min(1),
|
||||
bitbucketUsername: z.string().optional(),
|
||||
bitbucketWorkspaceName: z.string().optional(),
|
||||
adminId: z.string().optional(),
|
||||
userId: z.string().optional(),
|
||||
});
|
||||
|
||||
@@ -5,6 +5,8 @@ import { nanoid } from "nanoid";
|
||||
import { z } from "zod";
|
||||
import { admins } from "./admin";
|
||||
import { server } from "./server";
|
||||
import { users_temp } from "./user";
|
||||
// import { user } from "./user";
|
||||
import { generateAppName } from "./utils";
|
||||
|
||||
export const certificates = pgTable("certificate", {
|
||||
@@ -20,9 +22,12 @@ export const certificates = pgTable("certificate", {
|
||||
.$defaultFn(() => generateAppName("certificate"))
|
||||
.unique(),
|
||||
autoRenew: boolean("autoRenew"),
|
||||
adminId: text("adminId").references(() => admins.adminId, {
|
||||
onDelete: "cascade",
|
||||
}),
|
||||
// userId: text("userId").references(() => user.userId, {
|
||||
// onDelete: "cascade",
|
||||
// }),
|
||||
userId: text("userId")
|
||||
.notNull()
|
||||
.references(() => users_temp.id, { onDelete: "cascade" }),
|
||||
serverId: text("serverId").references(() => server.serverId, {
|
||||
onDelete: "cascade",
|
||||
}),
|
||||
@@ -35,9 +40,9 @@ export const certificatesRelations = relations(
|
||||
fields: [certificates.serverId],
|
||||
references: [server.serverId],
|
||||
}),
|
||||
admin: one(admins, {
|
||||
fields: [certificates.adminId],
|
||||
references: [admins.adminId],
|
||||
user: one(users_temp, {
|
||||
fields: [certificates.userId],
|
||||
references: [users_temp.id],
|
||||
}),
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import { pgGenerate } from "drizzle-dbml-generator"; // Using Postgres for this example
|
||||
import * as schema from "./index";
|
||||
|
||||
const out = "./schema.dbml";
|
||||
const relational = true;
|
||||
|
||||
pgGenerate({ schema, out, relational });
|
||||
@@ -5,6 +5,8 @@ import { nanoid } from "nanoid";
|
||||
import { z } from "zod";
|
||||
import { admins } from "./admin";
|
||||
import { backups } from "./backups";
|
||||
import { users_temp } from "./user";
|
||||
// import { user } from "./user";
|
||||
|
||||
export const destinations = pgTable("destination", {
|
||||
destinationId: text("destinationId")
|
||||
@@ -19,19 +21,22 @@ export const destinations = pgTable("destination", {
|
||||
region: text("region").notNull(),
|
||||
// maybe it can be null
|
||||
endpoint: text("endpoint").notNull(),
|
||||
adminId: text("adminId")
|
||||
// userId: text("userId")
|
||||
// .notNull()
|
||||
// .references(() => user.userId, { onDelete: "cascade" }),
|
||||
userId: text("userId")
|
||||
.notNull()
|
||||
.references(() => admins.adminId, { onDelete: "cascade" }),
|
||||
.references(() => users_temp.id, { onDelete: "cascade" }),
|
||||
});
|
||||
|
||||
export const destinationsRelations = relations(
|
||||
destinations,
|
||||
({ many, one }) => ({
|
||||
backups: many(backups),
|
||||
admin: one(admins, {
|
||||
fields: [destinations.adminId],
|
||||
references: [admins.adminId],
|
||||
}),
|
||||
// user: one(user, {
|
||||
// fields: [destinations.userId],
|
||||
// references: [user.id],
|
||||
// }),
|
||||
}),
|
||||
);
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@ import { admins } from "./admin";
|
||||
import { bitbucket } from "./bitbucket";
|
||||
import { github } from "./github";
|
||||
import { gitlab } from "./gitlab";
|
||||
import { users_temp } from "./user";
|
||||
// import { user } from "./user";
|
||||
|
||||
export const gitProviderType = pgEnum("gitProviderType", [
|
||||
"github",
|
||||
@@ -24,9 +26,12 @@ export const gitProvider = pgTable("git_provider", {
|
||||
createdAt: text("createdAt")
|
||||
.notNull()
|
||||
.$defaultFn(() => new Date().toISOString()),
|
||||
adminId: text("adminId").references(() => admins.adminId, {
|
||||
onDelete: "cascade",
|
||||
}),
|
||||
// userId: text("userId").references(() => user.userId, {
|
||||
// onDelete: "cascade",
|
||||
// }),
|
||||
userId: text("userId")
|
||||
.notNull()
|
||||
.references(() => users_temp.id, { onDelete: "cascade" }),
|
||||
});
|
||||
|
||||
export const gitProviderRelations = relations(gitProvider, ({ one, many }) => ({
|
||||
@@ -42,9 +47,9 @@ export const gitProviderRelations = relations(gitProvider, ({ one, many }) => ({
|
||||
fields: [gitProvider.gitProviderId],
|
||||
references: [bitbucket.gitProviderId],
|
||||
}),
|
||||
admin: one(admins, {
|
||||
fields: [gitProvider.adminId],
|
||||
references: [admins.adminId],
|
||||
user: one(users_temp, {
|
||||
fields: [gitProvider.userId],
|
||||
references: [users_temp.id],
|
||||
}),
|
||||
}));
|
||||
|
||||
|
||||
@@ -30,3 +30,4 @@ export * from "./gitlab";
|
||||
export * from "./server";
|
||||
export * from "./utils";
|
||||
export * from "./preview-deployments";
|
||||
export * from "./account";
|
||||
|
||||
@@ -3,7 +3,8 @@ import { boolean, integer, pgEnum, pgTable, text } from "drizzle-orm/pg-core";
|
||||
import { createInsertSchema } from "drizzle-zod";
|
||||
import { nanoid } from "nanoid";
|
||||
import { z } from "zod";
|
||||
import { admins } from "./admin";
|
||||
import { users_temp } from "./user";
|
||||
// import { user } from "./user";
|
||||
|
||||
export const notificationType = pgEnum("notificationType", [
|
||||
"slack",
|
||||
@@ -44,9 +45,12 @@ export const notifications = pgTable("notification", {
|
||||
gotifyId: text("gotifyId").references(() => gotify.gotifyId, {
|
||||
onDelete: "cascade",
|
||||
}),
|
||||
adminId: text("adminId").references(() => admins.adminId, {
|
||||
onDelete: "cascade",
|
||||
}),
|
||||
// userId: text("userId").references(() => user.userId, {
|
||||
// onDelete: "cascade",
|
||||
// }),
|
||||
userId: text("userId")
|
||||
.notNull()
|
||||
.references(() => users_temp.id, { onDelete: "cascade" }),
|
||||
});
|
||||
|
||||
export const slack = pgTable("slack", {
|
||||
@@ -121,9 +125,9 @@ export const notificationsRelations = relations(notifications, ({ one }) => ({
|
||||
fields: [notifications.gotifyId],
|
||||
references: [gotify.gotifyId],
|
||||
}),
|
||||
admin: one(admins, {
|
||||
fields: [notifications.adminId],
|
||||
references: [admins.adminId],
|
||||
user: one(users_temp, {
|
||||
fields: [notifications.userId],
|
||||
references: [users_temp.id],
|
||||
}),
|
||||
}));
|
||||
|
||||
@@ -148,7 +152,7 @@ export const apiCreateSlack = notificationsSchema
|
||||
export const apiUpdateSlack = apiCreateSlack.partial().extend({
|
||||
notificationId: z.string().min(1),
|
||||
slackId: z.string(),
|
||||
adminId: z.string().optional(),
|
||||
userId: z.string().optional(),
|
||||
});
|
||||
|
||||
export const apiTestSlackConnection = apiCreateSlack.pick({
|
||||
@@ -175,7 +179,7 @@ export const apiCreateTelegram = notificationsSchema
|
||||
export const apiUpdateTelegram = apiCreateTelegram.partial().extend({
|
||||
notificationId: z.string().min(1),
|
||||
telegramId: z.string().min(1),
|
||||
adminId: z.string().optional(),
|
||||
userId: z.string().optional(),
|
||||
});
|
||||
|
||||
export const apiTestTelegramConnection = apiCreateTelegram.pick({
|
||||
@@ -202,7 +206,7 @@ export const apiCreateDiscord = notificationsSchema
|
||||
export const apiUpdateDiscord = apiCreateDiscord.partial().extend({
|
||||
notificationId: z.string().min(1),
|
||||
discordId: z.string().min(1),
|
||||
adminId: z.string().optional(),
|
||||
userId: z.string().optional(),
|
||||
});
|
||||
|
||||
export const apiTestDiscordConnection = apiCreateDiscord
|
||||
@@ -236,7 +240,7 @@ export const apiCreateEmail = notificationsSchema
|
||||
export const apiUpdateEmail = apiCreateEmail.partial().extend({
|
||||
notificationId: z.string().min(1),
|
||||
emailId: z.string().min(1),
|
||||
adminId: z.string().optional(),
|
||||
userId: z.string().optional(),
|
||||
});
|
||||
|
||||
export const apiTestEmailConnection = apiCreateEmail.pick({
|
||||
@@ -268,7 +272,7 @@ export const apiCreateGotify = notificationsSchema
|
||||
export const apiUpdateGotify = apiCreateGotify.partial().extend({
|
||||
notificationId: z.string().min(1),
|
||||
gotifyId: z.string().min(1),
|
||||
adminId: z.string().optional(),
|
||||
userId: z.string().optional(),
|
||||
});
|
||||
|
||||
export const apiTestGotifyConnection = apiCreateGotify
|
||||
|
||||
@@ -5,6 +5,7 @@ import { createInsertSchema } from "drizzle-zod";
|
||||
import { nanoid } from "nanoid";
|
||||
import { z } from "zod";
|
||||
import { admins } from "./admin";
|
||||
// import { admins } from "./admin";
|
||||
import { applications } from "./application";
|
||||
import { compose } from "./compose";
|
||||
import { mariadb } from "./mariadb";
|
||||
@@ -12,6 +13,7 @@ import { mongo } from "./mongo";
|
||||
import { mysql } from "./mysql";
|
||||
import { postgres } from "./postgres";
|
||||
import { redis } from "./redis";
|
||||
import { users, users_temp } from "./user";
|
||||
|
||||
export const projects = pgTable("project", {
|
||||
projectId: text("projectId")
|
||||
@@ -23,9 +25,12 @@ export const projects = pgTable("project", {
|
||||
createdAt: text("createdAt")
|
||||
.notNull()
|
||||
.$defaultFn(() => new Date().toISOString()),
|
||||
adminId: text("adminId")
|
||||
// userId: text("userId")
|
||||
// .notNull()
|
||||
// .references(() => user.userId, { onDelete: "cascade" }),
|
||||
userId: text("userId")
|
||||
.notNull()
|
||||
.references(() => admins.adminId, { onDelete: "cascade" }),
|
||||
.references(() => users_temp.id, { onDelete: "cascade" }),
|
||||
env: text("env").notNull().default(""),
|
||||
});
|
||||
|
||||
@@ -37,10 +42,10 @@ export const projectRelations = relations(projects, ({ many, one }) => ({
|
||||
mongo: many(mongo),
|
||||
redis: many(redis),
|
||||
compose: many(compose),
|
||||
admin: one(admins, {
|
||||
fields: [projects.adminId],
|
||||
references: [admins.adminId],
|
||||
}),
|
||||
// user: one(user, {
|
||||
// fields: [projects.userId],
|
||||
// references: [user.id],
|
||||
// }),
|
||||
}));
|
||||
|
||||
const createSchema = createInsertSchema(projects, {
|
||||
|
||||
@@ -5,6 +5,8 @@ import { nanoid } from "nanoid";
|
||||
import { z } from "zod";
|
||||
import { admins } from "./admin";
|
||||
import { applications } from "./application";
|
||||
import { users_temp } from "./user";
|
||||
// import { user } from "./user";
|
||||
/**
|
||||
* This is an example of how to use the multi-project schema feature of Drizzle ORM. Use the same
|
||||
* database instance for multiple projects.
|
||||
@@ -27,16 +29,19 @@ export const registry = pgTable("registry", {
|
||||
.notNull()
|
||||
.$defaultFn(() => new Date().toISOString()),
|
||||
registryType: registryType("selfHosted").notNull().default("cloud"),
|
||||
adminId: text("adminId")
|
||||
// userId: text("userId")
|
||||
// .notNull()
|
||||
// .references(() => user.userId, { onDelete: "cascade" }),
|
||||
userId: text("userId")
|
||||
.notNull()
|
||||
.references(() => admins.adminId, { onDelete: "cascade" }),
|
||||
.references(() => users_temp.id, { onDelete: "cascade" }),
|
||||
});
|
||||
|
||||
export const registryRelations = relations(registry, ({ one, many }) => ({
|
||||
admin: one(admins, {
|
||||
fields: [registry.adminId],
|
||||
references: [admins.adminId],
|
||||
}),
|
||||
// user: one(user, {
|
||||
// fields: [registry.userId],
|
||||
// references: [user.id],
|
||||
// }),
|
||||
applications: many(applications),
|
||||
}));
|
||||
|
||||
@@ -45,7 +50,7 @@ const createSchema = createInsertSchema(registry, {
|
||||
username: z.string().min(1),
|
||||
password: z.string().min(1),
|
||||
registryUrl: z.string(),
|
||||
adminId: z.string().min(1),
|
||||
userId: z.string().min(1),
|
||||
registryId: z.string().min(1),
|
||||
registryType: z.enum(["cloud"]),
|
||||
imagePrefix: z.string().nullable().optional(),
|
||||
|
||||
@@ -0,0 +1,872 @@
|
||||
enum applicationStatus {
|
||||
idle
|
||||
running
|
||||
done
|
||||
error
|
||||
}
|
||||
|
||||
enum buildType {
|
||||
dockerfile
|
||||
heroku_buildpacks
|
||||
paketo_buildpacks
|
||||
nixpacks
|
||||
static
|
||||
}
|
||||
|
||||
enum certificateType {
|
||||
letsencrypt
|
||||
none
|
||||
}
|
||||
|
||||
enum composeType {
|
||||
"docker-compose"
|
||||
stack
|
||||
}
|
||||
|
||||
enum databaseType {
|
||||
postgres
|
||||
mariadb
|
||||
mysql
|
||||
mongo
|
||||
}
|
||||
|
||||
enum deploymentStatus {
|
||||
running
|
||||
done
|
||||
error
|
||||
}
|
||||
|
||||
enum domainType {
|
||||
compose
|
||||
application
|
||||
preview
|
||||
}
|
||||
|
||||
enum gitProviderType {
|
||||
github
|
||||
gitlab
|
||||
bitbucket
|
||||
}
|
||||
|
||||
enum mountType {
|
||||
bind
|
||||
volume
|
||||
file
|
||||
}
|
||||
|
||||
enum notificationType {
|
||||
slack
|
||||
telegram
|
||||
discord
|
||||
email
|
||||
gotify
|
||||
}
|
||||
|
||||
enum protocolType {
|
||||
tcp
|
||||
udp
|
||||
}
|
||||
|
||||
enum RegistryType {
|
||||
selfHosted
|
||||
cloud
|
||||
}
|
||||
|
||||
enum Roles {
|
||||
admin
|
||||
user
|
||||
}
|
||||
|
||||
enum serverStatus {
|
||||
active
|
||||
inactive
|
||||
}
|
||||
|
||||
enum serviceType {
|
||||
application
|
||||
postgres
|
||||
mysql
|
||||
mariadb
|
||||
mongo
|
||||
redis
|
||||
compose
|
||||
}
|
||||
|
||||
enum sourceType {
|
||||
docker
|
||||
git
|
||||
github
|
||||
gitlab
|
||||
bitbucket
|
||||
drop
|
||||
}
|
||||
|
||||
enum sourceTypeCompose {
|
||||
git
|
||||
github
|
||||
gitlab
|
||||
bitbucket
|
||||
raw
|
||||
}
|
||||
|
||||
table account {
|
||||
id text [pk, 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 [not null, default: false]
|
||||
created_at timestamp [not null]
|
||||
updated_at timestamp [not null]
|
||||
resetPasswordToken text
|
||||
resetPasswordExpiresAt text
|
||||
confirmationToken text
|
||||
confirmationExpiresAt text
|
||||
}
|
||||
|
||||
table admin {
|
||||
}
|
||||
|
||||
table application {
|
||||
applicationId text [pk, not null]
|
||||
name text [not null]
|
||||
appName text [not null, unique]
|
||||
description text
|
||||
env text
|
||||
previewEnv text
|
||||
previewBuildArgs text
|
||||
previewWildcard text
|
||||
previewPort integer [default: 3000]
|
||||
previewHttps boolean [not null, default: false]
|
||||
previewPath text [default: '/']
|
||||
certificateType certificateType [not null, default: 'none']
|
||||
previewLimit integer [default: 3]
|
||||
isPreviewDeploymentsActive boolean [default: false]
|
||||
buildArgs text
|
||||
memoryReservation text
|
||||
memoryLimit text
|
||||
cpuReservation text
|
||||
cpuLimit text
|
||||
title text
|
||||
enabled boolean
|
||||
subtitle text
|
||||
command text
|
||||
refreshToken text
|
||||
sourceType sourceType [not null, default: 'github']
|
||||
repository text
|
||||
owner text
|
||||
branch text
|
||||
buildPath text [default: '/']
|
||||
autoDeploy boolean
|
||||
gitlabProjectId integer
|
||||
gitlabRepository text
|
||||
gitlabOwner text
|
||||
gitlabBranch text
|
||||
gitlabBuildPath text [default: '/']
|
||||
gitlabPathNamespace text
|
||||
bitbucketRepository text
|
||||
bitbucketOwner text
|
||||
bitbucketBranch text
|
||||
bitbucketBuildPath text [default: '/']
|
||||
username text
|
||||
password text
|
||||
dockerImage text
|
||||
registryUrl text
|
||||
customGitUrl text
|
||||
customGitBranch text
|
||||
customGitBuildPath text
|
||||
customGitSSHKeyId text
|
||||
dockerfile text
|
||||
dockerContextPath text
|
||||
dockerBuildStage text
|
||||
dropBuildPath text
|
||||
healthCheckSwarm json
|
||||
restartPolicySwarm json
|
||||
placementSwarm json
|
||||
updateConfigSwarm json
|
||||
rollbackConfigSwarm json
|
||||
modeSwarm json
|
||||
labelsSwarm json
|
||||
networkSwarm json
|
||||
replicas integer [not null, default: 1]
|
||||
applicationStatus applicationStatus [not null, default: 'idle']
|
||||
buildType buildType [not null, default: 'nixpacks']
|
||||
herokuVersion text [default: '24']
|
||||
publishDirectory text
|
||||
createdAt text [not null]
|
||||
registryId text
|
||||
projectId text [not null]
|
||||
githubId text
|
||||
gitlabId text
|
||||
bitbucketId text
|
||||
serverId text
|
||||
}
|
||||
|
||||
table auth {
|
||||
id text [pk, not null]
|
||||
email text [not null, unique]
|
||||
password text [not null]
|
||||
rol Roles [not null]
|
||||
image text
|
||||
secret text
|
||||
token text
|
||||
is2FAEnabled boolean [not null, default: false]
|
||||
createdAt text [not null]
|
||||
resetPasswordToken text
|
||||
resetPasswordExpiresAt text
|
||||
confirmationToken text
|
||||
confirmationExpiresAt text
|
||||
}
|
||||
|
||||
table backup {
|
||||
backupId text [pk, not null]
|
||||
schedule text [not null]
|
||||
enabled boolean
|
||||
database text [not null]
|
||||
prefix text [not null]
|
||||
destinationId text [not null]
|
||||
databaseType databaseType [not null]
|
||||
postgresId text
|
||||
mariadbId text
|
||||
mysqlId text
|
||||
mongoId text
|
||||
}
|
||||
|
||||
table bitbucket {
|
||||
bitbucketId text [pk, not null]
|
||||
bitbucketUsername text
|
||||
appPassword text
|
||||
bitbucketWorkspaceName text
|
||||
gitProviderId text [not null]
|
||||
}
|
||||
|
||||
table certificate {
|
||||
certificateId text [pk, not null]
|
||||
name text [not null]
|
||||
certificateData text [not null]
|
||||
privateKey text [not null]
|
||||
certificatePath text [not null, unique]
|
||||
autoRenew boolean
|
||||
userId text
|
||||
serverId text
|
||||
}
|
||||
|
||||
table compose {
|
||||
composeId text [pk, not null]
|
||||
name text [not null]
|
||||
appName text [not null]
|
||||
description text
|
||||
env text
|
||||
composeFile text [not null, default: '']
|
||||
refreshToken text
|
||||
sourceType sourceTypeCompose [not null, default: 'github']
|
||||
composeType composeType [not null, default: 'docker-compose']
|
||||
repository text
|
||||
owner text
|
||||
branch text
|
||||
autoDeploy boolean
|
||||
gitlabProjectId integer
|
||||
gitlabRepository text
|
||||
gitlabOwner text
|
||||
gitlabBranch text
|
||||
gitlabPathNamespace text
|
||||
bitbucketRepository text
|
||||
bitbucketOwner text
|
||||
bitbucketBranch text
|
||||
customGitUrl text
|
||||
customGitBranch text
|
||||
customGitSSHKeyId text
|
||||
command text [not null, default: '']
|
||||
composePath text [not null, default: './docker-compose.yml']
|
||||
suffix text [not null, default: '']
|
||||
randomize boolean [not null, default: false]
|
||||
isolatedDeployment boolean [not null, default: false]
|
||||
composeStatus applicationStatus [not null, default: 'idle']
|
||||
projectId text [not null]
|
||||
createdAt text [not null]
|
||||
githubId text
|
||||
gitlabId text
|
||||
bitbucketId text
|
||||
serverId text
|
||||
}
|
||||
|
||||
table deployment {
|
||||
deploymentId text [pk, not null]
|
||||
title text [not null]
|
||||
description text
|
||||
status deploymentStatus [default: 'running']
|
||||
logPath text [not null]
|
||||
applicationId text
|
||||
composeId text
|
||||
serverId text
|
||||
isPreviewDeployment boolean [default: false]
|
||||
previewDeploymentId text
|
||||
createdAt text [not null]
|
||||
errorMessage text
|
||||
}
|
||||
|
||||
table destination {
|
||||
destinationId text [pk, not null]
|
||||
name text [not null]
|
||||
provider text
|
||||
accessKey text [not null]
|
||||
secretAccessKey text [not null]
|
||||
bucket text [not null]
|
||||
region text [not null]
|
||||
endpoint text [not null]
|
||||
userId text [not null]
|
||||
}
|
||||
|
||||
table discord {
|
||||
discordId text [pk, not null]
|
||||
webhookUrl text [not null]
|
||||
decoration boolean
|
||||
}
|
||||
|
||||
table domain {
|
||||
domainId text [pk, not null]
|
||||
host text [not null]
|
||||
https boolean [not null, default: false]
|
||||
port integer [default: 3000]
|
||||
path text [default: '/']
|
||||
serviceName text
|
||||
domainType domainType [default: 'application']
|
||||
uniqueConfigKey serial [not null, increment]
|
||||
createdAt text [not null]
|
||||
composeId text
|
||||
applicationId text
|
||||
previewDeploymentId text
|
||||
certificateType certificateType [not null, default: 'none']
|
||||
}
|
||||
|
||||
table email {
|
||||
emailId text [pk, not null]
|
||||
smtpServer text [not null]
|
||||
smtpPort integer [not null]
|
||||
username text [not null]
|
||||
password text [not null]
|
||||
fromAddress text [not null]
|
||||
toAddress text[] [not null]
|
||||
}
|
||||
|
||||
table git_provider {
|
||||
gitProviderId text [pk, not null]
|
||||
name text [not null]
|
||||
providerType gitProviderType [not null, default: 'github']
|
||||
createdAt text [not null]
|
||||
userId text
|
||||
}
|
||||
|
||||
table github {
|
||||
githubId text [pk, not null]
|
||||
githubAppName text
|
||||
githubAppId integer
|
||||
githubClientId text
|
||||
githubClientSecret text
|
||||
githubInstallationId text
|
||||
githubPrivateKey text
|
||||
githubWebhookSecret text
|
||||
gitProviderId text [not null]
|
||||
}
|
||||
|
||||
table gitlab {
|
||||
gitlabId text [pk, not null]
|
||||
gitlabUrl text [not null, default: 'https://gitlab.com']
|
||||
application_id text
|
||||
redirect_uri text
|
||||
secret text
|
||||
access_token text
|
||||
refresh_token text
|
||||
group_name text
|
||||
expires_at integer
|
||||
gitProviderId text [not null]
|
||||
}
|
||||
|
||||
table gotify {
|
||||
gotifyId text [pk, not null]
|
||||
serverUrl text [not null]
|
||||
appToken text [not null]
|
||||
priority integer [not null, default: 5]
|
||||
decoration boolean
|
||||
}
|
||||
|
||||
table invitation {
|
||||
id text [pk, 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]
|
||||
}
|
||||
|
||||
table mariadb {
|
||||
mariadbId text [pk, not null]
|
||||
name text [not null]
|
||||
appName text [not null, unique]
|
||||
description text
|
||||
databaseName text [not null]
|
||||
databaseUser text [not null]
|
||||
databasePassword text [not null]
|
||||
rootPassword text [not null]
|
||||
dockerImage text [not null]
|
||||
command text
|
||||
env text
|
||||
memoryReservation text
|
||||
memoryLimit text
|
||||
cpuReservation text
|
||||
cpuLimit text
|
||||
externalPort integer
|
||||
applicationStatus applicationStatus [not null, default: 'idle']
|
||||
createdAt text [not null]
|
||||
projectId text [not null]
|
||||
serverId text
|
||||
}
|
||||
|
||||
table member {
|
||||
id text [pk, not null]
|
||||
organization_id text [not null]
|
||||
user_id text [not null]
|
||||
role text [not null]
|
||||
created_at timestamp [not null]
|
||||
}
|
||||
|
||||
table mongo {
|
||||
mongoId text [pk, not null]
|
||||
name text [not null]
|
||||
appName text [not null, unique]
|
||||
description text
|
||||
databaseUser text [not null]
|
||||
databasePassword text [not null]
|
||||
dockerImage text [not null]
|
||||
command text
|
||||
env text
|
||||
memoryReservation text
|
||||
memoryLimit text
|
||||
cpuReservation text
|
||||
cpuLimit text
|
||||
externalPort integer
|
||||
applicationStatus applicationStatus [not null, default: 'idle']
|
||||
createdAt text [not null]
|
||||
projectId text [not null]
|
||||
serverId text
|
||||
replicaSets boolean [default: false]
|
||||
}
|
||||
|
||||
table mount {
|
||||
mountId text [pk, not null]
|
||||
type mountType [not null]
|
||||
hostPath text
|
||||
volumeName text
|
||||
filePath text
|
||||
content text
|
||||
serviceType serviceType [not null, default: 'application']
|
||||
mountPath text [not null]
|
||||
applicationId text
|
||||
postgresId text
|
||||
mariadbId text
|
||||
mongoId text
|
||||
mysqlId text
|
||||
redisId text
|
||||
composeId text
|
||||
}
|
||||
|
||||
table mysql {
|
||||
mysqlId text [pk, not null]
|
||||
name text [not null]
|
||||
appName text [not null, unique]
|
||||
description text
|
||||
databaseName text [not null]
|
||||
databaseUser text [not null]
|
||||
databasePassword text [not null]
|
||||
rootPassword text [not null]
|
||||
dockerImage text [not null]
|
||||
command text
|
||||
env text
|
||||
memoryReservation text
|
||||
memoryLimit text
|
||||
cpuReservation text
|
||||
cpuLimit text
|
||||
externalPort integer
|
||||
applicationStatus applicationStatus [not null, default: 'idle']
|
||||
createdAt text [not null]
|
||||
projectId text [not null]
|
||||
serverId text
|
||||
}
|
||||
|
||||
table notification {
|
||||
notificationId text [pk, not null]
|
||||
name text [not null]
|
||||
appDeploy boolean [not null, default: false]
|
||||
appBuildError boolean [not null, default: false]
|
||||
databaseBackup boolean [not null, default: false]
|
||||
dokployRestart boolean [not null, default: false]
|
||||
dockerCleanup boolean [not null, default: false]
|
||||
serverThreshold boolean [not null, default: false]
|
||||
notificationType notificationType [not null]
|
||||
createdAt text [not null]
|
||||
slackId text
|
||||
telegramId text
|
||||
discordId text
|
||||
emailId text
|
||||
gotifyId text
|
||||
userId text
|
||||
}
|
||||
|
||||
table organization {
|
||||
id text [pk, not null]
|
||||
name text [not null]
|
||||
slug text [unique]
|
||||
logo text
|
||||
created_at timestamp [not null]
|
||||
metadata text
|
||||
owner_id text [not null]
|
||||
}
|
||||
|
||||
table port {
|
||||
portId text [pk, not null]
|
||||
publishedPort integer [not null]
|
||||
targetPort integer [not null]
|
||||
protocol protocolType [not null]
|
||||
applicationId text [not null]
|
||||
}
|
||||
|
||||
table postgres {
|
||||
postgresId text [pk, not null]
|
||||
name text [not null]
|
||||
appName text [not null, unique]
|
||||
databaseName text [not null]
|
||||
databaseUser text [not null]
|
||||
databasePassword text [not null]
|
||||
description text
|
||||
dockerImage text [not null]
|
||||
command text
|
||||
env text
|
||||
memoryReservation text
|
||||
externalPort integer
|
||||
memoryLimit text
|
||||
cpuReservation text
|
||||
cpuLimit text
|
||||
applicationStatus applicationStatus [not null, default: 'idle']
|
||||
createdAt text [not null]
|
||||
projectId text [not null]
|
||||
serverId text
|
||||
}
|
||||
|
||||
table preview_deployments {
|
||||
previewDeploymentId text [pk, not null]
|
||||
branch text [not null]
|
||||
pullRequestId text [not null]
|
||||
pullRequestNumber text [not null]
|
||||
pullRequestURL text [not null]
|
||||
pullRequestTitle text [not null]
|
||||
pullRequestCommentId text [not null]
|
||||
previewStatus applicationStatus [not null, default: 'idle']
|
||||
appName text [not null, unique]
|
||||
applicationId text [not null]
|
||||
domainId text
|
||||
createdAt text [not null]
|
||||
expiresAt text
|
||||
}
|
||||
|
||||
table project {
|
||||
projectId text [pk, not null]
|
||||
name text [not null]
|
||||
description text
|
||||
createdAt text [not null]
|
||||
userId text [not null]
|
||||
env text [not null, default: '']
|
||||
}
|
||||
|
||||
table redirect {
|
||||
redirectId text [pk, not null]
|
||||
regex text [not null]
|
||||
replacement text [not null]
|
||||
permanent boolean [not null, default: false]
|
||||
uniqueConfigKey serial [not null, increment]
|
||||
createdAt text [not null]
|
||||
applicationId text [not null]
|
||||
}
|
||||
|
||||
table redis {
|
||||
redisId text [pk, not null]
|
||||
name text [not null]
|
||||
appName text [not null, unique]
|
||||
description text
|
||||
password text [not null]
|
||||
dockerImage text [not null]
|
||||
command text
|
||||
env text
|
||||
memoryReservation text
|
||||
memoryLimit text
|
||||
cpuReservation text
|
||||
cpuLimit text
|
||||
externalPort integer
|
||||
createdAt text [not null]
|
||||
applicationStatus applicationStatus [not null, default: 'idle']
|
||||
projectId text [not null]
|
||||
serverId text
|
||||
}
|
||||
|
||||
table registry {
|
||||
registryId text [pk, not null]
|
||||
registryName text [not null]
|
||||
imagePrefix text
|
||||
username text [not null]
|
||||
password text [not null]
|
||||
registryUrl text [not null, default: '']
|
||||
createdAt text [not null]
|
||||
selfHosted RegistryType [not null, default: 'cloud']
|
||||
userId text [not null]
|
||||
}
|
||||
|
||||
table security {
|
||||
securityId text [pk, not null]
|
||||
username text [not null]
|
||||
password text [not null]
|
||||
createdAt text [not null]
|
||||
applicationId text [not null]
|
||||
|
||||
indexes {
|
||||
(username, applicationId) [name: 'security_username_applicationId_unique', unique]
|
||||
}
|
||||
}
|
||||
|
||||
table server {
|
||||
serverId text [pk, not null]
|
||||
name text [not null]
|
||||
description text
|
||||
ipAddress text [not null]
|
||||
port integer [not null]
|
||||
username text [not null, default: 'root']
|
||||
appName text [not null]
|
||||
enableDockerCleanup boolean [not null, default: false]
|
||||
createdAt text [not null]
|
||||
userId text [not null]
|
||||
serverStatus serverStatus [not null, default: 'active']
|
||||
command text [not null, default: '']
|
||||
sshKeyId text
|
||||
metricsConfig jsonb [not null, default: `{"server":{"type":"Remote","refreshRate":60,"port":4500,"token":"","urlCallback":"","cronJob":"","retentionDays":2,"thresholds":{"cpu":0,"memory":0}},"containers":{"refreshRate":60,"services":{"include":[],"exclude":[]}}}`]
|
||||
}
|
||||
|
||||
table session {
|
||||
id text [pk, not null]
|
||||
expires_at timestamp [not null]
|
||||
token text [not null, unique]
|
||||
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
|
||||
}
|
||||
|
||||
table slack {
|
||||
slackId text [pk, not null]
|
||||
webhookUrl text [not null]
|
||||
channel text
|
||||
}
|
||||
|
||||
table "ssh-key" {
|
||||
sshKeyId text [pk, not null]
|
||||
privateKey text [not null, default: '']
|
||||
publicKey text [not null]
|
||||
name text [not null]
|
||||
description text
|
||||
createdAt text [not null]
|
||||
lastUsedAt text
|
||||
userId text
|
||||
}
|
||||
|
||||
table telegram {
|
||||
telegramId text [pk, not null]
|
||||
botToken text [not null]
|
||||
chatId text [not null]
|
||||
}
|
||||
|
||||
table user {
|
||||
id text [pk, not null]
|
||||
name text [not null, default: '']
|
||||
token text [not null]
|
||||
isRegistered boolean [not null, default: false]
|
||||
expirationDate text [not null]
|
||||
createdAt text [not null]
|
||||
canCreateProjects boolean [not null, default: false]
|
||||
canAccessToSSHKeys boolean [not null, default: false]
|
||||
canCreateServices boolean [not null, default: false]
|
||||
canDeleteProjects boolean [not null, default: false]
|
||||
canDeleteServices boolean [not null, default: false]
|
||||
canAccessToDocker boolean [not null, default: false]
|
||||
canAccessToAPI boolean [not null, default: false]
|
||||
canAccessToGitProviders boolean [not null, default: false]
|
||||
canAccessToTraefikFiles boolean [not null, default: false]
|
||||
accesedProjects text[] [not null, default: `ARRAY[]::text[]`]
|
||||
accesedServices text[] [not null, default: `ARRAY[]::text[]`]
|
||||
email text [not null, unique]
|
||||
email_verified boolean [not null]
|
||||
image text
|
||||
role text
|
||||
banned boolean
|
||||
ban_reason text
|
||||
ban_expires timestamp
|
||||
updated_at timestamp [not null]
|
||||
serverIp text
|
||||
certificateType certificateType [not null, default: 'none']
|
||||
host text
|
||||
letsEncryptEmail text
|
||||
sshPrivateKey text
|
||||
enableDockerCleanup boolean [not null, default: false]
|
||||
enableLogRotation boolean [not null, default: false]
|
||||
enablePaidFeatures boolean [not null, default: false]
|
||||
metricsConfig jsonb [not null, default: `{"server":{"type":"Dokploy","refreshRate":60,"port":4500,"token":"","retentionDays":2,"cronJob":"","urlCallback":"","thresholds":{"cpu":0,"memory":0}},"containers":{"refreshRate":60,"services":{"include":[],"exclude":[]}}}`]
|
||||
cleanupCacheApplications boolean [not null, default: false]
|
||||
cleanupCacheOnPreviews boolean [not null, default: false]
|
||||
cleanupCacheOnCompose boolean [not null, default: false]
|
||||
stripeCustomerId text
|
||||
stripeSubscriptionId text
|
||||
serversQuantity integer [not null, default: 0]
|
||||
}
|
||||
|
||||
table verification {
|
||||
id text [pk, not null]
|
||||
identifier text [not null]
|
||||
value text [not null]
|
||||
expires_at timestamp [not null]
|
||||
created_at timestamp
|
||||
updated_at timestamp
|
||||
}
|
||||
|
||||
ref: mount.applicationId > application.applicationId
|
||||
|
||||
ref: mount.postgresId > postgres.postgresId
|
||||
|
||||
ref: mount.mariadbId > mariadb.mariadbId
|
||||
|
||||
ref: mount.mongoId > mongo.mongoId
|
||||
|
||||
ref: mount.mysqlId > mysql.mysqlId
|
||||
|
||||
ref: mount.redisId > redis.redisId
|
||||
|
||||
ref: mount.composeId > compose.composeId
|
||||
|
||||
ref: application.projectId > project.projectId
|
||||
|
||||
ref: application.customGitSSHKeyId > "ssh-key".sshKeyId
|
||||
|
||||
ref: application.registryId > registry.registryId
|
||||
|
||||
ref: application.githubId - github.githubId
|
||||
|
||||
ref: application.gitlabId - gitlab.gitlabId
|
||||
|
||||
ref: application.bitbucketId - bitbucket.bitbucketId
|
||||
|
||||
ref: application.serverId > server.serverId
|
||||
|
||||
ref: backup.destinationId > destination.destinationId
|
||||
|
||||
ref: backup.postgresId > postgres.postgresId
|
||||
|
||||
ref: backup.mariadbId > mariadb.mariadbId
|
||||
|
||||
ref: backup.mysqlId > mysql.mysqlId
|
||||
|
||||
ref: backup.mongoId > mongo.mongoId
|
||||
|
||||
ref: git_provider.gitProviderId - bitbucket.gitProviderId
|
||||
|
||||
ref: certificate.serverId > server.serverId
|
||||
|
||||
ref: certificate.userId - user.id
|
||||
|
||||
ref: compose.projectId > project.projectId
|
||||
|
||||
ref: compose.customGitSSHKeyId > "ssh-key".sshKeyId
|
||||
|
||||
ref: compose.githubId - github.githubId
|
||||
|
||||
ref: compose.gitlabId - gitlab.gitlabId
|
||||
|
||||
ref: compose.bitbucketId - bitbucket.bitbucketId
|
||||
|
||||
ref: compose.serverId > server.serverId
|
||||
|
||||
ref: deployment.applicationId > application.applicationId
|
||||
|
||||
ref: deployment.composeId > compose.composeId
|
||||
|
||||
ref: deployment.serverId > server.serverId
|
||||
|
||||
ref: deployment.previewDeploymentId > preview_deployments.previewDeploymentId
|
||||
|
||||
ref: destination.userId - user.id
|
||||
|
||||
ref: domain.applicationId > application.applicationId
|
||||
|
||||
ref: domain.composeId > compose.composeId
|
||||
|
||||
ref: preview_deployments.domainId - domain.domainId
|
||||
|
||||
ref: github.gitProviderId - git_provider.gitProviderId
|
||||
|
||||
ref: gitlab.gitProviderId - git_provider.gitProviderId
|
||||
|
||||
ref: git_provider.userId - user.id
|
||||
|
||||
ref: mariadb.projectId > project.projectId
|
||||
|
||||
ref: mariadb.serverId > server.serverId
|
||||
|
||||
ref: mongo.projectId > project.projectId
|
||||
|
||||
ref: mongo.serverId > server.serverId
|
||||
|
||||
ref: mysql.projectId > project.projectId
|
||||
|
||||
ref: mysql.serverId > server.serverId
|
||||
|
||||
ref: notification.slackId - slack.slackId
|
||||
|
||||
ref: notification.telegramId - telegram.telegramId
|
||||
|
||||
ref: notification.discordId - discord.discordId
|
||||
|
||||
ref: notification.emailId - email.emailId
|
||||
|
||||
ref: notification.gotifyId - gotify.gotifyId
|
||||
|
||||
ref: notification.userId - user.id
|
||||
|
||||
ref: port.applicationId > application.applicationId
|
||||
|
||||
ref: postgres.projectId > project.projectId
|
||||
|
||||
ref: postgres.serverId > server.serverId
|
||||
|
||||
ref: preview_deployments.applicationId > application.applicationId
|
||||
|
||||
ref: project.userId - user.id
|
||||
|
||||
ref: redirect.applicationId > application.applicationId
|
||||
|
||||
ref: redis.projectId > project.projectId
|
||||
|
||||
ref: redis.serverId > server.serverId
|
||||
|
||||
ref: registry.userId - user.id
|
||||
|
||||
ref: security.applicationId > application.applicationId
|
||||
|
||||
ref: server.userId - user.id
|
||||
|
||||
ref: server.sshKeyId > "ssh-key".sshKeyId
|
||||
|
||||
ref: "ssh-key".userId - user.id
|
||||
@@ -22,6 +22,8 @@ import { mysql } from "./mysql";
|
||||
import { postgres } from "./postgres";
|
||||
import { redis } from "./redis";
|
||||
import { sshKeys } from "./ssh-key";
|
||||
import { users_temp } from "./user";
|
||||
// import { user } from "./user";
|
||||
import { generateAppName } from "./utils";
|
||||
|
||||
export const serverStatus = pgEnum("serverStatus", ["active", "inactive"]);
|
||||
@@ -40,12 +42,14 @@ export const server = pgTable("server", {
|
||||
.notNull()
|
||||
.$defaultFn(() => generateAppName("server")),
|
||||
enableDockerCleanup: boolean("enableDockerCleanup").notNull().default(false),
|
||||
createdAt: text("createdAt")
|
||||
createdAt: text("createdAt").notNull(),
|
||||
// .$defaultFn(() => new Date().toISOString()),
|
||||
// userId: text("userId")
|
||||
// .notNull()
|
||||
// .references(() => user.userId, { onDelete: "cascade" }),
|
||||
userId: text("userId")
|
||||
.notNull()
|
||||
.$defaultFn(() => new Date().toISOString()),
|
||||
adminId: text("adminId")
|
||||
.notNull()
|
||||
.references(() => admins.adminId, { onDelete: "cascade" }),
|
||||
.references(() => users_temp.id, { onDelete: "cascade" }),
|
||||
serverStatus: serverStatus("serverStatus").notNull().default("active"),
|
||||
command: text("command").notNull().default(""),
|
||||
sshKeyId: text("sshKeyId").references(() => sshKeys.sshKeyId, {
|
||||
@@ -100,10 +104,10 @@ export const server = pgTable("server", {
|
||||
});
|
||||
|
||||
export const serverRelations = relations(server, ({ one, many }) => ({
|
||||
admin: one(admins, {
|
||||
fields: [server.adminId],
|
||||
references: [admins.adminId],
|
||||
}),
|
||||
// user: one(user, {
|
||||
// fields: [server.userId],
|
||||
// references: [user.id],
|
||||
// }),
|
||||
deployments: many(deployments),
|
||||
sshKey: one(sshKeys, {
|
||||
fields: [server.sshKeyId],
|
||||
|
||||
@@ -1,5 +1,23 @@
|
||||
import { sql } from "drizzle-orm";
|
||||
import { pgTable, text, timestamp } from "drizzle-orm/pg-core";
|
||||
import { auth } from "./auth";
|
||||
import { users_temp } from "./user";
|
||||
|
||||
// OLD TABLE
|
||||
export const session = pgTable("session_temp", {
|
||||
id: text("id").primaryKey(),
|
||||
expiresAt: timestamp("expires_at").notNull(),
|
||||
token: text("token").notNull().unique(),
|
||||
createdAt: timestamp("created_at").notNull(),
|
||||
updatedAt: timestamp("updated_at").notNull(),
|
||||
ipAddress: text("ip_address"),
|
||||
userAgent: text("user_agent"),
|
||||
userId: text("user_id")
|
||||
.notNull()
|
||||
.references(() => users_temp.id),
|
||||
impersonatedBy: text("impersonated_by"),
|
||||
activeOrganizationId: text("active_organization_id"),
|
||||
});
|
||||
|
||||
export const sessionTable = pgTable("session", {
|
||||
id: text("id").primaryKey(),
|
||||
|
||||
@@ -7,6 +7,8 @@ import { admins } from "./admin";
|
||||
import { applications } from "./application";
|
||||
import { compose } from "./compose";
|
||||
import { server } from "./server";
|
||||
import { users_temp } from "./user";
|
||||
// import { user } from "./user";
|
||||
|
||||
export const sshKeys = pgTable("ssh-key", {
|
||||
sshKeyId: text("sshKeyId")
|
||||
@@ -21,18 +23,21 @@ export const sshKeys = pgTable("ssh-key", {
|
||||
.notNull()
|
||||
.$defaultFn(() => new Date().toISOString()),
|
||||
lastUsedAt: text("lastUsedAt"),
|
||||
adminId: text("adminId").references(() => admins.adminId, {
|
||||
onDelete: "cascade",
|
||||
}),
|
||||
// userId: text("userId").references(() => user.userId, {
|
||||
// onDelete: "cascade",
|
||||
// }),
|
||||
userId: text("userId")
|
||||
.notNull()
|
||||
.references(() => users_temp.id, { onDelete: "cascade" }),
|
||||
});
|
||||
|
||||
export const sshKeysRelations = relations(sshKeys, ({ many, one }) => ({
|
||||
applications: many(applications),
|
||||
compose: many(compose),
|
||||
servers: many(server),
|
||||
admin: one(admins, {
|
||||
fields: [sshKeys.adminId],
|
||||
references: [admins.adminId],
|
||||
user: one(users_temp, {
|
||||
fields: [sshKeys.userId],
|
||||
references: [users_temp.id],
|
||||
}),
|
||||
}));
|
||||
|
||||
@@ -48,7 +53,7 @@ export const apiCreateSshKey = createSchema
|
||||
description: true,
|
||||
privateKey: true,
|
||||
publicKey: true,
|
||||
adminId: true,
|
||||
userId: true,
|
||||
})
|
||||
.merge(sshKeyCreate.pick({ privateKey: true }));
|
||||
|
||||
|
||||
@@ -1,10 +1,19 @@
|
||||
import { relations, sql } from "drizzle-orm";
|
||||
import { boolean, pgTable, text, timestamp } from "drizzle-orm/pg-core";
|
||||
import {
|
||||
boolean,
|
||||
integer,
|
||||
jsonb,
|
||||
pgTable,
|
||||
text,
|
||||
timestamp,
|
||||
} from "drizzle-orm/pg-core";
|
||||
import { createInsertSchema } from "drizzle-zod";
|
||||
import { nanoid } from "nanoid";
|
||||
import { z } from "zod";
|
||||
import { account, organization } from "./account";
|
||||
import { admins } from "./admin";
|
||||
import { auth } from "./auth";
|
||||
import { certificateType } from "./shared";
|
||||
/**
|
||||
* This is an example of how to use the multi-project schema feature of Drizzle ORM. Use the same
|
||||
* database instance for multiple projects.
|
||||
@@ -12,6 +21,8 @@ import { auth } from "./auth";
|
||||
* @see https://orm.drizzle.team/docs/goodies#multi-project-schema
|
||||
*/
|
||||
|
||||
// OLD TABLE
|
||||
|
||||
export const users = pgTable("user", {
|
||||
userId: text("userId")
|
||||
.notNull()
|
||||
@@ -56,23 +67,146 @@ export const users = pgTable("user", {
|
||||
.references(() => auth.id, { onDelete: "cascade" }),
|
||||
});
|
||||
|
||||
export const usersRelations = relations(users, ({ one }) => ({
|
||||
auth: one(auth, {
|
||||
fields: [users.authId],
|
||||
references: [auth.id],
|
||||
}),
|
||||
admin: one(admins, {
|
||||
fields: [users.adminId],
|
||||
references: [admins.adminId],
|
||||
// TEMP
|
||||
export const users_temp = pgTable("user_temp", {
|
||||
id: text("id")
|
||||
.notNull()
|
||||
.primaryKey()
|
||||
.$defaultFn(() => nanoid()),
|
||||
name: text("name").notNull().default(""),
|
||||
token: text("token").notNull().default(""),
|
||||
isRegistered: boolean("isRegistered").notNull().default(false),
|
||||
expirationDate: text("expirationDate")
|
||||
.notNull()
|
||||
.$defaultFn(() => new Date().toISOString()),
|
||||
createdAt2: text("createdAt")
|
||||
.notNull()
|
||||
.$defaultFn(() => new Date().toISOString()),
|
||||
createdAt: timestamp("created_at").defaultNow(),
|
||||
canCreateProjects: boolean("canCreateProjects").notNull().default(false),
|
||||
canAccessToSSHKeys: boolean("canAccessToSSHKeys").notNull().default(false),
|
||||
canCreateServices: boolean("canCreateServices").notNull().default(false),
|
||||
canDeleteProjects: boolean("canDeleteProjects").notNull().default(false),
|
||||
canDeleteServices: boolean("canDeleteServices").notNull().default(false),
|
||||
canAccessToDocker: boolean("canAccessToDocker").notNull().default(false),
|
||||
canAccessToAPI: boolean("canAccessToAPI").notNull().default(false),
|
||||
canAccessToGitProviders: boolean("canAccessToGitProviders")
|
||||
.notNull()
|
||||
.default(false),
|
||||
canAccessToTraefikFiles: boolean("canAccessToTraefikFiles")
|
||||
.notNull()
|
||||
.default(false),
|
||||
accessedProjects: text("accesedProjects")
|
||||
.array()
|
||||
.notNull()
|
||||
.default(sql`ARRAY[]::text[]`),
|
||||
accessedServices: text("accesedServices")
|
||||
.array()
|
||||
.notNull()
|
||||
.default(sql`ARRAY[]::text[]`),
|
||||
// authId: text("authId")
|
||||
// .notNull()
|
||||
// .references(() => auth.id, { onDelete: "cascade" }),
|
||||
// Auth
|
||||
email: text("email").notNull().unique(),
|
||||
emailVerified: boolean("email_verified").notNull(),
|
||||
image: text("image"),
|
||||
banned: boolean("banned"),
|
||||
banReason: text("ban_reason"),
|
||||
banExpires: timestamp("ban_expires"),
|
||||
updatedAt: timestamp("updated_at").notNull(),
|
||||
// Admin
|
||||
serverIp: text("serverIp"),
|
||||
certificateType: certificateType("certificateType").notNull().default("none"),
|
||||
host: text("host"),
|
||||
letsEncryptEmail: text("letsEncryptEmail"),
|
||||
sshPrivateKey: text("sshPrivateKey"),
|
||||
enableDockerCleanup: boolean("enableDockerCleanup").notNull().default(false),
|
||||
enableLogRotation: boolean("enableLogRotation").notNull().default(false),
|
||||
// Metrics
|
||||
enablePaidFeatures: boolean("enablePaidFeatures").notNull().default(false),
|
||||
metricsConfig: jsonb("metricsConfig")
|
||||
.$type<{
|
||||
server: {
|
||||
type: "Dokploy" | "Remote";
|
||||
refreshRate: number;
|
||||
port: number;
|
||||
token: string;
|
||||
urlCallback: string;
|
||||
retentionDays: number;
|
||||
cronJob: string;
|
||||
thresholds: {
|
||||
cpu: number;
|
||||
memory: number;
|
||||
};
|
||||
};
|
||||
containers: {
|
||||
refreshRate: number;
|
||||
services: {
|
||||
include: string[];
|
||||
exclude: string[];
|
||||
};
|
||||
};
|
||||
}>()
|
||||
.notNull()
|
||||
.default({
|
||||
server: {
|
||||
type: "Dokploy",
|
||||
refreshRate: 60,
|
||||
port: 4500,
|
||||
token: "",
|
||||
retentionDays: 2,
|
||||
cronJob: "",
|
||||
urlCallback: "",
|
||||
thresholds: {
|
||||
cpu: 0,
|
||||
memory: 0,
|
||||
},
|
||||
},
|
||||
containers: {
|
||||
refreshRate: 60,
|
||||
services: {
|
||||
include: [],
|
||||
exclude: [],
|
||||
},
|
||||
},
|
||||
}),
|
||||
cleanupCacheApplications: boolean("cleanupCacheApplications")
|
||||
.notNull()
|
||||
.default(false),
|
||||
cleanupCacheOnPreviews: boolean("cleanupCacheOnPreviews")
|
||||
.notNull()
|
||||
.default(false),
|
||||
cleanupCacheOnCompose: boolean("cleanupCacheOnCompose")
|
||||
.notNull()
|
||||
.default(false),
|
||||
stripeCustomerId: text("stripeCustomerId"),
|
||||
stripeSubscriptionId: text("stripeSubscriptionId"),
|
||||
serversQuantity: integer("serversQuantity").notNull().default(0),
|
||||
});
|
||||
|
||||
export const usersRelations = relations(users_temp, ({ one, many }) => ({
|
||||
// auth: one(auth, {
|
||||
// fields: [users.authId],
|
||||
// references: [auth.id],
|
||||
// }),
|
||||
account: one(account, {
|
||||
fields: [users_temp.id],
|
||||
references: [account.userId],
|
||||
}),
|
||||
organizations: many(organization),
|
||||
// admin: one(admins, {
|
||||
// fields: [users.adminId],
|
||||
// references: [admins.adminId],
|
||||
// }),
|
||||
}));
|
||||
|
||||
const createSchema = createInsertSchema(users, {
|
||||
userId: z.string().min(1),
|
||||
authId: z.string().min(1),
|
||||
const createSchema = createInsertSchema(users_temp, {
|
||||
id: z.string().min(1),
|
||||
// authId: z.string().min(1),
|
||||
token: z.string().min(1),
|
||||
isRegistered: z.boolean().optional(),
|
||||
adminId: z.string(),
|
||||
// adminId: z.string(),
|
||||
accessedProjects: z.array(z.string()).optional(),
|
||||
accessedServices: z.array(z.string()).optional(),
|
||||
canCreateProjects: z.boolean().optional(),
|
||||
@@ -89,7 +223,7 @@ export const apiCreateUserInvitation = createSchema.pick({}).extend({
|
||||
|
||||
export const apiRemoveUser = createSchema
|
||||
.pick({
|
||||
authId: true,
|
||||
id: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
@@ -101,7 +235,7 @@ export const apiFindOneToken = createSchema
|
||||
|
||||
export const apiAssignPermissions = createSchema
|
||||
.pick({
|
||||
userId: true,
|
||||
id: true,
|
||||
canCreateProjects: true,
|
||||
canCreateServices: true,
|
||||
canDeleteProjects: true,
|
||||
@@ -118,12 +252,12 @@ export const apiAssignPermissions = createSchema
|
||||
|
||||
export const apiFindOneUser = createSchema
|
||||
.pick({
|
||||
userId: true,
|
||||
id: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiFindOneUserByAuth = createSchema
|
||||
.pick({
|
||||
authId: true,
|
||||
// authId: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
@@ -118,3 +118,5 @@ export * from "./monitoring/utils";
|
||||
export * from "./db/validations/domain";
|
||||
export * from "./db/validations/index";
|
||||
export * from "./utils/gpu-setup";
|
||||
|
||||
export * from "./lib/auth";
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user