diff options
Diffstat (limited to 'src/common/remote/activitypub/create.ts')
| -rw-r--r-- | src/common/remote/activitypub/create.ts | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/src/common/remote/activitypub/create.ts b/src/common/remote/activitypub/create.ts new file mode 100644 index 0000000000..4aaaeb3060 --- /dev/null +++ b/src/common/remote/activitypub/create.ts @@ -0,0 +1,86 @@ +import { JSDOM } from 'jsdom'; +import config from '../../../conf'; +import Post from '../../../models/post'; +import RemoteUserObject, { IRemoteUserObject } from '../../../models/remote-user-object'; +import uploadFromUrl from '../../drive/upload_from_url'; +const createDOMPurify = require('dompurify'); + +function createRemoteUserObject($ref, $id, { id }) { + const object = { $ref, $id }; + + if (!id) { + return { object }; + } + + return RemoteUserObject.insert({ uri: id, object }); +} + +async function createImage(actor, object) { + if ('attributedTo' in object && actor.account.uri !== object.attributedTo) { + throw new Error; + } + + const { _id } = await uploadFromUrl(object.url, actor); + return createRemoteUserObject('driveFiles.files', _id, object); +} + +async function createNote(resolver, actor, object) { + if ('attributedTo' in object && actor.account.uri !== object.attributedTo) { + throw new Error; + } + + const mediaIds = 'attachment' in object && + (await Promise.all(await create(resolver, actor, object.attachment))) + .filter(media => media !== null && media.object.$ref === 'driveFiles.files') + .map(({ object }) => object.$id); + + const { window } = new JSDOM(object.content); + + const { _id } = await Post.insert({ + channelId: undefined, + index: undefined, + createdAt: new Date(object.published), + mediaIds, + replyId: undefined, + repostId: undefined, + poll: undefined, + text: window.document.body.textContent, + textHtml: object.content && createDOMPurify(window).sanitize(object.content), + userId: actor._id, + appId: null, + viaMobile: false, + geo: undefined + }); + + // Register to search database + if (object.content && config.elasticsearch.enable) { + const es = require('../../db/elasticsearch'); + + es.index({ + index: 'misskey', + type: 'post', + id: _id.toString(), + body: { + text: window.document.body.textContent + } + }); + } + + return createRemoteUserObject('posts', _id, object); +} + +export default async function create(parentResolver, actor, value): Promise<Promise<IRemoteUserObject>[]> { + const results = await parentResolver.resolveRemoteUserObjects(value); + + return results.map(asyncResult => asyncResult.then(({ resolver, object }) => { + switch (object.type) { + case 'Image': + return createImage(actor, object); + + case 'Note': + return createNote(resolver, actor, object); + } + + return null; + })); +}; |