v1.104.0
[1.104.0] — 2026-07-06
Company logos in the scan table (privacy-preserving). A new Appearance toggle in App settings — Show company logos in the scan table (off by default) — draws each company's logo next to its name on #/scan. The logo is the company's favicon fetched from its own domain and proxied server-side (GET /api/logo), so no third-party logo service ever learns which employers you're viewing. Postings on a shared job board (Greenhouse, Lever, Ashby, …) show a coloured letter badge instead of the board's icon, and any logo that fails to load falls back to the same badge.
- New route module (29th)
server/lib/routes/logos.mjs—GET /api/logo?domain=. It validates the domain (no scheme/path/loopback), fetches/favicon.icothrough the SSRF-safesafeGet(a newbinarymode returns the raw bytes + content-type; DNS-pinning, redirect validation and the size cap are unchanged), image-magic sniffs the result so an HTML error page is never served as an image, caches hits and misses in an in-memory LRU, and writes nothing to disk. - New client lib
public/js/lib/company-logo.js(window.CompanyLogo): off by default via a localStorage flag; skips shared ATS hosts in favour of a deterministic letter-avatar; CSP-safeimg.onerrorfallback. Tests:tests/logo-routes.test.mjs(domain guard, image sniff/reject, negative cache, binarysafeGet). 5 new i18n keys ×16 (appear.*). Help §2 extended in place.
New: server/lib/routes/logos.mjs; public/js/lib/company-logo.js.