From 1472f0b141cdcb4f21c4db0d5ff3d84a5f8ccb93 Mon Sep 17 00:00:00 2001
From: syuilo <syuilotan@yahoo.co.jp>
Date: Wed, 13 Jun 2018 05:11:55 +0900
Subject: [PATCH] Fix #1712

---
 src/models/note.ts                         |  5 +++++
 src/remote/activitypub/renderer/hashtag.ts |  2 +-
 src/remote/activitypub/renderer/mention.ts |  9 +++++++++
 src/remote/activitypub/renderer/note.ts    | 17 +++++++++++++++--
 src/services/note/create.ts                |  7 ++++++-
 5 files changed, 36 insertions(+), 4 deletions(-)
 create mode 100644 src/remote/activitypub/renderer/mention.ts

diff --git a/src/models/note.ts b/src/models/note.ts
index 3bbfec0103..461bb405a0 100644
--- a/src/models/note.ts
+++ b/src/models/note.ts
@@ -48,6 +48,11 @@ export type INote = {
 	repliesCount: number;
 	reactionCounts: any;
 	mentions: mongo.ObjectID[];
+	mentionedRemoteUsers: Array<{
+		uri: string;
+		username: string;
+		host: string;
+	}>;
 
 	/**
 	 * public ... 公開
diff --git a/src/remote/activitypub/renderer/hashtag.ts b/src/remote/activitypub/renderer/hashtag.ts
index 50761c8684..a37ba63532 100644
--- a/src/remote/activitypub/renderer/hashtag.ts
+++ b/src/remote/activitypub/renderer/hashtag.ts
@@ -1,6 +1,6 @@
 import config from '../../../config';
 
-export default tag => ({
+export default (tag: string) => ({
 	type: 'Hashtag',
 	href: `${config.url}/tags/${encodeURIComponent(tag)}`,
 	name: '#' + tag
diff --git a/src/remote/activitypub/renderer/mention.ts b/src/remote/activitypub/renderer/mention.ts
new file mode 100644
index 0000000000..4cba7d6a94
--- /dev/null
+++ b/src/remote/activitypub/renderer/mention.ts
@@ -0,0 +1,9 @@
+export default (mention: {
+	uri: string;
+	username: string;
+	host: string;
+}) => ({
+	type: 'Mention',
+	href: mention.uri,
+	name: `@${mention.username}@${mention.host}`
+});
diff --git a/src/remote/activitypub/renderer/note.ts b/src/remote/activitypub/renderer/note.ts
index a05c12b388..39335a7cca 100644
--- a/src/remote/activitypub/renderer/note.ts
+++ b/src/remote/activitypub/renderer/note.ts
@@ -1,5 +1,6 @@
 import renderDocument from './document';
 import renderHashtag from './hashtag';
+import renderMention from './mention';
 import config from '../../../config';
 import DriveFile from '../../../models/drive-file';
 import Note, { INote } from '../../../models/note';
@@ -45,6 +46,18 @@ export default async function renderNote(note: INote, dive = true) {
 
 	const attributedTo = `${config.url}/users/${user._id}`;
 
+	const mentions = note.mentionedRemoteUsers && note.mentionedRemoteUsers.length > 0
+		? note.mentionedRemoteUsers.map(x => x.uri)
+		: [];
+
+	const cc = ['public', 'home', 'followers'].includes(note.visibility)
+		? [`${attributedTo}/followers`].concat(mentions)
+		: [];
+
+	const hashtagTags = (note.tags || []).map(renderHashtag);
+	const mentionTags = (note.mentionedRemoteUsers || []).map(renderMention);
+	const tag = hashtagTags.concat(mentionTags)
+
 	return {
 		id: `${config.url}/notes/${note._id}`,
 		type: 'Note',
@@ -52,9 +65,9 @@ export default async function renderNote(note: INote, dive = true) {
 		content: toHtml(note),
 		published: note.createdAt.toISOString(),
 		to: 'https://www.w3.org/ns/activitystreams#Public',
-		cc: `${attributedTo}/followers`,
+		cc,
 		inReplyTo,
 		attachment: (await promisedFiles).map(renderDocument),
-		tag: (note.tags || []).map(renderHashtag)
+		tag
 	};
 }
diff --git a/src/services/note/create.ts b/src/services/note/create.ts
index ddf07716e4..7eec7485be 100644
--- a/src/services/note/create.ts
+++ b/src/services/note/create.ts
@@ -329,7 +329,12 @@ export default async (user: IUser, data: {
 		if (mentionedUsers.length > 0) {
 			Note.update({ _id: note._id }, {
 				$set: {
-					mentions: mentionedUsers.map(u => u._id)
+					mentions: mentionedUsers.map(u => u._id),
+					mentionedRemoteUsers: mentionedUsers.filter(u => isRemoteUser(u)).map(u => ({
+						uri: (u as IRemoteUser).uri,
+						username: u.username,
+						host: u.host
+					}))
 				}
 			});
 		}