diff --git a/packages/backend/src/server/api/mastodon/converters.ts b/packages/backend/src/server/api/mastodon/converters.ts index 8af0b1a5b..5f8c73a2e 100644 --- a/packages/backend/src/server/api/mastodon/converters.ts +++ b/packages/backend/src/server/api/mastodon/converters.ts @@ -56,6 +56,9 @@ export function convertSearch(search: MastodonEntity.Search) { return search; } +export function convertStatusSource(statusSource: MastodonEntity.StatusSource) { + return simpleConvert(statusSource); +} export function convertStatus(status: MastodonEntity.Status) { status.account = convertAccount(status.account); diff --git a/packages/backend/src/server/api/mastodon/endpoints/status.ts b/packages/backend/src/server/api/mastodon/endpoints/status.ts index 0d3cc69dc..f3b196cb6 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/status.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/status.ts @@ -1,6 +1,6 @@ import Router from "@koa/router"; import { convertId, IdType } from "../../index.js"; -import { convertAccount, convertPoll, convertStatus, convertStatusEdit, } from "../converters.js"; +import { convertAccount, convertPoll, convertStatus, convertStatusEdit, convertStatusSource, } from "../converters.js"; import { NoteConverter } from "@/server/api/mastodon/converters/note.js"; import { getNote } from "@/server/api/common/getters.js"; import authenticate from "@/server/api/authenticate.js"; @@ -202,6 +202,30 @@ export function setupEndpointsStatus(router: Router): void { } }, ); + router.get<{ Params: { id: string } }>( + "/v1/statuses/:id/source", + async (ctx) => { + try { + const auth = await authenticate(ctx.headers.authorization, null); + const user = auth[0] ?? null; + + const id = convertId(ctx.params.id, IdType.IceshrimpId); + const note = await getNote(id, user).catch(_ => null); + + if (note === null) { + ctx.status = 404; + return; + } + + const src = NoteHelpers.getNoteSource(note); + ctx.body = convertStatusSource(src); + } catch (e: any) { + console.error(e); + ctx.status = 401; + ctx.body = e.response.data; + } + }, + ); router.get<{ Params: { id: string } }>( "/v1/statuses/:id/reblogged_by", async (ctx) => { diff --git a/packages/backend/src/server/api/mastodon/entities/status_source.ts b/packages/backend/src/server/api/mastodon/entities/status_source.ts new file mode 100644 index 000000000..04758f599 --- /dev/null +++ b/packages/backend/src/server/api/mastodon/entities/status_source.ts @@ -0,0 +1,7 @@ +namespace MastodonEntity { + export type StatusSource = { + id: string; + text: string; + spoiler_text: string; + }; +} diff --git a/packages/backend/src/server/api/mastodon/helpers/note.ts b/packages/backend/src/server/api/mastodon/helpers/note.ts index 448b391b7..4b17e8d13 100644 --- a/packages/backend/src/server/api/mastodon/helpers/note.ts +++ b/packages/backend/src/server/api/mastodon/helpers/note.ts @@ -201,6 +201,14 @@ export class NoteHelpers { return Promise.all(history); } + public static getNoteSource(note: Note): MastodonEntity.StatusSource { + return { + id: note.id, + text: note.text ?? '', + spoiler_text: note.cw ?? '' + } + } + public static async getNoteRebloggedBy(note: Note, maxId: string | undefined, sinceId: string | undefined, minId: string | undefined, limit: number = 40): Promise> { if (limit > 80) limit = 80; const query = PaginationHelpers.makePaginationQuery(