From f079041827b97849b3b5907980672686091277b4 Mon Sep 17 00:00:00 2001
From: mei23 <m@m544.net>
Date: Mon, 13 Aug 2018 03:49:17 +0900
Subject: [PATCH] ActivityPub visibility on send

---
 src/remote/activitypub/renderer/note.ts   | 20 ++++++++---
 src/remote/activitypub/renderer/person.ts |  2 ++
 src/server/activitypub.ts                 | 42 +++++++++++++++++++++++
 3 files changed, 60 insertions(+), 4 deletions(-)

diff --git a/src/remote/activitypub/renderer/note.ts b/src/remote/activitypub/renderer/note.ts
index 7cee2be22c..209e743927 100644
--- a/src/remote/activitypub/renderer/note.ts
+++ b/src/remote/activitypub/renderer/note.ts
@@ -50,9 +50,21 @@ export default async function renderNote(note: INote, dive = true): Promise<any>
 		? note.mentionedRemoteUsers.map(x => x.uri)
 		: [];
 
-	const cc = ['public', 'home', 'followers'].includes(note.visibility)
-		? [`${attributedTo}/followers`].concat(mentions)
-		: [];
+	let to: string[] = [];
+	let cc: string[] = [];
+
+	if (note.visibility == 'public') {
+		to = ['https://www.w3.org/ns/activitystreams#Public'];
+		cc = [`${attributedTo}/followers`].concat(mentions);
+	} else if (note.visibility == 'home') {
+		to = [`${attributedTo}/followers`];
+		cc = ['https://www.w3.org/ns/activitystreams#Public'].concat(mentions);
+	} else if (note.visibility == 'followers') {
+		to = [`${attributedTo}/followers`];
+		cc = mentions;
+	} else {
+		to = mentions;
+	}
 
 	const mentionedUsers = note.mentions ? await User.find({
 		_id: {
@@ -74,7 +86,7 @@ export default async function renderNote(note: INote, dive = true): Promise<any>
 		summary: note.cw,
 		content: toHtml(note),
 		published: note.createdAt.toISOString(),
-		to: 'https://www.w3.org/ns/activitystreams#Public',
+		to,
 		cc,
 		inReplyTo,
 		attachment: (await promisedFiles).map(renderDocument),
diff --git a/src/remote/activitypub/renderer/person.ts b/src/remote/activitypub/renderer/person.ts
index 7d828f97ae..0d227303c0 100644
--- a/src/remote/activitypub/renderer/person.ts
+++ b/src/remote/activitypub/renderer/person.ts
@@ -19,6 +19,8 @@ export default async (user: ILocalUser) => {
 		id,
 		inbox: `${id}/inbox`,
 		outbox: `${id}/outbox`,
+		followers: `${id}/followers`,
+		following: `${id}/following`,
 		sharedInbox: `${config.url}/inbox`,
 		url: `${config.url}/@${user.username}`,
 		preferredUsername: user.username,
diff --git a/src/server/activitypub.ts b/src/server/activitypub.ts
index 2d9a4746c6..7d6fe09269 100644
--- a/src/server/activitypub.ts
+++ b/src/server/activitypub.ts
@@ -89,6 +89,48 @@ router.get('/users/:user/outbox', async ctx => {
 	ctx.body = pack(rendered);
 });
 
+// followers
+router.get('/users/:user/followers', async ctx => {
+	const userId = new mongo.ObjectID(ctx.params.user);
+
+	const user = await User.findOne({
+		_id: userId,
+		host: null
+	});
+
+	if (user === null) {
+		ctx.status = 404;
+		return;
+	}
+
+	// TODO: Implement fetch and render
+
+	const rendered = renderOrderedCollection(`${config.url}/users/${userId}/followers`, 0, []);
+
+	ctx.body = pack(rendered);
+});
+
+// following
+router.get('/users/:user/following', async ctx => {
+	const userId = new mongo.ObjectID(ctx.params.user);
+
+	const user = await User.findOne({
+		_id: userId,
+		host: null
+	});
+
+	if (user === null) {
+		ctx.status = 404;
+		return;
+	}
+
+	// TODO: Implement fetch and render
+
+	const rendered = renderOrderedCollection(`${config.url}/users/${userId}/following`, 0, []);
+
+	ctx.body = pack(rendered);
+});
+
 // publickey
 router.get('/users/:user/publickey', async ctx => {
 	const userId = new mongo.ObjectID(ctx.params.user);