121 lines
4.1 KiB
JavaScript
121 lines
4.1 KiB
JavaScript
/**
|
|
* Patch: guard sendActivity calls in likePost and boostPost with try/catch.
|
|
*
|
|
* Root cause:
|
|
* - likePost: `ctx.sendActivity({ identifier }, recipient, like, ...)` is not
|
|
* wrapped in try/catch. If Fedify or the underlying queue (Redis) throws, the
|
|
* error propagates up through the route handler → 500, and the ap_interactions
|
|
* DB write that follows is never reached (like not recorded locally either).
|
|
*
|
|
* - boostPost: `ctx.sendActivity({ identifier }, "followers", announce, ...)` is
|
|
* the very first await in the function — also not wrapped. Same consequence:
|
|
* any delivery error aborts the function before the DB write, returning 500.
|
|
*
|
|
* Fix:
|
|
* Wrap both sendActivity calls in try/catch so federation delivery failures are
|
|
* non-fatal. The interaction is still recorded in ap_interactions so the client
|
|
* sees the correct UI state. Delivery of the boost to the original post author is
|
|
* already guarded (separate try/catch added previously).
|
|
*/
|
|
|
|
import { access, readFile, writeFile } from "node:fs/promises";
|
|
|
|
const MARKER = "// [patch] ap-interactions-send-guard";
|
|
|
|
const candidates = [
|
|
"node_modules/@rmdes/indiekit-endpoint-activitypub/lib/mastodon/helpers/interactions.js",
|
|
"node_modules/@indiekit/indiekit/node_modules/@rmdes/indiekit-endpoint-activitypub/lib/mastodon/helpers/interactions.js",
|
|
];
|
|
|
|
// ── Change 1: guard likePost sendActivity ─────────────────────────────────────
|
|
|
|
const OLD_LIKE_SEND = ` if (recipient) {
|
|
await ctx.sendActivity({ identifier: handle }, recipient, like, {
|
|
orderingKey: targetUrl,
|
|
});
|
|
}`;
|
|
|
|
const NEW_LIKE_SEND = ` if (recipient) {
|
|
try { ${MARKER}
|
|
await ctx.sendActivity({ identifier: handle }, recipient, like, {
|
|
orderingKey: targetUrl,
|
|
});
|
|
} catch { /* delivery failed — interaction still recorded locally */ }
|
|
}`;
|
|
|
|
// ── Change 2: guard boostPost sendActivity("followers") ──────────────────────
|
|
|
|
const OLD_BOOST_SEND = ` // Send to followers
|
|
await ctx.sendActivity({ identifier: handle }, "followers", announce, {
|
|
preferSharedInbox: true,
|
|
syncCollection: true,
|
|
orderingKey: targetUrl,
|
|
});`;
|
|
|
|
const NEW_BOOST_SEND = ` // Send to followers
|
|
try { ${MARKER}
|
|
await ctx.sendActivity({ identifier: handle }, "followers", announce, {
|
|
preferSharedInbox: true,
|
|
syncCollection: true,
|
|
orderingKey: targetUrl,
|
|
});
|
|
} catch { /* delivery failed — interaction still recorded locally */ }`;
|
|
|
|
async function exists(filePath) {
|
|
try {
|
|
await access(filePath);
|
|
return true;
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
let checked = 0;
|
|
let patched = 0;
|
|
|
|
for (const filePath of candidates) {
|
|
if (!(await exists(filePath))) continue;
|
|
checked += 1;
|
|
|
|
const source = await readFile(filePath, "utf8");
|
|
|
|
if (source.includes(MARKER)) {
|
|
console.log(`[postinstall] patch-ap-interactions-send-guard: already applied to ${filePath}`);
|
|
continue;
|
|
}
|
|
|
|
let updated = source;
|
|
let changes = 0;
|
|
|
|
if (!updated.includes(OLD_LIKE_SEND)) {
|
|
console.warn(`[postinstall] patch-ap-interactions-send-guard: likePost snippet not found in ${filePath}`);
|
|
} else {
|
|
updated = updated.replace(OLD_LIKE_SEND, NEW_LIKE_SEND);
|
|
changes++;
|
|
}
|
|
|
|
if (!updated.includes(OLD_BOOST_SEND)) {
|
|
console.warn(`[postinstall] patch-ap-interactions-send-guard: boostPost snippet not found in ${filePath}`);
|
|
} else {
|
|
updated = updated.replace(OLD_BOOST_SEND, NEW_BOOST_SEND);
|
|
changes++;
|
|
}
|
|
|
|
if (changes === 0) {
|
|
console.log(`[postinstall] patch-ap-interactions-send-guard: no changes in ${filePath}`);
|
|
continue;
|
|
}
|
|
|
|
await writeFile(filePath, updated, "utf8");
|
|
patched += 1;
|
|
console.log(`[postinstall] Applied patch-ap-interactions-send-guard to ${filePath} (${changes}/2 changes)`);
|
|
}
|
|
|
|
if (checked === 0) {
|
|
console.log("[postinstall] patch-ap-interactions-send-guard: no target files found");
|
|
} else if (patched === 0) {
|
|
console.log("[postinstall] patch-ap-interactions-send-guard: already up to date");
|
|
} else {
|
|
console.log(`[postinstall] patch-ap-interactions-send-guard: patched ${patched} file(s)`);
|
|
}
|