From 11b3d4fa0a881c555c70af9879b022e037325c09 Mon Sep 17 00:00:00 2001 From: Laura Hausmann Date: Wed, 18 Oct 2023 23:58:56 +0200 Subject: [PATCH] [backend] Require users to be followed before adding them to lists --- .../queue/processors/db/import-user-lists.ts | 17 +++++++++++++++- .../server/api/endpoints/users/lists/push.ts | 20 +++++++++++++++++-- .../src/server/api/mastodon/helpers/list.ts | 9 ++++++++- .../backend/src/services/user-list/push.ts | 3 ++- 4 files changed, 44 insertions(+), 5 deletions(-) diff --git a/packages/backend/src/queue/processors/db/import-user-lists.ts b/packages/backend/src/queue/processors/db/import-user-lists.ts index 0c23f0699..68ba001ec 100644 --- a/packages/backend/src/queue/processors/db/import-user-lists.ts +++ b/packages/backend/src/queue/processors/db/import-user-lists.ts @@ -10,7 +10,7 @@ import { DriveFiles, Users, UserLists, - UserListJoinings, + UserListJoinings, Blockings, Followings, } from "@/models/index.js"; import { genId } from "@/misc/gen-id.js"; import type { DbUserImportJobData } from "@/queue/types.js"; @@ -77,6 +77,21 @@ export async function importUserLists( target = await resolveUser(username, host); } + const isBlocked = await Blockings.exist({ + where: { + blockerId: target.id, + blockeeId: user.id, + }, + }); + const isFollowed = await Followings.exist({ + where: { + followerId: user.id, + followeeId: target.id, + }, + }); + + if (isBlocked || !isFollowed) continue; + if ( (await UserListJoinings.findOneBy({ userListId: list!.id, diff --git a/packages/backend/src/server/api/endpoints/users/lists/push.ts b/packages/backend/src/server/api/endpoints/users/lists/push.ts index 899754aaf..3b4a87835 100644 --- a/packages/backend/src/server/api/endpoints/users/lists/push.ts +++ b/packages/backend/src/server/api/endpoints/users/lists/push.ts @@ -1,5 +1,5 @@ import { pushUserToUserList } from "@/services/user-list/push.js"; -import { UserLists, UserListJoinings, Blockings } from "@/models/index.js"; +import { UserLists, UserListJoinings, Blockings, Followings } from "@/models/index.js"; import define from "../../../define.js"; import { ApiError } from "../../../error.js"; import { getUser } from "../../../common/getters.js"; @@ -38,6 +38,13 @@ export const meta = { code: "YOU_HAVE_BEEN_BLOCKED", id: "990232c5-3f9d-4d83-9f3f-ef27b6332a4b", }, + + notFollowing: { + message: + "You cannot push this user because you are not following this user.", + code: "NOT_FOLLOWING", + id: "0a2e4d73-fe61-41fb-822c-d365ec81ba2a", + }, }, } as const; @@ -68,7 +75,7 @@ export default define(meta, paramDef, async (ps, me) => { throw e; }); - // Check blocking + // Check blocking and following status if (user.id !== me.id) { const isBlocked = await Blockings.exist({ where: { @@ -76,9 +83,18 @@ export default define(meta, paramDef, async (ps, me) => { blockeeId: me.id, }, }); + const isFollowed = await Followings.exist({ + where: { + followerId: me.id, + followeeId: user.id, + }, + }); if (isBlocked) { throw new ApiError(meta.errors.youHaveBeenBlocked); } + if (!isFollowed) { + throw new ApiError(meta.errors.notFollowing); + } } const exist = await UserListJoinings.exist({ diff --git a/packages/backend/src/server/api/mastodon/helpers/list.ts b/packages/backend/src/server/api/mastodon/helpers/list.ts index 7ce6d12b5..0fa607b3e 100644 --- a/packages/backend/src/server/api/mastodon/helpers/list.ts +++ b/packages/backend/src/server/api/mastodon/helpers/list.ts @@ -1,5 +1,5 @@ import { ILocalUser, User } from "@/models/entities/user.js"; -import { Blockings, UserListJoinings, UserLists, Users } from "@/models/index.js"; +import { Blockings, Followings, UserListJoinings, UserLists, Users } from "@/models/index.js"; import { PaginationHelpers } from "@/server/api/mastodon/helpers/pagination.js"; import { UserList } from "@/models/entities/user-list.js"; import { pushUserToUserList } from "@/services/user-list/push.js"; @@ -76,7 +76,14 @@ export class ListHelpers { blockeeId: localUser.id, }, }); + const isFollowed = await Followings.exist({ + where: { + followeeId: user.id, + followerId: localUser.id, + }, + }); if (isBlocked) throw Error("Can't add users you've been blocked by to list"); + if (!isFollowed) throw Error("Can't add users you're not following to list"); } const exist = await UserListJoinings.exist({ diff --git a/packages/backend/src/services/user-list/push.ts b/packages/backend/src/services/user-list/push.ts index 7866ca17f..74827b46b 100644 --- a/packages/backend/src/services/user-list/push.ts +++ b/packages/backend/src/services/user-list/push.ts @@ -1,9 +1,10 @@ import { publishUserListStream } from "@/services/stream.js"; import type { User } from "@/models/entities/user.js"; import type { UserList } from "@/models/entities/user-list.js"; -import { UserListJoinings, Users } from "@/models/index.js"; +import { Followings, UserListJoinings, Users } from "@/models/index.js"; import type { UserListJoining } from "@/models/entities/user-list-joining.js"; import { genId } from "@/misc/gen-id.js"; +import { ApiError } from "@/server/api/error.js"; export async function pushUserToUserList(target: User, list: UserList) { await UserListJoinings.insert({