fix: detect own posts in Mastodon API status serialization

Own posts in ap_timeline have author.url set to the publication URL
(site root like "https://rmendes.net/") with no /@handle or /users/handle
pattern. extractUsername("/") returns "" which falls back to "unknown".

Fix: set module-level local identity (publicationUrl + handle) at plugin
init via setLocalIdentity(). serializeStatus() compares item.author.url
against the publication URL and passes isLocal:true + handle to
serializeAccount() when they match.

This is zero-cost for callers — no signature changes needed at the 20+
serializeStatus() call sites.
This commit is contained in:
Ricardo
2026-03-20 14:00:44 +01:00
parent 5fc4d3a6f5
commit 0cde298b46
2 changed files with 24 additions and 1 deletions
+4
View File
@@ -2,6 +2,7 @@ import express from "express";
import { setupFederation, buildPersonActor } from "./lib/federation-setup.js";
import { createMastodonRouter } from "./lib/mastodon/router.js";
import { setLocalIdentity } from "./lib/mastodon/entities/status.js";
import { initRedisCache } from "./lib/redis-cache.js";
import { lookupWithSecurity } from "./lib/lookup-helpers.js";
import {
@@ -1492,6 +1493,9 @@ export default class ActivityPubEndpoint {
routesPublic: this.contentNegotiationRoutes,
});
// Set local identity for own-post detection in status serialization
setLocalIdentity(this._publicationUrl, this.options.actor?.handle || "user");
// Mastodon Client API — virtual endpoint at root
// Mastodon-compatible clients (Phanpy, Elk, etc.) expect /api/v1/*,
// /api/v2/*, /oauth/* at the domain root, not under /activitypub.
+20 -1
View File
@@ -16,6 +16,21 @@
import { serializeAccount } from "./account.js";
import { sanitizeHtml } from "./sanitize.js";
// Module-level defaults set once at startup via setLocalIdentity()
let _localPublicationUrl = "";
let _localHandle = "";
/**
* Set the local identity for own-post detection.
* Called once during plugin init.
* @param {string} publicationUrl - e.g. "https://rmendes.net/"
* @param {string} handle - e.g. "rick"
*/
export function setLocalIdentity(publicationUrl, handle) {
_localPublicationUrl = publicationUrl;
_localHandle = handle;
}
/**
* Serialize an ap_timeline document as a Mastodon Status entity.
*
@@ -207,7 +222,11 @@ export function serializeStatus(item, { baseUrl, favouritedIds, rebloggedIds, bo
reblog: null,
application: null,
account: item.author
? serializeAccount(item.author, { baseUrl })
? serializeAccount(item.author, {
baseUrl,
isLocal: !!(_localPublicationUrl && item.author.url === _localPublicationUrl),
handle: _localHandle,
})
: null,
media_attachments: mediaAttachments,
mentions,