diff --git a/src/activitypub/inbox.js b/src/activitypub/inbox.js index d7dbcf6834..91e9bfab4a 100644 --- a/src/activitypub/inbox.js +++ b/src/activitypub/inbox.js @@ -352,6 +352,26 @@ inbox.like = async (req) => { socketHelpers.upvote(result, 'notifications:upvoted-your-post-in'); }; +inbox.dislike = async (req) => { + const { actor, object } = req.body; + const { type, id } = await activitypub.helpers.resolveLocalId(object.id); + + if (type !== 'post' || !(await posts.exists(id))) { + return reject('Dislike', object, actor); + } + + const allowed = await privileges.posts.can('posts:downvote', id, activitypub._constants.uid); + if (!allowed) { + activitypub.helpers.log(`[activitypub/inbox.like] ${id} not allowed to be downvoted.`); + return reject('Dislike', object, actor); + } + + activitypub.helpers.log(`[activitypub/inbox/dislike] id ${id} via ${actor}`); + + await posts.downvote(id, actor); + await activitypub.feps.announce(object.id, req.body); +}; + inbox.announce = async (req) => { let { actor, object, published, to, cc } = req.body; activitypub.helpers.log(`[activitypub/inbox/announce] Parsing Announce(${object.type}) from ${actor}`); diff --git a/src/activitypub/out.js b/src/activitypub/out.js index 6a267a36bc..d56f8720d5 100644 --- a/src/activitypub/out.js +++ b/src/activitypub/out.js @@ -277,6 +277,32 @@ Out.like.note = enabledCheck(async (uid, pid) => { ]); }); +Out.dislike = {}; + +Out.dislike.note = enabledCheck(async (uid, pid) => { + const payload = { + id: `${nconf.get('url')}/uid/${uid}#activity/dislike/${encodeURIComponent(pid)}`, + type: 'Dislike', + actor: `${nconf.get('url')}/uid/${uid}`, + object: utils.isNumber(pid) ? `${nconf.get('url')}/post/${pid}` : pid, + }; + + if (!activitypub.helpers.isUri(pid)) { // only 1b12 announce for local likes + await activitypub.feps.announce(pid, payload); + return; + } + + const recipient = await posts.getPostField(pid, 'uid'); + if (!activitypub.helpers.isUri(recipient)) { + return; + } + + await Promise.all([ + activitypub.send('uid', uid, [recipient], payload), + activitypub.feps.announce(pid, payload), + ]); +}); + Out.announce = {}; Out.announce.topic = enabledCheck(async (tid) => { diff --git a/src/api/helpers.js b/src/api/helpers.js index d7300f01e0..298725e915 100644 --- a/src/api/helpers.js +++ b/src/api/helpers.js @@ -147,14 +147,34 @@ async function executeCommand(caller, command, eventName, notification, data) { websockets.in(`uid_${caller.uid}`).emit(`posts.${command}`, result); websockets.in(data.room_id).emit(`event:${eventName}`, result); } - if (result && command === 'upvote') { - socketHelpers.upvote(result, notification); - await activitypub.out.like.note(caller.uid, data.pid); - } else if (result && notification) { - socketHelpers.sendNotificationToPostOwner(data.pid, caller.uid, command, notification); - } else if (result && command === 'unvote') { - socketHelpers.rescindUpvoteNotification(data.pid, caller.uid); - await activitypub.out.undo.like(caller.uid, data.pid); + + if (result) { + switch (command) { + case 'upvote': { + socketHelpers.upvote(result, notification); + await activitypub.out.like.note(caller.uid, data.pid); + break; + } + + case 'downvote': { + await activitypub.out.dislike.note(caller.uid, data.pid); + break; + } + + case 'unvote': { + socketHelpers.rescindUpvoteNotification(data.pid, caller.uid); + await activitypub.out.undo.like(caller.uid, data.pid); + break; + } + + default: { + if (notification) { + socketHelpers.sendNotificationToPostOwner(data.pid, caller.uid, command, notification); + } + break; + } + } } + return result; }