diff --git a/test/api/v3/integration/members/POST-send_private_message.test.js b/test/api/v3/integration/members/POST-send_private_message.test.js index 7498d2e560..aaa3cb3a2c 100644 --- a/test/api/v3/integration/members/POST-send_private_message.test.js +++ b/test/api/v3/integration/members/POST-send_private_message.test.js @@ -118,4 +118,56 @@ describe('POST /members/send-private-message', () => { expect(sendersMessageInReceiversInbox).to.exist; expect(sendersMessageInSendersInbox).to.exist; }); + + it('allows admin to send when sender has blocked the admin', async () => { + userToSendMessage = await generateUser({ + 'contributor.admin': 1, + }); + const receiver = await generateUser({'inbox.blocks': [userToSendMessage._id]}); + + await userToSendMessage.post('/members/send-private-message', { + message: messageToSend, + toUserId: receiver._id, + }); + + const updatedReceiver = await receiver.get('/user'); + const updatedSender = await userToSendMessage.get('/user'); + + const sendersMessageInReceiversInbox = _.find(updatedReceiver.inbox.messages, (message) => { + return message.uuid === userToSendMessage._id && message.text === messageToSend; + }); + + const sendersMessageInSendersInbox = _.find(updatedSender.inbox.messages, (message) => { + return message.uuid === receiver._id && message.text === messageToSend; + }); + + expect(sendersMessageInReceiversInbox).to.exist; + expect(sendersMessageInSendersInbox).to.exist; + }); + + it('allows admin to send when to user has opted out of messaging', async () => { + userToSendMessage = await generateUser({ + 'contributor.admin': 1, + }); + const receiver = await generateUser({'inbox.optOut': true}); + + await userToSendMessage.post('/members/send-private-message', { + message: messageToSend, + toUserId: receiver._id, + }); + + const updatedReceiver = await receiver.get('/user'); + const updatedSender = await userToSendMessage.get('/user'); + + const sendersMessageInReceiversInbox = _.find(updatedReceiver.inbox.messages, (message) => { + return message.uuid === userToSendMessage._id && message.text === messageToSend; + }); + + const sendersMessageInSendersInbox = _.find(updatedSender.inbox.messages, (message) => { + return message.uuid === receiver._id && message.text === messageToSend; + }); + + expect(sendersMessageInReceiversInbox).to.exist; + expect(sendersMessageInSendersInbox).to.exist; + }); }); diff --git a/website/server/controllers/api-v3/members.js b/website/server/controllers/api-v3/members.js index 1619ddf61d..e2690cc74f 100644 --- a/website/server/controllers/api-v3/members.js +++ b/website/server/controllers/api-v3/members.js @@ -476,7 +476,8 @@ api.sendPrivateMessage = { if (!receiver) throw new NotFound(res.t('userNotFound')); let objections = sender.getObjectionsToInteraction('send-private-message', receiver); - if (objections.length > 0) throw new NotAuthorized(res.t(objections[0])); + + if (objections.length > 0 && !sender.isAdmin()) throw new NotAuthorized(res.t(objections[0])); await sender.sendMessage(receiver, { receiverMsg: message }); diff --git a/website/server/models/user/methods.js b/website/server/models/user/methods.js index d58aca2761..4f1495168d 100644 --- a/website/server/models/user/methods.js +++ b/website/server/models/user/methods.js @@ -313,3 +313,7 @@ schema.methods.isMemberOfGroupPlan = async function isMemberOfGroupPlan () { return g.isSubscribed(); }); }; + +schema.methods.isAdmin = function isAdmin () { + return this.contributor && this.contributor.admin; +};