Merge remote-tracking branch 'origin/v2/main' into 1579-wave-1
# Conflicts: # clients/cli/package-lock.json # clients/cli/package.json # clients/web/src/App.tsx # clients/web/src/lib/environmentFactory.test.ts # clients/web/src/lib/environmentFactory.ts # clients/web/src/lib/remoteOAuthStorage.test.ts # clients/web/src/lib/remoteOAuthStorage.ts # clients/web/src/test/core/auth/connection-state.test.ts # clients/web/src/test/core/auth/providers.test.ts # clients/web/src/test/core/auth/storage-browser.test.ts # clients/web/src/test/core/auth/storage-remote.test.ts # clients/web/src/test/core/mcp/oauthManager.test.ts # clients/web/src/test/integration/auth/node/storage.test.ts # clients/web/src/test/integration/storage/adapters.test.ts # clients/web/src/utils/clearServerOAuthState.test.ts # clients/web/src/utils/clearServerOAuthState.ts # core/auth/connection-state.ts # core/auth/oauth-storage.ts # core/auth/providers.ts # core/auth/storage.ts # core/auth/store.ts # core/storage/adapters/remote-storage.ts
This commit is contained in:
commit
32a3610737
1 changed files with 5046 additions and 3271 deletions
|
|
@ -86,10 +86,7 @@ import { useServers } from "@inspector/core/react/useServers.js";
|
|||
import { useSettingsDraft } from "@inspector/core/react/useSettingsDraft.js";
|
||||
import { useClientSettingsDraft } from "@inspector/core/react/useClientSettingsDraft.js";
|
||||
import { useEmaIdpLoginState } from "@inspector/core/react/useEmaIdpLoginState.js";
|
||||
import {
|
||||
getRemoteOAuthStorage,
|
||||
getWebOAuthBaseUrl,
|
||||
} from "./lib/remoteOAuthStorage";
|
||||
import { getWebRemoteOAuthStorage } from "./lib/remoteOAuthStorage";
|
||||
import { useManagedTools } from "@inspector/core/react/useManagedTools.js";
|
||||
import { useManagedPrompts } from "@inspector/core/react/useManagedPrompts.js";
|
||||
import { useManagedResources } from "@inspector/core/react/useManagedResources.js";
|
||||
|
|
@ -1431,6 +1428,13 @@ function App() {
|
|||
[messages],
|
||||
);
|
||||
|
||||
// Shared OAuth runtime store (oauth.json via /api/storage/oauth). Memoized so
|
||||
// connect, EMA IdP session, and per-server clear share one in-memory view.
|
||||
const webOAuthStorage = useMemo(
|
||||
() => getWebRemoteOAuthStorage(getAuthToken()),
|
||||
[],
|
||||
);
|
||||
|
||||
// Backend-backed session storage used to carry the fetch (Network) log
|
||||
// across the OAuth full-page redirect. The auth handshake's first half —
|
||||
// protected-resource + auth-server discovery and Dynamic Client
|
||||
|
|
@ -2101,10 +2105,10 @@ function App() {
|
|||
// `onToggleConnection` unloaded the previous one), so all React state is
|
||||
// reset and we recover the initiating server from sessionStorage. We wait for
|
||||
// `servers` to hydrate before acting; the ref guard keeps the exchange to a
|
||||
// single run. The persisted PKCE verifier + DCR client info live in the
|
||||
// backend-backed `RemoteOAuthStorage` (`~/.mcp-inspector/storage/oauth.json`)
|
||||
// and survive the redirect, so `completeOAuthFlow` exchanges the code without
|
||||
// needing the original in-memory state machine.
|
||||
// single run. The persisted PKCE verifier + DCR client info live in shared
|
||||
// `RemoteOAuthStorage` (`oauth.json`) and survive the redirect, so
|
||||
// `completeOAuthFlow` exchanges the code without needing the original
|
||||
// in-memory state machine.
|
||||
useEffect(() => {
|
||||
if (typeof window === "undefined") return;
|
||||
if (window.location.pathname !== OAUTH_CALLBACK_PATH) return;
|
||||
|
|
@ -2212,6 +2216,15 @@ function App() {
|
|||
}
|
||||
|
||||
void (async () => {
|
||||
try {
|
||||
await webOAuthStorage.load();
|
||||
} catch (err) {
|
||||
connectStartRef.current = undefined;
|
||||
queueMicrotask(() => {
|
||||
showReAuthBanner(server.id, err instanceof Error ? err : String(err));
|
||||
});
|
||||
return;
|
||||
}
|
||||
const client = setupClientForServer(server, sessionId);
|
||||
setActiveServerId(server.id);
|
||||
try {
|
||||
|
|
@ -2267,7 +2280,7 @@ function App() {
|
|||
});
|
||||
}
|
||||
})();
|
||||
}, [servers, setupClientForServer, showReAuthBanner]);
|
||||
}, [servers, setupClientForServer, showReAuthBanner, webOAuthStorage]);
|
||||
|
||||
const onToggleConnection = useCallback(
|
||||
async (id: string) => {
|
||||
|
|
@ -3268,13 +3281,9 @@ function App() {
|
|||
|
||||
const clientSettingsModalValue = clientSettingsDraft ?? EMPTY_CLIENT_SETTINGS;
|
||||
|
||||
const emaOAuthStorage = useMemo(
|
||||
() => getRemoteOAuthStorage(getWebOAuthBaseUrl(), getAuthToken()),
|
||||
[],
|
||||
);
|
||||
const { loginState: emaIdpLoginState, logout: logoutEmaIdp } =
|
||||
useEmaIdpLoginState(
|
||||
emaOAuthStorage,
|
||||
webOAuthStorage,
|
||||
clientSettingsModalValue.emaEnabled
|
||||
? clientSettingsModalValue.issuer
|
||||
: undefined,
|
||||
|
|
@ -3298,14 +3307,11 @@ function App() {
|
|||
const clearServerOAuthAndDisconnect = useCallback(
|
||||
async (server: { id: string; name: string; config: MCPServerConfig }) => {
|
||||
const isActive = server.id === activeServerId;
|
||||
const cleared = clearServerOAuthState({
|
||||
const cleared = await clearServerOAuthState({
|
||||
config: server.config,
|
||||
inspectorClient: isActive ? inspectorClient : null,
|
||||
isActiveConnection: isActive,
|
||||
oauthStorage: getRemoteOAuthStorage(
|
||||
getWebOAuthBaseUrl(),
|
||||
getAuthToken(),
|
||||
),
|
||||
oauthStorage: webOAuthStorage,
|
||||
});
|
||||
if (!cleared) return;
|
||||
|
||||
|
|
@ -3331,6 +3337,7 @@ function App() {
|
|||
[
|
||||
activeServerId,
|
||||
inspectorClient,
|
||||
webOAuthStorage,
|
||||
finalizeExplicitDisconnect,
|
||||
clearOAuthResumeOnExplicitDisconnect,
|
||||
],
|
||||
|
|
|
|||
Loading…
Reference in a new issue