diff --git a/src/activitypub/inbox.js b/src/activitypub/inbox.js index 9a9381f43f..23ac85c844 100644 --- a/src/activitypub/inbox.js +++ b/src/activitypub/inbox.js @@ -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'); diff --git a/src/activitypub/index.js b/src/activitypub/index.js index e215d68c5d..767c88ce23 100644 --- a/src/activitypub/index.js +++ b/src/activitypub/index.js @@ -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]); diff --git a/src/activitypub/out.js b/src/activitypub/out.js index da6c62f361..7fb77c9140 100644 --- a/src/activitypub/out.js +++ b/src/activitypub/out.js @@ -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}`, }); }); diff --git a/src/api/topics.js b/src/api/topics.js index 9d3c149397..d7f2f4836f 100644 --- a/src/api/topics.js +++ b/src/api/topics.js @@ -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); } }