mirror of
				https://codeberg.org/yeentown/barkey.git
				synced 2025-10-26 19:14:12 +00:00 
			
		
		
		
	Implement remote follow
This commit is contained in:
		
							parent
							
								
									cba73d6bc1
								
							
						
					
					
						commit
						dc529711ce
					
				
					 11 changed files with 114 additions and 32 deletions
				
			
		|  | @ -1,8 +1,8 @@ | |||
| import * as mongo from 'mongodb'; | ||||
| import Notification from '../../../models/notification'; | ||||
| import Mute from '../../../models/mute'; | ||||
| import event from '../../../common/event'; | ||||
| import { pack } from '../../../models/notification'; | ||||
| import Notification from '../models/notification'; | ||||
| import Mute from '../models/mute'; | ||||
| import event from './event'; | ||||
| import { pack } from '../models/notification'; | ||||
| 
 | ||||
| export default ( | ||||
| 	notifiee: mongo.ObjectID, | ||||
							
								
								
									
										8
									
								
								src/common/remote/activitypub/renderer/follow.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/common/remote/activitypub/renderer/follow.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,8 @@ | |||
| import config from '../../../../conf'; | ||||
| import { IRemoteAccount } from '../../../../models/user'; | ||||
| 
 | ||||
| export default ({ username }, { account }) => ({ | ||||
| 	type: 'Follow', | ||||
| 	actor: `${config.url}/@${username}`, | ||||
| 	object: (account as IRemoteAccount).uri | ||||
| }); | ||||
|  | @ -66,6 +66,7 @@ export default async (value, usernameLower, hostLower, acctLower) => { | |||
| 				id: object.publicKey.id, | ||||
| 				publicKeyPem: object.publicKey.publicKeyPem | ||||
| 			}, | ||||
| 			inbox: object.inbox, | ||||
| 			uri: object.id, | ||||
| 		}, | ||||
| 	}); | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| const WebFinger = require('webfinger.js'); | ||||
| 
 | ||||
| const webFinger = new WebFinger({}); | ||||
| const webFinger = new WebFinger({ tls_only: false }); | ||||
| 
 | ||||
| type ILink = { | ||||
|   href: string; | ||||
|  |  | |||
|  | @ -70,6 +70,7 @@ export type ILocalAccount = { | |||
| }; | ||||
| 
 | ||||
| export type IRemoteAccount = { | ||||
| 	inbox: string; | ||||
| 	uri: string; | ||||
| 	publicKey: { | ||||
| 		id: string; | ||||
|  |  | |||
							
								
								
									
										89
									
								
								src/processor/http/follow.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								src/processor/http/follow.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,89 @@ | |||
| import { request } from 'https'; | ||||
| import { sign } from 'http-signature'; | ||||
| import { URL } from 'url'; | ||||
| import User, { ILocalAccount, IRemoteAccount, pack as packUser } from '../../models/user'; | ||||
| import Following from '../../models/following'; | ||||
| import event from '../../common/event'; | ||||
| import notify from '../../common/notify'; | ||||
| import context from '../../common/remote/activitypub/renderer/context'; | ||||
| import render from '../../common/remote/activitypub/renderer/follow'; | ||||
| import config from '../../conf'; | ||||
| 
 | ||||
| export default ({ data }, done) => Following.findOne({ _id: data.following }).then(({ followerId, followeeId }) => { | ||||
| 	const promisedFollower = User.findOne({ _id: followerId }); | ||||
| 	const promisedFollowee = User.findOne({ _id: followeeId }); | ||||
| 
 | ||||
| 	return Promise.all([ | ||||
| 		// Increment following count
 | ||||
| 		User.update(followerId, { | ||||
| 			$inc: { | ||||
| 				followingCount: 1 | ||||
| 			} | ||||
| 		}), | ||||
| 
 | ||||
| 		// Increment followers count
 | ||||
| 		User.update({ _id: followeeId }, { | ||||
| 			$inc: { | ||||
| 				followersCount: 1 | ||||
| 			} | ||||
| 		}), | ||||
| 
 | ||||
| 		// Notify
 | ||||
| 		promisedFollowee.then(followee => followee.host === null ? | ||||
| 			notify(followeeId, followerId, 'follow') : null), | ||||
| 
 | ||||
| 		// Publish follow event
 | ||||
| 		Promise.all([promisedFollower, promisedFollowee]).then(([follower, followee]) => { | ||||
| 			const followerEvent = packUser(followee, follower) | ||||
| 				.then(packed => event(follower._id, 'follow', packed)); | ||||
| 			let followeeEvent; | ||||
| 
 | ||||
| 			if (followee.host === null) { | ||||
| 				followeeEvent = packUser(follower, followee) | ||||
| 					.then(packed => event(followee._id, 'followed', packed)); | ||||
| 			} else { | ||||
| 				followeeEvent = new Promise((resolve, reject) => { | ||||
| 					const { | ||||
| 						protocol, | ||||
| 						hostname, | ||||
| 						port, | ||||
| 						pathname, | ||||
| 						search | ||||
| 					} = new URL(followee.account as IRemoteAccount).inbox); | ||||
| 
 | ||||
| 					const req = request({ | ||||
| 						protocol, | ||||
| 						hostname, | ||||
| 						port, | ||||
| 						method: 'POST', | ||||
| 						path: pathname + search, | ||||
| 					}, res => { | ||||
| 						res.on('close', () => { | ||||
| 							if (res.statusCode >= 200 && res.statusCode < 300) { | ||||
| 								resolve(); | ||||
| 							} else { | ||||
| 								reject(res); | ||||
| 							} | ||||
| 						}); | ||||
| 
 | ||||
| 						res.on('data', () => {}); | ||||
| 						res.on('error', reject); | ||||
| 					}); | ||||
| 
 | ||||
| 					sign(req, { | ||||
| 						authorizationHeaderName: 'Signature', | ||||
| 						key: (follower.account as ILocalAccount).keypair, | ||||
| 						keyId: `acct:${follower.username}@${config.host}` | ||||
| 					}); | ||||
| 
 | ||||
| 					const rendered = render(follower, followee); | ||||
| 					rendered['@context'] = context; | ||||
| 
 | ||||
| 					req.end(JSON.stringify(rendered)); | ||||
| 				}); | ||||
| 			} | ||||
| 
 | ||||
| 			return Promise.all([followerEvent, followeeEvent]); | ||||
| 		}) | ||||
| 	]); | ||||
| }).then(done, done); | ||||
|  | @ -1,7 +1,9 @@ | |||
| import follow from './follow'; | ||||
| import performActivityPub from './perform-activitypub'; | ||||
| import reportGitHubFailure from './report-github-failure'; | ||||
| 
 | ||||
| const handlers = { | ||||
|   follow, | ||||
|   performActivityPub, | ||||
|   reportGitHubFailure, | ||||
| }; | ||||
|  |  | |||
|  | @ -2,10 +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 notify from '../../common/notify'; | ||||
| import event from '../../../../common/event'; | ||||
| import queue from '../../../../queue'; | ||||
| 
 | ||||
| /** | ||||
|  * Follow a user | ||||
|  | @ -52,33 +51,15 @@ module.exports = (params, user) => new Promise(async (res, rej) => { | |||
| 	} | ||||
| 
 | ||||
| 	// Create following
 | ||||
| 	await Following.insert({ | ||||
| 	const { _id } = await Following.insert({ | ||||
| 		createdAt: new Date(), | ||||
| 		followerId: follower._id, | ||||
| 		followeeId: followee._id | ||||
| 	}); | ||||
| 
 | ||||
| 	queue.create('http', { type: 'follow', following: _id }).save(); | ||||
| 
 | ||||
| 	// Send response
 | ||||
| 	res(); | ||||
| 
 | ||||
| 	// Increment following count
 | ||||
| 	User.update(follower._id, { | ||||
| 		$inc: { | ||||
| 			followingCount: 1 | ||||
| 		} | ||||
| 	}); | ||||
| 
 | ||||
| 	// Increment followers count
 | ||||
| 	User.update({ _id: followee._id }, { | ||||
| 		$inc: { | ||||
| 			followersCount: 1 | ||||
| 		} | ||||
| 	}); | ||||
| 
 | ||||
| 	// Publish follow event
 | ||||
| 	event(follower._id, 'follow', await packUser(followee, follower)); | ||||
| 	event(followee._id, 'followed', await packUser(follower, followee)); | ||||
| 
 | ||||
| 	// Notify
 | ||||
| 	notify(followee._id, follower._id, 'follow'); | ||||
| }); | ||||
|  |  | |||
|  | @ -14,9 +14,9 @@ import DriveFile from '../../../../models/drive-file'; | |||
| import Watching from '../../../../models/post-watching'; | ||||
| import ChannelWatching from '../../../../models/channel-watching'; | ||||
| import { pack } from '../../../../models/post'; | ||||
| import notify from '../../common/notify'; | ||||
| import watch from '../../common/watch-post'; | ||||
| import event, { pushSw, publishChannelStream } from '../../../../common/event'; | ||||
| import notify from '../../../../common/notify'; | ||||
| import getAcct from '../../../../common/user/get-acct'; | ||||
| import parseAcct from '../../../../common/user/parse-acct'; | ||||
| import config from '../../../../conf'; | ||||
|  |  | |||
|  | @ -5,9 +5,9 @@ import $ from 'cafy'; | |||
| import Vote from '../../../../../models/poll-vote'; | ||||
| import Post from '../../../../../models/post'; | ||||
| import Watching from '../../../../../models/post-watching'; | ||||
| import notify from '../../../common/notify'; | ||||
| import watch from '../../../common/watch-post'; | ||||
| import { publishPostStream } from '../../../../../common/event'; | ||||
| import notify from '../../../../../common/notify'; | ||||
| 
 | ||||
| /** | ||||
|  * Vote poll of a post | ||||
|  |  | |||
|  | @ -6,9 +6,9 @@ import Reaction from '../../../../../models/post-reaction'; | |||
| import Post, { pack as packPost } from '../../../../../models/post'; | ||||
| import { pack as packUser } from '../../../../../models/user'; | ||||
| import Watching from '../../../../../models/post-watching'; | ||||
| import notify from '../../../common/notify'; | ||||
| import watch from '../../../common/watch-post'; | ||||
| import { publishPostStream, pushSw } from '../../../../../common/event'; | ||||
| import notify from '../../../../../common/notify'; | ||||
| 
 | ||||
| /** | ||||
|  * React to a post | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue