chore: remove AP enrich-actor + stubs patches now in fork source
Deploy Indiekit Server / deploy (push) Successful in 1m19s
Deploy Indiekit Server / deploy (push) Successful in 1m19s
Both patches are now in svemagie/indiekit-endpoint-activitypub@83d6af6: - enrich-actor-data (Fedify async getIcon/getImage + @user@domain handle) - stubs-remove-duplicate-routes (removed accounts/:id sub-routes from stubs.js) Updates package-lock.json to reference the new fork commit. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Generated
+1
-1
@@ -2419,7 +2419,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/@rmdes/indiekit-endpoint-activitypub": {
|
"node_modules/@rmdes/indiekit-endpoint-activitypub": {
|
||||||
"version": "3.13.4",
|
"version": "3.13.4",
|
||||||
"resolved": "git+https://gitea.giersig.eu/svemagie/indiekit-endpoint-activitypub#cfe35b28e834e22d15358ec6a061adc30fe65363",
|
"resolved": "git+https://gitea.giersig.eu/svemagie/indiekit-endpoint-activitypub#83d6af6cc92abbd41b16dd8ef9f84042a1c2eea0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fedify/debugger": "^2.1.0",
|
"@fedify/debugger": "^2.1.0",
|
||||||
|
|||||||
+2
-2
@@ -5,8 +5,8 @@
|
|||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"preinstall": "node scripts/setup-gitea-url-rewrite.mjs",
|
"preinstall": "node scripts/setup-gitea-url-rewrite.mjs",
|
||||||
"postinstall": "xattr -w com.apple.fileprovider.ignore#P 1 node_modules 2>/dev/null || true && node scripts/patch-lightningcss.mjs && node scripts/patch-endpoint-media-scope.mjs && node scripts/patch-endpoint-media-sharp-runtime.mjs && node scripts/patch-frontend-sharp-runtime.mjs && node scripts/patch-endpoint-files-upload-route.mjs && node scripts/patch-endpoint-files-upload-locales.mjs && node scripts/patch-endpoint-activitypub-locales.mjs && node scripts/patch-endpoint-homepage-locales.mjs && node scripts/patch-endpoint-homepage-identity-defaults.mjs && node scripts/patch-federation-unlisted-guards.mjs && node scripts/patch-endpoint-micropub-where-note-visibility.mjs && node scripts/patch-endpoint-podroll-opml-upload.mjs && node scripts/patch-frontend-serviceworker-file.mjs && node scripts/patch-endpoint-comments-locales.mjs && node scripts/patch-endpoint-posts-locales.mjs && node scripts/patch-endpoint-conversations-locales.mjs && node scripts/patch-conversations-collection-guards.mjs && node scripts/patch-indiekit-routes-rate-limits.mjs && node scripts/patch-indiekit-error-production-stack.mjs && node scripts/patch-indieauth-devmode-guard.mjs && node scripts/patch-listening-endpoint-runtime-guards.mjs && node scripts/patch-endpoint-github-changelog-categories.mjs && node scripts/patch-endpoint-github-contributions-log.mjs && node scripts/patch-store-github-error-message.mjs && node scripts/patch-store-github-update-fallback.mjs && node scripts/patch-store-github-gitea-methods.mjs && node scripts/patch-store-github-put-fallback.mjs && node scripts/patch-store-github-content-type.mjs && node scripts/patch-endpoint-blogroll-feeds-alias.mjs && node scripts/patch-endpoint-posts-uid-lookup.mjs && node scripts/patch-conversations-bluesky-self-filter.mjs && node scripts/patch-conversations-bluesky-cursor-fix.mjs && node scripts/patch-endpoint-micropub-source-filter.mjs && node scripts/patch-syndicate-force-checked-default.mjs && node scripts/patch-syndicate-normalize-syndication-array.mjs && node scripts/patch-endpoint-posts-fetch-diagnostic.mjs && node scripts/patch-micropub-fetch-internal-url.mjs && node scripts/patch-micropub-session-token.mjs && node scripts/patch-indiekit-endpoint-urls-protocol.mjs && node scripts/patch-webmention-sender-retry.mjs && node scripts/patch-webmention-sender-livefetch.mjs && node scripts/patch-webmention-sender-reset-stale.mjs && node scripts/patch-webmention-sender-empty-details.mjs && node scripts/patch-bluesky-syndicator-internal-url.mjs && node scripts/patch-bluesky-syndicator-media-type-guard.mjs && node scripts/patch-bluesky-og-own-post-title.mjs && node scripts/patch-bluesky-syndicator-delete.mjs && node scripts/patch-micropub-delete-propagation.mjs && node scripts/patch-micropub-category-from-posts.mjs && node scripts/patch-tag-input-autocomplete.mjs && node scripts/patch-microsub-compose-draft-guard.mjs && node scripts/patch-microsub-no-bookmark-autofollow.mjs && node scripts/patch-microsub-reader-ap-dispatch.mjs && node scripts/patch-microsub-batch-concurrency.mjs && node scripts/patch-ap-enrich-actor-data.mjs && node scripts/patch-ap-stubs-remove-duplicate-routes.mjs && node scripts/patch-session-maxage.mjs",
|
"postinstall": "xattr -w com.apple.fileprovider.ignore#P 1 node_modules 2>/dev/null || true && node scripts/patch-lightningcss.mjs && node scripts/patch-endpoint-media-scope.mjs && node scripts/patch-endpoint-media-sharp-runtime.mjs && node scripts/patch-frontend-sharp-runtime.mjs && node scripts/patch-endpoint-files-upload-route.mjs && node scripts/patch-endpoint-files-upload-locales.mjs && node scripts/patch-endpoint-activitypub-locales.mjs && node scripts/patch-endpoint-homepage-locales.mjs && node scripts/patch-endpoint-homepage-identity-defaults.mjs && node scripts/patch-federation-unlisted-guards.mjs && node scripts/patch-endpoint-micropub-where-note-visibility.mjs && node scripts/patch-endpoint-podroll-opml-upload.mjs && node scripts/patch-frontend-serviceworker-file.mjs && node scripts/patch-endpoint-comments-locales.mjs && node scripts/patch-endpoint-posts-locales.mjs && node scripts/patch-endpoint-conversations-locales.mjs && node scripts/patch-conversations-collection-guards.mjs && node scripts/patch-indiekit-routes-rate-limits.mjs && node scripts/patch-indiekit-error-production-stack.mjs && node scripts/patch-indieauth-devmode-guard.mjs && node scripts/patch-listening-endpoint-runtime-guards.mjs && node scripts/patch-endpoint-github-changelog-categories.mjs && node scripts/patch-endpoint-github-contributions-log.mjs && node scripts/patch-store-github-error-message.mjs && node scripts/patch-store-github-update-fallback.mjs && node scripts/patch-store-github-gitea-methods.mjs && node scripts/patch-store-github-put-fallback.mjs && node scripts/patch-store-github-content-type.mjs && node scripts/patch-endpoint-blogroll-feeds-alias.mjs && node scripts/patch-endpoint-posts-uid-lookup.mjs && node scripts/patch-conversations-bluesky-self-filter.mjs && node scripts/patch-conversations-bluesky-cursor-fix.mjs && node scripts/patch-endpoint-micropub-source-filter.mjs && node scripts/patch-syndicate-force-checked-default.mjs && node scripts/patch-syndicate-normalize-syndication-array.mjs && node scripts/patch-endpoint-posts-fetch-diagnostic.mjs && node scripts/patch-micropub-fetch-internal-url.mjs && node scripts/patch-micropub-session-token.mjs && node scripts/patch-indiekit-endpoint-urls-protocol.mjs && node scripts/patch-webmention-sender-retry.mjs && node scripts/patch-webmention-sender-livefetch.mjs && node scripts/patch-webmention-sender-reset-stale.mjs && node scripts/patch-webmention-sender-empty-details.mjs && node scripts/patch-bluesky-syndicator-internal-url.mjs && node scripts/patch-bluesky-syndicator-media-type-guard.mjs && node scripts/patch-bluesky-og-own-post-title.mjs && node scripts/patch-bluesky-syndicator-delete.mjs && node scripts/patch-micropub-delete-propagation.mjs && node scripts/patch-micropub-category-from-posts.mjs && node scripts/patch-tag-input-autocomplete.mjs && node scripts/patch-microsub-compose-draft-guard.mjs && node scripts/patch-microsub-no-bookmark-autofollow.mjs && node scripts/patch-microsub-reader-ap-dispatch.mjs && node scripts/patch-microsub-batch-concurrency.mjs && node scripts/patch-session-maxage.mjs",
|
||||||
"serve": "export NODE_ENV=${NODE_ENV:-production} INDIEKIT_DEBUG=${INDIEKIT_DEBUG:-0} && node scripts/preflight-production-security.mjs && node scripts/preflight-mongo-connection.mjs && node scripts/preflight-activitypub-rsa-key.mjs && node scripts/preflight-activitypub-profile-urls.mjs && node scripts/preflight-startup-gate.mjs && node scripts/patch-lightningcss.mjs && node scripts/patch-endpoint-media-scope.mjs && node scripts/patch-endpoint-media-sharp-runtime.mjs && node scripts/patch-frontend-sharp-runtime.mjs && node scripts/patch-endpoint-files-upload-route.mjs && node scripts/patch-endpoint-files-upload-locales.mjs && node scripts/patch-endpoint-activitypub-locales.mjs && node scripts/patch-endpoint-homepage-locales.mjs && node scripts/patch-endpoint-homepage-identity-defaults.mjs && node scripts/patch-federation-unlisted-guards.mjs && node scripts/patch-endpoint-micropub-where-note-visibility.mjs && node scripts/patch-endpoint-podroll-opml-upload.mjs && node scripts/patch-frontend-serviceworker-file.mjs && node scripts/patch-endpoint-comments-locales.mjs && node scripts/patch-endpoint-posts-locales.mjs && node scripts/patch-endpoint-conversations-locales.mjs && node scripts/patch-conversations-collection-guards.mjs && node scripts/patch-indiekit-routes-rate-limits.mjs && node scripts/patch-indiekit-error-production-stack.mjs && node scripts/patch-indieauth-devmode-guard.mjs && node scripts/patch-listening-endpoint-runtime-guards.mjs && node scripts/patch-endpoint-github-changelog-categories.mjs && node scripts/patch-endpoint-github-contributions-log.mjs && node scripts/patch-store-github-error-message.mjs && node scripts/patch-store-github-update-fallback.mjs && node scripts/patch-store-github-gitea-methods.mjs && node scripts/patch-store-github-put-fallback.mjs && node scripts/patch-store-github-content-type.mjs && node scripts/patch-microsub-reader-ap-dispatch.mjs && node scripts/patch-microsub-compose-draft-guard.mjs && node scripts/patch-microsub-no-bookmark-autofollow.mjs && node scripts/patch-microsub-batch-concurrency.mjs && node scripts/patch-endpoint-blogroll-feeds-alias.mjs && node scripts/patch-endpoint-posts-uid-lookup.mjs && node scripts/patch-conversations-bluesky-self-filter.mjs && node scripts/patch-conversations-bluesky-cursor-fix.mjs && node scripts/patch-endpoint-micropub-source-filter.mjs && node scripts/patch-syndicate-force-checked-default.mjs && node scripts/patch-syndicate-normalize-syndication-array.mjs && node scripts/patch-endpoint-posts-fetch-diagnostic.mjs && node scripts/patch-micropub-fetch-internal-url.mjs && node scripts/patch-micropub-session-token.mjs && node scripts/patch-indiekit-endpoint-urls-protocol.mjs && node scripts/patch-webmention-sender-retry.mjs && node scripts/patch-webmention-sender-livefetch.mjs && node scripts/patch-webmention-sender-reset-stale.mjs && node scripts/patch-webmention-sender-empty-details.mjs && node scripts/patch-bluesky-syndicator-internal-url.mjs && node scripts/patch-bluesky-syndicator-media-type-guard.mjs && node scripts/patch-bluesky-og-own-post-title.mjs && node scripts/patch-bluesky-syndicator-delete.mjs && node scripts/patch-micropub-delete-propagation.mjs && node scripts/patch-micropub-category-from-posts.mjs && node scripts/patch-tag-input-autocomplete.mjs && node scripts/patch-ap-enrich-actor-data.mjs && node scripts/patch-ap-stubs-remove-duplicate-routes.mjs && node scripts/patch-session-maxage.mjs && node --max-old-space-size=1024 --max-semi-space-size=32 --require ./metrics-shim.cjs node_modules/@indiekit/indiekit/bin/cli.js serve --config indiekit.config.mjs",
|
"serve": "export NODE_ENV=${NODE_ENV:-production} INDIEKIT_DEBUG=${INDIEKIT_DEBUG:-0} && node scripts/preflight-production-security.mjs && node scripts/preflight-mongo-connection.mjs && node scripts/preflight-activitypub-rsa-key.mjs && node scripts/preflight-activitypub-profile-urls.mjs && node scripts/preflight-startup-gate.mjs && node scripts/patch-lightningcss.mjs && node scripts/patch-endpoint-media-scope.mjs && node scripts/patch-endpoint-media-sharp-runtime.mjs && node scripts/patch-frontend-sharp-runtime.mjs && node scripts/patch-endpoint-files-upload-route.mjs && node scripts/patch-endpoint-files-upload-locales.mjs && node scripts/patch-endpoint-activitypub-locales.mjs && node scripts/patch-endpoint-homepage-locales.mjs && node scripts/patch-endpoint-homepage-identity-defaults.mjs && node scripts/patch-federation-unlisted-guards.mjs && node scripts/patch-endpoint-micropub-where-note-visibility.mjs && node scripts/patch-endpoint-podroll-opml-upload.mjs && node scripts/patch-frontend-serviceworker-file.mjs && node scripts/patch-endpoint-comments-locales.mjs && node scripts/patch-endpoint-posts-locales.mjs && node scripts/patch-endpoint-conversations-locales.mjs && node scripts/patch-conversations-collection-guards.mjs && node scripts/patch-indiekit-routes-rate-limits.mjs && node scripts/patch-indiekit-error-production-stack.mjs && node scripts/patch-indieauth-devmode-guard.mjs && node scripts/patch-listening-endpoint-runtime-guards.mjs && node scripts/patch-endpoint-github-changelog-categories.mjs && node scripts/patch-endpoint-github-contributions-log.mjs && node scripts/patch-store-github-error-message.mjs && node scripts/patch-store-github-update-fallback.mjs && node scripts/patch-store-github-gitea-methods.mjs && node scripts/patch-store-github-put-fallback.mjs && node scripts/patch-store-github-content-type.mjs && node scripts/patch-microsub-reader-ap-dispatch.mjs && node scripts/patch-microsub-compose-draft-guard.mjs && node scripts/patch-microsub-no-bookmark-autofollow.mjs && node scripts/patch-microsub-batch-concurrency.mjs && node scripts/patch-endpoint-blogroll-feeds-alias.mjs && node scripts/patch-endpoint-posts-uid-lookup.mjs && node scripts/patch-conversations-bluesky-self-filter.mjs && node scripts/patch-conversations-bluesky-cursor-fix.mjs && node scripts/patch-endpoint-micropub-source-filter.mjs && node scripts/patch-syndicate-force-checked-default.mjs && node scripts/patch-syndicate-normalize-syndication-array.mjs && node scripts/patch-endpoint-posts-fetch-diagnostic.mjs && node scripts/patch-micropub-fetch-internal-url.mjs && node scripts/patch-micropub-session-token.mjs && node scripts/patch-indiekit-endpoint-urls-protocol.mjs && node scripts/patch-webmention-sender-retry.mjs && node scripts/patch-webmention-sender-livefetch.mjs && node scripts/patch-webmention-sender-reset-stale.mjs && node scripts/patch-webmention-sender-empty-details.mjs && node scripts/patch-bluesky-syndicator-internal-url.mjs && node scripts/patch-bluesky-syndicator-media-type-guard.mjs && node scripts/patch-bluesky-og-own-post-title.mjs && node scripts/patch-bluesky-syndicator-delete.mjs && node scripts/patch-micropub-delete-propagation.mjs && node scripts/patch-micropub-category-from-posts.mjs && node scripts/patch-tag-input-autocomplete.mjs && node scripts/patch-session-maxage.mjs && node --max-old-space-size=1024 --max-semi-space-size=32 --require ./metrics-shim.cjs node_modules/@indiekit/indiekit/bin/cli.js serve --config indiekit.config.mjs",
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
|
|||||||
@@ -1,237 +0,0 @@
|
|||||||
/**
|
|
||||||
* patch-ap-enrich-actor-data.mjs
|
|
||||||
*
|
|
||||||
* Fixes avatar and handle extraction in three code paths:
|
|
||||||
* 1. followActor() in index.js — outbound follow stores wrong handle + empty avatar
|
|
||||||
* 2. inbox-listeners.js — incoming Follow stores wrong handle + empty avatar
|
|
||||||
* 3. inbox-handlers.js — Update handler refreshes with wrong handle + empty avatar
|
|
||||||
*
|
|
||||||
* Root cause: All three use `remoteActor.preferredUsername` (no domain) for handle
|
|
||||||
* and `remoteActor.icon` (sync property, often falsy) for avatar.
|
|
||||||
* Fix: Use `getIcon()` async getter and build `@user@domain` from URL.
|
|
||||||
*/
|
|
||||||
import { readFileSync, writeFileSync } from "node:fs";
|
|
||||||
import { resolve } from "node:path";
|
|
||||||
|
|
||||||
const BASE = resolve("/usr/local/indiekit/node_modules/@rmdes/indiekit-endpoint-activitypub");
|
|
||||||
|
|
||||||
const patchSpecs = [
|
|
||||||
// ─── Patch 1: followActor() in index.js ─────────────────────────────────
|
|
||||||
{
|
|
||||||
name: "followActor-avatar-handle",
|
|
||||||
marker: "// [patch] ap-enrich-actor-follow",
|
|
||||||
candidates: [resolve(BASE, "index.js")],
|
|
||||||
oldSnippet: ` const actorHandle =
|
|
||||||
actorInfo.handle ||
|
|
||||||
remoteActor.preferredUsername?.toString() ||
|
|
||||||
"";
|
|
||||||
const avatar =
|
|
||||||
actorInfo.photo ||
|
|
||||||
(remoteActor.icon
|
|
||||||
? (await remoteActor.icon)?.url?.href || ""
|
|
||||||
: "");`,
|
|
||||||
newSnippet: ` // [patch] ap-enrich-actor-follow
|
|
||||||
let _enrichedAvatar = ""; // [patch] ap-enrich-actor-follow
|
|
||||||
try { // [patch] ap-enrich-actor-follow
|
|
||||||
if (typeof remoteActor.getIcon === "function") { // [patch] ap-enrich-actor-follow
|
|
||||||
const _iconObj = await remoteActor.getIcon(); // [patch] ap-enrich-actor-follow
|
|
||||||
_enrichedAvatar = _iconObj?.url?.href || ""; // [patch] ap-enrich-actor-follow
|
|
||||||
} // [patch] ap-enrich-actor-follow
|
|
||||||
} catch { /* icon fetch failed */ } // [patch] ap-enrich-actor-follow
|
|
||||||
let _enrichedHandle = ""; // [patch] ap-enrich-actor-follow
|
|
||||||
try { // [patch] ap-enrich-actor-follow
|
|
||||||
const _username = remoteActor.preferredUsername?.toString() || ""; // [patch] ap-enrich-actor-follow
|
|
||||||
if (_username && actorUrl) { // [patch] ap-enrich-actor-follow
|
|
||||||
const _domain = new URL(actorUrl).hostname; // [patch] ap-enrich-actor-follow
|
|
||||||
_enrichedHandle = \`@\${_username}@\${_domain}\`; // [patch] ap-enrich-actor-follow
|
|
||||||
} // [patch] ap-enrich-actor-follow
|
|
||||||
} catch { /* URL parse failed */ } // [patch] ap-enrich-actor-follow
|
|
||||||
let _enrichedBanner = ""; // [patch] ap-enrich-actor-follow
|
|
||||||
try { // [patch] ap-enrich-actor-follow
|
|
||||||
if (typeof remoteActor.getImage === "function") { // [patch] ap-enrich-actor-follow
|
|
||||||
const _imgObj = await remoteActor.getImage(); // [patch] ap-enrich-actor-follow
|
|
||||||
_enrichedBanner = _imgObj?.url?.href || ""; // [patch] ap-enrich-actor-follow
|
|
||||||
} // [patch] ap-enrich-actor-follow
|
|
||||||
} catch { /* banner fetch failed */ } // [patch] ap-enrich-actor-follow
|
|
||||||
const actorHandle = actorInfo.handle || _enrichedHandle || remoteActor.preferredUsername?.toString() || ""; // [patch] ap-enrich-actor-follow
|
|
||||||
const avatar = actorInfo.photo || _enrichedAvatar || ""; // [patch] ap-enrich-actor-follow`,
|
|
||||||
},
|
|
||||||
|
|
||||||
// ─── Patch 2: Also store banner in followActor updateOne ────────────────
|
|
||||||
{
|
|
||||||
name: "followActor-store-banner",
|
|
||||||
marker: "// [patch] ap-enrich-actor-follow-banner",
|
|
||||||
candidates: [resolve(BASE, "index.js")],
|
|
||||||
oldSnippet: ` sharedInbox,
|
|
||||||
followedAt: new Date().toISOString(),
|
|
||||||
source: "reader",`,
|
|
||||||
newSnippet: ` sharedInbox,
|
|
||||||
banner: _enrichedBanner || "", // [patch] ap-enrich-actor-follow-banner
|
|
||||||
followedAt: new Date().toISOString(),
|
|
||||||
source: "reader",`,
|
|
||||||
},
|
|
||||||
|
|
||||||
// ─── Patch 3: inbox-listeners.js follower creation ──────────────────────
|
|
||||||
{
|
|
||||||
name: "inbox-listeners-follower-avatar-handle",
|
|
||||||
marker: "// [patch] ap-enrich-follower-data",
|
|
||||||
candidates: [resolve(BASE, "lib/inbox-listeners.js")],
|
|
||||||
oldSnippet: ` const followerData = {
|
|
||||||
actorUrl: followerUrl,
|
|
||||||
handle: followerActor.preferredUsername?.toString() || "",
|
|
||||||
name: followerName,
|
|
||||||
avatar: followerActor.icon
|
|
||||||
? (await followerActor.icon)?.url?.href || ""
|
|
||||||
: "",
|
|
||||||
inbox: followerActor.inbox?.id?.href || "",
|
|
||||||
sharedInbox: followerActor.endpoints?.sharedInbox?.href || "",
|
|
||||||
};`,
|
|
||||||
newSnippet: ` // Enrich avatar and handle using proper Fedify async getters // [patch] ap-enrich-follower-data
|
|
||||||
let _fAvatar = ""; // [patch] ap-enrich-follower-data
|
|
||||||
try { // [patch] ap-enrich-follower-data
|
|
||||||
if (typeof followerActor.getIcon === "function") { // [patch] ap-enrich-follower-data
|
|
||||||
const _fIcon = await followerActor.getIcon(); // [patch] ap-enrich-follower-data
|
|
||||||
_fAvatar = _fIcon?.url?.href || ""; // [patch] ap-enrich-follower-data
|
|
||||||
} // [patch] ap-enrich-follower-data
|
|
||||||
} catch { /* icon fetch failed */ } // [patch] ap-enrich-follower-data
|
|
||||||
let _fHandle = ""; // [patch] ap-enrich-follower-data
|
|
||||||
try { // [patch] ap-enrich-follower-data
|
|
||||||
const _fUsername = followerActor.preferredUsername?.toString() || ""; // [patch] ap-enrich-follower-data
|
|
||||||
if (_fUsername && followerUrl) { // [patch] ap-enrich-follower-data
|
|
||||||
const _fDomain = new URL(followerUrl).hostname; // [patch] ap-enrich-follower-data
|
|
||||||
_fHandle = \`@\${_fUsername}@\${_fDomain}\`; // [patch] ap-enrich-follower-data
|
|
||||||
} // [patch] ap-enrich-follower-data
|
|
||||||
} catch { /* URL parse failed */ } // [patch] ap-enrich-follower-data
|
|
||||||
let _fBanner = ""; // [patch] ap-enrich-follower-data
|
|
||||||
try { // [patch] ap-enrich-follower-data
|
|
||||||
if (typeof followerActor.getImage === "function") { // [patch] ap-enrich-follower-data
|
|
||||||
const _fImg = await followerActor.getImage(); // [patch] ap-enrich-follower-data
|
|
||||||
_fBanner = _fImg?.url?.href || ""; // [patch] ap-enrich-follower-data
|
|
||||||
} // [patch] ap-enrich-follower-data
|
|
||||||
} catch { /* banner fetch failed */ } // [patch] ap-enrich-follower-data
|
|
||||||
const followerData = { // [patch] ap-enrich-follower-data
|
|
||||||
actorUrl: followerUrl,
|
|
||||||
handle: _fHandle || followerActor.preferredUsername?.toString() || "",
|
|
||||||
name: followerName,
|
|
||||||
avatar: _fAvatar,
|
|
||||||
banner: _fBanner,
|
|
||||||
inbox: followerActor.inbox?.id?.href || "",
|
|
||||||
sharedInbox: followerActor.endpoints?.sharedInbox?.href || "",
|
|
||||||
};`,
|
|
||||||
},
|
|
||||||
|
|
||||||
// ─── Patch 4: inbox-handlers.js Update handler ─────────────────────────
|
|
||||||
{
|
|
||||||
name: "inbox-handlers-update-avatar-handle",
|
|
||||||
marker: "// [patch] ap-enrich-update-handler",
|
|
||||||
candidates: [resolve(BASE, "lib/inbox-handlers.js")],
|
|
||||||
oldSnippet: ` const existing = await collections.ap_followers.findOne({ actorUrl });
|
|
||||||
if (existing) {
|
|
||||||
await collections.ap_followers.updateOne(
|
|
||||||
{ actorUrl },
|
|
||||||
{
|
|
||||||
$set: {
|
|
||||||
name:
|
|
||||||
actorObj.name?.toString() ||
|
|
||||||
actorObj.preferredUsername?.toString() ||
|
|
||||||
actorUrl,
|
|
||||||
handle: actorObj.preferredUsername?.toString() || "",
|
|
||||||
avatar: actorObj.icon
|
|
||||||
? (await actorObj.icon)?.url?.href || ""
|
|
||||||
: "",
|
|
||||||
updatedAt: new Date().toISOString(),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}`,
|
|
||||||
newSnippet: ` const existing = await collections.ap_followers.findOne({ actorUrl });
|
|
||||||
if (existing) { // [patch] ap-enrich-update-handler
|
|
||||||
let _uAvatar = ""; // [patch] ap-enrich-update-handler
|
|
||||||
try { // [patch] ap-enrich-update-handler
|
|
||||||
if (typeof actorObj.getIcon === "function") { // [patch] ap-enrich-update-handler
|
|
||||||
const _uIcon = await actorObj.getIcon(); // [patch] ap-enrich-update-handler
|
|
||||||
_uAvatar = _uIcon?.url?.href || ""; // [patch] ap-enrich-update-handler
|
|
||||||
} // [patch] ap-enrich-update-handler
|
|
||||||
} catch { /* icon fetch failed */ } // [patch] ap-enrich-update-handler
|
|
||||||
let _uHandle = ""; // [patch] ap-enrich-update-handler
|
|
||||||
try { // [patch] ap-enrich-update-handler
|
|
||||||
const _uUsername = actorObj.preferredUsername?.toString() || ""; // [patch] ap-enrich-update-handler
|
|
||||||
if (_uUsername && actorUrl) { // [patch] ap-enrich-update-handler
|
|
||||||
const _uDomain = new URL(actorUrl).hostname; // [patch] ap-enrich-update-handler
|
|
||||||
_uHandle = \`@\${_uUsername}@\${_uDomain}\`; // [patch] ap-enrich-update-handler
|
|
||||||
} // [patch] ap-enrich-update-handler
|
|
||||||
} catch { /* URL parse failed */ } // [patch] ap-enrich-update-handler
|
|
||||||
let _uBanner = ""; // [patch] ap-enrich-update-handler
|
|
||||||
try { // [patch] ap-enrich-update-handler
|
|
||||||
if (typeof actorObj.getImage === "function") { // [patch] ap-enrich-update-handler
|
|
||||||
const _uImg = await actorObj.getImage(); // [patch] ap-enrich-update-handler
|
|
||||||
_uBanner = _uImg?.url?.href || ""; // [patch] ap-enrich-update-handler
|
|
||||||
} // [patch] ap-enrich-update-handler
|
|
||||||
} catch { /* banner fetch failed */ } // [patch] ap-enrich-update-handler
|
|
||||||
const _updateFields = { // [patch] ap-enrich-update-handler
|
|
||||||
name: actorObj.name?.toString() || actorObj.preferredUsername?.toString() || actorUrl,
|
|
||||||
handle: _uHandle || actorObj.preferredUsername?.toString() || "",
|
|
||||||
avatar: _uAvatar,
|
|
||||||
updatedAt: new Date().toISOString(),
|
|
||||||
}; // [patch] ap-enrich-update-handler
|
|
||||||
if (_uBanner) _updateFields.banner = _uBanner; // [patch] ap-enrich-update-handler
|
|
||||||
await collections.ap_followers.updateOne( // [patch] ap-enrich-update-handler
|
|
||||||
{ actorUrl },
|
|
||||||
{ $set: _updateFields },
|
|
||||||
);
|
|
||||||
// Also update ap_following if we follow this actor // [patch] ap-enrich-update-handler
|
|
||||||
const existingFollowing = await collections.ap_following.findOne({ actorUrl }); // [patch] ap-enrich-update-handler
|
|
||||||
if (existingFollowing) { // [patch] ap-enrich-update-handler
|
|
||||||
await collections.ap_following.updateOne( // [patch] ap-enrich-update-handler
|
|
||||||
{ actorUrl }, // [patch] ap-enrich-update-handler
|
|
||||||
{ $set: _updateFields }, // [patch] ap-enrich-update-handler
|
|
||||||
); // [patch] ap-enrich-update-handler
|
|
||||||
} // [patch] ap-enrich-update-handler
|
|
||||||
}
|
|
||||||
}`,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
let applied = 0;
|
|
||||||
let skipped = 0;
|
|
||||||
|
|
||||||
for (const spec of patchSpecs) {
|
|
||||||
const { name, marker, candidates, oldSnippet, newSnippet } = spec;
|
|
||||||
|
|
||||||
let targetFile = null;
|
|
||||||
for (const candidate of candidates) {
|
|
||||||
try {
|
|
||||||
readFileSync(candidate, "utf8");
|
|
||||||
targetFile = candidate;
|
|
||||||
break;
|
|
||||||
} catch { /* try next */ }
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!targetFile) {
|
|
||||||
console.warn(`[${name}] No target file found among candidates`);
|
|
||||||
skipped++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const content = readFileSync(targetFile, "utf8");
|
|
||||||
|
|
||||||
if (content.includes(marker)) {
|
|
||||||
console.log(`[${name}] Already applied (marker found), skipping`);
|
|
||||||
skipped++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!content.includes(oldSnippet)) {
|
|
||||||
console.warn(`[${name}] Old snippet not found in ${targetFile}`);
|
|
||||||
skipped++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const patched = content.replace(oldSnippet, newSnippet);
|
|
||||||
writeFileSync(targetFile, patched, "utf8");
|
|
||||||
console.log(`[${name}] ✅ Patched ${targetFile}`);
|
|
||||||
applied++;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(`\nDone: ${applied} applied, ${skipped} skipped`);
|
|
||||||
@@ -1,108 +0,0 @@
|
|||||||
/**
|
|
||||||
* patch-ap-stubs-remove-duplicate-routes.mjs
|
|
||||||
*
|
|
||||||
* Removes duplicate account sub-routes from stubs.js that are already
|
|
||||||
* properly implemented in accounts.js. Since accountsRouter is registered
|
|
||||||
* before stubsRouter in router.js, these are dead code that could confuse
|
|
||||||
* maintenance.
|
|
||||||
*
|
|
||||||
* Removes:
|
|
||||||
* - GET /api/v1/accounts/:id/statuses (duplicate of accounts.js)
|
|
||||||
* - GET /api/v1/accounts/:id/followers (duplicate of accounts.js)
|
|
||||||
* - GET /api/v1/accounts/:id/following (duplicate of accounts.js)
|
|
||||||
*/
|
|
||||||
import { readFileSync, writeFileSync } from "node:fs";
|
|
||||||
import { resolve } from "node:path";
|
|
||||||
|
|
||||||
const MARKER = "// [patch] ap-stubs-dedup-account-routes";
|
|
||||||
const TARGET = resolve(
|
|
||||||
"/usr/local/indiekit/node_modules/@rmdes/indiekit-endpoint-activitypub/lib/mastodon/routes/stubs.js",
|
|
||||||
);
|
|
||||||
|
|
||||||
let content;
|
|
||||||
try {
|
|
||||||
content = readFileSync(TARGET, "utf8");
|
|
||||||
} catch {
|
|
||||||
console.warn("Target file not found:", TARGET);
|
|
||||||
process.exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (content.includes(MARKER)) {
|
|
||||||
console.log("Already applied (marker found), skipping");
|
|
||||||
process.exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove the duplicate /api/v1/accounts/:id/statuses handler
|
|
||||||
const statusesBlock = `// ─── Account statuses ───────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
router.get("/api/v1/accounts/:id/statuses", async (req, res, next) => {
|
|
||||||
try {
|
|
||||||
const collections = req.app.locals.mastodonCollections;
|
|
||||||
const baseUrl = \`\${req.protocol}://\${req.get("host")}\`;
|
|
||||||
|
|
||||||
// Try to find the profile to see if this is the local user
|
|
||||||
const profile = await collections.ap_profile.findOne({});
|
|
||||||
const isLocal = profile && profile._id.toString() === req.params.id;
|
|
||||||
|
|
||||||
if (isLocal && profile?.url) {
|
|
||||||
// Return statuses authored by local user
|
|
||||||
const { serializeStatus } = await import("../entities/status.js");
|
|
||||||
const { parseLimit } = await import("../helpers/pagination.js");
|
|
||||||
|
|
||||||
const limit = parseLimit(req.query.limit);
|
|
||||||
const items = await collections.ap_timeline
|
|
||||||
.find({ "author.url": profile.url, isContext: { $ne: true } })
|
|
||||||
.sort({ _id: -1 })
|
|
||||||
.limit(limit)
|
|
||||||
.toArray();
|
|
||||||
|
|
||||||
const statuses = items.map((item) =>
|
|
||||||
serializeStatus(item, {
|
|
||||||
baseUrl,
|
|
||||||
favouritedIds: new Set(),
|
|
||||||
rebloggedIds: new Set(),
|
|
||||||
bookmarkedIds: new Set(),
|
|
||||||
pinnedIds: new Set(),
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
return res.json(statuses);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remote account or unknown — return empty
|
|
||||||
res.json([]);
|
|
||||||
} catch (error) {
|
|
||||||
next(error);
|
|
||||||
}
|
|
||||||
});`;
|
|
||||||
|
|
||||||
const followersBlock = `// ─── Account followers/following ────────────────────────────────────────────
|
|
||||||
|
|
||||||
router.get("/api/v1/accounts/:id/followers", (req, res) => {
|
|
||||||
res.json([]);
|
|
||||||
});
|
|
||||||
|
|
||||||
router.get("/api/v1/accounts/:id/following", (req, res) => {
|
|
||||||
res.json([]);
|
|
||||||
});`;
|
|
||||||
|
|
||||||
let patched = content;
|
|
||||||
|
|
||||||
if (patched.includes(statusesBlock)) {
|
|
||||||
patched = patched.replace(statusesBlock, `${MARKER} — removed duplicate accounts/:id/statuses, /followers, /following (implemented in accounts.js)`);
|
|
||||||
} else {
|
|
||||||
console.warn("Could not find statuses block to remove");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (patched.includes(followersBlock)) {
|
|
||||||
patched = patched.replace(followersBlock, "");
|
|
||||||
} else {
|
|
||||||
console.warn("Could not find followers/following block to remove");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (patched !== content) {
|
|
||||||
writeFileSync(TARGET, patched, "utf8");
|
|
||||||
console.log("✅ Removed duplicate account routes from stubs.js");
|
|
||||||
} else {
|
|
||||||
console.warn("No changes made");
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user