Mastodon 4.4+ clients read quotes from a top-level quote object with
state and quoted_status; Pleroma only had pleroma.quote, so they did
not show quote posts. Quoted statuses get a shallow quote with only
quoted_status_id, as quotes are rendered one level deep.
Inspired by Akkoma 5b7209980, which can not use the shallow form because
Akkoma already had a top-level quote status.
Containment.get_actor raised on remote shapes it did not know, such as
an attributedTo object without an id. This crashed object fetches and
poll refetches. Return nil, so containment rejects the object.
A fetch from a display URL (e.g. https://host/@user) returns the
actor with its canonical id. make_user_from_ap_id looked the user up
by the fetch URL, did not find it and tried to insert a duplicate.
Look the user up by the fetched id.
Based on Akkoma 48b3a3579.
refetch_object (used for poll updates) accepted whatever the remote
served. A hostile server could swap in another object or move the post
to another author.
The refetch now goes to the stored id without redirects, and the
returned id and actor must equal the stored ones.
Based on Akkoma 9061d148b and fee57eb37.
The fetcher accepted any document whose id was on the same host as the
fetch URL. Anyone who can place a JSON file on a host, for example
through an upload, could pass it off as another object or actor from
that host.
The id of a fetched document must now be the URL it came from (after
redirects), ignoring a trailing slash, the fragment, the host case and
differences that our URL encoding removes.
If it differs, as for Mastodon's /@user/123 display URLs, we refetch
once from that id, which must be on the same host. The refetch must
not redirect and must match exactly.
Test mocks that served a document under a different URL now serve it
from its own id.
Based on Akkoma 8684964c5 and 940792f8b.
A remote actor could set its inbox or shared inbox to a third-party
host, so our signed deliveries went there. It could also claim
another actor's followers collection, which the visibility checks
trust.
Validate fetched actors and incoming actor Updates: inbox,
endpoints.sharedInbox, followers, following, featured and the
publicKey id must be on the same host as the actor id.
Based on Akkoma f07eb4cb5. The Bridgy fixture gets the key id that
current Bridgy Fed serves.
Followers-only posts and DMs went to each recipient's personal inbox,
so a followers-only post was sent once per follower on the same server.
Mastodon, GoToSocial and Iceshrimp.NET always use the shared inbox.
Only activities with bcc or bto still go to personal inboxes.
Based on Akkoma a80444041.
Co-authored-by: Oneric <oneric@oneric.stub>
User.Query ignores is_active. The friends subquery already drops
deactivated users here, so this only removes the last ignored key.
Also add a changelog entry and a test.
The bucket entry expires one window after the first request. With a 50
or 80 ms window, a slow CI run could lose it between two requests, so
inspect_bucket/3 returned {0, 5} (seen on #8021 with Elixir 1.17). The
reset test expires the bucket itself, so a long window costs nothing.
Regex.match? raised on objects without content (for example posts with
only attachments), so no notifications were created for them when the
recipient had an irreversible filter.
The whole_word field was stored and returned by the API, but the regex
always used word boundaries. As in Mastodon, a filter with whole_word
false now also matches inside words.
The access check from the previous commit crashed on tags of unknown
users in followers-only posts, so such posts failed to be received.
Also add tests for the check.
Public activities went to every inbox, so followers on an instance in
the SimplePolicy reject list still got our posts. With authorized fetch
mode on, signed fetches from those instances were also accepted, unless
the instance was in :instance, :rejected_instances too.
Check the SimplePolicy reject and accept lists for deliveries and signed
fetches, when the policy is enabled. Quarantine keeps its meaning (no
private activities). An inbox without a host no longer crashes.
Based on the Akkoma changes 90c4785b8, ca000f830, 03662501c and d2b0d8647.
Co-authored-by: FloatingGhost <hannah@coffee-and-dreams.uk>
Co-authored-by: Atsuko Karagi <atsuko.karagi@localhost>
Phrases went into the Postgres and Elixir regexes as they were, so a
phrase like "(" broke the timeline and notification queries. The :re
form also put the word boundaries only around the whole alternation.
Escape each phrase and, as Mastodon does, add a word boundary only where
the phrase starts or ends with a word character.
Reported in Akkoma (d6209837b).
Hackney 4.9 enforces max_body while it reads and returns
{:error, {:closed, partial}} for a truncated body; the hackney
regression tests now pin that. The certifi override goes, as
hackney itself now asks for certifi ~> 2.18.0.
The C2S routes and the outbox/followers/following/replies collections
accepted a token with any scope. Requests with an OAuth token now need
the matching scope; HTTP signatures and Basic auth are not changed.
A token with only the profile scope can call verify_credentials, as in
Mastodon 4.3. The answer is the public account, so apps can use it to
log users in without seeing their email or settings.