Skip to content

Conversation

@apple-techie
Copy link

This PR fixes the issue where admins were not able to create services or projects because the backend was checking for specific permissions flags instead of the admin role.

This complements PR #3410 which addresses the UI side of this issue.

Fixes #3417

Copilot AI review requested due to automatic review settings January 8, 2026 08:43
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses a critical backend authorization issue where admin and owner roles were not properly checked when performing service and project operations. The fix ensures that admins and owners have full access to create, delete, and access services and projects without requiring explicit permission flags.

  • Adds admin/owner role checks to all service and project permission functions
  • Introduces new environment management permission functions with role-based access
  • Adds email validation to the updateUser function

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 394 to 400
throw new Error("Email is required and cannot be empty");
}

// Basic email format validation
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(userData.email)) {
throw new Error("Please enter a valid email address");
Copy link

Copilot AI Jan 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error handling in this function uses throw new Error instead of TRPCError which is the pattern used throughout the rest of this file for validation and permission errors. This inconsistency could lead to errors being handled differently by the TRPC framework and may not provide proper error codes to API consumers.

Suggested change
throw new Error("Email is required and cannot be empty");
}
// Basic email format validation
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(userData.email)) {
throw new Error("Please enter a valid email address");
throw new TRPCError({
code: "BAD_REQUEST",
message: "Email is required and cannot be empty",
});
}
// Basic email format validation
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(userData.email)) {
throw new TRPCError({
code: "BAD_REQUEST",
message: "Please enter a valid email address",
});

Copilot uses AI. Check for mistakes.
Comment on lines 244 to 257
export const canPerformAccessEnvironment = async (
userId: string,
environmentId: string,
organizationId: string,
) => {
const { accessedEnvironments } = await findMemberById(userId, organizationId);
const haveAccessToEnvironment = accessedEnvironments.includes(environmentId);

if (haveAccessToEnvironment) {
return true;
}

return false;
};
Copy link

Copilot AI Jan 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The canPerformAccessEnvironment function is missing the admin/owner role check that has been added to all other similar permission functions. Admins and owners should have access to all environments without needing to be in the accessedEnvironments list. This inconsistency means admins/owners may be incorrectly denied access to environments.

Copilot uses AI. Check for mistakes.
Comment on lines 266 to 272
if (!member) {
throw new TRPCError({
code: "UNAUTHORIZED",
message: "User not found in organization",
});
}

Copy link

Copilot AI Jan 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The null check for member is redundant because findMemberById already throws a TRPCError with code "UNAUTHORIZED" if the member is not found (line 381-386). This check will never be reached since the function would have already thrown an exception.

Suggested change
if (!member) {
throw new TRPCError({
code: "UNAUTHORIZED",
message: "User not found in organization",
});
}

Copilot uses AI. Check for mistakes.
Comment on lines 332 to 341
// Get user's member record
const member = await findMemberById(userId, organizationId);

if (!member) {
throw new TRPCError({
code: "UNAUTHORIZED",
message: "User not found in organization",
});
}

Copy link

Copilot AI Jan 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The null check for member is redundant because findMemberById already throws a TRPCError with code "UNAUTHORIZED" if the member is not found (line 381-386). This check will never be reached since the function would have already thrown an exception.

Suggested change
// Get user's member record
const member = await findMemberById(userId, organizationId);
if (!member) {
throw new TRPCError({
code: "UNAUTHORIZED",
message: "User not found in organization",
});
}
// Get user's member record (throws if not found)
const member = (await findMemberById(userId, organizationId))!;

Copilot uses AI. Check for mistakes.
Copy link
Contributor

@Siumauricio Siumauricio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello, these changes are not necessary. This method is only used when dealing with a member role; it does not apply when you are an owner or administrator. The issue you mentioned as related fixes all permission issues that were not showing up in the user interface, but there should be no problem in the backend. If you can give me an example of a use case, I can look into it, thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Admin role permissions ignored in canPerformCreationService (Backend Fix)

2 participants