inspector/core/client
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Cliff Hall 4a927d3978
fix(web): defer issuer validation to onBlur, block silent-drop on close, require a real host URL (closes #1544) (#1545)
* fix(web): defer IdP issuer URL error to onBlur in Client Settings (#1544)

The Enterprise-Managed Authorization Issuer field validated its URL inline on
every render, so the 'Must be an http(s) URL' error nagged while the user was
still mid-typing (e.g. before 'https:/…' is complete).

Gate the issuer error display on an issuerTouched flag set onBlur; once
touched it tracks the value live, so the error clears as soon as a valid URL
is entered. The persist gate (canPersistClientSettingsDraft → validateClientSettings)
is unchanged and still validates independently, so an invalid issuer is never
written to the backend regardless of touched state.

Closes #1544

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(web): reveal issuer error and block close on invalid issuer (#1544)

Extend the on-blur deferral so an invalid issuer can't be silently dropped on
modal close (the auto-save flush would otherwise discard it with no feedback).

ClientSettingsModal now intercepts its close (X / Esc / overlay): if the issuer
is invalid it reveals the field error (via the form's revealIssuerError prop,
overriding on-blur gating) and keeps the modal open instead of closing. The
user can fix the URL or clear the field — an empty issuer is valid to leave.
The block lives in the modal (unit-tested) rather than App, so App.tsx stays a
thin flush+close that only runs when the close is allowed; the persist gate is
unchanged. Reveal state resets via the modal's open/close remount key.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(core): require a real host in isAbsoluteHttpUrl, not just an http(s) scheme (#1544)

The issuer validation used URL.canParse + an http(s) protocol check, which the
WHATWG parser accepts for bare/degenerate values that aren't actually usable
URLs — e.g. https://foo, https://example, https://. , https://.. all passed.

Tighten the shared rule (used by both the Zod config schema and the form's
inline validation): after parsing and the http(s) scheme check, require the
host to actually look like a host — localhost, an IPv6 literal, or a dotted
domain/IPv4 with at least two non-empty labels. Single-label, bare-dot, and
empty-label hosts are now rejected. Add core tests for the accepted
(dotted/IPv4/IPv6/localhost) and newly-rejected cases.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 11:56:27 -04:00
..
config-parse.ts fix(web): defer issuer validation to onBlur, block silent-drop on close, require a real host URL (closes #1544) (#1545) 2026-06-29 11:56:27 -04:00
config.ts feat(web,core): enterprise-managed authorization (EMA) (#1509) (#1512) 2026-06-24 22:15:12 -04:00
index.ts feat(web,core): enterprise-managed authorization (EMA) (#1509) (#1512) 2026-06-24 22:15:12 -04:00
node-persistence.ts feat(web,core): enterprise-managed authorization (EMA) (#1509) (#1512) 2026-06-24 22:15:12 -04:00
remote.ts feat(web,core): enterprise-managed authorization (EMA) (#1509) (#1512) 2026-06-24 22:15:12 -04:00
secrets.ts feat(web,core): enterprise-managed authorization (EMA) (#1509) (#1512) 2026-06-24 22:15:12 -04:00
types.ts feat(web,core): enterprise-managed authorization (EMA) (#1509) (#1512) 2026-06-24 22:15:12 -04:00