mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-26 16:46:12 +01:00
feat: add checks to only continue with topic assertion if there is a relation to existing content, #12442
This commit is contained in:
@@ -245,7 +245,7 @@ inbox.accept = async (req) => {
|
||||
if (type === 'Follow') {
|
||||
const now = Date.now();
|
||||
await db.sortedSetAdd(`followingRemote:${uid}`, now, actor);
|
||||
await db.sortedSetAdd(`followersRemote:${actor}`, now, uid); // for followers backreference
|
||||
await db.sortedSetAdd(`followersRemote:${actor}`, now, uid); // for followers backreference and notes assertion checking
|
||||
const followingRemoteCount = await db.sortedSetCard(`followingRemote:${uid}`);
|
||||
await user.setUserField(uid, 'followingRemoteCount', followingRemoteCount);
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ const categories = require('../categories');
|
||||
const user = require('../user');
|
||||
const topics = require('../topics');
|
||||
const posts = require('../posts');
|
||||
const plugins = require('../plugins');
|
||||
const utils = require('../utils');
|
||||
|
||||
const activitypub = module.parent.exports;
|
||||
@@ -25,7 +26,7 @@ async function unlock(value) {
|
||||
await db.deleteObjectField('locks', value);
|
||||
}
|
||||
|
||||
Notes.assert = async (uid, input) => {
|
||||
Notes.assert = async (uid, input, options = { skipChecks: false }) => {
|
||||
/**
|
||||
* Given the id or object of any as:Note, traverses up to cache the entire threaded context
|
||||
*
|
||||
@@ -74,10 +75,15 @@ Notes.assert = async (uid, input) => {
|
||||
}
|
||||
mainPid = utils.isNumber(mainPid) ? parseInt(mainPid, 10) : mainPid;
|
||||
|
||||
// Privilege check for local categories
|
||||
// Relation & privilege check for local categories
|
||||
const privilege = `topics:${tid ? 'reply' : 'create'}`;
|
||||
const hasRelation = options.skipChecks || hasTid || await assertRelation(chain[0]);
|
||||
const allowed = await privileges.categories.can(privilege, cid, activitypub._constants.uid);
|
||||
if (!allowed) {
|
||||
if (!hasRelation || !allowed) {
|
||||
if (!hasRelation) {
|
||||
winston.info(`[activitypub/notes.assert] Not asserting ${id} as it has no relation to existing tracked content.`);
|
||||
}
|
||||
|
||||
unlock(id);
|
||||
return null;
|
||||
}
|
||||
@@ -168,6 +174,36 @@ Notes.assert = async (uid, input) => {
|
||||
return { tid, count };
|
||||
};
|
||||
|
||||
async function assertRelation(post) {
|
||||
/**
|
||||
* Given a mocked post object, ensures that it is related to some other object in database
|
||||
* This check ensures that random content isn't added to the database just because it is received.
|
||||
*/
|
||||
|
||||
// Is followed by at least one local user
|
||||
const isFollowed = await db.sortedSetCard(`followersRemote:${post.uid}`);
|
||||
|
||||
// Local user is mentioned
|
||||
const { tag } = post._activitypub;
|
||||
let uids = [];
|
||||
if (tag.length) {
|
||||
const slugs = tag.reduce((slugs, tag) => {
|
||||
if (tag.type === 'Mention') {
|
||||
const [slug, hostname] = tag.name.slice(1).split('@');
|
||||
if (hostname === nconf.get('url_parsed').hostname) {
|
||||
slugs.push(slug);
|
||||
}
|
||||
}
|
||||
return slugs;
|
||||
}, []);
|
||||
|
||||
uids = slugs.length ? await db.sortedSetScores('userslug:uid', slugs) : [];
|
||||
uids = uids.filter(Boolean);
|
||||
}
|
||||
|
||||
return isFollowed || uids.length;
|
||||
}
|
||||
|
||||
Notes.updateLocalRecipients = async (id, { to, cc }) => {
|
||||
const recipients = new Set([...(to || []), ...(cc || [])]);
|
||||
const uids = new Set();
|
||||
|
||||
Reference in New Issue
Block a user