From ece963f41b0b02d7a0d61436ae365762c073a4c8 Mon Sep 17 00:00:00 2001 From: Cristiano Pinto <140563307+crowmoed@users.noreply.github.com> Date: Sat, 15 Aug 2026 21:52:55 +0100 Subject: [PATCH] =?UTF-8?q?ui:=20mask=20API=20Key=20field=20in=20settings?= =?UTF-8?q?=20and=20error=20splash=20to=20stop=20browser=20a=E2=80=A6=20(#?= =?UTF-8?q?26562)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ui: mask API Key field in settings and error splash to stop browser autofill * ui: set autocomplete=new-password on private fields The password input type makes browsers offer to save the API key in the password manager and autofill saved site credentials into the field. The new-password autocomplete value disables both. --------- Co-authored-by: Pascal --- .../components/app/server/ServerErrorSplash.svelte | 2 ++ .../settings/SettingsChat/SettingsChatFields.svelte | 3 ++- .../src/lib/constants/settings-registry.constants.ts | 2 ++ tools/ui/src/lib/types/settings.d.ts | 2 ++ tools/ui/tests/unit/settings-private-fields.test.ts | 12 ++++++++++++ 5 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 tools/ui/tests/unit/settings-private-fields.test.ts diff --git a/tools/ui/src/lib/components/app/server/ServerErrorSplash.svelte b/tools/ui/src/lib/components/app/server/ServerErrorSplash.svelte index a2e23eecd..fbdbf19f2 100644 --- a/tools/ui/src/lib/components/app/server/ServerErrorSplash.svelte +++ b/tools/ui/src/lib/components/app/server/ServerErrorSplash.svelte @@ -158,6 +158,8 @@
= { { defaultValue: '', help: `Set the API Key if you are using ${CLI_FLAGS.API_KEY} option for the server.`, + isPrivate: true, key: SETTINGS_KEYS.API_KEY, label: 'API Key', section: SETTINGS_SECTION_SLUGS.GENERAL, @@ -713,6 +714,7 @@ export const SETTINGS_CHAT_SECTIONS: SettingsSection[] = [ help: s.help, isExperimental: s.isExperimental, isPositiveInteger: s.isPositiveInteger, + isPrivate: s.isPrivate, key: s.key, label: s.label, max: s.max, diff --git a/tools/ui/src/lib/types/settings.d.ts b/tools/ui/src/lib/types/settings.d.ts index 55f304ea2..d04837727 100644 --- a/tools/ui/src/lib/types/settings.d.ts +++ b/tools/ui/src/lib/types/settings.d.ts @@ -31,6 +31,7 @@ export interface SettingsEntry { radioOptions?: Array<{ value: string; label: string; key: string; isExperimental?: boolean }>; isExperimental?: boolean; isPositiveInteger?: boolean; + isPrivate?: boolean; placeholder?: string; min?: number; max?: number; @@ -55,6 +56,7 @@ export interface SettingsFieldConfig { type: SettingsFieldType; isExperimental?: boolean; isPositiveInteger?: boolean; + isPrivate?: boolean; placeholder?: string; min?: number; max?: number; diff --git a/tools/ui/tests/unit/settings-private-fields.test.ts b/tools/ui/tests/unit/settings-private-fields.test.ts new file mode 100644 index 000000000..0716b3cba --- /dev/null +++ b/tools/ui/tests/unit/settings-private-fields.test.ts @@ -0,0 +1,12 @@ +import { SETTINGS_CHAT_SECTIONS, SETTINGS_KEYS } from '$lib/constants'; +import { describe, expect, it } from 'vitest'; + +describe('checkApiKeyField', () => { + it('should have isPrivate set to true', () => { + const fields = SETTINGS_CHAT_SECTIONS.flatMap((section) => section.fields); + const apiKeyField = fields.find((field) => field?.key === SETTINGS_KEYS.API_KEY); + + expect(apiKeyField).toBeDefined(); + expect(apiKeyField?.isPrivate).toBe(true); + }); +});