diff --git a/packages/backend/src/server/api/mastodon/endpoints/list.ts b/packages/backend/src/server/api/mastodon/endpoints/list.ts index ad4641db5..e56e67846 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/list.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/list.ts @@ -8,6 +8,8 @@ import { ListHelpers } from "@/server/api/mastodon/helpers/list.js"; import { UserConverter } from "@/server/api/mastodon/converters/user.js"; import { PaginationHelpers } from "@/server/api/mastodon/helpers/pagination.js"; import { UserLists } from "@/models/index.js"; +import { NoteHelpers } from "@/server/api/mastodon/helpers/note.js"; +import { getUser } from "@/server/api/common/getters.js"; export function setupEndpointsList(router: Router): void { router.get("/v1/lists", async (ctx, reply) => { @@ -138,22 +140,37 @@ export function setupEndpointsList(router: Router): void { router.post<{ Params: { id: string } }>( "/v1/lists/:id/accounts", async (ctx, reply) => { - const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; - const accessTokens = ctx.headers.authorization; - const client = getClient(BASE_URL, accessTokens); try { - const data = await client.addAccountsToList( - convertId(ctx.params.id, IdType.IceshrimpId), - (ctx.query.account_ids as string[]).map((id) => - convertId(id, IdType.IceshrimpId), - ), - ); - ctx.body = data.data; + const auth = await authenticate(ctx.headers.authorization, null); + const user = auth[0] ?? undefined; + + if (!user) { + ctx.status = 401; + return; + } + + const id = convertId(ctx.params.id, IdType.IceshrimpId); + const list = await UserLists.findOneBy({userId: user.id, id: id}); + + if (!list) { + ctx.status = 404; + return; + } + + const body = ctx.request.body as any; + if (!body['account_ids']) { + ctx.status = 400; + ctx.body = { error: "Missing account_ids[] field" }; + return; + } + + const ids = NoteHelpers.normalizeToArray(body['account_ids']).map(p => convertId(p, IdType.IceshrimpId)); + const targets = await Promise.all(ids.map(p => getUser(p))); + await ListHelpers.addToList(user, list, targets); + ctx.body = {} } catch (e: any) { - console.error(e); - console.error(e.response.data); - ctx.status = 401; - ctx.body = e.response.data; + ctx.status = 400; + ctx.body = { error: e.message }; } }, ); diff --git a/packages/backend/src/server/api/mastodon/helpers/list.ts b/packages/backend/src/server/api/mastodon/helpers/list.ts index 4513a1c1f..85cdb9339 100644 --- a/packages/backend/src/server/api/mastodon/helpers/list.ts +++ b/packages/backend/src/server/api/mastodon/helpers/list.ts @@ -1,8 +1,9 @@ import { ILocalUser, User } from "@/models/entities/user.js"; -import { UserListJoinings, UserLists } from "@/models/index.js"; +import { Blockings, UserListJoinings, UserLists } from "@/models/index.js"; import { LinkPaginationObject } from "@/server/api/mastodon/helpers/user.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"; export class ListHelpers { public static async getLists(user: ILocalUser): Promise { @@ -53,4 +54,29 @@ export class ListHelpers { if (user.id != list.userId) throw new Error("List is not owned by user"); await UserLists.delete(list.id); } + + public static async addToList(localUser: ILocalUser, list: UserList, usersToAdd: User[]) { + if (localUser.id != list.userId) throw new Error("List is not owned by user"); + for (const user of usersToAdd) { + if (user.id !== localUser.id) { + const isBlocked = await Blockings.exist({ + where: { + blockerId: user.id, + blockeeId: localUser.id, + }, + }); + if (isBlocked) throw Error("Can't add users you've been blocked by to list"); + } + + const exist = await UserListJoinings.exist({ + where: { + userListId: list.id, + userId: user.id, + }, + }); + + if (exist) continue; + await pushUserToUserList(user, list); + } + } }