From d3764fd9fec468eeb186718b7a6af3c8dd13b42b Mon Sep 17 00:00:00 2001 From: Ruben Talstra Date: Sat, 22 Feb 2025 12:02:09 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat:=20Enhance=20group=20search=20?= =?UTF-8?q?functionality=20to=20support=20multiple=20group=20retrieval?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/models/groupMethods.js | 10 +++++----- api/strategies/openidStrategy.js | 24 +++++++++++------------- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/api/models/groupMethods.js b/api/models/groupMethods.js index 86f435d6f2..7148faa101 100644 --- a/api/models/groupMethods.js +++ b/api/models/groupMethods.js @@ -17,14 +17,14 @@ const getGroupById = (groupId, fieldsToSelect = null) => { }; /** - * Search for a single group based on partial data and return a matching group document as a plain object. + * Search for a single group or multiple groups based on partial data and return them as plain objects. * - * @param {Partial} searchCriteria - The partial data to use for searching the group. - * @param {string|string[]} [fieldsToSelect] - The fields to include or exclude in the returned document. - * @returns {Promise} A plain object representing the group document, or `null` if no group is found. + * @param {Partial} searchCriteria - The partial data to use for searching groups. + * @param {string|string[]} [fieldsToSelect] - The fields to include or exclude in the returned documents. + * @returns {Promise} An array of plain objects representing the group documents. */ const findGroup = (searchCriteria, fieldsToSelect = null) => { - const query = Group.findOne(searchCriteria); + const query = Group.find(searchCriteria); if (fieldsToSelect) { query.select(fieldsToSelect); } diff --git a/api/strategies/openidStrategy.js b/api/strategies/openidStrategy.js index 43b035e66e..abc41041ec 100644 --- a/api/strategies/openidStrategy.js +++ b/api/strategies/openidStrategy.js @@ -5,10 +5,10 @@ const { HttpsProxyAgent } = require('https-proxy-agent'); const { Issuer, Strategy: OpenIDStrategy, custom } = require('openid-client'); const { getStrategyFunctions } = require('~/server/services/Files/strategies'); const { findUser, createUser, updateUser } = require('~/models/userMethods'); +const { findGroup } = require('~/models/groupMethods'); const { hashToken } = require('~/server/utils/crypto'); const { isEnabled } = require('~/server/utils'); const { logger } = require('~/config'); -const Group = require('~/models'); let crypto; try { @@ -193,30 +193,28 @@ async function setupOpenId() { message: `You must have the "${requiredRole}" role to log in.`, }); } - // Synchronize the user's groups for OpenID. - const userGroupIds = user.groups.map(id => id.toString()); + if (!user.groups) { + user.groups = []; + } // Remove existing OpenID group references. - const currentOpenIdGroups = await Group.find({ - _id: { $in: userGroupIds }, + const currentOpenIdGroups = await findGroup({ + _id: { $in: user.groups }, provider: 'openid', }); const currentOpenIdGroupIds = new Set(currentOpenIdGroups.map(g => g._id.toString())); user.groups = user.groups.filter(id => !currentOpenIdGroupIds.has(id.toString())); - // Look up groups matching the roles. - const matchingGroups = await Group.find({ + // Look up groups in the Group collection matching the roles. + const matchingGroups = await findGroup({ provider: 'openid', externalId: { $in: roles }, }); - const userGroupSet = new Set(user.groups.map(id => id.toString())); - for (const group of matchingGroups) { - const groupIdStr = group._id.toString(); - if (!userGroupSet.has(groupIdStr)) { + matchingGroups.forEach(group => { + if (!user.groups.some(id => id.toString() === group._id.toString())) { user.groups.push(group._id); - userGroupSet.add(groupIdStr); } - } + }); } let username = '';