refactor: remove old references

This commit is contained in:
Mauricio Siu
2025-02-16 13:55:27 -06:00
parent a8d1471b16
commit 9856502ece
30 changed files with 250 additions and 819 deletions

View File

@@ -45,7 +45,7 @@ const baseApp: ApplicationNested = {
previewWildcard: "", previewWildcard: "",
project: { project: {
env: "", env: "",
adminId: "", organizationId: "",
name: "", name: "",
description: "", description: "",
createdAt: "", createdAt: "",

View File

@@ -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,

View File

@@ -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";

View File

@@ -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>

View File

@@ -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,
}); });

View File

@@ -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,
}); });

View File

@@ -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,
}); });

View File

@@ -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,
}); });

View File

@@ -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,
}); });

View File

@@ -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,
}); });

View File

@@ -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,
}); });

View File

@@ -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 }) => {

View File

@@ -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, {

View File

@@ -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(),
});

View File

@@ -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();

View File

@@ -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", {

View File

@@ -1,4 +1,4 @@
import { is, relations } from "drizzle-orm"; import { relations } from "drizzle-orm";
import { import {
type AnyPgColumn, type AnyPgColumn,
boolean, boolean,

View File

@@ -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],
// }),
}), }),
); );

View File

@@ -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",

View File

@@ -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";

View File

@@ -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",

View File

@@ -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")

View File

@@ -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),
})); }));

View File

@@ -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],

View File

@@ -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(),
});

View File

@@ -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,
});

View File

@@ -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")

View File

@@ -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(),
});

View File

@@ -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,

View File

@@ -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);