mirror of
				https://github.com/NodeBB/NodeBB.git
				synced 2025-11-03 20:45:58 +01:00 
			
		
		
		
	feat: unwind announce(delete), federate out Remove(Context) on delete, but not on purge
This commit is contained in:
		@@ -182,6 +182,7 @@ 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) {
 | 
			
		||||
@@ -200,8 +201,6 @@ inbox.delete = async (req) => {
 | 
			
		||||
 | 
			
		||||
		if (type === 'Tombstone') {
 | 
			
		||||
			method = 'delete'; // soft delete
 | 
			
		||||
		} else if (activitypub._constants.acceptable.contextTypes.includes(type)) {
 | 
			
		||||
			method = 'move'; // move to cid -1
 | 
			
		||||
		}
 | 
			
		||||
	} catch (e) {
 | 
			
		||||
		// probably 410/404
 | 
			
		||||
@@ -221,11 +220,7 @@ inbox.delete = async (req) => {
 | 
			
		||||
		// db.isSortedSetMember('usersRemote:lastCrawled', object.id),
 | 
			
		||||
	]);
 | 
			
		||||
 | 
			
		||||
	// 'move' method only applicable for contexts
 | 
			
		||||
	if (method === 'move' && !isContext) {
 | 
			
		||||
		return reject('Delete', object, actor);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	console.log(isNote, isContext);
 | 
			
		||||
	switch (true) {
 | 
			
		||||
		case isNote: {
 | 
			
		||||
			const cid = await posts.getCidByPid(id);
 | 
			
		||||
@@ -248,13 +243,8 @@ inbox.delete = async (req) => {
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
			const { tid, uid } = await posts.getPostFields(pid, ['tid', 'uid']);
 | 
			
		||||
			if (method === 'move') {
 | 
			
		||||
				activitypub.helpers.log(`[activitypub/inbox.delete] Moving tid ${tid} to cid -1.`);
 | 
			
		||||
				await api.topics.move({ uid }, { tid, cid: -1 });
 | 
			
		||||
			} else {
 | 
			
		||||
				activitypub.helpers.log(`[activitypub/inbox.delete] Deleting tid ${tid}.`);
 | 
			
		||||
				await api.topics[method]({ uid }, { tids: [tid] });
 | 
			
		||||
			}
 | 
			
		||||
			activitypub.helpers.log(`[activitypub/inbox.delete] Deleting tid ${tid}.`);
 | 
			
		||||
			await api.topics[method]({ uid }, { tids: [tid] });
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@@ -347,12 +337,6 @@ inbox.announce = async (req) => {
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		case object.type === 'Delete': {
 | 
			
		||||
			req.body = object;
 | 
			
		||||
			await inbox.delete(req);
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		case object.type === 'Create': {
 | 
			
		||||
			object = object.object;
 | 
			
		||||
			// falls through
 | 
			
		||||
 
 | 
			
		||||
@@ -406,6 +406,7 @@ async function sendMessage(uri, id, type, payload) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ActivityPub.send = async (type, id, targets, payload) => {
 | 
			
		||||
	console.log('sending', payload, targets);
 | 
			
		||||
	if (!meta.config.activitypubEnabled) {
 | 
			
		||||
		return ActivityPub.helpers.log('[activitypub/send] Federation not enabled; not sending.');
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -412,63 +412,6 @@ activitypubApi.announce.user = 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.follow =
 | 
			
		||||
@@ -573,3 +516,38 @@ activitypubApi.undo.flag = enabledCheck(async (caller, flag) => {
 | 
			
		||||
	});
 | 
			
		||||
	await db.sortedSetRemove(`flag:${flag.flagId}:remote`, caller.uid);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
activitypubApi.remove = {};
 | 
			
		||||
 | 
			
		||||
activitypubApi.remove.context = enabledCheck(async ({ uid }, { tid }) => {
 | 
			
		||||
	// Federates Remove(Context); where Context is the tid
 | 
			
		||||
	const now = new Date();
 | 
			
		||||
	const cid = await topics.getTopicField(tid, '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 deletion of tid ${tid} 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 });
 | 
			
		||||
 | 
			
		||||
	// Remove(Context)
 | 
			
		||||
	await activitypub.send('cid', cid, Array.from(targets), {
 | 
			
		||||
		id: `${nconf.get('url')}/topic/${tid}#activity/remove/${now.getTime()}`,
 | 
			
		||||
		type: 'Remove',
 | 
			
		||||
		actor: `${nconf.get('url')}/uid/${uid}`,
 | 
			
		||||
		to,
 | 
			
		||||
		cc,
 | 
			
		||||
		object: `${nconf.get('url')}/topic/${tid}`,
 | 
			
		||||
		origin: `${nconf.get('url')}/category/${cid}`,
 | 
			
		||||
	});
 | 
			
		||||
});
 | 
			
		||||
@@ -321,13 +321,12 @@ topicsAPI.move = async (caller, { tid, cid }) => {
 | 
			
		||||
			if (!topicData.deleted) {
 | 
			
		||||
				socketHelpers.sendNotificationToTopicOwner(tid, caller.uid, 'move', 'notifications:moved-your-topic');
 | 
			
		||||
 | 
			
		||||
				// AP: Announce(Delete(Object))
 | 
			
		||||
				if (cid === -1) {
 | 
			
		||||
					await activitypubApi.announce.delete({ uid: caller.uid }, { tid });
 | 
			
		||||
					// tbd: activitypubApi.move (to null target)
 | 
			
		||||
					// tbd: activitypubApi.undo.announce?
 | 
			
		||||
				} else {
 | 
			
		||||
					activitypubApi.announce.category(caller, { tid });
 | 
			
		||||
					// tbd: api.activitypub.announce.move
 | 
			
		||||
					// tbd: api.activitypub.move
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -25,7 +25,7 @@ module.exports = function (Topics) {
 | 
			
		||||
				deleterUid: uid,
 | 
			
		||||
				deletedTimestamp: Date.now(),
 | 
			
		||||
			}),
 | 
			
		||||
			api.activitypub.announce.delete({ uid }, { tid }),
 | 
			
		||||
			api.activitypub.remove.context({ uid }, { tid }),
 | 
			
		||||
		]);
 | 
			
		||||
 | 
			
		||||
		await categories.updateRecentTidForCid(cid);
 | 
			
		||||
@@ -82,7 +82,6 @@ module.exports = function (Topics) {
 | 
			
		||||
		}
 | 
			
		||||
		deletedTopic.tags = tags;
 | 
			
		||||
		await deleteFromFollowersIgnorers(tid);
 | 
			
		||||
		await api.activitypub.announce.delete({ uid }, { tid }),
 | 
			
		||||
 | 
			
		||||
		await Promise.all([
 | 
			
		||||
			db.deleteAll([
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user