





















@@ -60,13 +60,35 @@ const DISCORD_CDN_HOSTNAMES = [
6060"*.discordapp.net",
6161];
626263+function requireRecord(value: unknown, label: string): Record<string, unknown> {
64+expect(value, label).toBeTypeOf("object");
65+expect(value, label).not.toBeNull();
66+return value as Record<string, unknown>;
67+}
68+69+function requireArray(value: unknown, label: string): Array<unknown> {
70+expect(Array.isArray(value), label).toBe(true);
71+return value as Array<unknown>;
72+}
73+74+function callArg(mock: unknown, callIndex: number, argIndex: number, label: string) {
75+const calls = (mock as { mock?: { calls?: Array<Array<unknown>> } }).mock?.calls ?? [];
76+const call = calls.at(callIndex);
77+expect(call, label).toBeDefined();
78+return call?.[argIndex];
79+}
80+81+function fetchParams(): Record<string, unknown> {
82+return requireRecord(callArg(fetchRemoteMedia, 0, 0, "fetch media params"), "fetch media params");
83+}
84+6385function expectDiscordCdnSsrFPolicy(policy: unknown) {
64-expect(policy).toEqual(
65- expect.objectContaining({
66- allowRfc2544BenchmarkRange: true,
67- hostnameAllowlist: expect.arrayContaining(DISCORD_CDN_HOSTNAMES),
68-}),
69-);
86+const policyRecord = requireRecord(policy, "ssrf policy");
87+expect(policyRecord.allowRfc2544BenchmarkRange).toBe(true);
88+const hostnameAllowlist = requireArray(policyRecord.hostnameAllowlist, "hostname allowlist");
89+for (const hostname of DISCORD_CDN_HOSTNAMES) {
90+expect(hostnameAllowlist).toContain(hostname);
91+}
7092}
71937294function expectSinglePngDownload(params: {
@@ -77,30 +99,18 @@ function expectSinglePngDownload(params: {
7799placeholder: "<media:image>" | "<media:sticker>";
78100}) {
79101expect(fetchRemoteMedia).toHaveBeenCalledTimes(1);
80-const call = fetchRemoteMedia.mock.calls[0]?.[0] as {
81-url?: string;
82-filePathHint?: string;
83-maxBytes?: number;
84-fetchImpl?: unknown;
85-readIdleTimeoutMs?: number;
86-requestInit?: { signal?: AbortSignal };
87-ssrfPolicy?: unknown;
88-};
89-expect(call).toMatchObject({
90-url: params.expectedUrl,
91-filePathHint: params.filePathHint,
92-maxBytes: 512,
93-fetchImpl: undefined,
94-});
102+const call = fetchParams();
103+expect(call.url).toBe(params.expectedUrl);
104+expect(call.filePathHint).toBe(params.filePathHint);
105+expect(call.maxBytes).toBe(512);
106+expect(call.fetchImpl).toBeUndefined();
95107expectDiscordCdnSsrFPolicy(call.ssrfPolicy);
96108expect(saveMediaBuffer).toHaveBeenCalledTimes(1);
97-expect(saveMediaBuffer).toHaveBeenCalledWith(
98-expect.any(Buffer),
99-"image/png",
100-"inbound",
101-512,
102-params.filePathHint,
103-);
109+expect(Buffer.isBuffer(callArg(saveMediaBuffer, 0, 0, "saved buffer"))).toBe(true);
110+expect(callArg(saveMediaBuffer, 0, 1, "saved content type")).toBe("image/png");
111+expect(callArg(saveMediaBuffer, 0, 2, "saved direction")).toBe("inbound");
112+expect(callArg(saveMediaBuffer, 0, 3, "saved max bytes")).toBe(512);
113+expect(callArg(saveMediaBuffer, 0, 4, "saved file path hint")).toBe(params.filePathHint);
104114expect(params.result).toEqual([
105115{
106116path: params.expectedPath,
@@ -272,9 +282,7 @@ describe("resolveForwardedMediaList", () => {
272282{ fetchImpl: proxyFetch },
273283);
274284275-expect(fetchRemoteMedia).toHaveBeenCalledWith(
276-expect.objectContaining({ fetchImpl: proxyFetch }),
277-);
285+expect(fetchParams().fetchImpl).toBe(proxyFetch);
278286});
279287280288it("keeps forwarded attachment metadata when download fails", async () => {
@@ -410,9 +418,7 @@ describe("resolveForwardedMediaList", () => {
410418{ readIdleTimeoutMs: 60_000 },
411419);
412420413-expect(fetchRemoteMedia).toHaveBeenCalledWith(
414-expect.objectContaining({ readIdleTimeoutMs: 60_000 }),
415-);
421+expect(fetchParams().readIdleTimeoutMs).toBe(60_000);
416422});
417423418424it("passes readIdleTimeoutMs to forwarded sticker downloads", async () => {
@@ -440,9 +446,7 @@ describe("resolveForwardedMediaList", () => {
440446{ readIdleTimeoutMs: 60_000 },
441447);
442448443-expect(fetchRemoteMedia).toHaveBeenCalledWith(
444-expect.objectContaining({ readIdleTimeoutMs: 60_000 }),
445-);
449+expect(fetchParams().readIdleTimeoutMs).toBe(60_000);
446450});
447451});
448452@@ -507,9 +511,7 @@ describe("resolveMediaList", () => {
507511{ fetchImpl: proxyFetch },
508512);
509513510-expect(fetchRemoteMedia).toHaveBeenCalledWith(
511-expect.objectContaining({ fetchImpl: proxyFetch }),
512-);
514+expect(fetchParams().fetchImpl).toBe(proxyFetch);
513515});
514516515517it("keeps attachment metadata when download fails", async () => {
@@ -726,9 +728,7 @@ describe("resolveMediaList", () => {
726728{ readIdleTimeoutMs: 60_000 },
727729);
728730729-expect(fetchRemoteMedia).toHaveBeenCalledWith(
730-expect.objectContaining({ readIdleTimeoutMs: 60_000 }),
731-);
731+expect(fetchParams().readIdleTimeoutMs).toBe(60_000);
732732});
733733734734it("passes readIdleTimeoutMs to fetchRemoteMedia for stickers", async () => {
@@ -754,9 +754,7 @@ describe("resolveMediaList", () => {
754754{ readIdleTimeoutMs: 60_000 },
755755);
756756757-expect(fetchRemoteMedia).toHaveBeenCalledWith(
758-expect.objectContaining({ readIdleTimeoutMs: 60_000 }),
759-);
757+expect(fetchParams().readIdleTimeoutMs).toBe(60_000);
760758});
761759762760it("times out slow attachment downloads and returns fallback", async () => {
@@ -834,11 +832,8 @@ describe("resolveMediaList", () => {
834832placeholder: "<media:image>",
835833},
836834]);
837-expect(fetchRemoteMedia).toHaveBeenCalledWith(
838-expect.objectContaining({
839-requestInit: expect.objectContaining({ signal: abortController.signal }),
840-}),
841-);
835+const requestInit = requireRecord(fetchParams().requestInit, "fetch request init");
836+expect(requestInit.signal).toBe(abortController.signal);
842837});
843838});
844839@@ -893,15 +888,17 @@ describe("Discord media SSRF policy", () => {
893888},
894889);
895890896-const policy = fetchRemoteMedia.mock.calls[0]?.[0]?.ssrfPolicy;
897-expect(policy).toEqual(
898-expect.objectContaining({
899-allowPrivateNetwork: true,
900-allowRfc2544BenchmarkRange: true,
901-allowedHostnames: expect.arrayContaining(["assets.example.com"]),
902-hostnameAllowlist: expect.arrayContaining(["assets.example.com", ...DISCORD_CDN_HOSTNAMES]),
903-}),
891+const policy = requireRecord(fetchParams().ssrfPolicy, "ssrf policy");
892+expect(policy.allowPrivateNetwork).toBe(true);
893+expect(policy.allowRfc2544BenchmarkRange).toBe(true);
894+expect(requireArray(policy.allowedHostnames, "allowed hostnames")).toContain(
895+"assets.example.com",
904896);
897+const hostnameAllowlist = requireArray(policy.hostnameAllowlist, "hostname allowlist");
898+expect(hostnameAllowlist).toContain("assets.example.com");
899+for (const hostname of DISCORD_CDN_HOSTNAMES) {
900+expect(hostnameAllowlist).toContain(hostname);
901+}
905902});
906903});
907904此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。