/* eslint-disable @next/next/no-img-element */
'use client'
import { displayUrlName } from '@/lib/utils/domain'
import { faviconUrl } from '@/lib/utils/favicon'
/**
* Normalize a user- or model-supplied URL to a safe http(s) URL, or return
* null if the scheme is not allowed. Prevents XSS via javascript:/data: URLs
* embedded in model-generated spec blocks.
*/
const sanitizeHttpUrl = (raw: string | undefined): string | null => {
if (!raw) return null
try {
const parsed = new URL(raw)
if (parsed.protocol === 'http:' || parsed.protocol === 'https:') {
return parsed.toString()
}
return null
} catch {
return null
}
}
type ImageCreditOverlayProps = {
/** Fallback link URL (e.g. the image URL itself). Used when sourceUrl is not set. */
url: string
/** Original referring page URL; preferred for link/favicon/hostname when present. */
sourceUrl?: string
title?: string
description?: string
}
export function ImageCreditOverlay({
url,
sourceUrl,
title,
description
}: ImageCreditOverlayProps) {
const safeLink = sanitizeHttpUrl(sourceUrl) ?? sanitizeHttpUrl(url)
const favicon = safeLink ? faviconUrl(safeLink, 128) : ''
const label = title || description
const content = (
<>
{favicon && (
)}