chore: Deprecate mute/unmute meteor methods and convert to endpoint (#31811)

pull/32213/head
Yash Rajpal 2 years ago committed by GitHub
parent a8e1a46e2f
commit 9a6a7d0a40
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 5
      .changeset/fifty-planets-rhyme.md
  2. 6
      .changeset/lovely-trainers-kiss.md
  3. 41
      apps/meteor/app/api/server/v1/rooms.ts
  4. 6
      apps/meteor/client/views/room/hooks/useUserInfoActions/actions/useMuteUserAction.tsx
  5. 3
      apps/meteor/server/methods/muteUserInRoom.ts
  6. 3
      apps/meteor/server/methods/unmuteUserInRoom.ts
  7. 135
      apps/meteor/tests/end-to-end/api/09-rooms.js
  8. 46
      packages/rest-typings/src/v1/rooms.ts

@ -0,0 +1,5 @@
---
'@rocket.chat/meteor': patch
---
Deprecate muteUserInRoom and unmuteUserInRoom meteor methods

@ -0,0 +1,6 @@
---
'@rocket.chat/rest-typings': minor
'@rocket.chat/meteor': minor
---
Convert mute/unmute meteor methods to endpoints

@ -2,12 +2,14 @@ import { Media } from '@rocket.chat/core-services';
import type { IRoom, IUpload } from '@rocket.chat/core-typings';
import { Messages, Rooms, Users, Uploads } from '@rocket.chat/models';
import type { Notifications } from '@rocket.chat/rest-typings';
import { isGETRoomsNameExists, isRoomsImagesProps } from '@rocket.chat/rest-typings';
import { isGETRoomsNameExists, isRoomsImagesProps, isRoomsMuteUnmuteUserProps } from '@rocket.chat/rest-typings';
import { Meteor } from 'meteor/meteor';
import { isTruthy } from '../../../../lib/isTruthy';
import * as dataExport from '../../../../server/lib/dataExport';
import { eraseRoom } from '../../../../server/methods/eraseRoom';
import { muteUserInRoom } from '../../../../server/methods/muteUserInRoom';
import { unmuteUserInRoom } from '../../../../server/methods/unmuteUserInRoom';
import { canAccessRoomAsync, canAccessRoomIdAsync } from '../../../authorization/server/functions/canAccessRoom';
import { hasPermissionAsync } from '../../../authorization/server/functions/hasPermission';
import { saveRoomSettings } from '../../../channel-settings/server/methods/saveRoomSettings';
@ -19,6 +21,7 @@ import { settings } from '../../../settings/server';
import { API } from '../api';
import { composeRoomWithLastMessage } from '../helpers/composeRoomWithLastMessage';
import { getPaginationItems } from '../helpers/getPaginationItems';
import { getUserFromParams } from '../helpers/getUserFromParams';
import { getUploadFormData } from '../lib/getUploadFormData';
import {
findAdminRoom,
@ -678,3 +681,39 @@ 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();
},
},
);

@ -5,11 +5,11 @@ import {
useAllPermissions,
usePermission,
useSetModal,
useMethod,
useToastMessageDispatch,
useTranslation,
useUserRoom,
useUserSubscription,
useEndpoint,
} from '@rocket.chat/ui-contexts';
import React, { useMemo } from 'react';
@ -62,7 +62,7 @@ export const useMuteUserAction = (user: Pick<IUser, '_id' | 'username'>, rid: IR
const mutedMessage = isMuted ? 'User__username__unmuted_in_room__roomName__' : 'User__username__muted_in_room__roomName__';
const muteUser = useMethod(isMuted ? 'unmuteUserInRoom' : 'muteUserInRoom');
const muteUser = useEndpoint('POST', isMuted ? '/v1/rooms.unmuteUser' : '/v1/rooms.muteUser');
const muteUserOption = useMemo(() => {
const action = (): Promise<void> | void => {
@ -72,7 +72,7 @@ export const useMuteUserAction = (user: Pick<IUser, '_id' | 'username'>, rid: IR
throw new Error('User without username');
}
await muteUser({ rid, username: user.username });
await muteUser({ roomId: rid, username: user.username });
return dispatchToastMessage({
type: 'success',

@ -6,6 +6,7 @@ import { Match, check } from 'meteor/check';
import { Meteor } from 'meteor/meteor';
import { hasPermissionAsync } from '../../app/authorization/server/functions/hasPermission';
import { methodDeprecationLogger } from '../../app/lib/server/lib/deprecationWarningLogger';
import { RoomMemberActions } from '../../definition/IRoomTypeConfig';
import { callbacks } from '../../lib/callbacks';
import { roomCoordinator } from '../lib/rooms/roomCoordinator';
@ -80,6 +81,8 @@ export const muteUserInRoom = async (fromId: string, data: { rid: IRoom['_id'];
Meteor.methods<ServerMethods>({
async muteUserInRoom(data) {
methodDeprecationLogger.method('muteUserInRoom', '8.0.0');
check(
data,
Match.ObjectIncluding({

@ -6,6 +6,7 @@ import { Match, check } from 'meteor/check';
import { Meteor } from 'meteor/meteor';
import { hasPermissionAsync } from '../../app/authorization/server/functions/hasPermission';
import { methodDeprecationLogger } from '../../app/lib/server/lib/deprecationWarningLogger';
import { RoomMemberActions } from '../../definition/IRoomTypeConfig';
import { callbacks } from '../../lib/callbacks';
import { roomCoordinator } from '../lib/rooms/roomCoordinator';
@ -82,6 +83,8 @@ export const unmuteUserInRoom = async (fromId: string, data: { rid: IRoom['_id']
Meteor.methods<ServerMethods>({
async unmuteUserInRoom(data) {
methodDeprecationLogger.method('unmuteUserInRoom', '8.0.0');
const fromId = Meteor.userId();
check(

@ -2076,4 +2076,139 @@ describe('[Rooms]', function () {
await deleteRoom({ type: 'p', roomId });
});
});
describe('/rooms.muteUser', () => {
let testChannel;
before('create a channel', async () => {
const result = await createRoom({ type: 'c', name: `channel.test.${Date.now()}-${Math.random()}` });
testChannel = result.body.channel;
});
after(async () => {
await deleteRoom({ type: 'c', roomId: testChannel._id });
});
it('should invite rocket.cat user to room', () => {
return request
.post(api('channels.invite'))
.set(credentials)
.send({
roomId: testChannel._id,
username: 'rocket.cat',
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
expect(res.body).to.have.nested.property('channel.name', testChannel.name);
});
});
it('should mute the rocket.cat user', () => {
return request
.post(api('rooms.muteUser'))
.set(credentials)
.send({
roomId: testChannel._id,
username: 'rocket.cat',
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
});
});
it('should contain rocket.cat user in mute list', () => {
return request
.get(api('channels.info'))
.set(credentials)
.query({
roomId: testChannel._id,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
expect(res.body).to.have.nested.property('channel.name', testChannel.name);
expect(res.body.channel).to.have.property('muted').and.to.be.an('array');
expect(res.body.channel.muted).to.have.lengthOf(1);
expect(res.body.channel.muted[0]).to.be.equal('rocket.cat');
});
});
});
describe('/rooms.unmuteUser', () => {
let testChannel;
before('create a channel', async () => {
const result = await createRoom({ type: 'c', name: `channel.test.${Date.now()}-${Math.random()}` });
testChannel = result.body.channel;
await request
.post(api('rooms.saveRoomSettings'))
.set(credentials)
.send({
rid: testChannel._id,
readOnly: true,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
});
await request
.post(api('channels.invite'))
.set(credentials)
.send({
roomId: testChannel._id,
username: 'rocket.cat',
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
expect(res.body).to.have.nested.property('channel.name', testChannel.name);
});
});
after(async () => {
await deleteRoom({ type: 'c', roomId: testChannel._id });
});
it('should unmute the rocket.cat user in read-only room', () => {
return request
.post(api('rooms.unmuteUser'))
.set(credentials)
.send({
roomId: testChannel._id,
username: 'rocket.cat',
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
});
});
it('should contain rocket.cat user in unmute list', () => {
return request
.get(api('channels.info'))
.set(credentials)
.query({
roomId: testChannel._id,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
expect(res.body).to.have.nested.property('channel.name', testChannel.name);
expect(res.body.channel).to.have.property('unmuted').and.to.be.an('array');
expect(res.body.channel.unmuted).to.have.lengthOf(1);
expect(res.body.channel.unmuted[0]).to.be.equal('rocket.cat');
});
});
});
});

@ -436,6 +436,43 @@ 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;
@ -607,6 +644,15 @@ export type RoomsEndpoints = {
discussions: IRoom[];
}>;
};
'/v1/rooms.muteUser': {
POST: (params: RoomsMuteUnmuteUser) => void;
};
'/v1/rooms.unmuteUser': {
POST: (params: RoomsMuteUnmuteUser) => void;
};
'/v1/rooms.images': {
GET: (params: RoomsImagesProps) => PaginatedResult<{
files: IUpload[];

Loading…
Cancel
Save