mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 09:10:45 +00:00
fix(googlechat): normalize auth response headers
This commit is contained in:
@@ -205,6 +205,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Feishu: accept and honor `channels.feishu.blockStreaming` at the top level and per account, while keeping the legacy default off so Feishu cards no longer reject documented config or silently drop block replies. Fixes #75555. Thanks @vincentkoc.
|
||||
- Gateway/update: avoid `launchctl kickstart -k` immediately after fresh macOS update bootstraps, and unlink dangling global plugin-runtime symlinks during packaged postinstall and `doctor --fix` so upgrades no longer SIGTERM the newly booted Gateway or leave bundled plugin imports pointed at pruned `plugin-runtime-deps` trees. Completes #76261 and fixes #76466. (#76929)
|
||||
- Google Chat: normalize custom Google auth transport headers before google-auth/gaxios interceptors run, restoring webhook token verification when certificate retrieval expects Fetch `Headers`. Fixes #76742. Thanks @donbowman.
|
||||
- Google Chat: normalize Google auth certificate response headers before google-auth-library reads cache-control, so inbound webhook auth no longer rejects with `res?.headers.get is not a function`. Fixes #76880. Thanks @donbowman.
|
||||
- Doctor/plugins: reset stale `plugins.slots.memory` and `plugins.slots.contextEngine` references during `doctor --fix`, so cleanup of missing plugin config does not leave unrecoverable slot owners behind. Fixes #76550 and #76551. Thanks @vincentkoc.
|
||||
- Docs/WhatsApp: merge the duplicate top-level `web` objects in the gateway channel config example so copy-pasted WhatsApp config keeps both `web.whatsapp` and reconnect settings. Fixes #76619. Thanks @WadydX.
|
||||
- Plugins/Anthropic: expose Claude thinking profiles from the bundled provider-policy artifact so non-runtime callers keep Opus 4.7 `adaptive`, `xhigh`, and `max` instead of downgrading to `high`. Fixes #76779. Thanks @tomascupr and @iAbhi001.
|
||||
|
||||
@@ -348,6 +348,9 @@ describe("googlechat google auth runtime", () => {
|
||||
expect(transport.interceptors.request.add).toHaveBeenCalledWith({
|
||||
resolved: expect.any(Function),
|
||||
});
|
||||
expect(transport.interceptors.response.add).toHaveBeenCalledWith({
|
||||
resolved: expect.any(Function),
|
||||
});
|
||||
expect("window" in globalThis).toBe(false);
|
||||
} finally {
|
||||
if (originalWindowDescriptor) {
|
||||
@@ -369,6 +372,20 @@ describe("googlechat google auth runtime", () => {
|
||||
expect(normalized.headers.get("x-test")).toBe("1");
|
||||
});
|
||||
|
||||
it("normalizes Google auth response headers before upstream cache-control reads", () => {
|
||||
const response = {
|
||||
data: {},
|
||||
headers: {
|
||||
"cache-control": "public, max-age=3600",
|
||||
},
|
||||
};
|
||||
|
||||
const normalized = __testing.normalizeGoogleAuthResponseHeaders(response);
|
||||
|
||||
expect(normalized.headers).toBeInstanceOf(Headers);
|
||||
expect(normalized.headers.get("cache-control")).toBe("public, max-age=3600");
|
||||
});
|
||||
|
||||
it("rejects service-account credentials that override Google auth endpoints", async () => {
|
||||
await expect(
|
||||
resolveValidatedGoogleChatCredentials({
|
||||
|
||||
@@ -23,6 +23,9 @@ type GoogleAuthTransport = InstanceType<GaxiosModule["Gaxios"]>;
|
||||
type GoogleAuthRequestWithUnknownHeaders = RequestInit & {
|
||||
headers?: unknown;
|
||||
};
|
||||
type GoogleAuthResponseWithUnknownHeaders = {
|
||||
headers?: unknown;
|
||||
};
|
||||
type GuardedGoogleAuthRequestInit = RequestInit & {
|
||||
agent?: unknown;
|
||||
cert?: unknown;
|
||||
@@ -79,12 +82,24 @@ function normalizeGoogleAuthPreparedRequestHeaders<T extends GoogleAuthRequestWi
|
||||
return config as T & { headers: Headers };
|
||||
}
|
||||
|
||||
function normalizeGoogleAuthResponseHeaders<T extends GoogleAuthResponseWithUnknownHeaders>(
|
||||
response: T,
|
||||
): T & { headers: Headers } {
|
||||
if (!(response.headers instanceof Headers)) {
|
||||
response.headers = new Headers(response.headers as HeadersInit | undefined);
|
||||
}
|
||||
return response as T & { headers: Headers };
|
||||
}
|
||||
|
||||
function installGoogleAuthHeaderCompatibilityInterceptor(
|
||||
transport: GoogleAuthTransport,
|
||||
): GoogleAuthTransport {
|
||||
transport.interceptors.request.add({
|
||||
resolved: async (config) => normalizeGoogleAuthPreparedRequestHeaders(config),
|
||||
});
|
||||
transport.interceptors.response.add({
|
||||
resolved: async (response) => normalizeGoogleAuthResponseHeaders(response),
|
||||
});
|
||||
return transport;
|
||||
}
|
||||
|
||||
@@ -558,6 +573,7 @@ export const __testing = {
|
||||
googleAuthTransportPromise = null;
|
||||
},
|
||||
normalizeGoogleAuthPreparedRequestHeaders,
|
||||
normalizeGoogleAuthResponseHeaders,
|
||||
resolveGoogleAuthEnvProxyUrl,
|
||||
validateGoogleChatServiceAccountCredentials,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user