This commit is contained in:
syuilo 2018-04-07 16:14:35 +09:00
parent 7dc06b3d43
commit 93f631e358
8 changed files with 58 additions and 43 deletions

View File

@ -1,13 +1,12 @@
import * as debug from 'debug'; import * as debug from 'debug';
import Resolver from '../../resolver';
import uploadFromUrl from '../../../../services/drive/upload-from-url'; import uploadFromUrl from '../../../../services/drive/upload-from-url';
import { IRemoteUser } from '../../../../models/user'; import { IRemoteUser } from '../../../../models/user';
import { IDriveFile } from '../../../../models/drive-file'; import { IDriveFile } from '../../../../models/drive-file';
const log = debug('misskey:activitypub'); const log = debug('misskey:activitypub');
export default async function(resolver: Resolver, actor: IRemoteUser, image): Promise<IDriveFile> { export default async function(actor: IRemoteUser, image): Promise<IDriveFile> {
if ('attributedTo' in image && actor.account.uri !== image.attributedTo) { if ('attributedTo' in image && actor.account.uri !== image.attributedTo) {
log(`invalid image: ${JSON.stringify(image, null, 2)}`); log(`invalid image: ${JSON.stringify(image, null, 2)}`);
throw new Error('invalid image'); throw new Error('invalid image');

View File

@ -4,10 +4,11 @@ import Resolver from '../../resolver';
import { IRemoteUser } from '../../../../models/user'; import { IRemoteUser } from '../../../../models/user';
import createNote from './note'; import createNote from './note';
import createImage from './image'; import createImage from './image';
import { ICreate } from '../../type';
const log = debug('misskey:activitypub'); const log = debug('misskey:activitypub');
export default async (actor: IRemoteUser, activity): Promise<void> => { export default async (actor: IRemoteUser, activity: ICreate): Promise<void> => {
if ('actor' in activity && actor.account.uri !== activity.actor) { if ('actor' in activity && actor.account.uri !== activity.actor) {
throw new Error('invalid actor'); throw new Error('invalid actor');
} }
@ -29,7 +30,7 @@ export default async (actor: IRemoteUser, activity): Promise<void> => {
switch (object.type) { switch (object.type) {
case 'Image': case 'Image':
createImage(resolver, actor, object); createImage(actor, object);
break; break;
case 'Note': case 'Note':

View File

@ -43,7 +43,7 @@ export default async function createNote(resolver: Resolver, actor: IRemoteUser,
// TODO: attachmentは必ずしも配列ではない // TODO: attachmentは必ずしも配列ではない
// TODO: ループの中でawaitはすべきでない // TODO: ループの中でawaitはすべきでない
note.attachment.forEach(async media => { note.attachment.forEach(async media => {
const created = await createImage(resolver, note.actor, media); const created = await createImage(note.actor, media);
media.push(created); media.push(created);
}); });
} }

View File

@ -1,11 +1,12 @@
import parseAcct from '../../../acct/parse'; import parseAcct from '../../../acct/parse';
import User from '../../../models/user'; import User, { IRemoteUser } from '../../../models/user';
import config from '../../../config'; import config from '../../../config';
import follow from '../../../services/following/create'; import follow from '../../../services/following/create';
import { IFollow } from '../type';
export default async (actor, activity): Promise<void> => { export default async (actor: IRemoteUser, activity: IFollow): Promise<void> => {
const prefix = config.url + '/@'; const prefix = config.url + '/@';
const id = activity.object.id || activity.object; const id = typeof activity == 'string' ? activity : activity.id;
if (!id.startsWith(prefix)) { if (!id.startsWith(prefix)) {
return null; return null;

View File

@ -1,11 +1,12 @@
import parseAcct from '../../../../acct/parse'; import parseAcct from '../../../../acct/parse';
import User from '../../../../models/user'; import User, { IRemoteUser } from '../../../../models/user';
import config from '../../../../config'; import config from '../../../../config';
import unfollow from '../../../../services/following/delete'; import unfollow from '../../../../services/following/delete';
import { IFollow } from '../../type';
export default async (actor, activity): Promise<void> => { export default async (actor: IRemoteUser, activity: IFollow): Promise<void> => {
const prefix = config.url + '/@'; const prefix = config.url + '/@';
const id = activity.object.id || activity.object; const id = typeof activity == 'string' ? activity : activity.id;
if (!id.startsWith(prefix)) { if (!id.startsWith(prefix)) {
return null; return null;

View File

@ -1,13 +1,35 @@
import unfollow from './follow'; import * as debug from 'debug';
export default async (actor, activity): Promise<void> => { import { IRemoteUser } from '../../../../models/user';
import { IUndo } from '../../type';
import unfollow from './follow';
import Resolver from '../../resolver';
const log = debug('misskey:activitypub');
export default async (actor: IRemoteUser, activity: IUndo): Promise<void> => {
if ('actor' in activity && actor.account.uri !== activity.actor) { if ('actor' in activity && actor.account.uri !== activity.actor) {
throw new Error('invalid actor'); throw new Error('invalid actor');
} }
switch (activity.object.type) { const uri = activity.id || activity;
log(`Undo: ${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 'Follow': case 'Follow':
unfollow(actor, activity.object); unfollow(actor, object);
break; break;
} }

View File

@ -1,25 +0,0 @@
import parseAcct from '../../../acct/parse';
import User from '../../../models/user';
import config from '../../../config';
import unfollow from '../../../services/following/delete';
export default async (actor, activity): Promise<void> => {
const prefix = config.url + '/@';
const id = activity.object.id || activity.object;
if (!id.startsWith(prefix)) {
return null;
}
const { username, host } = parseAcct(id.slice(prefix.length));
if (host !== null) {
throw new Error();
}
const followee = await User.findOne({ username, host });
if (followee === null) {
throw new Error();
}
await unfollow(actor, followee, activity);
};

View File

@ -1,8 +1,5 @@
export type Object = { [x: string]: any }; export type Object = { [x: string]: any };
export type ActivityType =
'Create';
export interface IObject { export interface IObject {
'@context': string | object | any[]; '@context': string | object | any[];
type: string; type: string;
@ -10,6 +7,13 @@ export interface IObject {
summary?: string; summary?: string;
} }
export interface IActivity extends IObject {
//type: 'Activity';
actor: IObject | string;
object: IObject | string;
target?: IObject | string;
}
export interface ICollection extends IObject { export interface ICollection extends IObject {
type: 'Collection'; type: 'Collection';
totalItems: number; totalItems: number;
@ -30,3 +34,15 @@ export const isOrderedCollection = (object: IObject): object is IOrderedCollecti
export const isCollectionOrOrderedCollection = (object: IObject): object is ICollection | IOrderedCollection => export const isCollectionOrOrderedCollection = (object: IObject): object is ICollection | IOrderedCollection =>
isCollection(object) || isOrderedCollection(object); isCollection(object) || isOrderedCollection(object);
export interface ICreate extends IActivity {
type: 'Create';
}
export interface IUndo extends IActivity {
type: 'Undo';
}
export interface IFollow extends IActivity {
type: 'Follow';
}