fix(web): silence the stale gate hint, clear whitespace fields, narrow the paste heuristic
This commit is contained in:
@@ -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')
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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'
|
||||
|
||||
Reference in New Issue
Block a user