Two related changes that ensure remote images render inline in timelines
instead of as clickable links.
reverse_proxy: always force inline for whitelisted content types
When `inline_content_types` is configured as a whitelist, the upstream's
`content-disposition` header used to be passed through unchanged. Some
origins send `content-disposition: attachment` for media we want
embedded, so the proxy now always emits `content-disposition: inline`
for whitelisted types (overriding the upstream header), deriving a
filename from `MIME.extensions/1` (e.g. `inline.gif`) so browsers have
something to use for "Save As". When the type has no known extension,
the bare token `inline` is emitted. The `inline_content_types: true`
(pass-through) and `:false` (always attachment) behaviours are
unchanged.
ActivityPub: sniff MIME type for extensionless/generic attachments
Some remotes (e.g. extensionless Cloudflare Images URLs) ship
attachments with no usable `mediaType` (missing, empty, or
`application/octet-stream`), which would render as links instead of
inline images. `AttachmentValidator.fix_media_type/1` now fetches the
first 8 KB of the URL and runs it through libmagic when the declared
type carries no real information. Only `image/*` results replace the
declared type; any other result, non-2xx response, transport error, or
exception yields `nil` and the original type is kept, so ingestion
never blocks and non-image media is never reclassified. Present real
types are left untouched (no fetch is attempted).
The new logic lives in `Pleroma.Web.ActivityPub.ObjectValidators.AttachmentTypeSniffer`.
Tests: comprehensive coverage of both changes, including a dedicated
suite for the sniffer covering happy paths, non-image bodies, HTTP
failures, raised exceptions, guard clauses, and verification that the
Range header is sent; AttachmentValidator tests for mimeType fallback,
empty-string mediaType, multi-URL sniffing, and HTTP-failure fallback;
ReverseProxy tests for inline_content_types `true`/`false`/custom
whitelists, bare-inline for types without a MIME extension, and
attachment_name handling.
Checking against the default port of the Endpoint URL scheme is
redundant as normal instances will have the combination https/443
by default created by pleroma.instance gen, Tor-only instances should
have combination http/80 and local testing instances httt/XXXX.
The default scheme port doesn't add anything usefull in these configs.
increase_vote_count/3 was incrementing votersCount on every vote
activity, causing inflation when a single voter picks multiple options.
Now only increments when the actor is a new unique voter, and preserves
existing votersCount otherwise.
Also adds is_integer guard to voters_count/1 to handle nil safely, and
adds tests for the voters_count clause ordering and edge cases.
Reject unknown remote Update targets and invalidate signed payloads when their signer identity cannot be mapped, avoiding crashes and fail-open signature state.
When user supplied arguments to pleroma_ctl include whitespace
that has been properly quoted, all arguments were sent to
ReleaseTasks in one string, which then String.split/1 the input on any
whitespace. This broke Mix tasks that accept certain user input like
instance gen and user management.
To fix this, pleroma_ctl now sends the arguments in list
form. Additionally pleroma_ctl arguments now need to be pre-processed.
Fixespleroma/pleroma#7874