mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-17 08:50:15 +01:00
👫 fix: Update Entra ID group retrieval to use getMemberGroups and add pagination support (#10199)
Some checks are pending
Docker Dev Branch Images Build / build (Dockerfile, lc-dev, node) (push) Waiting to run
Docker Dev Branch Images Build / build (Dockerfile.multi, lc-dev-api, api-build) (push) Waiting to run
Docker Dev Images Build / build (Dockerfile, librechat-dev, node) (push) Waiting to run
Docker Dev Images Build / build (Dockerfile.multi, librechat-dev-api, api-build) (push) Waiting to run
Sync Locize Translations & Create Translation PR / Sync Translation Keys with Locize (push) Waiting to run
Sync Locize Translations & Create Translation PR / Create Translation PR on Version Published (push) Blocked by required conditions
Some checks are pending
Docker Dev Branch Images Build / build (Dockerfile, lc-dev, node) (push) Waiting to run
Docker Dev Branch Images Build / build (Dockerfile.multi, lc-dev-api, api-build) (push) Waiting to run
Docker Dev Images Build / build (Dockerfile, librechat-dev, node) (push) Waiting to run
Docker Dev Images Build / build (Dockerfile.multi, librechat-dev-api, api-build) (push) Waiting to run
Sync Locize Translations & Create Translation PR / Sync Translation Keys with Locize (push) Waiting to run
Sync Locize Translations & Create Translation PR / Create Translation PR on Version Published (push) Blocked by required conditions
This commit is contained in:
parent
13b784a3e6
commit
d46dde4e01
2 changed files with 134 additions and 31 deletions
|
|
@ -159,7 +159,7 @@ const searchEntraIdPrincipals = async (accessToken, sub, query, type = 'all', li
|
|||
|
||||
/**
|
||||
* Get current user's Entra ID group memberships from Microsoft Graph
|
||||
* Uses /me/memberOf endpoint to get groups the user is a member of
|
||||
* Uses /me/getMemberGroups endpoint to get transitive groups the user is a member of
|
||||
* @param {string} accessToken - OpenID Connect access token
|
||||
* @param {string} sub - Subject identifier
|
||||
* @returns {Promise<Array<string>>} Array of group ID strings (GUIDs)
|
||||
|
|
@ -167,10 +167,12 @@ const searchEntraIdPrincipals = async (accessToken, sub, query, type = 'all', li
|
|||
const getUserEntraGroups = async (accessToken, sub) => {
|
||||
try {
|
||||
const graphClient = await createGraphClient(accessToken, sub);
|
||||
const response = await graphClient
|
||||
.api('/me/getMemberGroups')
|
||||
.post({ securityEnabledOnly: false });
|
||||
|
||||
const groupsResponse = await graphClient.api('/me/memberOf').select('id').get();
|
||||
|
||||
return (groupsResponse.value || []).map((group) => group.id);
|
||||
const groupIds = Array.isArray(response?.value) ? response.value : [];
|
||||
return [...new Set(groupIds.map((groupId) => String(groupId)))];
|
||||
} catch (error) {
|
||||
logger.error('[getUserEntraGroups] Error fetching user groups:', error);
|
||||
return [];
|
||||
|
|
@ -187,13 +189,22 @@ const getUserEntraGroups = async (accessToken, sub) => {
|
|||
const getUserOwnedEntraGroups = async (accessToken, sub) => {
|
||||
try {
|
||||
const graphClient = await createGraphClient(accessToken, sub);
|
||||
const allGroupIds = [];
|
||||
let nextLink = '/me/ownedObjects/microsoft.graph.group';
|
||||
|
||||
const groupsResponse = await graphClient
|
||||
.api('/me/ownedObjects/microsoft.graph.group')
|
||||
.select('id')
|
||||
.get();
|
||||
while (nextLink) {
|
||||
const response = await graphClient.api(nextLink).select('id').top(999).get();
|
||||
const groups = response?.value || [];
|
||||
allGroupIds.push(...groups.map((group) => group.id));
|
||||
|
||||
return (groupsResponse.value || []).map((group) => group.id);
|
||||
nextLink = response['@odata.nextLink']
|
||||
? response['@odata.nextLink']
|
||||
.replace(/^https:\/\/graph\.microsoft\.com\/v1\.0/, '')
|
||||
.trim() || null
|
||||
: null;
|
||||
}
|
||||
|
||||
return allGroupIds;
|
||||
} catch (error) {
|
||||
logger.error('[getUserOwnedEntraGroups] Error fetching user owned groups:', error);
|
||||
return [];
|
||||
|
|
@ -211,21 +222,27 @@ const getUserOwnedEntraGroups = async (accessToken, sub) => {
|
|||
const getGroupMembers = async (accessToken, sub, groupId) => {
|
||||
try {
|
||||
const graphClient = await createGraphClient(accessToken, sub);
|
||||
const allMembers = [];
|
||||
let nextLink = `/groups/${groupId}/members`;
|
||||
const allMembers = new Set();
|
||||
let nextLink = `/groups/${groupId}/transitiveMembers`;
|
||||
|
||||
while (nextLink) {
|
||||
const membersResponse = await graphClient.api(nextLink).select('id').top(999).get();
|
||||
|
||||
const members = membersResponse.value || [];
|
||||
allMembers.push(...members.map((member) => member.id));
|
||||
const members = membersResponse?.value || [];
|
||||
members.forEach((member) => {
|
||||
if (typeof member?.id === 'string' && member['@odata.type'] === '#microsoft.graph.user') {
|
||||
allMembers.add(member.id);
|
||||
}
|
||||
});
|
||||
|
||||
nextLink = membersResponse['@odata.nextLink']
|
||||
? membersResponse['@odata.nextLink'].split('/v1.0')[1]
|
||||
? membersResponse['@odata.nextLink']
|
||||
.replace(/^https:\/\/graph\.microsoft\.com\/v1\.0/, '')
|
||||
.trim() || null
|
||||
: null;
|
||||
}
|
||||
|
||||
return allMembers;
|
||||
return Array.from(allMembers);
|
||||
} catch (error) {
|
||||
logger.error('[getGroupMembers] Error fetching group members:', error);
|
||||
return [];
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue