Server Settings: disambiguate EMA OAuth credential fields (#1692) (#1749)

* Server Settings: disambiguate EMA OAuth credential fields (#1692)

Under enterprise-managed authorization the OAuth Settings "Client ID" /
"Client Secret" fields hold the *resource authorization server* credentials
(EMA leg 3 — the Test Client from the xaa.dev resource registration), not the
app/IdP pair configured in Client Settings. The unqualified labels sat under a
toggle naming the enterprise IdP, pulling readers toward the wrong pair.

- When enterpriseManaged is on, relabel to "Resource AS Client ID" /
  "Resource AS Client Secret" and add a description naming the resource
  authorization server and pointing the app pair back to Client Settings.
- Document the Scopes delimiter: space-separated (RFC 6749), with a warning
  that commas produce one invalid token, plus a placeholder example.

Adds tests for both label states and the scopes hint, plus an
EnterpriseManagedOAuth story.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XNdjEPKLG637X8YmhDiEk5

* pr-screenshots: OAuth EMA field disambiguation proof shots (#1692)

Add before/after screenshots of the Server Settings → OAuth Settings fields
(EMA off = plain Client ID/Secret; EMA on = Resource AS Client ID/Secret) plus
the new space-separated Scopes hint, with a README section documenting them.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XNdjEPKLG637X8YmhDiEk5

* Address review: genericize EMA copy, reuse enterpriseManaged const (#1692)

- Drop the hardcoded xaa.dev staging host from the resource-AS field
  description (it's a general EMA concept, not env-specific); phrase it as
  "the resource authorization server's registered client credential (EMA leg
  3)". Also trims the copy's overlap with the checkbox description.
- Reuse the existing `enterpriseManaged` const for the EMA Checkbox's `checked`
  prop instead of recomputing `settings.enterpriseManaged ?? false`.
- Update the test assertion and pr-screenshots README/EMA-on screenshot to
  match the new copy.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XNdjEPKLG637X8YmhDiEk5

* Client Settings: mirror EMA disambiguation (IdP-qualified labels) (#1692)

The Server Settings OAuth fields now label the leg-3 resource-AS pair
explicitly; make Client Settings parallel so each modal names its pair and
points at where the other lives.

- Relabel the EMA credential fields to "IdP Client ID" / "IdP Client Secret"
  (parallel to Server Settings' "Resource AS Client ID/Secret"), so the label
  alone disambiguates without relying on the description.
- Add the reciprocal cross-reference to each description: these are the
  enterprise IdP pair (EMA legs 1–2), not the per-server resource authorization
  server credentials, which go in Server Settings → OAuth Settings.
- Update ClientSettingsForm/ClientSettingsModal tests for the new labels; add a
  pr-screenshots section + Client Settings screenshot.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XNdjEPKLG637X8YmhDiEk5

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Cliff Hall 2026-07-23 16:51:24 -04:00 • committed by GitHub
commit 402d7b204d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 131 additions and 12 deletions

View file

@ -475,7 +475,7 @@ describe("ClientSettingsForm interactions", () => {
/>,
);
await user.type(screen.getByLabelText("Client ID"), "x");
await user.type(screen.getByLabelText("IdP Client ID"), "x");
expect(onSettingsChange).toHaveBeenLastCalledWith(expect.any(Function));
expect(
resolveSettingsChange(
@ -485,7 +485,7 @@ describe("ClientSettingsForm interactions", () => {
).toBe("x");
onSettingsChange.mockClear();
await user.type(screen.getByLabelText("Client Secret"), "s");
await user.type(screen.getByLabelText("IdP Client Secret"), "s");
expect(onSettingsChange).toHaveBeenLastCalledWith(expect.any(Function));
expect(
resolveSettingsChange(

View file

@ -177,8 +177,8 @@ export function ClientSettingsForm({
}
/>
<TextInput
label="Client ID"
description="Client id registered with your enterprise IdP."
label="IdP Client ID"
description="Client id registered with your enterprise IdP (EMA legs 1–2) — not the per-server resource authorization server credentials, which go in Server Settings → OAuth Settings."
value={settings.clientId}
onChange={(e) => patch({ clientId: e.currentTarget.value })}
error={showClientIdError}
@ -190,8 +190,8 @@ export function ClientSettingsForm({
}
/>
<TextInput
label="Client Secret"
description="Client secret for your enterprise IdP (if required)."
label="IdP Client Secret"
description="Client secret for your enterprise IdP, if required (EMA legs 1–2) — not the per-server resource authorization server credentials, which go in Server Settings → OAuth Settings."
type="password"
value={settings.clientSecret}
onChange={(e) =>