From 6772bf7107cf97670e59ec81bec5aebcd3d089e8 Mon Sep 17 00:00:00 2001 From: Kolkman Date: Wed, 26 Aug 2026 16:11:11 +0200 Subject: [PATCH] Working logic to redirect to sessions --- VIBE/CHAT_LOG.md | 42 ++++++++++++++++++++ VIBE/PROMPTS.md | 7 ++++ XPI/unsigned/LinkLog-0.1.0.xpi | Bin 47869 -> 48274 bytes webextension/_locales/de/messages.json | 2 + webextension/_locales/en-US/messages.json | 6 +++ webextension/_locales/es/messages.json | 2 + webextension/_locales/fr/messages.json | 2 + webextension/_locales/nl/messages.json | 2 + webextension/popup.css | 15 ++++++++ webextension/popup.html | 3 +- webextension/popup.js | 45 ++++++++++++++++++++-- 11 files changed, 122 insertions(+), 4 deletions(-) diff --git a/VIBE/CHAT_LOG.md b/VIBE/CHAT_LOG.md index 0836147..f355271 100644 --- a/VIBE/CHAT_LOG.md +++ b/VIBE/CHAT_LOG.md @@ -849,6 +849,12 @@ Change the title of the field “One-time password” to “One-time password (w ### Assistant outcome Updated the OTP field label in the English, Spanish, German, French, and Dutch extension locale catalogs to clarify that the code is needed only when OTP is configured. +### User +The plugin settings still show `emailLabel`; make that `email` as the title for the email field. + +### Assistant outcome +Added the missing `emailLabel` and `emailPlaceholder` messages to every extension locale. The English field now resolves to `Email` instead of displaying the localization key. + ### User For the new password in the user setting add a validation field to make sure they are the same before submitting. @@ -914,3 +920,39 @@ Remove the “New primary email address” functionality and keep only selecting ### Assistant outcome Removed the replacement-email workflow entirely. Added cleanup migration 14 for its unused table; verified alternatives remain the only addresses eligible for primary selection. + +### User +When the user is logged in, the web plugin should not display “Please sign in to use LinkLog.” + +### Assistant outcome +Removed the authenticated-state warning flash by hiding the popup sign-in warning in the initial markup. The popup reveals it only after the session check confirms that no valid bearer session is available. + +### User +When the user is signed in, the plugin should not display “Please sign in to use LinkLog.” or the settings link. + +### Assistant outcome +Updated popup session detection to validate the stored bearer token through `/api/auth/me` before hiding the sign-in warning and revealing capture fields. Expired or invalid sessions now keep the warning and settings action visible. + +### User +The plugin still does not behave as expected and still shows that the user should sign in. + +### Assistant outcome +Centralized popup session validation, ensured valid bearer sessions hide the sign-in warning, and cleared stale credentials when the backend rejects a session. The capture form is shown only after successful validation. + +### User +In the popup show that the user has logged in. + +### Assistant outcome +Added a localized authenticated-session indicator to the Firefox popup, showing the returned username and backend URL after successful session validation. It remains hidden for signed-out or invalid sessions. + +### User +The popup still shows the sign-in block even though the authenticated session text is displayed; show the block only when signed out. + +### Assistant outcome +Made popup authentication states mutually exclusive using the DOM `hidden` property. Authenticated sessions now always hide the sign-in block, while signed-out sessions hide the session text and show only the warning block. + +### User +The authenticated session text and sign-in block are still shown together. + +### Assistant outcome +Made popup state transitions defensive by synchronizing both `hidden` attributes and CSS classes. Non-authentication tag-loading errors no longer switch the popup to signed-out state; only a rejected session does. Added `display: none !important` guards for both authentication blocks. diff --git a/VIBE/PROMPTS.md b/VIBE/PROMPTS.md index 6b14b71..791bc6f 100644 --- a/VIBE/PROMPTS.md +++ b/VIBE/PROMPTS.md @@ -147,6 +147,7 @@ 138. When the user is not logged in then the plugin should just display no form fields but warn the user that they have to log in with a link to settings. 139. Remove DEFAULT_BACKEND setting in the plugin. 140. Change the title of the field "One-time password" to "One-time password (when configured)". +157. The plugin settings still show 'emailLabel'; make that 'email' as title for the email field. 141. Remove any leading and trailing spaces when entering fields in the settings page of the plugin. 142. Do a full security audit document in what you have done in detail in Security-audit.md 143. Address issue 1. and improve password storage @@ -164,6 +165,12 @@ 152. Make sure an email can only be selected when it has been validated. 153. Remove the entire "New primary email address" block; keep only selecting an existing alternative as primary. 155. Remove the “New primary email address” functionality and keep only selecting an existing alternative as primary. +158. When the user is logged in the webplugin should not display "Please sign in to use LinkLog." +156. When the user is signed in the plugin should not display "Please sign in to use LinkLog." and the link to the settings +159. The plugin still does not behave as expected. It still shows that the user should sign in. +160. In the popup show that the user has logged in. +161. The popup still shows the sign-in block even though the authenticated session text is displayed; show the block only when signed out. +162. The authenticated session text and sign-in block are still shown together. ## Future entries diff --git a/XPI/unsigned/LinkLog-0.1.0.xpi b/XPI/unsigned/LinkLog-0.1.0.xpi index fbf392084f58299ebd48293234d90dc4d75f88a2..ca769e292687e814c728c828205ccefb5ed3b5f2 100644 GIT binary patch delta 13810 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 sQDuMx -
+ + diff --git a/webextension/popup.js b/webextension/popup.js index 1221e9f..e2ade98 100644 --- a/webextension/popup.js +++ b/webextension/popup.js @@ -12,6 +12,7 @@ const newTagsInput = document.getElementById('new-tags'); const feedLink = document.getElementById('feed-link'); const authWarning = document.getElementById('auth-warning'); const warningSettingsButton = document.getElementById('warning-settings'); +const authSession = document.getElementById('auth-session'); const t = window.linklogI18n; @@ -31,13 +32,36 @@ async function getSettings() { return result; } +async function validateSession(settings) { + if (!settings.backendUrl || !settings.accessToken) return null; + try { + const response = await fetch(`${settings.backendUrl}/api/auth/me`, { + headers: {'Authorization': `Bearer ${settings.accessToken}`}, + }); + if (!response.ok) { + await browser.storage.local.remove(['accessToken', 'tokenType', 'tokenExpiresAt', 'refreshToken']); + return null; + } + return await response.json(); + } catch (error) { + return null; + } +} + function showSignedOutState() { form.classList.add('hidden'); + authSession.hidden = true; + authSession.classList.add('hidden'); + authWarning.hidden = false; authWarning.classList.remove('hidden'); } -function showSignedInState() { +function showSignedInState(user, backendUrl) { + authWarning.hidden = true; authWarning.classList.add('hidden'); + authSession.textContent = t('loggedInAt', [user.username || user.email, backendUrl]); + authSession.hidden = false; + authSession.classList.remove('hidden'); form.classList.remove('hidden'); } @@ -59,12 +83,20 @@ async function loadExistingTags() { showSignedOutState(); return; } - showSignedInState(); + const user = await validateSession(settings); + if (!user) { + showSignedOutState(); + return; + } + showSignedInState(user, settings.backendUrl); const response = await fetch(`${settings.backendUrl}/api/tags`, { headers: {'Authorization': `Bearer ${settings.accessToken}`}, }); if (!response.ok) { - if (response.status === 401) showSignedOutState(); + if (response.status === 401) { + showSignedOutState(); + return; + } existingTags.textContent = t('loadTagsFailed'); return; } @@ -124,6 +156,13 @@ async function handleSubmit(event) { return; } + if (!await validateSession(settings)) { + showSignedOutState(); + setStatus(t('sessionExpired'), true); + browser.runtime.openOptionsPage(); + return; + } + try { const response = await fetch(`${backendUrl}/api/links`, { method: 'POST',