mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-07 10:34:44 +00:00
fix(slack): cancel followed redirect bodies
This commit is contained in:
@@ -291,10 +291,11 @@ describe("fetchWithSlackAuth", () => {
|
||||
|
||||
it("strips Authorization header on cross-origin redirects", async () => {
|
||||
// First call: redirect response from Slack
|
||||
const redirectResponse = new Response(null, {
|
||||
const redirectResponse = new Response("redirect body", {
|
||||
status: 302,
|
||||
headers: { location: "https://cdn.slack-edge.com/presigned-url?sig=abc123" },
|
||||
});
|
||||
const cancel = vi.spyOn(redirectResponse.body!, "cancel").mockResolvedValue(undefined);
|
||||
|
||||
// Second call: actual file content from CDN
|
||||
const fileResponse = new Response(Buffer.from("actual image data"), {
|
||||
@@ -321,13 +322,15 @@ describe("fetchWithSlackAuth", () => {
|
||||
"https://cdn.slack-edge.com/presigned-url?sig=abc123",
|
||||
{ redirect: "follow" },
|
||||
);
|
||||
expect(cancel).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
it("preserves Authorization header on same-origin redirects", async () => {
|
||||
const redirectResponse = new Response(null, {
|
||||
const redirectResponse = new Response("redirect body", {
|
||||
status: 302,
|
||||
headers: { location: "/files/redirect-target" },
|
||||
});
|
||||
const cancel = vi.spyOn(redirectResponse.body!, "cancel").mockResolvedValue(undefined);
|
||||
|
||||
const fileResponse = new Response(Buffer.from("image data"), {
|
||||
status: 200,
|
||||
@@ -342,6 +345,7 @@ describe("fetchWithSlackAuth", () => {
|
||||
headers: { Authorization: "Bearer xoxb-test-token" },
|
||||
redirect: "follow",
|
||||
});
|
||||
expect(cancel).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
it("returns redirect response when no location header is provided", async () => {
|
||||
|
||||
@@ -104,6 +104,12 @@ function resolveSlackFetchForRuntime(): typeof fetch {
|
||||
return isMockedFetch(globalThis.fetch) ? globalThis.fetch : fetchWithRuntimeDispatcher;
|
||||
}
|
||||
|
||||
async function cancelUnreadResponseBody(response: Response): Promise<void> {
|
||||
if (!response.bodyUsed) {
|
||||
await response.body?.cancel().catch(() => undefined);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches a URL with Authorization header while keeping same-origin redirects
|
||||
* authenticated and dropping auth once the redirect crosses origins.
|
||||
@@ -136,6 +142,7 @@ export async function fetchWithSlackAuth(url: string, token: string): Promise<Re
|
||||
if (resolvedUrl.protocol !== "https:") {
|
||||
return initialRes;
|
||||
}
|
||||
await cancelUnreadResponseBody(initialRes);
|
||||
if (resolvedUrl.origin === parsed.origin) {
|
||||
return fetchImpl(resolvedUrl.toString(), {
|
||||
headers: authHeaders,
|
||||
|
||||
Reference in New Issue
Block a user