summaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
authorsyuilo <Syuilotan@yahoo.co.jp>2021-11-07 18:04:32 +0900
committerGitHub <noreply@github.com>2021-11-07 18:04:32 +0900
commita28c515ef63a6f9c188cf0a7f544db1afa8e1331 (patch)
tree4b207f6998e0697ab5c732c04769b069dfd054c7 /src/server
parentperf: delete-account処理を軽くする (#7958) (diff)
downloadmisskey-a28c515ef63a6f9c188cf0a7f544db1afa8e1331.tar.gz
misskey-a28c515ef63a6f9c188cf0a7f544db1afa8e1331.tar.bz2
misskey-a28c515ef63a6f9c188cf0a7f544db1afa8e1331.zip
feat: make possible to configure following/followers visibility (#7959)
* feat: make possible to configure following/followers visibility * add test * ap * add ap test * set Cache-Control * hide following/followers count
Diffstat (limited to 'src/server')
-rw-r--r--src/server/activitypub/followers.ts16
-rw-r--r--src/server/activitypub/following.ts16
-rw-r--r--src/server/api/endpoints/i/update.ts5
-rw-r--r--src/server/api/endpoints/users/followers.ts30
-rw-r--r--src/server/api/endpoints/users/following.ts30
-rw-r--r--src/server/web/feed.ts2
6 files changed, 92 insertions, 7 deletions
diff --git a/src/server/activitypub/followers.ts b/src/server/activitypub/followers.ts
index 8b6a066bf0..baf2d23460 100644
--- a/src/server/activitypub/followers.ts
+++ b/src/server/activitypub/followers.ts
@@ -8,7 +8,7 @@ import renderOrderedCollection from '@/remote/activitypub/renderer/ordered-colle
import renderOrderedCollectionPage from '@/remote/activitypub/renderer/ordered-collection-page';
import renderFollowUser from '@/remote/activitypub/renderer/follow-user';
import { setResponseType } from '../activitypub';
-import { Users, Followings } from '@/models/index';
+import { Users, Followings, UserProfiles } from '@/models/index';
import { LessThan } from 'typeorm';
export default async (ctx: Router.RouterContext) => {
@@ -38,6 +38,20 @@ export default async (ctx: Router.RouterContext) => {
return;
}
+ //#region Check ff visibility
+ const profile = await UserProfiles.findOneOrFail(user.id);
+
+ if (profile.ffVisibility === 'private') {
+ ctx.status = 403;
+ ctx.set('Cache-Control', 'public, max-age=30');
+ return;
+ } else if (profile.ffVisibility === 'followers') {
+ ctx.status = 403;
+ ctx.set('Cache-Control', 'public, max-age=30');
+ return;
+ }
+ //#endregion
+
const limit = 10;
const partOf = `${config.url}/users/${userId}/followers`;
diff --git a/src/server/activitypub/following.ts b/src/server/activitypub/following.ts
index 5fc5d68a9c..b9eb806c3c 100644
--- a/src/server/activitypub/following.ts
+++ b/src/server/activitypub/following.ts
@@ -8,7 +8,7 @@ import renderOrderedCollection from '@/remote/activitypub/renderer/ordered-colle
import renderOrderedCollectionPage from '@/remote/activitypub/renderer/ordered-collection-page';
import renderFollowUser from '@/remote/activitypub/renderer/follow-user';
import { setResponseType } from '../activitypub';
-import { Users, Followings } from '@/models/index';
+import { Users, Followings, UserProfiles } from '@/models/index';
import { LessThan, FindConditions } from 'typeorm';
import { Following } from '@/models/entities/following';
@@ -39,6 +39,20 @@ export default async (ctx: Router.RouterContext) => {
return;
}
+ //#region Check ff visibility
+ const profile = await UserProfiles.findOneOrFail(user.id);
+
+ if (profile.ffVisibility === 'private') {
+ ctx.status = 403;
+ ctx.set('Cache-Control', 'public, max-age=30');
+ return;
+ } else if (profile.ffVisibility === 'followers') {
+ ctx.status = 403;
+ ctx.set('Cache-Control', 'public, max-age=30');
+ return;
+ }
+ //#endregion
+
const limit = 10;
const partOf = `${config.url}/users/${userId}/following`;
diff --git a/src/server/api/endpoints/i/update.ts b/src/server/api/endpoints/i/update.ts
index 3b8b1579ea..d0f201ab60 100644
--- a/src/server/api/endpoints/i/update.ts
+++ b/src/server/api/endpoints/i/update.ts
@@ -72,6 +72,10 @@ export const meta = {
validator: $.optional.bool,
},
+ ffVisibility: {
+ validator: $.optional.str,
+ },
+
carefulBot: {
validator: $.optional.bool,
},
@@ -174,6 +178,7 @@ export default define(meta, async (ps, _user, token) => {
if (ps.lang !== undefined) profileUpdates.lang = ps.lang;
if (ps.location !== undefined) profileUpdates.location = ps.location;
if (ps.birthday !== undefined) profileUpdates.birthday = ps.birthday;
+ if (ps.ffVisibility !== undefined) profileUpdates.ffVisibility = ps.ffVisibility;
if (ps.avatarId !== undefined) updates.avatarId = ps.avatarId;
if (ps.bannerId !== undefined) updates.bannerId = ps.bannerId;
if (ps.mutedWords !== undefined) {
diff --git a/src/server/api/endpoints/users/followers.ts b/src/server/api/endpoints/users/followers.ts
index e54b6078ee..6d042a2861 100644
--- a/src/server/api/endpoints/users/followers.ts
+++ b/src/server/api/endpoints/users/followers.ts
@@ -2,7 +2,7 @@ import $ from 'cafy';
import { ID } from '@/misc/cafy-id';
import define from '../../define';
import { ApiError } from '../../error';
-import { Users, Followings } from '@/models/index';
+import { Users, Followings, UserProfiles } from '@/models/index';
import { makePaginationQuery } from '../../common/make-pagination-query';
import { toPunyNullable } from '@/misc/convert-host';
@@ -53,7 +53,13 @@ export const meta = {
message: 'No such user.',
code: 'NO_SUCH_USER',
id: '27fa5435-88ab-43de-9360-387de88727cd'
- }
+ },
+
+ forbidden: {
+ message: 'Forbidden.',
+ code: 'FORBIDDEN',
+ id: '3c6a84db-d619-26af-ca14-06232a21df8a'
+ },
}
};
@@ -66,6 +72,26 @@ export default define(meta, async (ps, me) => {
throw new ApiError(meta.errors.noSuchUser);
}
+ const profile = await UserProfiles.findOneOrFail(user.id);
+
+ if (profile.ffVisibility === 'private') {
+ if (me == null || (me.id !== user.id)) {
+ throw new ApiError(meta.errors.forbidden);
+ }
+ } else if (profile.ffVisibility === 'followers') {
+ if (me == null) {
+ throw new ApiError(meta.errors.forbidden);
+ } else if (me.id !== user.id) {
+ const following = await Followings.findOne({
+ followeeId: user.id,
+ followerId: me.id,
+ });
+ if (following == null) {
+ throw new ApiError(meta.errors.forbidden);
+ }
+ }
+ }
+
const query = makePaginationQuery(Followings.createQueryBuilder('following'), ps.sinceId, ps.untilId)
.andWhere(`following.followeeId = :userId`, { userId: user.id })
.innerJoinAndSelect('following.follower', 'follower');
diff --git a/src/server/api/endpoints/users/following.ts b/src/server/api/endpoints/users/following.ts
index f2ef7f47e1..1033117ef8 100644
--- a/src/server/api/endpoints/users/following.ts
+++ b/src/server/api/endpoints/users/following.ts
@@ -2,7 +2,7 @@ import $ from 'cafy';
import { ID } from '@/misc/cafy-id';
import define from '../../define';
import { ApiError } from '../../error';
-import { Users, Followings } from '@/models/index';
+import { Users, Followings, UserProfiles } from '@/models/index';
import { makePaginationQuery } from '../../common/make-pagination-query';
import { toPunyNullable } from '@/misc/convert-host';
@@ -53,7 +53,13 @@ export const meta = {
message: 'No such user.',
code: 'NO_SUCH_USER',
id: '63e4aba4-4156-4e53-be25-c9559e42d71b'
- }
+ },
+
+ forbidden: {
+ message: 'Forbidden.',
+ code: 'FORBIDDEN',
+ id: 'f6cdb0df-c19f-ec5c-7dbb-0ba84a1f92ba'
+ },
}
};
@@ -66,6 +72,26 @@ export default define(meta, async (ps, me) => {
throw new ApiError(meta.errors.noSuchUser);
}
+ const profile = await UserProfiles.findOneOrFail(user.id);
+
+ if (profile.ffVisibility === 'private') {
+ if (me == null || (me.id !== user.id)) {
+ throw new ApiError(meta.errors.forbidden);
+ }
+ } else if (profile.ffVisibility === 'followers') {
+ if (me == null) {
+ throw new ApiError(meta.errors.forbidden);
+ } else if (me.id !== user.id) {
+ const following = await Followings.findOne({
+ followeeId: user.id,
+ followerId: me.id,
+ });
+ if (following == null) {
+ throw new ApiError(meta.errors.forbidden);
+ }
+ }
+ }
+
const query = makePaginationQuery(Followings.createQueryBuilder('following'), ps.sinceId, ps.untilId)
.andWhere(`following.followerId = :userId`, { userId: user.id })
.innerJoinAndSelect('following.followee', 'followee');
diff --git a/src/server/web/feed.ts b/src/server/web/feed.ts
index 4b6de517b7..1d4c47dafb 100644
--- a/src/server/web/feed.ts
+++ b/src/server/web/feed.ts
@@ -27,7 +27,7 @@ export default async function(user: User) {
title: `${author.name} (@${user.username}@${config.host})`,
updated: notes[0].createdAt,
generator: 'Misskey',
- description: `${user.notesCount} Notes, ${user.followingCount} Following, ${user.followersCount} Followers${profile.description ? ` · ${profile.description}` : ''}`,
+ description: `${user.notesCount} Notes, ${profile.ffVisibility === 'public' ? user.followingCount : '?'} Following, ${profile.ffVisibility === 'public' ? user.followersCount : '?'} Followers${profile.description ? ` · ${profile.description}` : ''}`,
link: author.link,
image: user.avatarUrl ? user.avatarUrl : undefined,
feedLinks: {