From d79f6d64099583566675faee2665cd7730f2aeef Mon Sep 17 00:00:00 2001 From: Abhinav Kumar Date: Thu, 10 Oct 2024 01:20:32 +0530 Subject: [PATCH] chore!: remove deprecated method deleteMessage (#33472) --- .changeset/kind-clocks-smash.md | 5 + apps/meteor/app/lib/server/index.ts | 1 - .../app/lib/server/methods/deleteMessage.ts | 35 --- apps/meteor/client/lib/chats/ChatAPI.ts | 2 +- apps/meteor/client/lib/chats/data.ts | 18 +- .../lib/chats/flows/requestMessageDeletion.ts | 2 +- apps/meteor/tests/end-to-end/api/methods.ts | 278 +----------------- 7 files changed, 24 insertions(+), 317 deletions(-) create mode 100644 .changeset/kind-clocks-smash.md delete mode 100644 apps/meteor/app/lib/server/methods/deleteMessage.ts diff --git a/.changeset/kind-clocks-smash.md b/.changeset/kind-clocks-smash.md new file mode 100644 index 000000000000..c108c9560a73 --- /dev/null +++ b/.changeset/kind-clocks-smash.md @@ -0,0 +1,5 @@ +--- +'@rocket.chat/meteor': major +--- + +Removes deprecated `deleteMessage` method. Moving forward, use the `chat.delete` endpoint. diff --git a/apps/meteor/app/lib/server/index.ts b/apps/meteor/app/lib/server/index.ts index ecfdb2ed81cd..f56827baeb8a 100644 --- a/apps/meteor/app/lib/server/index.ts +++ b/apps/meteor/app/lib/server/index.ts @@ -17,7 +17,6 @@ import './methods/cleanRoomHistory'; import './methods/createChannel'; import './methods/createPrivateGroup'; import './methods/createToken'; -import './methods/deleteMessage'; import './methods/deleteUserOwnAccount'; import './methods/executeSlashCommandPreview'; import './startup/mentionUserNotInChannel'; diff --git a/apps/meteor/app/lib/server/methods/deleteMessage.ts b/apps/meteor/app/lib/server/methods/deleteMessage.ts deleted file mode 100644 index b0be64c245ef..000000000000 --- a/apps/meteor/app/lib/server/methods/deleteMessage.ts +++ /dev/null @@ -1,35 +0,0 @@ -import type { IMessage } from '@rocket.chat/core-typings'; -import type { ServerMethods } from '@rocket.chat/ddp-client'; -import { Meteor } from 'meteor/meteor'; - -import { deleteMessageValidatingPermission } from '../functions/deleteMessage'; -import { methodDeprecationLogger } from '../lib/deprecationWarningLogger'; - -declare module '@rocket.chat/ddp-client' { - // eslint-disable-next-line @typescript-eslint/naming-convention - interface ServerMethods { - deleteMessage({ _id }: Pick): void; - } -} - -Meteor.methods({ - async deleteMessage(message) { - methodDeprecationLogger.method('deleteMessage', '7.0.0'); - - check( - message, - Match.ObjectIncluding({ - _id: String, - }), - ); - - const uid = Meteor.userId(); - - if (!uid) { - throw new Meteor.Error('error-invalid-user', 'Invalid user', { - method: 'deleteMessage', - }); - } - return deleteMessageValidatingPermission(message, uid); - }, -}); diff --git a/apps/meteor/client/lib/chats/ChatAPI.ts b/apps/meteor/client/lib/chats/ChatAPI.ts index 30dd5909ee03..325073d43837 100644 --- a/apps/meteor/client/lib/chats/ChatAPI.ts +++ b/apps/meteor/client/lib/chats/ChatAPI.ts @@ -79,7 +79,7 @@ export type DataAPI = { canUpdateMessage(message: IMessage): Promise; updateMessage(message: Pick & Partial>, previewUrls?: string[]): Promise; canDeleteMessage(message: IMessage): Promise; - deleteMessage(mid: IMessage['_id']): Promise; + deleteMessage(msgIdOrMsg: IMessage | IMessage['_id']): Promise; getDraft(mid: IMessage['_id'] | undefined): Promise; discardDraft(mid: IMessage['_id'] | undefined): Promise; saveDraft(mid: IMessage['_id'] | undefined, text: string): Promise; diff --git a/apps/meteor/client/lib/chats/data.ts b/apps/meteor/client/lib/chats/data.ts index 445f61f27226..4f6263147ba6 100644 --- a/apps/meteor/client/lib/chats/data.ts +++ b/apps/meteor/client/lib/chats/data.ts @@ -214,8 +214,22 @@ export const createDataAPI = ({ rid, tmid }: { rid: IRoom['_id']; tmid: IMessage return deleteAllowed && onTimeForDelete; }; - const deleteMessage = async (mid: IMessage['_id']): Promise => { - await sdk.call('deleteMessage', { _id: mid }); + const deleteMessage = async (msgIdOrMsg: IMessage | IMessage['_id']): Promise => { + let msgId: string; + let roomId: string; + if (typeof msgIdOrMsg === 'string') { + msgId = msgIdOrMsg; + const msg = await findMessageByID(msgId); + if (!msg) { + throw new Error('Message not found'); + } + roomId = msg.rid; + } else { + msgId = msgIdOrMsg._id; + roomId = msgIdOrMsg.rid; + } + + await sdk.rest.post('/v1/chat.delete', { msgId, roomId }); }; const drafts = new Map(); diff --git a/apps/meteor/client/lib/chats/flows/requestMessageDeletion.ts b/apps/meteor/client/lib/chats/flows/requestMessageDeletion.ts index d10086840529..130266284b48 100644 --- a/apps/meteor/client/lib/chats/flows/requestMessageDeletion.ts +++ b/apps/meteor/client/lib/chats/flows/requestMessageDeletion.ts @@ -21,7 +21,7 @@ export const requestMessageDeletion = async (chat: ChatAPI, message: IMessage): dispatchToastMessage({ type: 'error', message: t('Message_deleting_blocked') }); return; } - await chat.data.deleteMessage(message._id); + await chat.data.deleteMessage(message); imperativeModal.close(); diff --git a/apps/meteor/tests/end-to-end/api/methods.ts b/apps/meteor/tests/end-to-end/api/methods.ts index e3c42389e506..9e05fba88b4c 100644 --- a/apps/meteor/tests/end-to-end/api/methods.ts +++ b/apps/meteor/tests/end-to-end/api/methods.ts @@ -2,7 +2,7 @@ import type { Credentials } from '@rocket.chat/api-client'; import type { IMessage, IRoom, IThreadMessage, IUser } from '@rocket.chat/core-typings'; import { Random } from '@rocket.chat/random'; import { expect } from 'chai'; -import { after, before, beforeEach, describe, it } from 'mocha'; +import { after, before, describe, it } from 'mocha'; import { api, credentials, getCredentials, methodCall, request } from '../../data/api-data'; import { sendSimpleMessage } from '../../data/chat.helper'; @@ -2519,282 +2519,6 @@ describe('Meteor.methods', () => { }); }); - describe('[@deleteMessage]', () => { - let rid: IRoom['_id']; - let messageId: IMessage['_id']; - - before('create room', (done) => { - const channelName = `methods-test-channel-${Date.now()}`; - void request - .post(api('groups.create')) - .set(credentials) - .send({ - name: channelName, - }) - .expect('Content-Type', 'application/json') - .expect(200) - .expect((res) => { - expect(res.body).to.have.property('success', true); - expect(res.body).to.have.nested.property('group._id'); - expect(res.body).to.have.nested.property('group.name', channelName); - expect(res.body).to.have.nested.property('group.t', 'p'); - expect(res.body).to.have.nested.property('group.msgs', 0); - rid = res.body.group._id; - }) - .end(done); - }); - - beforeEach('send message with URL', (done) => { - void request - .post(methodCall('sendMessage')) - .set(credentials) - .send({ - message: JSON.stringify({ - method: 'sendMessage', - params: [ - { - _id: `${Date.now() + Math.random()}`, - rid, - msg: 'test message with https://github.com', - }, - ], - id: 'id', - msg: 'method', - }), - }) - .expect('Content-Type', 'application/json') - .expect(200) - .expect((res) => { - expect(res.body).to.have.a.property('success', true); - expect(res.body).to.have.a.property('message').that.is.a('string'); - - const data = JSON.parse(res.body.message); - expect(data).to.have.a.property('result').that.is.an('object'); - expect(data.result).to.have.a.property('urls').that.is.an('array'); - expect(data.result.urls[0].url).to.equal('https://github.com'); - messageId = data.result._id; - }) - .end(done); - }); - - after(() => - Promise.all([ - deleteRoom({ type: 'p', roomId: rid }), - updatePermission('bypass-time-limit-edit-and-delete', ['bot', 'app']), - updateSetting('Message_AllowEditing_BlockEditInMinutes', 0), - ]), - ); - - it('should delete a message', (done) => { - void request - .post(methodCall('deleteMessage')) - .set(credentials) - .send({ - message: JSON.stringify({ - method: 'deleteMessage', - params: [{ _id: messageId, rid }], - id: 'id', - msg: 'method', - }), - }) - .expect('Content-Type', 'application/json') - .expect(200) - .expect((res) => { - expect(res.body).to.have.a.property('success', true); - expect(res.body).to.have.a.property('message').that.is.a('string'); - const data = JSON.parse(res.body.message); - expect(data).to.have.a.property('msg', 'result'); - expect(data).to.have.a.property('id', 'id'); - }) - .end(done); - }); - - it('should delete a message when bypass time limits permission is enabled', async () => { - await Promise.all([ - updatePermission('bypass-time-limit-edit-and-delete', ['admin']), - updateSetting('Message_AllowEditing_BlockEditInMinutes', 0.01), - ]); - - await request - .post(methodCall('deleteMessage')) - .set(credentials) - .send({ - message: JSON.stringify({ - method: 'deleteMessage', - params: [{ _id: messageId, rid }], - id: 'id', - msg: 'method', - }), - }) - .expect('Content-Type', 'application/json') - .expect(200) - .expect((res) => { - expect(res.body).to.have.a.property('success', true); - expect(res.body).to.have.a.property('message').that.is.a('string'); - const data = JSON.parse(res.body.message); - expect(data).to.have.a.property('msg', 'result'); - expect(data).to.have.a.property('id', 'id'); - }); - - await Promise.all([ - updatePermission('bypass-time-limit-edit-and-delete', ['bot', 'app']), - updateSetting('Message_AllowEditing_BlockEditInMinutes', 0), - ]); - }); - - describe('message deletion when user is not part of the room', () => { - let ridTestRoom: IRoom['_id']; - let messageIdTestRoom: IMessage['_id']; - let testUser: TestUser; - let testUserCredentials: Credentials; - - before('create room, add new owner, and leave room', async () => { - testUser = await createUser(); - testUserCredentials = await login(testUser.username, password); - const channelName = `methods-test-channel-${Date.now()}`; - - await request - .post(api('groups.create')) - .set(testUserCredentials) - .send({ - name: channelName, - }) - .expect('Content-Type', 'application/json') - .expect(200) - .expect((res) => { - expect(res.body).to.have.property('success', true); - expect(res.body).to.have.nested.property('group._id'); - expect(res.body).to.have.nested.property('group.name', channelName); - expect(res.body).to.have.nested.property('group.t', 'p'); - expect(res.body).to.have.nested.property('group.msgs', 0); - ridTestRoom = res.body.group._id; - }); - - await request - .post(methodCall('sendMessage')) - .set(testUserCredentials) - .send({ - message: JSON.stringify({ - method: 'sendMessage', - params: [ - { - _id: `${Date.now() + Math.random()}`, - rid: ridTestRoom, - msg: 'just a random test message', - }, - ], - id: 'id', - msg: 'method', - }), - }) - .expect('Content-Type', 'application/json') - .expect(200) - .expect((res) => { - expect(res.body).to.have.a.property('success', true); - expect(res.body).to.have.a.property('message').that.is.a('string'); - const data = JSON.parse(res.body.message); - expect(data).to.have.a.property('result').that.is.an('object'); - messageIdTestRoom = data.result._id; - }); - - await request - .post(methodCall('addUsersToRoom')) - .set(testUserCredentials) - .send({ - message: JSON.stringify({ - method: 'addUsersToRoom', - params: [ - { - rid: ridTestRoom, - users: ['rocket.cat'], - }, - ], - id: 'id', - msg: 'method', - }), - }) - .expect('Content-Type', 'application/json') - .expect(200) - .expect((res) => { - expect(res.body).to.have.a.property('success', true); - expect(res.body).to.have.a.property('message').that.is.a('string'); - }); - - await request - .post(api('groups.addOwner')) - .set(testUserCredentials) - .send({ - roomId: ridTestRoom, - userId: 'rocket.cat', - }) - .expect((res) => { - expect(res.body).to.have.a.property('success', true); - }); - - await request - .post(api('groups.leave')) - .set(testUserCredentials) - .send({ - roomId: ridTestRoom, - }) - .expect(200) - .expect((res) => { - expect(res.body).to.have.a.property('success', true); - }); - }); - - it('should not delete a message if the user is no longer member of the room', async () => { - await request - .post(methodCall('deleteMessage')) - .set(testUserCredentials) - .send({ - message: JSON.stringify({ - method: 'deleteMessage', - params: [{ _id: messageIdTestRoom, rid: ridTestRoom }], - id: 'id', - msg: 'method', - }), - }) - .expect('Content-Type', 'application/json') - .expect(200) - .expect((res) => { - expect(res.body).to.have.a.property('success', true); - expect(res.body).to.have.a.property('message').that.is.a('string'); - const data = JSON.parse(res.body.message); - expect(data).to.have.a.property('msg', 'result'); - expect(data).to.have.a.property('id', 'id'); - expect(data.error).to.have.a.property('error', 'error-action-not-allowed'); - }); - }); - - it('should not delete a message if the user was never part of the room', async () => { - await request - .post(methodCall('deleteMessage')) - .set(credentials) - .send({ - message: JSON.stringify({ - method: 'deleteMessage', - params: [{ _id: messageIdTestRoom, rid: ridTestRoom }], - id: 'id', - msg: 'method', - }), - }) - .expect('Content-Type', 'application/json') - .expect(200) - .expect((res) => { - expect(res.body).to.have.a.property('success', true); - expect(res.body).to.have.a.property('message').that.is.a('string'); - const data = JSON.parse(res.body.message); - expect(data).to.have.a.property('msg', 'result'); - expect(data).to.have.a.property('id', 'id'); - expect(data.error).to.have.a.property('error', 'error-action-not-allowed'); - }); - }); - - after(() => Promise.all([deleteRoom({ type: 'p', roomId: ridTestRoom }), deleteUser(testUser)])); - }); - }); - describe('[@setUserActiveStatus]', () => { let testUser: TestUser; let testUser2: TestUser;