From 7c2aa0d739c55ee728d4bc535646e7be9310990d Mon Sep 17 00:00:00 2001 From: Zac Gaetano Date: Mon, 6 Apr 2026 21:45:08 -0400 Subject: [PATCH] fix: extension Save & Connect stuck on connecting state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Login failures (wrong password) were caught by the 401 handler in apiFetch() which threw "Session expired" instead of returning the actual error message. Now /api/login 401 responses pass through so the real "Invalid credentials" error is shown. - Settings panel now shows error messages from login() failures instead of staying stuck on "Saved — connecting…" forever. Co-Authored-By: Claude Sonnet 4.6 --- chrome-extension/popup.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/chrome-extension/popup.js b/chrome-extension/popup.js index 231ee2a..a8fb5c9 100644 --- a/chrome-extension/popup.js +++ b/chrome-extension/popup.js @@ -87,9 +87,11 @@ async function login() { await loadFolders(); } else { setConnStatus('red', r.error || 'Auth failed'); + showSettingsStatus(`❌ ${r.error || 'Auth failed'}`, 'error'); } } catch (e) { setConnStatus('red', 'Connection failed'); + showSettingsStatus(`❌ ${e.message || 'Connection failed'}`, 'error'); } } @@ -310,7 +312,12 @@ async function apiFetch(method, path, body) { if (authToken) opts.headers['x-auth-token'] = authToken; if (body) opts.body = JSON.stringify(body); const r = await fetch(url, opts); - if (r.status === 401) { authToken = null; await chrome.storage.local.remove('token'); throw new Error('Session expired'); } + // Don't treat 401 on /api/login as session expiry — it's just bad credentials + if (r.status === 401 && !path.includes('/api/login')) { + authToken = null; + await chrome.storage.local.remove('token'); + throw new Error('Session expired'); + } return r.json(); }