Four security/UX fixes from 2026-05-24 audit: * lib/safeUrl.ts (new): validate external URLs, reject non-http(s) schemes (closes finding #3 — backend supplies lot.source_url verbatim from scraped sites; javascript:/data:/file: would have executed on click). * lib/api.ts: refactor apiFetch to delegate to apiFetchWithStatus — single read-body-once implementation, drops the body-stream-twice anti-pattern (finding #8). * components/trade-in/ListingsCard.tsx: drop tr.onClick (not keyboard accessible), keep the inline <a> as the only interactive element, gate it through safeUrl() (findings #7 + #3). * app/error.tsx (new): Next 15 App Router route-segment error boundary — prevents white-screen on component crash (finding #16). Scope-cut from original audit: * #17 (sessionId crypto.randomUUID) — already implemented in sessionId.ts; no change needed. * safeUrl wiring in DealsCard / IMVBenchmark — neither renders user-supplied URLs (DealsCard has no links, IMVBenchmark links a hardcoded domain). |
||
|---|---|---|
| .. | ||
| public | ||
| src | ||
| .dockerignore | ||
| Dockerfile | ||
| next.config.ts | ||
| package.json | ||
| tsconfig.json | ||