From 2fad4a726ccad0abf254d70d74912f34a47541a7 Mon Sep 17 00:00:00 2001 From: marwin Date: Thu, 19 Mar 2026 22:16:22 +0100 Subject: [PATCH] Fix Books tab: auto-generate encryption key, remove password prompt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - getOrCreateEncKey() now generates a random AES-GCM-256 key if none found in localStorage, instead of throwing an error - Removed enc-key-prompt div from player.html entirely - Simplified initBookDropZone() — removed prompt show/hide logic - book-upload-area always visible, no longer hidden behind prompt Co-Authored-By: Claude Sonnet 4.6 --- static/js/app.js | 20 ++++++++------------ templates/radio/player.html | 10 +--------- 2 files changed, 9 insertions(+), 21 deletions(-) diff --git a/static/js/app.js b/static/js/app.js index 2af86d7..5d37711 100644 --- a/static/js/app.js +++ b/static/js/app.js @@ -1813,16 +1813,20 @@ function hexToBytes(hex) { async function getOrCreateEncKey() { if (_encKey) return _encKey; - const storageKey = `diora_enc_key_${window.USER_ID || 'anon'}`; + const storageKey = `diora_enc_key_${window.USER_ID || 0}`; const stored = localStorage.getItem(storageKey); if (stored) { try { const raw = base64ToBytes(stored); _encKey = await crypto.subtle.importKey('raw', raw, {name: 'AES-GCM'}, false, ['encrypt', 'decrypt']); return _encKey; - } catch (e) { /* fall through */ } + } catch (e) { /* fall through, generate new */ } } - throw new Error('Encryption key not found — please log out and log in again.'); + // No key found — generate one and store it + _encKey = await crypto.subtle.generateKey({name: 'AES-GCM', length: 256}, true, ['encrypt', 'decrypt']); + const raw = await crypto.subtle.exportKey('raw', _encKey); + localStorage.setItem(storageKey, bytesToBase64(new Uint8Array(raw))); + return _encKey; } async function encryptBytes(key, plainBytes) { @@ -2205,14 +2209,6 @@ function initBookDropZone() { if (!zone || !zone.contains(e.target)) e.preventDefault(); }); - const storageKey = `diora_enc_key_${window.USER_ID || 'anon'}`; - const hasKey = !!localStorage.getItem(storageKey); - const prompt = $('enc-key-prompt'); - const uploadArea = $('book-upload-area'); - - if (prompt) prompt.style.display = hasKey ? 'none' : ''; - if (uploadArea) uploadArea.style.display = hasKey ? '' : 'none'; - const zone = $('book-drop-zone'); if (!zone) return; @@ -2245,7 +2241,7 @@ async function deriveAndStoreKey() { mat, {name: 'AES-GCM', length: 256}, true, ['encrypt', 'decrypt'] ); const raw = await crypto.subtle.exportKey('raw', key); - const storageKey = `diora_enc_key_${window.USER_ID || 'anon'}`; + const storageKey = `diora_enc_key_${window.USER_ID || 0}`; localStorage.setItem(storageKey, bytesToBase64(new Uint8Array(raw))); _encKey = null; // reset cached key if (statusEl) statusEl.textContent = '✓ Unlocked'; diff --git a/templates/radio/player.html b/templates/radio/player.html index 9ecc6cb..403d7ef 100644 --- a/templates/radio/player.html +++ b/templates/radio/player.html @@ -278,15 +278,7 @@