diff --git a/.changeset/giant-dancers-relate.md b/.changeset/giant-dancers-relate.md new file mode 100644 index 000000000000..d58385c5da7a --- /dev/null +++ b/.changeset/giant-dancers-relate.md @@ -0,0 +1,5 @@ +--- +"@rocket.chat/meteor": patch +--- + +Fixed an `UnhandledPromiseRejection` error on `PUT livechat/departments/:_id` endpoint when `agents` array failed validation diff --git a/apps/meteor/app/livechat/imports/server/rest/departments.ts b/apps/meteor/app/livechat/imports/server/rest/departments.ts index 095baefaa294..8355bbd35db7 100644 --- a/apps/meteor/app/livechat/imports/server/rest/departments.ts +++ b/apps/meteor/app/livechat/imports/server/rest/departments.ts @@ -110,10 +110,6 @@ API.v1.addRoute( const permissionToSave = await hasPermissionAsync(this.userId, 'manage-livechat-departments'); const permissionToAddAgents = await hasPermissionAsync(this.userId, 'add-livechat-department-agents'); - check(this.urlParams, { - _id: String, - }); - check(this.bodyParams, { department: Object, agents: Match.Maybe(Array), @@ -128,13 +124,13 @@ API.v1.addRoute( } if (success && agents && permissionToAddAgents) { - success = Livechat.saveDepartmentAgents(_id, { upsert: agents }); + success = await Livechat.saveDepartmentAgents(_id, { upsert: agents }); } if (success) { return API.v1.success({ department: await LivechatDepartment.findOneById(_id), - agents: await LivechatDepartmentAgents.find({ departmentId: _id }).toArray(), + agents: await LivechatDepartmentAgents.findByDepartmentId(_id).toArray(), }); } @@ -266,10 +262,6 @@ API.v1.addRoute( return API.v1.success(agents); }, async post() { - check(this.urlParams, { - _id: String, - }); - check( this.bodyParams, Match.ObjectIncluding({ diff --git a/apps/meteor/app/livechat/server/lib/Livechat.js b/apps/meteor/app/livechat/server/lib/Livechat.js index 58a07f00a0d3..35c11ffd3d4f 100644 --- a/apps/meteor/app/livechat/server/lib/Livechat.js +++ b/apps/meteor/app/livechat/server/lib/Livechat.js @@ -192,7 +192,6 @@ export const Livechat = { }, async saveDepartmentAgents(_id, departmentAgents) { - check(_id, String); check(departmentAgents, { upsert: Match.Maybe([ Match.ObjectIncluding({ @@ -212,7 +211,7 @@ export const Livechat = { ]), }); - const department = await LivechatDepartmentRaw.findOneById(_id); + const department = await LivechatDepartmentRaw.findOneById(_id, { projection: { enabled: 1 } }); if (!department) { throw new Meteor.Error('error-department-not-found', 'Department not found', { method: 'livechat:saveDepartmentAgents', diff --git a/apps/meteor/tests/end-to-end/api/livechat/10-departments.ts b/apps/meteor/tests/end-to-end/api/livechat/10-departments.ts index a5a4d848b70d..538ae040fde6 100644 --- a/apps/meteor/tests/end-to-end/api/livechat/10-departments.ts +++ b/apps/meteor/tests/end-to-end/api/livechat/10-departments.ts @@ -344,8 +344,15 @@ import { IS_EE } from '../../../e2e/config/constants'; }); describe('PUT livechat/departments/:_id', () => { + let department: ILivechatDepartment; + before(async () => { + department = await createDepartment(); + }); + after(async () => { + await deleteDepartment(department._id); + }); + it('should return an error if fallbackForwardDepartment points to same department', async () => { - const department = await createDepartment(); await request .put(api(`livechat/department/${department._id}`)) .set(credentials) @@ -361,7 +368,58 @@ import { IS_EE } from '../../../e2e/config/constants'; }) .expect('Content-Type', 'application/json') .expect(400); - await deleteDepartment(department._id); + }); + it('should fail if `agents` param is not an array', async () => { + await request + .put(api(`livechat/department/${department._id}`)) + .set(credentials) + .send({ + department: { + name: faker.hacker.adjective(), + enabled: true, + showOnOfflineForm: true, + showOnRegistration: true, + email: faker.internet.email(), + }, + agents: 'not an array', + }) + .expect('Content-Type', 'application/json') + .expect(400); + }); + it('should throw an error if user has permission to add agents and agents array has invalid format', async () => { + await updatePermission('add-livechat-department-agents', ['admin']); + await request + .put(api(`livechat/department/${department._id}`)) + .set(credentials) + .send({ + department: { + name: faker.hacker.adjective(), + enabled: true, + showOnOfflineForm: true, + showOnRegistration: true, + email: faker.internet.email(), + }, + agents: [{ notAValidKey: 'string' }], + }) + .expect('Content-Type', 'application/json') + .expect(400); + }); + it('should throw an error if user has permission to add agents and agents array has invalid internal format', async () => { + await request + .put(api(`livechat/department/${department._id}`)) + .set(credentials) + .send({ + department: { + name: faker.hacker.adjective(), + enabled: true, + showOnOfflineForm: true, + showOnRegistration: true, + email: faker.internet.email(), + }, + agents: [{ upsert: [{ notAValidKey: 'string' }] }], + }) + .expect('Content-Type', 'application/json') + .expect(400); }); });