fix(api): 🐛 Don't allow replying to reblogs
Some checks failed
CodeQL Scan / Analyze (javascript-typescript) (push) Failing after 0s
Build Docker Images / lint (push) Failing after 6s
Build Docker Images / check (push) Failing after 6s
Build Docker Images / tests (push) Failing after 6s
Deploy Docs to GitHub Pages / build (push) Failing after 0s
Build Docker Images / build (server, Dockerfile, ${{ github.repository_owner }}/server) (push) Has been skipped
Build Docker Images / build (worker, Worker.Dockerfile, ${{ github.repository_owner }}/worker) (push) Has been skipped
Deploy Docs to GitHub Pages / Deploy (push) Has been skipped
Mirror to Codeberg / Mirror (push) Failing after 0s
Nix Build / check (push) Failing after 0s

This commit is contained in:
Jesse Wierzbinski 2025-05-01 04:36:08 +02:00
parent 2155ca12be
commit 294924fc49
No known key found for this signature in database
2 changed files with 54 additions and 2 deletions

View file

@ -208,6 +208,44 @@ describe("/api/v1/statuses", () => {
});
});
test("shouldn't allow replying to a reblog", async () => {
await using client = await generateClient(users[0]);
await using client2 = await generateClient(users[1]);
const { data, ok } = await client.postStatus("Hello, world!");
expect(ok).toBe(true);
const { data: reblog, ok: ok2 } = await client2.reblogStatus(data.id);
expect(ok2).toBe(true);
const { ok: ok3 } = await client.postStatus("Hello, world again!", {
in_reply_to_id: reblog.id,
});
expect(ok3).toBe(false);
});
test("shouldn't allow quoting a reblog", async () => {
await using client = await generateClient(users[0]);
await using client2 = await generateClient(users[1]);
const { data, ok } = await client.postStatus("Hello, world!");
expect(ok).toBe(true);
const { data: reblog, ok: ok2 } = await client2.reblogStatus(data.id);
expect(ok2).toBe(true);
const { ok: ok3 } = await client.postStatus("Hello, world again!", {
quote_id: reblog.id,
});
expect(ok3).toBe(false);
});
describe("mentions testing", () => {
test("should correctly parse @mentions", async () => {
await using client = await generateClient(users[0]);

View file

@ -163,21 +163,35 @@ export default apiRoute((app) =>
);
}
const reply = in_reply_to_id
? await Note.fromId(in_reply_to_id)
: null;
// Check that in_reply_to_id and quote_id are real posts if provided
if (in_reply_to_id && !(await Note.fromId(in_reply_to_id))) {
if (in_reply_to_id && !reply) {
throw new ApiError(
422,
"Note referenced by in_reply_to_id not found",
);
}
if (quote_id && !(await Note.fromId(quote_id))) {
if (in_reply_to_id && reply?.data.reblogId) {
throw new ApiError(422, "Cannot reply to a reblog");
}
const quote = quote_id ? await Note.fromId(quote_id) : null;
if (quote_id && !quote) {
throw new ApiError(
422,
"Note referenced by quote_id not found",
);
}
if (quote_id && quote?.data.reblogId) {
throw new ApiError(422, "Cannot quote a reblog");
}
const sanitizedSpoilerText = spoiler_text
? await sanitizedHtmlStrip(spoiler_text)
: undefined;