diff options
| author | yyamashita <yyamashita@hetzner.yyamashita.com> | 2026-06-17 22:27:47 +0900 |
|---|---|---|
| committer | yyamashita <yyamashita@hetzner.yyamashita.com> | 2026-06-17 22:27:47 +0900 |
| commit | 5f653a4c9f7c76d461ee4377fb4e025771cff872 (patch) | |
| tree | 4cb8e8ee191bc082a69c10b99c717df948c01cca /app/routes/events.$id.tsx | |
| parent | b323ad4824cc62cf54a9bfa4f9f68dda4b783323 (diff) | |
Add image proxy endpoint to avoid mixed content issues
Serve external event images through /api/image?url=<encoded> so HTTP
image URLs from venue sites are fetched server-side and delivered over
HTTPS. Validates Content-Type is image/*, blocks private IPs (SSRF),
and caches responses in memory (24h TTL, 200-entry LRU).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'app/routes/events.$id.tsx')
| -rw-r--r-- | app/routes/events.$id.tsx | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/app/routes/events.$id.tsx b/app/routes/events.$id.tsx index 87c5e2d..87836ed 100644 --- a/app/routes/events.$id.tsx +++ b/app/routes/events.$id.tsx @@ -1,6 +1,7 @@ import { useLoaderData, Link } from "react-router"; import type { Route } from "./+types/events.$id"; import { getEvent } from "~/lib/db.server"; +import { proxyImageUrl } from "~/lib/image-proxy"; export async function loader({ params }: Route.LoaderArgs) { const id = parseInt(params.id, 10); @@ -83,7 +84,7 @@ export default function EventDetail() { <div className="mt-6"> {event.image_url && ( <img - src={event.image_url} + src={proxyImageUrl(event.image_url)!} alt={event.title} className="w-full object-contain rounded-xl mb-6" /> |
