diff --git a/src/activitypub/contexts.js b/src/activitypub/contexts.js index d6d8500739..34037d79a4 100644 --- a/src/activitypub/contexts.js +++ b/src/activitypub/contexts.js @@ -52,7 +52,11 @@ Contexts.get = async (uid, id) => { return false; }; -Contexts.getItems = async (uid, id, root = true) => { +Contexts.getItems = async (uid, id, options) => { + if (!options.hasOwnProperty('root')) { + options.root = true; + } + winston.verbose(`[activitypub/context] Retrieving context ${id}`); let { type, items, orderedItems, first, next } = await activitypub.get('uid', uid, id); if (!acceptableTypes.includes(type)) { @@ -71,19 +75,31 @@ Contexts.getItems = async (uid, id, root = true) => { } const chain = new Set(items || []); - if (!next && root && first) { + if (!next && options.root && first) { next = first; } if (next) { winston.verbose('[activitypub/context] Fetching next page...'); Array - .from(await Contexts.getItems(uid, next, false)) + .from(await Contexts.getItems(uid, next, { + ...options, + root: false, + })) .forEach((item) => { chain.add(item); }); } + // Handle special case where originating object is not actually part of the context collection + const inputId = activitypub.helpers.isUri(options.input) ? options.input : options.input.id; + const inCollection = Array.from(chain).map(p => p.pid).includes(inputId); + if (!inCollection) { + chain.add(activitypub.helpers.isUri(options.input) ? + parseString(uid, options.input) : + parseItem(uid, options.input)); + } + return chain; }; diff --git a/src/activitypub/notes.js b/src/activitypub/notes.js index 7972d9de1e..772ba2412a 100644 --- a/src/activitypub/notes.js +++ b/src/activitypub/notes.js @@ -48,7 +48,7 @@ Notes.assert = async (uid, input, options = { skipChecks: false }) => { const { tid } = context; return { tid, count: 0 }; } else if (context.context) { - chain = Array.from(await activitypub.contexts.getItems(uid, context.context)); + chain = Array.from(await activitypub.contexts.getItems(uid, context.context, { input })); } else { // Fall back to inReplyTo traversal chain = Array.from(await Notes.getParentChain(uid, input));