mirror of
https://github.com/NodeBB/NodeBB.git
synced 2026-05-07 09:56:16 +02:00
fix: #14147, dont create wrong backlinks
syncBacklinks expects raw post content, html was passed to it from onNewPost since it was switched to use getPostSummary
backlinkRegex was matching ${nconf.get('url')}/topic/1aef954c-d0dc-45cf-acf2-e3a59f6cc134/foo and return tid=1 instead of the uuid
remove useless if check in syncBacklinks
fixed parseInts on tids
current - remove are both arrays use .length
This commit is contained in:
@@ -259,14 +259,14 @@ module.exports = function (Topics) {
|
|||||||
return postData;
|
return postData;
|
||||||
};
|
};
|
||||||
|
|
||||||
async function onNewPost({ pid, tid, uid: postOwner }, { uid, handle }) {
|
async function onNewPost({ pid, tid, content, uid: postOwner }, { uid, handle }) {
|
||||||
const [[postData], [userInfo]] = await Promise.all([
|
const [[postData], [userInfo]] = await Promise.all([
|
||||||
posts.getPostSummaryByPids([pid], uid, { extraFields: ['attachments'] }),
|
posts.getPostSummaryByPids([pid], uid, { extraFields: ['attachments'] }),
|
||||||
posts.getUserInfoForPosts([postOwner], uid),
|
posts.getUserInfoForPosts([postOwner], uid),
|
||||||
]);
|
]);
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
Topics.addParentPosts([postData], uid),
|
Topics.addParentPosts([postData], uid),
|
||||||
Topics.syncBacklinks(postData),
|
Topics.syncBacklinks({ ...postData, content }),
|
||||||
Topics.markAsRead([tid], uid),
|
Topics.markAsRead([tid], uid),
|
||||||
]);
|
]);
|
||||||
if (utils.isNumber(postOwner) && postData.category.cid === -1) {
|
if (utils.isNumber(postOwner) && postData.category.cid === -1) {
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ const plugins = require('../plugins');
|
|||||||
const utils = require('../utils');
|
const utils = require('../utils');
|
||||||
const privileges = require('../privileges');
|
const privileges = require('../privileges');
|
||||||
|
|
||||||
const backlinkRegex = new RegExp(`(?:${nconf.get('url').replace('/', '\\/')}|\b|\\s)\\/topic\\/(\\d+)(?:\\/\\w+)?`, 'g');
|
const backlinkRegex = new RegExp(`(?:${nconf.get('url').replace('/', '\\/')}|\b|\\s)\\/topic\\/([a-fA-F0-9-]+)(?=\\/|$|\\s)?`, 'g');
|
||||||
|
|
||||||
module.exports = function (Topics) {
|
module.exports = function (Topics) {
|
||||||
Topics.onNewPostMade = async function (postData) {
|
Topics.onNewPostMade = async function (postData) {
|
||||||
@@ -447,29 +447,27 @@ module.exports = function (Topics) {
|
|||||||
throw new Error('[[error:invalid-data]]');
|
throw new Error('[[error:invalid-data]]');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let { pid, uid, content } = postData;
|
||||||
let { content } = postData;
|
|
||||||
// ignore lines that start with `>`
|
// ignore lines that start with `>`
|
||||||
content = (content || '').split('\n').filter(line => !line.trim().startsWith('>')).join('\n');
|
content = (content || '').split('\n').filter(line => !line.trim().startsWith('>')).join('\n');
|
||||||
// Scan post content for topic links
|
// Scan post content for topic links
|
||||||
const matches = [...content.matchAll(backlinkRegex)];
|
const matches = [...content.matchAll(backlinkRegex)];
|
||||||
if (!matches) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { pid, uid, tid } = postData;
|
let add = _.uniq(matches.map(match => match[1]));
|
||||||
let add = _.uniq(matches.map(match => match[1]).map(tid => parseInt(tid, 10)));
|
|
||||||
|
|
||||||
const now = Date.now();
|
const [topicsExist, current] = await Promise.all([
|
||||||
const topicsExist = await Topics.exists(add);
|
Topics.exists(add),
|
||||||
const current = (await db.getSortedSetMembers(`pid:${pid}:backlinks`)).map(tid => parseInt(tid, 10));
|
db.getSortedSetMembers(`pid:${pid}:backlinks`),
|
||||||
|
]);
|
||||||
const remove = current.filter(tid => !add.includes(tid));
|
const remove = current.filter(tid => !add.includes(tid));
|
||||||
add = add.filter((_tid, idx) => topicsExist[idx] && !current.includes(_tid) && tid !== _tid);
|
const postTid = String(postData.tid);
|
||||||
|
add = add.filter((_tid, idx) => topicsExist[idx] && !current.includes(_tid) && postTid !== _tid);
|
||||||
|
|
||||||
// Remove old backlinks
|
// Remove old backlinks
|
||||||
await db.sortedSetRemove(`pid:${pid}:backlinks`, remove);
|
await db.sortedSetRemove(`pid:${pid}:backlinks`, remove);
|
||||||
|
|
||||||
// Add new backlinks
|
// Add new backlinks
|
||||||
|
const now = Date.now();
|
||||||
await db.sortedSetAdd(`pid:${pid}:backlinks`, add.map(() => now), add);
|
await db.sortedSetAdd(`pid:${pid}:backlinks`, add.map(() => now), add);
|
||||||
await Promise.all(add.map(async (tid) => {
|
await Promise.all(add.map(async (tid) => {
|
||||||
await Topics.events.log(tid, {
|
await Topics.events.log(tid, {
|
||||||
@@ -479,6 +477,6 @@ module.exports = function (Topics) {
|
|||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return add.length + (current - remove);
|
return add.length + (current.length - remove.length);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1152,12 +1152,10 @@ describe('Post\'s', () => {
|
|||||||
|
|
||||||
describe('.syncBacklinks()', () => {
|
describe('.syncBacklinks()', () => {
|
||||||
it('should error on invalid data', async () => {
|
it('should error on invalid data', async () => {
|
||||||
try {
|
await assert.rejects(
|
||||||
await topics.syncBacklinks();
|
topics.syncBacklinks(),
|
||||||
} catch (e) {
|
{ message: '[[error:invalid-data]]' },
|
||||||
assert(e);
|
);
|
||||||
assert.strictEqual(e.message, '[[error:invalid-data]]');
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should do nothing if the post does not contain a link to a topic', async () => {
|
it('should do nothing if the post does not contain a link to a topic', async () => {
|
||||||
@@ -1192,9 +1190,7 @@ describe('Post\'s', () => {
|
|||||||
const backlinks = await db.getSortedSetMembers('pid:2:backlinks');
|
const backlinks = await db.getSortedSetMembers('pid:2:backlinks');
|
||||||
|
|
||||||
assert.strictEqual(count, 0);
|
assert.strictEqual(count, 0);
|
||||||
assert(events);
|
|
||||||
assert.strictEqual(events.length, 1);
|
assert.strictEqual(events.length, 1);
|
||||||
assert(backlinks);
|
|
||||||
assert.strictEqual(backlinks.length, 0);
|
assert.strictEqual(backlinks.length, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1219,6 +1215,17 @@ describe('Post\'s', () => {
|
|||||||
assert(backlinks);
|
assert(backlinks);
|
||||||
assert.strictEqual(backlinks.length, 0);
|
assert.strictEqual(backlinks.length, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should not create a wrong backlink to topic/1 with AP topic url', async () => {
|
||||||
|
const { postData } = await topics.post({
|
||||||
|
uid: 1,
|
||||||
|
cid,
|
||||||
|
title: 'Topic backlink testing - topic 2',
|
||||||
|
content: `testing ${nconf.get('url')}/topic/1aef954c-d0dc-45cf-acf2-e3a59f6cc134/foo`,
|
||||||
|
});
|
||||||
|
const backlinks = await db.getSortedSetMembers(`pid:${postData.pid}:backlinks`);
|
||||||
|
assert.strictEqual(backlinks.length, 0);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('integration tests', () => {
|
describe('integration tests', () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user