// Only the following domains are approved: redd.it, redditstatic.com, redditmedia.com, or snoo.dev
import { sanitizeSvg } from '@devvit/shared-types/sanitizeSvg.js';
export const REDD_IT = 'redd.it';
export const REDDIT_STATIC = 'redditstatic.com';
export const REDDIT_MEDIA = 'redditmedia.com';
export const SNOO_DEV = 'snoo.dev';
export const VerifiedPublicImageHosts = [REDD_IT, REDDIT_STATIC, REDDIT_MEDIA];
export const VerifiedImageHosts = [
    SNOO_DEV,
    REDD_IT,
    REDDIT_STATIC,
    REDDIT_MEDIA,
];
const MIME_SVG_XML = 'image/svg+xml';
const ALLOWED_DATA_MIMETYPES = [MIME_SVG_XML];
function validateDataUrl(url) {
    // mediaType is everything before the data section
    const mediaType = url.pathname.split(',')[0];
    // chunks are separated by semicolons, with the first being the mimetype
    const mimetype = mediaType.split(';')[0];
    return ALLOWED_DATA_MIMETYPES.includes(mimetype);
}
function validateHttpUrl(url) {
    // Get just the domain name from the hostname
    const domain = url.hostname.split('.').slice(-2).join('.');
    return VerifiedImageHosts.includes(domain);
}
/**
 * Validates whether an image URL is allowed to be displayed
 * @param imageUrl
 * @returns true if the URL is allowed
 */
export function isValidImageURL(imageUrl) {
    try {
        const url = new URL(imageUrl);
        const protocol = url.protocol.substring(0, 4);
        switch (protocol) {
            case 'blob':
                return true;
            case 'data':
                return validateDataUrl(url);
            case 'http':
                return validateHttpUrl(url);
        }
    }
    catch (_) {
        // invalid imageUrl
    }
    return false;
}
/**
 * Performs any sanitization needed on a given image URL
 * Currently only processes SVG data URIs
 * @param imageUrl
 * @returns the sanitized URL
 */
export function sanitizeImageURL(imageUrl) {
    try {
        // only parse up until the data segment so we don't waste time parsing it here
        const dataSeparator = imageUrl.indexOf(',');
        const url = new URL(dataSeparator > 0 ? imageUrl.slice(0, dataSeparator) : imageUrl);
        // nothing to sanitize
        if (url.protocol.startsWith('http') || url.protocol.startsWith('blob')) {
            return encodeURI(imageUrl);
        }
        const mediaType = url.pathname;
        const [mimetype] = mediaType.split(';');
        // can't sanitize binary image data
        if (mimetype !== MIME_SVG_XML) {
            return imageUrl;
        }
        const base64 = mediaType.split(';').at(-1) === 'base64';
        const data = imageUrl.slice(dataSeparator + 1);
        const svgData = base64 ? atob(data) : data;
        // extract SVG
        const svg = decodeURIComponent(svgData);
        // sanitize
        const safeSvg = sanitizeSvg(svg);
        if (safeSvg === undefined) {
            return undefined;
        }
        // URI encode if we're not base64 encoding to ensure the img tag doesn't choke on `#` and `?` characters
        const safeData = base64 ? btoa(safeSvg) : encodeURIComponent(safeSvg);
        return `data:${mediaType},${safeData}`;
    }
    catch {
        // failed to parse URL
    }
}
//# sourceMappingURL=imageUtil.js.map