mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 05:30:42 +00:00
fix(googlechat): isolate auth transports
This commit is contained in:
@@ -61,6 +61,7 @@ Docs: https://docs.openclaw.ai
|
||||
### Fixes
|
||||
|
||||
- Control UI/Talk: make failed Talk startup errors dismissable and clear the stale Talk error state when dismissed, so missing realtime voice provider configuration does not leave a permanent chat banner. Fixes #77071. Thanks @ijoshdavis.
|
||||
- Google Chat: create an isolated Google auth transport per auth client, so google-auth-library interceptor mutations do not accumulate across webhook verification and access-token clients. Thanks @vincentkoc.
|
||||
- Control UI/performance: cap long-task and long-animation-frame diagnostics in the shared event log, so slow-render telemetry does not evict gateway/plugin events from the Debug and Overview views. Thanks @vincentkoc.
|
||||
- Web fetch: late-bind `web_fetch` config and provider fallback metadata from the active runtime snapshot, matching `web_search` so long-lived tools do not use stale fetch provider settings. Thanks @vincentkoc.
|
||||
- Discord: clear stale startup probe bot/application status when the async bot probe throws, not just when it returns a degraded probe result. Thanks @vincentkoc.
|
||||
|
||||
@@ -359,6 +359,18 @@ describe("googlechat google auth runtime", () => {
|
||||
}
|
||||
});
|
||||
|
||||
it("keeps auth transports isolated from google-auth interceptor mutations", async () => {
|
||||
const first = await getGoogleAuthTransport();
|
||||
const second = await getGoogleAuthTransport();
|
||||
|
||||
expect(first).not.toBe(second);
|
||||
expect(mocks.gaxiosCtor).toHaveBeenCalledTimes(2);
|
||||
expect(first.interceptors.request.add).toHaveBeenCalledOnce();
|
||||
expect(first.interceptors.response.add).toHaveBeenCalledOnce();
|
||||
expect(second.interceptors.request.add).toHaveBeenCalledOnce();
|
||||
expect(second.interceptors.response.add).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
it("normalizes Google auth request headers before upstream interceptors run", async () => {
|
||||
const config = {
|
||||
headers: { "x-test": "1" },
|
||||
|
||||
@@ -71,7 +71,6 @@ const MAX_GOOGLE_AUTH_RESPONSE_BYTES = 1024 * 1024;
|
||||
const MAX_GOOGLE_CHAT_SERVICE_ACCOUNT_FILE_BYTES = 64 * 1024;
|
||||
|
||||
let googleAuthRuntimePromise: Promise<GoogleAuthRuntime> | null = null;
|
||||
let googleAuthTransportPromise: Promise<GoogleAuthTransport> | null = null;
|
||||
|
||||
function normalizeGoogleAuthPreparedRequestHeaders<T extends GoogleAuthRequestWithUnknownHeaders>(
|
||||
config: T,
|
||||
@@ -536,22 +535,12 @@ export async function loadGoogleAuthRuntime(): Promise<GoogleAuthRuntime> {
|
||||
}
|
||||
|
||||
export async function getGoogleAuthTransport(): Promise<GoogleAuthTransport> {
|
||||
if (!googleAuthTransportPromise) {
|
||||
googleAuthTransportPromise = (async () => {
|
||||
try {
|
||||
const { Gaxios } = await loadGoogleAuthRuntime();
|
||||
return installGoogleAuthHeaderCompatibilityInterceptor(
|
||||
new Gaxios({
|
||||
fetchImplementation: createGoogleAuthFetch(),
|
||||
}),
|
||||
);
|
||||
} catch (error) {
|
||||
googleAuthTransportPromise = null;
|
||||
throw error;
|
||||
}
|
||||
})();
|
||||
}
|
||||
return await googleAuthTransportPromise;
|
||||
const { Gaxios } = await loadGoogleAuthRuntime();
|
||||
return installGoogleAuthHeaderCompatibilityInterceptor(
|
||||
new Gaxios({
|
||||
fetchImplementation: createGoogleAuthFetch(),
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
export async function resolveValidatedGoogleChatCredentials(
|
||||
@@ -570,7 +559,6 @@ export async function resolveValidatedGoogleChatCredentials(
|
||||
export const __testing = {
|
||||
resetGoogleAuthRuntimeForTests(): void {
|
||||
googleAuthRuntimePromise = null;
|
||||
googleAuthTransportPromise = null;
|
||||
},
|
||||
normalizeGoogleAuthPreparedRequestHeaders,
|
||||
normalizeGoogleAuthResponseHeaders,
|
||||
|
||||
Reference in New Issue
Block a user