mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-26 08:36:12 +01:00
fix: defer federation of new topics when topic is scheduled, tie activitypub api module to global enable toggle
This commit is contained in:
@@ -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`];
|
||||
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
});
|
||||
};
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user