Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,24 @@ To be released.
reference through an `Update`; failed rejection updates can be retried
without changing the quote state or counts. [[#602]]

- FEP-044f quote authorization now uses Fedify's
*@fedify/interaction-controls* package to build and verify quote
requests and authorizations and to evaluate local quote policies.
Verification is stricter in a few cases: [[#635], [#641]]

- Incoming `QuoteRequest` activities must have an `id` and an `actor`,
and their quote post's `quote` and `quoteUrl` must point to the same
post. Invalid requests are ignored before the quote post is stored.
- An embedded quote post from another origin is fetched from its own
server instead of being trusted.
- A `QuoteAuthorization` from an `Accept` or from a remote quote post is
always fetched from its IRI. Embedded authorization contents are not
trusted. The authorization must be hosted on the same origin as the
quoted post's author. If the authorization can't be fetched because
of a temporary failure, the `Accept` is retried later.
- Outgoing `Accept` and `Reject` responses to quote requests now have
explicit IDs and address the requester in `to`.

- Added WebP (`image/webp`) as an accepted format for profile avatar and
banner image uploads. Previously only JPEG, PNG, and GIF were accepted
by both the Mastodon-compatible
Expand Down Expand Up @@ -78,8 +96,6 @@ To be released.
14 adds post-quantum ML-DSA passkey support on runtimes that provide the
algorithms. [[GHSA-2g3p-m8c9-hhwh], [GHSA-j3h4-m3m2-7p7j]]

[GHSA-97w4-f4rq-mgqm]: https://github.com/fedify-dev/fedify/security/advisories/GHSA-97w4-f4rq-mgqm
[GHSA-39gj-rchc-q5m3]: https://github.com/fedify-dev/fedify/security/advisories/GHSA-39gj-rchc-q5m3
[FEP-c0e0]: https://w3id.org/fep/c0e0
[Gukhanmun]: https://gukhanmun.org/
[RFC 6749]: https://datatracker.ietf.org/doc/html/rfc6749#section-3.3
Expand All @@ -90,6 +106,8 @@ To be released.
[#549]: https://github.com/fedify-dev/hollo/issues/549
[#602]: https://github.com/fedify-dev/hollo/issues/602
[#609]: https://github.com/fedify-dev/hollo/issues/609
[#635]: https://github.com/fedify-dev/hollo/issues/635
[#641]: https://github.com/fedify-dev/hollo/pull/641


Version 0.9.21
Expand Down Expand Up @@ -157,6 +175,7 @@ Released on September 30, 2026.
definition also causes the migration to fail; inspect it before replacing
it. [[#624], [#626]]

[GHSA-97w4-f4rq-mgqm]: https://github.com/fedify-dev/fedify/security/advisories/GHSA-97w4-f4rq-mgqm
[#624]: https://github.com/fedify-dev/hollo/issues/624
[#626]: https://github.com/fedify-dev/hollo/pull/626

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"@fedify/debugger": "~2.4.0",
"@fedify/fedify": "~2.4.0",
"@fedify/hono": "~2.4.0",
"@fedify/interaction-controls": "~2.4.0",
"@fedify/markdown-it-hashtag": "~0.3.0",
"@fedify/markdown-it-mention": "~0.3.0",
"@fedify/postgres": "~2.4.0",
Expand Down
15 changes: 15 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

37 changes: 19 additions & 18 deletions src/api/v1/statuses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,7 @@ import {
import { getPostRelations, serializePost } from "../../entities/status";
import federation from "../../federation";
import { updateAccountStats } from "../../federation/account";
import {
getQuoteAuthorizationIri,
sendQuoteUpdate,
} from "../../federation/inbox";
import { sendQuoteUpdate } from "../../federation/inbox";
import {
getRecipients,
persistPost,
Expand All @@ -37,6 +34,11 @@ import {
toUpdate,
updatePostStats,
} from "../../federation/post";
import {
createQuoteAuthorization,
createQuoteRequest,
getQuoteAuthorizationIri,
} from "../../federation/quote";
import { appendPostToTimelines } from "../../federation/timeline";
import { requestBody } from "../../helpers";
import { isLocalHost } from "../../instance-host";
Expand Down Expand Up @@ -632,14 +634,12 @@ app.post(
sharedInbox: new URL(post.quoteTarget.account.sharedInboxUrl),
},
},
new vocab.QuoteRequest({
id: new URL("#quote-request", post.iri),
actor: new URL(owner.account.iri),
object: new URL(post.quoteTarget.iri),
instrument: toObject(post, fedCtx, {
includeInactiveQuoteTarget: true,
}),
}),
createQuoteRequest(
post,
owner.account.iri,
post.quoteTarget.iri,
toObject(post, fedCtx, { includeInactiveQuoteTarget: true }),
),
{
orderingKey,
preferSharedInbox: true,
Expand Down Expand Up @@ -1976,12 +1976,13 @@ app.post(
new vocab.Delete({
id: new URL("#delete", quoteAuthorizationIri),
actor: new URL(owner.account.iri),
object: new vocab.QuoteAuthorization({
id: new URL(quoteAuthorizationIri),
attribution: new URL(owner.account.iri),
interactingObject: new URL(quotingPost.iri),
interactionTarget: new URL(targetPost.iri),
}),
// Keep the embedded authorization instead of the helper's
// IRI-only revocation so the wire format stays unchanged.
object: createQuoteAuthorization(
{ iri: targetPost.iri, account: owner.account },
quotingPost,
quoteAuthorizationIri,
),
}),
{
orderingKey: getPostOrderingKey(quotingPost.iri),
Expand Down
Loading
Loading