* test: cover EMA interactive leg 1 end-to-end (#1693)
The EMA e2e suite only drove silent EMA (seeded IdP session + legs 2–3);
the interactive leg-1 authorization-code exchange — the exact path that
broke in #1688 (a dropped RFC 9207 iss) — had no e2e coverage.
- Extend the mock IdP (ema-mock-servers.ts) with an interactive
authorization endpoint (GET /authorize auto-approves and redirects with
code + state + RFC 9207 iss) and an authorization_code branch on
POST /token (client-cred + PKCE S256 check → id_token). The IdP metadata
already advertises authorization_response_iss_parameter_supported, so the
SDK enforces iss on the exchange.
- Add two leg-1 e2e tests: the full authorize → callback(iss) → id_token →
resource-token → connect ladder, and the RFC 9207 guard that a missing
callback iss rejects the exchange before any token is stored.
Part 1 of #1693 (composable test-server AS advertising + emitting iss, plus
standard-OAuth iss coverage) already landed in #1725.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XNdjEPKLG637X8YmhDiEk5
* test: apply review nits — simplify iss regex, dedupe redirect provider
Address non-blocking review nits on #1693:
- Drop the redundant `Issuer mismatch|` alternation from the guard test's
matcher; `/issuer/i` already matches (case-insensitive).
- Export `createStaticRedirectUrlProvider` from the shared oauth fixtures
helper and reuse it in the EMA e2e, removing the local duplicate.
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>