From e8b42d7e1668679e6a6ee0a7aea1e2ff7f37005b Mon Sep 17 00:00:00 2001 From: syuilo Date: Wed, 4 Apr 2018 23:12:35 +0900 Subject: wip --- src/queue/processors/http/process-inbox.ts | 55 ++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 src/queue/processors/http/process-inbox.ts (limited to 'src/queue/processors/http/process-inbox.ts') diff --git a/src/queue/processors/http/process-inbox.ts b/src/queue/processors/http/process-inbox.ts new file mode 100644 index 0000000000..fff1fbf663 --- /dev/null +++ b/src/queue/processors/http/process-inbox.ts @@ -0,0 +1,55 @@ +import * as kue from 'kue'; + +import { verifySignature } from 'http-signature'; +import parseAcct from '../../acct/parse'; +import User, { IRemoteUser } from '../../models/user'; +import act from '../../remote/activitypub/act'; +import resolvePerson from '../../remote/activitypub/resolve-person'; +import Resolver from '../../remote/activitypub/resolver'; + +// ユーザーのinboxにアクティビティが届いた時の処理 +export default async (job: kue.Job, done): Promise => { + const signature = job.data.signature; + const activity = job.data.activity; + + const keyIdLower = signature.keyId.toLowerCase(); + let user; + + if (keyIdLower.startsWith('acct:')) { + const { username, host } = parseAcct(keyIdLower.slice('acct:'.length)); + if (host === null) { + console.warn(`request was made by local user: @${username}`); + done(); + } + + user = await User.findOne({ usernameLower: username, hostLower: host }) as IRemoteUser; + } else { + user = await User.findOne({ + host: { $ne: null }, + 'account.publicKey.id': signature.keyId + }) as IRemoteUser; + + // アクティビティを送信してきたユーザーがまだMisskeyサーバーに登録されていなかったら登録する + if (user === null) { + user = await resolvePerson(signature.keyId); + } + } + + if (user === null) { + done(new Error('failed to resolve user')); + return; + } + + if (!verifySignature(signature, user.account.publicKey.publicKeyPem)) { + done(new Error('signature verification failed')); + return; + } + + // アクティビティを処理 + try { + await act(new Resolver(), user, activity); + done(); + } catch (e) { + done(e); + } +}; -- cgit v1.2.3-freya From b6b98752053042b3b37d5b94bc823635edc2061f Mon Sep 17 00:00:00 2001 From: syuilo Date: Thu, 5 Apr 2018 01:24:01 +0900 Subject: wip --- src/queue/processors/http/process-inbox.ts | 12 ++++++------ src/queue/processors/index.ts | 18 ------------------ 2 files changed, 6 insertions(+), 24 deletions(-) delete mode 100644 src/queue/processors/index.ts (limited to 'src/queue/processors/http/process-inbox.ts') diff --git a/src/queue/processors/http/process-inbox.ts b/src/queue/processors/http/process-inbox.ts index fff1fbf663..82585d3a6b 100644 --- a/src/queue/processors/http/process-inbox.ts +++ b/src/queue/processors/http/process-inbox.ts @@ -1,11 +1,11 @@ import * as kue from 'kue'; import { verifySignature } from 'http-signature'; -import parseAcct from '../../acct/parse'; -import User, { IRemoteUser } from '../../models/user'; -import act from '../../remote/activitypub/act'; -import resolvePerson from '../../remote/activitypub/resolve-person'; -import Resolver from '../../remote/activitypub/resolver'; +import parseAcct from '../../../acct/parse'; +import User, { IRemoteUser } from '../../../models/user'; +import act from '../../../remote/activitypub/act'; +import resolvePerson from '../../../remote/activitypub/resolve-person'; +import Resolver from '../../../remote/activitypub/resolver'; // ユーザーのinboxにアクティビティが届いた時の処理 export default async (job: kue.Job, done): Promise => { @@ -47,7 +47,7 @@ export default async (job: kue.Job, done): Promise => { // アクティビティを処理 try { - await act(new Resolver(), user, activity); + await act(user, activity); done(); } catch (e) { done(e); diff --git a/src/queue/processors/index.ts b/src/queue/processors/index.ts deleted file mode 100644 index 172048ddae..0000000000 --- a/src/queue/processors/index.ts +++ /dev/null @@ -1,18 +0,0 @@ -import queue from '../queue'; -import db from './db'; -import http from './http'; - -export default () => { - queue.process('db', db); - - /* - 256 is the default concurrency limit of Mozilla Firefox and Google - Chromium. - - a8af215e691f3a2205a3758d2d96e9d328e100ff - chromium/src.git - Git at Google - https://chromium.googlesource.com/chromium/src.git/+/a8af215e691f3a2205a3758d2d96e9d328e100ff - Network.http.max-connections - MozillaZine Knowledge Base - http://kb.mozillazine.org/Network.http.max-connections - */ - queue.process('http', 256, http); -}; -- cgit v1.2.3-freya From c2c03a1c650c0395fc4d77334ec86d00b1bb24c2 Mon Sep 17 00:00:00 2001 From: syuilo Date: Thu, 5 Apr 2018 03:21:11 +0900 Subject: wip --- src/api/drive/add-file.ts | 12 ++++----- src/api/drive/upload-from-url.ts | 2 +- src/api/post/create.ts | 13 +++++----- src/api/post/watch.ts | 2 +- src/queue/processors/db/delete-post-dependents.ts | 12 ++++----- src/queue/processors/http/process-inbox.ts | 1 - src/remote/activitypub/act/create.ts | 25 ++++++++++++------ src/remote/activitypub/act/delete.ts | 31 ++++++++++++++--------- src/remote/activitypub/act/undo.ts | 2 +- src/remote/activitypub/delete/index.ts | 10 -------- src/remote/activitypub/delete/post.ts | 13 ---------- src/remote/activitypub/resolve-person.ts | 1 - src/server/activitypub/inbox.ts | 4 +-- 13 files changed, 60 insertions(+), 68 deletions(-) delete mode 100644 src/remote/activitypub/delete/index.ts delete mode 100644 src/remote/activitypub/delete/post.ts (limited to 'src/queue/processors/http/process-inbox.ts') diff --git a/src/api/drive/add-file.ts b/src/api/drive/add-file.ts index 24eb5208d5..64a2f18340 100644 --- a/src/api/drive/add-file.ts +++ b/src/api/drive/add-file.ts @@ -10,12 +10,12 @@ import * as debug from 'debug'; import fileType = require('file-type'); import prominence = require('prominence'); -import DriveFile, { IMetadata, getGridFSBucket } from '../models/drive-file'; -import DriveFolder from '../models/drive-folder'; -import { pack } from '../models/drive-file'; -import event, { publishDriveStream } from '../publishers/stream'; -import getAcct from '../acct/render'; -import config from '../config'; +import DriveFile, { IMetadata, getGridFSBucket } from '../../models/drive-file'; +import DriveFolder from '../../models/drive-folder'; +import { pack } from '../../models/drive-file'; +import event, { publishDriveStream } from '../../publishers/stream'; +import getAcct from '../../acct/render'; +import config from '../../config'; const gm = _gm.subClass({ imageMagick: true diff --git a/src/api/drive/upload-from-url.ts b/src/api/drive/upload-from-url.ts index f96af0f266..26c890d157 100644 --- a/src/api/drive/upload-from-url.ts +++ b/src/api/drive/upload-from-url.ts @@ -1,5 +1,5 @@ import * as URL from 'url'; -import { IDriveFile, validateFileName } from '../models/drive-file'; +import { IDriveFile, validateFileName } from '../../models/drive-file'; import create from './add-file'; import * as debug from 'debug'; import * as tmp from 'tmp'; diff --git a/src/api/post/create.ts b/src/api/post/create.ts index 8256cbc355..36819ec2b8 100644 --- a/src/api/post/create.ts +++ b/src/api/post/create.ts @@ -1,6 +1,5 @@ -import parseAcct from '../../acct/parse'; import Post, { pack, IPost } from '../../models/post'; -import User, { isLocalUser, isRemoteUser, IUser } from '../../models/user'; +import User, { isLocalUser, IUser } from '../../models/user'; import stream from '../../publishers/stream'; import Following from '../../models/following'; import { createHttp } from '../../queue'; @@ -25,14 +24,16 @@ export default async (user: IUser, content: { repost: IPost; media: IDriveFile[]; geo: any; - poll: any; + poll?: any; viaMobile: boolean; - tags: string[]; - cw: string; - visibility: string; + tags?: string[]; + cw?: string; + visibility?: string; uri?: string; app?: IApp; }) => new Promise(async (res, rej) => { + if (content.visibility == null) content.visibility = 'public'; + const tags = content.tags || []; let tokens = null; diff --git a/src/api/post/watch.ts b/src/api/post/watch.ts index 61ea444430..bbd9976f40 100644 --- a/src/api/post/watch.ts +++ b/src/api/post/watch.ts @@ -1,5 +1,5 @@ import * as mongodb from 'mongodb'; -import Watching from '../models/post-watching'; +import Watching from '../../models/post-watching'; export default async (me: mongodb.ObjectID, post: object) => { // 自分の投稿はwatchできない diff --git a/src/queue/processors/db/delete-post-dependents.ts b/src/queue/processors/db/delete-post-dependents.ts index 879c41ec9c..6de21eb053 100644 --- a/src/queue/processors/db/delete-post-dependents.ts +++ b/src/queue/processors/db/delete-post-dependents.ts @@ -1,9 +1,9 @@ -import Favorite from '../../models/favorite'; -import Notification from '../../models/notification'; -import PollVote from '../../models/poll-vote'; -import PostReaction from '../../models/post-reaction'; -import PostWatching from '../../models/post-watching'; -import Post from '../../models/post'; +import Favorite from '../../../models/favorite'; +import Notification from '../../../models/notification'; +import PollVote from '../../../models/poll-vote'; +import PostReaction from '../../../models/post-reaction'; +import PostWatching from '../../../models/post-watching'; +import Post from '../../../models/post'; export default async ({ data }) => Promise.all([ Favorite.remove({ postId: data._id }), diff --git a/src/queue/processors/http/process-inbox.ts b/src/queue/processors/http/process-inbox.ts index 82585d3a6b..c3074429f8 100644 --- a/src/queue/processors/http/process-inbox.ts +++ b/src/queue/processors/http/process-inbox.ts @@ -5,7 +5,6 @@ import parseAcct from '../../../acct/parse'; import User, { IRemoteUser } from '../../../models/user'; import act from '../../../remote/activitypub/act'; import resolvePerson from '../../../remote/activitypub/resolve-person'; -import Resolver from '../../../remote/activitypub/resolver'; // ユーザーのinboxにアクティビティが届いた時の処理 export default async (job: kue.Job, done): Promise => { diff --git a/src/remote/activitypub/act/create.ts b/src/remote/activitypub/act/create.ts index c486571fc1..f97832a989 100644 --- a/src/remote/activitypub/act/create.ts +++ b/src/remote/activitypub/act/create.ts @@ -36,17 +36,17 @@ export default async (actor, activity): Promise => { switch (object.type) { case 'Image': - createImage(resolver, object); + createImage(object); break; case 'Note': - createNote(resolver, object); + createNote(object); break; } /// - async function createImage(resolver: Resolver, image) { + async function createImage(image) { if ('attributedTo' in image && actor.account.uri !== image.attributedTo) { throw new Error('invalid image'); } @@ -54,7 +54,7 @@ export default async (actor, activity): Promise => { return await uploadFromUrl(image.url, actor); } - async function createNote(resolver: Resolver, note) { + async function createNote(note) { if ( ('attributedTo' in note && actor.account.uri !== note.attributedTo) || typeof note.id !== 'string' @@ -63,20 +63,29 @@ export default async (actor, activity): Promise => { } const media = []; - if ('attachment' in note) { note.attachment.forEach(async media => { - const created = await createImage(resolver, media); + const created = await createImage(media); media.push(created); }); } + let reply = null; + if ('inReplyTo' in note) { + const inReplyToPost = await Post.findOne({ uri: note.id || note }); + if (inReplyToPost) { + reply = inReplyToPost; + } else { + reply = await createNote(await resolver.resolve(note)); + } + } + const { window } = new JSDOM(note.content); - await createPost(actor, { + return await createPost(actor, { createdAt: new Date(note.published), media, - reply: undefined, + reply, repost: undefined, text: window.document.body.textContent, viaMobile: false, diff --git a/src/remote/activitypub/act/delete.ts b/src/remote/activitypub/act/delete.ts index f9eb4dd08d..334ca47edf 100644 --- a/src/remote/activitypub/act/delete.ts +++ b/src/remote/activitypub/act/delete.ts @@ -1,21 +1,28 @@ -import create from '../create'; -import deleteObject from '../delete'; +import Resolver from '../resolver'; +import Post from '../../../models/post'; +import { createDb } from '../../../queue'; -export default async (resolver, actor, activity) => { +export default async (actor, activity): Promise => { if ('actor' in activity && actor.account.uri !== activity.actor) { throw new Error(); } - const results = await create(resolver, actor, activity.object); + const resolver = new Resolver(); - await Promise.all(results.map(async promisedResult => { - const result = await promisedResult; - if (result === null) { - return; - } + const object = await resolver.resolve(activity); - await deleteObject(result); - })); + switch (object.type) { + case 'Note': + deleteNote(object); + break; + } + + async function deleteNote(note) { + const post = await Post.findOneAndDelete({ uri: note.id }); - return null; + createDb({ + type: 'deletePostDependents', + id: post._id + }).delay(65536).save(); + } }; diff --git a/src/remote/activitypub/act/undo.ts b/src/remote/activitypub/act/undo.ts index b3b83777d1..9d9f6b0359 100644 --- a/src/remote/activitypub/act/undo.ts +++ b/src/remote/activitypub/act/undo.ts @@ -7,7 +7,7 @@ export default async (actor, activity): Promise => { switch (activity.object.type) { case 'Follow': - unfollow(activity.object); + unfollow(actor, activity.object); break; } diff --git a/src/remote/activitypub/delete/index.ts b/src/remote/activitypub/delete/index.ts deleted file mode 100644 index bc9104284b..0000000000 --- a/src/remote/activitypub/delete/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -import deletePost from './post'; - -export default async ({ object }) => { - switch (object.$ref) { - case 'posts': - return deletePost(object); - } - - return null; -}; diff --git a/src/remote/activitypub/delete/post.ts b/src/remote/activitypub/delete/post.ts deleted file mode 100644 index f6c816647d..0000000000 --- a/src/remote/activitypub/delete/post.ts +++ /dev/null @@ -1,13 +0,0 @@ -import Post from '../../../models/post'; -import queue from '../../../queue'; - -export default async ({ $id }) => { - const promisedDeletion = Post.findOneAndDelete({ _id: $id }); - - await new Promise((resolve, reject) => queue.create('db', { - type: 'deletePostDependents', - id: $id - }).delay(65536).save(error => error ? reject(error) : resolve())); - - return promisedDeletion; -}; diff --git a/src/remote/activitypub/resolve-person.ts b/src/remote/activitypub/resolve-person.ts index 77d08398be..28162497f3 100644 --- a/src/remote/activitypub/resolve-person.ts +++ b/src/remote/activitypub/resolve-person.ts @@ -2,7 +2,6 @@ import { JSDOM } from 'jsdom'; import { toUnicode } from 'punycode'; import User, { validateUsername, isValidName, isValidDescription } from '../../models/user'; import webFinger from '../webfinger'; -import create from './create'; import Resolver from './resolver'; import uploadFromUrl from '../../api/drive/upload-from-url'; diff --git a/src/server/activitypub/inbox.ts b/src/server/activitypub/inbox.ts index 847dc19af6..b0015409a9 100644 --- a/src/server/activitypub/inbox.ts +++ b/src/server/activitypub/inbox.ts @@ -1,7 +1,7 @@ import * as bodyParser from 'body-parser'; import * as express from 'express'; import { parseRequest } from 'http-signature'; -import queue from '../../queue'; +import { createHttp } from '../../queue'; const app = express(); @@ -22,7 +22,7 @@ app.post('/@:user/inbox', bodyParser.json({ return res.sendStatus(401); } - queue.create('http', { + createHttp({ type: 'processInbox', activity: req.body, signature, -- cgit v1.2.3-freya From 862463a13cc952919322b4e2f06c196bf2850517 Mon Sep 17 00:00:00 2001 From: syuilo Date: Fri, 6 Apr 2018 14:35:17 +0900 Subject: Fix bug --- src/queue/processors/http/process-inbox.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/queue/processors/http/process-inbox.ts') diff --git a/src/queue/processors/http/process-inbox.ts b/src/queue/processors/http/process-inbox.ts index c3074429f8..4666e7f373 100644 --- a/src/queue/processors/http/process-inbox.ts +++ b/src/queue/processors/http/process-inbox.ts @@ -19,6 +19,7 @@ export default async (job: kue.Job, done): Promise => { if (host === null) { console.warn(`request was made by local user: @${username}`); done(); + return; } user = await User.findOne({ usernameLower: username, hostLower: host }) as IRemoteUser; @@ -40,7 +41,8 @@ export default async (job: kue.Job, done): Promise => { } if (!verifySignature(signature, user.account.publicKey.publicKeyPem)) { - done(new Error('signature verification failed')); + console.warn('signature verification failed'); + done(); return; } -- cgit v1.2.3-freya From 3cf6eab11945e5b2577ef67117a51a210529e456 Mon Sep 17 00:00:00 2001 From: syuilo Date: Fri, 6 Apr 2018 22:40:06 +0900 Subject: Log --- src/queue/processors/http/process-inbox.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/queue/processors/http/process-inbox.ts') diff --git a/src/queue/processors/http/process-inbox.ts b/src/queue/processors/http/process-inbox.ts index 4666e7f373..eb4b62d37f 100644 --- a/src/queue/processors/http/process-inbox.ts +++ b/src/queue/processors/http/process-inbox.ts @@ -1,4 +1,5 @@ import * as kue from 'kue'; +import * as debug from 'debug'; import { verifySignature } from 'http-signature'; import parseAcct from '../../../acct/parse'; @@ -6,11 +7,20 @@ import User, { IRemoteUser } from '../../../models/user'; import act from '../../../remote/activitypub/act'; import resolvePerson from '../../../remote/activitypub/resolve-person'; +const log = debug('misskey:queue:inbox'); + // ユーザーのinboxにアクティビティが届いた時の処理 export default async (job: kue.Job, done): Promise => { const signature = job.data.signature; const activity = job.data.activity; + //#region Log + const info = Object.assign({}, activity); + delete info['@context']; + delete info['signature']; + log(info); + //#endregion + const keyIdLower = signature.keyId.toLowerCase(); let user; -- cgit v1.2.3-freya