From 02bb99ac029e8fc12aec384717341f603052d7c0 Mon Sep 17 00:00:00 2001
From: syuilo <syuilotan@yahoo.co.jp>
Date: Mon, 23 Apr 2018 15:27:01 +0900
Subject: [PATCH] =?UTF-8?q?=E4=BB=96=E3=81=AEMisskey=E3=82=A4=E3=83=B3?=
 =?UTF-8?q?=E3=82=B9=E3=82=BF=E3=83=B3=E3=82=B9=E3=81=AB=E3=83=AA=E3=82=A2?=
 =?UTF-8?q?=E3=82=AF=E3=82=B7=E3=83=A7=E3=83=B3=E6=83=85=E5=A0=B1=E3=82=92?=
 =?UTF-8?q?=E4=BC=9D=E3=81=88=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/models/note-reaction.ts                        | 13 +++++++++++++
 src/remote/activitypub/kernel/like.ts              | 12 +++++++++++-
 src/remote/activitypub/renderer/like.ts            |  5 +++--
 src/remote/activitypub/type.ts                     |  1 +
 src/server/api/endpoints/notes/reactions/create.ts | 13 ++-----------
 src/services/note/reaction/create.ts               |  2 +-
 6 files changed, 31 insertions(+), 15 deletions(-)

diff --git a/src/models/note-reaction.ts b/src/models/note-reaction.ts
index 9bf467f222..7891ebdf17 100644
--- a/src/models/note-reaction.ts
+++ b/src/models/note-reaction.ts
@@ -1,4 +1,5 @@
 import * as mongo from 'mongodb';
+import $ from 'cafy';
 import deepcopy = require('deepcopy');
 import db from '../db/mongodb';
 import Reaction from './note-reaction';
@@ -16,6 +17,18 @@ export interface INoteReaction {
 	reaction: string;
 }
 
+export const validateReaction = $().string().or([
+	'like',
+	'love',
+	'laugh',
+	'hmm',
+	'surprise',
+	'congrats',
+	'angry',
+	'confused',
+	'pudding'
+]);
+
 /**
  * NoteReactionを物理削除します
  */
diff --git a/src/remote/activitypub/kernel/like.ts b/src/remote/activitypub/kernel/like.ts
index fc5d0a2f61..17ec73f12b 100644
--- a/src/remote/activitypub/kernel/like.ts
+++ b/src/remote/activitypub/kernel/like.ts
@@ -3,6 +3,7 @@ import Note from '../../../models/note';
 import { IRemoteUser } from '../../../models/user';
 import { ILike } from '../type';
 import create from '../../../services/note/reaction/create';
+import { validateReaction } from '../../../models/note-reaction';
 
 export default async (actor: IRemoteUser, activity: ILike) => {
 	const id = typeof activity.object == 'string' ? activity.object : activity.object.id;
@@ -17,5 +18,14 @@ export default async (actor: IRemoteUser, activity: ILike) => {
 		throw new Error();
 	}
 
-	await create(actor, note, 'pudding');
+	let reaction = 'pudding';
+
+	// 他のMisskeyインスタンスからのリアクション
+	if (activity._misskey_reaction) {
+		if (validateReaction.ok(activity._misskey_reaction)) {
+			reaction = activity._misskey_reaction;
+		}
+	}
+
+	await create(actor, note, reaction);
 };
diff --git a/src/remote/activitypub/renderer/like.ts b/src/remote/activitypub/renderer/like.ts
index 061a10ba84..33e1341a20 100644
--- a/src/remote/activitypub/renderer/like.ts
+++ b/src/remote/activitypub/renderer/like.ts
@@ -1,8 +1,9 @@
 import config from '../../../config';
 import { ILocalUser } from '../../../models/user';
 
-export default (user: ILocalUser, note) => ({
+export default (user: ILocalUser, note, reaction: string) => ({
 	type: 'Like',
 	actor: `${config.url}/users/${user._id}`,
-	object: note.uri ? note.uri : `${config.url}/notes/${note._id}`
+	object: note.uri ? note.uri : `${config.url}/notes/${note._id}`,
+	_misskey_reaction: reaction
 });
diff --git a/src/remote/activitypub/type.ts b/src/remote/activitypub/type.ts
index 08e5493dd4..6018ac29c4 100644
--- a/src/remote/activitypub/type.ts
+++ b/src/remote/activitypub/type.ts
@@ -82,6 +82,7 @@ export interface IAccept extends IActivity {
 
 export interface ILike extends IActivity {
 	type: 'Like';
+	_misskey_reaction: string;
 }
 
 export interface IAnnounce extends IActivity {
diff --git a/src/server/api/endpoints/notes/reactions/create.ts b/src/server/api/endpoints/notes/reactions/create.ts
index c80c5416b1..9e217cc3e0 100644
--- a/src/server/api/endpoints/notes/reactions/create.ts
+++ b/src/server/api/endpoints/notes/reactions/create.ts
@@ -4,6 +4,7 @@
 import $ from 'cafy';
 import Note from '../../../../../models/note';
 import create from '../../../../../services/note/reaction/create';
+import { validateReaction } from '../../../../../models/note-reaction';
 
 /**
  * React to a note
@@ -14,17 +15,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	if (noteIdErr) return rej('invalid noteId param');
 
 	// Get 'reaction' parameter
-	const [reaction, reactionErr] = $(params.reaction).string().or([
-		'like',
-		'love',
-		'laugh',
-		'hmm',
-		'surprise',
-		'congrats',
-		'angry',
-		'confused',
-		'pudding'
-	]).$;
+	const [reaction, reactionErr] = $(params.reaction).string().pipe(validateReaction.ok).$;
 	if (reactionErr) return rej('invalid reaction param');
 
 	// Fetch reactee
diff --git a/src/services/note/reaction/create.ts b/src/services/note/reaction/create.ts
index 06fd6c0576..123c091c85 100644
--- a/src/services/note/reaction/create.ts
+++ b/src/services/note/reaction/create.ts
@@ -87,7 +87,7 @@ export default async (user: IUser, note: INote, reaction: string) => new Promise
 	//#region 配信
 	// リアクターがローカルユーザーかつリアクション対象がリモートユーザーの投稿なら配送
 	if (isLocalUser(user) && isRemoteUser(note._user)) {
-		const content = pack(renderLike(user, note));
+		const content = pack(renderLike(user, note, reaction));
 		deliver(user, content, note._user.inbox);
 	}
 	//#endregion