feat: add canCreateEnvironments permission for environment creation - Add database field and API validation - Implement permission checking in environment creation - Add UI toggle in user permissions modal - Hide create button for unauthorized users Fixes #2593

This commit is contained in:
HarikrishnanD
2025-09-12 17:56:02 +05:30
parent 24729f35ec
commit 30b28afbac
11 changed files with 13275 additions and 23 deletions

View File

@@ -108,6 +108,9 @@ export const member = pgTable("member", {
canAccessToTraefikFiles: boolean("canAccessToTraefikFiles")
.notNull()
.default(false),
canCreateEnvironments: boolean("canCreateEnvironments")
.notNull()
.default(false),
accessedProjects: text("accesedProjects")
.array()
.notNull()

View File

@@ -186,6 +186,7 @@ export const apiAssignPermissions = createSchema
canAccessToAPI: z.boolean().optional(),
canAccessToSSHKeys: z.boolean().optional(),
canAccessToGitProviders: z.boolean().optional(),
canCreateEnvironments: z.boolean().optional(),
})
.required();

View File

@@ -272,6 +272,46 @@ export const checkProjectAccess = async (
}
};
export const checkEnvironmentCreationPermission = async (
userId: string,
projectId: string,
organizationId: string,
) => {
// Get user's member record
const member = await findMemberById(userId, organizationId);
if (!member) {
throw new TRPCError({
code: "UNAUTHORIZED",
message: "User not found in organization",
});
}
// Owners and admins can always create environments
if (member.role === "owner" || member.role === "admin") {
return true;
}
// Check if user has canCreateEnvironments permission
if (!member.canCreateEnvironments) {
throw new TRPCError({
code: "UNAUTHORIZED",
message: "You don't have permission to create environments",
});
}
// Check if user has access to the project
const hasProjectAccess = member.accessedProjects.includes(projectId);
if (!hasProjectAccess) {
throw new TRPCError({
code: "UNAUTHORIZED",
message: "You don't have access to this project",
});
}
return true;
};
export const findMemberById = async (
userId: string,
organizationId: string,