diff --git a/src/remote/activitypub/act/create.ts b/src/remote/activitypub/act/create.ts index f97832a989..80afb61bd7 100644 --- a/src/remote/activitypub/act/create.ts +++ b/src/remote/activitypub/act/create.ts @@ -1,11 +1,13 @@ import { JSDOM } from 'jsdom'; +import * as debug from 'debug'; import Resolver from '../resolver'; -import DriveFile from '../../../models/drive-file'; import Post from '../../../models/post'; import uploadFromUrl from '../../../api/drive/upload-from-url'; import createPost from '../../../api/post/create'; +const log = debug('misskey:activitypub'); + export default async (actor, activity): Promise => { if ('actor' in activity && actor.account.uri !== activity.actor) { throw new Error('invalid actor'); @@ -13,26 +15,20 @@ export default async (actor, activity): Promise => { const uri = activity.id || activity; - try { - await Promise.all([ - DriveFile.findOne({ 'metadata.uri': uri }).then(file => { - if (file !== null) { - throw new Error(); - } - }, () => {}), - Post.findOne({ uri }).then(post => { - if (post !== null) { - throw new Error(); - } - }, () => {}) - ]); - } catch (object) { - throw new Error(`already registered: ${uri}`); - } + log(`Create: ${uri}`); + + // TODO: 同じURIをもつものが既に登録されていないかチェック const resolver = new Resolver(); - const object = await resolver.resolve(activity); + let object; + + try { + object = await resolver.resolve(activity.object); + } catch (e) { + log(`Resolve failed: ${e}`); + throw e; + } switch (object.type) { case 'Image': @@ -42,15 +38,22 @@ export default async (actor, activity): Promise => { case 'Note': createNote(object); break; + + default: + console.warn(`Unknown type: ${object.type}`); + break; } /// async function createImage(image) { if ('attributedTo' in image && actor.account.uri !== image.attributedTo) { + log(`invalid image: ${JSON.stringify(image, null, 2)}`); throw new Error('invalid image'); } + log(`Creating the Image: ${uri}`); + return await uploadFromUrl(image.url, actor); } @@ -59,11 +62,14 @@ export default async (actor, activity): Promise => { ('attributedTo' in note && actor.account.uri !== note.attributedTo) || typeof note.id !== 'string' ) { + log(`invalid note: ${JSON.stringify(note, null, 2)}`); throw new Error('invalid note'); } + log(`Creating the Note: ${uri}`); + const media = []; - if ('attachment' in note) { + if ('attachment' in note && note.attachment != null) { note.attachment.forEach(async media => { const created = await createImage(media); media.push(created); @@ -71,7 +77,7 @@ export default async (actor, activity): Promise => { } let reply = null; - if ('inReplyTo' in note) { + if ('inReplyTo' in note && note.inReplyTo != null) { const inReplyToPost = await Post.findOne({ uri: note.id || note }); if (inReplyToPost) { reply = inReplyToPost; diff --git a/src/remote/activitypub/act/index.ts b/src/remote/activitypub/act/index.ts index f22500acef..5840227098 100644 --- a/src/remote/activitypub/act/index.ts +++ b/src/remote/activitypub/act/index.ts @@ -18,6 +18,10 @@ export default async (actor, activity: IObject): Promise => { await follow(actor, activity); break; + case 'Accept': + // noop + break; + case 'Undo': await undo(actor, activity); break; diff --git a/src/remote/activitypub/renderer/note.ts b/src/remote/activitypub/renderer/note.ts index 43531b121a..e45b10215a 100644 --- a/src/remote/activitypub/renderer/note.ts +++ b/src/remote/activitypub/renderer/note.ts @@ -2,11 +2,14 @@ import renderDocument from './document'; import renderHashtag from './hashtag'; import config from '../../../config'; import DriveFile from '../../../models/drive-file'; -import Post from '../../../models/post'; -import User from '../../../models/user'; +import Post, { IPost } from '../../../models/post'; +import User, { IUser } from '../../../models/user'; + +export default async (user: IUser, post: IPost) => { + const promisedFiles = post.mediaIds + ? DriveFile.find({ _id: { $in: post.mediaIds } }) + : Promise.resolve([]); -export default async (user, post) => { - const promisedFiles = DriveFile.find({ _id: { $in: post.mediaIds } }); let inReplyTo; if (post.replyId) { @@ -39,6 +42,6 @@ export default async (user, post) => { cc: `${attributedTo}/followers`, inReplyTo, attachment: (await promisedFiles).map(renderDocument), - tag: post.tags.map(renderHashtag) + tag: (post.tags || []).map(renderHashtag) }; };