diff --git a/src/activitypub/mocks.js b/src/activitypub/mocks.js index 2bf3b5b1bd..e5a0ffbe6d 100644 --- a/src/activitypub/mocks.js +++ b/src/activitypub/mocks.js @@ -205,7 +205,6 @@ Mocks.note = async (post) => { const id = `${nconf.get('url')}/post/${post.pid}`; const published = new Date(parseInt(post.timestamp, 10)).toISOString(); - const raw = await posts.getPostField(post.pid, 'content'); // todo: post visibility const to = new Set([activitypub._constants.publicAddress]); @@ -230,7 +229,18 @@ Mocks.note = async (post) => { })); } - const mentionsEnabled = await plugins.isActive('nodebb-plugin-mentions'); + let source = null; + const [markdownEnabled, mentionsEnabled] = await Promise.all([ + plugins.isActive('nodebb-plugin-markdown'), + plugins.isActive('nodebb-plugin-mentions'), + ]); + if (markdownEnabled) { + const raw = await posts.getPostField(post.pid, 'content'); + source = { + content: raw, + mediaType: 'text/markdown', + }; + } if (mentionsEnabled) { const mentions = require.main.require('nodebb-plugin-mentions'); const matches = await mentions.getMatches(post.content); @@ -278,10 +288,7 @@ Mocks.note = async (post) => { summary: null, name, content: post.content, - source: { - content: raw, - mediaType: 'text/markdown', - }, + source, tag, attachment: [], // todo... requires refactoring of link preview plugin // replies: {} todo... diff --git a/src/activitypub/notes.js b/src/activitypub/notes.js index 32325e71fb..83c26b8cb7 100644 --- a/src/activitypub/notes.js +++ b/src/activitypub/notes.js @@ -230,13 +230,13 @@ Notes.assertTopic = async (uid, id) => { let cid; let title; if (hasTid) { - ({ cid, title, mainPid } = await topics.getTopicFields(tid, ['tid', 'cid', 'title', 'mainPid'])); + ({ cid, mainPid } = await topics.getTopicFields(tid, ['tid', 'cid', 'mainPid'])); } else { // mainPid ok to leave as-is cid = -1; title = name || utils.decodeHTMLEntities(utils.stripHTMLTags(content)); if (title.length > meta.config.maximumTitleLength) { - title = `${title.slice(0, meta.config.maximumTitleLength)}...`; + title = `${title.slice(0, meta.config.maximumTitleLength - 3)}...`; } } mainPid = utils.isNumber(mainPid) ? parseInt(mainPid, 10) : mainPid; @@ -274,31 +274,43 @@ Notes.assertTopic = async (uid, id) => { tags = (mainPost._activitypub.tag || []) .filter(o => o.type === 'Hashtag') .map(o => o.name.slice(1)); - tags = await topics.filterTags(tags, cid); - await topics.create({ - tid, - uid: authorId, - cid, - mainPid, - title, - timestamp, - tags, - }); - topics.onNewPostMade(mainPost); + try { + await topics.post({ + tid, + uid: authorId, + cid, + pid: mainPid, + title, + timestamp, + tags, + content: mainPost.content, + _activitypub: mainPost._activitypub, + }); + } catch (e) { + console.log(e); + } + unprocessed.pop(); } - await Promise.all([ - db.sortedSetAdd(`tid:${tid}:posts`, timestamps, ids), - Notes.assert(uid, unprocessed), - ]); - await Promise.all([ // must be done after .assert() - Notes.assertParentChain(chain), - Notes.updateTopicCounts(tid), - Notes.syncUserInboxes(tid), - topics.updateLastPostTimeFromLastPid(tid), - topics.updateTeaser(tid), - ]); + unprocessed.reverse(); + for (const post of unprocessed) { + // eslint-disable-next-line no-await-in-loop + await topics.reply(post); + } + + await Notes.syncUserInboxes(tid); + // await Promise.all([ + // db.sortedSetAdd(`tid:${tid}:posts`, timestamps, ids), + // Notes.assert(uid, unprocessed), + // ]); + // await Promise.all([ // must be done after .assert() + // Notes.assertParentChain(chain), + // Notes.updateTopicCounts(tid), + // Notes.syncUserInboxes(tid), + // topics.updateLastPostTimeFromLastPid(tid), + // topics.updateTeaser(tid), + // ]); return tid; }; diff --git a/src/posts/create.js b/src/posts/create.js index d541564c2e..c876c53660 100644 --- a/src/posts/create.js +++ b/src/posts/create.js @@ -10,12 +10,12 @@ const topics = require('../topics'); const categories = require('../categories'); const groups = require('../groups'); const privileges = require('../privileges'); +const utils = require('../utils'); module.exports = function (Posts) { Posts.create = async function (data) { // This is an internal method, consider using Topics.reply instead - const { uid } = data; - const { tid } = data; + const { uid, tid, _activitypub } = data; const content = data.content.toString(); const timestamp = data.timestamp || Date.now(); const isMain = data.isMain || false; @@ -28,13 +28,14 @@ module.exports = function (Posts) { await checkToPid(data.toPid, uid); } - const pid = await db.incrObjectField('global', 'nextPid'); + const pid = data.pid || await db.incrObjectField('global', 'nextPid'); let postData = { pid: pid, uid: uid, tid: tid, content: content, timestamp: timestamp, + _activitypub, }; if (data.toPid) { @@ -56,7 +57,7 @@ module.exports = function (Posts) { await Promise.all([ db.sortedSetAdd('posts:pid', timestamp, postData.pid), - db.incrObjectField('global', 'postCount'), + utils.isNumber(pid) ? db.incrObjectField('global', 'postCount') : null, user.onNewPostMade(postData), topics.onNewPostMade(postData), categories.onNewPostMade(topicData.cid, topicData.pinned, postData), diff --git a/src/topics/create.js b/src/topics/create.js index 6f10c950c2..9b5a3ac87b 100644 --- a/src/topics/create.js +++ b/src/topics/create.js @@ -135,7 +135,7 @@ module.exports = function (Topics) { throw new Error('[[error:no-topic]]'); } - if (uid > 0 && settings.followTopicsOnCreate) { + if (utils.isNumber(uid) && uid > 0 && settings.followTopicsOnCreate) { await Topics.follow(postData.tid, uid); } const topicData = topics[0]; diff --git a/test/template-helpers.js b/test/template-helpers.js index 00ae777f82..f01bdd642c 100644 --- a/test/template-helpers.js +++ b/test/template-helpers.js @@ -151,7 +151,7 @@ describe('helpers', () => { find: 'viewing', read: 'viewing', }; - const html = helpers.spawnPrivilegeStates('guests', privs, types); + const html = helpers.spawnPrivilegeStates(1, 'guests', privs, types); assert.equal(html, `