Skip to content
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/migrate-rooms-mute-unmute-endpoints.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@rocket.chat/meteor": minor
"@rocket.chat/rest-typings": minor
---

Migrated `rooms.muteUser` and `rooms.unmuteUser` endpoints to the new OpenAPI pattern with AJV schema validation
135 changes: 98 additions & 37 deletions apps/meteor/app/api/server/v1/rooms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
ajv,
isGETRoomsNameExists,
isRoomsImagesProps,
isRoomsMuteUnmuteUserProps,
isRoomsExportProps,
isRoomsIsMemberProps,
isRoomsCleanHistoryProps,
Expand Down Expand Up @@ -875,42 +874,6 @@ API.v1.addRoute(
},
);

API.v1.addRoute(
'rooms.muteUser',
{ authRequired: true, validateParams: isRoomsMuteUnmuteUserProps },
{
async post() {
const user = await getUserFromParams(this.bodyParams);

if (!user.username) {
return API.v1.failure('Invalid user');
}

await muteUserInRoom(this.userId, { rid: this.bodyParams.roomId, username: user.username });

return API.v1.success();
},
},
);

API.v1.addRoute(
'rooms.unmuteUser',
{ authRequired: true, validateParams: isRoomsMuteUnmuteUserProps },
{
async post() {
const user = await getUserFromParams(this.bodyParams);

if (!user.username) {
return API.v1.failure('Invalid user');
}

await unmuteUserInRoom(this.userId, { rid: this.bodyParams.roomId, username: user.username });

return API.v1.success();
},
},
);

API.v1.addRoute(
'rooms.open',
{ authRequired: true, validateParams: isRoomsOpenProps },
Expand Down Expand Up @@ -1027,6 +990,44 @@ const isRoomsLeavePropsSchema = {
const isRoomsFavoriteProps = ajv.compile<RoomsFavorite>(RoomsFavoriteSchema);
const isRoomsLeaveProps = ajv.compile<RoomsLeave>(isRoomsLeavePropsSchema);

type RoomsMuteUnmuteUser = { userId: string; roomId: string } | { username: string; roomId: string };

const RoomsMuteUnmuteUserSchema = {
type: 'object',
oneOf: [
{
properties: {
userId: {
type: 'string',
minLength: 1,
},
roomId: {
type: 'string',
minLength: 1,
},
},
required: ['userId', 'roomId'],
additionalProperties: false,
},
{
properties: {
username: {
type: 'string',
minLength: 1,
},
roomId: {
type: 'string',
minLength: 1,
},
},
required: ['username', 'roomId'],
additionalProperties: false,
},
],
};

const isRoomsMuteUnmuteUserProps = ajv.compile<RoomsMuteUnmuteUser>(RoomsMuteUnmuteUserSchema);

export const roomEndpoints = API.v1
.get(
'rooms.roles',
Expand Down Expand Up @@ -1231,6 +1232,66 @@ export const roomEndpoints = API.v1

await leaveRoomMethod(user, room._id);

return API.v1.success();
},
)
.post(
'rooms.muteUser',
{
authRequired: true,
body: isRoomsMuteUnmuteUserProps,
response: {
200: ajv.compile<void>({
type: 'object',
properties: {
success: { type: 'boolean', enum: [true] },
},
required: ['success'],
additionalProperties: false,
}),
400: validateBadRequestErrorResponse,
401: validateUnauthorizedErrorResponse,
},
},
async function action() {
const user = await getUserFromParams(this.bodyParams);

if (!user.username) {
return API.v1.failure('Invalid user');
}

await muteUserInRoom(this.userId, { rid: this.bodyParams.roomId, username: user.username });

return API.v1.success();
},
)
.post(
'rooms.unmuteUser',
{
authRequired: true,
body: isRoomsMuteUnmuteUserProps,
response: {
200: ajv.compile<void>({
type: 'object',
properties: {
success: { type: 'boolean', enum: [true] },
},
required: ['success'],
additionalProperties: false,
}),
400: validateBadRequestErrorResponse,
401: validateUnauthorizedErrorResponse,
},
},
async function action() {
const user = await getUserFromParams(this.bodyParams);

if (!user.username) {
return API.v1.failure('Invalid user');
}

await unmuteUserInRoom(this.userId, { rid: this.bodyParams.roomId, username: user.username });

return API.v1.success();
Comment thread
coderabbitai[bot] marked this conversation as resolved.
},
);
Expand Down
45 changes: 0 additions & 45 deletions packages/rest-typings/src/v1/rooms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -485,43 +485,6 @@ export type Notifications = {

type RoomsGetDiscussionsProps = PaginatedRequest<BaseRoomsProps>;

type RoomsMuteUnmuteUser = { userId: string; roomId: string } | { username: string; roomId: string };

const RoomsMuteUnmuteUserSchema = {
type: 'object',
oneOf: [
{
properties: {
userId: {
type: 'string',
minLength: 1,
},
roomId: {
type: 'string',
minLength: 1,
},
},
required: ['userId', 'roomId'],
additionalProperties: false,
},
{
properties: {
username: {
type: 'string',
minLength: 1,
},
roomId: {
type: 'string',
minLength: 1,
},
},
required: ['username', 'roomId'],
additionalProperties: false,
},
],
};

export const isRoomsMuteUnmuteUserProps = ajv.compile<RoomsMuteUnmuteUser>(RoomsMuteUnmuteUserSchema);
export type RoomsImagesProps = {
roomId: string;
startingFromId?: string;
Expand Down Expand Up @@ -823,14 +786,6 @@ export type RoomsEndpoints = {
GET: (params: RoomsIsMemberProps) => { isMember: boolean };
};

'/v1/rooms.muteUser': {
POST: (params: RoomsMuteUnmuteUser) => void;
};

'/v1/rooms.unmuteUser': {
POST: (params: RoomsMuteUnmuteUser) => void;
};

'/v1/rooms.images': {
GET: (params: RoomsImagesProps) => PaginatedResult<{
files: IUpload[];
Expand Down