diff options
| author | syuilo <syuilotan@yahoo.co.jp> | 2018-04-04 23:12:35 +0900 |
|---|---|---|
| committer | syuilo <syuilotan@yahoo.co.jp> | 2018-04-04 23:12:35 +0900 |
| commit | e8b42d7e1668679e6a6ee0a7aea1e2ff7f37005b (patch) | |
| tree | 6973284192eb419bd7bfed2361a594e668b81f9a /src/remote/activitypub/act | |
| parent | Merge pull request #1393 from akihikodaki/duplicate (diff) | |
| download | sharkey-e8b42d7e1668679e6a6ee0a7aea1e2ff7f37005b.tar.gz sharkey-e8b42d7e1668679e6a6ee0a7aea1e2ff7f37005b.tar.bz2 sharkey-e8b42d7e1668679e6a6ee0a7aea1e2ff7f37005b.zip | |
wip
Diffstat (limited to 'src/remote/activitypub/act')
| -rw-r--r-- | src/remote/activitypub/act/create.ts | 90 | ||||
| -rw-r--r-- | src/remote/activitypub/act/index.ts | 44 |
2 files changed, 105 insertions, 29 deletions
diff --git a/src/remote/activitypub/act/create.ts b/src/remote/activitypub/act/create.ts index fa681982cf..c1a30ce7d0 100644 --- a/src/remote/activitypub/act/create.ts +++ b/src/remote/activitypub/act/create.ts @@ -1,10 +1,92 @@ -import create from '../create'; +import { JSDOM } from 'jsdom'; +const createDOMPurify = require('dompurify'); + import Resolver from '../resolver'; +import DriveFile from '../../../models/drive-file'; +import Post from '../../../models/post'; +import uploadFromUrl from '../../../drive/upload-from-url'; +import createPost from '../../../post/create'; -export default (resolver: Resolver, actor, activity, distribute) => { +export default async (resolver: Resolver, actor, activity): Promise<void> => { if ('actor' in activity && actor.account.uri !== activity.actor) { - throw new Error(); + throw new Error('invalid actor'); } - return create(resolver, actor, activity.object, distribute); + 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}`); + } + + const object = await resolver.resolve(activity); + + switch (object.type) { + case 'Image': + createImage(resolver, object); + break; + + case 'Note': + createNote(resolver, object); + break; + } + + /// + + async function createImage(resolver: Resolver, image) { + if ('attributedTo' in image && actor.account.uri !== image.attributedTo) { + throw new Error('invalid image'); + } + + return await uploadFromUrl(image.url, actor); + } + + async function createNote(resolver: Resolver, note) { + if ( + ('attributedTo' in note && actor.account.uri !== note.attributedTo) || + typeof note.id !== 'string' + ) { + throw new Error('invalid note'); + } + + const mediaIds = []; + + if ('attachment' in note) { + note.attachment.forEach(async media => { + const created = await createImage(resolver, media); + mediaIds.push(created._id); + }); + } + + const { window } = new JSDOM(note.content); + + await createPost(actor, { + channelId: undefined, + index: undefined, + createdAt: new Date(note.published), + mediaIds, + replyId: undefined, + repostId: undefined, + poll: undefined, + text: window.document.body.textContent, + textHtml: note.content && createDOMPurify(window).sanitize(note.content), + userId: actor._id, + appId: null, + viaMobile: false, + geo: undefined, + uri: note.id + }, null, null, []); + } }; diff --git a/src/remote/activitypub/act/index.ts b/src/remote/activitypub/act/index.ts index d282e12885..d78335f16e 100644 --- a/src/remote/activitypub/act/index.ts +++ b/src/remote/activitypub/act/index.ts @@ -2,35 +2,29 @@ import create from './create'; import performDeleteActivity from './delete'; import follow from './follow'; import undo from './undo'; -import createObject from '../create'; import Resolver from '../resolver'; +import { IObject } from '../type'; -export default async (parentResolver: Resolver, actor, value, distribute?: boolean) => { - const collection = await parentResolver.resolveCollection(value); +export default async (parentResolver: Resolver, actor, activity: IObject): Promise<void> => { + switch (activity.type) { + case 'Create': + await create(parentResolver, actor, activity); + break; - return collection.object.map(async element => { - const { resolver, object } = await collection.resolver.resolveOne(element); - const created = await (await createObject(resolver, actor, [object], distribute))[0]; + case 'Delete': + await performDeleteActivity(parentResolver, actor, activity); + break; - if (created !== null) { - return created; - } + case 'Follow': + await follow(parentResolver, actor, activity); + break; - switch (object.type) { - case 'Create': - return create(resolver, actor, object, distribute); + case 'Undo': + await undo(parentResolver, actor, activity); + break; - case 'Delete': - return performDeleteActivity(resolver, actor, object); - - case 'Follow': - return follow(resolver, actor, object, distribute); - - case 'Undo': - return undo(resolver, actor, object); - - default: - return null; - } - }); + default: + console.warn(`unknown activity type: ${activity.type}`); + return null; + } }; |