From 4b507ed349496fbd7fafc7913bd299763fed827c Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Tue, 3 Apr 2018 17:18:06 +0900 Subject: Implement remote account unfollow --- src/processor/http/index.ts | 2 ++ src/processor/http/unfollow.ts | 54 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 src/processor/http/unfollow.ts (limited to 'src/processor/http') diff --git a/src/processor/http/index.ts b/src/processor/http/index.ts index 0301b472ce..8f9aa717c3 100644 --- a/src/processor/http/index.ts +++ b/src/processor/http/index.ts @@ -3,6 +3,7 @@ import follow from './follow'; import performActivityPub from './perform-activitypub'; import processInbox from './process-inbox'; import reportGitHubFailure from './report-github-failure'; +import unfollow from './unfollow'; const handlers = { deliverPost, @@ -10,6 +11,7 @@ const handlers = { performActivityPub, processInbox, reportGitHubFailure, + unfollow }; export default (job, done) => handlers[job.data.type](job).then(() => done(), done); diff --git a/src/processor/http/unfollow.ts b/src/processor/http/unfollow.ts new file mode 100644 index 0000000000..4a8f033914 --- /dev/null +++ b/src/processor/http/unfollow.ts @@ -0,0 +1,54 @@ +import FollowedLog from '../../models/followed-log'; +import Following from '../../models/following'; +import FollowingLog from '../../models/following-log'; +import User, { isRemoteUser, pack as packUser } from '../../models/user'; +import stream from '../../publishers/stream'; +import renderFollow from '../../remote/activitypub/renderer/follow'; +import renderUndo from '../../remote/activitypub/renderer/undo'; +import context from '../../remote/activitypub/renderer/context'; +import request from '../../remote/request'; + +export default async ({ data }) => { + // Delete following + const following = await Following.findOneAndDelete({ _id: data.id }); + if (following === null) { + return; + } + + const promisedFollower = User.findOne({ _id: following.followerId }); + const promisedFollowee = User.findOne({ _id: following.followeeId }); + + await Promise.all([ + // Decrement following count + User.update({ _id: following.followerId }, { $inc: { followingCount: -1 } }), + promisedFollower.then(({ followingCount }) => FollowingLog.insert({ + userId: following.followerId, + count: followingCount - 1 + })), + + // Decrement followers count + User.update({ _id: following.followeeId }, { $inc: { followersCount: -1 } }), + promisedFollowee.then(({ followersCount }) => FollowedLog.insert({ + userId: following.followeeId, + count: followersCount - 1 + })), + + // Publish follow event + Promise.all([promisedFollower, promisedFollowee]).then(async ([follower, followee]) => { + if (isRemoteUser(follower)) { + return; + } + + const promisedPackedUser = packUser(followee, follower); + + if (isRemoteUser(followee)) { + const undo = renderUndo(renderFollow(follower, followee)); + undo['@context'] = context; + + await request(follower, followee.account.inbox, undo); + } + + stream(follower._id, 'unfollow', promisedPackedUser); + }) + ]); +}; -- cgit v1.2.3-freya