wip
This commit is contained in:
		
							parent
							
								
									5bd1451b61
								
							
						
					
					
						commit
						77f056b4fc
					
				
					 9 changed files with 142 additions and 104 deletions
				
			
		
							
								
								
									
										82
									
								
								src/api/following/create.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								src/api/following/create.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,82 @@
 | 
			
		|||
import User, { isLocalUser, isRemoteUser, pack as packUser, IUser } from '../../models/user';
 | 
			
		||||
import Following from '../../models/following';
 | 
			
		||||
import FollowingLog from '../../models/following-log';
 | 
			
		||||
import FollowedLog from '../../models/followed-log';
 | 
			
		||||
import event from '../../publishers/stream';
 | 
			
		||||
import notify from '../../publishers/notify';
 | 
			
		||||
import context from '../../remote/activitypub/renderer/context';
 | 
			
		||||
import renderFollow from '../../remote/activitypub/renderer/follow';
 | 
			
		||||
import renderAccept from '../../remote/activitypub/renderer/accept';
 | 
			
		||||
import { createHttp } from '../../queue';
 | 
			
		||||
 | 
			
		||||
export default async function(follower: IUser, followee: IUser, activity?) {
 | 
			
		||||
	const following = await Following.insert({
 | 
			
		||||
		createdAt: new Date(),
 | 
			
		||||
		followerId: follower._id,
 | 
			
		||||
		followeeId: followee._id
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	//#region Increment following count
 | 
			
		||||
	User.update({ _id: follower._id }, {
 | 
			
		||||
		$inc: {
 | 
			
		||||
			followingCount: 1
 | 
			
		||||
		}
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	FollowingLog.insert({
 | 
			
		||||
		createdAt: following.createdAt,
 | 
			
		||||
		userId: follower._id,
 | 
			
		||||
		count: follower.followingCount + 1
 | 
			
		||||
	});
 | 
			
		||||
	//#endregion
 | 
			
		||||
 | 
			
		||||
	//#region Increment followers count
 | 
			
		||||
	User.update({ _id: followee._id }, {
 | 
			
		||||
		$inc: {
 | 
			
		||||
			followersCount: 1
 | 
			
		||||
		}
 | 
			
		||||
	});
 | 
			
		||||
	FollowedLog.insert({
 | 
			
		||||
		createdAt: following.createdAt,
 | 
			
		||||
		userId: followee._id,
 | 
			
		||||
		count: followee.followersCount + 1
 | 
			
		||||
	});
 | 
			
		||||
	//#endregion
 | 
			
		||||
 | 
			
		||||
	// Publish follow event
 | 
			
		||||
	if (isLocalUser(follower)) {
 | 
			
		||||
		packUser(followee, follower).then(packed => event(follower._id, 'follow', packed));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Publish followed event
 | 
			
		||||
	if (isLocalUser(followee)) {
 | 
			
		||||
		packUser(follower, followee).then(packed => event(followee._id, 'followed', packed)),
 | 
			
		||||
 | 
			
		||||
		// 通知を作成
 | 
			
		||||
		notify(followee._id, follower._id, 'follow');
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (isLocalUser(follower) && isRemoteUser(followee)) {
 | 
			
		||||
		const content = renderFollow(follower, followee);
 | 
			
		||||
		content['@context'] = context;
 | 
			
		||||
 | 
			
		||||
		createHttp({
 | 
			
		||||
			type: 'deliver',
 | 
			
		||||
			user: follower,
 | 
			
		||||
			content,
 | 
			
		||||
			to: followee.account.inbox
 | 
			
		||||
		}).save();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (isRemoteUser(follower) && isLocalUser(followee)) {
 | 
			
		||||
		const content = renderAccept(activity);
 | 
			
		||||
		content['@context'] = context;
 | 
			
		||||
 | 
			
		||||
		createHttp({
 | 
			
		||||
			type: 'deliver',
 | 
			
		||||
			user: followee,
 | 
			
		||||
			content,
 | 
			
		||||
			to: follower.account.inbox
 | 
			
		||||
		}).save();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,56 +1,63 @@
 | 
			
		|||
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';
 | 
			
		||||
import FollowedLog from '../../../models/followed-log';
 | 
			
		||||
import Following from '../../../models/following';
 | 
			
		||||
import FollowingLog from '../../../models/following-log';
 | 
			
		||||
import User, { isLocalUser, 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';
 | 
			
		||||
import Logger from '../../../utils/logger';
 | 
			
		||||
 | 
			
		||||
export default async ({ data }) => {
 | 
			
		||||
	// Delete following
 | 
			
		||||
	const following = await Following.findOneAndDelete({ _id: data.id });
 | 
			
		||||
	const following = await Following.findOne({ _id: data.id });
 | 
			
		||||
	if (following === null) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const promisedFollower = User.findOne({ _id: following.followerId });
 | 
			
		||||
	const promisedFollowee = User.findOne({ _id: following.followeeId });
 | 
			
		||||
	const [follower, followee] = await Promise.all([
 | 
			
		||||
		User.findOne({ _id: following.followerId }),
 | 
			
		||||
		User.findOne({ _id: following.followeeId })
 | 
			
		||||
	]);
 | 
			
		||||
 | 
			
		||||
	await Promise.all([
 | 
			
		||||
		// Decrement following count
 | 
			
		||||
		User.update({ _id: following.followerId }, { $inc: { followingCount: -1 } }),
 | 
			
		||||
		promisedFollower.then(({ followingCount }) => FollowingLog.insert({
 | 
			
		||||
			createdAt: new Date(),
 | 
			
		||||
			userId: following.followerId,
 | 
			
		||||
			count: followingCount - 1
 | 
			
		||||
		})),
 | 
			
		||||
	if (isLocalUser(follower) && isRemoteUser(followee)) {
 | 
			
		||||
		const undo = renderUndo(renderFollow(follower, followee));
 | 
			
		||||
		undo['@context'] = context;
 | 
			
		||||
 | 
			
		||||
		// Decrement followers count
 | 
			
		||||
		User.update({ _id: following.followeeId }, { $inc: { followersCount: -1 } }),
 | 
			
		||||
		promisedFollowee.then(({ followersCount }) => FollowedLog.insert({
 | 
			
		||||
			createdAt: new Date(),
 | 
			
		||||
			userId: following.followeeId,
 | 
			
		||||
			count: followersCount - 1
 | 
			
		||||
		})),
 | 
			
		||||
		await request(follower, followee.account.inbox, undo);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	try {
 | 
			
		||||
		await Promise.all([
 | 
			
		||||
			// Delete following
 | 
			
		||||
			Following.findOneAndDelete({ _id: data.id }),
 | 
			
		||||
 | 
			
		||||
			// Decrement following count
 | 
			
		||||
			User.update({ _id: follower._id }, { $inc: { followingCount: -1 } }),
 | 
			
		||||
			FollowingLog.insert({
 | 
			
		||||
				createdAt: new Date(),
 | 
			
		||||
				userId: follower._id,
 | 
			
		||||
				count: follower.followingCount - 1
 | 
			
		||||
			}),
 | 
			
		||||
 | 
			
		||||
			// Decrement followers count
 | 
			
		||||
			User.update({ _id: followee._id }, { $inc: { followersCount: -1 } }),
 | 
			
		||||
			FollowedLog.insert({
 | 
			
		||||
				createdAt: new Date(),
 | 
			
		||||
				userId: followee._id,
 | 
			
		||||
				count: followee.followersCount - 1
 | 
			
		||||
			})
 | 
			
		||||
		]);
 | 
			
		||||
 | 
			
		||||
		if (isLocalUser(follower)) {
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		const promisedPackedUser = packUser(followee, follower);
 | 
			
		||||
 | 
			
		||||
		// 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);
 | 
			
		||||
		})
 | 
			
		||||
	]);
 | 
			
		||||
		stream(follower._id, 'unfollow', promisedPackedUser);
 | 
			
		||||
	} catch (error) {
 | 
			
		||||
		Logger.error(error.toString());
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,10 +4,10 @@ const createDOMPurify = require('dompurify');
 | 
			
		|||
import Resolver from '../resolver';
 | 
			
		||||
import DriveFile from '../../../models/drive-file';
 | 
			
		||||
import Post from '../../../models/post';
 | 
			
		||||
import uploadFromUrl from '../../../drive/upload-from-url';
 | 
			
		||||
import createPost from '../../../post/create';
 | 
			
		||||
import uploadFromUrl from '../../../api/drive/upload-from-url';
 | 
			
		||||
import createPost from '../../../api/post/create';
 | 
			
		||||
 | 
			
		||||
export default async (resolver: Resolver, actor, activity): Promise<void> => {
 | 
			
		||||
export default async (actor, activity): Promise<void> => {
 | 
			
		||||
	if ('actor' in activity && actor.account.uri !== activity.actor) {
 | 
			
		||||
		throw new Error('invalid actor');
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -31,6 +31,8 @@ export default async (resolver: Resolver, actor, activity): Promise<void> => {
 | 
			
		|||
		throw new Error(`already registered: ${uri}`);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const resolver = new Resolver();
 | 
			
		||||
 | 
			
		||||
	const object = await resolver.resolve(activity);
 | 
			
		||||
 | 
			
		||||
	switch (object.type) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,15 +1,9 @@
 | 
			
		|||
import { MongoError } from 'mongodb';
 | 
			
		||||
import parseAcct from '../../../acct/parse';
 | 
			
		||||
import Following, { IFollowing } from '../../../models/following';
 | 
			
		||||
import User from '../../../models/user';
 | 
			
		||||
import config from '../../../config';
 | 
			
		||||
import queue from '../../../queue';
 | 
			
		||||
import context from '../renderer/context';
 | 
			
		||||
import renderAccept from '../renderer/accept';
 | 
			
		||||
import request from '../../request';
 | 
			
		||||
import Resolver from '../resolver';
 | 
			
		||||
import follow from '../../../api/following/create';
 | 
			
		||||
 | 
			
		||||
export default async (resolver: Resolver, actor, activity, distribute) => {
 | 
			
		||||
export default async (actor, activity): Promise<void> => {
 | 
			
		||||
	const prefix = config.url + '/@';
 | 
			
		||||
	const id = activity.object.id || activity.object;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -27,52 +21,5 @@ export default async (resolver: Resolver, actor, activity, distribute) => {
 | 
			
		|||
		throw new Error();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!distribute) {
 | 
			
		||||
		const { _id } = await Following.findOne({
 | 
			
		||||
			followerId: actor._id,
 | 
			
		||||
			followeeId: followee._id
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		return {
 | 
			
		||||
			resolver,
 | 
			
		||||
			object: { $ref: 'following', $id: _id }
 | 
			
		||||
		};
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const promisedFollowing = Following.insert({
 | 
			
		||||
		createdAt: new Date(),
 | 
			
		||||
		followerId: actor._id,
 | 
			
		||||
		followeeId: followee._id
 | 
			
		||||
	}).then(following => new Promise((resolve, reject) => {
 | 
			
		||||
		queue.create('http', {
 | 
			
		||||
			type: 'follow',
 | 
			
		||||
			following: following._id
 | 
			
		||||
		}).save(error => {
 | 
			
		||||
			if (error) {
 | 
			
		||||
				reject(error);
 | 
			
		||||
			} else {
 | 
			
		||||
				resolve(following);
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
	}) as Promise<IFollowing>, async error => {
 | 
			
		||||
		// duplicate key error
 | 
			
		||||
		if (error instanceof MongoError && error.code === 11000) {
 | 
			
		||||
			return Following.findOne({
 | 
			
		||||
				followerId: actor._id,
 | 
			
		||||
				followeeId: followee._id
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		throw error;
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	const accept = renderAccept(activity);
 | 
			
		||||
	accept['@context'] = context;
 | 
			
		||||
 | 
			
		||||
	await request(followee, actor.account.inbox, accept);
 | 
			
		||||
 | 
			
		||||
	return promisedFollowing.then(({ _id }) => ({
 | 
			
		||||
		resolver,
 | 
			
		||||
		object: { $ref: 'following', $id: _id }
 | 
			
		||||
	}));
 | 
			
		||||
	await follow(actor, followee, activity);
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue