fix: defer federation of new topics when topic is scheduled, tie activitypub api module to global enable toggle

This commit is contained in:
Julian Lam
2024-02-26 15:39:09 -05:00
parent aadac7053a
commit 5f85e70006
4 changed files with 57 additions and 17 deletions

View File

@@ -211,7 +211,7 @@ Mocks.note = async (post) => {
const raw = await posts.getPostField(post.pid, 'content');
// todo: post visibility, category privileges integration
// todo: post visibility
const to = [activitypub._constants.publicAddress];
const cc = [`${nconf.get('url')}/uid/${post.user.uid}/followers`];

View File

@@ -9,14 +9,29 @@
*/
const nconf = require('nconf');
const winston = require('winston');
const db = require('../database');
const meta = require('../meta');
const privileges = require('../privileges');
const activitypub = require('../activitypub');
const posts = require('../posts');
const activitypubApi = module.exports;
activitypubApi.follow = async (caller, { uid } = {}) => {
function noop() {}
function enabledCheck(next) {
return async function (caller, params) {
if (!meta.config.activitypubEnabled) {
return noop;
}
next(caller, params);
};
}
activitypubApi.follow = enabledCheck(async (caller, { uid } = {}) => {
const result = await activitypub.helpers.query(uid);
if (!result) {
throw new Error('[[error:activitypub.invalid-id]]');
@@ -26,10 +41,10 @@ activitypubApi.follow = async (caller, { uid } = {}) => {
type: 'Follow',
object: result.actorUri,
});
};
});
// should be .undo.follow
activitypubApi.unfollow = async (caller, { uid }) => {
activitypubApi.unfollow = enabledCheck(async (caller, { uid }) => {
const result = await activitypub.helpers.query(uid);
if (!result) {
throw new Error('[[error:activitypub.invalid-id]]');
@@ -48,7 +63,7 @@ activitypubApi.unfollow = async (caller, { uid }) => {
db.sortedSetRemove(`followingRemote:${caller.uid}`, result.actorUri),
db.decrObjectField(`user:${caller.uid}`, 'followingRemoteCount'),
]);
};
});
activitypubApi.create = {};
@@ -65,12 +80,18 @@ async function buildRecipients(object, uid) {
return { targets };
}
activitypubApi.create.post = async (caller, { pid }) => {
activitypubApi.create.post = enabledCheck(async (caller, { pid }) => {
const post = (await posts.getPostSummaryByPids([pid], caller.uid, { stripTags: false })).pop();
if (!post) {
return;
}
const allowed = await privileges.posts.can('topics:read', pid, activitypub._constants.uid);
if (!allowed) {
winston.verbose(`[activitypub/api] Not federating creation of pid ${pid} to the fediverse due to privileges.`);
return;
}
const object = await activitypub.mocks.note(post);
const { targets } = await buildRecipients(object, post.user.uid);
@@ -82,11 +103,11 @@ activitypubApi.create.post = async (caller, { pid }) => {
};
await activitypub.send('uid', caller.uid, Array.from(targets), payload);
};
});
activitypubApi.update = {};
activitypubApi.update.profile = async (caller, { uid }) => {
activitypubApi.update.profile = enabledCheck(async (caller, { uid }) => {
const [object, followers] = await Promise.all([
activitypub.mocks.actors.user(uid),
db.getSortedSetMembers(`followersRemote:${caller.uid}`),
@@ -98,12 +119,18 @@ activitypubApi.update.profile = async (caller, { uid }) => {
cc: [],
object,
});
};
});
activitypubApi.update.note = async (caller, { post }) => {
activitypubApi.update.note = enabledCheck(async (caller, { post }) => {
const object = await activitypub.mocks.note(post);
const { targets } = await buildRecipients(object, post.user.uid);
const allowed = await privileges.posts.can('topics:read', post.pid, activitypub._constants.uid);
if (!allowed) {
winston.verbose(`[activitypub/api] Not federating update of pid ${post.pid} to the fediverse due to privileges.`);
return;
}
const payload = {
type: 'Update',
to: object.to,
@@ -112,12 +139,12 @@ activitypubApi.update.note = async (caller, { post }) => {
};
await activitypub.send('uid', caller.uid, Array.from(targets), payload);
};
});
activitypubApi.like = {};
activitypubApi.like.note = async (caller, { pid }) => {
if (!activitypub.helpers.isUri(pid)) {
activitypubApi.like.note = enabledCheck(async (caller, { pid }) => {
if (!activitypub.helpers.isUri(pid)) { // remote only
return;
}
@@ -130,13 +157,13 @@ activitypubApi.like.note = async (caller, { pid }) => {
type: 'Like',
object: pid,
});
};
});
activitypubApi.undo = {};
// activitypubApi.undo.follow =
activitypubApi.undo.like = async (caller, { pid }) => {
activitypubApi.undo.like = enabledCheck(async (caller, { pid }) => {
if (!activitypub.helpers.isUri(pid)) {
return;
}
@@ -154,4 +181,4 @@ activitypubApi.undo.like = async (caller, { pid }) => {
object: pid,
},
});
};
});

View File

@@ -80,7 +80,10 @@ topicsAPI.create = async function (caller, data) {
socketHelpers.emitToUids('event:new_post', { posts: [result.postData] }, [caller.uid]);
socketHelpers.emitToUids('event:new_topic', result.topicData, [caller.uid]);
socketHelpers.notifyNew(caller.uid, 'newTopic', { posts: [result.postData], topic: result.topicData });
activitypubApi.create.post(caller, { pid: result.postData.pid });
if (!isScheduling) {
activitypubApi.create.post(caller, { pid: result.postData.pid });
}
return result.topicData;
};

View File

@@ -10,6 +10,7 @@ const socketHelpers = require('../socket.io/helpers');
const topics = require('./index');
const groups = require('../groups');
const user = require('../user');
const api = require('../api');
const Scheduled = module.exports;
@@ -47,6 +48,7 @@ async function postTids(tids) {
sendNotifications(uids, topicsData),
updateUserLastposttimes(uids, topicsData),
updateGroupPosts(uids, topicsData),
federatePosts(uids, topicsData),
...topicsData.map(topicData => unpin(topicData.tid, topicData)),
));
}
@@ -149,6 +151,14 @@ async function updateGroupPosts(uids, topicsData) {
}));
}
function federatePosts(uids, topicData) {
topicData.forEach(({ mainPid: pid }, idx) => {
const uid = uids[idx];
api.activitypub.create.post({ uid }, { pid });
});
}
async function shiftPostTimes(tid, timestamp) {
const pids = (await posts.getPidsFromSet(`tid:${tid}:posts`, 0, -1, false));
// Leaving other related score values intact, since they reflect post order correctly, and it seems that's good enough