This commit is contained in:
syuilo 2018-04-09 05:02:52 +09:00
parent 08beb45935
commit 536277122d
13 changed files with 7 additions and 0 deletions

View file

@ -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<void> => {
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;
}
};

View file

@ -0,0 +1,45 @@
import * as debug from 'debug';
import Resolver from '../../resolver';
import post from '../../../../services/note/create';
import { IRemoteUser } from '../../../../models/user';
import { IAnnounce, INote } from '../../type';
import { fetchNote, resolveNote } from '../../objects/note';
const log = debug('misskey:activitypub');
/**
*
*/
export default async function(resolver: Resolver, actor: IRemoteUser, activity: IAnnounce, note: INote): Promise<void> {
const uri = activity.id || activity;
if (typeof uri !== 'string') {
throw new Error('invalid announce');
}
// 既に同じURIを持つものが登録されていないかチェック
const exist = await fetchNote(uri);
if (exist) {
return;
}
const renote = await resolveNote(note);
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
});
}

View file

@ -0,0 +1,6 @@
import { IRemoteUser } from '../../../../models/user';
import { createImage } from '../../objects/image';
export default async function(actor: IRemoteUser, image): Promise<void> {
await createImage(image.url, actor);
}

View file

@ -0,0 +1,44 @@
import * as debug from 'debug';
import Resolver from '../../resolver';
import { IRemoteUser } from '../../../../models/user';
import createNote from './note';
import createImage from './image';
import { ICreate } from '../../type';
const log = debug('misskey:activitypub');
export default async (actor: IRemoteUser, activity: ICreate): Promise<void> => {
if ('actor' in activity && actor.uri !== activity.actor) {
throw new Error('invalid actor');
}
const uri = activity.id || activity;
log(`Create: ${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 'Image':
createImage(actor, object);
break;
case 'Note':
createNote(resolver, actor, object);
break;
default:
console.warn(`Unknown type: ${object.type}`);
break;
}
};

View file

@ -0,0 +1,13 @@
import Resolver from '../../resolver';
import { IRemoteUser } from '../../../../models/user';
import { createNote, fetchNote } from '../../objects/note';
/**
* 稿
*/
export default async function(resolver: Resolver, actor: IRemoteUser, note, silent = false): Promise<void> {
const exist = await fetchNote(note);
if (exist == null) {
await createNote(note);
}
}

View file

@ -0,0 +1,36 @@
import Resolver from '../../resolver';
import deleteNote from './note';
import Note from '../../../../models/note';
import { IRemoteUser } from '../../../../models/user';
/**
*
*/
export default async (actor: IRemoteUser, activity): Promise<void> => {
if ('actor' in activity && actor.uri !== activity.actor) {
throw new Error('invalid actor');
}
const resolver = new Resolver();
const object = await resolver.resolve(activity.object);
const uri = (object as any).id;
switch (object.type) {
case 'Note':
deleteNote(actor, uri);
break;
case 'Tombstone':
const note = await Note.findOne({ uri });
if (note != null) {
deleteNote(actor, uri);
}
break;
default:
console.warn(`Unknown type: ${object.type}`);
break;
}
};

View file

@ -0,0 +1,30 @@
import * as debug from 'debug';
import Note from '../../../../models/note';
import { IRemoteUser } from '../../../../models/user';
const log = debug('misskey:activitypub');
export default async function(actor: IRemoteUser, uri: string): Promise<void> {
log(`Deleting the Note: ${uri}`);
const note = await Note.findOne({ uri });
if (note == null) {
throw new Error('note not found');
}
if (!note.userId.equals(actor._id)) {
throw new Error('投稿を削除しようとしているユーザーは投稿の作成者ではありません');
}
Note.update({ _id: note._id }, {
$set: {
deletedAt: new Date(),
text: null,
textHtml: null,
mediaIds: [],
poll: null
}
});
}

View file

@ -0,0 +1,24 @@
import User, { IRemoteUser } from '../../../models/user';
import config from '../../../config';
import follow from '../../../services/following/create';
import { IFollow } from '../type';
export default async (actor: IRemoteUser, activity: IFollow): Promise<void> => {
const id = typeof activity.object == 'string' ? activity.object : activity.object.id;
if (!id.startsWith(config.url + '/')) {
return null;
}
const followee = await User.findOne({ _id: id.split('/').pop() });
if (followee === null) {
throw new Error('followee not found');
}
if (followee.host != null) {
throw new Error('フォローしようとしているユーザーはローカルユーザーではありません');
}
await follow(actor, followee, activity);
};

View file

@ -0,0 +1,51 @@
import { Object } from '../type';
import { IRemoteUser } from '../../../models/user';
import create from './create';
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<void> => {
switch (activity.type) {
case 'Create':
await create(actor, activity);
break;
case 'Delete':
await performDeleteActivity(actor, activity);
break;
case 'Follow':
await follow(actor, activity);
break;
case 'Accept':
// noop
break;
case 'Announce':
await announce(actor, activity);
break;
case 'Like':
await like(actor, activity);
break;
case 'Undo':
await undo(actor, activity);
break;
case 'Collection':
case 'OrderedCollection':
// TODO
break;
default:
console.warn(`unknown activity type: ${(activity as any).type}`);
return null;
}
};
export default self;

View file

@ -0,0 +1,20 @@
import Note from '../../../models/note';
import { IRemoteUser } from '../../../models/user';
import { ILike } from '../type';
import create from '../../../services/note/reaction/create';
export default async (actor: IRemoteUser, activity: ILike) => {
const id = typeof activity.object == 'string' ? activity.object : activity.object.id;
// Transform:
// https://misskey.ex/notes/xxxx to
// xxxx
const noteId = id.split('/').pop();
const note = await Note.findOne({ _id: noteId });
if (note === null) {
throw new Error();
}
await create(actor, note, 'pudding');
};

View file

@ -0,0 +1,24 @@
import User, { IRemoteUser } from '../../../../models/user';
import config from '../../../../config';
import unfollow from '../../../../services/following/delete';
import { IFollow } from '../../type';
export default async (actor: IRemoteUser, activity: IFollow): Promise<void> => {
const id = typeof activity.object == 'string' ? activity.object : activity.object.id;
if (!id.startsWith(config.url + '/')) {
return null;
}
const followee = await User.findOne({ _id: id.split('/').pop() });
if (followee === null) {
throw new Error('followee not found');
}
if (followee.host != null) {
throw new Error('フォロー解除しようとしているユーザーはローカルユーザーではありません');
}
await unfollow(actor, followee, activity);
};

View file

@ -0,0 +1,37 @@
import * as debug from 'debug';
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.uri !== activity.actor) {
throw new Error('invalid actor');
}
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':
unfollow(actor, object);
break;
}
return null;
};