Skip to content

Commit c635c9f

Browse files
tiagoevanpabhinavkrindougfabris
authored
fix: API method rooms.delete deleting main team room (RocketChat#36790)
Co-authored-by: Abhinav Kumar <15830206+abhinavkrin@users.noreply.github.com> Co-authored-by: Douglas Fabris <27704687+dougfabris@users.noreply.github.com>
1 parent 6f13304 commit c635c9f

4 files changed

Lines changed: 58 additions & 9 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@rocket.chat/meteor': patch
3+
---
4+
5+
Fixes an issue where the API method `rooms.delete` inadvertently deletes the main room of a team

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

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Media, Team } from '@rocket.chat/core-services';
1+
import { Media, MeteorError, Team } from '@rocket.chat/core-services';
22
import type { IRoom, IUpload } from '@rocket.chat/core-typings';
33
import { isPrivateRoom, isPublicRoom } from '@rocket.chat/core-typings';
44
import { Messages, Rooms, Users, Uploads, Subscriptions } from '@rocket.chat/models';
@@ -130,7 +130,21 @@ API.v1.addRoute(
130130
return API.v1.failure("The 'roomId' param is required");
131131
}
132132

133-
await eraseRoom(roomId, this.userId);
133+
const room = await Rooms.findOneById(roomId);
134+
135+
if (!room) {
136+
throw new MeteorError('error-invalid-room', 'Invalid room', {
137+
method: 'eraseRoom',
138+
});
139+
}
140+
141+
if (room.teamMain) {
142+
throw new Meteor.Error('error-cannot-delete-team-channel', 'Cannot delete a team channel', {
143+
method: 'eraseRoom',
144+
});
145+
}
146+
147+
await eraseRoom(room, this.userId);
134148

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

apps/meteor/server/lib/eraseRoom.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
import { AppEvents, Apps } from '@rocket.chat/apps';
22
import { Message, Team } from '@rocket.chat/core-services';
3+
import type { IRoom } from '@rocket.chat/core-typings';
34
import { Rooms } from '@rocket.chat/models';
45
import { Meteor } from 'meteor/meteor';
56

67
import { roomCoordinator } from './rooms/roomCoordinator';
78
import { hasPermissionAsync } from '../../app/authorization/server/functions/hasPermission';
89
import { deleteRoom } from '../../app/lib/server/functions/deleteRoom';
910

10-
export async function eraseRoom(rid: string, uid: string): Promise<void> {
11-
const room = await Rooms.findOneById(rid);
11+
export async function eraseRoom(roomOrId: string | IRoom, uid: string): Promise<void> {
12+
const room = typeof roomOrId === 'string' ? await Rooms.findOneById(roomOrId) : roomOrId;
1213

1314
if (!room) {
1415
throw new Meteor.Error('error-invalid-room', 'Invalid room', {
@@ -46,7 +47,7 @@ export async function eraseRoom(rid: string, uid: string): Promise<void> {
4647
}
4748
}
4849

49-
await deleteRoom(rid);
50+
await deleteRoom(room._id);
5051

5152
if (team) {
5253
const user = await Meteor.userAsync();

apps/meteor/tests/end-to-end/api/rooms.ts

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2598,13 +2598,30 @@ describe('[Rooms]', () => {
25982598

25992599
describe('/rooms.delete', () => {
26002600
let testChannel: IRoom;
2601+
let testTeam: ITeam;
2602+
let testUser: IUser;
2603+
let testUser2: IUser;
2604+
let userCredentials: Credentials;
26012605

2602-
before('create an channel', async () => {
2603-
const result = await createRoom({ type: 'c', name: `channel.test.${Date.now()}-${Math.random()}` });
2604-
testChannel = result.body.channel;
2606+
before('create channel and team', async () => {
2607+
testUser = await createUser();
2608+
testUser2 = await createUser();
2609+
userCredentials = await login(testUser.username, password);
2610+
2611+
const {
2612+
body: { channel },
2613+
} = await createRoom({ type: 'c', name: `channel.test.${Date.now()}-${Math.random()}` });
2614+
testChannel = channel;
2615+
testTeam = await createTeam(userCredentials, `team.test.${Date.now()}-${Math.random()}`, TEAM_TYPE.PUBLIC, [
2616+
testUser.username as string,
2617+
testUser2.username as string,
2618+
]);
26052619
});
26062620

2607-
after(() => deleteRoom({ type: 'c', roomId: testChannel._id }));
2621+
after('delete channel and team', async () => {
2622+
await deleteTeam(userCredentials, testTeam.name);
2623+
await deleteRoom({ type: 'c', roomId: testChannel._id });
2624+
});
26082625

26092626
it('should throw an error when roomId is not provided', (done) => {
26102627
void request
@@ -2643,6 +2660,18 @@ describe('[Rooms]', () => {
26432660
})
26442661
.end(done);
26452662
});
2663+
it('should throw an error when room is a main team room', (done) => {
2664+
void request
2665+
.post(api('rooms.delete'))
2666+
.set(credentials)
2667+
.send({ roomId: testTeam.roomId })
2668+
.expect('Content-Type', 'application/json')
2669+
.expect(400)
2670+
.expect((res) => {
2671+
expect(res.body).to.have.property('success', false);
2672+
})
2673+
.end(done);
2674+
});
26462675
});
26472676

26482677
describe('rooms.saveRoomSettings', () => {

0 commit comments

Comments
 (0)