mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
feat: adjust roles
This commit is contained in:
@@ -57,7 +57,7 @@ export const ShowProjects = () => {
|
|||||||
authId: auth?.id || "",
|
authId: auth?.id || "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
enabled: !!auth?.id && auth?.role === "user",
|
enabled: !!auth?.id && auth?.role === "member",
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
const { mutateAsync } = api.project.remove.useMutation();
|
const { mutateAsync } = api.project.remove.useMutation();
|
||||||
@@ -91,7 +91,7 @@ export const ShowProjects = () => {
|
|||||||
</CardDescription>
|
</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
|
|
||||||
{(auth?.role === "admin" || user?.canCreateProjects) && (
|
{(auth?.role === "owner" || user?.canCreateProjects) && (
|
||||||
<div className="">
|
<div className="">
|
||||||
<HandleProject />
|
<HandleProject />
|
||||||
</div>
|
</div>
|
||||||
@@ -293,7 +293,7 @@ export const ShowProjects = () => {
|
|||||||
<div
|
<div
|
||||||
onClick={(e) => e.stopPropagation()}
|
onClick={(e) => e.stopPropagation()}
|
||||||
>
|
>
|
||||||
{(auth?.role === "admin" ||
|
{(auth?.role === "owner" ||
|
||||||
user?.canDeleteProjects) && (
|
user?.canDeleteProjects) && (
|
||||||
<AlertDialog>
|
<AlertDialog>
|
||||||
<AlertDialogTrigger className="w-full">
|
<AlertDialogTrigger className="w-full">
|
||||||
|
|||||||
@@ -261,7 +261,6 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { user } = await validateRequest(context.req);
|
const { user } = await validateRequest(context.req);
|
||||||
console.log("Response", user);
|
|
||||||
|
|
||||||
if (user) {
|
if (user) {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
apiVerify2FA,
|
apiVerify2FA,
|
||||||
apiVerifyLogin2FA,
|
apiVerifyLogin2FA,
|
||||||
auth,
|
auth,
|
||||||
|
member,
|
||||||
} from "@/server/db/schema";
|
} from "@/server/db/schema";
|
||||||
import { WEBSITE_URL } from "@/server/utils/stripe";
|
import { WEBSITE_URL } from "@/server/utils/stripe";
|
||||||
import {
|
import {
|
||||||
@@ -32,7 +33,7 @@ import {
|
|||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import * as bcrypt from "bcrypt";
|
import * as bcrypt from "bcrypt";
|
||||||
import { isBefore } from "date-fns";
|
import { isBefore } from "date-fns";
|
||||||
import { eq } from "drizzle-orm";
|
import { and, eq } from "drizzle-orm";
|
||||||
import { nanoid } from "nanoid";
|
import { nanoid } from "nanoid";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { db } from "../../db";
|
import { db } from "../../db";
|
||||||
@@ -170,8 +171,14 @@ export const authRouter = createTRPCRouter({
|
|||||||
}),
|
}),
|
||||||
|
|
||||||
get: protectedProcedure.query(async ({ ctx }) => {
|
get: protectedProcedure.query(async ({ ctx }) => {
|
||||||
const auth = await findAuthById(ctx.user.id);
|
const memberResult = await db.query.member.findFirst({
|
||||||
return auth;
|
where: and(
|
||||||
|
eq(member.userId, ctx.user.id),
|
||||||
|
eq(member.organizationId, ctx.session?.activeOrganizationId || ""),
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
|
return memberResult;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
logout: protectedProcedure.mutation(async ({ ctx }) => {
|
logout: protectedProcedure.mutation(async ({ ctx }) => {
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ import { ZodError } from "zod";
|
|||||||
|
|
||||||
interface CreateContextOptions {
|
interface CreateContextOptions {
|
||||||
user: (User & { rol: "admin" | "user"; ownerId: string }) | null;
|
user: (User & { rol: "admin" | "user"; ownerId: string }) | null;
|
||||||
session: Session | null;
|
session: (Session & { activeOrganizationId: string }) | null;
|
||||||
req: CreateNextContextOptions["req"];
|
req: CreateNextContextOptions["req"];
|
||||||
res: CreateNextContextOptions["res"];
|
res: CreateNextContextOptions["res"];
|
||||||
}
|
}
|
||||||
@@ -75,12 +75,15 @@ export const createTRPCContext = async (opts: CreateNextContextOptions) => {
|
|||||||
user = cookieResult.user;
|
user = cookieResult.user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log("session", { session, user });
|
||||||
|
|
||||||
return createInnerTRPCContext({
|
return createInnerTRPCContext({
|
||||||
req,
|
req,
|
||||||
res,
|
res,
|
||||||
session: session,
|
session: session,
|
||||||
...((user && {
|
...((user && {
|
||||||
user: {
|
user: {
|
||||||
|
...user,
|
||||||
email: user.email,
|
email: user.email,
|
||||||
rol: user.role,
|
rol: user.role,
|
||||||
id: user.id,
|
id: user.id,
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ export const member = pgTable("member", {
|
|||||||
userId: text("user_id")
|
userId: text("user_id")
|
||||||
.notNull()
|
.notNull()
|
||||||
.references(() => users_temp.id),
|
.references(() => users_temp.id),
|
||||||
role: text("role").notNull(),
|
role: text("role").notNull().$type<"owner" | "member" | "admin">(),
|
||||||
createdAt: timestamp("created_at").notNull(),
|
createdAt: timestamp("created_at").notNull(),
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@ export const invitation = pgTable("invitation", {
|
|||||||
.notNull()
|
.notNull()
|
||||||
.references(() => organization.id),
|
.references(() => organization.id),
|
||||||
email: text("email").notNull(),
|
email: text("email").notNull(),
|
||||||
role: text("role"),
|
role: text("role").$type<"owner" | "member" | "admin">(),
|
||||||
status: text("status").notNull(),
|
status: text("status").notNull(),
|
||||||
expiresAt: timestamp("expires_at").notNull(),
|
expiresAt: timestamp("expires_at").notNull(),
|
||||||
inviterId: text("inviter_id")
|
inviterId: text("inviter_id")
|
||||||
|
|||||||
@@ -10,7 +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 { account } from "./account";
|
import { account, organization } from "./account";
|
||||||
import { admins } from "./admin";
|
import { admins } from "./admin";
|
||||||
import { auth } from "./auth";
|
import { auth } from "./auth";
|
||||||
import { certificateType } from "./shared";
|
import { certificateType } from "./shared";
|
||||||
@@ -185,7 +185,7 @@ export const users_temp = pgTable("user_temp", {
|
|||||||
serversQuantity: integer("serversQuantity").notNull().default(0),
|
serversQuantity: integer("serversQuantity").notNull().default(0),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const usersRelations = relations(users_temp, ({ one }) => ({
|
export const usersRelations = relations(users_temp, ({ one, many }) => ({
|
||||||
// auth: one(auth, {
|
// auth: one(auth, {
|
||||||
// fields: [users.authId],
|
// fields: [users.authId],
|
||||||
// references: [auth.id],
|
// references: [auth.id],
|
||||||
@@ -194,6 +194,7 @@ export const usersRelations = relations(users_temp, ({ one }) => ({
|
|||||||
fields: [users_temp.id],
|
fields: [users_temp.id],
|
||||||
references: [account.userId],
|
references: [account.userId],
|
||||||
}),
|
}),
|
||||||
|
organizations: many(organization),
|
||||||
// admin: one(admins, {
|
// admin: one(admins, {
|
||||||
// fields: [users.adminId],
|
// fields: [users.adminId],
|
||||||
// references: [admins.adminId],
|
// references: [admins.adminId],
|
||||||
|
|||||||
@@ -3,85 +3,116 @@ import * as bcrypt from "bcrypt";
|
|||||||
import { betterAuth } from "better-auth";
|
import { betterAuth } from "better-auth";
|
||||||
import { drizzleAdapter } from "better-auth/adapters/drizzle";
|
import { drizzleAdapter } from "better-auth/adapters/drizzle";
|
||||||
import { createAuthMiddleware, organization } from "better-auth/plugins";
|
import { createAuthMiddleware, organization } from "better-auth/plugins";
|
||||||
import { eq } from "drizzle-orm";
|
import { desc, eq } from "drizzle-orm";
|
||||||
import { db } from "../db";
|
import { db } from "../db";
|
||||||
import * as schema from "../db/schema";
|
import * as schema from "../db/schema";
|
||||||
|
|
||||||
export const auth = betterAuth({
|
export const auth = betterAuth({
|
||||||
database: drizzleAdapter(db, {
|
database: drizzleAdapter(db, {
|
||||||
provider: "pg",
|
provider: "pg",
|
||||||
schema: schema,
|
schema: schema,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
emailAndPassword: {
|
emailAndPassword: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
|
|
||||||
password: {
|
password: {
|
||||||
async hash(password) {
|
async hash(password) {
|
||||||
return bcrypt.hashSync(password, 10);
|
return bcrypt.hashSync(password, 10);
|
||||||
},
|
},
|
||||||
async verify({ hash, password }) {
|
async verify({ hash, password }) {
|
||||||
return bcrypt.compareSync(password, hash);
|
return bcrypt.compareSync(password, hash);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
hooks: {
|
hooks: {
|
||||||
after: createAuthMiddleware(async (ctx) => {
|
after: createAuthMiddleware(async (ctx) => {
|
||||||
if (ctx.path.startsWith("/sign-up")) {
|
if (ctx.path.startsWith("/sign-up")) {
|
||||||
const newSession = ctx.context.newSession;
|
const newSession = ctx.context.newSession;
|
||||||
await db
|
const organization = await db
|
||||||
.update(schema.users_temp)
|
.insert(schema.organization)
|
||||||
.set({
|
.values({
|
||||||
role: "admin",
|
name: "My Organization",
|
||||||
})
|
ownerId: newSession?.user?.id || "",
|
||||||
.where(eq(schema.users_temp.id, newSession?.user?.id || ""));
|
createdAt: new Date(),
|
||||||
}
|
})
|
||||||
}),
|
.returning()
|
||||||
},
|
.then((res) => res[0]);
|
||||||
user: {
|
|
||||||
modelName: "users_temp",
|
await db.insert(schema.member).values({
|
||||||
additionalFields: {
|
userId: newSession?.user?.id || "",
|
||||||
role: {
|
organizationId: organization?.id || "",
|
||||||
type: "string",
|
role: "owner",
|
||||||
},
|
createdAt: new Date(),
|
||||||
ownerId: {
|
});
|
||||||
type: "string",
|
}
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
},
|
databaseHooks: {
|
||||||
plugins: [organization()],
|
session: {
|
||||||
|
create: {
|
||||||
|
before: async (session) => {
|
||||||
|
const member = await db.query.member.findFirst({
|
||||||
|
where: eq(schema.member.userId, session.userId),
|
||||||
|
orderBy: desc(schema.member.createdAt),
|
||||||
|
with: {
|
||||||
|
organization: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
data: {
|
||||||
|
...session,
|
||||||
|
activeOrganizationId: member?.organization.id,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
user: {
|
||||||
|
modelName: "users_temp",
|
||||||
|
additionalFields: {
|
||||||
|
role: {
|
||||||
|
type: "string",
|
||||||
|
},
|
||||||
|
ownerId: {
|
||||||
|
type: "string",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
plugins: [organization()],
|
||||||
});
|
});
|
||||||
|
|
||||||
export const validateRequest = async (request: IncomingMessage) => {
|
export const validateRequest = async (request: IncomingMessage) => {
|
||||||
const session = await auth.api.getSession({
|
const session = await auth.api.getSession({
|
||||||
headers: new Headers({
|
headers: new Headers({
|
||||||
cookie: request.headers.cookie || "",
|
cookie: request.headers.cookie || "",
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!session?.session || !session.user) {
|
if (!session?.session || !session.user) {
|
||||||
return {
|
return {
|
||||||
session: null,
|
session: null,
|
||||||
user: null,
|
user: null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session?.user) {
|
if (session?.user) {
|
||||||
if (session?.user.role === "user") {
|
const member = await db.query.member.findFirst({
|
||||||
const owner = await db.query.member.findFirst({
|
where: eq(schema.member.userId, session.user.id),
|
||||||
where: eq(schema.member.userId, session.user.id),
|
with: {
|
||||||
with: {
|
organization: true,
|
||||||
organization: true,
|
},
|
||||||
},
|
});
|
||||||
});
|
|
||||||
|
|
||||||
if (owner) {
|
session.user.role = member?.role || "member";
|
||||||
session.user.ownerId = owner.organization.ownerId;
|
if (member) {
|
||||||
}
|
session.user.ownerId = member.organization.ownerId;
|
||||||
} else {
|
} else {
|
||||||
session.user.ownerId = session?.user?.id || "";
|
session.user.ownerId = session.user.id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return session;
|
return session;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
import { randomBytes } from "node:crypto";
|
import { randomBytes } from "node:crypto";
|
||||||
import { db } from "@dokploy/server/db";
|
import { db } from "@dokploy/server/db";
|
||||||
import {
|
import {
|
||||||
admins,
|
account,
|
||||||
type apiCreateUserInvitation,
|
admins,
|
||||||
auth,
|
type apiCreateUserInvitation,
|
||||||
users_temp,
|
auth,
|
||||||
|
member,
|
||||||
|
organization,
|
||||||
|
users_temp,
|
||||||
} from "@dokploy/server/db/schema";
|
} from "@dokploy/server/db/schema";
|
||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import * as bcrypt from "bcrypt";
|
import * as bcrypt from "bcrypt";
|
||||||
@@ -13,188 +16,190 @@ import { IS_CLOUD } from "../constants";
|
|||||||
|
|
||||||
export type Admin = typeof users_temp.$inferSelect;
|
export type Admin = typeof users_temp.$inferSelect;
|
||||||
export const createInvitation = async (
|
export const createInvitation = async (
|
||||||
input: typeof apiCreateUserInvitation._type,
|
input: typeof apiCreateUserInvitation._type,
|
||||||
adminId: string
|
adminId: string,
|
||||||
) => {
|
) => {
|
||||||
await db.transaction(async (tx) => {
|
await db.transaction(async (tx) => {
|
||||||
const result = await tx
|
const result = await tx
|
||||||
.insert(auth)
|
.insert(auth)
|
||||||
.values({
|
.values({
|
||||||
email: input.email.toLowerCase(),
|
email: input.email.toLowerCase(),
|
||||||
rol: "user",
|
rol: "user",
|
||||||
password: bcrypt.hashSync("01231203012312", 10),
|
password: bcrypt.hashSync("01231203012312", 10),
|
||||||
})
|
})
|
||||||
.returning()
|
.returning()
|
||||||
.then((res) => res[0]);
|
.then((res) => res[0]);
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "BAD_REQUEST",
|
code: "BAD_REQUEST",
|
||||||
message: "Error creating the user",
|
message: "Error creating the user",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const expiresIn24Hours = new Date();
|
const expiresIn24Hours = new Date();
|
||||||
expiresIn24Hours.setDate(expiresIn24Hours.getDate() + 1);
|
expiresIn24Hours.setDate(expiresIn24Hours.getDate() + 1);
|
||||||
const token = randomBytes(32).toString("hex");
|
const token = randomBytes(32).toString("hex");
|
||||||
await tx
|
// await tx
|
||||||
.insert(users)
|
// .insert(users)
|
||||||
.values({
|
// .values({
|
||||||
adminId: adminId,
|
// adminId: adminId,
|
||||||
authId: result.id,
|
// authId: result.id,
|
||||||
token,
|
// token,
|
||||||
expirationDate: expiresIn24Hours.toISOString(),
|
// expirationDate: expiresIn24Hours.toISOString(),
|
||||||
})
|
// })
|
||||||
.returning();
|
// .returning();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const findUserById = async (userId: string) => {
|
export const findUserById = async (userId: string) => {
|
||||||
const user = await db.query.users_temp.findFirst({
|
const user = await db.query.users_temp.findFirst({
|
||||||
where: eq(users_temp.id, userId),
|
where: eq(users_temp.id, userId),
|
||||||
// with: {
|
// with: {
|
||||||
// account: true,
|
// account: true,
|
||||||
// },
|
// },
|
||||||
});
|
});
|
||||||
if (!user) {
|
if (!user) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "NOT_FOUND",
|
code: "NOT_FOUND",
|
||||||
message: "User not found",
|
message: "User not found",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return user;
|
return user;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const updateUser = async (userId: string, userData: Partial<Admin>) => {
|
export const updateUser = async (userId: string, userData: Partial<Admin>) => {
|
||||||
const user = await db
|
const user = await db
|
||||||
.update(users_temp)
|
.update(users_temp)
|
||||||
.set({
|
.set({
|
||||||
...userData,
|
...userData,
|
||||||
})
|
})
|
||||||
.where(eq(users_temp.id, userId))
|
.where(eq(users_temp.id, userId))
|
||||||
.returning()
|
.returning()
|
||||||
.then((res) => res[0]);
|
.then((res) => res[0]);
|
||||||
|
|
||||||
return user;
|
return user;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const updateAdminById = async (
|
export const updateAdminById = async (
|
||||||
adminId: string,
|
adminId: string,
|
||||||
adminData: Partial<Admin>
|
adminData: Partial<Admin>,
|
||||||
) => {
|
) => {
|
||||||
const admin = await db
|
// const admin = await db
|
||||||
.update(admins)
|
// .update(admins)
|
||||||
.set({
|
// .set({
|
||||||
...adminData,
|
// ...adminData,
|
||||||
})
|
// })
|
||||||
.where(eq(admins.adminId, adminId))
|
// .where(eq(admins.adminId, adminId))
|
||||||
.returning()
|
// .returning()
|
||||||
.then((res) => res[0]);
|
// .then((res) => res[0]);
|
||||||
|
// return admin;
|
||||||
return admin;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const findAdminById = async (userId: string) => {
|
export const findAdminById = async (userId: string) => {
|
||||||
const admin = await db.query.admins.findFirst({
|
const admin = await db.query.admins.findFirst({
|
||||||
where: eq(admins.userId, userId),
|
// where: eq(admins.userId, userId),
|
||||||
});
|
});
|
||||||
return admin;
|
return admin;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const isAdminPresent = async () => {
|
export const isAdminPresent = async () => {
|
||||||
const admin = await db.query.users_temp.findFirst({
|
const admin = await db.query.member.findFirst({
|
||||||
where: eq(users_temp.role, "admin"),
|
where: eq(member.role, "owner"),
|
||||||
});
|
});
|
||||||
if (!admin) {
|
|
||||||
return false;
|
console.log("admin", admin);
|
||||||
}
|
|
||||||
return true;
|
if (!admin) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const findAdminByAuthId = async (authId: string) => {
|
export const findAdminByAuthId = async (authId: string) => {
|
||||||
const admin = await db.query.admins.findFirst({
|
const admin = await db.query.admins.findFirst({
|
||||||
where: eq(admins.authId, authId),
|
where: eq(admins.authId, authId),
|
||||||
with: {
|
with: {
|
||||||
users: true,
|
users: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
if (!admin) {
|
if (!admin) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "NOT_FOUND",
|
code: "NOT_FOUND",
|
||||||
message: "Admin not found",
|
message: "Admin not found",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return admin;
|
return admin;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const findAdmin = async () => {
|
export const findAdmin = async () => {
|
||||||
const admin = await db.query.admins.findFirst({});
|
const admin = await db.query.admins.findFirst({});
|
||||||
if (!admin) {
|
if (!admin) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "NOT_FOUND",
|
code: "NOT_FOUND",
|
||||||
message: "Admin not found",
|
message: "Admin not found",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return admin;
|
return admin;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getUserByToken = async (token: string) => {
|
export const getUserByToken = async (token: string) => {
|
||||||
const user = await db.query.users.findFirst({
|
const user = await db.query.users.findFirst({
|
||||||
where: eq(users.token, token),
|
where: eq(users.token, token),
|
||||||
with: {
|
with: {
|
||||||
auth: {
|
auth: {
|
||||||
columns: {
|
columns: {
|
||||||
password: false,
|
password: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!user) {
|
if (!user) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "NOT_FOUND",
|
code: "NOT_FOUND",
|
||||||
message: "Invitation not found",
|
message: "Invitation not found",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
...user,
|
...user,
|
||||||
isExpired: user.isRegistered,
|
isExpired: user.isRegistered,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const removeUserById = async (userId: string) => {
|
export const removeUserById = async (userId: string) => {
|
||||||
await db
|
await db
|
||||||
.delete(users_temp)
|
.delete(users_temp)
|
||||||
.where(eq(users_temp.id, userId))
|
.where(eq(users_temp.id, userId))
|
||||||
.returning()
|
.returning()
|
||||||
.then((res) => res[0]);
|
.then((res) => res[0]);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const removeAdminByAuthId = async (authId: string) => {
|
export const removeAdminByAuthId = async (authId: string) => {
|
||||||
const admin = await findAdminByAuthId(authId);
|
const admin = await findAdminByAuthId(authId);
|
||||||
if (!admin) return null;
|
if (!admin) return null;
|
||||||
|
|
||||||
// First delete all associated users
|
// First delete all associated users
|
||||||
const users = admin.users;
|
const users = admin.users;
|
||||||
|
|
||||||
for (const user of users) {
|
for (const user of users) {
|
||||||
await removeUserById(user.id);
|
await removeUserById(user.id);
|
||||||
}
|
}
|
||||||
// Then delete the auth record which will cascade delete the admin
|
// Then delete the auth record which will cascade delete the admin
|
||||||
return await db
|
return await db
|
||||||
.delete(auth)
|
.delete(auth)
|
||||||
.where(eq(auth.id, authId))
|
.where(eq(auth.id, authId))
|
||||||
.returning()
|
.returning()
|
||||||
.then((res) => res[0]);
|
.then((res) => res[0]);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getDokployUrl = async () => {
|
export const getDokployUrl = async () => {
|
||||||
if (IS_CLOUD) {
|
if (IS_CLOUD) {
|
||||||
return "https://app.dokploy.com";
|
return "https://app.dokploy.com";
|
||||||
}
|
}
|
||||||
const admin = await findAdmin();
|
const admin = await findAdmin();
|
||||||
|
|
||||||
if (admin.host) {
|
if (admin.host) {
|
||||||
return `https://${admin.host}`;
|
return `https://${admin.host}`;
|
||||||
}
|
}
|
||||||
return `http://${admin.serverIp}:${process.env.PORT}`;
|
return `http://${admin.serverIp}:${process.env.PORT}`;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user