feat: image integrity check
This commit is contained in:
parent
b38527ca1f
commit
6e5fba4f15
@ -10,7 +10,7 @@
|
||||
"publicDir": "public/snort",
|
||||
"httpCache": "",
|
||||
"animalNamePlaceholders": false,
|
||||
"defaultZapPoolFee": 0.5,
|
||||
"defaultZapPoolFee": 1,
|
||||
"bypassImgProxyError": false,
|
||||
"features": {
|
||||
"analytics": true,
|
||||
@ -22,7 +22,7 @@
|
||||
"moderation": true
|
||||
},
|
||||
"defaultPreferences": {
|
||||
"checkSigs": false
|
||||
"checkSigs": true
|
||||
},
|
||||
"noteCreatorToast": true,
|
||||
"hideFromNavbar": ["/graph"],
|
||||
|
@ -47,6 +47,7 @@ const ImageElement = ({ url, meta, onMediaClick }: ImageElementProps) => {
|
||||
<ProxyImg
|
||||
key={url}
|
||||
src={url}
|
||||
sha256={meta?.sha256}
|
||||
onClick={onMediaClick}
|
||||
className={classNames("max-h-[80vh] w-full h-full object-contain object-center md:object-left", {
|
||||
"md:max-h-[510px]": !meta,
|
||||
|
@ -5,13 +5,14 @@ import { getUrlHostname } from "@/SnortUtils";
|
||||
|
||||
type ProxyImgProps = HTMLProps<HTMLImageElement> & {
|
||||
size?: number;
|
||||
sha256?: string;
|
||||
className?: string;
|
||||
promptToLoadDirectly?: boolean;
|
||||
missingImageElement?: ReactNode;
|
||||
};
|
||||
|
||||
export const ProxyImg = forwardRef<HTMLImageElement, ProxyImgProps>(
|
||||
({ size, className, promptToLoadDirectly, missingImageElement, ...props }: ProxyImgProps, ref) => {
|
||||
({ size, className, promptToLoadDirectly, missingImageElement, sha256, ...props }: ProxyImgProps, ref) => {
|
||||
const { proxy } = useImgProxy();
|
||||
const [loadFailed, setLoadFailed] = useState(false);
|
||||
const [bypass, setBypass] = useState(CONFIG.bypassImgProxyError);
|
||||
@ -34,7 +35,7 @@ export const ProxyImg = forwardRef<HTMLImageElement, ProxyImgProps>(
|
||||
</div>
|
||||
);
|
||||
}
|
||||
const src = loadFailed && bypass ? props.src : proxy(props.src ?? "", size);
|
||||
const src = loadFailed && bypass ? props.src : proxy(props.src ?? "", size, sha256);
|
||||
if (!src || (loadFailed && !bypass)) return missingImageElement;
|
||||
return (
|
||||
<img
|
||||
@ -48,7 +49,7 @@ export const ProxyImg = forwardRef<HTMLImageElement, ProxyImgProps>(
|
||||
if (props.onError) {
|
||||
props.onError(e);
|
||||
} else {
|
||||
console.error("Failed to proxy image ", props.src);
|
||||
console.error("Failed to proxy image: ", props.src, e);
|
||||
setLoadFailed(true);
|
||||
}
|
||||
}}
|
||||
|
@ -13,11 +13,11 @@ export default function useImgProxy() {
|
||||
const settings = useLogin(s => s.appData.item.preferences.imgProxyConfig);
|
||||
|
||||
return {
|
||||
proxy: (url: string, resize?: number) => proxyImg(url, settings, resize),
|
||||
proxy: (url: string, resize?: number, sha256?: string) => proxyImg(url, settings, resize, sha256),
|
||||
};
|
||||
}
|
||||
|
||||
export function proxyImg(url: string, settings?: ImgProxySettings, resize?: number) {
|
||||
export function proxyImg(url: string, settings?: ImgProxySettings, resize?: number, sha256?: string) {
|
||||
const te = new TextEncoder();
|
||||
function urlSafe(s: string) {
|
||||
return s.replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
|
||||
@ -33,10 +33,17 @@ export function proxyImg(url: string, settings?: ImgProxySettings, resize?: numb
|
||||
}
|
||||
if (!settings) return url;
|
||||
if (url.startsWith("data:") || url.startsWith("blob:") || url.length == 0) return url;
|
||||
const opt = resize ? `rs:fit:${resize}:${resize}/dpr:${window.devicePixelRatio}` : "";
|
||||
const opts = [];
|
||||
if (sha256) {
|
||||
opts.push(`hs:sha256:${sha256}`);
|
||||
}
|
||||
if (resize) {
|
||||
opts.push(`rs:fit:${resize}:${resize}`);
|
||||
opts.push(`dpr:${window.devicePixelRatio}`);
|
||||
}
|
||||
const urlBytes = te.encode(url);
|
||||
const urlEncoded = urlSafe(base64.encode(urlBytes));
|
||||
const path = `/${opt}/${urlEncoded}`;
|
||||
const path = `/${opts.join("/")}/${urlEncoded}`;
|
||||
const sig = signUrl(path);
|
||||
return `${new URL(settings.url).toString()}${sig}${path}`;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user