From 895e3d939e8013b902229f644bc9c805c3ba8777 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Mon, 28 Dec 2020 10:20:52 -0500 Subject: [PATCH] fix: #9149, server-side handling of disableChatMessageEditing --- src/messaging/edit.js | 14 ++++++------- test/messaging.js | 47 +++++++++++++++++++++++++++++++++++++------ 2 files changed, 48 insertions(+), 13 deletions(-) diff --git a/src/messaging/edit.js b/src/messaging/edit.js index 3e94d55bbb..2ad14d2126 100644 --- a/src/messaging/edit.js +++ b/src/messaging/edit.js @@ -47,9 +47,11 @@ module.exports = function (Messaging) { durationConfig = 'chatDeleteDuration'; } + const isAdminOrGlobalMod = await user.isAdminOrGlobalMod(uid); + if (meta.config.disableChat) { throw new Error('[[error:chat-disabled]]'); - } else if (meta.config.disableChatMessageEditing) { + } else if (!isAdminOrGlobalMod && meta.config.disableChatMessageEditing) { throw new Error('[[error:chat-message-editing-disabled]]'); } @@ -57,19 +59,17 @@ module.exports = function (Messaging) { if (userData.banned) { throw new Error('[[error:user-banned]]'); } + const canChat = await privileges.global.can('chat', uid); if (!canChat) { throw new Error('[[error:no-privileges]]'); } - const [isAdmin, messageData] = await Promise.all([ - user.isAdministrator(uid), - Messaging.getMessageFields(messageId, ['fromuid', 'timestamp', 'system']), - ]); - - if (isAdmin && !messageData.system) { + const messageData = await Messaging.getMessageFields(messageId, ['fromuid', 'timestamp', 'system']); + if (isAdminOrGlobalMod && !messageData.system) { return; } + const chatConfigDuration = meta.config[durationConfig]; if (chatConfigDuration && Date.now() - messageData.timestamp > chatConfigDuration * 1000) { throw new Error('[[error:chat-' + type + '-duration-expired, ' + meta.config[durationConfig] + ']]'); diff --git a/test/messaging.js b/test/messaging.js index ae6f3f164c..3ebe798a98 100644 --- a/test/messaging.js +++ b/test/messaging.js @@ -597,12 +597,15 @@ describe('Messaging Library', function () { describe('edit/delete', function () { var socketModules = require('../src/socket.io/modules'); var mid; - before(function (done) { - socketModules.chats.send({ uid: fooUid }, { roomId: roomId, message: 'first chat message' }, function (err, messageData) { - assert.ifError(err); - mid = messageData.mid; - done(); - }); + let mid2; + before(async function () { + await socketModules.chats.addUserToRoom({ uid: fooUid }, { roomId: roomId, username: 'baz' }); + mid = (await socketModules.chats.send({ uid: fooUid }, { roomId: roomId, message: 'first chat message' })).mid; + mid2 = (await socketModules.chats.send({ uid: bazUid }, { roomId: roomId, message: 'second chat message' })).mid; + }); + + after(async () => { + await socketModules.chats.leave({ uid: bazUid }, roomId); }); it('should fail to edit message with invalid data', function (done) { @@ -723,6 +726,38 @@ describe('Messaging Library', function () { done(); }); }); + + describe('disabled via ACP', () => { + before(async () => { + meta.config.disableChatMessageEditing = true; + }); + + after(async () => { + meta.config.disableChatMessageEditing = false; + }); + + it('should error out for regular users', async () => { + try { + await socketModules.chats.delete({ uid: bazUid }, { messageId: mid2, roomId: roomId }); + } catch (err) { + assert.strictEqual('[[error:chat-message-editing-disabled]]', err.message); + } + }); + + it('should succeed for administrators', async () => { + await socketModules.chats.delete({ uid: fooUid }, { messageId: mid2, roomId: roomId }); + await socketModules.chats.restore({ uid: fooUid }, { messageId: mid2, roomId: roomId }); + }); + + it('should succeed for global moderators', async () => { + await Groups.join(['Global Moderators'], bazUid); + + await socketModules.chats.delete({ uid: fooUid }, { messageId: mid2, roomId: roomId }); + await socketModules.chats.restore({ uid: fooUid }, { messageId: mid2, roomId: roomId }); + + await Groups.leave(['Global Moderators'], bazUid); + }); + }); }); describe('controller', function () {