@@ -91,6 +91,8 @@ const GetGroupQueryModel = z.object({
9191 excludedAttributes : z . literal ( 'members' ) . optional ( ) ,
9292} ) ;
9393
94+ const GetGroupsQueryModel = QuerySchemaModel . merge ( GetGroupQueryModel ) ;
95+
9496const SharedUserRouteParams = z . object ( {
9597 userId : z . string ( ) . uuid ( ) ,
9698} ) ;
@@ -1194,7 +1196,7 @@ export const createSCIMPlugin =
11941196 return reply . status ( result . error . status ) . send ( result . error ) ;
11951197 }
11961198
1197- const queryParse = QuerySchemaModel . safeParse ( req . query ) ;
1199+ const queryParse = GetGroupsQueryModel . safeParse ( req . query ) ;
11981200 if ( queryParse . error ) {
11991201 return reply . status ( 403 ) . send (
12001202 createSCIMError ( {
@@ -1205,6 +1207,7 @@ export const createSCIMPlugin =
12051207 }
12061208
12071209 const groupStore = new GroupStore ( result . logger , pool ) ;
1210+ const groupMemberStore = new GroupMemberStore ( result . logger , pool ) ;
12081211
12091212 const startIndex = queryParse . data . startIndex ?? 1 ;
12101213 const count = queryParse . data . count ?? 100 ;
@@ -1252,12 +1255,20 @@ export const createSCIMPlugin =
12521255 }
12531256 }
12541257
1258+ const groupMembers =
1259+ group && queryParse . data . excludedAttributes !== 'members'
1260+ ? await groupMemberStore . getGroupMembersForOrganizationIdAndGroupId (
1261+ result . organizationId ,
1262+ group . id ,
1263+ )
1264+ : undefined ;
1265+
12551266 return reply . status ( 200 ) . send ( {
12561267 schemas : [ 'urn:ietf:params:scim:api:messages:2.0:ListResponse' ] ,
12571268 totalResults : group ? 1 : 0 ,
12581269 startIndex,
12591270 itemsPerPage : group ? 1 : 0 ,
1260- Resources : group ? [ createSCIMGroupObjectFromGroup ( baseUri , group ) ] : [ ] ,
1271+ Resources : group ? [ createSCIMGroupObjectFromGroup ( baseUri , group , groupMembers ) ] : [ ] ,
12611272 } satisfies SCIMListResponseObject ) ;
12621273 }
12631274
@@ -1269,8 +1280,24 @@ export const createSCIMPlugin =
12691280 } ,
12701281 ) ;
12711282
1283+ const groupMembersByGroupId =
1284+ queryParse . data . excludedAttributes !== 'members' && pagedGroups . length > 0
1285+ ? await groupMemberStore . getGroupMembersForOrganizationIdAndGroupIds (
1286+ result . organizationId ,
1287+ pagedGroups . map ( group => group . id ) ,
1288+ )
1289+ : null ;
1290+
12721291 for ( const group of pagedGroups ) {
1273- groups . push ( createSCIMGroupObjectFromGroup ( baseUri , group ) ) ;
1292+ groups . push (
1293+ createSCIMGroupObjectFromGroup (
1294+ baseUri ,
1295+ group ,
1296+ groupMembersByGroupId === null
1297+ ? undefined
1298+ : ( groupMembersByGroupId . get ( group . id ) ?? [ ] ) ,
1299+ ) ,
1300+ ) ;
12741301 }
12751302
12761303 return reply . status ( 200 ) . send ( {
@@ -1957,11 +1984,7 @@ function createSCIMGroupObjectFromGroup(
19571984 baseUri : string ,
19581985 group : Group ,
19591986 /**
1960- * The members are optional as they do not need to be included within actions such as
1961- * "list all groups".
1962- *
1963- * Only when a specific group object is requested or updated we include the list of members
1964- * so the SCIM provider can see if a user is or is not a member of an organization.
1987+ * Members are omitted when the client requests `excludedAttributes=members`.
19651988 */
19661989 members ?: Array < GroupMember > ,
19671990) : SCIMGroupObject {
0 commit comments