mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
refactor: remove old references
This commit is contained in:
@@ -45,7 +45,7 @@ const baseApp: ApplicationNested = {
|
|||||||
previewWildcard: "",
|
previewWildcard: "",
|
||||||
project: {
|
project: {
|
||||||
env: "",
|
env: "",
|
||||||
adminId: "",
|
organizationId: "",
|
||||||
name: "",
|
name: "",
|
||||||
description: "",
|
description: "",
|
||||||
createdAt: "",
|
createdAt: "",
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ vi.mock("node:fs", () => ({
|
|||||||
default: fs,
|
default: fs,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
import type { Admin, FileConfig } from "@dokploy/server";
|
import type { Admin, FileConfig, User } from "@dokploy/server";
|
||||||
import {
|
import {
|
||||||
createDefaultServerTraefikConfig,
|
createDefaultServerTraefikConfig,
|
||||||
loadOrCreateConfig,
|
loadOrCreateConfig,
|
||||||
@@ -13,7 +13,7 @@ import {
|
|||||||
} from "@dokploy/server";
|
} from "@dokploy/server";
|
||||||
import { beforeEach, expect, test, vi } from "vitest";
|
import { beforeEach, expect, test, vi } from "vitest";
|
||||||
|
|
||||||
const baseAdmin: Admin = {
|
const baseAdmin: Partial<User> = {
|
||||||
enablePaidFeatures: false,
|
enablePaidFeatures: false,
|
||||||
metricsConfig: {
|
metricsConfig: {
|
||||||
containers: {
|
containers: {
|
||||||
@@ -40,9 +40,7 @@ const baseAdmin: Admin = {
|
|||||||
cleanupCacheApplications: false,
|
cleanupCacheApplications: false,
|
||||||
cleanupCacheOnCompose: false,
|
cleanupCacheOnCompose: false,
|
||||||
cleanupCacheOnPreviews: false,
|
cleanupCacheOnPreviews: false,
|
||||||
createdAt: "",
|
createdAt: new Date(),
|
||||||
authId: "",
|
|
||||||
adminId: "string",
|
|
||||||
serverIp: null,
|
serverIp: null,
|
||||||
certificateType: "none",
|
certificateType: "none",
|
||||||
host: null,
|
host: null,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { buffer } from "node:stream/consumers";
|
import { buffer } from "node:stream/consumers";
|
||||||
import { db } from "@/server/db";
|
import { db } from "@/server/db";
|
||||||
import { admins, server, users_temp } from "@/server/db/schema";
|
import { server, users_temp } from "@/server/db/schema";
|
||||||
import { findAdminById, findUserById } from "@dokploy/server";
|
import { findAdminById, findUserById } from "@dokploy/server";
|
||||||
import { asc, eq } from "drizzle-orm";
|
import { asc, eq } from "drizzle-orm";
|
||||||
import type { NextApiRequest, NextApiResponse } from "next";
|
import type { NextApiRequest, NextApiResponse } from "next";
|
||||||
|
|||||||
@@ -201,14 +201,7 @@ const Project = (
|
|||||||
const [isBulkActionLoading, setIsBulkActionLoading] = useState(false);
|
const [isBulkActionLoading, setIsBulkActionLoading] = useState(false);
|
||||||
const { projectId } = props;
|
const { projectId } = props;
|
||||||
const { data: auth } = api.auth.get.useQuery();
|
const { data: auth } = api.auth.get.useQuery();
|
||||||
const { data: user } = api.user.byAuthId.useQuery(
|
|
||||||
{
|
|
||||||
authId: auth?.id || "",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
enabled: !!auth?.id && auth?.role === "member",
|
|
||||||
},
|
|
||||||
);
|
|
||||||
const { data, isLoading, refetch } = api.project.one.useQuery({ projectId });
|
const { data, isLoading, refetch } = api.project.one.useQuery({ projectId });
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
@@ -335,7 +328,7 @@ const Project = (
|
|||||||
</CardTitle>
|
</CardTitle>
|
||||||
<CardDescription>{data?.description}</CardDescription>
|
<CardDescription>{data?.description}</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
{(auth?.role === "owner" || user?.canCreateServices) && (
|
{(auth?.role === "owner" || auth?.user?.canCreateServices) && (
|
||||||
<div className="flex flex-row gap-4 flex-wrap">
|
<div className="flex flex-row gap-4 flex-wrap">
|
||||||
<ProjectEnvironment projectId={projectId}>
|
<ProjectEnvironment projectId={projectId}>
|
||||||
<Button variant="outline">Project Environment</Button>
|
<Button variant="outline">Project Environment</Button>
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ import { cn } from "@/lib/utils";
|
|||||||
import { appRouter } from "@/server/api/root";
|
import { appRouter } from "@/server/api/root";
|
||||||
import { api } from "@/utils/api";
|
import { api } from "@/utils/api";
|
||||||
import { validateRequest } from "@dokploy/server/lib/auth";
|
import { validateRequest } from "@dokploy/server/lib/auth";
|
||||||
// import { validateRequest } from "@dokploy/server";
|
|
||||||
import { createServerSideHelpers } from "@trpc/react-query/server";
|
import { createServerSideHelpers } from "@trpc/react-query/server";
|
||||||
import copy from "copy-to-clipboard";
|
import copy from "copy-to-clipboard";
|
||||||
import { GlobeIcon, HelpCircle, ServerOff, Trash2 } from "lucide-react";
|
import { GlobeIcon, HelpCircle, ServerOff, Trash2 } from "lucide-react";
|
||||||
@@ -89,14 +88,6 @@ const Service = (
|
|||||||
const { data: isCloud } = api.settings.isCloud.useQuery();
|
const { data: isCloud } = api.settings.isCloud.useQuery();
|
||||||
const { data: auth } = api.auth.get.useQuery();
|
const { data: auth } = api.auth.get.useQuery();
|
||||||
const { data: monitoring } = api.admin.getMetricsToken.useQuery();
|
const { data: monitoring } = api.admin.getMetricsToken.useQuery();
|
||||||
const { data: user } = api.user.byAuthId.useQuery(
|
|
||||||
{
|
|
||||||
authId: auth?.id || "",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
enabled: !!auth?.id && auth?.role === "member",
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="pb-10">
|
<div className="pb-10">
|
||||||
@@ -187,7 +178,8 @@ const Service = (
|
|||||||
|
|
||||||
<div className="flex flex-row gap-2 justify-end">
|
<div className="flex flex-row gap-2 justify-end">
|
||||||
<UpdateApplication applicationId={applicationId} />
|
<UpdateApplication applicationId={applicationId} />
|
||||||
{(auth?.role === "owner" || user?.canDeleteServices) && (
|
{(auth?.role === "owner" ||
|
||||||
|
auth?.user?.canDeleteServices) && (
|
||||||
<DeleteService id={applicationId} type="application" />
|
<DeleteService id={applicationId} type="application" />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -387,8 +379,8 @@ export async function getServerSideProps(
|
|||||||
req: req as any,
|
req: req as any,
|
||||||
res: res as any,
|
res: res as any,
|
||||||
db: null as any,
|
db: null as any,
|
||||||
session: session,
|
session: session as any,
|
||||||
user: user,
|
user: user as any,
|
||||||
},
|
},
|
||||||
transformer: superjson,
|
transformer: superjson,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -82,14 +82,6 @@ const Service = (
|
|||||||
const { data: auth } = api.auth.get.useQuery();
|
const { data: auth } = api.auth.get.useQuery();
|
||||||
const { data: monitoring } = api.admin.getMetricsToken.useQuery();
|
const { data: monitoring } = api.admin.getMetricsToken.useQuery();
|
||||||
const { data: isCloud } = api.settings.isCloud.useQuery();
|
const { data: isCloud } = api.settings.isCloud.useQuery();
|
||||||
const { data: user } = api.user.byAuthId.useQuery(
|
|
||||||
{
|
|
||||||
authId: auth?.id || "",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
enabled: !!auth?.id && auth?.role === "member",
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="pb-10">
|
<div className="pb-10">
|
||||||
@@ -181,7 +173,8 @@ const Service = (
|
|||||||
<div className="flex flex-row gap-2 justify-end">
|
<div className="flex flex-row gap-2 justify-end">
|
||||||
<UpdateCompose composeId={composeId} />
|
<UpdateCompose composeId={composeId} />
|
||||||
|
|
||||||
{(auth?.role === "owner" || user?.canDeleteServices) && (
|
{(auth?.role === "owner" ||
|
||||||
|
auth?.user?.canDeleteServices) && (
|
||||||
<DeleteService id={composeId} type="compose" />
|
<DeleteService id={composeId} type="compose" />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -382,8 +375,8 @@ export async function getServerSideProps(
|
|||||||
req: req as any,
|
req: req as any,
|
||||||
res: res as any,
|
res: res as any,
|
||||||
db: null as any,
|
db: null as any,
|
||||||
session: session,
|
session: session as any,
|
||||||
user: user,
|
user: user as any,
|
||||||
},
|
},
|
||||||
transformer: superjson,
|
transformer: superjson,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -63,14 +63,7 @@ const Mariadb = (
|
|||||||
const { data } = api.mariadb.one.useQuery({ mariadbId });
|
const { data } = api.mariadb.one.useQuery({ mariadbId });
|
||||||
const { data: auth } = api.auth.get.useQuery();
|
const { data: auth } = api.auth.get.useQuery();
|
||||||
const { data: monitoring } = api.admin.getMetricsToken.useQuery();
|
const { data: monitoring } = api.admin.getMetricsToken.useQuery();
|
||||||
const { data: user } = api.user.byAuthId.useQuery(
|
|
||||||
{
|
|
||||||
authId: auth?.id || "",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
enabled: !!auth?.id && auth?.role === "member",
|
|
||||||
},
|
|
||||||
);
|
|
||||||
const { data: isCloud } = api.settings.isCloud.useQuery();
|
const { data: isCloud } = api.settings.isCloud.useQuery();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -154,7 +147,8 @@ const Mariadb = (
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex flex-row gap-2 justify-end">
|
<div className="flex flex-row gap-2 justify-end">
|
||||||
<UpdateMariadb mariadbId={mariadbId} />
|
<UpdateMariadb mariadbId={mariadbId} />
|
||||||
{(auth?.role === "owner" || user?.canDeleteServices) && (
|
{(auth?.role === "owner" ||
|
||||||
|
auth?.user?.canDeleteServices) && (
|
||||||
<DeleteService id={mariadbId} type="mariadb" />
|
<DeleteService id={mariadbId} type="mariadb" />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -332,8 +326,8 @@ export async function getServerSideProps(
|
|||||||
req: req as any,
|
req: req as any,
|
||||||
res: res as any,
|
res: res as any,
|
||||||
db: null as any,
|
db: null as any,
|
||||||
session: session,
|
session: session as any,
|
||||||
user: user,
|
user: user as any,
|
||||||
},
|
},
|
||||||
transformer: superjson,
|
transformer: superjson,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -63,14 +63,6 @@ const Mongo = (
|
|||||||
|
|
||||||
const { data: auth } = api.auth.get.useQuery();
|
const { data: auth } = api.auth.get.useQuery();
|
||||||
const { data: monitoring } = api.admin.getMetricsToken.useQuery();
|
const { data: monitoring } = api.admin.getMetricsToken.useQuery();
|
||||||
const { data: user } = api.user.byAuthId.useQuery(
|
|
||||||
{
|
|
||||||
authId: auth?.id || "",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
enabled: !!auth?.id && auth?.role === "member",
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
const { data: isCloud } = api.settings.isCloud.useQuery();
|
const { data: isCloud } = api.settings.isCloud.useQuery();
|
||||||
|
|
||||||
@@ -156,7 +148,8 @@ const Mongo = (
|
|||||||
|
|
||||||
<div className="flex flex-row gap-2 justify-end">
|
<div className="flex flex-row gap-2 justify-end">
|
||||||
<UpdateMongo mongoId={mongoId} />
|
<UpdateMongo mongoId={mongoId} />
|
||||||
{(auth?.role === "owner" || user?.canDeleteServices) && (
|
{(auth?.role === "owner" ||
|
||||||
|
auth?.user?.canDeleteServices) && (
|
||||||
<DeleteService id={mongoId} type="mongo" />
|
<DeleteService id={mongoId} type="mongo" />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -334,8 +327,8 @@ export async function getServerSideProps(
|
|||||||
req: req as any,
|
req: req as any,
|
||||||
res: res as any,
|
res: res as any,
|
||||||
db: null as any,
|
db: null as any,
|
||||||
session: session,
|
session: session as any,
|
||||||
user: user,
|
user: user as any,
|
||||||
},
|
},
|
||||||
transformer: superjson,
|
transformer: superjson,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -62,14 +62,6 @@ const MySql = (
|
|||||||
const { data } = api.mysql.one.useQuery({ mysqlId });
|
const { data } = api.mysql.one.useQuery({ mysqlId });
|
||||||
const { data: auth } = api.auth.get.useQuery();
|
const { data: auth } = api.auth.get.useQuery();
|
||||||
const { data: monitoring } = api.admin.getMetricsToken.useQuery();
|
const { data: monitoring } = api.admin.getMetricsToken.useQuery();
|
||||||
const { data: user } = api.user.byAuthId.useQuery(
|
|
||||||
{
|
|
||||||
authId: auth?.id || "",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
enabled: !!auth?.id && auth?.role === "member",
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
const { data: isCloud } = api.settings.isCloud.useQuery();
|
const { data: isCloud } = api.settings.isCloud.useQuery();
|
||||||
|
|
||||||
@@ -156,7 +148,8 @@ const MySql = (
|
|||||||
|
|
||||||
<div className="flex flex-row gap-2 justify-end">
|
<div className="flex flex-row gap-2 justify-end">
|
||||||
<UpdateMysql mysqlId={mysqlId} />
|
<UpdateMysql mysqlId={mysqlId} />
|
||||||
{(auth?.role === "owner" || user?.canDeleteServices) && (
|
{(auth?.role === "owner" ||
|
||||||
|
auth?.user?.canDeleteServices) && (
|
||||||
<DeleteService id={mysqlId} type="mysql" />
|
<DeleteService id={mysqlId} type="mysql" />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -339,8 +332,8 @@ export async function getServerSideProps(
|
|||||||
req: req as any,
|
req: req as any,
|
||||||
res: res as any,
|
res: res as any,
|
||||||
db: null as any,
|
db: null as any,
|
||||||
session: session,
|
session: session as any,
|
||||||
user: user,
|
user: user as any,
|
||||||
},
|
},
|
||||||
transformer: superjson,
|
transformer: superjson,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -61,14 +61,7 @@ const Postgresql = (
|
|||||||
const [tab, setSab] = useState<TabState>(activeTab);
|
const [tab, setSab] = useState<TabState>(activeTab);
|
||||||
const { data } = api.postgres.one.useQuery({ postgresId });
|
const { data } = api.postgres.one.useQuery({ postgresId });
|
||||||
const { data: auth } = api.auth.get.useQuery();
|
const { data: auth } = api.auth.get.useQuery();
|
||||||
const { data: user } = api.user.byAuthId.useQuery(
|
|
||||||
{
|
|
||||||
authId: auth?.id || "",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
enabled: !!auth?.id && auth?.role === "member",
|
|
||||||
},
|
|
||||||
);
|
|
||||||
const { data: monitoring } = api.admin.getMetricsToken.useQuery();
|
const { data: monitoring } = api.admin.getMetricsToken.useQuery();
|
||||||
const { data: isCloud } = api.settings.isCloud.useQuery();
|
const { data: isCloud } = api.settings.isCloud.useQuery();
|
||||||
|
|
||||||
@@ -154,7 +147,8 @@ const Postgresql = (
|
|||||||
|
|
||||||
<div className="flex flex-row gap-2 justify-end">
|
<div className="flex flex-row gap-2 justify-end">
|
||||||
<UpdatePostgres postgresId={postgresId} />
|
<UpdatePostgres postgresId={postgresId} />
|
||||||
{(auth?.role === "owner" || user?.canDeleteServices) && (
|
{(auth?.role === "owner" ||
|
||||||
|
auth?.user?.canDeleteServices) && (
|
||||||
<DeleteService id={postgresId} type="postgres" />
|
<DeleteService id={postgresId} type="postgres" />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -335,8 +329,8 @@ export async function getServerSideProps(
|
|||||||
req: req as any,
|
req: req as any,
|
||||||
res: res as any,
|
res: res as any,
|
||||||
db: null as any,
|
db: null as any,
|
||||||
session: session,
|
session: session as any,
|
||||||
user: user,
|
user: user as any,
|
||||||
},
|
},
|
||||||
transformer: superjson,
|
transformer: superjson,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -62,14 +62,6 @@ const Redis = (
|
|||||||
|
|
||||||
const { data: auth } = api.auth.get.useQuery();
|
const { data: auth } = api.auth.get.useQuery();
|
||||||
const { data: monitoring } = api.admin.getMetricsToken.useQuery();
|
const { data: monitoring } = api.admin.getMetricsToken.useQuery();
|
||||||
const { data: user } = api.user.byAuthId.useQuery(
|
|
||||||
{
|
|
||||||
authId: auth?.id || "",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
enabled: !!auth?.id && auth?.role === "member",
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
const { data: isCloud } = api.settings.isCloud.useQuery();
|
const { data: isCloud } = api.settings.isCloud.useQuery();
|
||||||
|
|
||||||
@@ -155,7 +147,8 @@ const Redis = (
|
|||||||
|
|
||||||
<div className="flex flex-row gap-2 justify-end">
|
<div className="flex flex-row gap-2 justify-end">
|
||||||
<UpdateRedis redisId={redisId} />
|
<UpdateRedis redisId={redisId} />
|
||||||
{(auth?.role === "owner" || user?.canDeleteServices) && (
|
{(auth?.role === "owner" ||
|
||||||
|
auth?.user?.canDeleteServices) && (
|
||||||
<DeleteService id={redisId} type="redis" />
|
<DeleteService id={redisId} type="redis" />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -327,8 +320,8 @@ export async function getServerSideProps(
|
|||||||
req: req as any,
|
req: req as any,
|
||||||
res: res as any,
|
res: res as any,
|
||||||
db: null as any,
|
db: null as any,
|
||||||
session: session,
|
session: session as any,
|
||||||
user: user,
|
user: user as any,
|
||||||
},
|
},
|
||||||
transformer: superjson,
|
transformer: superjson,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import {
|
|||||||
apiCreateUserInvitation,
|
apiCreateUserInvitation,
|
||||||
apiFindOneToken,
|
apiFindOneToken,
|
||||||
apiRemoveUser,
|
apiRemoveUser,
|
||||||
apiUpdateAdmin,
|
|
||||||
apiUpdateWebServerMonitoring,
|
apiUpdateWebServerMonitoring,
|
||||||
} from "@/server/db/schema";
|
} from "@/server/db/schema";
|
||||||
import {
|
import {
|
||||||
@@ -36,19 +35,17 @@ export const adminRouter = createTRPCRouter({
|
|||||||
...rest,
|
...rest,
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
update: adminProcedure
|
update: adminProcedure.mutation(async ({ input, ctx }) => {
|
||||||
.input(apiUpdateAdmin)
|
if (ctx.user.rol === "member") {
|
||||||
.mutation(async ({ input, ctx }) => {
|
throw new TRPCError({
|
||||||
if (ctx.user.rol === "member") {
|
code: "UNAUTHORIZED",
|
||||||
throw new TRPCError({
|
message: "You are not allowed to update this admin",
|
||||||
code: "UNAUTHORIZED",
|
});
|
||||||
message: "You are not allowed to update this admin",
|
}
|
||||||
});
|
const { id } = await findUserById(ctx.user.id);
|
||||||
}
|
// @ts-ignore
|
||||||
const { id } = await findUserById(ctx.user.id);
|
return updateAdmin(id, input);
|
||||||
// @ts-ignore
|
}),
|
||||||
return updateAdmin(id, input);
|
|
||||||
}),
|
|
||||||
createUserInvitation: adminProcedure
|
createUserInvitation: adminProcedure
|
||||||
.input(apiCreateUserInvitation)
|
.input(apiCreateUserInvitation)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
|
|||||||
@@ -1,30 +1,23 @@
|
|||||||
import {
|
import {
|
||||||
apiCreateAdmin,
|
// apiCreateAdmin,
|
||||||
apiCreateUser,
|
// apiCreateUser,
|
||||||
apiFindOneAuth,
|
// apiFindOneAuth,
|
||||||
apiLogin,
|
// apiLogin,
|
||||||
apiUpdateAuth,
|
// apiUpdateAuth,
|
||||||
apiVerify2FA,
|
// apiVerify2FA,
|
||||||
apiVerifyLogin2FA,
|
// apiVerifyLogin2FA,
|
||||||
auth,
|
// auth,
|
||||||
member,
|
member,
|
||||||
} from "@/server/db/schema";
|
} from "@/server/db/schema";
|
||||||
import { WEBSITE_URL } from "@/server/utils/stripe";
|
import { WEBSITE_URL } from "@/server/utils/stripe";
|
||||||
import {
|
import {
|
||||||
type Auth,
|
|
||||||
IS_CLOUD,
|
IS_CLOUD,
|
||||||
createAdmin,
|
|
||||||
createUser,
|
|
||||||
findAuthByEmail,
|
|
||||||
findAuthById,
|
findAuthById,
|
||||||
findUserById,
|
findUserById,
|
||||||
generate2FASecret,
|
generate2FASecret,
|
||||||
getUserByToken,
|
getUserByToken,
|
||||||
removeAdminByAuthId,
|
|
||||||
sendDiscordNotification,
|
sendDiscordNotification,
|
||||||
sendEmailNotification,
|
sendEmailNotification,
|
||||||
updateAuthById,
|
|
||||||
updateUser,
|
|
||||||
validateRequest,
|
validateRequest,
|
||||||
verify2FA,
|
verify2FA,
|
||||||
} from "@dokploy/server";
|
} from "@dokploy/server";
|
||||||
@@ -43,81 +36,77 @@ import {
|
|||||||
} from "../trpc";
|
} from "../trpc";
|
||||||
|
|
||||||
export const authRouter = createTRPCRouter({
|
export const authRouter = createTRPCRouter({
|
||||||
createAdmin: publicProcedure
|
createAdmin: publicProcedure.mutation(async ({ ctx, input }) => {
|
||||||
.input(apiCreateAdmin)
|
try {
|
||||||
.mutation(async ({ ctx, input }) => {
|
if (!IS_CLOUD) {
|
||||||
try {
|
const admin = await db.query.admins.findFirst({});
|
||||||
if (!IS_CLOUD) {
|
if (admin) {
|
||||||
const admin = await db.query.admins.findFirst({});
|
throw new TRPCError({
|
||||||
if (admin) {
|
code: "BAD_REQUEST",
|
||||||
throw new TRPCError({
|
message: "Admin already exists",
|
||||||
code: "BAD_REQUEST",
|
});
|
||||||
message: "Admin already exists",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
const newAdmin = await createAdmin(input);
|
}
|
||||||
|
const newAdmin = await createAdmin(input);
|
||||||
|
|
||||||
if (IS_CLOUD) {
|
if (IS_CLOUD) {
|
||||||
await sendDiscordNotificationWelcome(newAdmin);
|
await sendDiscordNotificationWelcome(newAdmin);
|
||||||
await sendVerificationEmail(newAdmin.id);
|
await sendVerificationEmail(newAdmin.id);
|
||||||
return {
|
|
||||||
status: "success",
|
|
||||||
type: "cloud",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
// const session = await lucia.createSession(newAdmin.id || "", {});
|
|
||||||
// ctx.res.appendHeader(
|
|
||||||
// "Set-Cookie",
|
|
||||||
// lucia.createSessionCookie(session.id).serialize(),
|
|
||||||
// );
|
|
||||||
return {
|
return {
|
||||||
status: "success",
|
status: "success",
|
||||||
type: "selfhosted",
|
type: "cloud",
|
||||||
};
|
};
|
||||||
} catch (error) {
|
|
||||||
throw new TRPCError({
|
|
||||||
code: "BAD_REQUEST",
|
|
||||||
// @ts-ignore
|
|
||||||
message: `Error: ${error?.code === "23505" ? "Email already exists" : "Error creating admin"}`,
|
|
||||||
cause: error,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}),
|
// const session = await lucia.createSession(newAdmin.id || "", {});
|
||||||
createUser: publicProcedure
|
// ctx.res.appendHeader(
|
||||||
.input(apiCreateUser)
|
// "Set-Cookie",
|
||||||
.mutation(async ({ ctx, input }) => {
|
// lucia.createSessionCookie(session.id).serialize(),
|
||||||
try {
|
// );
|
||||||
const token = await getUserByToken(input.token);
|
return {
|
||||||
// if (token.isExpired) {
|
status: "success",
|
||||||
// throw new TRPCError({
|
type: "selfhosted",
|
||||||
// code: "BAD_REQUEST",
|
};
|
||||||
// message: "Invalid token",
|
} catch (error) {
|
||||||
// });
|
throw new TRPCError({
|
||||||
// }
|
code: "BAD_REQUEST",
|
||||||
|
// @ts-ignore
|
||||||
|
message: `Error: ${error?.code === "23505" ? "Email already exists" : "Error creating admin"}`,
|
||||||
|
cause: error,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
createUser: publicProcedure.mutation(async ({ ctx, input }) => {
|
||||||
|
try {
|
||||||
|
const token = await getUserByToken(input.token);
|
||||||
|
// if (token.isExpired) {
|
||||||
|
// throw new TRPCError({
|
||||||
|
// code: "BAD_REQUEST",
|
||||||
|
// message: "Invalid token",
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
// const newUser = await createUser(input);
|
// const newUser = await createUser(input);
|
||||||
|
|
||||||
// if (IS_CLOUD) {
|
// if (IS_CLOUD) {
|
||||||
// await sendVerificationEmail(token.authId);
|
// await sendVerificationEmail(token.authId);
|
||||||
// return true;
|
// return true;
|
||||||
// }
|
// }
|
||||||
// const session = await lucia.createSession(newUser?.authId || "", {});
|
// const session = await lucia.createSession(newUser?.authId || "", {});
|
||||||
// ctx.res.appendHeader(
|
// ctx.res.appendHeader(
|
||||||
// "Set-Cookie",
|
// "Set-Cookie",
|
||||||
// lucia.createSessionCookie(session.id).serialize(),
|
// lucia.createSessionCookie(session.id).serialize(),
|
||||||
// );
|
// );
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "BAD_REQUEST",
|
code: "BAD_REQUEST",
|
||||||
message: "Error creating the user",
|
message: "Error creating the user",
|
||||||
cause: error,
|
cause: error,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
login: publicProcedure.input(apiLogin).mutation(async ({ ctx, input }) => {
|
login: publicProcedure.mutation(async ({ ctx, input }) => {
|
||||||
try {
|
try {
|
||||||
const auth = await findAuthByEmail(input.email);
|
const auth = await findAuthByEmail(input.email);
|
||||||
|
|
||||||
@@ -192,33 +181,31 @@ export const authRouter = createTRPCRouter({
|
|||||||
return true;
|
return true;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
update: protectedProcedure
|
update: protectedProcedure.mutation(async ({ ctx, input }) => {
|
||||||
.input(apiUpdateAuth)
|
const currentAuth = await findAuthByEmail(ctx.user.email);
|
||||||
.mutation(async ({ ctx, input }) => {
|
|
||||||
const currentAuth = await findAuthByEmail(ctx.user.email);
|
|
||||||
|
|
||||||
if (input.currentPassword || input.password) {
|
if (input.currentPassword || input.password) {
|
||||||
const correctPassword = bcrypt.compareSync(
|
const correctPassword = bcrypt.compareSync(
|
||||||
input.currentPassword || "",
|
input.currentPassword || "",
|
||||||
currentAuth?.password || "",
|
currentAuth?.password || "",
|
||||||
);
|
);
|
||||||
if (!correctPassword) {
|
if (!correctPassword) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "BAD_REQUEST",
|
code: "BAD_REQUEST",
|
||||||
message: "Current password is incorrect",
|
message: "Current password is incorrect",
|
||||||
});
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// const auth = await updateAuthById(ctx.user.authId, {
|
}
|
||||||
// ...(input.email && { email: input.email.toLowerCase() }),
|
// const auth = await updateAuthById(ctx.user.authId, {
|
||||||
// ...(input.password && {
|
// ...(input.email && { email: input.email.toLowerCase() }),
|
||||||
// password: bcrypt.hashSync(input.password, 10),
|
// ...(input.password && {
|
||||||
// }),
|
// password: bcrypt.hashSync(input.password, 10),
|
||||||
// ...(input.image && { image: input.image }),
|
// }),
|
||||||
// });
|
// ...(input.image && { image: input.image }),
|
||||||
|
// });
|
||||||
|
|
||||||
return auth;
|
return auth;
|
||||||
}),
|
}),
|
||||||
removeSelfAccount: protectedProcedure
|
removeSelfAccount: protectedProcedure
|
||||||
.input(
|
.input(
|
||||||
z.object({
|
z.object({
|
||||||
@@ -279,7 +266,7 @@ export const authRouter = createTRPCRouter({
|
|||||||
verifyToken: protectedProcedure.mutation(async () => {
|
verifyToken: protectedProcedure.mutation(async () => {
|
||||||
return true;
|
return true;
|
||||||
}),
|
}),
|
||||||
one: adminProcedure.input(apiFindOneAuth).query(async ({ input }) => {
|
one: adminProcedure.query(async ({ input }) => {
|
||||||
const auth = await findAuthById(input.id);
|
const auth = await findAuthById(input.id);
|
||||||
return auth;
|
return auth;
|
||||||
}),
|
}),
|
||||||
@@ -287,34 +274,30 @@ export const authRouter = createTRPCRouter({
|
|||||||
generate2FASecret: protectedProcedure.query(async ({ ctx }) => {
|
generate2FASecret: protectedProcedure.query(async ({ ctx }) => {
|
||||||
return await generate2FASecret(ctx.user.id);
|
return await generate2FASecret(ctx.user.id);
|
||||||
}),
|
}),
|
||||||
verify2FASetup: protectedProcedure
|
verify2FASetup: protectedProcedure.mutation(async ({ ctx, input }) => {
|
||||||
.input(apiVerify2FA)
|
// const auth = await findAuthById(ctx.user.authId);
|
||||||
.mutation(async ({ ctx, input }) => {
|
// await verify2FA(auth, input.secret, input.pin);
|
||||||
// const auth = await findAuthById(ctx.user.authId);
|
// await updateAuthById(auth.id, {
|
||||||
// await verify2FA(auth, input.secret, input.pin);
|
// is2FAEnabled: true,
|
||||||
// await updateAuthById(auth.id, {
|
// secret: input.secret,
|
||||||
// is2FAEnabled: true,
|
// });
|
||||||
// secret: input.secret,
|
// return auth;
|
||||||
// });
|
}),
|
||||||
// return auth;
|
|
||||||
}),
|
|
||||||
|
|
||||||
verifyLogin2FA: publicProcedure
|
verifyLogin2FA: publicProcedure.mutation(async ({ ctx, input }) => {
|
||||||
.input(apiVerifyLogin2FA)
|
// const auth = await findAuthById(input.id);
|
||||||
.mutation(async ({ ctx, input }) => {
|
|
||||||
// const auth = await findAuthById(input.id);
|
|
||||||
|
|
||||||
// await verify2FA(auth, auth.secret || "", input.pin);
|
// await verify2FA(auth, auth.secret || "", input.pin);
|
||||||
|
|
||||||
// const session = await lucia.createSession(auth.id, {});
|
// const session = await lucia.createSession(auth.id, {});
|
||||||
|
|
||||||
// ctx.res.appendHeader(
|
// ctx.res.appendHeader(
|
||||||
// "Set-Cookie",
|
// "Set-Cookie",
|
||||||
// lucia.createSessionCookie(session.id).serialize(),
|
// lucia.createSessionCookie(session.id).serialize(),
|
||||||
// );
|
// );
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}),
|
}),
|
||||||
disable2FA: protectedProcedure.mutation(async ({ ctx }) => {
|
disable2FA: protectedProcedure.mutation(async ({ ctx }) => {
|
||||||
// const auth = await findAuthById(ctx.user.authId);
|
// const auth = await findAuthById(ctx.user.authId);
|
||||||
// await updateAuthById(auth.id, {
|
// await updateAuthById(auth.id, {
|
||||||
|
|||||||
@@ -1,210 +0,0 @@
|
|||||||
import { relations } from "drizzle-orm";
|
|
||||||
import {
|
|
||||||
boolean,
|
|
||||||
integer,
|
|
||||||
json,
|
|
||||||
jsonb,
|
|
||||||
pgTable,
|
|
||||||
text,
|
|
||||||
} from "drizzle-orm/pg-core";
|
|
||||||
import { createInsertSchema } from "drizzle-zod";
|
|
||||||
import { nanoid } from "nanoid";
|
|
||||||
import { z } from "zod";
|
|
||||||
import { auth } from "./auth";
|
|
||||||
import { certificates } from "./certificate";
|
|
||||||
import { registry } from "./registry";
|
|
||||||
import { certificateType } from "./shared";
|
|
||||||
import { sshKeys } from "./ssh-key";
|
|
||||||
import { users } from "./user";
|
|
||||||
|
|
||||||
export const admins = pgTable("admin", {
|
|
||||||
adminId: text("adminId")
|
|
||||||
.notNull()
|
|
||||||
.primaryKey()
|
|
||||||
.$defaultFn(() => nanoid()),
|
|
||||||
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),
|
|
||||||
authId: text("authId")
|
|
||||||
.notNull()
|
|
||||||
.references(() => auth.id, { onDelete: "cascade" }),
|
|
||||||
createdAt: text("createdAt")
|
|
||||||
.notNull()
|
|
||||||
.$defaultFn(() => new Date().toISOString()),
|
|
||||||
stripeCustomerId: text("stripeCustomerId"),
|
|
||||||
stripeSubscriptionId: text("stripeSubscriptionId"),
|
|
||||||
serversQuantity: integer("serversQuantity").notNull().default(0),
|
|
||||||
|
|
||||||
// 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),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const adminsRelations = relations(admins, ({ one, many }) => ({
|
|
||||||
auth: one(auth, {
|
|
||||||
fields: [admins.authId],
|
|
||||||
references: [auth.id],
|
|
||||||
}),
|
|
||||||
users: many(users),
|
|
||||||
registry: many(registry),
|
|
||||||
sshKeys: many(sshKeys),
|
|
||||||
certificates: many(certificates),
|
|
||||||
}));
|
|
||||||
|
|
||||||
const createSchema = createInsertSchema(admins, {
|
|
||||||
adminId: z.string(),
|
|
||||||
enableDockerCleanup: z.boolean().optional(),
|
|
||||||
sshPrivateKey: z.string().optional(),
|
|
||||||
certificateType: z.enum(["letsencrypt", "none"]).default("none"),
|
|
||||||
serverIp: z.string().optional(),
|
|
||||||
letsEncryptEmail: z.string().optional(),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const apiUpdateAdmin = createSchema.partial();
|
|
||||||
|
|
||||||
export const apiSaveSSHKey = createSchema
|
|
||||||
.pick({
|
|
||||||
sshPrivateKey: true,
|
|
||||||
})
|
|
||||||
.required();
|
|
||||||
|
|
||||||
export const apiAssignDomain = createSchema
|
|
||||||
.pick({
|
|
||||||
host: true,
|
|
||||||
certificateType: true,
|
|
||||||
letsEncryptEmail: true,
|
|
||||||
})
|
|
||||||
.required()
|
|
||||||
.partial({
|
|
||||||
letsEncryptEmail: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
export const apiUpdateDockerCleanup = createSchema
|
|
||||||
.pick({
|
|
||||||
enableDockerCleanup: true,
|
|
||||||
})
|
|
||||||
.required()
|
|
||||||
.extend({
|
|
||||||
serverId: z.string().optional(),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const apiTraefikConfig = z.object({
|
|
||||||
traefikConfig: z.string().min(1),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const apiModifyTraefikConfig = z.object({
|
|
||||||
path: z.string().min(1),
|
|
||||||
traefikConfig: z.string().min(1),
|
|
||||||
serverId: z.string().optional(),
|
|
||||||
});
|
|
||||||
export const apiReadTraefikConfig = z.object({
|
|
||||||
path: z.string().min(1),
|
|
||||||
serverId: z.string().optional(),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const apiEnableDashboard = z.object({
|
|
||||||
enableDashboard: z.boolean().optional(),
|
|
||||||
serverId: z.string().optional(),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const apiServerSchema = z
|
|
||||||
.object({
|
|
||||||
serverId: z.string().optional(),
|
|
||||||
})
|
|
||||||
.optional();
|
|
||||||
|
|
||||||
export const apiReadStatsLogs = z.object({
|
|
||||||
page: z
|
|
||||||
.object({
|
|
||||||
pageIndex: z.number(),
|
|
||||||
pageSize: z.number(),
|
|
||||||
})
|
|
||||||
.optional(),
|
|
||||||
status: z.string().array().optional(),
|
|
||||||
search: z.string().optional(),
|
|
||||||
sort: z.object({ id: z.string(), desc: z.boolean() }).optional(),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const apiUpdateWebServerMonitoring = z.object({
|
|
||||||
metricsConfig: z
|
|
||||||
.object({
|
|
||||||
server: z.object({
|
|
||||||
refreshRate: z.number().min(2),
|
|
||||||
port: z.number().min(1),
|
|
||||||
token: z.string(),
|
|
||||||
urlCallback: z.string().url(),
|
|
||||||
retentionDays: z.number().min(1),
|
|
||||||
cronJob: z.string().min(1),
|
|
||||||
thresholds: z.object({
|
|
||||||
cpu: z.number().min(0),
|
|
||||||
memory: z.number().min(0),
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
containers: z.object({
|
|
||||||
refreshRate: z.number().min(2),
|
|
||||||
services: z.object({
|
|
||||||
include: z.array(z.string()).optional(),
|
|
||||||
exclude: z.array(z.string()).optional(),
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
.required(),
|
|
||||||
});
|
|
||||||
@@ -1,130 +0,0 @@
|
|||||||
import { getRandomValues } from "node:crypto";
|
|
||||||
import { relations } from "drizzle-orm";
|
|
||||||
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 { users } from "./user";
|
|
||||||
|
|
||||||
const randomImages = [
|
|
||||||
"/avatars/avatar-1.png",
|
|
||||||
"/avatars/avatar-2.png",
|
|
||||||
"/avatars/avatar-3.png",
|
|
||||||
"/avatars/avatar-4.png",
|
|
||||||
"/avatars/avatar-5.png",
|
|
||||||
"/avatars/avatar-6.png",
|
|
||||||
"/avatars/avatar-7.png",
|
|
||||||
"/avatars/avatar-8.png",
|
|
||||||
"/avatars/avatar-9.png",
|
|
||||||
"/avatars/avatar-10.png",
|
|
||||||
"/avatars/avatar-11.png",
|
|
||||||
"/avatars/avatar-12.png",
|
|
||||||
];
|
|
||||||
|
|
||||||
const generateRandomImage = () => {
|
|
||||||
return (
|
|
||||||
randomImages[
|
|
||||||
// @ts-ignore
|
|
||||||
getRandomValues(new Uint32Array(1))[0] % randomImages.length
|
|
||||||
] || "/avatars/avatar-1.png"
|
|
||||||
);
|
|
||||||
};
|
|
||||||
export type DatabaseUser = typeof auth.$inferSelect;
|
|
||||||
export const roles = pgEnum("Roles", ["admin", "user"]);
|
|
||||||
|
|
||||||
export const auth = pgTable("auth", {
|
|
||||||
id: text("id")
|
|
||||||
.notNull()
|
|
||||||
.primaryKey()
|
|
||||||
.$defaultFn(() => nanoid()),
|
|
||||||
email: text("email").notNull().unique(),
|
|
||||||
password: text("password").notNull(),
|
|
||||||
rol: roles("rol").notNull(),
|
|
||||||
image: text("image").$defaultFn(() => generateRandomImage()),
|
|
||||||
secret: text("secret"),
|
|
||||||
token: text("token"),
|
|
||||||
is2FAEnabled: boolean("is2FAEnabled").notNull().default(false),
|
|
||||||
createdAt: text("createdAt")
|
|
||||||
.notNull()
|
|
||||||
.$defaultFn(() => new Date().toISOString()),
|
|
||||||
resetPasswordToken: text("resetPasswordToken"),
|
|
||||||
resetPasswordExpiresAt: text("resetPasswordExpiresAt"),
|
|
||||||
confirmationToken: text("confirmationToken"),
|
|
||||||
confirmationExpiresAt: text("confirmationExpiresAt"),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const authRelations = relations(auth, ({ many }) => ({
|
|
||||||
// admins: many(admins),
|
|
||||||
users: many(users),
|
|
||||||
}));
|
|
||||||
const createSchema = createInsertSchema(auth, {
|
|
||||||
email: z.string().email(),
|
|
||||||
password: z.string().min(8),
|
|
||||||
rol: z.enum(["admin", "user"]),
|
|
||||||
image: z.string().optional(),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const apiCreateAdmin = createSchema.pick({
|
|
||||||
email: true,
|
|
||||||
password: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
export const apiCreateUser = createSchema
|
|
||||||
.pick({
|
|
||||||
password: true,
|
|
||||||
id: true,
|
|
||||||
token: true,
|
|
||||||
})
|
|
||||||
.required()
|
|
||||||
.extend({
|
|
||||||
token: z.string().min(1),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const apiLogin = createSchema
|
|
||||||
.pick({
|
|
||||||
email: true,
|
|
||||||
password: true,
|
|
||||||
})
|
|
||||||
.required();
|
|
||||||
|
|
||||||
export const apiUpdateAuth = createSchema.partial().extend({
|
|
||||||
email: z.string().nullable(),
|
|
||||||
password: z.string().nullable(),
|
|
||||||
image: z.string().optional(),
|
|
||||||
currentPassword: z.string().nullable(),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const apiUpdateAuthByAdmin = createSchema.partial().extend({
|
|
||||||
email: z.string().nullable(),
|
|
||||||
password: z.string().nullable(),
|
|
||||||
image: z.string().optional(),
|
|
||||||
id: z.string().min(1),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const apiFindOneAuth = createSchema
|
|
||||||
.pick({
|
|
||||||
id: true,
|
|
||||||
})
|
|
||||||
.required();
|
|
||||||
|
|
||||||
export const apiVerify2FA = createSchema
|
|
||||||
.extend({
|
|
||||||
pin: z.string().min(6),
|
|
||||||
secret: z.string().min(1),
|
|
||||||
})
|
|
||||||
.pick({
|
|
||||||
pin: true,
|
|
||||||
secret: true,
|
|
||||||
})
|
|
||||||
.required();
|
|
||||||
|
|
||||||
export const apiVerifyLogin2FA = createSchema
|
|
||||||
.extend({
|
|
||||||
pin: z.string().min(6),
|
|
||||||
})
|
|
||||||
.pick({
|
|
||||||
pin: true,
|
|
||||||
id: true,
|
|
||||||
})
|
|
||||||
.required();
|
|
||||||
@@ -4,10 +4,7 @@ import { createInsertSchema } from "drizzle-zod";
|
|||||||
import { nanoid } from "nanoid";
|
import { nanoid } from "nanoid";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { organization } from "./account";
|
import { organization } from "./account";
|
||||||
import { admins } from "./admin";
|
|
||||||
import { server } from "./server";
|
import { server } from "./server";
|
||||||
import { users_temp } from "./user";
|
|
||||||
// import { user } from "./user";
|
|
||||||
import { generateAppName } from "./utils";
|
import { generateAppName } from "./utils";
|
||||||
|
|
||||||
export const certificates = pgTable("certificate", {
|
export const certificates = pgTable("certificate", {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { is, relations } from "drizzle-orm";
|
import { relations } from "drizzle-orm";
|
||||||
import {
|
import {
|
||||||
type AnyPgColumn,
|
type AnyPgColumn,
|
||||||
boolean,
|
boolean,
|
||||||
|
|||||||
@@ -4,10 +4,7 @@ import { createInsertSchema } from "drizzle-zod";
|
|||||||
import { nanoid } from "nanoid";
|
import { nanoid } from "nanoid";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { organization } from "./account";
|
import { organization } from "./account";
|
||||||
import { admins } from "./admin";
|
|
||||||
import { backups } from "./backups";
|
import { backups } from "./backups";
|
||||||
import { users_temp } from "./user";
|
|
||||||
// import { user } from "./user";
|
|
||||||
|
|
||||||
export const destinations = pgTable("destination", {
|
export const destinations = pgTable("destination", {
|
||||||
destinationId: text("destinationId")
|
destinationId: text("destinationId")
|
||||||
@@ -20,7 +17,6 @@ export const destinations = pgTable("destination", {
|
|||||||
secretAccessKey: text("secretAccessKey").notNull(),
|
secretAccessKey: text("secretAccessKey").notNull(),
|
||||||
bucket: text("bucket").notNull(),
|
bucket: text("bucket").notNull(),
|
||||||
region: text("region").notNull(),
|
region: text("region").notNull(),
|
||||||
// maybe it can be null
|
|
||||||
endpoint: text("endpoint").notNull(),
|
endpoint: text("endpoint").notNull(),
|
||||||
organizationId: text("organizationId")
|
organizationId: text("organizationId")
|
||||||
.notNull()
|
.notNull()
|
||||||
@@ -35,10 +31,6 @@ export const destinationsRelations = relations(
|
|||||||
fields: [destinations.organizationId],
|
fields: [destinations.organizationId],
|
||||||
references: [organization.id],
|
references: [organization.id],
|
||||||
}),
|
}),
|
||||||
// user: one(user, {
|
|
||||||
// fields: [destinations.userId],
|
|
||||||
// references: [user.id],
|
|
||||||
// }),
|
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -4,12 +4,9 @@ import { createInsertSchema } from "drizzle-zod";
|
|||||||
import { nanoid } from "nanoid";
|
import { nanoid } from "nanoid";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { organization } from "./account";
|
import { organization } from "./account";
|
||||||
import { admins } from "./admin";
|
|
||||||
import { bitbucket } from "./bitbucket";
|
import { bitbucket } from "./bitbucket";
|
||||||
import { github } from "./github";
|
import { github } from "./github";
|
||||||
import { gitlab } from "./gitlab";
|
import { gitlab } from "./gitlab";
|
||||||
import { users_temp } from "./user";
|
|
||||||
// import { user } from "./user";
|
|
||||||
|
|
||||||
export const gitProviderType = pgEnum("gitProviderType", [
|
export const gitProviderType = pgEnum("gitProviderType", [
|
||||||
"github",
|
"github",
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
export * from "./application";
|
export * from "./application";
|
||||||
export * from "./postgres";
|
export * from "./postgres";
|
||||||
export * from "./user";
|
export * from "./user";
|
||||||
export * from "./admin";
|
|
||||||
export * from "./auth";
|
|
||||||
export * from "./project";
|
export * from "./project";
|
||||||
export * from "./domain";
|
export * from "./domain";
|
||||||
export * from "./mariadb";
|
export * from "./mariadb";
|
||||||
|
|||||||
@@ -4,8 +4,6 @@ import { createInsertSchema } from "drizzle-zod";
|
|||||||
import { nanoid } from "nanoid";
|
import { nanoid } from "nanoid";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { organization } from "./account";
|
import { organization } from "./account";
|
||||||
import { users_temp } from "./user";
|
|
||||||
// import { user } from "./user";
|
|
||||||
|
|
||||||
export const notificationType = pgEnum("notificationType", [
|
export const notificationType = pgEnum("notificationType", [
|
||||||
"slack",
|
"slack",
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
import { relations } from "drizzle-orm";
|
import { relations } from "drizzle-orm";
|
||||||
|
|
||||||
import { pgTable, text } from "drizzle-orm/pg-core";
|
import { pgTable, text } from "drizzle-orm/pg-core";
|
||||||
import { createInsertSchema } from "drizzle-zod";
|
import { createInsertSchema } from "drizzle-zod";
|
||||||
import { nanoid } from "nanoid";
|
import { nanoid } from "nanoid";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { organization } from "./account";
|
import { organization } from "./account";
|
||||||
import { admins } from "./admin";
|
|
||||||
// import { admins } from "./admin";
|
|
||||||
import { applications } from "./application";
|
import { applications } from "./application";
|
||||||
import { compose } from "./compose";
|
import { compose } from "./compose";
|
||||||
import { mariadb } from "./mariadb";
|
import { mariadb } from "./mariadb";
|
||||||
@@ -14,7 +11,6 @@ import { mongo } from "./mongo";
|
|||||||
import { mysql } from "./mysql";
|
import { mysql } from "./mysql";
|
||||||
import { postgres } from "./postgres";
|
import { postgres } from "./postgres";
|
||||||
import { redis } from "./redis";
|
import { redis } from "./redis";
|
||||||
import { users, users_temp } from "./user";
|
|
||||||
|
|
||||||
export const projects = pgTable("project", {
|
export const projects = pgTable("project", {
|
||||||
projectId: text("projectId")
|
projectId: text("projectId")
|
||||||
|
|||||||
@@ -4,10 +4,7 @@ import { createInsertSchema } from "drizzle-zod";
|
|||||||
import { nanoid } from "nanoid";
|
import { nanoid } from "nanoid";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { organization } from "./account";
|
import { organization } from "./account";
|
||||||
import { admins } from "./admin";
|
|
||||||
import { applications } from "./application";
|
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
|
* This is an example of how to use the multi-project schema feature of Drizzle ORM. Use the same
|
||||||
* database instance for multiple projects.
|
* database instance for multiple projects.
|
||||||
@@ -36,10 +33,6 @@ export const registry = pgTable("registry", {
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const registryRelations = relations(registry, ({ one, many }) => ({
|
export const registryRelations = relations(registry, ({ one, many }) => ({
|
||||||
// user: one(user, {
|
|
||||||
// fields: [registry.userId],
|
|
||||||
// references: [user.id],
|
|
||||||
// }),
|
|
||||||
applications: many(applications),
|
applications: many(applications),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|||||||
@@ -10,9 +10,7 @@ import {
|
|||||||
import { createInsertSchema } from "drizzle-zod";
|
import { createInsertSchema } from "drizzle-zod";
|
||||||
import { nanoid } from "nanoid";
|
import { nanoid } from "nanoid";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { organization } from "./account";
|
import { organization } from "./account";
|
||||||
import { admins } from "./admin";
|
|
||||||
import { applications } from "./application";
|
import { applications } from "./application";
|
||||||
import { certificates } from "./certificate";
|
import { certificates } from "./certificate";
|
||||||
import { compose } from "./compose";
|
import { compose } from "./compose";
|
||||||
@@ -23,8 +21,6 @@ import { mysql } from "./mysql";
|
|||||||
import { postgres } from "./postgres";
|
import { postgres } from "./postgres";
|
||||||
import { redis } from "./redis";
|
import { redis } from "./redis";
|
||||||
import { sshKeys } from "./ssh-key";
|
import { sshKeys } from "./ssh-key";
|
||||||
import { users_temp } from "./user";
|
|
||||||
// import { user } from "./user";
|
|
||||||
import { generateAppName } from "./utils";
|
import { generateAppName } from "./utils";
|
||||||
|
|
||||||
export const serverStatus = pgEnum("serverStatus", ["active", "inactive"]);
|
export const serverStatus = pgEnum("serverStatus", ["active", "inactive"]);
|
||||||
@@ -101,10 +97,6 @@ export const server = pgTable("server", {
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const serverRelations = relations(server, ({ one, many }) => ({
|
export const serverRelations = relations(server, ({ one, many }) => ({
|
||||||
// user: one(user, {
|
|
||||||
// fields: [server.userId],
|
|
||||||
// references: [user.id],
|
|
||||||
// }),
|
|
||||||
deployments: many(deployments),
|
deployments: many(deployments),
|
||||||
sshKey: one(sshKeys, {
|
sshKey: one(sshKeys, {
|
||||||
fields: [server.sshKeyId],
|
fields: [server.sshKeyId],
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
import { sql } from "drizzle-orm";
|
|
||||||
import { pgTable, text, timestamp } from "drizzle-orm/pg-core";
|
import { pgTable, text, timestamp } from "drizzle-orm/pg-core";
|
||||||
import { auth } from "./auth";
|
|
||||||
import { users_temp } from "./user";
|
import { users_temp } from "./user";
|
||||||
|
|
||||||
// OLD TABLE
|
// OLD TABLE
|
||||||
@@ -18,14 +16,3 @@ export const session = pgTable("session_temp", {
|
|||||||
impersonatedBy: text("impersonated_by"),
|
impersonatedBy: text("impersonated_by"),
|
||||||
activeOrganizationId: text("active_organization_id"),
|
activeOrganizationId: text("active_organization_id"),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const sessionTable = pgTable("session", {
|
|
||||||
id: text("id").primaryKey(),
|
|
||||||
userId: text("user_id")
|
|
||||||
.notNull()
|
|
||||||
.references(() => auth.id, { onDelete: "cascade" }),
|
|
||||||
expiresAt: timestamp("expires_at", {
|
|
||||||
withTimezone: true,
|
|
||||||
mode: "date",
|
|
||||||
}).notNull(),
|
|
||||||
});
|
|
||||||
|
|||||||
@@ -1,27 +0,0 @@
|
|||||||
import { pgTable, text } from "drizzle-orm/pg-core";
|
|
||||||
import { createInsertSchema } from "drizzle-zod";
|
|
||||||
import { nanoid } from "nanoid";
|
|
||||||
import { z } from "zod";
|
|
||||||
|
|
||||||
export const source = pgTable("project", {
|
|
||||||
projectId: text("projectId")
|
|
||||||
.notNull()
|
|
||||||
.primaryKey()
|
|
||||||
.$defaultFn(() => nanoid()),
|
|
||||||
name: text("name").notNull(),
|
|
||||||
description: text("description"),
|
|
||||||
createdAt: text("createdAt")
|
|
||||||
.notNull()
|
|
||||||
.$defaultFn(() => new Date().toISOString()),
|
|
||||||
});
|
|
||||||
|
|
||||||
const createSchema = createInsertSchema(source, {
|
|
||||||
name: z.string().min(1),
|
|
||||||
description: z.string(),
|
|
||||||
projectId: z.string(),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const apiCreate = createSchema.pick({
|
|
||||||
name: true,
|
|
||||||
description: true,
|
|
||||||
});
|
|
||||||
@@ -4,12 +4,9 @@ import { createInsertSchema } from "drizzle-zod";
|
|||||||
import { nanoid } from "nanoid";
|
import { nanoid } from "nanoid";
|
||||||
import { sshKeyCreate, sshKeyType } from "../validations";
|
import { sshKeyCreate, sshKeyType } from "../validations";
|
||||||
import { organization } from "./account";
|
import { organization } from "./account";
|
||||||
import { admins } from "./admin";
|
|
||||||
import { applications } from "./application";
|
import { applications } from "./application";
|
||||||
import { compose } from "./compose";
|
import { compose } from "./compose";
|
||||||
import { server } from "./server";
|
import { server } from "./server";
|
||||||
import { users_temp } from "./user";
|
|
||||||
// import { user } from "./user";
|
|
||||||
|
|
||||||
export const sshKeys = pgTable("ssh-key", {
|
export const sshKeys = pgTable("ssh-key", {
|
||||||
sshKeyId: text("sshKeyId")
|
sshKeyId: text("sshKeyId")
|
||||||
|
|||||||
@@ -11,8 +11,6 @@ import { createInsertSchema } from "drizzle-zod";
|
|||||||
import { nanoid } from "nanoid";
|
import { nanoid } from "nanoid";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { account, organization } from "./account";
|
import { account, organization } from "./account";
|
||||||
import { admins } from "./admin";
|
|
||||||
import { auth } from "./auth";
|
|
||||||
import { projects } from "./project";
|
import { projects } from "./project";
|
||||||
import { certificateType } from "./shared";
|
import { certificateType } from "./shared";
|
||||||
/**
|
/**
|
||||||
@@ -24,50 +22,6 @@ import { certificateType } from "./shared";
|
|||||||
|
|
||||||
// OLD TABLE
|
// OLD TABLE
|
||||||
|
|
||||||
export const users = pgTable("user", {
|
|
||||||
userId: text("userId")
|
|
||||||
.notNull()
|
|
||||||
.primaryKey()
|
|
||||||
.$defaultFn(() => nanoid()),
|
|
||||||
|
|
||||||
token: text("token").notNull(),
|
|
||||||
isRegistered: boolean("isRegistered").notNull().default(false),
|
|
||||||
expirationDate: timestamp("expirationDate", {
|
|
||||||
precision: 3,
|
|
||||||
mode: "string",
|
|
||||||
}).notNull(),
|
|
||||||
createdAt: text("createdAt")
|
|
||||||
.notNull()
|
|
||||||
.$defaultFn(() => new Date().toISOString()),
|
|
||||||
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[]`),
|
|
||||||
adminId: text("adminId")
|
|
||||||
.notNull()
|
|
||||||
.references(() => admins.adminId, { onDelete: "cascade" }),
|
|
||||||
authId: text("authId")
|
|
||||||
.notNull()
|
|
||||||
.references(() => auth.id, { onDelete: "cascade" }),
|
|
||||||
});
|
|
||||||
|
|
||||||
// TEMP
|
// TEMP
|
||||||
export const users_temp = pgTable("user_temp", {
|
export const users_temp = pgTable("user_temp", {
|
||||||
id: text("id")
|
id: text("id")
|
||||||
@@ -187,19 +141,11 @@ export const users_temp = pgTable("user_temp", {
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const usersRelations = relations(users_temp, ({ one, many }) => ({
|
export const usersRelations = relations(users_temp, ({ one, many }) => ({
|
||||||
// auth: one(auth, {
|
|
||||||
// fields: [users.authId],
|
|
||||||
// references: [auth.id],
|
|
||||||
// }),
|
|
||||||
account: one(account, {
|
account: one(account, {
|
||||||
fields: [users_temp.id],
|
fields: [users_temp.id],
|
||||||
references: [account.userId],
|
references: [account.userId],
|
||||||
}),
|
}),
|
||||||
organizations: many(organization),
|
organizations: many(organization),
|
||||||
// admin: one(admins, {
|
|
||||||
// fields: [users.adminId],
|
|
||||||
// references: [admins.adminId],
|
|
||||||
// }),
|
|
||||||
projects: many(projects),
|
projects: many(projects),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -263,3 +209,91 @@ export const apiFindOneUserByAuth = createSchema
|
|||||||
// authId: true,
|
// authId: true,
|
||||||
})
|
})
|
||||||
.required();
|
.required();
|
||||||
|
export const apiSaveSSHKey = createSchema
|
||||||
|
.pick({
|
||||||
|
sshPrivateKey: true,
|
||||||
|
})
|
||||||
|
.required();
|
||||||
|
|
||||||
|
export const apiAssignDomain = createSchema
|
||||||
|
.pick({
|
||||||
|
host: true,
|
||||||
|
certificateType: true,
|
||||||
|
letsEncryptEmail: true,
|
||||||
|
})
|
||||||
|
.required()
|
||||||
|
.partial({
|
||||||
|
letsEncryptEmail: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const apiUpdateDockerCleanup = createSchema
|
||||||
|
.pick({
|
||||||
|
enableDockerCleanup: true,
|
||||||
|
})
|
||||||
|
.required()
|
||||||
|
.extend({
|
||||||
|
serverId: z.string().optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const apiTraefikConfig = z.object({
|
||||||
|
traefikConfig: z.string().min(1),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const apiModifyTraefikConfig = z.object({
|
||||||
|
path: z.string().min(1),
|
||||||
|
traefikConfig: z.string().min(1),
|
||||||
|
serverId: z.string().optional(),
|
||||||
|
});
|
||||||
|
export const apiReadTraefikConfig = z.object({
|
||||||
|
path: z.string().min(1),
|
||||||
|
serverId: z.string().optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const apiEnableDashboard = z.object({
|
||||||
|
enableDashboard: z.boolean().optional(),
|
||||||
|
serverId: z.string().optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const apiServerSchema = z
|
||||||
|
.object({
|
||||||
|
serverId: z.string().optional(),
|
||||||
|
})
|
||||||
|
.optional();
|
||||||
|
|
||||||
|
export const apiReadStatsLogs = z.object({
|
||||||
|
page: z
|
||||||
|
.object({
|
||||||
|
pageIndex: z.number(),
|
||||||
|
pageSize: z.number(),
|
||||||
|
})
|
||||||
|
.optional(),
|
||||||
|
status: z.string().array().optional(),
|
||||||
|
search: z.string().optional(),
|
||||||
|
sort: z.object({ id: z.string(), desc: z.boolean() }).optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const apiUpdateWebServerMonitoring = z.object({
|
||||||
|
metricsConfig: z
|
||||||
|
.object({
|
||||||
|
server: z.object({
|
||||||
|
refreshRate: z.number().min(2),
|
||||||
|
port: z.number().min(1),
|
||||||
|
token: z.string(),
|
||||||
|
urlCallback: z.string().url(),
|
||||||
|
retentionDays: z.number().min(1),
|
||||||
|
cronJob: z.string().min(1),
|
||||||
|
thresholds: z.object({
|
||||||
|
cpu: z.number().min(0),
|
||||||
|
memory: z.number().min(0),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
containers: z.object({
|
||||||
|
refreshRate: z.number().min(2),
|
||||||
|
services: z.object({
|
||||||
|
include: z.array(z.string()).optional(),
|
||||||
|
exclude: z.array(z.string()).optional(),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
.required(),
|
||||||
|
});
|
||||||
|
|||||||
@@ -2,9 +2,7 @@ import { randomBytes } from "node:crypto";
|
|||||||
import { db } from "@dokploy/server/db";
|
import { db } from "@dokploy/server/db";
|
||||||
import {
|
import {
|
||||||
account,
|
account,
|
||||||
admins,
|
|
||||||
type apiCreateUserInvitation,
|
type apiCreateUserInvitation,
|
||||||
auth,
|
|
||||||
member,
|
member,
|
||||||
organization,
|
organization,
|
||||||
users_temp,
|
users_temp,
|
||||||
|
|||||||
@@ -1,12 +1,6 @@
|
|||||||
import { randomBytes } from "node:crypto";
|
import { randomBytes } from "node:crypto";
|
||||||
import { db } from "@dokploy/server/db";
|
import { db } from "@dokploy/server/db";
|
||||||
import {
|
import { users_temp } from "@dokploy/server/db/schema";
|
||||||
admins,
|
|
||||||
type apiCreateAdmin,
|
|
||||||
type apiCreateUser,
|
|
||||||
auth,
|
|
||||||
users_temp,
|
|
||||||
} from "@dokploy/server/db/schema";
|
|
||||||
import { getPublicIpWithFallback } from "@dokploy/server/wss/utils";
|
import { getPublicIpWithFallback } from "@dokploy/server/wss/utils";
|
||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import * as bcrypt from "bcrypt";
|
import * as bcrypt from "bcrypt";
|
||||||
@@ -17,89 +11,6 @@ import QRCode from "qrcode";
|
|||||||
import { IS_CLOUD } from "../constants";
|
import { IS_CLOUD } from "../constants";
|
||||||
import { findUserById } from "./admin";
|
import { findUserById } from "./admin";
|
||||||
|
|
||||||
export type Auth = typeof auth.$inferSelect;
|
|
||||||
|
|
||||||
export const createAdmin = async (input: typeof apiCreateAdmin._type) => {
|
|
||||||
return await db.transaction(async (tx) => {
|
|
||||||
const hashedPassword = bcrypt.hashSync(input.password, 10);
|
|
||||||
const newAuth = await tx
|
|
||||||
.insert(auth)
|
|
||||||
.values({
|
|
||||||
email: input.email.toLowerCase(),
|
|
||||||
password: hashedPassword,
|
|
||||||
rol: "admin",
|
|
||||||
})
|
|
||||||
.returning()
|
|
||||||
.then((res) => res[0]);
|
|
||||||
|
|
||||||
if (!newAuth) {
|
|
||||||
throw new TRPCError({
|
|
||||||
code: "BAD_REQUEST",
|
|
||||||
message: "Error creating the user",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
await tx
|
|
||||||
.insert(admins)
|
|
||||||
.values({
|
|
||||||
authId: newAuth.id,
|
|
||||||
...(!IS_CLOUD && {
|
|
||||||
serverIp:
|
|
||||||
process.env.ADVERTISE_ADDR || (await getPublicIpWithFallback()),
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
.returning();
|
|
||||||
|
|
||||||
return newAuth;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const createUser = async (input: typeof apiCreateUser._type) => {
|
|
||||||
return await db.transaction(async (tx) => {
|
|
||||||
const hashedPassword = bcrypt.hashSync(input.password, 10);
|
|
||||||
const res = await tx
|
|
||||||
.update(auth)
|
|
||||||
.set({
|
|
||||||
password: hashedPassword,
|
|
||||||
})
|
|
||||||
.where(eq(auth.id, input.id))
|
|
||||||
.returning()
|
|
||||||
.then((res) => res[0]);
|
|
||||||
|
|
||||||
if (!res) {
|
|
||||||
throw new TRPCError({
|
|
||||||
code: "BAD_REQUEST",
|
|
||||||
message: "Error creating the user",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const user = await tx
|
|
||||||
.update(users)
|
|
||||||
.set({
|
|
||||||
isRegistered: true,
|
|
||||||
expirationDate: undefined,
|
|
||||||
})
|
|
||||||
.where(eq(users.token, input.token))
|
|
||||||
.returning()
|
|
||||||
.then((res) => res[0]);
|
|
||||||
|
|
||||||
return user;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const findAuthByEmail = async (email: string) => {
|
|
||||||
const result = await db.query.auth.findFirst({
|
|
||||||
where: eq(auth.email, email),
|
|
||||||
});
|
|
||||||
if (!result) {
|
|
||||||
throw new TRPCError({
|
|
||||||
code: "NOT_FOUND",
|
|
||||||
message: "User not found",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const findAuthById = async (authId: string) => {
|
export const findAuthById = async (authId: string) => {
|
||||||
const result = await db.query.users_temp.findFirst({
|
const result = await db.query.users_temp.findFirst({
|
||||||
where: eq(users_temp.id, authId),
|
where: eq(users_temp.id, authId),
|
||||||
@@ -117,21 +28,6 @@ export const findAuthById = async (authId: string) => {
|
|||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const updateAuthById = async (
|
|
||||||
authId: string,
|
|
||||||
authData: Partial<Auth>,
|
|
||||||
) => {
|
|
||||||
const result = await db
|
|
||||||
.update(auth)
|
|
||||||
.set({
|
|
||||||
...authData,
|
|
||||||
})
|
|
||||||
.where(eq(auth.id, authId))
|
|
||||||
.returning();
|
|
||||||
|
|
||||||
return result[0];
|
|
||||||
};
|
|
||||||
|
|
||||||
export const generate2FASecret = async (userId: string) => {
|
export const generate2FASecret = async (userId: string) => {
|
||||||
const user = await findUserById(userId);
|
const user = await findUserById(userId);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user