d99253ba79
Ownership-scoped (userId, matching update/remove) icon byte proxy. Loads the row's stored iconUrl server-side and streams it through IconDiscoveryService.fetchIconBytes -- never accepts a client-supplied URL, so this can't become an open SSRF proxy. Not-found/not-owned/no-icon -> 404. Upstream fetch failure (unreachable, timeout, non-image, SSRF-blocked) -> 502, never a 200 with a placeholder. Success sets Cache-Control so the browser doesn't refetch every load. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>