[mastodon-client] DELETE /lists/:id/accounts

This commit is contained in:
Laura Hausmann 2023-10-02 19:06:02 +02:00
parent 94d75585b4
commit 239fef3e71
No known key found for this signature in database
GPG key ID: D044E84C5BE01605
3 changed files with 49 additions and 17 deletions

View file

@ -1,5 +1,4 @@
import Router from "@koa/router"; import Router from "@koa/router";
import { getClient } from "../index.js";
import { convertAccount, convertList, } from "../converters.js"; import { convertAccount, convertList, } from "../converters.js";
import { convertId, IdType } from "../../index.js"; import { convertId, IdType } from "../../index.js";
import authenticate from "@/server/api/authenticate.js"; import authenticate from "@/server/api/authenticate.js";
@ -206,22 +205,37 @@ export function setupEndpointsList(router: Router): void {
router.delete<{ Params: { id: string } }>( router.delete<{ Params: { id: string } }>(
"/v1/lists/:id/accounts", "/v1/lists/:id/accounts",
async (ctx, reply) => { async (ctx, reply) => {
const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
const accessTokens = ctx.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try { try {
const data = await client.deleteAccountsFromList( const auth = await authenticate(ctx.headers.authorization, null);
convertId(ctx.params.id, IdType.IceshrimpId), const user = auth[0] ?? undefined;
(ctx.query.account_ids as string[]).map((id) =>
convertId(id, IdType.IceshrimpId), if (!user) {
), ctx.status = 401;
); return;
ctx.body = data.data; }
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.removeFromList(user, list, targets);
ctx.body = {}
} catch (e: any) { } catch (e: any) {
console.error(e); ctx.status = 400;
console.error(e.response.data); ctx.body = { error: e.message };
ctx.status = 401;
ctx.body = e.response.data;
} }
}, },
); );

View file

@ -1,10 +1,11 @@
import { ILocalUser, User } from "@/models/entities/user.js"; import { ILocalUser, User } from "@/models/entities/user.js";
import { Blockings, UserListJoinings, UserLists } from "@/models/index.js"; import { Blockings, UserListJoinings, UserLists, Users } from "@/models/index.js";
import { LinkPaginationObject } from "@/server/api/mastodon/helpers/user.js"; import { LinkPaginationObject } from "@/server/api/mastodon/helpers/user.js";
import { PaginationHelpers } from "@/server/api/mastodon/helpers/pagination.js"; import { PaginationHelpers } from "@/server/api/mastodon/helpers/pagination.js";
import { UserList } from "@/models/entities/user-list.js"; import { UserList } from "@/models/entities/user-list.js";
import { pushUserToUserList } from "@/services/user-list/push.js"; import { pushUserToUserList } from "@/services/user-list/push.js";
import { genId } from "@/misc/gen-id.js"; import { genId } from "@/misc/gen-id.js";
import { publishUserListStream } from "@/services/stream.js";
export class ListHelpers { export class ListHelpers {
public static async getLists(user: ILocalUser): Promise<MastodonEntity.List[]> { public static async getLists(user: ILocalUser): Promise<MastodonEntity.List[]> {
@ -81,6 +82,22 @@ export class ListHelpers {
} }
} }
public static async removeFromList(localUser: ILocalUser, list: UserList, usersToRemove: User[]) {
if (localUser.id != list.userId) throw new Error("List is not owned by user");
for (const user of usersToRemove) {
const exist = await UserListJoinings.exist({
where: {
userListId: list.id,
userId: user.id,
},
});
if (!exist) continue;
await UserListJoinings.delete({ userListId: list.id, userId: user.id });
publishUserListStream(list.id, "userRemoved", await Users.pack(user));
}
}
public static async createList(user: ILocalUser, title: string): Promise<MastodonEntity.List> { public static async createList(user: ILocalUser, title: string): Promise<MastodonEntity.List> {
const list = await UserLists.insert({ const list = await UserLists.insert({
id: genId(), id: genId(),

View file

@ -9,7 +9,7 @@ import { setupEndpointsNotifications } from "./endpoints/notifications.js";
import { setupEndpointsSearch } from "./endpoints/search.js"; import { setupEndpointsSearch } from "./endpoints/search.js";
import { setupEndpointsMedia } from "@/server/api/mastodon/endpoints/media.js"; import { setupEndpointsMedia } from "@/server/api/mastodon/endpoints/media.js";
import { setupEndpointsMisc } from "@/server/api/mastodon/endpoints/misc.js"; import { setupEndpointsMisc } from "@/server/api/mastodon/endpoints/misc.js";
import { koaBody } from "koa-body"; import { HttpMethodEnum, koaBody } from "koa-body";
import multer from "@koa/multer"; import multer from "@koa/multer";
import { setupEndpointsList } from "@/server/api/mastodon/endpoints/list.js"; import { setupEndpointsList } from "@/server/api/mastodon/endpoints/list.js";
@ -29,6 +29,7 @@ export function setupMastodonApi(router: Router, fileRouter: Router, upload: mul
koaBody({ koaBody({
multipart: true, multipart: true,
urlencoded: true, urlencoded: true,
parsedMethods: [HttpMethodEnum.POST, HttpMethodEnum.PUT, HttpMethodEnum.PATCH, HttpMethodEnum.DELETE] // dear god mastodon why
}), }),
); );