diff --git a/src/messaging/index.js b/src/messaging/index.js index 789b6de2a0..c5e9dfe9d0 100644 --- a/src/messaging/index.js +++ b/src/messaging/index.js @@ -380,6 +380,7 @@ Messaging.canMessageRoom = async (uid, roomId) => { Messaging.isUserInRoom(uid, roomId), privileges.global.can('chat', uid), checkReputation(uid), + user.checkMuted(uid), ]); if (!roomData) { throw new Error('[[error:no-room]]'); diff --git a/src/user/posts.js b/src/user/posts.js index 9ca31cd6e7..26b0f348bf 100644 --- a/src/user/posts.js +++ b/src/user/posts.js @@ -13,6 +13,20 @@ module.exports = function (User) { await isReady(uid, cid, 'lastqueuetime'); }; + User.checkMuted = async function (uid) { + const now = Date.now(); + const mutedUntil = await User.getUserField(uid, 'mutedUntil'); + if (mutedUntil > now) { + let muteLeft = ((mutedUntil - now) / (1000 * 60)); + if (muteLeft > 60) { + muteLeft = (muteLeft / 60).toFixed(0); + throw new Error(`[[error:user-muted-for-hours, ${muteLeft}]]`); + } else { + throw new Error(`[[error:user-muted-for-minutes, ${muteLeft.toFixed(0)}]]`); + } + } + }; + async function isReady(uid, cid, field) { if (parseInt(uid, 10) === 0) { return; @@ -30,17 +44,9 @@ module.exports = function (User) { return; } - const now = Date.now(); - if (userData.mutedUntil > now) { - let muteLeft = ((userData.mutedUntil - now) / (1000 * 60)); - if (muteLeft > 60) { - muteLeft = (muteLeft / 60).toFixed(0); - throw new Error(`[[error:user-muted-for-hours, ${muteLeft}]]`); - } else { - throw new Error(`[[error:user-muted-for-minutes, ${muteLeft.toFixed(0)}]]`); - } - } + await User.checkMuted(uid); + const now = Date.now(); if (now - userData.joindate < meta.config.initialPostDelay * 1000) { throw new Error(`[[error:user-too-new, ${meta.config.initialPostDelay}]]`); } diff --git a/test/messaging.js b/test/messaging.js index 2e5af6b60c..c829eb5077 100644 --- a/test/messaging.js +++ b/test/messaging.js @@ -113,6 +113,28 @@ describe('Messaging Library', () => { }); }); }); + + it('should not allow messaging room if user is muted', async () => { + const twoMinutesFromNow = Date.now() + (2 * 60 * 1000); + const twoHoursFromNow = Date.now() + (2 * 60 * 60 * 1000); + const roomId = 0; + + await User.setUserField(mocks.users.herp.uid, 'mutedUntil', twoMinutesFromNow); + await assert.rejects(Messaging.canMessageRoom(mocks.users.herp.uid, roomId), (err) => { + assert(err.message.startsWith('[[error:user-muted-for-minutes,')); + return true; + }); + + await User.setUserField(mocks.users.herp.uid, 'mutedUntil', twoHoursFromNow); + await assert.rejects(Messaging.canMessageRoom(mocks.users.herp.uid, roomId), (err) => { + assert(err.message.startsWith('[[error:user-muted-for-hours,')); + return true; + }); + await db.deleteObjectField(`user:${mocks.users.herp.uid}`, 'mutedUntil'); + await assert.rejects(Messaging.canMessageRoom(mocks.users.herp.uid, roomId), { + message: '[[error:no-room]]', + }); + }); }); describe('rooms', () => {