From c9a513abc0312aaa8e2efcf60ed2dfdf16f2f056 Mon Sep 17 00:00:00 2001 From: librelad Date: Tue, 18 Aug 2026 21:13:30 +0100 Subject: [PATCH] fix(webui): stop inventing a username on password-only app cards MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Login Details card fell back to the literal 'admin' when an app declared no user or email key, so speedtest — which has a single CFG_SPEEDTEST_PASSWORD_1 and no user concept at all — advertised "User: admin" to anyone reading its card. There is no such account; the field was fabricated by the fallback. Show the username row only when a user or email key actually exists, and the password row only when a password key does. eoCredList already omits any row whose value is null, so passing undefined for either half renders just the half that is real. Co-Authored-By: Claude Opus 5 --- .../components/apps/core/js/apps-manager.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/containers/libreportal/frontend/components/apps/core/js/apps-manager.js b/containers/libreportal/frontend/components/apps/core/js/apps-manager.js index b5a0ca1..dc6d268 100755 --- a/containers/libreportal/frontend/components/apps/core/js/apps-manager.js +++ b/containers/libreportal/frontend/components/apps/core/js/apps-manager.js @@ -977,14 +977,20 @@ class AppsManager { const passKeys = Object.keys(cfg).filter(k => loginKey('PASSWORD').test(k)); const emailVal = emailKeys[0] ? cfg[emailKeys[0]] : ''; const userVal = userKeys[0] ? cfg[userKeys[0]] : ''; - const identifier = emailVal || userVal || 'admin'; - const userLabel = (emailVal || (typeof identifier === 'string' && identifier.includes('@'))) ? 'Email' : 'User'; + // Only claim a username when the app actually declares one. This used to + // fall back to the literal 'admin', which invented a login name for + // password-only apps — speedtest has a single CFG_SPEEDTEST_PASSWORD_1 and + // no user concept at all, yet its card advertised "User: admin". + // eoCredList omits any row whose value is null, so passing undefined for + // either half renders just the half that exists. + const identifier = emailVal || userVal; + const userLabel = (emailVal || identifier.includes('@')) ? 'Email' : 'User'; if (userKeys[0] || emailKeys[0] || passKeys[0]) { creds.push({ title: `${app.name.split(' - ')[0]} Login`, - username: identifier, + username: identifier || undefined, userLabel, - password: cfg[passKeys[0]] || '(not generated)' + password: passKeys[0] ? (cfg[passKeys[0]] || '(not generated)') : undefined }); }