fix(journal): actor profile fields must serialize as a JSON array
Mastodon's PropertyValue parser requires the actor's attachment to be a JSON *array* and silently ignores a bare object — and Fedify compacts single-element arrays to bare objects, so the 🥾 trails.cool field shipped in #464 never rendered (verified: Mastodon stored fields = {} after a forced actor refresh on the soak instance). Ship two fields so the array survives serialization: the 🥾 profile link (rel=me) plus an Instance link — the latter is genuinely useful for self-hosted instances anyway. Test now asserts the array shape explicitly. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
b0bfed4d4a
commit
d74ce32cd0
2 changed files with 20 additions and 6 deletions
|
|
@ -95,12 +95,18 @@ describe("actor object", () => {
|
|||
expect(actor.preferredUsername).toBe("bruno");
|
||||
expect(actor.name).toBe("Bruno");
|
||||
expect(actor.summary).toBe("Riding bikes");
|
||||
// Profile-metadata field Mastodon renders ("this is a trails profile")
|
||||
const attachments = Array.isArray(actor.attachment) ? actor.attachment : [actor.attachment];
|
||||
const field = attachments.find((a: { type: string }) => a?.type === "PropertyValue");
|
||||
expect(field?.name).toBe("🥾 trails.cool");
|
||||
expect(field?.value).toContain('href="http://localhost:3000/users/bruno"');
|
||||
expect(field?.value).toContain('rel="me"');
|
||||
// Profile-metadata fields Mastodon renders ("this is a trails
|
||||
// profile"). MUST serialize as a JSON array — Mastodon's parser
|
||||
// silently ignores a bare attachment object, which is what Fedify
|
||||
// compacts single-element arrays into (hence two fields).
|
||||
expect(Array.isArray(actor.attachment)).toBe(true);
|
||||
const fields = actor.attachment.filter((a: { type: string }) => a?.type === "PropertyValue");
|
||||
expect(fields.length).toBeGreaterThanOrEqual(2);
|
||||
const trails = fields.find((f: { name: string }) => f.name === "🥾 trails.cool");
|
||||
expect(trails?.value).toContain('href="http://localhost:3000/users/bruno"');
|
||||
expect(trails?.value).toContain('rel="me"');
|
||||
const instance = fields.find((f: { name: string }) => f.name === "Instance");
|
||||
expect(instance?.value).toContain("localhost:3000");
|
||||
});
|
||||
|
||||
it("404s the actor for a private user", async () => {
|
||||
|
|
|
|||
|
|
@ -180,11 +180,19 @@ function buildFederation(): Federation<void> {
|
|||
// metadata table — a human-visible "this is a trails profile"
|
||||
// marker. (The machine-readable marker is NodeInfo; this is
|
||||
// flair.) Mastodon strips most HTML in values but keeps links.
|
||||
// NOTE: Mastodon's parser requires `attachment` to be a JSON
|
||||
// *array* and silently ignores a bare object — and Fedify
|
||||
// compacts single-element arrays to bare objects. Keep at least
|
||||
// two fields here so the array survives serialization.
|
||||
attachments: [
|
||||
new PropertyValue({
|
||||
name: "🥾 trails.cool",
|
||||
value: `<a href="${localActorIri(identifier)}" rel="me">${getOrigin().replace(/^https?:\/\//, "")}/users/${identifier}</a>`,
|
||||
}),
|
||||
new PropertyValue({
|
||||
name: "Instance",
|
||||
value: `<a href="${getOrigin()}">${getOrigin().replace(/^https?:\/\//, "")}</a>`,
|
||||
}),
|
||||
],
|
||||
});
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue