From 7942f76acb5363e065b681f70f91fe785480a298 Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Mon, 2 Apr 2018 19:50:40 +0900 Subject: Implement Follow activity --- src/remote/activitypub/act/follow.ts | 51 ++++++++++++++++++++++++++++++++++++ src/remote/activitypub/act/index.ts | 4 +++ 2 files changed, 55 insertions(+) create mode 100644 src/remote/activitypub/act/follow.ts (limited to 'src/remote') diff --git a/src/remote/activitypub/act/follow.ts b/src/remote/activitypub/act/follow.ts new file mode 100644 index 0000000000..ec9e080dfc --- /dev/null +++ b/src/remote/activitypub/act/follow.ts @@ -0,0 +1,51 @@ +import { MongoError } from 'mongodb'; +import parseAcct from '../../../acct/parse'; +import Following from '../../../models/following'; +import User from '../../../models/user'; +import config from '../../../config'; +import queue from '../../../queue'; + +export default async (actor, activity) => { + const prefix = config.url + '/@'; + const id = activity.object.id || activity.object; + let following; + + if (!id.startsWith(prefix)) { + return null; + } + + const { username, host } = parseAcct(id.slice(prefix.length)); + if (host !== null) { + throw new Error(); + } + + const followee = await User.findOne({ username, host }); + if (followee === null) { + throw new Error(); + } + + try { + following = await Following.insert({ + createdAt: new Date(), + followerId: actor._id, + followeeId: followee._id + }); + } catch (exception) { + // duplicate key error + if (exception instanceof MongoError && exception.code === 11000) { + return null; + } + + throw exception; + } + + await new Promise((resolve, reject) => { + queue.create('http', { type: 'follow', following: following._id }).save(error => { + if (error) { + reject(error); + } else { + resolve(null); + } + }); + }); +}; diff --git a/src/remote/activitypub/act/index.ts b/src/remote/activitypub/act/index.ts index 06d662c191..24320dcb1d 100644 --- a/src/remote/activitypub/act/index.ts +++ b/src/remote/activitypub/act/index.ts @@ -1,4 +1,5 @@ import create from './create'; +import follow from './follow'; import createObject from '../create'; import Resolver from '../resolver'; @@ -15,6 +16,9 @@ export default (actor, value, distribute) => { case 'Create': return create(resolver, actor, object, distribute); + case 'Follow': + return follow(actor, object); + default: return null; } -- cgit v1.2.3-freya