diff --git a/static/js/app.js b/static/js/app.js index 23dbcf1..b3a76ac 100644 --- a/static/js/app.js +++ b/static/js/app.js @@ -2611,13 +2611,15 @@ async function loadBookList() { listEl.innerHTML = '
Loading…
'; try { - const res = await fetch('/books/'); + const res = await fetch('/books/', {cache: 'no-store'}); if (!res.ok) { + console.error('loadBookList: server returned', res.status); listEl.innerHTML = `Server error ${res.status} loading books.
`; return; } const books = await res.json(); if (!Array.isArray(books)) { + console.error('loadBookList: unexpected response', books); listEl.innerHTML = `Unexpected response from server.
`; return; } @@ -2626,22 +2628,32 @@ async function loadBookList() { return; } - const key = await getOrCreateEncKey(); + let key; + try { + key = await getOrCreateEncKey(); + } catch (e) { + console.error('loadBookList: getOrCreateEncKey failed', e); + listEl.innerHTML = `Encryption not available: ${e.message}. Make sure you are on HTTPS.
`; + return; + } + const decrypted = []; for (const b of books) { try { const metaBuf = await decryptBytes(key, b.meta_iv, b.meta_ct); const meta = JSON.parse(new TextDecoder().decode(metaBuf)); bookMetaCache[b.id] = {title: meta.title || '?', author: meta.author || '', type: meta.type || 'epub'}; - decrypted.push({id: b.id, title: meta.title || '?', author: meta.author || '', type: meta.type || 'epub', scroll_fraction: b.scroll_fraction, uploaded_at: b.uploaded_at}); + decrypted.push({id: b.id, title: meta.title || '?', author: meta.author || '', type: meta.type || 'epub', scroll_fraction: b.scroll_fraction, uploaded_at: b.uploaded_at, keyOk: true}); } catch (e) { + console.warn(`loadBookList: could not decrypt book #${b.id}:`, e.message); bookMetaCache[b.id] = {title: `Book #${b.id}`, author: '', type: 'epub'}; - decrypted.push({id: b.id, title: `Book #${b.id}`, author: '', type: 'epub', scroll_fraction: b.scroll_fraction, uploaded_at: b.uploaded_at}); + decrypted.push({id: b.id, title: `Book #${b.id}`, author: '', type: 'epub', scroll_fraction: b.scroll_fraction, uploaded_at: b.uploaded_at, keyOk: false}); } } renderBookList(decrypted); } catch (e) { - if (listEl) listEl.innerHTML = `Error: ${e.message}
`; + console.error('loadBookList error:', e); + if (listEl) listEl.innerHTML = `Error loading books: ${e.message}
`; } } @@ -2651,14 +2663,15 @@ function renderBookList(books) { let html = ''; for (const b of books) { const pct = Math.round((b.scroll_fraction || 0) * 100); + const keyWarning = b.keyOk === false ? '⚠️ wrong key' : ''; html += `Failed to open book: ${escapeHtml(e.message)}
`; + overlay.style.display = 'none'; + alert(`Failed to open book: ${e.message}`); } }