From ab6561e60f1d05e0010ae28868d62070d6857855 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Mon, 20 Oct 2025 14:03:45 -0400 Subject: [PATCH] feat: inbox handler for Remove(Context) --- src/activitypub/inbox.js | 39 +++++++++++++++++++++++++++++++++++++-- src/api/activitypub.js | 2 +- src/api/topics.js | 4 ++-- 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/src/activitypub/inbox.js b/src/activitypub/inbox.js index 14fe460a53..9a9381f43f 100644 --- a/src/activitypub/inbox.js +++ b/src/activitypub/inbox.js @@ -13,6 +13,7 @@ const notifications = require('../notifications'); const messaging = require('../messaging'); const flags = require('../flags'); const api = require('../api'); +const utils = require('../utils'); const activitypub = require('.'); const socketHelpers = require('../socket.io/helpers'); @@ -78,6 +79,42 @@ inbox.add = async (req) => { } }; +inbox.remove = async (req) => { + const { actor, object } = req.body; + + const isContext = activitypub._constants.acceptable.contextTypes.has(object.type); + if (!isContext) { + return; // don't know how to handle other types + } + console.log('isContext?', isContext); + + const mainPid = await activitypub.contexts.getItems(0, object.id, { returnRootId: true }); + const exists = await posts.exists(mainPid); + if (!exists) { + return; // post not cached; do nothing. + } + console.log('mainPid is', mainPid); + + // Ensure that cid is same-origin as the actor + const tid = await posts.getPostField(mainPid, 'tid'); + const cid = await topics.getTopicField(tid, 'cid'); + if (utils.isNumber(cid)) { + // remote removal of topic in local cid; what?? + return; + } + const actorHostname = new URL(actor).hostname; + const cidHostname = new URL(cid).hostname; + if (actorHostname !== cidHostname) { + throw new Error('[[error:activitypub.origin-mismatch]]'); + } + + activitypub.helpers.log(`[activitypub/inbox/remove] Removing topic ${tid} from ${cid}`); + await topics.tools.move(tid, { + cid: -1, + uid: 'system', + }); +}; + inbox.update = async (req) => { const { actor, object } = req.body; const isPublic = publiclyAddressed([...(object.to || []), ...(object.cc || [])]); @@ -182,7 +219,6 @@ inbox.update = async (req) => { inbox.delete = async (req) => { const { actor, object } = req.body; - console.log(actor, object); if (typeof object !== 'string') { const { id } = object; if (!id) { @@ -220,7 +256,6 @@ inbox.delete = async (req) => { // db.isSortedSetMember('usersRemote:lastCrawled', object.id), ]); - console.log(isNote, isContext); switch (true) { case isNote: { const cid = await posts.getCidByPid(id); diff --git a/src/api/activitypub.js b/src/api/activitypub.js index bf302054ea..688960d619 100644 --- a/src/api/activitypub.js +++ b/src/api/activitypub.js @@ -541,7 +541,7 @@ activitypubApi.remove.context = enabledCheck(async ({ uid }, { tid }) => { }, { cid }); // Remove(Context) - await activitypub.send('cid', cid, Array.from(targets), { + await activitypub.send('uid', uid, Array.from(targets), { id: `${nconf.get('url')}/topic/${tid}#activity/remove/${now.getTime()}`, type: 'Remove', actor: `${nconf.get('url')}/uid/${uid}`, diff --git a/src/api/topics.js b/src/api/topics.js index 50252ebdad..cef93a195d 100644 --- a/src/api/topics.js +++ b/src/api/topics.js @@ -322,11 +322,11 @@ topicsAPI.move = async (caller, { tid, cid }) => { socketHelpers.sendNotificationToTopicOwner(tid, caller.uid, 'move', 'notifications:moved-your-topic'); if (cid === -1) { - // tbd: activitypubApi.move (to null target) + activitypubApi.remove.context(caller, { tid }); // tbd: activitypubApi.undo.announce? } else { + // tbd: activitypubApi.move activitypubApi.announce.category(caller, { tid }); - // tbd: api.activitypub.move } }