feat: update Remove(Context) to use target instead of origin, federate out Move(Context) on topic move between local cids

This commit is contained in:
Julian Lam
2025-10-22 15:04:47 -04:00
parent 3ede64d8a1
commit d02e188a5f
4 changed files with 49 additions and 13 deletions

View File

@@ -86,14 +86,12 @@ inbox.remove = async (req) => {
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');

View File

@@ -533,7 +533,7 @@ ActivityPub.buildRecipients = async function (object, { pid, uid, cid }) {
* - Builds a list of targets for activitypub.send to consume
* - Extends to and cc since the activity can be addressed more widely
* - Optional parameters:
* - `cid`: includes followers of the passed-in cid (local only)
* - `cid`: includes followers of the passed-in cid (local only, can also be an array)
* - `uid`: includes followers of the passed-in uid (local only)
* - `pid`: includes post announcers and all topic participants
*/
@@ -551,12 +551,15 @@ ActivityPub.buildRecipients = async function (object, { pid, uid, cid }) {
}
if (cid) {
const cidFollowers = await ActivityPub.notes.getCategoryFollowers(cid);
followers = followers.concat(cidFollowers);
const followersUrl = `${nconf.get('url')}/category/${cid}/followers`;
if (!to.has(followersUrl)) {
cc.add(followersUrl);
}
cid = Array.isArray(cid) ? cid : [cid];
await Promise.all(cid.map(async (cid) => {
const cidFollowers = await ActivityPub.notes.getCategoryFollowers(cid);
followers = followers.concat(cidFollowers);
const followersUrl = `${nconf.get('url')}/category/${cid}/followers`;
if (!to.has(followersUrl)) {
cc.add(followersUrl);
}
}));
}
const targets = new Set([...followers, ...to, ...cc]);

View File

@@ -351,10 +351,9 @@ Out.remove.context = enabledCheck(async (uid, tid) => {
const { to, cc, targets } = await activitypub.buildRecipients({
to: [activitypub._constants.publicAddress],
cc: [`${nconf.get('url')}/category/${cid}/followers`],
cc: [],
}, { cid });
// Remove(Context)
await activitypub.send('uid', uid, Array.from(targets), {
id: `${nconf.get('url')}/topic/${tid}#activity/remove/${now.getTime()}`,
type: 'Remove',
@@ -362,7 +361,43 @@ Out.remove.context = enabledCheck(async (uid, tid) => {
to,
cc,
object: `${nconf.get('url')}/topic/${tid}`,
origin: `${nconf.get('url')}/category/${cid}`,
target: `${nconf.get('url')}/category/${cid}`,
});
});
Out.move = {};
Out.move.context = enabledCheck(async (uid, tid) => {
// Federates Move(Context); where Context is the tid
const now = new Date();
const { cid, oldCid } = await topics.getTopicFields(tid, ['cid', 'oldCid']);
// This check may be revised if inter-community moderation becomes real.
const isNotLocal = id => !utils.isNumber(cid) || parseInt(cid, 10) < 1;
if ([cid, oldCid].some(isNotLocal)) {
return;
}
const allowed = await privileges.categories.can('topics:read', cid, activitypub._constants.uid);
if (!allowed) {
activitypub.helpers.log(`[activitypub/api] Not federating move of tid ${tid} to the fediverse due to privileges.`);
return;
}
const { to, cc, targets } = await activitypub.buildRecipients({
to: [activitypub._constants.publicAddress],
cc: [],
}, { cid: [cid, oldCid] });
await activitypub.send('uid', uid, Array.from(targets), {
id: `${nconf.get('url')}/topic/${tid}#activity/move/${now.getTime()}`,
type: 'Move',
actor: `${nconf.get('url')}/uid/${uid}`,
to,
cc,
object: `${nconf.get('url')}/topic/${tid}`,
origin: `${nconf.get('url')}/category/${oldCid}`,
target: `${nconf.get('url')}/category/${cid}`,
});
});

View File

@@ -326,7 +326,7 @@ topicsAPI.move = async (caller, { tid, cid }) => {
activitypub.out.remove.context(caller.uid, tid);
// tbd: activitypubApi.undo.announce?
} else {
// tbd: activitypubApi.move
activitypub.out.move.context(caller.uid, tid);
activitypub.out.announce.category(tid);
}
}