Catodon federating deletes of objects it doesn't own
Hey @[email protected], now that I'm tracking errors encountered, I've got a bit more visibility into things that normally would've just been caught and ignored.
Today I received a Delete(Object) from Catodon associated with a user from catodon.rocks.
Two things:
-
Its
objectreferenced an item outside ofcatodon.rocks, and so it failed NodeBB's actor-object match check. Normally people can't delete other peoples' posts, so I think this might be a mistake? -
The activity's
audiencematches the activity'sattributedTo. While you're certainly allowed to put anything you want in there, threadiverse software uses it to point to a group actor. Wondering if this was intentional.
Thanks!
@[email protected] whoa, really sorry about that, looking into it. Thanks for reporting.
@[email protected] fwiw, I'm running the develop version on catodon.rocks, not stable, I'm still working on group actors implementation, and it's obviously not ready yet.
@[email protected] I was wondering if maybe there was some group-actor shenanigans going on :)
@[email protected] You were right, it was a bug in catodon’s forum delete path: for forum posts, it could emit a plain top-level Delete fallback even when the deleted post was remote-authored, which made it look like our forum actor was deleting an object it didn’t own. I changed it so that:
audience, rather than conflatingaudiencewith the author/deleter.So this should resolve the two issues you pointed out on the Catodon side - if you see it again, or anything else that looks off, please lmk!
One request from our side: Would you consider handling Announce(Delete)? In forum/communities federation, that’s how a group passes along deletion of a post that came from another server, without making it look like the group owns that post. In practice, the remaining issue is with remote-authored posts in catodon forums: when the original author is on another server and deletes the post, catodon can remove it locally and forward that deletion, and it is accepted by Lemmy and Piefed, but NodeBB servers currently keep showing the post because they ignore
Announce(Delete).@[email protected] sure thing. I thought we did handle it but it's been awhile. I'll take a look!
@[email protected] handling of
Announce(Delete)is merged (but untested across real 1b12 generators)... do you mind doing a quick test?@[email protected] Thanks! This should work but it still doesn't for me, but it could very well be something on our end, I'd suggest testing with Lemmy or Piefed. It's 4am here so I will continue tomorrow (and update you if needed). BTW the thing I've been stuck on for days now is how to make forum posts with no content, just title and primary link, display the link in NodeBB... it worked from the first attempt with Lemmy and Piefed, but I haven't managed to make it work with NodeBB. The only time I succeeded was when I added the primary link's url in the content, but that was not a proper solution, and it made the url appear on lemmy and piefed too, which wasn't needed. And I'm pretty sure I've seen lemmy posts with just a primary link be displayed correctly on nodebb, and I can't figure out what I'm doing wrong...
@[email protected] could you please take a look at these issues on NodeBB's side, too? Perhaps some are a misjudgment on my part, but I think that at least some are legit:
In src/activitypub/out.js, Out.dislike.note is missing await:
const payload = activitypub.mocks.activities.dislike(pid, uid);
mocks.activities.dislike() is async, so NodeBB sends a Promise instead of a valid Dislike activity. That means Catodon does not receive NodeBB downvotes correctly.
Suggested fix:
const payload = await activitypub.mocks.activities.dislike(pid, uid);
(this would mirror NodeBB's behaviour for outgoing Likes)
Catodon sends forum root posts as Page objects with:
-url set to the primary link
-a link attachment with mediaType: "text/html"
NodeBB appears to preserve the URL into postData.url, but the post UI does not render it in the post body, it only shows up in the post menu as “View original post”.
Also, src/activitypub/notes.js only appends image attachments inline, so Link attachments are ignored visually.
Suggestion: NodeBB should render AP primary links for Page / forum-root posts, either from post.url or from the Link attachment.
Two issues with the Announce(Delete) handling:
In src/activitypub/inbox.js, the Announce(Delete) branch ignores unknown objects:
if (!exists) {
... Doing nothing.
break;
}
If Delete arrives before Create, NodeBB ignores the Delete, then later creates the post. That leaves a deleted remote post visible.
Suggestion: NodeBB should remember unknown deletes, tombstone pending IDs, or otherwise suppress/retry later Creates that arrive after a Delete.
Also, the Announce(Delete) path calls low-level posts.delete(id, uid) instead of the normal API delete path. For a topic OP, especially a single-post topic, that does not behave like NodeBB’s normal delete flow and may not delete the topic or emit the usual delete events.
Suggestion: use the API-level delete path where appropriate, similar to direct Delete handling.
src/activitypub/inbox.js handles Undo(Like), but there is no Dislike case in inbox.undo, which results in remote Undo(Dislike) activities being silently ignored, so remote downvotes can become permanent from NodeBB’s perspective.
Suggestion: add an Undo(Dislike) case mirroring Undo(Like), and unvote the post accordingly.
src/activitypub/out.js has Out.undo.like but no Out.undo.dislike, and src/api/helpers.js always calls activitypub.out.undo.like(...) for any unvote, even when the removed vote was a downvote.
Suggestion:
-add Out.undo.dislike
-make the unvote path choose Undo(Like) or Undo(Dislike) based on the previous vote state
In src/activitypub/inbox.js, inside inbox.dislike, the log message says [activitypub/inbox.like] - you probably want it to say [activitypub/inbox.dislike]
These issues (if confirmed on your side) affect downvotes, downvote removal, primary-link display, and reliable deletion of federated forum/group posts.