Skip to content

Commit fd4f9b2

Browse files
chore: Adds deprecation warning on livechat:removeRoom with new endpoint replacing it (RocketChat#36958)
1 parent a4f615f commit fd4f9b2

7 files changed

Lines changed: 126 additions & 52 deletions

File tree

.changeset/three-turkeys-dress.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@rocket.chat/meteor": patch
3+
"@rocket.chat/rest-typings": patch
4+
---
5+
6+
Adds deprecation warning on `livechat:removeRoom` with new endpoint replacing it; `livechat/rooms.delete`

apps/meteor/app/livechat/server/api/v1/room.ts

Lines changed: 56 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ import {
1919
isPOSTLivechatRoomCloseByUserParams,
2020
isPOSTLivechatRoomsCloseAll,
2121
isPOSTLivechatRoomsCloseAllSuccessResponse,
22+
POSTLivechatRemoveRoomSuccess,
23+
isPOSTLivechatRemoveRoomParams,
24+
validateBadRequestErrorResponse,
25+
validateUnauthorizedErrorResponse,
26+
validateForbiddenErrorResponse,
2227
} from '@rocket.chat/rest-typings';
2328
import { check } from 'meteor/check';
2429

@@ -438,32 +443,61 @@ API.v1.addRoute(
438443
},
439444
);
440445

441-
const livechatRoomsEndpoints = API.v1.post(
442-
'livechat/rooms.removeAllClosedRooms',
443-
{
444-
response: {
445-
200: isPOSTLivechatRoomsCloseAllSuccessResponse,
446+
const livechatRoomsEndpoints = API.v1
447+
.post(
448+
'livechat/rooms.delete',
449+
{
450+
response: {
451+
200: POSTLivechatRemoveRoomSuccess,
452+
400: validateBadRequestErrorResponse,
453+
401: validateUnauthorizedErrorResponse,
454+
403: validateForbiddenErrorResponse,
455+
},
456+
authRequired: true,
457+
permissionsRequired: ['remove-closed-livechat-room'],
458+
body: isPOSTLivechatRemoveRoomParams,
446459
},
447-
authRequired: true,
448-
permissionsRequired: ['remove-closed-livechat-rooms'],
449-
body: isPOSTLivechatRoomsCloseAll,
450-
},
451-
async function action() {
452-
livechatLogger.info(`User ${this.userId} is removing all closed rooms`);
460+
async function action() {
461+
const { roomId } = this.bodyParams;
462+
463+
try {
464+
await removeOmnichannelRoom(roomId);
465+
return API.v1.success();
466+
} catch (error: unknown) {
467+
if (error instanceof Meteor.Error) {
468+
return API.v1.failure(error.reason);
469+
}
470+
471+
return API.v1.failure('error-removing-room');
472+
}
473+
},
474+
)
475+
.post(
476+
'livechat/rooms.removeAllClosedRooms',
477+
{
478+
response: {
479+
200: isPOSTLivechatRoomsCloseAllSuccessResponse,
480+
},
481+
authRequired: true,
482+
permissionsRequired: ['remove-closed-livechat-rooms'],
483+
body: isPOSTLivechatRoomsCloseAll,
484+
},
485+
async function action() {
486+
livechatLogger.info(`User ${this.userId} is removing all closed rooms`);
453487

454-
const params = this.bodyParams;
488+
const params = this.bodyParams;
455489

456-
const extraQuery = await callbacks.run('livechat.applyRoomRestrictions', {}, { userId: this.userId });
457-
const promises: Promise<void>[] = [];
458-
await LivechatRooms.findClosedRooms(params?.departmentIds, {}, extraQuery).forEach(({ _id }: IOmnichannelRoom) => {
459-
promises.push(removeOmnichannelRoom(_id));
460-
});
461-
await Promise.all(promises);
490+
const extraQuery = await callbacks.run('livechat.applyRoomRestrictions', {}, { userId: this.userId });
491+
const promises: Promise<void>[] = [];
492+
await LivechatRooms.findClosedRooms(params?.departmentIds, {}, extraQuery).forEach(({ _id }: IOmnichannelRoom) => {
493+
promises.push(removeOmnichannelRoom(_id));
494+
});
495+
await Promise.all(promises);
462496

463-
livechatLogger.info(`User ${this.userId} removed ${promises.length} closed rooms`);
464-
return API.v1.success({ removedRooms: promises.length });
465-
},
466-
);
497+
livechatLogger.info(`User ${this.userId} removed ${promises.length} closed rooms`);
498+
return API.v1.success({ removedRooms: promises.length });
499+
},
500+
);
467501

468502
type LivechatRoomsEndpoints = ExtractRoutesFromAPI<typeof livechatRoomsEndpoints>;
469503

apps/meteor/app/livechat/server/lib/rooms.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import type {
99
IOmnichannelRoom,
1010
TransferData,
1111
} from '@rocket.chat/core-typings';
12+
import { isOmnichannelRoom } from '@rocket.chat/core-typings';
1213
import {
1314
LivechatRooms,
1415
LivechatContacts,
@@ -267,6 +268,14 @@ export async function removeOmnichannelRoom(rid: string) {
267268
throw new Meteor.Error('error-invalid-room', 'Invalid room');
268269
}
269270

271+
if (!isOmnichannelRoom(room)) {
272+
throw new Meteor.Error('error-this-is-not-a-livechat-room');
273+
}
274+
275+
if (room.open) {
276+
throw new Meteor.Error('error-room-is-not-closed');
277+
}
278+
270279
const inquiry = await LivechatInquiry.findOneByRoomId(rid);
271280

272281
const result = await Promise.allSettled([

apps/meteor/app/livechat/server/methods/removeRoom.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { LivechatRooms } from '@rocket.chat/models';
44
import { Meteor } from 'meteor/meteor';
55

66
import { hasPermissionAsync } from '../../../authorization/server/functions/hasPermission';
7+
import { methodDeprecationLogger } from '../../../lib/server/lib/deprecationWarningLogger';
78
import { removeOmnichannelRoom } from '../lib/rooms';
89

910
declare module '@rocket.chat/ddp-client' {
@@ -15,6 +16,7 @@ declare module '@rocket.chat/ddp-client' {
1516

1617
Meteor.methods<ServerMethods>({
1718
async 'livechat:removeRoom'(rid) {
19+
methodDeprecationLogger.method('livechat:removeRoom', '8.0.0', '/v1/livechat/rooms.delete');
1820
const user = Meteor.userId();
1921
if (!user || !(await hasPermissionAsync(user, 'remove-closed-livechat-room'))) {
2022
throw new Meteor.Error('error-not-allowed', 'Not allowed', { method: 'livechat:removeRoom' });

apps/meteor/client/views/omnichannel/currentChats/hooks/useRemoveCurrentChatMutation.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
import type { IRoom } from '@rocket.chat/core-typings';
2-
import { useMethod } from '@rocket.chat/ui-contexts';
2+
import { useEndpoint } from '@rocket.chat/ui-contexts';
33
import type { UseMutationOptions, UseMutationResult } from '@tanstack/react-query';
44
import { useQueryClient, useMutation } from '@tanstack/react-query';
55

66
export const useRemoveCurrentChatMutation = (
7-
options?: Omit<UseMutationOptions<void, Error, IRoom['_id']>, 'mutationFn'>,
8-
): UseMutationResult<void, Error, IRoom['_id']> => {
9-
const removeRoom = useMethod('livechat:removeRoom');
7+
options?: Omit<UseMutationOptions<null, Error, IRoom['_id']>, 'mutationFn'>,
8+
): UseMutationResult<null, Error, IRoom['_id']> => {
9+
const removeRoom = useEndpoint('POST', '/v1/livechat/rooms.delete');
1010
const queryClient = useQueryClient();
1111

1212
return useMutation({
13-
mutationFn: (rid) => removeRoom(rid),
13+
mutationFn: (rid) => removeRoom({ roomId: rid }),
1414
...options,
1515

1616
onSuccess: (...args) => {

apps/meteor/tests/e2e/utils/omnichannel/rooms.ts

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,7 @@ export const createRoom = async (api: BaseTest['api'], { visitorToken, agentId }
5454
data: room,
5555
async delete() {
5656
await closeRoom(api, { roomId: room._id, visitorToken });
57-
return api.post('/method.call/livechat:removeRoom', {
58-
message: JSON.stringify({
59-
msg: 'method',
60-
id: '16',
61-
method: 'livechat:removeRoom',
62-
params: [room._id],
63-
}),
64-
});
57+
return api.post('/livechat/rooms.delete', { roomId: room._id });
6558
},
6659
};
6760
};

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

Lines changed: 47 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4109,6 +4109,53 @@ export const isPOSTLivechatRoomsCloseAllSuccessResponse = ajv.compile<{ removedR
41094109
POSTLivechatRoomsCloseAllSuccessResponseSchema,
41104110
);
41114111

4112+
type POSTLivechatRemoveRoomParams = {
4113+
roomId: string;
4114+
};
4115+
4116+
const POSTLivechatRemoveRoomParamsSchema = {
4117+
type: 'object',
4118+
properties: {
4119+
roomId: {
4120+
type: 'string',
4121+
},
4122+
},
4123+
required: ['roomId'],
4124+
additionalProperties: false,
4125+
};
4126+
4127+
export const isPOSTLivechatRemoveRoomParams = ajv.compile<POSTLivechatRemoveRoomParams>(POSTLivechatRemoveRoomParamsSchema);
4128+
4129+
const POSTLivechatRemoveRoomSuccessSchema = {
4130+
type: 'object',
4131+
properties: {
4132+
success: {
4133+
type: 'boolean',
4134+
enum: [true],
4135+
},
4136+
},
4137+
additionalProperties: false,
4138+
};
4139+
4140+
export const POSTLivechatRemoveRoomSuccess = ajv.compile<void>(POSTLivechatRemoveRoomSuccessSchema);
4141+
4142+
type POSTLivechatRemoveCustomFields = {
4143+
customFieldId: string;
4144+
};
4145+
4146+
const POSTLivechatRemoveCustomFieldsSchema = {
4147+
type: 'object',
4148+
properties: {
4149+
customFieldId: {
4150+
type: 'string',
4151+
},
4152+
},
4153+
required: ['customFieldId'],
4154+
additionalProperties: false,
4155+
};
4156+
4157+
export const isPOSTLivechatRemoveCustomFields = ajv.compile<POSTLivechatRemoveCustomFields>(POSTLivechatRemoveCustomFieldsSchema);
4158+
41124159
const POSTLivechatSaveCustomFieldsSchema = {
41134160
type: 'object',
41144161
properties: {
@@ -4228,23 +4275,6 @@ export const POSTLivechatSaveCustomFieldSuccess = ajv.compile<{ customField: ILi
42284275
POSTLivechatSaveCustomFieldSuccessSchema,
42294276
);
42304277

4231-
type POSTLivechatRemoveCustomFields = {
4232-
customFieldId: string;
4233-
};
4234-
4235-
const POSTLivechatRemoveCustomFieldsSchema = {
4236-
type: 'object',
4237-
properties: {
4238-
customFieldId: {
4239-
type: 'string',
4240-
},
4241-
},
4242-
required: ['customFieldId'],
4243-
additionalProperties: false,
4244-
};
4245-
4246-
export const isPOSTLivechatRemoveCustomFields = ajv.compile<POSTLivechatRemoveCustomFields>(POSTLivechatRemoveCustomFieldsSchema);
4247-
42484278
const POSTLivechatRemoveCustomFieldSuccessSchema = {
42494279
type: 'object',
42504280
properties: {

0 commit comments

Comments
 (0)