From 6e34e77372bd74c85ebf5a6b4214c818231dbe8b Mon Sep 17 00:00:00 2001 From: syuilo Date: Sun, 8 Apr 2018 06:55:26 +0900 Subject: Implement announce And bug fixes --- src/remote/activitypub/act/announce/index.ts | 39 +++++++++++++++++++++ src/remote/activitypub/act/announce/note.ts | 52 ++++++++++++++++++++++++++++ src/remote/activitypub/act/index.ts | 5 +++ src/remote/activitypub/act/like.ts | 2 +- 4 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 src/remote/activitypub/act/announce/index.ts create mode 100644 src/remote/activitypub/act/announce/note.ts (limited to 'src/remote/activitypub/act') diff --git a/src/remote/activitypub/act/announce/index.ts b/src/remote/activitypub/act/announce/index.ts new file mode 100644 index 0000000000..c3ac06607d --- /dev/null +++ b/src/remote/activitypub/act/announce/index.ts @@ -0,0 +1,39 @@ +import * as debug from 'debug'; + +import Resolver from '../../resolver'; +import { IRemoteUser } from '../../../../models/user'; +import announceNote from './note'; +import { IAnnounce } from '../../type'; + +const log = debug('misskey:activitypub'); + +export default async (actor: IRemoteUser, activity: IAnnounce): Promise => { + if ('actor' in activity && actor.uri !== activity.actor) { + throw new Error('invalid actor'); + } + + const uri = activity.id || activity; + + log(`Announce: ${uri}`); + + const resolver = new Resolver(); + + let object; + + try { + object = await resolver.resolve(activity.object); + } catch (e) { + log(`Resolution failed: ${e}`); + throw e; + } + + switch (object.type) { + case 'Note': + announceNote(resolver, actor, activity, object); + break; + + default: + console.warn(`Unknown announce type: ${object.type}`); + break; + } +}; diff --git a/src/remote/activitypub/act/announce/note.ts b/src/remote/activitypub/act/announce/note.ts new file mode 100644 index 0000000000..24d159f184 --- /dev/null +++ b/src/remote/activitypub/act/announce/note.ts @@ -0,0 +1,52 @@ +import * as debug from 'debug'; + +import Resolver from '../../resolver'; +import Note from '../../../../models/note'; +import post from '../../../../services/note/create'; +import { IRemoteUser, isRemoteUser } from '../../../../models/user'; +import { IAnnounce, INote } from '../../type'; +import createNote from '../create/note'; +import resolvePerson from '../../resolve-person'; + +const log = debug('misskey:activitypub'); + +/** + * アナウンスアクティビティを捌きます + */ +export default async function(resolver: Resolver, actor: IRemoteUser, activity: IAnnounce, note: INote): Promise { + const uri = activity.id || activity; + + if (typeof uri !== 'string') { + throw new Error('invalid announce'); + } + + // 既に同じURIを持つものが登録されていないかチェック + const exist = await Note.findOne({ uri }); + if (exist) { + return; + } + + // アナウンス元の投稿の投稿者をフェッチ + const announcee = await resolvePerson(note.attributedTo); + + const renote = isRemoteUser(announcee) + ? await createNote(resolver, announcee, note, true) + : await Note.findOne({ _id: note.id.split('/').pop() }); + + log(`Creating the (Re)Note: ${uri}`); + + //#region Visibility + let visibility = 'public'; + if (!activity.to.includes('https://www.w3.org/ns/activitystreams#Public')) visibility = 'unlisted'; + if (activity.cc.length == 0) visibility = 'private'; + // TODO + if (visibility != 'public') throw new Error('unspported visibility'); + //#endergion + + await post(actor, { + createdAt: new Date(activity.published), + renote, + visibility, + uri + }); +} diff --git a/src/remote/activitypub/act/index.ts b/src/remote/activitypub/act/index.ts index 45d7bd16a9..15ea9494ae 100644 --- a/src/remote/activitypub/act/index.ts +++ b/src/remote/activitypub/act/index.ts @@ -5,6 +5,7 @@ import performDeleteActivity from './delete'; import follow from './follow'; import undo from './undo'; import like from './like'; +import announce from './announce'; const self = async (actor: IRemoteUser, activity: Object): Promise => { switch (activity.type) { @@ -24,6 +25,10 @@ const self = async (actor: IRemoteUser, activity: Object): Promise => { // noop break; + case 'Announce': + await announce(actor, activity); + break; + case 'Like': await like(actor, activity); break; diff --git a/src/remote/activitypub/act/like.ts b/src/remote/activitypub/act/like.ts index a3243948ba..4941608588 100644 --- a/src/remote/activitypub/act/like.ts +++ b/src/remote/activitypub/act/like.ts @@ -7,7 +7,7 @@ export default async (actor: IRemoteUser, activity: ILike) => { const id = typeof activity.object == 'string' ? activity.object : activity.object.id; // Transform: - // https://misskey.ex/@syuilo/xxxx to + // https://misskey.ex/notes/xxxx to // xxxx const noteId = id.split('/').pop(); -- cgit v1.2.3-freya