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
6 changed files with 5046 additions and 3271 deletions
|
|
@ -83,7 +83,7 @@ describe("InspectorClient EMA E2E", () => {
|
|||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
clearAllOAuthClientState();
|
||||
await clearAllOAuthClientState();
|
||||
vi.spyOn(console, "log").mockImplementation(() => {});
|
||||
|
||||
const keys = await createEmaMockKeyMaterial();
|
||||
|
|
@ -199,14 +199,12 @@ describe("InspectorClient EMA E2E", () => {
|
|||
await flushStoreFileWrites(oauthTestStatePath);
|
||||
|
||||
const raw = JSON.parse(await fs.readFile(oauthTestStatePath, "utf-8")) as {
|
||||
state: {
|
||||
servers: Record<
|
||||
string,
|
||||
{ tokens?: { access_token?: string }; enterpriseManaged?: boolean }
|
||||
>;
|
||||
};
|
||||
servers: Record<
|
||||
string,
|
||||
{ tokens?: { access_token?: string }; enterpriseManaged?: boolean }
|
||||
>;
|
||||
};
|
||||
const entry = raw.state.servers[mcpUrl];
|
||||
const entry = raw.servers[mcpUrl];
|
||||
expect(entry?.tokens?.access_token).toBeDefined();
|
||||
expect(entry?.enterpriseManaged).toBe(true);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -91,9 +91,9 @@ describe("InspectorClient OAuth E2E", () => {
|
|||
}
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
beforeEach(async () => {
|
||||
clearOAuthTestData();
|
||||
clearAllOAuthClientState();
|
||||
await clearAllOAuthClientState();
|
||||
// Capture console.log output instead of printing to stdout during tests
|
||||
vi.spyOn(console, "log").mockImplementation(() => {});
|
||||
});
|
||||
|
|
@ -630,7 +630,7 @@ describe("InspectorClient OAuth E2E", () => {
|
|||
expect(client.getStatus()).toBe("connected");
|
||||
|
||||
await client.disconnect();
|
||||
client.clearOAuthTokens();
|
||||
await client.clearOAuthTokens();
|
||||
|
||||
const authUrlSecond = await client.authenticate();
|
||||
if (!authUrlSecond) throw new Error("Expected authorization URL");
|
||||
|
|
@ -995,7 +995,7 @@ describe("InspectorClient OAuth E2E", () => {
|
|||
expect(tokens?.access_token).toBeDefined();
|
||||
expect(await client.isOAuthAuthorized()).toBe(true);
|
||||
|
||||
client.clearOAuthTokens();
|
||||
await client.clearOAuthTokens();
|
||||
expect(await client.isOAuthAuthorized()).toBe(false);
|
||||
expect(await client.getOAuthTokens()).toBeUndefined();
|
||||
});
|
||||
|
|
@ -1072,16 +1072,14 @@ describe("InspectorClient OAuth E2E", () => {
|
|||
expect(client.getStatus()).toBe("connected");
|
||||
|
||||
type StateShape = {
|
||||
state?: {
|
||||
servers?: Record<string, { tokens?: { access_token?: string } }>;
|
||||
};
|
||||
servers?: Record<string, { tokens?: { access_token?: string } }>;
|
||||
};
|
||||
// Persistence is fire-and-forget; await the write rather than polling.
|
||||
await flushStoreFileWrites(customPath);
|
||||
const parsed = JSON.parse(
|
||||
await fs.readFile(customPath, "utf-8"),
|
||||
) as StateShape;
|
||||
const servers = parsed.state?.servers ?? {};
|
||||
const servers = parsed.servers ?? {};
|
||||
expect(Object.keys(servers).length).toBeGreaterThan(0);
|
||||
expect(
|
||||
Object.values(servers).some((s) => !!s?.tokens?.access_token),
|
||||
|
|
|
|||
|
|
@ -388,7 +388,7 @@ describe("InspectorClient remote mid-session OAuth", () => {
|
|||
expect(recovery?.authChallenge.reason).toBe("insufficient_scope");
|
||||
|
||||
const mcpServerUrl = `${serverUrl}/mcp`;
|
||||
const scopeBeforeStepUp = oauthConfig.storage.getScope(mcpServerUrl);
|
||||
const scopeBeforeStepUp = await oauthConfig.storage.getScope(mcpServerUrl);
|
||||
expect(scopeBeforeStepUp).toContain("mcp");
|
||||
expect(scopeBeforeStepUp).not.toContain("weather:read");
|
||||
|
||||
|
|
@ -413,7 +413,7 @@ describe("InspectorClient remote mid-session OAuth", () => {
|
|||
|
||||
expect(callbackClient.getStatus()).toBe("connected");
|
||||
|
||||
const scopeAfterStepUp = oauthConfig.storage.getScope(mcpServerUrl);
|
||||
const scopeAfterStepUp = await oauthConfig.storage.getScope(mcpServerUrl);
|
||||
expect(scopeAfterStepUp).toContain("weather:read");
|
||||
expect(scopeAfterStepUp).toContain("mcp");
|
||||
|
||||
|
|
|
|||
|
|
@ -352,18 +352,11 @@ describe("InspectorClient OAuth E2E with Remote Storage", () => {
|
|||
remoteAuthToken!,
|
||||
(body) => {
|
||||
const b = body as {
|
||||
state?: {
|
||||
servers?: Record<
|
||||
string,
|
||||
{ tokens?: { access_token?: string } }
|
||||
>;
|
||||
};
|
||||
servers?: Record<string, { tokens?: { access_token?: string } }>;
|
||||
};
|
||||
return !!(
|
||||
b?.state?.servers &&
|
||||
Object.values(b.state.servers).some(
|
||||
(s) => s?.tokens?.access_token,
|
||||
)
|
||||
b?.servers &&
|
||||
Object.values(b.servers).some((s) => s?.tokens?.access_token)
|
||||
);
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -173,8 +173,8 @@ describe("InspectorClient OAuth", () => {
|
|||
expect(tokens).toBeUndefined();
|
||||
});
|
||||
|
||||
it("should clear OAuth tokens", () => {
|
||||
client.clearOAuthTokens();
|
||||
it("should clear OAuth tokens", async () => {
|
||||
await client.clearOAuthTokens();
|
||||
// Should not throw
|
||||
expect(client).toBeDefined();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -4959,7 +4959,7 @@ describe("InspectorClient", () => {
|
|||
expect(c.getOAuthFlowState()).toBeUndefined();
|
||||
await expect(c.getOAuthState()).resolves.toBeUndefined();
|
||||
// clearOAuthTokens is a no-op when there is no manager
|
||||
expect(() => c.clearOAuthTokens()).not.toThrow();
|
||||
await expect(c.clearOAuthTokens()).resolves.toBeUndefined();
|
||||
});
|
||||
|
||||
it("setOAuthConfig throws when oauthManager is unset", () => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue