diff --git a/components/image.js b/components/image.js index 4339db31..750a90c5 100644 --- a/components/image.js +++ b/components/image.js @@ -1,6 +1,6 @@ import styles from './text.module.css' import { Fragment, useState, useEffect, useMemo, useCallback, forwardRef, useRef, memo } from 'react' -import { IMGPROXY_URL_REGEXP } from '@/lib/url' +import { IMGPROXY_URL_REGEXP, MEDIA_DOMAIN_REGEXP } from '@/lib/url' import { useShowModal } from './modal' import { useMe } from './me' import { Dropdown } from 'react-bootstrap' @@ -63,7 +63,7 @@ function ImageOriginal ({ src, topLevel, rel, tab, children, onClick, ...props } } } -function ImageProxy ({ src, srcSet: { dimensions, ...srcSetObj } = {}, onClick, topLevel, onError, ...props }) { +function TrustedImage ({ src, srcSet: { dimensions, ...srcSetObj } = {}, onClick, topLevel, onError, ...props }) { const srcSet = useMemo(() => { if (Object.keys(srcSetObj).length === 0) return undefined // srcSetObj shape: { [widthDescriptor]: , ... } @@ -132,7 +132,7 @@ export default function ZoomableImage ({ src, srcSet, ...props }) { const showModal = useShowModal() // if `srcSet` is falsy, it means the image was not processed by worker yet - const [imgproxy, setImgproxy] = useState(!!srcSet || IMGPROXY_URL_REGEXP.test(src)) + const [trustedDomain, setTrustedDomain] = useState(!!srcSet || IMGPROXY_URL_REGEXP.test(src) || MEDIA_DOMAIN_REGEXP.test(src)) // backwards compatibility: // src may already be imgproxy url since we used to replace image urls with imgproxy urls @@ -158,13 +158,13 @@ export default function ZoomableImage ({ src, srcSet, ...props }) { ) }), [showModal, originalUrl, styles]) - const handleError = useCallback(() => setImgproxy(false), [setImgproxy]) + const handleError = useCallback(() => setTrustedDomain(false), [setTrustedDomain]) if (!src) return null - if (imgproxy) { + if (trustedDomain) { return ( - diff --git a/lib/url.js b/lib/url.js index 36d2192c..47b44827 100644 --- a/lib/url.js +++ b/lib/url.js @@ -89,5 +89,7 @@ export const URL_REGEXP = /^((https?|ftp):\/\/)?(www.)?(((([a-z]|\d|-|\.|_|~|[\u export const WS_REGEXP = /^(wss?:\/\/)([0-9]{1,3}(?:\.[0-9]{1,3}){3}|(?=[^\/]{1,254}(?![^\/]))(?:(?=[a-zA-Z0-9-]{1,63}\.)(?:xn--+)?[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*\.)+[a-zA-Z]{2,63})(:([0-9]{1,5}))?(\/[^\s`@#$^&=.?"{}\\]+\/?)*([^\s`@#$^&=?"{}\/\\]+)?(\?[^\s`#$^"{}\\]+)*$/ export const IMGPROXY_URL_REGEXP = new RegExp(`^${process.env.NEXT_PUBLIC_IMGPROXY_URL}.*$`) +export const MEDIA_DOMAIN_REGEXP = new RegExp(`^https?://${process.env.NEXT_PUBLIC_MEDIA_DOMAIN}/.*$`) + // this regex is not a bullet proof way of checking if a url points to an image. to be sure, fetch the url and check the mimetype export const IMG_URL_REGEXP = /^(https?:\/\/.*\.(?:png|jpg|jpeg|gif))$/