Merge pull request #5112 from Infisical/fix/SECRETS-37

fix: add member to project not using the organization default role
This commit is contained in:
carlosmonastyrski
2026-01-06 11:59:29 -03:00
committed by GitHub
2 changed files with 15 additions and 7 deletions

View File

@@ -2,7 +2,6 @@ import { z } from "zod";
import {
AccessScope,
OrgMembershipRole,
ProjectMembershipRole,
ProjectMembershipsSchema,
ProjectUserMembershipRolesSchema,
@@ -275,7 +274,7 @@ export const registerProjectMembershipRouter = async (server: FastifyZodProvider
orgId: req.permission.orgId
},
data: {
roles: [{ isTemporary: false, role: OrgMembershipRole.NoAccess }],
roles: [],
usernames: usernamesAndEmails
}
});

View File

@@ -1,5 +1,6 @@
import {
AccessScope,
OrgMembershipRole,
OrgMembershipStatus,
ProjectMembershipRole,
TemporaryPermissionMode,
@@ -157,13 +158,22 @@ export const membershipUserServiceFactory = ({
const { scopeData, data } = dto;
const factory = scopeFactory[scopeData.scope];
const hasNoPermanentRole = data.roles.every((el) => el.isTemporary);
const orgDetails = await orgDAL.findById(dto.permission.orgId);
// If roles array is empty and scope is Organization, use org's default role
let rolesToUse = data.roles;
if (data.roles.length === 0 && scopeData.scope === AccessScope.Organization) {
const defaultRole = orgDetails.defaultMembershipRole || OrgMembershipRole.NoAccess;
rolesToUse = [{ isTemporary: false, role: defaultRole }];
}
const hasNoPermanentRole = rolesToUse.every((el) => el.isTemporary);
if (hasNoPermanentRole) {
throw new BadRequestError({
message: "User must have at least one permanent role"
});
}
const isInvalidTemporaryRole = data.roles.some((el) => {
const isInvalidTemporaryRole = rolesToUse.some((el) => {
if (el.isTemporary) {
if (!el.temporaryAccessStartTime || !el.temporaryRange) {
return true;
@@ -188,7 +198,6 @@ export const membershipUserServiceFactory = ({
});
if (existingMemberships.length === users.length) return { memberships: [] };
const orgDetails = await orgDAL.findById(dto.permission.orgId);
const isSubOrganization = Boolean(orgDetails.rootOrgId);
const newMembershipUsers = users.filter((user) => !existingMemberships?.find((el) => el.actorUserId === user.id));
@@ -212,7 +221,7 @@ export const membershipUserServiceFactory = ({
};
});
const customInputRoles = data.roles.filter((el) => factory.isCustomRole(el.role));
const customInputRoles = rolesToUse.filter((el) => factory.isCustomRole(el.role));
const hasCustomRole = customInputRoles.length > 0;
if (hasCustomRole) {
const plan = await licenseService.getPlan(scopeData.orgId);
@@ -241,7 +250,7 @@ export const membershipUserServiceFactory = ({
const roleDocs: TMembershipRolesInsert[] = [];
docs.forEach((membership) => {
data.roles.forEach((membershipRole) => {
rolesToUse.forEach((membershipRole) => {
const isCustomRole = Boolean(customRolesGroupBySlug?.[membershipRole.role]?.[0]);
if (membershipRole.isTemporary) {
const relativeTimeInMs = membershipRole.temporaryRange ? ms(membershipRole.temporaryRange) : null;