1
- import type { IUserWithRoleInfo , ISubscription , IUser } from '@rocket.chat/core-typings' ;
1
+ import type { IUserWithRoleInfo , IUser , IRoom , UserStatus } from '@rocket.chat/core-typings' ;
2
2
import { Users , Subscriptions } from '@rocket.chat/models' ;
3
- import type { FilterOperators , FindOptions } from 'mongodb' ;
3
+ import type { Filter , FilterOperators , FindOptions } from 'mongodb' ;
4
4
5
5
import { settings } from '../../app/settings/server' ;
6
6
7
7
type FindUsersParam = {
8
8
rid : string ;
9
- status ?: FilterOperators < string > ;
9
+ status ?: FilterOperators < UserStatus > ;
10
10
skip ?: number ;
11
11
limit ?: number ;
12
12
filter ?: string ;
13
13
sort ?: Record < string , any > ;
14
14
} ;
15
15
16
- async function findUsersWithRolesOfRoom (
17
- { rid, status, limit = 0 , filter = '' } : FindUsersParam ,
18
- options : FindOptions < IUser > ,
19
- ) : Promise < { members : IUserWithRoleInfo [ ] ; totalCount : number ; allMembersIds : string [ ] } > {
20
- // Sort roles in descending order so that owners are listed before moderators
21
- // This could possibly cause issues with custom roles, but that's intended to improve performance
22
- const highestRolesMembersSubscriptions = await Subscriptions . findByRoomIdAndRoles ( rid , [ 'owner' , 'moderator' ] , {
23
- projection : { 'u._id' : 1 , 'roles' : 1 } ,
24
- sort : { roles : - 1 } ,
25
- } ) . toArray ( ) ;
26
-
27
- const searchFields = settings . get < string > ( 'Accounts_SearchFields' ) . trim ( ) . split ( ',' ) ;
28
-
29
- const totalCount = highestRolesMembersSubscriptions . length ;
30
- const allMembersIds = highestRolesMembersSubscriptions . map ( ( s : ISubscription ) => s . u ?. _id ) ;
31
- const highestRolesMembersIdsToFind = allMembersIds . slice ( 0 , limit ) ;
32
-
33
- const { cursor } = Users . findPaginatedActiveUsersByIds ( filter , searchFields , highestRolesMembersIdsToFind , options , [
34
- {
35
- __rooms : rid ,
36
- ...( status && { status } ) ,
37
- } ,
38
- ] ) ;
39
- const highestRolesMembers = await cursor . toArray ( ) ;
40
-
41
- // maps for efficient lookup of highest roles and sort order
42
- const ordering : Record < string , number > = { } ;
43
- const highestRoleById : Record < string , string > = { } ;
44
-
45
- const limitedHighestRolesMembersSubs = highestRolesMembersSubscriptions . slice ( 0 , limit ) ;
46
- limitedHighestRolesMembersSubs . forEach ( ( sub , index ) => {
47
- ordering [ sub . u . _id ] = index ;
48
- highestRoleById [ sub . u . _id ] = sub . roles ?. includes ( 'owner' ) ? 'owner' : 'moderator' ;
49
- } ) ;
50
-
51
- highestRolesMembers . sort ( ( a , b ) => ordering [ a . _id ] - ordering [ b . _id ] ) ;
52
- const membersWithHighestRoles = highestRolesMembers . map (
53
- ( member ) : IUserWithRoleInfo => ( {
54
- ...member ,
55
- highestRole : {
56
- role : highestRoleById [ member . _id ] ,
57
- level : highestRoleById [ member . _id ] === 'owner' ? 0 : 1 ,
58
- } ,
59
- } ) ,
60
- ) ;
61
- return { members : membersWithHighestRoles , totalCount, allMembersIds } ;
62
- }
63
-
64
16
export async function findUsersOfRoomByHighestRole ( {
65
17
rid,
66
18
status,
@@ -85,22 +37,25 @@ export async function findUsersOfRoomByHighestRole({
85
37
} ,
86
38
limit,
87
39
} ;
88
- const extraQuery = {
40
+ const extraQuery : Filter < IUser & { __rooms : IRoom [ '_id' ] [ ] } > = {
89
41
__rooms : rid ,
90
42
...( status && { status } ) ,
91
43
} ;
92
44
const searchFields = settings . get < string > ( 'Accounts_SearchFields' ) . trim ( ) . split ( ',' ) ;
93
45
94
- // Find highest roles members (owners and moderator)
46
+ // Find highest roles members (owners and moderators)
47
+ const result = await Subscriptions . findPaginatedActiveHighestRoleUsers ( filter , rid , searchFields , options , extraQuery ) ;
95
48
const {
96
- members : highestRolesMembers ,
97
- totalCount : totalMembersWithRoles ,
98
- allMembersIds : highestRolesMembersIds ,
99
- } = await findUsersWithRolesOfRoom ( { rid, status, limit, filter } , options ) ;
49
+ members : highestRolesMembers = [ ] ,
50
+ totalCount : totalMembersWithRoles = { total : 0 } ,
51
+ ids = { allMembersIds : [ ] } ,
52
+ } = result [ 0 ] || { } ;
53
+ const { total : totalMembersWithRolesCount } = totalMembersWithRoles ;
54
+ const { allMembersIds : highestRolesMembersIds } = ids ;
100
55
101
56
if ( limit <= highestRolesMembers . length ) {
102
57
const totalMembersCount = await Users . countActiveUsersExcept ( filter , highestRolesMembersIds , searchFields , [ extraQuery ] ) ;
103
- return { members : highestRolesMembers , total : totalMembersWithRoles + totalMembersCount } ;
58
+ return { members : highestRolesMembers , total : totalMembersWithRolesCount + totalMembersCount } ;
104
59
}
105
60
if ( options . limit ) {
106
61
options . limit -= highestRolesMembers . length ;
@@ -122,5 +77,5 @@ export async function findUsersOfRoomByHighestRole({
122
77
) ;
123
78
124
79
const allMembers = highestRolesMembers . concat ( membersWithHighestRoles ) ;
125
- return { members : allMembers , total : totalMembersWithRoles + totalMembersCount } ;
80
+ return { members : allMembers , total : totalMembersWithRolesCount + totalMembersCount } ;
126
81
}
0 commit comments