fix(web): silence the stale gate hint, clear whitespace fields, narrow the paste heuristic

This commit is contained in:
Yichen Jiang
2026-08-07 11:35:23 +08:00
parent 91e9d5afa2
commit 5a422337f8
8 changed files with 55 additions and 11 deletions

View File

@@ -93,6 +93,10 @@ export function CustomProviderCard(props: CustomProviderCardProps): ReactNode {
// because its own field already explains itself, and a satisfied card says
// nothing at all rather than printing an empty paragraph.
const hint = failure !== undefined || ready
// The key field prints its own failure directly beneath itself, so a card
// blocked only by the key stays silent here rather than answering with the
// next unmet gate — which is satisfied, and reads as a second, false fault.
|| keyFailure !== undefined
? undefined
: baseURL.length === 0
? t('customNeedsBaseUrl')

View File

@@ -167,7 +167,12 @@ export function ProviderEditor(props: ProviderEditorProps): ReactNode {
return typeof value === 'string' && value.trim().length > 0 ? value : undefined
}
const setField = (key: string, next: string | undefined): void => {
setDraft(current => next === undefined ? deletePath(current, [key]) : setPath(current, [key], next))
// A value of nothing but whitespace is cleared, not stored: `stringAt`
// already reports it as absent, so the field would otherwise render empty
// while the draft still carried the spaces into `settings.yaml`, where
// both adapters would accept that non-empty string as a real value.
const value = next === undefined || next.trim().length === 0 ? undefined : next
setDraft(current => value === undefined ? deletePath(current, [key]) : setPath(current, [key], value))
}
// The model list is validated by the same per-row checker for both families,

View File

@@ -12,13 +12,15 @@
const LEGAL_API_KEY = /^[\x21-\x7E]+$/
/**
* A pasted `NAME=value` environment line. Restricted to an upper-case
* identifier so a real key cannot match: `sk-` forms break at the hyphen.
* This heuristic runs only here — a resolver applying it could lock a user
* out of a gateway whose key legitimately takes this shape, with the
* environment refusing it too and no way through.
* A pasted `NAME=value` environment line. Two narrowings keep real keys clear
* of it: the name must be upper-case, so `sk-` forms break at the hyphen, and
* the `=` must be followed by something other than another `=`, so base64
* padding on an all-upper-case key (`ABCD==`) is not mistaken for an
* assignment. This heuristic runs only here — a resolver applying it could
* lock a user out of a gateway whose key legitimately takes this shape, with
* the environment refusing it too and no way through.
*/
const ENV_LINE = /^[A-Z][A-Z0-9_]*=/
const ENV_LINE = /^[A-Z][A-Z0-9_]*=[^=]/
/** Copy key naming why a typed key cannot be saved. */
export type ApiKeyFailureKey = 'keyBlank' | 'keyIllegalCharacters' | 'keyLooksWrapped'