feat: federate Delete on post delete as well as purge, topic deletion federates Announce(Delete(Object))

This commit is contained in:
Julian Lam
2025-10-06 13:45:40 -04:00
parent 923ddbc1f1
commit 93b6cb5984
4 changed files with 69 additions and 1 deletions

View File

@@ -350,7 +350,7 @@ activitypubApi.announce = {};
activitypubApi.announce.note = enabledCheck(async (caller, { tid }) => { activitypubApi.announce.note = enabledCheck(async (caller, { tid }) => {
const { mainPid: pid, cid } = await topics.getTopicFields(tid, ['mainPid', 'cid']); const { mainPid: pid, cid } = await topics.getTopicFields(tid, ['mainPid', 'cid']);
// Only remote posts can be announced to real categories // Only remote posts can be announced to local categories
if (utils.isNumber(pid) || parseInt(cid, 10) === -1) { if (utils.isNumber(pid) || parseInt(cid, 10) === -1) {
return; return;
} }
@@ -379,6 +379,63 @@ activitypubApi.announce.note = enabledCheck(async (caller, { tid }) => {
}); });
}); });
activitypubApi.announce.delete = enabledCheck(async ({ uid }, { tid }) => {
const now = new Date();
const { mainPid: pid, cid } = await topics.getTopicFields(tid, ['mainPid', 'cid']);
// Only local categories
if (!utils.isNumber(cid) || parseInt(cid, 10) < 1) {
return;
}
const allowed = await privileges.categories.can('topics:read', cid, activitypub._constants.uid);
if (!allowed) {
activitypub.helpers.log(`[activitypub/api] Not federating announce of pid ${pid} to the fediverse due to privileges.`);
return;
}
const { to, cc, targets } = await activitypub.buildRecipients({
to: [activitypub._constants.publicAddress],
cc: [`${nconf.get('url')}/category/${cid}/followers`],
}, { cid });
const deleteTpl = {
id: `${nconf.get('url')}/topic/${tid}#activity/delete/${now.getTime()}`,
type: 'Delete',
actor: `${nconf.get('url')}/category/${cid}`,
to,
cc,
origin: `${nconf.get('url')}/category/${cid}`,
};
// 7888 variant
await activitypub.send('cid', cid, Array.from(targets), {
id: `${nconf.get('url')}/topic/${tid}#activity/announce/delete/${now.getTime()}`,
type: 'Announce',
actor: `${nconf.get('url')}/category/${cid}`,
to,
cc,
object: {
...deleteTpl,
object: `${nconf.get('url')}/topic/${tid}`,
},
});
// 1b12 variant
await activitypub.send('cid', cid, Array.from(targets), {
id: `${nconf.get('url')}/post/${encodeURIComponent(pid)}#activity/announce/delete/${now.getTime()}`,
type: 'Announce',
actor: `${nconf.get('url')}/category/${cid}`,
to,
cc,
object: {
...deleteTpl,
actor: `${nconf.get('url')}/uid/${uid}`,
object: utils.isNumber(pid) ? `${nconf.get('url')}/post/${pid}` : pid,
},
});
});
activitypubApi.undo = {}; activitypubApi.undo = {};
// activitypubApi.undo.follow = // activitypubApi.undo.follow =

View File

@@ -34,6 +34,7 @@ module.exports = function (Posts) {
await Promise.all([ await Promise.all([
topics.updateLastPostTimeFromLastPid(postData.tid), topics.updateLastPostTimeFromLastPid(postData.tid),
topics.updateTeaser(postData.tid), topics.updateTeaser(postData.tid),
isDeleting ? activitypub.notes.delete(pid) : null,
isDeleting ? isDeleting ?
db.sortedSetRemove(`cid:${topicData.cid}:pids`, pid) : db.sortedSetRemove(`cid:${topicData.cid}:pids`, pid) :
db.sortedSetAdd(`cid:${topicData.cid}:pids`, postData.timestamp, pid), db.sortedSetAdd(`cid:${topicData.cid}:pids`, postData.timestamp, pid),

View File

@@ -8,6 +8,7 @@ const categories = require('../categories');
const flags = require('../flags'); const flags = require('../flags');
const plugins = require('../plugins'); const plugins = require('../plugins');
const batch = require('../batch'); const batch = require('../batch');
const api = require('../api');
const utils = require('../utils'); const utils = require('../utils');
module.exports = function (Topics) { module.exports = function (Topics) {
@@ -80,6 +81,7 @@ module.exports = function (Topics) {
} }
deletedTopic.tags = tags; deletedTopic.tags = tags;
await deleteFromFollowersIgnorers(tid); await deleteFromFollowersIgnorers(tid);
await api.activitypub.announce.delete({ uid }, { tid }),
await Promise.all([ await Promise.all([
db.deleteAll([ db.deleteAll([

View File

@@ -7,6 +7,7 @@ const topics = require('.');
const categories = require('../categories'); const categories = require('../categories');
const user = require('../user'); const user = require('../user');
const plugins = require('../plugins'); const plugins = require('../plugins');
const api = require('../api');
const privileges = require('../privileges'); const privileges = require('../privileges');
const utils = require('../utils'); const utils = require('../utils');
@@ -277,6 +278,13 @@ module.exports = function (Topics) {
const oldCid = topicData.cid; const oldCid = topicData.cid;
await categories.moveRecentReplies(tid, oldCid, cid); await categories.moveRecentReplies(tid, oldCid, cid);
// AP: Announce(Delete(Object))
if (cid === -1) {
await api.activitypub.announce.delete({ uid: data.uid }, { tid });
} else {
// tbd: api.activitypub.announce.move
}
await Promise.all([ await Promise.all([
Topics.setTopicFields(tid, { Topics.setTopicFields(tid, {
cid: cid, cid: cid,