feat(web,core): enterprise-managed authorization (EMA) (#1509) (#1512)

Adds enterprise-managed authorization (EMA): browser-side IdP login + RFC 8693 token-exchange and JWT-bearer resource-token mint, per-server EMA opt-in in Server Settings, IdP config in Client Settings, and IdP clientSecret keychain storage. Includes the v2/main merge and review follow-ups (400 on malformed client config; normalizeIdpIssuer import consolidation).
This commit is contained in:
Bob Dickinson 2026-06-24 19:15:12 -07:00 • committed by GitHub
commit 5de4e911e3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -1,4 +1,4 @@
import type { OAuthStep, AuthGuidedState } from "./types.js";
import type { OAuthStep, OAuthFlowState } from "./types.js";
import type { BaseOAuthClientProvider } from "./providers.js";
import { discoverScopes, getAuthorizationServerUrl } from "./discovery.js";
import {
@ -15,10 +15,10 @@ import {
} from "@modelcontextprotocol/sdk/shared/auth.js";
export interface StateMachineContext {
state: AuthGuidedState;
state: OAuthFlowState;
serverUrl: string;
provider: BaseOAuthClientProvider;
updateState: (updates: Partial<AuthGuidedState>) => void;
updateState: (updates: Partial<OAuthFlowState>) => void;
fetchFn?: typeof fetch;
}
@ -258,13 +258,13 @@ export const oauthTransitions: Record<OAuthStep, StateTransition> = {
export class OAuthStateMachine {
private serverUrl: string;
private provider: BaseOAuthClientProvider;
private updateState: (updates: Partial<AuthGuidedState>) => void;
private updateState: (updates: Partial<OAuthFlowState>) => void;
private fetchFn?: typeof fetch;
constructor(
serverUrl: string,
provider: BaseOAuthClientProvider,
updateState: (updates: Partial<AuthGuidedState>) => void,
updateState: (updates: Partial<OAuthFlowState>) => void,
fetchFn?: typeof fetch,
) {
this.serverUrl = serverUrl;
@ -273,7 +273,7 @@ export class OAuthStateMachine {
this.fetchFn = fetchFn;
}
async executeStep(state: AuthGuidedState): Promise<void> {
async executeStep(state: OAuthFlowState): Promise<void> {
const context: StateMachineContext = {
state,
serverUrl: this.serverUrl,