summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorsyuilo <Syuilotan@yahoo.co.jp>2018-09-01 21:38:49 +0900
committerGitHub <noreply@github.com>2018-09-01 21:38:49 +0900
commit4b1886990f7de0a1b993b2f3f17c3ee99f78a5ec (patch)
tree15426a39bf9b6d30c1ddb50a61e070d5bda6300a /src
parent8.20.0 (diff)
parentSend Update activity (diff)
downloadsharkey-4b1886990f7de0a1b993b2f3f17c3ee99f78a5ec.tar.gz
sharkey-4b1886990f7de0a1b993b2f3f17c3ee99f78a5ec.tar.bz2
sharkey-4b1886990f7de0a1b993b2f3f17c3ee99f78a5ec.zip
Merge pull request #2570 from mei23/mei-0901-update2b
Implement ActivityPub Update(Person)
Diffstat (limited to 'src')
-rw-r--r--src/queue/processors/http/process-inbox.ts28
-rw-r--r--src/remote/activitypub/models/person.ts18
-rw-r--r--src/remote/activitypub/renderer/update.ts14
-rw-r--r--src/server/api/endpoints/i/update.ts4
-rw-r--r--src/services/i/update.ts38
5 files changed, 89 insertions, 13 deletions
diff --git a/src/queue/processors/http/process-inbox.ts b/src/queue/processors/http/process-inbox.ts
index 7e564dd32a..8e6b3769de 100644
--- a/src/queue/processors/http/process-inbox.ts
+++ b/src/queue/processors/http/process-inbox.ts
@@ -5,7 +5,7 @@ const httpSignature = require('http-signature');
import parseAcct from '../../../misc/acct/parse';
import User, { IRemoteUser } from '../../../models/user';
import perform from '../../../remote/activitypub/perform';
-import { resolvePerson } from '../../../remote/activitypub/models/person';
+import { resolvePerson, updatePerson } from '../../../remote/activitypub/models/person';
import { toUnicode } from 'punycode';
import { URL } from 'url';
@@ -44,11 +44,6 @@ export default async (job: bq.Job, done: any): Promise<void> => {
}
user = await User.findOne({ usernameLower: username, host: host.toLowerCase() }) as IRemoteUser;
-
- // アクティビティを送信してきたユーザーがまだMisskeyサーバーに登録されていなかったら登録する
- if (user === null) {
- user = await resolvePerson(activity.actor) as IRemoteUser;
- }
} else {
// アクティビティ内のホストの検証
const host = toUnicode(new URL(signature.keyId).hostname.toLowerCase());
@@ -64,11 +59,26 @@ export default async (job: bq.Job, done: any): Promise<void> => {
host: { $ne: null },
'publicKey.id': signature.keyId
}) as IRemoteUser;
+ }
- // アクティビティを送信してきたユーザーがまだMisskeyサーバーに登録されていなかったら登録する
- if (user === null) {
- user = await resolvePerson(activity.actor) as IRemoteUser;
+ // Update activityの場合は、ここで署名検証/更新処理まで実施して終了
+ if (activity.type === 'Update') {
+ if (activity.object && activity.object.type === 'Person') {
+ if (user == null) {
+ console.warn('Update activity received, but user not registed.');
+ } else if (!httpSignature.verifySignature(signature, user.publicKey.publicKeyPem)) {
+ console.warn('Update activity received, but signature verification failed.');
+ } else {
+ updatePerson(activity.actor, null, activity.object);
+ }
}
+ done();
+ return;
+ }
+
+ // アクティビティを送信してきたユーザーがまだMisskeyサーバーに登録されていなかったら登録する
+ if (user === null) {
+ user = await resolvePerson(activity.actor) as IRemoteUser;
}
if (user === null) {
diff --git a/src/remote/activitypub/models/person.ts b/src/remote/activitypub/models/person.ts
index 3bd4e16763..dff38f5460 100644
--- a/src/remote/activitypub/models/person.ts
+++ b/src/remote/activitypub/models/person.ts
@@ -139,6 +139,7 @@ export async function createPerson(uri: string, resolver?: Resolver): Promise<IU
avatarId: null,
bannerId: null,
createdAt: Date.parse(person.published) || null,
+ updatedAt: new Date(),
description: htmlToMFM(person.summary),
followersCount,
followingCount,
@@ -215,10 +216,12 @@ export async function createPerson(uri: string, resolver?: Resolver): Promise<IU
/**
* Personの情報を更新します。
- *
* Misskeyに対象のPersonが登録されていなければ無視します。
+ * @param uri URI of Person
+ * @param resolver Resolver
+ * @param hint Hint of Person object (この値が正当なPersonの場合、Remote resolveをせずに更新に利用します)
*/
-export async function updatePerson(uri: string, resolver?: Resolver): Promise<void> {
+export async function updatePerson(uri: string, resolver?: Resolver, hint?: object): Promise<void> {
if (typeof uri !== 'string') throw 'uri is not string';
// URIがこのサーバーを指しているならスキップ
@@ -236,7 +239,7 @@ export async function updatePerson(uri: string, resolver?: Resolver): Promise<vo
if (resolver == null) resolver = new Resolver();
- const object = await resolver.resolve(uri) as any;
+ const object = hint || await resolver.resolve(uri) as any;
const err = validatePerson(object, uri);
@@ -290,7 +293,14 @@ export async function updatePerson(uri: string, resolver?: Resolver): Promise<vo
name: person.name,
url: person.url,
endpoints: person.endpoints,
- isCat: (person as any).isCat === true ? true : false
+ isBot: object.type == 'Service',
+ isCat: (person as any).isCat === true ? true : false,
+ isLocked: person.manuallyApprovesFollowers,
+ createdAt: Date.parse(person.published) || null,
+ publicKey: {
+ id: person.publicKey.id,
+ publicKeyPem: person.publicKey.publicKeyPem
+ },
}
});
}
diff --git a/src/remote/activitypub/renderer/update.ts b/src/remote/activitypub/renderer/update.ts
new file mode 100644
index 0000000000..cf9acc9acb
--- /dev/null
+++ b/src/remote/activitypub/renderer/update.ts
@@ -0,0 +1,14 @@
+import config from '../../../config';
+import { ILocalUser } from '../../../models/user';
+
+export default (object: any, user: ILocalUser) => {
+ const activity = {
+ id: `${config.url}/users/${user._id}#updates/${new Date().getTime()}`,
+ actor: `${config.url}/users/${user._id}`,
+ type: 'Update',
+ to: [ 'https://www.w3.org/ns/activitystreams#Public' ],
+ object
+ } as any;
+
+ return activity;
+};
diff --git a/src/server/api/endpoints/i/update.ts b/src/server/api/endpoints/i/update.ts
index cdb4eb3f56..585339e249 100644
--- a/src/server/api/endpoints/i/update.ts
+++ b/src/server/api/endpoints/i/update.ts
@@ -5,6 +5,7 @@ import DriveFile from '../../../../models/drive-file';
import acceptAllFollowRequests from '../../../../services/following/requests/accept-all';
import { IApp } from '../../../../models/app';
import config from '../../../../config';
+import { publishToFollowers } from '../../../../services/i/update';
export const meta = {
desc: {
@@ -144,4 +145,7 @@ export default async (params: any, user: ILocalUser, app: IApp) => new Promise(a
if (user.isLocked && isLocked === false) {
acceptAllFollowRequests(user);
}
+
+ // フォロワーにUpdateを配信
+ publishToFollowers(user._id);
});
diff --git a/src/services/i/update.ts b/src/services/i/update.ts
new file mode 100644
index 0000000000..25b55b0355
--- /dev/null
+++ b/src/services/i/update.ts
@@ -0,0 +1,38 @@
+import * as mongo from 'mongodb';
+import User, { isLocalUser, isRemoteUser } from '../../models/user';
+import Following from '../../models/following';
+import renderPerson from '../../remote/activitypub/renderer/person';
+import renderUpdate from '../../remote/activitypub/renderer/update';
+import packAp from '../../remote/activitypub/renderer';
+import { deliver } from '../../queue';
+
+export async function publishToFollowers(userId: mongo.ObjectID) {
+ const user = await User.findOne({
+ _id: userId
+ });
+
+ const followers = await Following.find({
+ followeeId: user._id
+ });
+
+ const queue: string[] = [];
+
+ // フォロワーがリモートユーザーかつ投稿者がローカルユーザーならUpdateを配信
+ if (isLocalUser(user)) {
+ followers.map(following => {
+ const follower = following._follower;
+
+ if (isRemoteUser(follower)) {
+ const inbox = follower.sharedInbox || follower.inbox;
+ if (!queue.includes(inbox)) queue.push(inbox);
+ }
+ });
+
+ if (queue.length > 0) {
+ const content = packAp(renderUpdate(await renderPerson(user), user));
+ queue.forEach(inbox => {
+ deliver(user, content, inbox);
+ });
+ }
+ }
+}