fix(uxp): fetch thumbnails via API.request() to carry Bearer token

img.src direct assignment never sends Authorization headers, so all
thumbnail requests returned 401 once the global auth gate was enabled.
Now fetches via API.request(), converts response to a blob URL, and
assigns that to img.src. Falls back to the placeholder div on error.
This commit is contained in:
Zac Gaetano 2026-05-28 09:41:26 -04:00
parent eeb0d9f65f
commit c3e4306d9f

View file

@ -125,25 +125,32 @@
Library._syncActions(); Library._syncActions();
}; };
// Fetch thumbnail with Bearer auth, assign as blob URL.
// img.src direct assignment never sends Authorization headers.
Library._loadThumb = function (assetId, img) {
API.request('/api/v1/assets/' + assetId + '/thumbnail?redirect=1')
.then(function (r) { return r.ok ? r.blob() : Promise.reject(new Error('HTTP ' + r.status)); })
.then(function (blob) { img.src = URL.createObjectURL(blob); })
.catch(function () {
const p = document.createElement('div');
p.className = 'asset-thumb-placeholder';
p.textContent = 'no preview';
if (img.parentNode) img.replaceWith(p);
});
};
Library._makeCard = function (asset) { Library._makeCard = function (asset) {
const card = document.createElement('div'); const card = document.createElement('div');
card.className = 'asset-card'; card.className = 'asset-card';
if (asset.id === Library.state.selectedId) card.classList.add('selected'); if (asset.id === Library.state.selectedId) card.classList.add('selected');
card.dataset.assetId = asset.id; card.dataset.assetId = asset.id;
// Thumbnail // Thumbnail — loaded async with auth header
const thumbUrl = `${API.state.serverUrl}/api/v1/assets/${asset.id}/thumbnail?redirect=1`;
const img = document.createElement('img'); const img = document.createElement('img');
img.className = 'asset-thumb'; img.className = 'asset-thumb';
img.alt = asset.display_name || asset.filename || asset.id; img.alt = asset.display_name || asset.filename || asset.id;
img.src = thumbUrl;
img.onerror = () => {
const p = document.createElement('div');
p.className = 'asset-thumb-placeholder';
p.textContent = 'no preview';
img.replaceWith(p);
};
card.appendChild(img); card.appendChild(img);
Library._loadThumb(asset.id, img);
// Status badge // Status badge
const status = (asset.status || 'ready').toLowerCase(); const status = (asset.status || 'ready').toLowerCase();