Skip to content

Commit 5b34d5c

Browse files
committed
refactor(groups.members): Refactor of groups.members to new openAPI structure
1 parent 4f88165 commit 5b34d5c

File tree

5 files changed

+130
-87
lines changed

5 files changed

+130
-87
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@rocket.chat/rest-typings': minor
3+
'@rocket.chat/meteor': minor
4+
---
5+
6+
Migration of groups.memebers added ajv validation for request and response, schema changes for request.

apps/meteor/app/api/server/v1/groups.ts

Lines changed: 123 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,21 @@
11
import { Team, isMeteorError } from '@rocket.chat/core-services';
22
import type { IIntegration, IUser, IRoom, RoomType, UserStatus } from '@rocket.chat/core-typings';
33
import { Integrations, Messages, Rooms, Subscriptions, Uploads, Users } from '@rocket.chat/models';
4-
import { isGroupsOnlineProps, isGroupsMessagesProps, isGroupsFilesProps } from '@rocket.chat/rest-typings';
4+
import { isGroupsOnlineProps
5+
, isGroupsMessagesProps,
6+
isGroupsFilesProps,
7+
ajv,
8+
validateBadRequestErrorResponse,
9+
validateUnauthorizedErrorResponse,
10+
validateForbiddenErrorResponse,
11+
withGroupBaseProperties, } from '@rocket.chat/rest-typings';
512
import { isTruthy } from '@rocket.chat/tools';
613
import { check, Match } from 'meteor/check';
714
import { Meteor } from 'meteor/meteor';
815
import type { Filter } from 'mongodb';
916

17+
18+
import type { ExtractRoutesFromAPI } from '../ApiClass';
1019
import { eraseRoom } from '../../../../server/lib/eraseRoom';
1120
import { findUsersOfRoom } from '../../../../server/lib/findUsersOfRoom';
1221
import { openRoom } from '../../../../server/lib/openRoom';
@@ -36,6 +45,111 @@ import { addUserToFileObj } from '../helpers/addUserToFileObj';
3645
import { composeRoomWithLastMessage } from '../helpers/composeRoomWithLastMessage';
3746
import { getPaginationItems } from '../helpers/getPaginationItems';
3847
import { getUserFromParams, getUserListFromParams } from '../helpers/getUserFromParams';
48+
import type { PaginatedRequest, GroupsBaseProps } from '@rocket.chat/rest-typings';
49+
import { nullable } from 'zod';
50+
51+
type GroupsMembersProps = PaginatedRequest<GroupsBaseProps & { filter?: string; status?: string[] }>;
52+
53+
const GroupsMembersPropsSchema = withGroupBaseProperties({
54+
offset: {
55+
type: 'string',
56+
},
57+
count: {
58+
type: 'string',
59+
},
60+
filter: {
61+
type: 'string',
62+
},
63+
query: {
64+
type: 'string',
65+
nullable: true
66+
},
67+
sort: {
68+
type: 'string',
69+
nullable: true
70+
},
71+
status: {
72+
type: 'array',
73+
items: { type: 'string' },
74+
},
75+
});
76+
77+
const isGroupsMembersProps = ajv.compile<GroupsMembersProps>(GroupsMembersPropsSchema);
78+
79+
80+
const isGroupsMembersResponse = ajv.compile({
81+
type: 'object',
82+
properties: {
83+
members: {
84+
type: 'array',
85+
items: { $ref: '#/components/schemas/IUser' },
86+
},
87+
count: { type: 'integer' },
88+
offset: { type: 'integer' },
89+
total: { type: 'integer' },
90+
success: { type: 'boolean', enum: [true] },
91+
},
92+
required: ['members', 'success'],
93+
additionalProperties: false,
94+
});
95+
96+
const groupsEndPoints = API.v1
97+
.get(
98+
'groups.members',
99+
{
100+
authRequired: true,
101+
query: isGroupsMembersProps,
102+
response: {
103+
200: isGroupsMembersResponse,
104+
400: validateBadRequestErrorResponse,
105+
401: validateUnauthorizedErrorResponse,
106+
403: validateForbiddenErrorResponse
107+
}
108+
},
109+
async function action(){
110+
const findResult = await findPrivateGroupByIdOrName({
111+
params: this.queryParams,
112+
userId: this.userId,
113+
});
114+
115+
if (findResult.broadcast && !(await hasPermissionAsync(this.userId, 'view-broadcast-member-list', findResult.rid))) {
116+
return API.v1.forbidden('User does not have the permissions required for this action');
117+
}
118+
119+
const { offset: skip, count: limit } = await getPaginationItems(this.queryParams);
120+
const { sort = {} } = await this.parseJsonQuery();
121+
122+
check(
123+
this.queryParams,
124+
Match.ObjectIncluding({
125+
status: Match.Maybe([String]),
126+
filter: Match.Maybe(String),
127+
}),
128+
);
129+
130+
const { status, filter } = this.queryParams;
131+
132+
const { cursor, totalCount } = await findUsersOfRoom({
133+
rid: findResult.rid,
134+
...(status && { status: { $in: status as UserStatus[] } }),
135+
skip,
136+
limit,
137+
filter,
138+
...(sort?.username && { sort: { username: sort.username } }),
139+
});
140+
141+
const [members, total] = await Promise.all([cursor.toArray(), totalCount]);
142+
143+
return API.v1.success({
144+
members,
145+
count: members.length,
146+
offset: skip,
147+
total,
148+
});
149+
}
150+
)
151+
152+
39153

40154
async function getRoomFromParams(params: { roomId?: string } | { roomName?: string }): Promise<IRoom> {
41155
if (
@@ -718,54 +832,6 @@ API.v1.addRoute(
718832
},
719833
);
720834

721-
API.v1.addRoute(
722-
'groups.members',
723-
{ authRequired: true },
724-
{
725-
async get() {
726-
const findResult = await findPrivateGroupByIdOrName({
727-
params: this.queryParams,
728-
userId: this.userId,
729-
});
730-
731-
if (findResult.broadcast && !(await hasPermissionAsync(this.userId, 'view-broadcast-member-list', findResult.rid))) {
732-
return API.v1.forbidden();
733-
}
734-
735-
const { offset: skip, count: limit } = await getPaginationItems(this.queryParams);
736-
const { sort = {} } = await this.parseJsonQuery();
737-
738-
check(
739-
this.queryParams,
740-
Match.ObjectIncluding({
741-
status: Match.Maybe([String]),
742-
filter: Match.Maybe(String),
743-
}),
744-
);
745-
746-
const { status, filter } = this.queryParams;
747-
748-
const { cursor, totalCount } = await findUsersOfRoom({
749-
rid: findResult.rid,
750-
...(status && { status: { $in: status as UserStatus[] } }),
751-
skip,
752-
limit,
753-
filter,
754-
...(sort?.username && { sort: { username: sort.username } }),
755-
});
756-
757-
const [members, total] = await Promise.all([cursor.toArray(), totalCount]);
758-
759-
return API.v1.success({
760-
members,
761-
count: members.length,
762-
offset: skip,
763-
total,
764-
});
765-
},
766-
},
767-
);
768-
769835
API.v1.addRoute(
770836
'groups.messages',
771837
{ authRequired: true, validateParams: isGroupsMessagesProps },
@@ -1300,3 +1366,11 @@ API.v1.addRoute(
13001366
},
13011367
},
13021368
);
1369+
1370+
1371+
export type GroupsHistoryEndpoints = ExtractRoutesFromAPI<typeof groupsEndPoints>;
1372+
1373+
declare module '@rocket.chat/rest-typings' {
1374+
// eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/no-empty-interface
1375+
interface Endpoints extends GroupsHistoryEndpoints {}
1376+
}

packages/rest-typings/src/v1/groups/GroupsMembersProps.ts

Lines changed: 0 additions & 28 deletions
This file was deleted.

packages/rest-typings/src/v1/groups/groups.ts

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import type { GroupsInviteProps } from './GroupsInviteProps';
1818
import type { GroupsKickProps } from './GroupsKickProps';
1919
import type { GroupsLeaveProps } from './GroupsLeaveProps';
2020
import type { GroupsListProps } from './GroupsListProps';
21-
import type { GroupsMembersProps } from './GroupsMembersProps';
2221
import type { GroupsMessagesProps } from './GroupsMessagesProps';
2322
import type { GroupsModeratorsProps } from './GroupsModeratorsProps';
2423
import type { GroupsOnlineProps } from './GroupsOnlineProps';
@@ -46,14 +45,6 @@ export type GroupsEndpoints = {
4645
files: IUploadWithUser[];
4746
}>;
4847
};
49-
'/v1/groups.members': {
50-
GET: (params: GroupsMembersProps) => {
51-
count: number;
52-
offset: number;
53-
members: IUser[];
54-
total: number;
55-
};
56-
};
5748
'/v1/groups.history': {
5849
GET: (params: GroupsHistoryProps) => PaginatedResult<{
5950
messages: IMessage[];

packages/rest-typings/src/v1/groups/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export type * from './groups';
22

3+
export * from './BaseProps';
34
export * from './GroupsArchiveProps';
45
export * from './GroupsCloseProps';
56
export * from './GroupsConvertToTeamProps';
@@ -9,7 +10,6 @@ export * from './GroupsDeleteProps';
910
export * from './GroupsFilesProps';
1011
export * from './GroupsKickProps';
1112
export * from './GroupsLeaveProps';
12-
export * from './GroupsMembersProps';
1313
export * from './GroupsMessagesProps';
1414
export * from './GroupsRolesProps';
1515
export * from './GroupsUnarchiveProps';

0 commit comments

Comments
 (0)