@continuedev/fetch 1.0.13 → 1.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/certs.d.ts +17 -0
- package/dist/certs.js +105 -0
- package/dist/certs.test.d.ts +1 -0
- package/dist/certs.test.js +139 -0
- package/dist/fetch.js +6 -9
- package/dist/fetch.test.js +0 -1
- package/dist/getAgentOptions.d.ts +2 -2
- package/dist/getAgentOptions.js +13 -40
- package/dist/getAgentOptions.test.js +129 -77
- package/dist/node-fetch-patch.d.ts +16 -0
- package/dist/node-fetch-patch.js +395 -0
- package/dist/node-fetch-patch.test.d.ts +1 -0
- package/dist/node-fetch-patch.test.js +50 -0
- package/dist/stream.js +27 -4
- package/dist/util.d.ts +6 -1
- package/dist/util.js +57 -17
- package/dist/util.test.js +92 -18
- package/package.json +1 -1
- package/src/certs.test.ts +187 -0
- package/src/certs.ts +129 -0
- package/src/fetch.ts +6 -10
- package/src/getAgentOptions.test.ts +158 -91
- package/src/getAgentOptions.ts +23 -44
- package/src/node-fetch-patch.js +518 -0
- package/src/node-fetch-patch.test.js +67 -0
- package/src/node_modules/.vite/vitest/d41d8cd98f00b204e9800998ecf8427e/results.json +1 -0
- package/src/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
- package/src/stream.ts +29 -4
- package/src/util.test.ts +130 -18
- package/src/util.ts +84 -19
- package/src/fetch.test.ts +0 -173
package/src/util.test.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { afterEach, expect, test, vi } from "vitest";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
getProxyFromEnv,
|
|
4
|
+
patternMatchesHostname,
|
|
5
|
+
shouldBypassProxy,
|
|
6
|
+
} from "./util.js";
|
|
3
7
|
|
|
4
8
|
// Reset environment variables after each test
|
|
5
9
|
afterEach(() => {
|
|
@@ -52,51 +56,159 @@ test("getProxyFromEnv prefers HTTPS_PROXY over other env vars for https protocol
|
|
|
52
56
|
expect(getProxyFromEnv("https:")).toBe("https://preferred.example.com");
|
|
53
57
|
});
|
|
54
58
|
|
|
59
|
+
// Tests for patternMatchesHostname
|
|
60
|
+
test("patternMatchesHostname with exact hostname match", () => {
|
|
61
|
+
expect(patternMatchesHostname("example.com", "example.com")).toBe(true);
|
|
62
|
+
expect(patternMatchesHostname("example.com", "different.com")).toBe(false);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
test("patternMatchesHostname with wildcard domains", () => {
|
|
66
|
+
expect(patternMatchesHostname("sub.example.com", "*.example.com")).toBe(true);
|
|
67
|
+
expect(patternMatchesHostname("sub.sub.example.com", "*.example.com")).toBe(
|
|
68
|
+
true,
|
|
69
|
+
);
|
|
70
|
+
expect(patternMatchesHostname("example.com", "*.example.com")).toBe(false);
|
|
71
|
+
expect(patternMatchesHostname("sub.different.com", "*.example.com")).toBe(
|
|
72
|
+
false,
|
|
73
|
+
);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
test("patternMatchesHostname with domain suffix", () => {
|
|
77
|
+
expect(patternMatchesHostname("sub.example.com", ".example.com")).toBe(true);
|
|
78
|
+
expect(patternMatchesHostname("example.com", ".example.com")).toBe(true);
|
|
79
|
+
expect(patternMatchesHostname("different.com", ".example.com")).toBe(false);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
test("patternMatchesHostname with case insensitivity", () => {
|
|
83
|
+
expect(patternMatchesHostname("EXAMPLE.com", "example.COM")).toBe(true);
|
|
84
|
+
expect(patternMatchesHostname("sub.EXAMPLE.com", "*.example.COM")).toBe(true);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
// Port handling tests
|
|
88
|
+
test("patternMatchesHostname with exact port match", () => {
|
|
89
|
+
expect(patternMatchesHostname("example.com:8080", "example.com:8080")).toBe(
|
|
90
|
+
true,
|
|
91
|
+
);
|
|
92
|
+
expect(patternMatchesHostname("example.com:8080", "example.com:9090")).toBe(
|
|
93
|
+
false,
|
|
94
|
+
);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
test("patternMatchesHostname with port in pattern but not in hostname", () => {
|
|
98
|
+
expect(patternMatchesHostname("example.com", "example.com:8080")).toBe(false);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
test("patternMatchesHostname with port in hostname but not in pattern", () => {
|
|
102
|
+
expect(patternMatchesHostname("example.com:8080", "example.com")).toBe(true);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
test("patternMatchesHostname with wildcard domains and ports", () => {
|
|
106
|
+
expect(
|
|
107
|
+
patternMatchesHostname("sub.example.com:8080", "*.example.com:8080"),
|
|
108
|
+
).toBe(true);
|
|
109
|
+
expect(
|
|
110
|
+
patternMatchesHostname("sub.example.com:9090", "*.example.com:8080"),
|
|
111
|
+
).toBe(false);
|
|
112
|
+
expect(patternMatchesHostname("sub.example.com", "*.example.com:8080")).toBe(
|
|
113
|
+
false,
|
|
114
|
+
);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
test("patternMatchesHostname with domain suffix and ports", () => {
|
|
118
|
+
expect(
|
|
119
|
+
patternMatchesHostname("sub.example.com:8080", ".example.com:8080"),
|
|
120
|
+
).toBe(true);
|
|
121
|
+
expect(patternMatchesHostname("example.com:8080", ".example.com:8080")).toBe(
|
|
122
|
+
true,
|
|
123
|
+
);
|
|
124
|
+
expect(
|
|
125
|
+
patternMatchesHostname("sub.example.com:9090", ".example.com:8080"),
|
|
126
|
+
).toBe(false);
|
|
127
|
+
});
|
|
128
|
+
|
|
55
129
|
// Tests for shouldBypassProxy
|
|
56
130
|
test("shouldBypassProxy returns false when NO_PROXY is not set", () => {
|
|
57
|
-
expect(shouldBypassProxy("example.com")).toBe(false);
|
|
131
|
+
expect(shouldBypassProxy("example.com", undefined)).toBe(false);
|
|
58
132
|
});
|
|
59
133
|
|
|
60
134
|
test("shouldBypassProxy returns true for exact hostname match", () => {
|
|
61
135
|
process.env.NO_PROXY = "example.com,another.com";
|
|
62
|
-
expect(shouldBypassProxy("example.com")).toBe(true);
|
|
136
|
+
expect(shouldBypassProxy("example.com", undefined)).toBe(true);
|
|
63
137
|
});
|
|
64
138
|
|
|
65
139
|
test("shouldBypassProxy returns false when hostname doesn't match any NO_PROXY entry", () => {
|
|
66
140
|
process.env.NO_PROXY = "example.com,another.com";
|
|
67
|
-
expect(shouldBypassProxy("different.com")).toBe(false);
|
|
141
|
+
expect(shouldBypassProxy("different.com", undefined)).toBe(false);
|
|
68
142
|
});
|
|
69
143
|
|
|
70
144
|
test("shouldBypassProxy handles lowercase no_proxy", () => {
|
|
71
145
|
process.env.no_proxy = "example.com";
|
|
72
|
-
expect(shouldBypassProxy("example.com")).toBe(true);
|
|
146
|
+
expect(shouldBypassProxy("example.com", undefined)).toBe(true);
|
|
73
147
|
});
|
|
74
148
|
|
|
75
149
|
test("shouldBypassProxy works with wildcard domains", () => {
|
|
76
150
|
process.env.NO_PROXY = "*.example.com";
|
|
77
|
-
expect(shouldBypassProxy("sub.example.com")).toBe(true);
|
|
78
|
-
expect(shouldBypassProxy("example.com")).toBe(false);
|
|
79
|
-
expect(shouldBypassProxy("different.com")).toBe(false);
|
|
151
|
+
expect(shouldBypassProxy("sub.example.com", undefined)).toBe(true);
|
|
152
|
+
expect(shouldBypassProxy("example.com", undefined)).toBe(false);
|
|
153
|
+
expect(shouldBypassProxy("different.com", undefined)).toBe(false);
|
|
80
154
|
});
|
|
81
155
|
|
|
82
156
|
test("shouldBypassProxy works with domain suffix", () => {
|
|
83
157
|
process.env.NO_PROXY = ".example.com";
|
|
84
|
-
expect(shouldBypassProxy("sub.example.com")).toBe(true);
|
|
85
|
-
expect(shouldBypassProxy("example.com")).toBe(true);
|
|
86
|
-
expect(shouldBypassProxy("different.com")).toBe(false);
|
|
158
|
+
expect(shouldBypassProxy("sub.example.com", undefined)).toBe(true);
|
|
159
|
+
expect(shouldBypassProxy("example.com", undefined)).toBe(true);
|
|
160
|
+
expect(shouldBypassProxy("different.com", undefined)).toBe(false);
|
|
87
161
|
});
|
|
88
162
|
|
|
89
163
|
test("shouldBypassProxy handles multiple entries with different patterns", () => {
|
|
90
164
|
process.env.NO_PROXY = "internal.local,*.example.com,.test.com";
|
|
91
|
-
expect(shouldBypassProxy("internal.local")).toBe(true);
|
|
92
|
-
expect(shouldBypassProxy("sub.example.com")).toBe(true);
|
|
93
|
-
expect(shouldBypassProxy("sub.test.com")).toBe(true);
|
|
94
|
-
expect(shouldBypassProxy("test.com")).toBe(true);
|
|
95
|
-
expect(shouldBypassProxy("example.org")).toBe(false);
|
|
165
|
+
expect(shouldBypassProxy("internal.local", undefined)).toBe(true);
|
|
166
|
+
expect(shouldBypassProxy("sub.example.com", undefined)).toBe(true);
|
|
167
|
+
expect(shouldBypassProxy("sub.test.com", undefined)).toBe(true);
|
|
168
|
+
expect(shouldBypassProxy("test.com", undefined)).toBe(true);
|
|
169
|
+
expect(shouldBypassProxy("example.org", undefined)).toBe(false);
|
|
96
170
|
});
|
|
97
171
|
|
|
98
172
|
test("shouldBypassProxy ignores whitespace in NO_PROXY", () => {
|
|
99
173
|
process.env.NO_PROXY = " example.com , *.test.org ";
|
|
100
|
-
expect(shouldBypassProxy("example.com")).toBe(true);
|
|
101
|
-
expect(shouldBypassProxy("subdomain.test.org")).toBe(true);
|
|
174
|
+
expect(shouldBypassProxy("example.com", undefined)).toBe(true);
|
|
175
|
+
expect(shouldBypassProxy("subdomain.test.org", undefined)).toBe(true);
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
test("shouldBypassProxy with ports in NO_PROXY", () => {
|
|
179
|
+
process.env.NO_PROXY = "example.com:8080,*.test.org:443,.internal.net:8443";
|
|
180
|
+
expect(shouldBypassProxy("example.com:8080", undefined)).toBe(true);
|
|
181
|
+
expect(shouldBypassProxy("example.com:9090", undefined)).toBe(false);
|
|
182
|
+
expect(shouldBypassProxy("sub.test.org:443", undefined)).toBe(true);
|
|
183
|
+
expect(shouldBypassProxy("sub.internal.net:8443", undefined)).toBe(true);
|
|
184
|
+
expect(shouldBypassProxy("internal.net:8443", undefined)).toBe(true);
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
test("shouldBypassProxy accepts options with noProxy patterns", () => {
|
|
188
|
+
const options = { noProxy: ["example.com:8080", "*.internal.net"] };
|
|
189
|
+
expect(shouldBypassProxy("example.com:8080", options)).toBe(true);
|
|
190
|
+
expect(shouldBypassProxy("example.com", options)).toBe(false);
|
|
191
|
+
expect(shouldBypassProxy("server.internal.net", options)).toBe(true);
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
test("shouldBypassProxy combines environment and options noProxy patterns", () => {
|
|
195
|
+
process.env.NO_PROXY = "example.org,*.test.com";
|
|
196
|
+
const options = { noProxy: ["example.com:8080", "*.internal.net"] };
|
|
197
|
+
expect(shouldBypassProxy("example.org", options)).toBe(true);
|
|
198
|
+
expect(shouldBypassProxy("sub.test.com", options)).toBe(true);
|
|
199
|
+
expect(shouldBypassProxy("example.com:8080", options)).toBe(true);
|
|
200
|
+
expect(shouldBypassProxy("server.internal.net", options)).toBe(true);
|
|
201
|
+
expect(shouldBypassProxy("other.domain", options)).toBe(false);
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
test("shouldBypassProxy handles empty noProxy array in options", () => {
|
|
205
|
+
process.env.NO_PROXY = "example.org";
|
|
206
|
+
const options = { noProxy: [] };
|
|
207
|
+
expect(shouldBypassProxy("example.org", options)).toBe(true);
|
|
208
|
+
expect(shouldBypassProxy("different.com", options)).toBe(false);
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
test("shouldBypassProxy handles undefined options", () => {
|
|
212
|
+
process.env.NO_PROXY = "example.org";
|
|
213
|
+
expect(shouldBypassProxy("example.org", undefined)).toBe(true);
|
|
102
214
|
});
|
package/src/util.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { RequestOptions } from "@continuedev/config-types";
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Gets the proxy settings from environment variables
|
|
3
5
|
* @param protocol The URL protocol (http: or https:)
|
|
@@ -16,28 +18,91 @@ export function getProxyFromEnv(protocol: string): string | undefined {
|
|
|
16
18
|
}
|
|
17
19
|
}
|
|
18
20
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
21
|
+
// Note that request options proxy (per model) takes precedence over environment variables
|
|
22
|
+
export function getProxy(
|
|
23
|
+
protocol: string,
|
|
24
|
+
requestOptions?: RequestOptions,
|
|
25
|
+
): string | undefined {
|
|
26
|
+
if (requestOptions?.proxy) {
|
|
27
|
+
return requestOptions.proxy;
|
|
28
|
+
}
|
|
29
|
+
return getProxyFromEnv(protocol);
|
|
30
|
+
}
|
|
29
31
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
32
|
+
export function getEnvNoProxyPatterns(): string[] {
|
|
33
|
+
const envValue = process.env.NO_PROXY || process.env.no_proxy;
|
|
34
|
+
if (envValue) {
|
|
35
|
+
return envValue
|
|
36
|
+
.split(",")
|
|
37
|
+
.map((item) => item.trim().toLowerCase())
|
|
38
|
+
.filter((i) => !!i);
|
|
39
|
+
} else {
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
}
|
|
33
43
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
44
|
+
export function getReqOptionsNoProxyPatterns(
|
|
45
|
+
options: RequestOptions | undefined,
|
|
46
|
+
): string[] {
|
|
47
|
+
return (
|
|
48
|
+
options?.noProxy?.map((i) => i.trim().toLowerCase()).filter((i) => !!i) ??
|
|
49
|
+
[]
|
|
50
|
+
);
|
|
51
|
+
}
|
|
37
52
|
|
|
38
|
-
|
|
39
|
-
|
|
53
|
+
export function patternMatchesHostname(hostname: string, pattern: string) {
|
|
54
|
+
// Split hostname and pattern to separate hostname and port
|
|
55
|
+
const [hostnameWithoutPort, hostnamePort] = hostname.toLowerCase().split(":");
|
|
56
|
+
const [patternWithoutPort, patternPort] = pattern.toLowerCase().split(":");
|
|
40
57
|
|
|
58
|
+
// If pattern specifies a port but hostname doesn't match it, no match
|
|
59
|
+
if (patternPort && (!hostnamePort || hostnamePort !== patternPort)) {
|
|
41
60
|
return false;
|
|
42
|
-
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Now compare just the hostname parts
|
|
64
|
+
|
|
65
|
+
// exact match
|
|
66
|
+
if (patternWithoutPort === hostnameWithoutPort) {
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
// wildcard domain match (*.example.com)
|
|
70
|
+
if (
|
|
71
|
+
patternWithoutPort.startsWith("*.") &&
|
|
72
|
+
hostnameWithoutPort.endsWith(patternWithoutPort.substring(1))
|
|
73
|
+
) {
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
// Domain suffix match (.example.com)
|
|
77
|
+
if (
|
|
78
|
+
patternWithoutPort.startsWith(".") &&
|
|
79
|
+
hostnameWithoutPort.endsWith(patternWithoutPort.slice(1))
|
|
80
|
+
) {
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// TODO IP address ranges
|
|
85
|
+
|
|
86
|
+
// TODO CIDR notation
|
|
87
|
+
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Checks if a hostname should bypass proxy based on NO_PROXY environment variable
|
|
93
|
+
* @param hostname The hostname to check
|
|
94
|
+
* @returns True if the hostname should bypass proxy
|
|
95
|
+
*/
|
|
96
|
+
export function shouldBypassProxy(
|
|
97
|
+
hostname: string,
|
|
98
|
+
requestOptions: RequestOptions | undefined,
|
|
99
|
+
): boolean {
|
|
100
|
+
const ignores = [
|
|
101
|
+
...getEnvNoProxyPatterns(),
|
|
102
|
+
...getReqOptionsNoProxyPatterns(requestOptions),
|
|
103
|
+
];
|
|
104
|
+
const hostLowerCase = hostname.toLowerCase();
|
|
105
|
+
return ignores.some((ignore) =>
|
|
106
|
+
patternMatchesHostname(hostLowerCase, ignore),
|
|
107
|
+
);
|
|
43
108
|
}
|
package/src/fetch.test.ts
DELETED
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
import { globalAgent } from "https";
|
|
2
|
-
import * as fs from "node:fs";
|
|
3
|
-
import * as os from "node:os";
|
|
4
|
-
import * as path from "node:path";
|
|
5
|
-
import { afterEach, beforeEach, expect, test } from "vitest";
|
|
6
|
-
import { getAgentOptions } from "./getAgentOptions.js";
|
|
7
|
-
|
|
8
|
-
// Store original env
|
|
9
|
-
const originalEnv = process.env;
|
|
10
|
-
const originalGlobalAgentOptions = { ...globalAgent.options };
|
|
11
|
-
|
|
12
|
-
// Temporary directory for test certificate files
|
|
13
|
-
let tempDir: string;
|
|
14
|
-
|
|
15
|
-
beforeEach(() => {
|
|
16
|
-
// Create a temporary directory for test files
|
|
17
|
-
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "fetch-test-"));
|
|
18
|
-
|
|
19
|
-
process.env = { ...originalEnv };
|
|
20
|
-
|
|
21
|
-
// Reset globalAgent for each test
|
|
22
|
-
globalAgent.options = { ...originalGlobalAgentOptions };
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
afterEach(() => {
|
|
26
|
-
process.env = originalEnv;
|
|
27
|
-
globalAgent.options = originalGlobalAgentOptions;
|
|
28
|
-
|
|
29
|
-
// Clean up temporary directory
|
|
30
|
-
try {
|
|
31
|
-
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
32
|
-
} catch (error) {
|
|
33
|
-
console.error(`Failed to remove temp directory: ${error}`);
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
// Helper function to create test certificate files
|
|
38
|
-
function createTestCertFile(filename: string, content: string): string {
|
|
39
|
-
const filePath = path.join(tempDir, filename);
|
|
40
|
-
fs.writeFileSync(filePath, content, "utf8");
|
|
41
|
-
return filePath;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
test("getAgentOptions returns basic configuration with default values", () => {
|
|
45
|
-
const options = getAgentOptions();
|
|
46
|
-
|
|
47
|
-
// Check default timeout (7200 seconds = 2 hours = 7,200,000 ms)
|
|
48
|
-
expect(options.timeout).toBe(7200000);
|
|
49
|
-
expect(options.sessionTimeout).toBe(7200000);
|
|
50
|
-
expect(options.keepAliveMsecs).toBe(7200000);
|
|
51
|
-
expect(options.keepAlive).toBe(true);
|
|
52
|
-
|
|
53
|
-
// Verify certificates array exists and contains items
|
|
54
|
-
expect(options.ca).toBeInstanceOf(Array);
|
|
55
|
-
expect(options.ca.length).toBeGreaterThan(0);
|
|
56
|
-
|
|
57
|
-
// Verify at least one of the real TLS root certificates is included
|
|
58
|
-
// This assumes there's at least one certificate with "CERTIFICATE" in it
|
|
59
|
-
expect(options.ca.some((cert: any) => cert.includes("CERTIFICATE"))).toBe(
|
|
60
|
-
true,
|
|
61
|
-
);
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
test("getAgentOptions respects custom timeout", () => {
|
|
65
|
-
const customTimeout = 300; // 5 minutes
|
|
66
|
-
const options = getAgentOptions({ timeout: customTimeout });
|
|
67
|
-
|
|
68
|
-
// Check timeout values (300 seconds = 300,000 ms)
|
|
69
|
-
expect(options.timeout).toBe(300000);
|
|
70
|
-
expect(options.sessionTimeout).toBe(300000);
|
|
71
|
-
expect(options.keepAliveMsecs).toBe(300000);
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
test("getAgentOptions uses verifySsl setting", () => {
|
|
75
|
-
// With verifySsl true
|
|
76
|
-
let options = getAgentOptions({ verifySsl: true });
|
|
77
|
-
expect(options.rejectUnauthorized).toBe(true);
|
|
78
|
-
|
|
79
|
-
// With verifySsl false
|
|
80
|
-
options = getAgentOptions({ verifySsl: false });
|
|
81
|
-
expect(options.rejectUnauthorized).toBe(false);
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
test("getAgentOptions incorporates custom CA bundle paths", () => {
|
|
85
|
-
// Create a test CA bundle file
|
|
86
|
-
const caBundleContent =
|
|
87
|
-
"-----BEGIN CERTIFICATE-----\nMIIDtTCCAp2gAwIBAgIJAMcuSp7chAYdMA==\n-----END CERTIFICATE-----";
|
|
88
|
-
const caBundlePath = createTestCertFile("ca-bundle.pem", caBundleContent);
|
|
89
|
-
|
|
90
|
-
// Single string path
|
|
91
|
-
let options = getAgentOptions({ caBundlePath });
|
|
92
|
-
|
|
93
|
-
// Verify that our test certificate is included in the CA list
|
|
94
|
-
expect(options.ca).toContain(caBundleContent);
|
|
95
|
-
|
|
96
|
-
// Create multiple test CA bundle files
|
|
97
|
-
const caContent1 =
|
|
98
|
-
"-----BEGIN CERTIFICATE-----\nABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\n-----END CERTIFICATE-----";
|
|
99
|
-
const caContent2 =
|
|
100
|
-
"-----BEGIN CERTIFICATE-----\n0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\n-----END CERTIFICATE-----";
|
|
101
|
-
const caPath1 = createTestCertFile("ca1.pem", caContent1);
|
|
102
|
-
const caPath2 = createTestCertFile("ca2.pem", caContent2);
|
|
103
|
-
|
|
104
|
-
// Array of paths
|
|
105
|
-
options = getAgentOptions({
|
|
106
|
-
caBundlePath: [caPath1, caPath2],
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
// Verify that both test certificates are included in the CA list
|
|
110
|
-
expect(options.ca).toContain(caContent1);
|
|
111
|
-
expect(options.ca).toContain(caContent2);
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
test("getAgentOptions includes global certs when running as binary", () => {
|
|
115
|
-
// Set up test certs in globalAgent
|
|
116
|
-
globalAgent.options.ca = ["global-cert-1", "global-cert-2"];
|
|
117
|
-
|
|
118
|
-
// Set IS_BINARY environment variable
|
|
119
|
-
process.env.IS_BINARY = "true";
|
|
120
|
-
|
|
121
|
-
const options = getAgentOptions();
|
|
122
|
-
|
|
123
|
-
// Test for global certs
|
|
124
|
-
expect(options.ca).toContain("global-cert-1");
|
|
125
|
-
expect(options.ca).toContain("global-cert-2");
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
test("getAgentOptions handles client certificate configuration", () => {
|
|
129
|
-
// Create test certificate files
|
|
130
|
-
const clientCertContent =
|
|
131
|
-
"-----BEGIN CERTIFICATE-----\nCLIENTCERT\n-----END CERTIFICATE-----";
|
|
132
|
-
const clientKeyContent =
|
|
133
|
-
"-----BEGIN PRIVATE KEY-----\nCLIENTKEY\n-----END PRIVATE KEY-----";
|
|
134
|
-
const certPath = createTestCertFile("client.cert", clientCertContent);
|
|
135
|
-
const keyPath = createTestCertFile("client.key", clientKeyContent);
|
|
136
|
-
|
|
137
|
-
const clientCertOptions = {
|
|
138
|
-
clientCertificate: {
|
|
139
|
-
cert: certPath,
|
|
140
|
-
key: keyPath,
|
|
141
|
-
passphrase: "secret-passphrase",
|
|
142
|
-
},
|
|
143
|
-
};
|
|
144
|
-
|
|
145
|
-
const options = getAgentOptions(clientCertOptions);
|
|
146
|
-
|
|
147
|
-
expect(options.cert).toBe(clientCertContent);
|
|
148
|
-
expect(options.key).toBe(clientKeyContent);
|
|
149
|
-
expect(options.passphrase).toBe("secret-passphrase");
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
test("getAgentOptions handles client certificate without passphrase", () => {
|
|
153
|
-
// Create test certificate files
|
|
154
|
-
const clientCertContent =
|
|
155
|
-
"-----BEGIN CERTIFICATE-----\nCLIENTCERT2\n-----END CERTIFICATE-----";
|
|
156
|
-
const clientKeyContent =
|
|
157
|
-
"-----BEGIN PRIVATE KEY-----\nCLIENTKEY2\n-----END PRIVATE KEY-----";
|
|
158
|
-
const certPath = createTestCertFile("client2.cert", clientCertContent);
|
|
159
|
-
const keyPath = createTestCertFile("client2.key", clientKeyContent);
|
|
160
|
-
|
|
161
|
-
const clientCertOptions = {
|
|
162
|
-
clientCertificate: {
|
|
163
|
-
cert: certPath,
|
|
164
|
-
key: keyPath,
|
|
165
|
-
},
|
|
166
|
-
};
|
|
167
|
-
|
|
168
|
-
const options = getAgentOptions(clientCertOptions);
|
|
169
|
-
|
|
170
|
-
expect(options.cert).toBe(clientCertContent);
|
|
171
|
-
expect(options.key).toBe(clientKeyContent);
|
|
172
|
-
expect(options.passphrase).toBeUndefined();
|
|
173
|
-
});
|