summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorsyuilo <Syuilotan@yahoo.co.jp>2018-04-01 23:32:46 +0900
committerGitHub <noreply@github.com>2018-04-01 23:32:46 +0900
commit13c2de67a4e5aedc9e70726752c15ff232b7c9fd (patch)
tree3da38725843c01e0dddf9a044e8017018b735325 /src
parentAdd missing semicolon (diff)
parentImplement remote follow (diff)
downloadsharkey-13c2de67a4e5aedc9e70726752c15ff232b7c9fd.tar.gz
sharkey-13c2de67a4e5aedc9e70726752c15ff232b7c9fd.tar.bz2
sharkey-13c2de67a4e5aedc9e70726752c15ff232b7c9fd.zip
Merge pull request #1356 from akihikodaki/publickey
Implement remote follow
Diffstat (limited to 'src')
-rw-r--r--src/common/notify.ts (renamed from src/server/api/common/notify.ts)8
-rw-r--r--src/common/remote/activitypub/renderer/follow.ts8
-rw-r--r--src/common/remote/activitypub/resolve-person.ts1
-rw-r--r--src/common/remote/webfinger.ts2
-rw-r--r--src/models/user.ts1
-rw-r--r--src/processor/http/follow.ts89
-rw-r--r--src/processor/http/index.ts2
-rw-r--r--src/server/api/endpoints/following/create.ts29
-rw-r--r--src/server/api/endpoints/posts/create.ts2
-rw-r--r--src/server/api/endpoints/posts/polls/vote.ts2
-rw-r--r--src/server/api/endpoints/posts/reactions/create.ts2
11 files changed, 114 insertions, 32 deletions
diff --git a/src/server/api/common/notify.ts b/src/common/notify.ts
index 69bf8480b0..fc65820d3b 100644
--- a/src/server/api/common/notify.ts
+++ b/src/common/notify.ts
@@ -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,
diff --git a/src/common/remote/activitypub/renderer/follow.ts b/src/common/remote/activitypub/renderer/follow.ts
new file mode 100644
index 0000000000..05c0ecca06
--- /dev/null
+++ b/src/common/remote/activitypub/renderer/follow.ts
@@ -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
+});
diff --git a/src/common/remote/activitypub/resolve-person.ts b/src/common/remote/activitypub/resolve-person.ts
index b8c507d358..73584946e5 100644
--- a/src/common/remote/activitypub/resolve-person.ts
+++ b/src/common/remote/activitypub/resolve-person.ts
@@ -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,
},
});
diff --git a/src/common/remote/webfinger.ts b/src/common/remote/webfinger.ts
index 9f1b916c9f..039156d776 100644
--- a/src/common/remote/webfinger.ts
+++ b/src/common/remote/webfinger.ts
@@ -1,6 +1,6 @@
const WebFinger = require('webfinger.js');
-const webFinger = new WebFinger({});
+const webFinger = new WebFinger({ tls_only: false });
type ILink = {
href: string;
diff --git a/src/models/user.ts b/src/models/user.ts
index 9588c45153..d9ac72b88f 100644
--- a/src/models/user.ts
+++ b/src/models/user.ts
@@ -70,6 +70,7 @@ export type ILocalAccount = {
};
export type IRemoteAccount = {
+ inbox: string;
uri: string;
publicKey: {
id: string;
diff --git a/src/processor/http/follow.ts b/src/processor/http/follow.ts
new file mode 100644
index 0000000000..adaa2f3f65
--- /dev/null
+++ b/src/processor/http/follow.ts
@@ -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);
diff --git a/src/processor/http/index.ts b/src/processor/http/index.ts
index da942ad2a1..a001cf11f7 100644
--- a/src/processor/http/index.ts
+++ b/src/processor/http/index.ts
@@ -1,7 +1,9 @@
+import follow from './follow';
import performActivityPub from './perform-activitypub';
import reportGitHubFailure from './report-github-failure';
const handlers = {
+ follow,
performActivityPub,
reportGitHubFailure,
};
diff --git a/src/server/api/endpoints/following/create.ts b/src/server/api/endpoints/following/create.ts
index a689250e35..03c13ab7fc 100644
--- a/src/server/api/endpoints/following/create.ts
+++ b/src/server/api/endpoints/following/create.ts
@@ -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');
});
diff --git a/src/server/api/endpoints/posts/create.ts b/src/server/api/endpoints/posts/create.ts
index 42901ebcbf..6e7d2329a7 100644
--- a/src/server/api/endpoints/posts/create.ts
+++ b/src/server/api/endpoints/posts/create.ts
@@ -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';
diff --git a/src/server/api/endpoints/posts/polls/vote.ts b/src/server/api/endpoints/posts/polls/vote.ts
index 98df074e5d..59b1f099fb 100644
--- a/src/server/api/endpoints/posts/polls/vote.ts
+++ b/src/server/api/endpoints/posts/polls/vote.ts
@@ -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
diff --git a/src/server/api/endpoints/posts/reactions/create.ts b/src/server/api/endpoints/posts/reactions/create.ts
index 8db76d6436..441d563835 100644
--- a/src/server/api/endpoints/posts/reactions/create.ts
+++ b/src/server/api/endpoints/posts/reactions/create.ts
@@ -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