mirror of
https://github.com/block/buzz.git
synced 2026-10-29 21:41:33 +00:00
## Summary - Supersedes #1913 with a KLIPY-hosted URL implementation. - Adds KLIPY GIF search and trending results to desktop message and forum composers. - Keeps selected GIFs hosted by KLIPY; Buzz stores only the external URL and media metadata (no imeta tag, since relays only accept hash-backed local `/media/` entries). - Aligns the Emoji/GIF picker with Buzz's standard segmented control, theme surfaces, and motion behavior. ## Relay-to-provider boundary - The relay proxies KLIPY search/share so the `BUZZ_KLIPY_API_KEY` never reaches the desktop; the key stays server-side behind a redacted `Debug` impl. - The dedicated GIF `reqwest` client sets `redirect::Policy::none()`. Because the API key rides in the request path, following a provider `3xx` could replay a key-bearing URL to an attacker-chosen host (an SSRF/key-disclosure primitive). With redirects disabled, a `3xx` returns as a non-success status that the handlers map to a generic `502`; the `Location` target is never read or forwarded. - Admission reuses the established NIP-98, membership, replay, and per-pubkey rate-limit gates, with an upstream response-size cap and allowlisting so KLIPY error bodies never cross the relay boundary. ## Accessibility - Under `prefers-reduced-motion: reduce`, the picker grid renders a static provider poster (a normalized `jpg` asset) instead of the animated preview, or a named static placeholder when no poster is available. It reacts to preference changes while mounted. `no-preference` keeps the animated preview. - Selected GIFs carry their title through `ImetaMedia`'s `displayLabel`, so the composer thumbnail, preview dialog, editor, lightbox, and remove control all derive one non-empty accessible name instead of an empty `Attachment ` label. Ordinary hashed uploads keep their existing hash-derived names. --------- Signed-off-by: kenny lopez <klopez4212@gmail.com> Signed-off-by: Kenny Lopez <klopez4212@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Duncan <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz> Signed-off-by: Hayt <9e1c23a3fd83f61da34420e4e88ff1b16e45cafcc0cd9019eb07d4ecfa8ca9b0@buzz.block.builderlab.xyz> Co-authored-by: Princess Donut <b238ea756dee4d98afa5883fc7f1de61eeabe65bf700e3a5a5a80db5e42e2c2b@buzz.block.builderlab.xyz> Co-authored-by: Duncan <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz> Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Co-authored-by: Hayt <9e1c23a3fd83f61da34420e4e88ff1b16e45cafcc0cd9019eb07d4ecfa8ca9b0@buzz.block.builderlab.xyz>
42 lines
1.7 KiB
Markdown
42 lines
1.7 KiB
Markdown
# Relay-proxied GIF search
|
|
|
|
Buzz relays can optionally provide GIF search without distributing a provider
|
|
credential to desktop clients. An operator configures `BUZZ_KLIPY_API_KEY` in
|
|
the relay's secret store. When present, the relay advertises this NIP-11 shape:
|
|
|
|
```json
|
|
{
|
|
"supported_extensions": ["buzz-gif"],
|
|
"gif": {
|
|
"provider": "klipy",
|
|
"search": "/gifs/search",
|
|
"share": "/gifs/share"
|
|
}
|
|
}
|
|
```
|
|
|
|
The descriptor is provider-agnostic so a relay can advertise another provider
|
|
or paths later. Clients must require `buzz-gif`, recognize the provider, and use
|
|
only safe relay-relative search and share paths.
|
|
|
|
`POST /gifs/search` requires NIP-98 authentication and relay membership. Its
|
|
per-pubkey, per-community Redis admission limit defaults to 30 requests per
|
|
minute and can be tuned with `BUZZ_RATE_LIMIT_GIF_SEARCHES_PER_MIN`. The relay
|
|
sends the provider credential upstream and returns only allowlisted successful
|
|
result data. Provider error bodies are never returned to clients or written to
|
|
logs.
|
|
|
|
`POST /gifs/share` uses the same authentication and membership boundary. It
|
|
accepts a bounded GIF slug plus anonymous customer ID and forwards KLIPY's share
|
|
signal so selected media can enter the user's provider-backed Recents. The
|
|
endpoint returns no provider body.
|
|
|
|
## Message and rendering boundary
|
|
|
|
Selecting a GIF sends a normal Buzz message containing a KLIPY CDN image URL.
|
|
Because Buzz's imeta validator permits only hash-verified local `/media/` paths,
|
|
external GIFs are deliberately content-only and carry no imeta tag. Buzz does
|
|
not download, cache, or store the GIF bytes. Existing image URL rendering
|
|
handles the message, including pasted GIF URLs on relays that do not advertise
|
|
`buzz-gif`. Only the picker is capability-gated.
|