fix: send auth when downloading an image from the image preview

The preview's Download button fetched the image URL with no credentials.
Backend file URLs (/api/v1/files/{id}/content) require authentication, so
the request returned 401 — and because the response status was never
checked, the JSON error body was saved as the downloaded file
(generated_image.json containing {"detail":"Not authenticated"}).

Sends the bearer token when the target is this deployment's own backend.
That is not necessarily the page origin: in development the frontend is
served from a separate origin and WEBUI_BASE_URL points at the backend, so
a same-origin-only check would still fail there. A third-party image host
never receives the token.

Also rejects a non-OK response instead of writing its body to disk, and
surfaces failures as a toast rather than a console-only error.
This commit is contained in:
silentoplayz 2026-07-30 00:14:26 -04:00
parent 810378c0b8
commit 7b3d7a0eba

View file

@ -1,9 +1,11 @@
<script lang="ts">
import { onDestroy, getContext } from 'svelte';
import { toast } from 'svelte-sonner';
import fileSaver from 'file-saver';
const { saveAs } = fileSaver;
import { WEBUI_BASE_URL } from '$lib/constants';
import PanzoomContainer from '$lib/components/common/PanzoomContainer.svelte';
import XMark from '$lib/components/icons/XMark.svelte';
@ -119,9 +121,35 @@
src.startsWith('http://') ||
src.startsWith('https://')
) {
// Handle remote URLs
fetch(src)
.then((response) => response.blob())
const ownOrigins = new Set([window.location.origin]);
if (WEBUI_BASE_URL) {
try {
ownOrigins.add(new URL(WEBUI_BASE_URL, window.location.origin).origin);
} catch {
}
}
let isOwnBackend = src.startsWith('/');
if (!isOwnBackend) {
try {
isOwnBackend = ownOrigins.has(new URL(src).origin);
} catch {
isOwnBackend = false;
}
}
fetch(
src,
isOwnBackend && localStorage.token
? { headers: { Authorization: `Bearer ${localStorage.token}` } }
: undefined
)
.then((response) => {
if (!response.ok) {
throw new Error(`Failed to download image: ${response.status}`);
}
return response.blob();
})
.then((blob) => {
// detect the MIME type from the blob
const mimeType = blob.type || 'image/png';
@ -140,6 +168,7 @@
})
.catch((error) => {
console.error('Error downloading remote image:', error);
toast.error($i18n.t('Failed to download image'));
});
return;
}