import { Users } from "@/models/index.js"; import { resolveUser } from "@/remote/resolve-user.js"; import Router from "@koa/router"; import { FindOptionsWhere, IsNull } from "typeorm"; import { getClient } from "../ApiMastodonCompatibleService.js"; import { argsToBools, limitToInt } from "./timeline.js"; const relationshopModel = { id: "", following: false, followed_by: false, delivery_following: false, blocking: false, blocked_by: false, muting: false, muting_notifications: false, requested: false, domain_blocking: false, showing_reblogs: false, endorsed: false, notifying: false, note: "", }; export function apiAccountMastodon(router: Router): void { router.get("/v1/accounts/verify_credentials", async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); try { const data = await client.verifyAccountCredentials(); const acct = data.data; acct.url = `${BASE_URL}/@${acct.url}`; acct.note = ""; acct.avatar_static = acct.avatar; acct.header = acct.header || ""; acct.header_static = acct.header || ""; acct.source = { note: acct.note, fields: acct.fields, privacy: "public", sensitive: false, language: "", }; console.log(acct); ctx.body = acct; } catch (e: any) { console.error(e); console.error(e.response.data); ctx.status = 401; ctx.body = e.response.data; } }); router.patch("/v1/accounts/update_credentials", async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); try { const data = await client.updateCredentials( (ctx.request as any).body as any, ); ctx.body = data.data; } catch (e: any) { console.error(e); console.error(e.response.data); ctx.status = 401; ctx.body = e.response.data; } }); router.get("/v1/accounts/lookup", async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); try { const data = await client.search((request.query as any).acct, 'accounts'); ctx.body = data.data.accounts[0]; } catch (e: any) { console.error(e); console.error(e.response.data); ctx.status = 401; ctx.body = e.response.data; } }); router.get<{ Params: { id: string } }>( "/v1/accounts/:id(^.*\\d.*$)", async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); try { const data = await client.getAccount(ctx.params.id); ctx.body = data.data; } catch (e: any) { console.error(e); console.error(e.response.data); ctx.status = 401; ctx.body = e.response.data; } }, ); router.get<{ Params: { id: string } }>( "/v1/accounts/:id/statuses", async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); try { const data = await client.getAccountStatuses( ctx.params.id, argsToBools(limitToInt(ctx.query as any)), ); ctx.body = data.data; } catch (e: any) { console.error(e); console.error(e.response.data); ctx.status = 401; ctx.body = e.response.data; } }, ); router.get<{ Params: { id: string } }>( "/v1/accounts/:id/followers", async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); try { const data = await client.getAccountFollowers( ctx.params.id, limitToInt(ctx.query as any), ); ctx.body = data.data; } catch (e: any) { console.error(e); console.error(e.response.data); ctx.status = 401; ctx.body = e.response.data; } }, ); router.get<{ Params: { id: string } }>( "/v1/accounts/:id/following", async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); try { const data = await client.getAccountFollowing( ctx.params.id, limitToInt(ctx.query as any), ); ctx.body = data.data; } catch (e: any) { console.error(e); console.error(e.response.data); ctx.status = 401; ctx.body = e.response.data; } }, ); router.get<{ Params: { id: string } }>( "/v1/accounts/:id/lists", async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); try { const data = await client.getAccountLists(ctx.params.id); ctx.body = data.data; } catch (e: any) { console.error(e); console.error(e.response.data); ctx.status = 401; ctx.body = e.response.data; } }, ); router.post<{ Params: { id: string } }>( "/v1/accounts/:id/follow", async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); try { const data = await client.followAccount(ctx.params.id); const acct = data.data; acct.following = true; ctx.body = data.data; } catch (e: any) { console.error(e); console.error(e.response.data); ctx.status = 401; ctx.body = e.response.data; } }, ); router.post<{ Params: { id: string } }>( "/v1/accounts/:id/unfollow", async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); try { const data = await client.unfollowAccount(ctx.params.id); const acct = data.data; acct.following = false; ctx.body = data.data; } catch (e: any) { console.error(e); console.error(e.response.data); ctx.status = 401; ctx.body = e.response.data; } }, ); router.post<{ Params: { id: string } }>( "/v1/accounts/:id/block", async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); try { const data = await client.blockAccount(ctx.params.id); ctx.body = data.data; } catch (e: any) { console.error(e); console.error(e.response.data); ctx.status = 401; ctx.body = e.response.data; } }, ); router.post<{ Params: { id: string } }>( "/v1/accounts/:id/unblock", async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); try { const data = await client.unblockAccount(ctx.params.id); ctx.body = data.data; } catch (e: any) { console.error(e); console.error(e.response.data); ctx.status = 401; ctx.body = e.response.data; } }, ); router.post<{ Params: { id: string } }>( "/v1/accounts/:id/mute", async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); try { const data = await client.muteAccount( ctx.params.id, (ctx.request as any).body as any, ); ctx.body = data.data; } catch (e: any) { console.error(e); console.error(e.response.data); ctx.status = 401; ctx.body = e.response.data; } }, ); router.post<{ Params: { id: string } }>( "/v1/accounts/:id/unmute", async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); try { const data = await client.unmuteAccount(ctx.params.id); ctx.body = data.data; } catch (e: any) { console.error(e); console.error(e.response.data); ctx.status = 401; ctx.body = e.response.data; } }, ); router.get("/v1/accounts/relationships", async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); let users; try { // TODO: this should be body const idsRaw = ctx.request.query ? ctx.request.query["id[]"] : null; const ids = typeof idsRaw === "string" ? [idsRaw] : idsRaw; users = ids; relationshopModel.id = idsRaw?.toString() || "1"; if (!idsRaw) { ctx.body = [relationshopModel]; return; } const data = await client.getRelationships(ids); ctx.body = data.data; } catch (e: any) { console.error(e); let data = e.response.data; data.users = users; console.error(data); ctx.status = 401; ctx.body = data; } }); router.get("/v1/bookmarks", async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); try { const data = (await client.getBookmarks(ctx.query as any)) as any; ctx.body = data.data; } catch (e: any) { console.error(e); console.error(e.response.data); ctx.status = 401; ctx.body = e.response.data; } }); router.get("/v1/favourites", async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); try { const data = await client.getFavourites(ctx.query as any); ctx.body = data.data; } catch (e: any) { console.error(e); console.error(e.response.data); ctx.status = 401; ctx.body = e.response.data; } }); router.get("/v1/mutes", async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); try { const data = await client.getMutes(ctx.query as any); ctx.body = data.data; } catch (e: any) { console.error(e); console.error(e.response.data); ctx.status = 401; ctx.body = e.response.data; } }); router.get("/v1/blocks", async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); try { const data = await client.getBlocks(ctx.query as any); ctx.body = data.data; } catch (e: any) { console.error(e); console.error(e.response.data); ctx.status = 401; ctx.body = e.response.data; } }); router.get("/v1/follow_ctxs", async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); try { const data = await client.getFollowRequests( ((ctx.query as any) || { limit: 20 }).limit, ); ctx.body = data.data; } catch (e: any) { console.error(e); console.error(e.response.data); ctx.status = 401; ctx.body = e.response.data; } }); router.post<{ Params: { id: string } }>( "/v1/follow_ctxs/:id/authorize", async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); try { const data = await client.acceptFollowRequest(ctx.params.id); ctx.body = data.data; } catch (e: any) { console.error(e); console.error(e.response.data); ctx.status = 401; ctx.body = e.response.data; } }, ); router.post<{ Params: { id: string } }>( "/v1/follow_ctxs/:id/reject", async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); try { const data = await client.rejectFollowRequest(ctx.params.id); ctx.body = data.data; } catch (e: any) { console.error(e); console.error(e.response.data); ctx.status = 401; ctx.body = e.response.data; } }, ); }