iceshrimp/packages/backend/src/server/api/mastodon/endpoints/account.ts

419 lines
12 KiB
TypeScript

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;
}
},
);
}