The Fedify object dispatcher constructs the post lookup URL from the
{+id} path variable (e.g. "replies/bd78a"), which has no trailing slash.
Posts in MongoDB store their URL with a trailing slash, so the exact
findOne() match was silently returning null → Fedify serving 404 →
mountains.social showing "Could not connect to the given address".
Fix uses $in to try both variants so the dispatcher works regardless
of whether the request URL has a trailing slash or not.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
82 lines
2.6 KiB
JavaScript
82 lines
2.6 KiB
JavaScript
/**
|
|
* Patch: make the Fedify object dispatcher's post lookup tolerate trailing-slash
|
|
* differences between the AP object URL and the stored post URL.
|
|
*
|
|
* Root cause:
|
|
* setupObjectDispatchers resolvePost() builds postUrl from the {+id} template
|
|
* variable (e.g. "replies/bd78a") and does an exact findOne() match against
|
|
* posts.properties.url. Posts in MongoDB are stored with a trailing slash
|
|
* ("https://blog.giersig.eu/replies/bd78a/"), but the AP object URL returned
|
|
* by the /api/ap-url lookup endpoint has no trailing slash. The exact match
|
|
* fails → Fedify returns 404 → remote instance shows "Could not connect".
|
|
*
|
|
* Fix:
|
|
* Replace the single-value findOne() with a $in query that tries both the
|
|
* bare URL and the URL with a trailing slash appended.
|
|
*/
|
|
|
|
import { access, readFile, writeFile } from "node:fs/promises";
|
|
|
|
const candidates = [
|
|
"node_modules/@rmdes/indiekit-endpoint-activitypub/lib/federation-setup.js",
|
|
"node_modules/@indiekit/indiekit/node_modules/@rmdes/indiekit-endpoint-activitypub/lib/federation-setup.js",
|
|
];
|
|
|
|
const MARKER = "// trailing-slash url fix";
|
|
|
|
const OLD_SNIPPET = ` const postUrl = \`\${publicationUrl.replace(/\\/$/, "")}/\${id}\`;
|
|
const post = await collections.posts.findOne({ "properties.url": postUrl });`;
|
|
|
|
const NEW_SNIPPET = ` const postUrl = \`\${publicationUrl.replace(/\\/$/, "")}/\${id}\`; // trailing-slash url fix
|
|
const post = await collections.posts.findOne({
|
|
"properties.url": { $in: [postUrl, postUrl + "/"] },
|
|
});`;
|
|
|
|
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)) {
|
|
continue;
|
|
}
|
|
|
|
if (!source.includes(OLD_SNIPPET)) {
|
|
console.log(`[postinstall] patch-ap-object-url-trailing-slash: snippet not found in ${filePath}`);
|
|
continue;
|
|
}
|
|
|
|
const updated = source.replace(OLD_SNIPPET, NEW_SNIPPET);
|
|
|
|
if (updated === source) {
|
|
continue;
|
|
}
|
|
|
|
await writeFile(filePath, updated, "utf8");
|
|
patched += 1;
|
|
console.log(`[postinstall] Applied patch-ap-object-url-trailing-slash to ${filePath}`);
|
|
}
|
|
|
|
if (checked === 0) {
|
|
console.log("[postinstall] patch-ap-object-url-trailing-slash: no target files found");
|
|
} else if (patched === 0) {
|
|
console.log("[postinstall] patch-ap-object-url-trailing-slash: already up to date");
|
|
} else {
|
|
console.log(`[postinstall] patch-ap-object-url-trailing-slash: patched ${patched}/${checked} file(s)`);
|
|
}
|