fix: assert actors on note assertion, resolve crash if announcing something that's already been announced

This commit is contained in:
Julian Lam
2024-02-20 11:57:50 -05:00
parent 0edaf17c6a
commit 6a7f8f146f
2 changed files with 18 additions and 5 deletions

View File

@@ -28,9 +28,12 @@ Actors.assert = async (ids, options = {}) => {
return true; return true;
} }
winston.verbose(`[activitypub/actors] Asserting ${ids.length} actor(s)`);
const followersUrlMap = new Map(); const followersUrlMap = new Map();
const actors = await Promise.all(ids.map(async (id) => { const actors = await Promise.all(ids.map(async (id) => {
try { try {
winston.verbose(`[activitypub/actors] Processing ${id}`);
const actor = (typeof id === 'object' && id.hasOwnProperty('id')) ? id : await activitypub.get('uid', 0, id); const actor = (typeof id === 'object' && id.hasOwnProperty('id')) ? id : await activitypub.get('uid', 0, id);
// Follow counts // Follow counts

View File

@@ -23,6 +23,8 @@ Notes.resolveId = async (uid, id) => {
// also, db.exists call is probably expensive // also, db.exists call is probably expensive
Notes.assert = async (uid, input, options = {}) => { Notes.assert = async (uid, input, options = {}) => {
// Ensures that each note has been saved to the database // Ensures that each note has been saved to the database
const actors = new Set();
await Promise.all(input.map(async (item) => { await Promise.all(input.map(async (item) => {
let id = activitypub.helpers.isUri(item) ? item : item.pid; let id = activitypub.helpers.isUri(item) ? item : item.pid;
id = await Notes.resolveId(uid, id); id = await Notes.resolveId(uid, id);
@@ -36,15 +38,19 @@ Notes.assert = async (uid, input, options = {}) => {
if (activitypub.helpers.isUri(item)) { if (activitypub.helpers.isUri(item)) {
// get failure throws for now but should save intermediate object // get failure throws for now but should save intermediate object
const object = await activitypub.get('uid', uid, item); const object = await activitypub.get('uid', uid, item);
actors.add(object.attributedTo);
postData = await activitypub.mocks.post(object); postData = await activitypub.mocks.post(object);
} else { } else {
postData = item; postData = item;
actors.add(item.uid);
} }
// Parse ActivityPub-specific data // Parse ActivityPub-specific data if exists (if not, was parsed already)
if (postData.hasOwnProperty('_activityPub')) {
const { to, cc, attachment } = postData._activitypub; const { to, cc, attachment } = postData._activitypub;
await Notes.updateLocalRecipients(id, { to, cc }); await Notes.updateLocalRecipients(id, { to, cc });
await Notes.saveAttachments(id, attachment); await Notes.saveAttachments(id, attachment);
}
const hash = { ...postData }; const hash = { ...postData };
delete hash._activitypub; delete hash._activitypub;
@@ -58,6 +64,10 @@ Notes.assert = async (uid, input, options = {}) => {
// pubsub.publish('post:edit', String(id)); // pubsub.publish('post:edit', String(id));
// } // }
})); }));
if (actors.size) {
activitypub.actors.assert(Array.from(actors));
}
}; };
Notes.updateLocalRecipients = async (id, { to, cc }) => { Notes.updateLocalRecipients = async (id, { to, cc }) => {
@@ -98,7 +108,7 @@ Notes.saveAttachments = async (id, attachments) => {
}, },
}; };
attachments.filter(Boolean).map(({ mediaType, url, name, width, height }, idx) => { attachments.filter(Boolean).forEach(({ mediaType, url, name, width, height }, idx) => {
if (!url) { // only required property if (!url) { // only required property
return; return;
} }