ui: mask API Key field in settings and error splash to stop browser a… (#26562)
* 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 <admin@serveurperso.com>
This commit is contained in:
co-authored by
Pascal
parent
0d9ceae1e3
commit
ece963f41b
@@ -158,6 +158,8 @@
|
|||||||
<div class="relative">
|
<div class="relative">
|
||||||
<Input
|
<Input
|
||||||
id="api-key-input"
|
id="api-key-input"
|
||||||
|
type="password"
|
||||||
|
autocomplete="new-password"
|
||||||
placeholder="Enter your API key..."
|
placeholder="Enter your API key..."
|
||||||
bind:value={apiKeyInput}
|
bind:value={apiKeyInput}
|
||||||
onkeydown={handleApiKeyKeydown}
|
onkeydown={handleApiKeyKeydown}
|
||||||
|
|||||||
@@ -81,7 +81,8 @@
|
|||||||
<div class="relative w-full">
|
<div class="relative w-full">
|
||||||
<Input
|
<Input
|
||||||
id={field.key}
|
id={field.key}
|
||||||
type={field.isPositiveInteger ? 'number' : 'text'}
|
type={field.isPrivate ? 'password' : field.isPositiveInteger ? 'number' : 'text'}
|
||||||
|
autocomplete={field.isPrivate ? 'new-password' : undefined}
|
||||||
{...field.isPositiveInteger
|
{...field.isPositiveInteger
|
||||||
? {
|
? {
|
||||||
min: String(field.min ?? 1),
|
min: String(field.min ?? 1),
|
||||||
|
|||||||
@@ -324,6 +324,7 @@ const SETTINGS_REGISTRY: Record<string, SettingsSectionEntry> = {
|
|||||||
{
|
{
|
||||||
defaultValue: '',
|
defaultValue: '',
|
||||||
help: `Set the API Key if you are using <code> ${CLI_FLAGS.API_KEY} </code> option for the server.`,
|
help: `Set the API Key if you are using <code> ${CLI_FLAGS.API_KEY} </code> option for the server.`,
|
||||||
|
isPrivate: true,
|
||||||
key: SETTINGS_KEYS.API_KEY,
|
key: SETTINGS_KEYS.API_KEY,
|
||||||
label: 'API Key',
|
label: 'API Key',
|
||||||
section: SETTINGS_SECTION_SLUGS.GENERAL,
|
section: SETTINGS_SECTION_SLUGS.GENERAL,
|
||||||
@@ -713,6 +714,7 @@ export const SETTINGS_CHAT_SECTIONS: SettingsSection[] = [
|
|||||||
help: s.help,
|
help: s.help,
|
||||||
isExperimental: s.isExperimental,
|
isExperimental: s.isExperimental,
|
||||||
isPositiveInteger: s.isPositiveInteger,
|
isPositiveInteger: s.isPositiveInteger,
|
||||||
|
isPrivate: s.isPrivate,
|
||||||
key: s.key,
|
key: s.key,
|
||||||
label: s.label,
|
label: s.label,
|
||||||
max: s.max,
|
max: s.max,
|
||||||
|
|||||||
Vendored
+2
@@ -31,6 +31,7 @@ export interface SettingsEntry {
|
|||||||
radioOptions?: Array<{ value: string; label: string; key: string; isExperimental?: boolean }>;
|
radioOptions?: Array<{ value: string; label: string; key: string; isExperimental?: boolean }>;
|
||||||
isExperimental?: boolean;
|
isExperimental?: boolean;
|
||||||
isPositiveInteger?: boolean;
|
isPositiveInteger?: boolean;
|
||||||
|
isPrivate?: boolean;
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
min?: number;
|
min?: number;
|
||||||
max?: number;
|
max?: number;
|
||||||
@@ -55,6 +56,7 @@ export interface SettingsFieldConfig {
|
|||||||
type: SettingsFieldType;
|
type: SettingsFieldType;
|
||||||
isExperimental?: boolean;
|
isExperimental?: boolean;
|
||||||
isPositiveInteger?: boolean;
|
isPositiveInteger?: boolean;
|
||||||
|
isPrivate?: boolean;
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
min?: number;
|
min?: number;
|
||||||
max?: number;
|
max?: number;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user