fix: use URL-hash ID for Mastodon account route guards
Deploy Indiekit Server / deploy (push) Successful in 1m23s
Deploy Indiekit Server / deploy (push) Successful in 1m23s
Mastodon API GET /accounts/:id/followers and /following always returned [] because the guards compared profile._id.toString() against the client-provided id, which comes from verify_credentials via remoteActorId(profile.url) — a sha256 hash. ObjectId and hash never match. Patch ap-accounts-id-hash replaces profile._id.toString() with remoteActorId(profile.url) in all three affected account routes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -103,4 +103,53 @@ for (const f of OG_CANDIDATES) {
|
||||
}
|
||||
if (!ogDone) console.log(`[postinstall] ${SCRIPT}: ap-og-image — no target file found or no changes`);
|
||||
|
||||
// ── patch-ap-accounts-id-hash: use URL-hash ID instead of MongoDB _id ─────────
|
||||
// GET /api/v1/accounts/:id, /followers, /following all checked profile._id.toString()
|
||||
// against the client-provided id, but verify_credentials returns remoteActorId(profile.url)
|
||||
// (sha256 hash). The ObjectId and the hash never match → followers/following always [].
|
||||
|
||||
const HASH_MARKER = "// [patch] ap-accounts-id-hash";
|
||||
const ACCOUNTS_CANDIDATES = apPath("lib/mastodon/routes/accounts.js");
|
||||
|
||||
const HASH_PATCHES = [
|
||||
{
|
||||
old: ` if (profile && profile._id.toString() === id) {`,
|
||||
new: ` if (profile && remoteActorId(profile.url) === id) { ${HASH_MARKER}`,
|
||||
},
|
||||
{
|
||||
old: ` // Only serve followers for the local account\n if (!profile || profile._id.toString() !== id) {`,
|
||||
new: ` // Only serve followers for the local account\n if (!profile || remoteActorId(profile.url) !== id) { ${HASH_MARKER}`,
|
||||
},
|
||||
{
|
||||
old: ` // Only serve following for the local account\n if (!profile || profile._id.toString() !== id) {`,
|
||||
new: ` // Only serve following for the local account\n if (!profile || remoteActorId(profile.url) !== id) { ${HASH_MARKER}`,
|
||||
},
|
||||
];
|
||||
|
||||
let hashDone = false;
|
||||
for (const f of ACCOUNTS_CANDIDATES) {
|
||||
if (!(await fileExists(f))) continue;
|
||||
const src = await readFile(f, "utf8");
|
||||
if (src.includes(HASH_MARKER)) {
|
||||
console.log(`[postinstall] ${SCRIPT}: ap-accounts-id-hash already applied in ${f}`);
|
||||
hashDone = true; break;
|
||||
}
|
||||
let updated = src;
|
||||
let changed = false;
|
||||
for (const { old, new: replacement } of HASH_PATCHES) {
|
||||
if (updated.includes(old)) {
|
||||
updated = updated.replace(old, replacement);
|
||||
changed = true;
|
||||
} else {
|
||||
console.warn(`[postinstall] ${SCRIPT}: ap-accounts-id-hash — snippet not found in ${f}: ${old.slice(0, 60)}...`);
|
||||
}
|
||||
}
|
||||
if (changed && updated !== src) {
|
||||
await writeFile(f, updated, "utf8");
|
||||
console.log(`[postinstall] ${SCRIPT}: applied ap-accounts-id-hash to ${f}`);
|
||||
total++; hashDone = true; break;
|
||||
}
|
||||
}
|
||||
if (!hashDone) console.log(`[postinstall] ${SCRIPT}: ap-accounts-id-hash — no target file found or no changes`);
|
||||
|
||||
console.log(`[postinstall] ${SCRIPT}: done (${total} patch(es) applied)`);
|
||||
|
||||
Reference in New Issue
Block a user