Implement remote account unfollow

This commit is contained in:
Akihiko Odaki 2018-04-03 17:18:06 +09:00
parent bd935c5696
commit 749f0fd6cb
6 changed files with 81 additions and 47 deletions

View file

@ -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);

View file

@ -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);
})
]);
};

View file

@ -15,7 +15,7 @@ export default async (resolver, actor, activity) => {
switch (result.object.$ref) {
case 'following':
await unfollow(result.resolver, result.object);
await unfollow(result.object);
}
}));

View file

@ -1,24 +1,11 @@
import FollowedLog from '../../../../models/followed-log';
import Following from '../../../../models/following';
import FollowingLog from '../../../../models/following-log';
import User from '../../../../models/user';
import queue from '../../../../queue';
export default async (resolver, { $id }) => {
const following = await Following.findOneAndDelete({ _id: $id });
if (following === null) {
return;
}
await Promise.all([
User.update({ _id: following.followerId }, { $inc: { followingCount: -1 } }),
User.findOne({ _id: following.followerId }).then(({ followingCount }) => FollowingLog.insert({
userId: following.followerId,
count: followingCount - 1
})),
User.update({ _id: following.followeeId }, { $inc: { followersCount: -1 } }),
User.findOne({ _id: following.followeeId }).then(({ followersCount }) => FollowedLog.insert({
userId: following.followeeId,
count: followersCount - 1
})),
]);
};
export default ({ $id }) => new Promise((resolve, reject) => {
queue.create('http', { type: 'unfollow', id: $id }).save(error => {
if (error) {
reject(error);
} else {
resolve();
}
});
});

View file

@ -0,0 +1,4 @@
export default object => ({
type: 'Undo',
object
});

View file

@ -2,9 +2,9 @@
* Module dependencies
*/
import $ from 'cafy';
import User, { pack as packUser } from '../../../../models/user';
import User from '../../../../models/user';
import Following from '../../../../models/following';
import event from '../../../../publishers/stream';
import queue from '../../../../queue';
/**
* Unfollow a user
@ -49,28 +49,15 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
return rej('already not following');
}
// Delete following
await Following.findOneAndDelete({
_id: exist._id
});
// Send response
res();
// Decrement following count
User.update({ _id: follower._id }, {
$inc: {
followingCount: -1
queue.create('http', {
type: 'unfollow',
id: exist._id
}).save(error => {
if (error) {
return rej('unfollow failed');
}
});
// Decrement followers count
User.update({ _id: followee._id }, {
$inc: {
followersCount: -1
}
// Send response
res();
});
// Publish follow event
event(follower._id, 'unfollow', await packUser(followee, follower));
});