-
-
Notifications
You must be signed in to change notification settings - Fork 132
Fix public audience interop #999
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 2.0-maintenance
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1,3 @@ | ||
| export * from "./transformers.ts"; | ||
| export * from "./types.ts"; | ||
| export * from "./public-audience.ts"; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| import { getLogger } from "@logtape/logtape"; | ||
| import { PUBLIC_COLLECTION } from "@fedify/vocab"; | ||
|
|
||
| const logger = getLogger(["fedify", "compat", "public-audience"]); | ||
|
|
||
| /** | ||
| * Rewrites the compact `as:Public` or `Public` CURIE in the `object` field of a | ||
| * serialized Follow activity to the full ActivityStreams Public collection URI. | ||
| * | ||
| * Some ActivityPub implementations compare the field as a plain URL | ||
| * without applying JSON-LD expansion, causing them to reject public-addressed | ||
| * Follow activities that use a compact IRI. This helper works around that gap. | ||
| */ | ||
| export function normalizePublicFollowObject( | ||
| jsonLd: unknown, | ||
| ): unknown { | ||
| if (typeof jsonLd !== "object" || jsonLd === null) { | ||
| return jsonLd; | ||
| } | ||
|
|
||
| try { | ||
| const record = jsonLd as Record<string, unknown>; | ||
| if ( | ||
| record.type === "Follow" && | ||
| (record.object === "as:Public" || record.object === "Public") | ||
| ) { | ||
| const normalized = { | ||
| ...record, | ||
| object: PUBLIC_COLLECTION.href, | ||
| }; | ||
|
|
||
| return normalized; | ||
| } | ||
| } catch (error) { | ||
| logger.debug( | ||
| "Failed to normalize public follow object; sending the activity as is.\n{error}", | ||
| { | ||
| error, | ||
| }, | ||
| ); | ||
| } | ||
|
|
||
| return jsonLd; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,6 +11,7 @@ import { SpanStatusCode, trace, type TracerProvider } from "@opentelemetry/api"; | |
| import { encodeHex } from "byte-encodings/hex"; | ||
| import serialize from "json-canon"; | ||
| import metadata from "../../deno.json" with { type: "json" }; | ||
| import { normalizePublicFollowObject } from "../compat/public-audience.ts"; | ||
| import { | ||
| fetchKey, | ||
| type FetchKeyResult, | ||
|
|
@@ -66,11 +67,12 @@ export async function createProof( | |
| throw new TypeError("Unsupported algorithm: " + privateKey.algorithm.name); | ||
| } | ||
| const objectWithoutProofs = object.clone({ proofs: [] }); | ||
| const compactMsg = await objectWithoutProofs.toJsonLd({ | ||
| let compactMsg = await objectWithoutProofs.toJsonLd({ | ||
| format: "compact", | ||
| contextLoader, | ||
| context, | ||
| }); | ||
| compactMsg = normalizePublicFollowObject(compactMsg); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When callers use the public AGENTS.md reference: AGENTS.md:L189-L189 Useful? React with 👍 / 👎. |
||
| const msgCanon = serialize(compactMsg); | ||
| const encoder = new TextEncoder(); | ||
| const msgBytes = encoder.encode(msgCanon); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When the supplied public
Followalready has an Object Integrity Proof created over the compactas:Publicrepresentation—for example, a persisted activity signed by an earlier Fedify release—the preceding proof check skips re-signing, but this line changes the signed payload before delivery. Receivers then hash the full-URI representation and reject the existing proof, so normalization must not mutate bytes covered by a retained proof without replacing that proof.AGENTS.md reference: AGENTS.md:L189-L189
Useful? React with 👍 / 👎.