diff --git a/.changeset/seven-badgers-dress.md b/.changeset/seven-badgers-dress.md new file mode 100644 index 0000000000000..3d2b1ef6ad85b --- /dev/null +++ b/.changeset/seven-badgers-dress.md @@ -0,0 +1,5 @@ +--- +"@rocket.chat/meteor": major +--- + +Removes deprecated Realtime API method: `livechat:changeLivechatStatus` diff --git a/apps/meteor/app/livechat/server/index.ts b/apps/meteor/app/livechat/server/index.ts index dc423707d4d42..5b4cd880eed01 100644 --- a/apps/meteor/app/livechat/server/index.ts +++ b/apps/meteor/app/livechat/server/index.ts @@ -15,7 +15,6 @@ import './hooks/saveLastMessageToInquiry'; import './hooks/afterUserActions'; import './hooks/afterAgentRemoved'; import './hooks/afterSaveOmnichannelMessage'; -import './methods/changeLivechatStatus'; import './methods/closeRoom'; import './methods/getAnalyticsChartData'; import './methods/getRoutingConfig'; diff --git a/apps/meteor/app/livechat/server/methods/changeLivechatStatus.ts b/apps/meteor/app/livechat/server/methods/changeLivechatStatus.ts deleted file mode 100644 index c52f7a8a2e0b0..0000000000000 --- a/apps/meteor/app/livechat/server/methods/changeLivechatStatus.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { ILivechatAgentStatus } from '@rocket.chat/core-typings'; -import type { ServerMethods } from '@rocket.chat/ddp-client'; -import { Users } from '@rocket.chat/models'; -import { Meteor } from 'meteor/meteor'; - -import { hasPermissionAsync } from '../../../authorization/server/functions/hasPermission'; -import { methodDeprecationLogger } from '../../../lib/server/lib/deprecationWarningLogger'; -import { setUserStatusLivechat, allowAgentChangeServiceStatus } from '../lib/utils'; - -declare module '@rocket.chat/ddp-client' { - // eslint-disable-next-line @typescript-eslint/naming-convention - interface ServerMethods { - 'livechat:changeLivechatStatus'(params?: { status?: ILivechatAgentStatus; agentId?: string }): unknown; - } -} - -Meteor.methods({ - async 'livechat:changeLivechatStatus'({ status, agentId = Meteor.userId() } = {}) { - methodDeprecationLogger.method('livechat:changeLivechatStatus', '7.0.0', '/v1/livechat/agent.status'); - - const uid = Meteor.userId(); - - if (!uid || !agentId) { - throw new Meteor.Error('error-not-allowed', 'Not allowed', { - method: 'livechat:changeLivechatStatus', - }); - } - - const agent = await Users.findOneAgentById(agentId, { - projection: { - status: 1, - statusLivechat: 1, - }, - }); - - if (!agent) { - throw new Meteor.Error('error-not-allowed', 'Invalid Agent Id', { - method: 'livechat:changeLivechatStatus', - }); - } - - if (status && !['available', 'not-available'].includes(status)) { - throw new Meteor.Error('error-not-allowed', 'Invalid Status', { - method: 'livechat:changeLivechatStatus', - }); - } - - const newStatus: ILivechatAgentStatus = - status || - (agent.statusLivechat === ILivechatAgentStatus.AVAILABLE ? ILivechatAgentStatus.NOT_AVAILABLE : ILivechatAgentStatus.AVAILABLE); - - if (newStatus === agent.statusLivechat) { - return; - } - - if (agentId !== uid) { - if (!(await hasPermissionAsync(uid, 'manage-livechat-agents'))) { - throw new Meteor.Error('error-not-allowed', 'Not allowed', { - method: 'livechat:changeLivechatStatus', - }); - } - return setUserStatusLivechat(agentId, newStatus); - } - - if (!(await allowAgentChangeServiceStatus(newStatus, agentId))) { - throw new Meteor.Error('error-business-hours-are-closed', 'Not allowed', { - method: 'livechat:changeLivechatStatus', - }); - } - - return setUserStatusLivechat(agentId, newStatus); - }, -}); diff --git a/apps/meteor/tests/end-to-end/api/livechat/methods/changeLivechatStatus.ts b/apps/meteor/tests/end-to-end/api/livechat/methods/changeLivechatStatus.ts deleted file mode 100644 index 9067965f4d18d..0000000000000 --- a/apps/meteor/tests/end-to-end/api/livechat/methods/changeLivechatStatus.ts +++ /dev/null @@ -1,231 +0,0 @@ -import type { Credentials } from '@rocket.chat/api-client'; -import type { ILivechatAgent, IUser } from '@rocket.chat/core-typings'; -import { expect } from 'chai'; -import { after, before, describe, it } from 'mocha'; -import type { Response } from 'supertest'; - -import { getCredentials, request, credentials, methodCall } from '../../../../data/api-data'; -import { disableDefaultBusinessHour, makeDefaultBusinessHourActiveAndClosed } from '../../../../data/livechat/businessHours'; -import { createAgent } from '../../../../data/livechat/rooms'; -import { updatePermission, updateSetting } from '../../../../data/permissions.helper'; -import { password } from '../../../../data/user'; -import { createUser, deleteUser, getMe, login } from '../../../../data/users.helper'; - -describe('livechat:changeLivechatStatus', () => { - let agent: { user: IUser; credentials: Credentials }; - - before((done) => getCredentials(done)); - - before(async () => { - await updateSetting('Livechat_enabled', true); - - const user = await createUser(); - const userCredentials = await login(user.username, password); - await createAgent(user.username); - - agent = { - user, - credentials: userCredentials, - }; - }); - - after(async () => { - await deleteUser(agent.user); - }); - - describe('changeLivechatStatus', () => { - // eslint-disable-next-line no-restricted-properties - it('should return an "unauthorized error" when the user does not have the necessary permission to change other status', async () => { - await updatePermission('manage-livechat-agents', []); - await request - .post(methodCall('livechat:changeLivechatStatus')) - .set(credentials) - .send({ - message: JSON.stringify({ - method: 'livechat:changeLivechatStatus', - params: [{ status: 'not-available', agentId: agent.user._id }], - id: 'id', - msg: 'method', - }), - }) - .expect(200) - .expect((res: Response) => { - expect(res.body).to.have.property('success', true); - const parsedBody = JSON.parse(res.body.message); - expect(parsedBody).to.have.property('error'); - expect(parsedBody.error).to.have.property('error', 'error-not-allowed'); - }); - - await updatePermission('manage-livechat-agents', ['admin']); - }); - it('should return an error if user is not an agent', async () => { - const user = await createUser(); - const userCredentials = await login(user.username, password); - await request - .post(methodCall('livechat:changeLivechatStatus')) - .set(userCredentials) - .send({ - message: JSON.stringify({ - method: 'livechat:changeLivechatStatus', - params: [{ status: 'available', agentId: user._id }], - id: 'id', - msg: 'method', - }), - }) - .expect(200) - .expect((res: Response) => { - expect(res.body).to.have.property('success', true); - const parsedBody = JSON.parse(res.body.message); - expect(parsedBody).to.have.property('error'); - expect(parsedBody.error).to.have.property('error', 'error-not-allowed'); - expect(parsedBody.error).to.have.property('reason', 'Invalid Agent Id'); - }); - - // cleanup - await deleteUser(user); - }); - it('should return an error if status is not valid', async () => { - await request - .post(methodCall('livechat:changeLivechatStatus')) - .set(agent.credentials) - .send({ - message: JSON.stringify({ - method: 'livechat:changeLivechatStatus', - params: [{ status: 'invalid-status', agentId: agent.user._id }], - id: 'id', - msg: 'method', - }), - }) - .expect(200) - .expect((res: Response) => { - expect(res.body).to.have.property('success', true); - const parsedBody = JSON.parse(res.body.message); - expect(parsedBody).to.have.property('error'); - expect(parsedBody.error).to.have.property('error', 'error-not-allowed'); - expect(parsedBody.error).to.have.property('reason', 'Invalid Status'); - }); - }); - it('should return an error if agentId param is not valid', async () => { - await request - .post(methodCall('livechat:changeLivechatStatus')) - .set(agent.credentials) - .send({ - message: JSON.stringify({ - method: 'livechat:changeLivechatStatus', - params: [{ status: 'available', agentId: 'invalid-agent-id' }], - id: 'id', - msg: 'method', - }), - }) - .expect(200) - .expect((res: Response) => { - expect(res.body).to.have.property('success', true); - const parsedBody = JSON.parse(res.body.message); - expect(parsedBody).to.have.property('error'); - expect(parsedBody.error).to.have.property('error', 'error-not-allowed'); - expect(parsedBody.error).to.have.property('reason', 'Invalid Agent Id'); - }); - }); - it('should change logged in users status', async () => { - const currentUser: ILivechatAgent = await getMe(agent.credentials); - const currentStatus = currentUser.statusLivechat; - const newStatus = currentStatus === 'available' ? 'not-available' : 'available'; - - await request - .post(methodCall('livechat:changeLivechatStatus')) - .set(agent.credentials) - .send({ - message: JSON.stringify({ - method: 'livechat:changeLivechatStatus', - params: [{ status: newStatus, agentId: currentUser._id }], - id: 'id', - msg: 'method', - }), - }) - .expect(200) - .expect((res: Response) => { - expect(res.body).to.have.property('success', true); - const parsedBody = JSON.parse(res.body.message); - expect(parsedBody).to.not.have.property('error'); - }); - }); - it('should allow managers to change other agents status', async () => { - await updatePermission('manage-livechat-agents', ['admin']); - - const currentUser: ILivechatAgent = await getMe(agent.credentials); - const currentStatus = currentUser.statusLivechat; - const newStatus = currentStatus === 'available' ? 'not-available' : 'available'; - - await request - .post(methodCall('livechat:changeLivechatStatus')) - .set(credentials) - .send({ - message: JSON.stringify({ - method: 'livechat:changeLivechatStatus', - params: [{ status: newStatus, agentId: currentUser._id }], - id: 'id', - msg: 'method', - }), - }) - .expect(200) - .expect((res: Response) => { - expect(res.body).to.have.property('success', true); - const parsedBody = JSON.parse(res.body.message); - expect(parsedBody).to.not.have.property('error'); - }); - }); - it('should throw an error if agent tries to make themselves available outside of Business hour', async () => { - await makeDefaultBusinessHourActiveAndClosed(); - - const currentUser: ILivechatAgent = await getMe(agent.credentials); - const currentStatus = currentUser.statusLivechat; - const newStatus = currentStatus === 'available' ? 'not-available' : 'available'; - - await request - .post(methodCall('livechat:changeLivechatStatus')) - .set(agent.credentials) - .send({ - message: JSON.stringify({ - method: 'livechat:changeLivechatStatus', - params: [{ status: newStatus, agentId: currentUser._id }], - id: 'id', - msg: 'method', - }), - }) - .expect(200) - .expect((res: Response) => { - expect(res.body).to.have.property('success', true); - const parsedBody = JSON.parse(res.body.message); - expect(parsedBody).to.have.property('error'); - expect(parsedBody.error).to.have.property('error', 'error-business-hours-are-closed'); - }); - }); - it('should allow managers to make other agents available outside business hour', async () => { - await updatePermission('manage-livechat-agents', ['admin']); - - const currentUser: ILivechatAgent = await getMe(agent.credentials); - const currentStatus = currentUser.statusLivechat; - const newStatus = currentStatus === 'available' ? 'not-available' : 'available'; - - await request - .post(methodCall('livechat:changeLivechatStatus')) - .set(credentials) - .send({ - message: JSON.stringify({ - method: 'livechat:changeLivechatStatus', - params: [{ status: newStatus, agentId: currentUser._id }], - id: 'id', - msg: 'method', - }), - }) - .expect(200) - .expect((res: Response) => { - expect(res.body).to.have.property('success', true); - const parsedBody = JSON.parse(res.body.message); - expect(parsedBody).to.not.have.property('error'); - }); - - await disableDefaultBusinessHour(); - }); - }); -});