fix(backfill-timeline): exclude unlisted posts from ap_timeline on startup
backfillTimeline() runs on every Indiekit restart and backfills ap_timeline
from the posts collection. The query had no visibility filter, so unlisted
posts (e.g. Swarm checkins) were inserted into ap_timeline and became visible
in Mastodon API timelines (Phanpy/Elk).
Root cause traced via ObjectId timestamp: bc625 ap_timeline entry was created
at restart time (20:56 UTC), not via the syndicator (which already had an
unlisted guard). The backfill ran on startup and inserted the post.
Fix: add 'properties.visibility': { $ne: 'unlisted' } to the posts.find()
query in backfill-timeline.js. Also deleted 18 existing unlisted posts from
ap_timeline (cleanup applied directly on server).
This commit is contained in:
@@ -2,13 +2,39 @@ import { access, readFile, writeFile } from "node:fs/promises";
|
|||||||
|
|
||||||
// activitypub index.js and federation-setup.js unlisted guards are now
|
// activitypub index.js and federation-setup.js unlisted guards are now
|
||||||
// built into the fork — only endpoint-syndicate (separate package) needs patching.
|
// built into the fork — only endpoint-syndicate (separate package) needs patching.
|
||||||
|
// backfill-timeline.js also needs patching — it runs on every startup and
|
||||||
|
// backfills ap_timeline from posts without filtering unlisted posts.
|
||||||
|
|
||||||
const endpointSyndicateCandidates = [
|
const endpointSyndicateCandidates = [
|
||||||
"node_modules/@indiekit/endpoint-syndicate/lib/utils.js",
|
"node_modules/@indiekit/endpoint-syndicate/lib/utils.js",
|
||||||
"node_modules/@indiekit/indiekit/node_modules/@indiekit/endpoint-syndicate/lib/utils.js",
|
"node_modules/@indiekit/indiekit/node_modules/@indiekit/endpoint-syndicate/lib/utils.js",
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const backfillTimelineCandidates = [
|
||||||
|
"node_modules/@rmdes/indiekit-endpoint-activitypub/lib/mastodon/backfill-timeline.js",
|
||||||
|
];
|
||||||
|
|
||||||
const patchSpecs = [
|
const patchSpecs = [
|
||||||
|
{
|
||||||
|
name: "backfill-timeline-unlisted-guard",
|
||||||
|
candidates: backfillTimelineCandidates,
|
||||||
|
oldSnippet: ` const allPosts = await posts
|
||||||
|
.find({
|
||||||
|
"properties.post-status": { $ne: "draft" },
|
||||||
|
"properties.deleted": { $exists: false },
|
||||||
|
"properties.url": { $exists: true },
|
||||||
|
})
|
||||||
|
.toArray();`,
|
||||||
|
newSnippet: ` const allPosts = await posts
|
||||||
|
.find({
|
||||||
|
"properties.post-status": { $ne: "draft" },
|
||||||
|
"properties.deleted": { $exists: false },
|
||||||
|
"properties.url": { $exists: true },
|
||||||
|
// Exclude unlisted posts — they must not appear in ap_timeline (Mastodon API).
|
||||||
|
"properties.visibility": { $ne: "unlisted" },
|
||||||
|
})
|
||||||
|
.toArray();`,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "endpoint-syndicate-source-url-unlisted-guard",
|
name: "endpoint-syndicate-source-url-unlisted-guard",
|
||||||
candidates: endpointSyndicateCandidates,
|
candidates: endpointSyndicateCandidates,
|
||||||
|
|||||||
Reference in New Issue
Block a user