From d84099108adb3c3180fd9deb7e653cbebcc6bee2 Mon Sep 17 00:00:00 2001 From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com> Date: Sun, 13 Jul 2025 14:00:26 -0600 Subject: [PATCH] refactor: simplify role management by removing unused role schema and related logic; update user role checks in context and procedures --- .../server/api/routers/organization.ts | 10 +- apps/dokploy/server/api/routers/role.ts | 155 +++++++------- apps/dokploy/server/api/trpc.ts | 20 +- packages/server/src/db/schema/account.ts | 14 +- packages/server/src/db/schema/index.ts | 2 +- packages/server/src/db/schema/rbac.ts | 104 +++++----- packages/server/src/lib/auth.ts | 108 ++-------- packages/server/src/lib/permissions.ts | 56 +++++ packages/server/src/services/admin.ts | 13 +- packages/server/src/services/role.ts | 196 +++++++++--------- 10 files changed, 305 insertions(+), 373 deletions(-) diff --git a/apps/dokploy/server/api/routers/organization.ts b/apps/dokploy/server/api/routers/organization.ts index 502562e3a..3cbdca32d 100644 --- a/apps/dokploy/server/api/routers/organization.ts +++ b/apps/dokploy/server/api/routers/organization.ts @@ -1,6 +1,6 @@ import { db } from "@/server/db"; -import { invitation, member, organization, role } from "@/server/db/schema"; -import { createDefaultRoles, IS_CLOUD } from "@dokploy/server/index"; +import { invitation, member, organization } from "@/server/db/schema"; +import { IS_CLOUD } from "@dokploy/server/index"; import { TRPCError } from "@trpc/server"; import { and, desc, eq, exists } from "drizzle-orm"; import { nanoid } from "nanoid"; @@ -38,18 +38,12 @@ export const organizationRouter = createTRPCRouter({ message: "Failed to create organization", }); } - await createDefaultRoles(result.id); - - const ownerRole = await db.query.role.findFirst({ - where: and(eq(role.name, "owner"), eq(role.organizationId, result.id)), - }); await db.insert(member).values({ organizationId: result.id, role: "owner", createdAt: new Date(), userId: ctx.user.id, - roleId: ownerRole?.roleId || "", }); return result; }), diff --git a/apps/dokploy/server/api/routers/role.ts b/apps/dokploy/server/api/routers/role.ts index 841c18346..f7dc095dc 100644 --- a/apps/dokploy/server/api/routers/role.ts +++ b/apps/dokploy/server/api/routers/role.ts @@ -1,86 +1,75 @@ -import { createTRPCRouter, protectedProcedure } from "@/server/api/trpc"; -import { db } from "@/server/db"; -import { - apiFindOneRole, - createRoleSchema, - role, - updateRoleSchema, -} from "@/server/db/schema"; -import { createRole, removeRoleById, updateRoleById } from "@dokploy/server"; -import { defaultPermissions } from "@dokploy/server/lib/permissions"; -import { TRPCError } from "@trpc/server"; -import { and, asc, eq } from "drizzle-orm"; +import { createTRPCRouter } from "@/server/api/trpc"; +// import { createRole, removeRoleById, updateRoleById } from "@dokploy/server"; +// import { defaultPermissions } from "@dokploy/server/lib/permissions"; export const roleRouter = createTRPCRouter({ - all: protectedProcedure.query(async ({ ctx }) => { - const roles = await db.query.role.findMany({ - where: and( - eq(role.organizationId, ctx.session.activeOrganizationId), - eq(role.isSystem, false), - ), - orderBy: [asc(role.createdAt)], - }); - return roles; - }), - delete: protectedProcedure - .input(apiFindOneRole) - .mutation(async ({ input }) => { - try { - return removeRoleById(input.roleId); - } catch (error) { - const message = - error instanceof Error ? error.message : "Error input: Deleting role"; - throw new TRPCError({ - code: "BAD_REQUEST", - message, - }); - } - }), - create: protectedProcedure - .input(createRoleSchema) - .mutation(async ({ input, ctx }) => { - try { - return await createRole( - { - ...input, - }, - ctx.session.activeOrganizationId, - ); - } catch (error) { - console.error(error); - throw new TRPCError({ - code: "BAD_REQUEST", - message: "Error input: Creating role", - cause: error, - }); - } - }), - update: protectedProcedure - .input(updateRoleSchema) - .mutation(async ({ input }) => { - return await updateRoleById(input.roleId, input); - }), - getDefaultRoles: protectedProcedure.query(async ({ ctx }) => { - const roles = await db.query.role.findMany({ - where: and( - eq(role.organizationId, ctx.session.activeOrganizationId), - eq(role.isSystem, true), - ), - }); - // add the description from the constants roles to the roles - const rolesWithDescription = defaultPermissions.map((role) => { - const roleInfo = roles.find((r) => r.name === role.name); - return { - ...roleInfo, - ...role, - }; - }); - - const set = new Set(rolesWithDescription.flatMap((r) => r.permissions)); - - return { - roles: rolesWithDescription, - permissions: Array.from(set), - }; - }), + // all: protectedProcedure.query(async ({ ctx }) => { + // const roles = await db.query.role.findMany({ + // where: and( + // eq(role.organizationId, ctx.session.activeOrganizationId), + // eq(role.isSystem, false), + // ), + // orderBy: [asc(role.createdAt)], + // }); + // return roles; + // }), + // delete: protectedProcedure + // .input(apiFindOneRole) + // .mutation(async ({ input }) => { + // try { + // return removeRoleById(input.roleId); + // } catch (error) { + // const message = + // error instanceof Error ? error.message : "Error input: Deleting role"; + // throw new TRPCError({ + // code: "BAD_REQUEST", + // message, + // }); + // } + // }), + // create: protectedProcedure + // .input(createRoleSchema) + // .mutation(async ({ input, ctx }) => { + // try { + // return await createRole( + // { + // ...input, + // }, + // ctx.session.activeOrganizationId, + // ); + // } catch (error) { + // console.error(error); + // throw new TRPCError({ + // code: "BAD_REQUEST", + // message: "Error input: Creating role", + // cause: error, + // }); + // } + // }), + // update: protectedProcedure + // .input(updateRoleSchema) + // .mutation(async ({ input }) => { + // return await updateRoleById(input.roleId, input); + // }), + // getDefaultRoles: protectedProcedure.query(async ({ ctx }) => { + // const roles = await db.query.role.findMany({ + // where: and( + // eq(role.organizationId, ctx.session.activeOrganizationId), + // eq(role.isSystem, true), + // ), + // }); + // // add the description from the constants roles to the roles + // const rolesWithDescription = defaultPermissions.map((role) => { + // const roleInfo = roles.find((r) => r.name === role.name); + // return { + // ...roleInfo, + // ...role, + // }; + // }); + // const set = new Set(rolesWithDescription.flatMap((r) => r.permissions)); + // return { + // roles: rolesWithDescription, + // permissions: Array.from(set), + // }; + // }), }); diff --git a/apps/dokploy/server/api/trpc.ts b/apps/dokploy/server/api/trpc.ts index fa7e740b8..afd620540 100644 --- a/apps/dokploy/server/api/trpc.ts +++ b/apps/dokploy/server/api/trpc.ts @@ -30,17 +30,7 @@ import { ZodError } from "zod"; */ interface CreateContextOptions { - user: - | (User & { - role: { - roleId: string; - name: string; - permissions: string[]; - isSystem: boolean; - }; - ownerId: string; - }) - | null; + user: (User & { role: "member" | "admin" | "owner"; ownerId: string }) | null; session: | (Session & { activeOrganizationId: string; impersonatedBy?: string }) | null; @@ -192,7 +182,7 @@ export const uploadProcedure = async (opts: any) => { }; export const cliProcedure = t.procedure.use(({ ctx, next }) => { - if (!ctx.session || !ctx.user || ctx.user.role.name !== "owner") { + if (!ctx.session || !ctx.user || ctx.user.role !== "owner") { throw new TRPCError({ code: "UNAUTHORIZED" }); } return next({ @@ -206,11 +196,7 @@ export const cliProcedure = t.procedure.use(({ ctx, next }) => { }); export const adminProcedure = t.procedure.use(({ ctx, next }) => { - if ( - !ctx.session || - !ctx.user || - (ctx.user.role.name !== "owner" && ctx.user.role.name !== "admin") - ) { + if (!ctx.session || !ctx.user || ctx.user.role !== "owner") { throw new TRPCError({ code: "UNAUTHORIZED" }); } return next({ diff --git a/packages/server/src/db/schema/account.ts b/packages/server/src/db/schema/account.ts index e0e4066dd..c61583f71 100644 --- a/packages/server/src/db/schema/account.ts +++ b/packages/server/src/db/schema/account.ts @@ -10,7 +10,7 @@ import { nanoid } from "nanoid"; import { projects } from "./project"; import { server } from "./server"; import { users } from "./user"; -import { role } from "./rbac"; +// import { role } from "./rbac"; export const account = pgTable("account", { id: text("id") @@ -92,8 +92,8 @@ export const member = pgTable("member", { userId: text("user_id") .notNull() .references(() => users.id, { onDelete: "cascade" }), - role: text("role"), - roleId: text("roleId").references(() => role.roleId, { onDelete: "cascade" }), + role: text("role").$type<"owner" | "member" | "admin">(), + // roleId: text("roleId").references(() => role.roleId, { onDelete: "cascade" }), createdAt: timestamp("created_at").notNull(), teamId: text("team_id"), // Permissions @@ -116,10 +116,10 @@ export const memberRelations = relations(member, ({ one }) => ({ fields: [member.userId], references: [users.id], }), - role: one(role, { - fields: [member.roleId], - references: [role.roleId], - }), + // role: one(role, { + // fields: [member.roleId], + // references: [role.roleId], + // }), })); export const invitation = pgTable("invitation", { diff --git a/packages/server/src/db/schema/index.ts b/packages/server/src/db/schema/index.ts index 3694e6db8..1a19c3f6e 100644 --- a/packages/server/src/db/schema/index.ts +++ b/packages/server/src/db/schema/index.ts @@ -30,7 +30,7 @@ export * from "./server"; export * from "./utils"; export * from "./preview-deployments"; export * from "./ai"; -export * from "./rbac"; +// export * from "./rbac"; export * from "./account"; export * from "./schedule"; export * from "./rollbacks"; diff --git a/packages/server/src/db/schema/rbac.ts b/packages/server/src/db/schema/rbac.ts index 0ff2fbbc9..df6ba662a 100644 --- a/packages/server/src/db/schema/rbac.ts +++ b/packages/server/src/db/schema/rbac.ts @@ -1,58 +1,58 @@ -import { relations } from "drizzle-orm"; -import { pgTable, text, timestamp, boolean, unique } from "drizzle-orm/pg-core"; -import { nanoid } from "nanoid"; -import { organization, member } from "./account"; -import { createInsertSchema } from "drizzle-zod"; -import { z } from "zod"; +// import { relations } from "drizzle-orm"; +// import { pgTable, text, timestamp, boolean, unique } from "drizzle-orm/pg-core"; +// import { nanoid } from "nanoid"; +// import { organization, member } from "./account"; +// import { createInsertSchema } from "drizzle-zod"; +// import { z } from "zod"; -export const role = pgTable( - "member_role", - { - roleId: text("roleId") - .primaryKey() - .$defaultFn(() => nanoid()), - name: text("name").notNull().unique(), - description: text("description"), - canDelete: boolean("canDelete").notNull().default(true), - isSystem: boolean("is_system").default(false), - permissions: text("permissions").array(), - createdAt: timestamp("created_at").notNull().defaultNow(), - updatedAt: timestamp("updated_at").notNull().defaultNow(), - organizationId: text("organizationId") - .notNull() - .references(() => organization.id, { onDelete: "cascade" }), - }, - (table) => ({ - roleName: unique("role_name_unique").on(table.name, table.organizationId), - }), -); +// export const role = pgTable( +// "member_role", +// { +// roleId: text("roleId") +// .primaryKey() +// .$defaultFn(() => nanoid()), +// name: text("name").notNull().unique(), +// description: text("description"), +// canDelete: boolean("canDelete").notNull().default(true), +// isSystem: boolean("is_system").default(false), +// permissions: text("permissions").array(), +// createdAt: timestamp("created_at").notNull().defaultNow(), +// updatedAt: timestamp("updated_at").notNull().defaultNow(), +// organizationId: text("organizationId") +// .notNull() +// .references(() => organization.id, { onDelete: "cascade" }), +// }, +// (table) => ({ +// roleName: unique("role_name_unique").on(table.name, table.organizationId), +// }), +// ); -export const roleRelations = relations(role, ({ one, many }) => ({ - organization: one(organization, { - fields: [role.organizationId], - references: [organization.id], - }), - members: many(member), -})); +// export const roleRelations = relations(role, ({ one, many }) => ({ +// organization: one(organization, { +// fields: [role.organizationId], +// references: [organization.id], +// }), +// members: many(member), +// })); -export type Role = typeof role.$inferSelect; +// export type Role = typeof role.$inferSelect; -export const createRoleSchema = createInsertSchema(role) - .omit({ - roleId: true, - createdAt: true, - updatedAt: true, - isSystem: true, - organizationId: true, - }) - .extend({ - permissions: z.array(z.string()), - }); +// export const createRoleSchema = createInsertSchema(role) +// .omit({ +// roleId: true, +// createdAt: true, +// updatedAt: true, +// isSystem: true, +// organizationId: true, +// }) +// .extend({ +// permissions: z.array(z.string()), +// }); -export const updateRoleSchema = createRoleSchema.extend({ - roleId: z.string().min(1), -}); +// export const updateRoleSchema = createRoleSchema.extend({ +// roleId: z.string().min(1), +// }); -export const apiFindOneRole = z.object({ - roleId: z.string().min(1), -}); +// export const apiFindOneRole = z.object({ +// roleId: z.string().min(1), +// }); diff --git a/packages/server/src/lib/auth.ts b/packages/server/src/lib/auth.ts index 276a816e0..bca218835 100644 --- a/packages/server/src/lib/auth.ts +++ b/packages/server/src/lib/auth.ts @@ -2,7 +2,7 @@ import type { IncomingMessage } from "node:http"; import * as bcrypt from "bcrypt"; import { betterAuth } from "better-auth"; import { drizzleAdapter } from "better-auth/adapters/drizzle"; -import { APIError, createAuthMiddleware } from "better-auth/api"; +import { APIError } from "better-auth/api"; import { admin, apiKey, organization, twoFactor } from "better-auth/plugins"; import { and, desc, eq } from "drizzle-orm"; import { IS_CLOUD } from "../constants"; @@ -11,12 +11,7 @@ import * as schema from "../db/schema"; import { getUserByToken } from "../services/admin"; import { sendEmail } from "../verification/send-verification-email"; import { getPublicIpWithFallback } from "../wss/utils"; -import { createDefaultRoles } from "../services/role"; -import { - findWebServer, - updateWebServer, -} from "@dokploy/server/services/web-server"; -import type { Role } from "../db/schema/rbac"; +import { findWebServer, updateWebServer } from "../services/web-server"; const { handler, api } = betterAuth({ database: drizzleAdapter(db, { @@ -84,48 +79,6 @@ const { handler, api } = betterAuth({ }); }, }, - hooks: { - after: createAuthMiddleware(async (ctx) => { - if (ctx.path === "/organization/accept-invitation") { - const invitationId = ctx.body.invitationId; - - if (invitationId) { - const user = await getUserByToken(invitationId); - if (!user) { - throw new APIError("BAD_REQUEST", { - message: "User not found", - }); - } - - const role = await db.query.role.findFirst({ - where: and( - eq(schema.role.name, user.role || "member"), - eq(schema.role.organizationId, user.organizationId), - ), - }); - - const userTemp = await db.query.users.findFirst({ - where: eq(schema.users.email, user.email), - }); - - const member = await db.query.member.findFirst({ - where: and( - eq(schema.member.userId, userTemp?.id || ""), - eq(schema.member.organizationId, user.organizationId), - ), - }); - - await db - .update(schema.member) - .set({ - roleId: role?.roleId || "", - }) - .where(eq(schema.member.userId, member?.userId || "")) - .returning(); - } - } - }), - }, databaseHooks: { user: { create: { @@ -135,25 +88,14 @@ const { handler, api } = betterAuth({ context?.request?.headers?.get("x-dokploy-token"); if (xDokployToken) { const user = await getUserByToken(xDokployToken); - if (!user) { throw new APIError("BAD_REQUEST", { message: "User not found", }); } } else { - const ownerRole = await db.query.role.findFirst({ - where: and(eq(schema.role.name, "owner")), - }); - - if (!ownerRole) { - throw new APIError("BAD_REQUEST", { - message: "Owner role not found", - }); - } - const isAdminPresent = await db.query.member.findFirst({ - where: and(eq(schema.member.roleId, ownerRole.roleId)), + where: eq(schema.member.role, "owner"), }); if (isAdminPresent) { throw new APIError("BAD_REQUEST", { @@ -164,11 +106,8 @@ const { handler, api } = betterAuth({ } }, after: async (user) => { - const ownerRole = await db.query.role.findFirst({ - where: and(eq(schema.role.name, "owner")), - }); const isAdminPresent = await db.query.member.findFirst({ - where: and(eq(schema.member.roleId, ownerRole?.roleId || "")), + where: eq(schema.member.role, "owner"), }); if (!IS_CLOUD) { @@ -189,20 +128,11 @@ const { handler, api } = betterAuth({ .returning() .then((res) => res[0]); - await createDefaultRoles(organization?.id || ""); - - const ownerRole = await tx.query.role.findFirst({ - where: and( - eq(schema.role.name, "owner"), - eq(schema.role.organizationId, organization?.id || ""), - ), - }); - await tx.insert(schema.member).values({ userId: user.id, organizationId: organization?.id || "", + role: "owner", createdAt: new Date(), - roleId: ownerRole?.roleId || "", }); }); } @@ -216,7 +146,6 @@ const { handler, api } = betterAuth({ where: eq(schema.member.userId, session.userId), orderBy: desc(schema.member.createdAt), with: { - role: true, organization: true, }, }); @@ -225,7 +154,6 @@ const { handler, api } = betterAuth({ data: { ...session, activeOrganizationId: member?.organization.id, - roleId: member?.roleId, }, }; }, @@ -237,9 +165,9 @@ const { handler, api } = betterAuth({ updateAge: 60 * 60 * 24, }, user: { - modelName: "users", + modelName: "users_temp", additionalFields: { - roleId: { + role: { type: "string", // required: true, input: false, @@ -293,7 +221,6 @@ const { handler, api } = betterAuth({ export const auth = { handler, createApiKey: api.createApiKey, - createInvitation: api.createInvitation, }; export const validateRequest = async (request: IncomingMessage) => { @@ -348,7 +275,6 @@ export const validateRequest = async (request: IncomingMessage) => { ), with: { organization: true, - role: true, }, }); @@ -381,7 +307,7 @@ export const validateRequest = async (request: IncomingMessage) => { createdAt, updatedAt, twoFactorEnabled, - role: member?.role, + role: member?.role || "member", ownerId: member?.organization.ownerId || apiKeyRecord.user.id, }, }; @@ -410,7 +336,6 @@ export const validateRequest = async (request: IncomingMessage) => { }; } - let role: Role | null = null; if (session?.user) { const member = await db.query.member.findFirst({ where: and( @@ -421,26 +346,17 @@ export const validateRequest = async (request: IncomingMessage) => { ), ), with: { - role: true, organization: true, }, }); - role = member?.role || null; + + session.user.role = member?.role || "member"; if (member) { session.user.ownerId = member.organization.ownerId; } else { session.user.ownerId = session.user.id; } } - const mockSession = { - session: { - ...session.session, - }, - user: { - ...session.user, - role, - ownerId: session.user.ownerId, - }, - }; - return mockSession; + + return session; }; diff --git a/packages/server/src/lib/permissions.ts b/packages/server/src/lib/permissions.ts index 49a3da974..80ce40fd9 100644 --- a/packages/server/src/lib/permissions.ts +++ b/packages/server/src/lib/permissions.ts @@ -1,3 +1,59 @@ +import { + defaultStatements, + memberAc, + ownerAc, + adminAc, +} from "better-auth/plugins/organization/access"; +import { createAccessControl } from "better-auth/plugins/access"; + +/** + * make sure to use `as const` so typescript can infer the type correctly + */ +const statement = { + ...defaultStatements, + project: ["view", "create", "delete"], + service: ["view", "create", "delete"], + traefik_files: ["access"], + docker: ["access"], + api: ["access"], + schedules: ["access"], + git_providers: ["access"], + ssh_keys: ["access"], +} as const; + +export const ac = createAccessControl(statement); + +export const owner = ac.newRole({ + ...ownerAc.statements, + // inherit all the statements from the statements object + project: ["create", "view", "delete"], + service: ["create", "view", "delete"], + traefik_files: ["access"], + docker: ["access"], + api: ["access"], + schedules: ["access"], + git_providers: ["access"], + ssh_keys: ["access"], +}); + +export const admin = ac.newRole({ + ...adminAc.statements, + project: ["create", "view", "delete"], + service: ["create", "view", "delete"], + traefik_files: ["access"], + docker: ["access"], + api: ["access"], + schedules: ["access"], + git_providers: ["access"], + ssh_keys: ["access"], +}); + +export const member = ac.newRole({ + ...memberAc.statements, + project: ["create", "view", "delete"], + service: ["create", "view", "delete"], +}); + export const PERMISSIONS = { PROJECT: { VIEW: { diff --git a/packages/server/src/services/admin.ts b/packages/server/src/services/admin.ts index 59977e8f2..b7e2ec440 100644 --- a/packages/server/src/services/admin.ts +++ b/packages/server/src/services/admin.ts @@ -3,7 +3,6 @@ import { invitation, member, organization, - role, users, } from "@dokploy/server/db/schema"; import { TRPCError } from "@trpc/server"; @@ -35,12 +34,8 @@ export const findOrganizationById = async (organizationId: string) => { }; export const isAdminPresent = async () => { - const ownerRole = await db.query.role.findFirst({ - where: eq(role.name, "owner"), - }); - const admin = await db.query.member.findFirst({ - where: eq(member.roleId, ownerRole?.roleId || ""), + where: eq(member.role, "owner"), }); if (!admin) { @@ -50,12 +45,8 @@ export const isAdminPresent = async () => { }; export const findOwner = async () => { - const ownerRole = await db.query.role.findFirst({ - where: eq(role.name, "owner"), - }); - const owner = await db.query.member.findFirst({ - where: eq(member.roleId, ownerRole?.roleId || ""), + where: eq(member.role, "owner"), with: { user: true, }, diff --git a/packages/server/src/services/role.ts b/packages/server/src/services/role.ts index c13f523e7..72f3fc63a 100644 --- a/packages/server/src/services/role.ts +++ b/packages/server/src/services/role.ts @@ -1,119 +1,119 @@ -import { eq } from "drizzle-orm"; -import { db } from "../db"; -import { - type createRoleSchema, - member, - role, - type updateRoleSchema, -} from "../db/schema"; -import type { z } from "zod"; -import { - adminPermissions, - memberPermissions, - ownerPermissions, -} from "../lib/permissions"; +// import { eq } from "drizzle-orm"; +// import { db } from "../db"; +// import { +// type createRoleSchema, +// member, +// role, +// type updateRoleSchema, +// } from "../db/schema"; +// import type { z } from "zod"; +// import { +// adminPermissions, +// memberPermissions, +// ownerPermissions, +// } from "../lib/permissions"; -export const createRole = async ( - input: z.infer, - organizationId: string, -) => { - await db.transaction(async (tx) => { - const { ...other } = input; - const newRole = await tx - .insert(role) - .values({ ...other, organizationId }) - .returning() - .then((res) => res[0]); +// export const createRole = async ( +// input: z.infer, +// organizationId: string, +// ) => { +// await db.transaction(async (tx) => { +// const { ...other } = input; +// const newRole = await tx +// .insert(role) +// .values({ ...other, organizationId }) +// .returning() +// .then((res) => res[0]); - if (!newRole) { - throw new Error("Failed to create role"); - } +// if (!newRole) { +// throw new Error("Failed to create role"); +// } - return role; - }); -}; +// return role; +// }); +// }; -const findRoleById = async (roleId: string) => { - const result = await db.query.role.findFirst({ - where: eq(role.roleId, roleId), - }); +// const findRoleById = async (roleId: string) => { +// const result = await db.query.role.findFirst({ +// where: eq(role.roleId, roleId), +// }); - if (!result) { - throw new Error("Role not found"); - } +// if (!result) { +// throw new Error("Role not found"); +// } - return result; -}; +// return result; +// }; -export const removeRoleById = async (roleId: string) => { - const currentRole = await findRoleById(roleId); +// export const removeRoleById = async (roleId: string) => { +// const currentRole = await findRoleById(roleId); - if (!currentRole) { - throw new Error("Role not found"); - } +// if (!currentRole) { +// throw new Error("Role not found"); +// } - if (currentRole.isSystem) { - throw new Error("Cannot delete system role"); - } +// if (currentRole.isSystem) { +// throw new Error("Cannot delete system role"); +// } - const members = await db.query.member.findMany({ - where: eq(member.roleId, roleId), - }); +// const members = await db.query.member.findMany({ +// where: eq(member.roleId, roleId), +// }); - if (members.length > 0) { - throw new Error("Cannot delete role with assigned members"); - } +// if (members.length > 0) { +// throw new Error("Cannot delete role with assigned members"); +// } - await db.delete(role).where(eq(role.roleId, roleId)); +// await db.delete(role).where(eq(role.roleId, roleId)); - return currentRole; -}; +// return currentRole; +// }; -export const updateRoleById = async ( - roleId: string, - input: z.infer, -) => { - const currentRole = await findRoleById(roleId); +// export const updateRoleById = async ( +// roleId: string, +// input: z.infer, +// ) => { +// const currentRole = await findRoleById(roleId); - if (!currentRole) { - throw new Error("Role not found"); - } +// if (!currentRole) { +// throw new Error("Role not found"); +// } - if (currentRole.isSystem) { - throw new Error("Cannot update system role"); - } +// if (currentRole.isSystem) { +// throw new Error("Cannot update system role"); +// } - await db.update(role).set(input).where(eq(role.roleId, roleId)); +// await db.update(role).set(input).where(eq(role.roleId, roleId)); - return currentRole; -}; +// return currentRole; +// }; -export const createDefaultRoles = async (organizationId: string) => { - await db.transaction(async (tx) => { - await tx.insert(role).values({ - name: "owner", - description: "Owner of the organization with full access to all features", - organizationId, - isSystem: true, - permissions: ownerPermissions.map((permission) => permission.name), - }); +// export const createDefaultRoles = async (organizationId: string) => { +// await db.transaction(async (tx) => { +// await tx.insert(role).values({ +// name: "owner", +// description: "Owner of the organization with full access to all features", +// organizationId, +// isSystem: true, +// permissions: ownerPermissions.map((permission) => permission.name), +// }); - await tx.insert(role).values({ - name: "admin", - description: - "Administrator with access to manage projects, services and configurations", - organizationId, - isSystem: true, - permissions: adminPermissions.map((permission) => permission.name), - }); +// await tx.insert(role).values({ +// name: "admin", +// description: +// "Administrator with access to manage projects, services and configurations", +// organizationId, +// isSystem: true, +// permissions: adminPermissions.map((permission) => permission.name), +// }); - await tx.insert(role).values({ - name: "member", - description: - "Regular member with access to create projects and manage services", - organizationId, - isSystem: true, - permissions: memberPermissions.map((permission) => permission.name), - }); - }); -}; +// await tx.insert(role).values({ +// name: "member", +// description: +// "Regular member with access to create projects and manage services", +// organizationId, +// isSystem: true, +// permissions: memberPermissions.map((permission) => permission.name), +// }); +// }); +// };