summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorsyuilo <Syuilotan@yahoo.co.jp>2018-04-02 19:53:04 +0900
committerGitHub <noreply@github.com>2018-04-02 19:53:04 +0900
commit4fc04acdc1f08b6770a5f34d562f130b4c4db0c4 (patch)
tree87ff0708cb2c8ea8953d16f289bf22fc71df5307 /src
parentMerge pull request #1372 from akihikodaki/misc (diff)
parentImplement Follow activity (diff)
downloadsharkey-4fc04acdc1f08b6770a5f34d562f130b4c4db0c4.tar.gz
sharkey-4fc04acdc1f08b6770a5f34d562f130b4c4db0c4.tar.bz2
sharkey-4fc04acdc1f08b6770a5f34d562f130b4c4db0c4.zip
Merge pull request #1373 from akihikodaki/misc
Implement Follow activity
Diffstat (limited to 'src')
-rw-r--r--src/models/following.ts1
-rw-r--r--src/processor/http/follow.ts14
-rw-r--r--src/remote/activitypub/act/follow.ts51
-rw-r--r--src/remote/activitypub/act/index.ts4
4 files changed, 65 insertions, 5 deletions
diff --git a/src/models/following.ts b/src/models/following.ts
index 3f8a9be50f..fe9ce550d3 100644
--- a/src/models/following.ts
+++ b/src/models/following.ts
@@ -2,6 +2,7 @@ import * as mongo from 'mongodb';
import db from '../db/mongodb';
const Following = db.get<IFollowing>('following');
+Following.createIndex(['followerId', 'followeeId'], { unique: true });
export default Following;
export type IFollowing = {
diff --git a/src/processor/http/follow.ts b/src/processor/http/follow.ts
index a7e4fa23d5..7ec1ee6756 100644
--- a/src/processor/http/follow.ts
+++ b/src/processor/http/follow.ts
@@ -1,7 +1,7 @@
import { request } from 'https';
import { sign } from 'http-signature';
import { URL } from 'url';
-import User, { isLocalUser, pack as packUser, ILocalUser } from '../../models/user';
+import User, { isLocalUser, pack as packUser } from '../../models/user';
import Following from '../../models/following';
import event from '../../publishers/stream';
import notify from '../../publishers/notify';
@@ -10,7 +10,7 @@ import render from '../../remote/activitypub/renderer/follow';
import config from '../../config';
export default ({ data }, done) => Following.findOne({ _id: data.following }).then(({ followerId, followeeId }) => {
- const promisedFollower: Promise<ILocalUser> = User.findOne({ _id: followerId });
+ const promisedFollower = User.findOne({ _id: followerId });
const promisedFollowee = User.findOne({ _id: followeeId });
return Promise.all([
@@ -34,14 +34,18 @@ export default ({ data }, done) => Following.findOne({ _id: data.following }).th
// Publish follow event
Promise.all([promisedFollower, promisedFollowee]).then(([follower, followee]) => {
- const followerEvent = packUser(followee, follower)
- .then(packed => event(follower._id, 'follow', packed));
+ let followerEvent;
let followeeEvent;
+ if (isLocalUser(follower)) {
+ followerEvent = packUser(followee, follower)
+ .then(packed => event(follower._id, 'follow', packed));
+ }
+
if (isLocalUser(followee)) {
followeeEvent = packUser(follower, followee)
.then(packed => event(followee._id, 'followed', packed));
- } else {
+ } else if (isLocalUser(follower)) {
followeeEvent = new Promise((resolve, reject) => {
const {
protocol,
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;
}