diff --git a/webapp/channels/src/components/channel_invite_modal/channel_invite_modal.test.tsx b/webapp/channels/src/components/channel_invite_modal/channel_invite_modal.test.tsx index 497093dc35..b242497f31 100644 --- a/webapp/channels/src/components/channel_invite_modal/channel_invite_modal.test.tsx +++ b/webapp/channels/src/components/channel_invite_modal/channel_invite_modal.test.tsx @@ -717,4 +717,94 @@ describe('components/channel_invite_modal', () => { ); expect(guestInviteLinks).toHaveLength(0); }); + + test('should NOT filter out groups when NOT ABAC is enforced', async () => { + const mockGroups = [ + { + id: 'group1', + name: 'developers', + display_name: 'Developers', + description: 'Development team', + source: 'ldap', + remote_id: 'dev-group', + create_at: 1234567890, + update_at: 1234567890, + delete_at: 0, + has_syncables: false, + member_count: 5, + scheme_admin: false, + allow_reference: true, + }, + ]; + + const channelWithPolicy = { + ...channel, + policy_enforced: false, + }; + + const props = { + ...baseProps, + channel: channelWithPolicy, + groups: mockGroups, + profilesNotInCurrentChannel: [users[0]], + }; + + await act(async () => { + renderWithContext(); + }); + + const input = screen.getByRole('combobox', {name: /search for people/i}); + await userEvent.type(input, '@'); + + // Should only show users, not groups when ABAC is enforced + expect(getUserSpan('user-1')).toBeInTheDocument(); + + // Groups should appear in the dropdown + expect(getUserSpan('Developers')).toBeInTheDocument(); + }); + + test('should filter out groups when ABAC is enforced', async () => { + const mockGroups = [ + { + id: 'group1', + name: 'developers', + display_name: 'Developers', + description: 'Development team', + source: 'ldap', + remote_id: 'dev-group', + create_at: 1234567890, + update_at: 1234567890, + delete_at: 0, + has_syncables: false, + member_count: 5, + scheme_admin: false, + allow_reference: true, + }, + ]; + + const channelWithPolicy = { + ...channel, + policy_enforced: true, + }; + + const props = { + ...baseProps, + channel: channelWithPolicy, + groups: mockGroups, + profilesNotInCurrentChannel: [users[0]], + }; + + await act(async () => { + renderWithContext(); + }); + + const input = screen.getByRole('combobox', {name: /search for people/i}); + await userEvent.type(input, '@'); + + // Should only show users, not groups when ABAC is enforced + expect(getUserSpan('user-1')).toBeInTheDocument(); + + // Groups should not appear in the dropdown + expect(screen.queryByText('Developers')).toBeNull(); + }); }); diff --git a/webapp/channels/src/components/channel_invite_modal/channel_invite_modal.tsx b/webapp/channels/src/components/channel_invite_modal/channel_invite_modal.tsx index 68958f6530..a084fea0bf 100644 --- a/webapp/channels/src/components/channel_invite_modal/channel_invite_modal.tsx +++ b/webapp/channels/src/components/channel_invite_modal/channel_invite_modal.tsx @@ -183,11 +183,11 @@ const ChannelInviteModalComponent = (props: Props) => { let users: UserProfileValue[]; if (props.channel.policy_enforced) { - // When ABAC is enabled, only use the ABAC-filtered profilesNotInCurrentChannel + // When ABAC is enabled, only use the ABAC-filtered profilesNotInCurrentChannel const filteredUsers = filterProfilesStartingWithTerm(props.profilesNotInCurrentChannel, term); users = filterOutDeletedAndExcludedAndNotInTeamUsers(filteredUsers, excludedAndNotInTeamUserIds); } else { - // When ABAC is not enabled, use the current logic + // When ABAC is not enabled, use the current logic const filteredUsers = filterProfilesStartingWithTerm(props.profilesNotInCurrentChannel.concat(props.profilesInCurrentChannel), term); users = filterOutDeletedAndExcludedAndNotInTeamUsers(filteredUsers, excludedAndNotInTeamUserIds); } @@ -198,7 +198,9 @@ const ChannelInviteModalComponent = (props: Props) => { } const groupsAndUsers = [ - ...filterGroupsMatchingTerm(props.groups, term) as GroupValue[], + + // Only include groups if ABAC policy is NOT enforced + ...(props.channel.policy_enforced ? [] : filterGroupsMatchingTerm(props.groups, term) as GroupValue[]), ...users, ].sort(sortUsersAndGroups); @@ -342,7 +344,9 @@ const ChannelInviteModalComponent = (props: Props) => { const promises = [ props.actions.searchProfiles(term, options), ]; - if (props.isGroupsEnabled) { + + // Only search for groups if groups are enabled AND ABAC policy is NOT enforced + if (props.isGroupsEnabled && !props.channel.policy_enforced) { promises.push(props.actions.searchAssociatedGroupsForReference(term, props.channel.team_id, props.channel.id, opts)); } await Promise.all(promises); @@ -451,11 +455,6 @@ const ChannelInviteModalComponent = (props: Props) => { props.channel.team_id, props.channel.group_constrained, props.actions, - - // Removing these dependencies as they cause an infinite loop - // These profiles are updated by the actions above, which triggers the effect again - // props.profilesNotInCurrentChannel, - // props.profilesInCurrentChannel, ]); // Compute options with useMemo to ensure they're always fresh