test: pin the CIMD form copy; narrow the "no exemption" claim in the docs

Copilot review round 5. Two of three findings taken; the third rests on a false
premise about the SDK and is declined with evidence in the PR thread.

The hint and the input description are part of this fix's user-facing contract —
an HTTPS-only instruction there puts the local-fixture workflow back out of
reach even while the validator stays permissive — and nothing asserted them.
Two cases now do, plus one asserting a loopback http URL raises no error in the
form. Each mutation (restoring either piece of old copy) fails exactly one of
them.

The docs said there was "no loopback exemption at all" before #2305, which
contradicts the sentence above it: the runtime already tolerated an `http://`
already-stored `client_id`, and that asymmetry is what the issue is about. The
gap was in the config/form validator, and the wording now says so.

Also added: a note to use the canonical spelling of the host. `127.1` and
`2130706433` are accepted here and by the SDK, since both canonicalize to
`127.0.0.1` — but a CIMD `client_id` is string-compared by the authorization
server against the URL it dereferenced, so an exotic spelling is a real footgun
independent of what either validator allows.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GfHQ8vMm5NBgzbUJ6UwxmB
Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
cliffhall 2026-09-11 03:48:54 -04:00
commit 8baa1216fd

View file

@ -312,6 +312,60 @@ describe("ClientSettingsForm EMA IdP session", () => {
expect(screen.getByText(CIMD_METADATA_URL_HTTPS_ERROR)).toBeInTheDocument();
});
it("tells the reader the loopback exemption exists, in both pieces of CIMD copy", () => {
renderWithMantine(
<ClientSettingsForm
settings={{
...EMPTY_CLIENT_SETTINGS,
cimdEnabled: true,
clientMetadataUrl: "",
}}
expandedSections={["cimd"]}
onExpandedSectionsChange={vi.fn()}
onSettingsChange={vi.fn()}
emaIdpLoginState="none"
/>,
);
// The copy is part of this feature's contract, not decoration: the whole
// point of #2305 is that a local fixture URL is enterable, and an
// HTTPS-only instruction here puts that back out of reach for a reader
// even while the validator stays permissive. Both places that state the
// requirement are asserted, since either one alone would still mislead.
const hint = screen.getByText(/must be served over HTTPS/);
expect(hint).toHaveTextContent("localhost, 127.0.0.1 or [::1]");
expect(
screen.getByText(/HTTPS URL of your OAuth client metadata JSON document/),
).toHaveTextContent(
"http:// is accepted only on localhost, 127.0.0.1 or [::1]",
);
});
it("shows no CIMD URL error for a loopback http URL", () => {
renderWithMantine(
<ClientSettingsForm
settings={{
...EMPTY_CLIENT_SETTINGS,
cimdEnabled: true,
clientMetadataUrl: "http://localhost:8092/client-metadata.json",
}}
expandedSections={["cimd"]}
onExpandedSectionsChange={vi.fn()}
onSettingsChange={vi.fn()}
emaIdpLoginState="none"
revealErrors
/>,
);
expect(
screen.queryByText(CIMD_METADATA_URL_HTTPS_ERROR),
).not.toBeInTheDocument();
expect(
screen.queryByText(CIMD_METADATA_URL_INVALID_ERROR),
).not.toBeInTheDocument();
});
it("shows no CIMD URL error for a valid URL", () => {
renderWithMantine(
<ClientSettingsForm