diff --git a/packages/backend/src/server/api/endpoints/charts/user/following.ts b/packages/backend/src/server/api/endpoints/charts/user/following.ts index 20d0ecb25d..1d333f9a9b 100644 --- a/packages/backend/src/server/api/endpoints/charts/user/following.ts +++ b/packages/backend/src/server/api/endpoints/charts/user/following.ts @@ -8,6 +8,8 @@ import { Endpoint } from '@/server/api/endpoint-base.js'; import { getJsonSchema } from '@/core/chart/core.js'; import PerUserFollowingChart from '@/core/chart/charts/per-user-following.js'; import { schema } from '@/core/chart/charts/entities/per-user-following.js'; +import { CacheService } from '@/core/CacheService.js'; +import { RoleService } from '@/core/RoleService.js'; export const meta = { tags: ['charts', 'users', 'following'], @@ -40,9 +42,84 @@ export const paramDef = { export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private perUserFollowingChart: PerUserFollowingChart, + private readonly cacheService: CacheService, + private readonly roleService: RoleService, ) { super(meta, paramDef, async (ps, me) => { - return await this.perUserFollowingChart.getChart(ps.span, ps.limit, ps.offset ? new Date(ps.offset) : null, ps.userId); + const profile = await this.cacheService.userProfileCache.fetch(ps.userId); + + // These are structured weird to avoid un-necessary calls to roleService and cacheService + const iAmModeratorOrTarget = me && (me.id === ps.userId || await this.roleService.isModerator(me)); + const iAmFollowingOrTarget = me && (me.id === ps.userId || await this.cacheService.isFollowing(me.id, ps.userId)); + + const canViewFollowing = + profile.followingVisibility === 'public' + || iAmModeratorOrTarget + || (profile.followingVisibility === 'followers' && iAmFollowingOrTarget); + + const canViewFollowers = + profile.followersVisibility === 'public' + || iAmModeratorOrTarget + || (profile.followersVisibility === 'followers' && iAmFollowingOrTarget); + + if (!canViewFollowing && !canViewFollowers) { + return { + local: { + followings: { + total: [], + inc: [], + dec: [], + }, + followers: { + total: [], + inc: [], + dec: [], + }, + }, + remote: { + followings: { + total: [], + inc: [], + dec: [], + }, + followers: { + total: [], + inc: [], + dec: [], + }, + }, + }; + } + + const chart = await this.perUserFollowingChart.getChart(ps.span, ps.limit, ps.offset ? new Date(ps.offset) : null, ps.userId); + + if (!canViewFollowers) { + chart.local.followers = { + total: [], + inc: [], + dec: [], + }; + chart.remote.followers = { + total: [], + inc: [], + dec: [], + }; + } + + if (!canViewFollowing) { + chart.local.followings = { + total: [], + inc: [], + dec: [], + }; + chart.remote.followings = { + total: [], + inc: [], + dec: [], + }; + } + + return chart; }); } }