feat(registry): developer-facing SVG icon per profile
Adds an optional vector icon field on registry profiles, exposed only
via the public read API for developers building badges, app showcases,
and programmatic listings. Not rendered on the public Explore profile.
Backend
- lexicon: new optional `icon` blob (image/svg+xml, 200KB max)
- DB: additive icon_cid/icon_mime columns; existing deployments
pick them up via ALTER TABLE — no wipe required
- validator + registry queries + jetstream indexer all extended in
lockstep with the existing avatar plumbing
Sanitisation + serve path
- lib/svg-sanitize.ts strips <script>, <style>, <foreignObject>,
on*= handlers, comments/PIs/DOCTYPEs, and href/xlink:href values
pointing at javascript: or non-image data: URLs
- new GET /api/registry/icon/:did proxies the bytes with
Content-Type: image/svg+xml, X-Content-Type-Options: nosniff, and
a strict Content-Security-Policy so any script that survived the
sanitiser is neutralised at render time
- GET /api/registry/profile/:id now includes an `iconUrl` next to
`avatarUrl`
UI
- "Developer icon (SVG, optional)" section on the manage form with
a 64px preview slot, mime + size validation client-side, and the
same keep/upload/remove pattern as the main avatar
- explainer text makes it clear the icon is dev-only and not shown
on the public profile
Docs
- DeveloperResources endpoint reference lists the new
/api/registry/icon/:did endpoint
- i18n strings under forms.profile.icon and the API docs
OAuth scope is unchanged — image/svg+xml is already covered by the
existing blob:image/* permission set.
Made-with: Cursor