diff --git a/packages/backend/src/server/api/mastodon/converters.ts b/packages/backend/src/server/api/mastodon/converters.ts index 44712b97b..74ca8efdf 100644 --- a/packages/backend/src/server/api/mastodon/converters.ts +++ b/packages/backend/src/server/api/mastodon/converters.ts @@ -40,7 +40,7 @@ export function convertNotification(notification: MastodonEntity.Notification) { export function convertPoll(poll: Entity.Poll) { return simpleConvert(poll); } -export function convertReaction(reaction: Entity.Reaction) { +export function convertReaction(reaction: MastodonEntity.Reaction) { if (reaction.accounts) { reaction.accounts = reaction.accounts.map(convertAccount); } @@ -50,7 +50,7 @@ export function convertRelationship(relationship: Entity.Relationship) { return simpleConvert(relationship); } -export function convertStatus(status: Entity.Status) { +export function convertStatus(status: MastodonEntity.Status) { status.account = convertAccount(status.account); status.id = convertId(status.id, IdType.MastodonId); if (status.in_reply_to_account_id) @@ -75,7 +75,7 @@ export function convertStatus(status: Entity.Status) { return status; } -export function convertConversation(conversation: Entity.Conversation) { +export function convertConversation(conversation: MastodonEntity.Conversation) { conversation.id = convertId(conversation.id, IdType.MastodonId); conversation.accounts = conversation.accounts.map(convertAccount); if (conversation.last_status) { diff --git a/packages/backend/src/server/api/mastodon/endpoints/status.ts b/packages/backend/src/server/api/mastodon/endpoints/status.ts index fbc6223f7..dab1648d0 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/status.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/status.ts @@ -1,7 +1,6 @@ import Router from "@koa/router"; import { getClient } from "../ApiMastodonCompatibleService.js"; import { emojiRegexAtStartToEnd } from "@/misc/emoji-regex.js"; -import axios from "axios"; import querystring from "node:querystring"; import qs from "qs"; import { convertId, IdType } from "../../index.js"; @@ -11,8 +10,6 @@ import { getNote } from "@/server/api/common/getters.js"; import authenticate from "@/server/api/authenticate.js"; import { NoteHelpers } from "@/server/api/mastodon/helpers/note.js"; import { UserHelpers } from "@/server/api/mastodon/helpers/user.js"; -import createReaction from "@/services/note/reaction/create.js"; -import deleteReaction from "@/services/note/reaction/delete.js"; import { convertPaginationArgsIds, limitToInt, normalizeUrlQuery } from "@/server/api/mastodon/endpoints/timeline.js"; import { PaginationHelpers } from "@/server/api/mastodon/helpers/pagination.js"; import { UserConverter } from "@/server/api/mastodon/converters/user.js"; @@ -172,28 +169,45 @@ export function apiStatusMastodon(router: Router): void { } }); router.delete<{ Params: { id: string } }>("/v1/statuses/:id", 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.deleteStatus( - convertId(ctx.params.id, IdType.IceshrimpId), - ); - ctx.body = data.data; + const auth = await authenticate(ctx.headers.authorization, null); + const user = auth[0] ?? null; + + if (!user) { + ctx.status = 401; + return; + } + + const noteId = convertId(ctx.params.id, IdType.IceshrimpId); + const note = await getNote(noteId, user ?? null).then(n => n).catch(() => null); + + if (!note) { + ctx.status = 404; + ctx.body = { + error: "Note not found" + } + return; + } + + if (user.id !== note.userId) { + ctx.status = 403; + ctx.body = { + error: "Cannot delete someone else's note" + } + return; + } + + ctx.body = await NoteHelpers.deleteNote(note, user) + .then(p => convertStatus(p)); } catch (e: any) { - console.error(e.response.data, ctx.params.id); - ctx.status = 401; - ctx.body = e.response.data; + console.error(`Error processing ${ctx.method} /api${ctx.path}: ${e.message}`); + ctx.status = 500; + ctx.body = { + error: e.message + } } }); - interface IReaction { - id: string; - createdAt: string; - user: MisskeyEntity.User; - type: string; - } - router.get<{ Params: { id: string } }>( "/v1/statuses/:id/context", async (ctx) => { @@ -250,9 +264,6 @@ export function apiStatusMastodon(router: Router): void { router.get<{ Params: { id: string } }>( "/v1/statuses/:id/reblogged_by", async (ctx) => { - const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; - const accessTokens = ctx.headers.authorization; - const client = getClient(BASE_URL, accessTokens); try { const auth = await authenticate(ctx.headers.authorization, null); const user = auth[0] ?? null; diff --git a/packages/backend/src/server/api/mastodon/entities/status.ts b/packages/backend/src/server/api/mastodon/entities/status.ts index db476b1a5..0058911de 100644 --- a/packages/backend/src/server/api/mastodon/entities/status.ts +++ b/packages/backend/src/server/api/mastodon/entities/status.ts @@ -17,8 +17,8 @@ namespace MastodonEntity { in_reply_to_id: string | null; in_reply_to_account_id: string | null; reblog: Status | null; - content: string; - text: string | null; + content: string | undefined; + text: string | null | undefined; created_at: string; emojis: Emoji[]; replies_count: number; diff --git a/packages/backend/src/server/api/mastodon/helpers/note.ts b/packages/backend/src/server/api/mastodon/helpers/note.ts index 57892d73e..fd10616c1 100644 --- a/packages/backend/src/server/api/mastodon/helpers/note.ts +++ b/packages/backend/src/server/api/mastodon/helpers/note.ts @@ -15,6 +15,7 @@ import { PaginationHelpers } from "@/server/api/mastodon/helpers/pagination.js"; import { UserConverter } from "@/server/api/mastodon/converters/user.js"; import { AccountCache, LinkPaginationObject, UserHelpers } from "@/server/api/mastodon/helpers/user.js"; import { addPinned, removePinned } from "@/services/i/pin.js"; +import { NoteConverter } from "@/server/api/mastodon/converters/note.js"; export class NoteHelpers { public static async getDefaultReaction(): Promise { @@ -112,6 +113,14 @@ export class NoteHelpers { return note; } + public static async deleteNote(note: Note, user: ILocalUser): Promise { + if (user.id !== note.userId) throw new Error("Can't delete someone elses note"); + const status = await NoteConverter.encode(note, user); + await deleteNote(user, note); + status.content = undefined; + return status; + } + public static async getNoteFavoritedBy(note: Note, maxId: string | undefined, sinceId: string | undefined, minId: string | undefined, limit: number = 40): Promise> { if (limit > 80) limit = 80; const query = PaginationHelpers.makePaginationQuery(