@continuedev/fetch 1.0.16 → 1.1.0
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/CHANGELOG.md +1177 -0
- package/dist/fetch.e2e.test.js +356 -0
- package/dist/fetch.js +22 -2
- package/dist/ssl-certificate.test.d.ts +1 -0
- package/dist/ssl-certificate.test.js +231 -0
- package/dist/stream.test.js +4 -0
- package/package.json +9 -3
- package/src/fetch.e2e.test.ts +518 -0
- package/src/fetch.ts +23 -2
- package/src/ssl-certificate.test.ts +301 -0
- package/src/stream.test.ts +7 -0
- package/vitest.config.ts +3 -0
- package/dist/fetch.test.js +0 -131
- /package/dist/{fetch.test.d.ts → fetch.e2e.test.d.ts} +0 -0
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as os from "node:os";
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
import { afterEach, beforeEach, describe, expect, test } from "vitest";
|
|
5
|
+
import { CertsCache, getCertificateContent } from "./certs.js";
|
|
6
|
+
import { getAgentOptions } from "./getAgentOptions.js";
|
|
7
|
+
|
|
8
|
+
// Store original env
|
|
9
|
+
const originalEnv = process.env;
|
|
10
|
+
|
|
11
|
+
// Temporary directory for test certificate files
|
|
12
|
+
let tempDir: string;
|
|
13
|
+
|
|
14
|
+
beforeEach(() => {
|
|
15
|
+
// Create a temporary directory for test files
|
|
16
|
+
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "cert-troubleshoot-test-"));
|
|
17
|
+
process.env = { ...originalEnv };
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
afterEach(() => {
|
|
21
|
+
process.env = originalEnv;
|
|
22
|
+
CertsCache.getInstance().clear();
|
|
23
|
+
|
|
24
|
+
// Clean up temporary directory
|
|
25
|
+
if (tempDir && fs.existsSync(tempDir)) {
|
|
26
|
+
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
describe("SSL certificate handling", () => {
|
|
31
|
+
describe("CA certificate handling", () => {
|
|
32
|
+
test("should handle custom CA bundle from file path", async () => {
|
|
33
|
+
const customCaCert = `-----BEGIN CERTIFICATE-----
|
|
34
|
+
MIIDXTCCAkWgAwIBAgIJAKoK/heBjcOuMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
|
|
35
|
+
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
|
|
36
|
+
aWRnaXRzIFB0eSBMdGQwHhcNMTcwODI4MTkzNDA5WhcNMTgwODI4MTkzNDA5WjBF
|
|
37
|
+
-----END CERTIFICATE-----`;
|
|
38
|
+
|
|
39
|
+
const caCertPath = path.join(tempDir, "ca-bundle.pem");
|
|
40
|
+
fs.writeFileSync(caCertPath, customCaCert);
|
|
41
|
+
|
|
42
|
+
const options = await getAgentOptions({ caBundlePath: caCertPath });
|
|
43
|
+
|
|
44
|
+
expect(options.ca).toBeDefined();
|
|
45
|
+
expect(Array.isArray(options.ca)).toBe(true);
|
|
46
|
+
expect(options.ca).toContain(customCaCert);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
test("should handle NODE_EXTRA_CA_CERTS environment variable", async () => {
|
|
50
|
+
const extraCaCert = `-----BEGIN CERTIFICATE-----
|
|
51
|
+
MIIDUzCCAjugAwIBAgIJALvxFjX5V+/vMA0GCSqGSIb3DQEBCwUAMDgxCzAJBgNV
|
|
52
|
+
BAYTAlVTMRAwDgYDVQQIDAdDb21wYW55MRcwFQYDVQQKDA5Db21wYW55IENvcnAw
|
|
53
|
+
-----END CERTIFICATE-----`;
|
|
54
|
+
|
|
55
|
+
const extraCaPath = path.join(tempDir, "extra-ca.crt");
|
|
56
|
+
fs.writeFileSync(extraCaPath, extraCaCert);
|
|
57
|
+
|
|
58
|
+
process.env.NODE_EXTRA_CA_CERTS = extraCaPath;
|
|
59
|
+
|
|
60
|
+
const options = await getAgentOptions();
|
|
61
|
+
|
|
62
|
+
expect(options.ca).toBeDefined();
|
|
63
|
+
expect(Array.isArray(options.ca)).toBe(true);
|
|
64
|
+
expect(options.ca).toContain(extraCaCert);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
test("should combine NODE_EXTRA_CA_CERTS with custom CA bundle", async () => {
|
|
68
|
+
const extraCaCert = `-----BEGIN CERTIFICATE-----
|
|
69
|
+
MIIDExtra1234567890abcdefghijklmnopqrstuvwxyz
|
|
70
|
+
-----END CERTIFICATE-----`;
|
|
71
|
+
|
|
72
|
+
const customCaCert = `-----BEGIN CERTIFICATE-----
|
|
73
|
+
MIIDCustom1234567890abcdefghijklmnopqrstuvwxyz
|
|
74
|
+
-----END CERTIFICATE-----`;
|
|
75
|
+
|
|
76
|
+
const extraCaPath = path.join(tempDir, "extra-ca.crt");
|
|
77
|
+
const customCaPath = path.join(tempDir, "custom-ca.pem");
|
|
78
|
+
|
|
79
|
+
fs.writeFileSync(extraCaPath, extraCaCert);
|
|
80
|
+
fs.writeFileSync(customCaPath, customCaCert);
|
|
81
|
+
|
|
82
|
+
process.env.NODE_EXTRA_CA_CERTS = extraCaPath;
|
|
83
|
+
|
|
84
|
+
const options = await getAgentOptions({ caBundlePath: customCaPath });
|
|
85
|
+
|
|
86
|
+
expect(options.ca).toBeDefined();
|
|
87
|
+
expect(Array.isArray(options.ca)).toBe(true);
|
|
88
|
+
expect(options.ca).toContain(extraCaCert);
|
|
89
|
+
expect(options.ca).toContain(customCaCert);
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
describe("Data URI certificate handling", () => {
|
|
94
|
+
test("should handle base64 encoded data URI certificates", () => {
|
|
95
|
+
const originalCert = `-----BEGIN CERTIFICATE-----
|
|
96
|
+
MIIDUzCCAjugAwIBAgIJALvxFjX5V+/vMA0GCSqGSIb3DQEB
|
|
97
|
+
-----END CERTIFICATE-----`;
|
|
98
|
+
|
|
99
|
+
const base64Data = Buffer.from(originalCert).toString("base64");
|
|
100
|
+
const dataUri = `data:application/x-pem-file;base64,${base64Data}`;
|
|
101
|
+
|
|
102
|
+
const result = getCertificateContent(dataUri);
|
|
103
|
+
|
|
104
|
+
expect(result).toBe(originalCert);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
test("should handle URL-encoded data URI certificates", () => {
|
|
108
|
+
const originalCert =
|
|
109
|
+
"certificate with spaces and special chars: !@#$%^&*()";
|
|
110
|
+
const encodedData = encodeURIComponent(originalCert);
|
|
111
|
+
const dataUri = `data:text/plain,${encodedData}`;
|
|
112
|
+
|
|
113
|
+
const result = getCertificateContent(dataUri);
|
|
114
|
+
|
|
115
|
+
expect(result).toBe(originalCert);
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
describe("SSL/TLS configuration", () => {
|
|
120
|
+
test("should configure SSL verification correctly", async () => {
|
|
121
|
+
// Test with SSL verification enabled
|
|
122
|
+
let options = await getAgentOptions({ verifySsl: true });
|
|
123
|
+
expect(options.rejectUnauthorized).toBe(true);
|
|
124
|
+
|
|
125
|
+
// Test with SSL verification disabled
|
|
126
|
+
options = await getAgentOptions({ verifySsl: false });
|
|
127
|
+
expect(options.rejectUnauthorized).toBe(false);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
test("should configure timeout correctly", async () => {
|
|
131
|
+
const customTimeout = 60; // 1 minute in seconds
|
|
132
|
+
const options = await getAgentOptions({ timeout: customTimeout });
|
|
133
|
+
|
|
134
|
+
expect(options.timeout).toBe(customTimeout * 1000); // Should be converted to milliseconds
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
test("should handle client certificate authentication", async () => {
|
|
138
|
+
const clientCert = `-----BEGIN CERTIFICATE-----
|
|
139
|
+
MIIDClientCert1234567890abcdefghijklmnopqrstuvwxyz
|
|
140
|
+
-----END CERTIFICATE-----`;
|
|
141
|
+
|
|
142
|
+
const clientKey = `-----BEGIN PRIVATE KEY-----
|
|
143
|
+
MIIEClientKey567890abcdefghijklmnopqrstuvwxyz
|
|
144
|
+
-----END PRIVATE KEY-----`;
|
|
145
|
+
|
|
146
|
+
const clientCertPath = path.join(tempDir, "client.crt");
|
|
147
|
+
const clientKeyPath = path.join(tempDir, "client.key");
|
|
148
|
+
|
|
149
|
+
fs.writeFileSync(clientCertPath, clientCert);
|
|
150
|
+
fs.writeFileSync(clientKeyPath, clientKey);
|
|
151
|
+
|
|
152
|
+
const options = await getAgentOptions({
|
|
153
|
+
clientCertificate: {
|
|
154
|
+
cert: clientCertPath,
|
|
155
|
+
key: clientKeyPath,
|
|
156
|
+
passphrase: "test-passphrase",
|
|
157
|
+
},
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
expect(options.cert).toBe(clientCert);
|
|
161
|
+
expect(options.key).toBe(clientKey);
|
|
162
|
+
expect(options.passphrase).toBe("test-passphrase");
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
describe("Certificate caching behavior", () => {
|
|
167
|
+
test("should cache certificate content to avoid repeated file reads", async () => {
|
|
168
|
+
const certsCache = CertsCache.getInstance();
|
|
169
|
+
const certPath = path.join(tempDir, "cached-cert.pem");
|
|
170
|
+
const certContent = `-----BEGIN CERTIFICATE-----
|
|
171
|
+
MIIDCachedCert1234567890abcdefghijklmnopqrstuvwxyz
|
|
172
|
+
-----END CERTIFICATE-----`;
|
|
173
|
+
|
|
174
|
+
fs.writeFileSync(certPath, certContent);
|
|
175
|
+
|
|
176
|
+
// First call should read from file
|
|
177
|
+
const result1 = await certsCache.getCachedCustomCert(certPath);
|
|
178
|
+
expect(result1).toBe(certContent);
|
|
179
|
+
|
|
180
|
+
// Modify the file on disk
|
|
181
|
+
const modifiedContent = certContent.replace("CachedCert", "ModifiedCert");
|
|
182
|
+
fs.writeFileSync(certPath, modifiedContent);
|
|
183
|
+
|
|
184
|
+
// Second call should return cached content, not the modified content
|
|
185
|
+
const result2 = await certsCache.getCachedCustomCert(certPath);
|
|
186
|
+
expect(result2).toBe(certContent); // Should still be the original cached content
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
test("should handle cache clearing", async () => {
|
|
190
|
+
const certsCache = CertsCache.getInstance();
|
|
191
|
+
const certPath = path.join(tempDir, "clear-cache-cert.pem");
|
|
192
|
+
const originalContent = `-----BEGIN CERTIFICATE-----
|
|
193
|
+
MIIDOriginalCert1234567890abcdefghijklmnopqrstuvwxyz
|
|
194
|
+
-----END CERTIFICATE-----`;
|
|
195
|
+
|
|
196
|
+
fs.writeFileSync(certPath, originalContent);
|
|
197
|
+
|
|
198
|
+
// Load into cache
|
|
199
|
+
await certsCache.getCachedCustomCert(certPath);
|
|
200
|
+
|
|
201
|
+
// Clear cache
|
|
202
|
+
certsCache.clear();
|
|
203
|
+
|
|
204
|
+
// Modify file
|
|
205
|
+
const newContent = originalContent.replace("OriginalCert", "NewCert");
|
|
206
|
+
fs.writeFileSync(certPath, newContent);
|
|
207
|
+
|
|
208
|
+
// Should read new content after cache clear
|
|
209
|
+
const result2 = await certsCache.getCachedCustomCert(certPath);
|
|
210
|
+
expect(result2).toBe(newContent);
|
|
211
|
+
});
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
describe("Error handling scenarios", () => {
|
|
215
|
+
test("should handle non-existent certificate files gracefully", async () => {
|
|
216
|
+
const nonExistentPath = path.join(tempDir, "does-not-exist.pem");
|
|
217
|
+
|
|
218
|
+
// Should not throw but should continue with system certificates only
|
|
219
|
+
const options = await getAgentOptions({ caBundlePath: nonExistentPath });
|
|
220
|
+
|
|
221
|
+
expect(options.ca).toBeDefined();
|
|
222
|
+
expect(Array.isArray(options.ca)).toBe(true);
|
|
223
|
+
// Should only contain system certificates, not the missing custom one
|
|
224
|
+
expect(options.ca.length).toBeGreaterThan(0);
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
test("should handle empty certificate files", () => {
|
|
228
|
+
const emptyCertPath = path.join(tempDir, "empty-cert.pem");
|
|
229
|
+
fs.writeFileSync(emptyCertPath, "");
|
|
230
|
+
|
|
231
|
+
const result = getCertificateContent(emptyCertPath);
|
|
232
|
+
expect(result).toBe("");
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
test("should handle malformed data URIs", () => {
|
|
236
|
+
const validMalformedDataUris = ["data:invalid-format", "data:"];
|
|
237
|
+
|
|
238
|
+
validMalformedDataUris.forEach((uri) => {
|
|
239
|
+
// These should not throw but may return unexpected content
|
|
240
|
+
expect(() => getCertificateContent(uri)).not.toThrow();
|
|
241
|
+
const result = getCertificateContent(uri);
|
|
242
|
+
expect(typeof result).toBe("string");
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
// This one will be treated as a file path and should throw
|
|
246
|
+
expect(() => getCertificateContent("not-a-data-uri-at-all")).toThrow(
|
|
247
|
+
"ENOENT",
|
|
248
|
+
);
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
describe("Real-world scenarios", () => {
|
|
253
|
+
test("should handle certificate bundle with multiple certificates", () => {
|
|
254
|
+
const bundleContent = `-----BEGIN CERTIFICATE-----
|
|
255
|
+
MIIDRootCA1234567890abcdefghijklmnopqrstuvwxyz
|
|
256
|
+
-----END CERTIFICATE-----
|
|
257
|
+
-----BEGIN CERTIFICATE-----
|
|
258
|
+
MIIDIntermediateCA1234567890abcdefghijklmnopqrstuvwxyz
|
|
259
|
+
-----END CERTIFICATE-----`;
|
|
260
|
+
|
|
261
|
+
const bundlePath = path.join(tempDir, "ca-bundle.pem");
|
|
262
|
+
fs.writeFileSync(bundlePath, bundleContent);
|
|
263
|
+
|
|
264
|
+
const result = getCertificateContent(bundlePath);
|
|
265
|
+
expect(result).toBe(bundleContent);
|
|
266
|
+
expect(result).toContain("RootCA");
|
|
267
|
+
expect(result).toContain("IntermediateCA");
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
test("should work with common certificate file extensions", () => {
|
|
271
|
+
const certExtensions = [".pem", ".crt", ".cer"];
|
|
272
|
+
const testCert = `-----BEGIN CERTIFICATE-----
|
|
273
|
+
MIIDTestCert1234567890abcdefghijklmnopqrstuvwxyz
|
|
274
|
+
-----END CERTIFICATE-----`;
|
|
275
|
+
|
|
276
|
+
for (const ext of certExtensions) {
|
|
277
|
+
const certPath = path.join(tempDir, `test-cert${ext}`);
|
|
278
|
+
fs.writeFileSync(certPath, testCert);
|
|
279
|
+
|
|
280
|
+
const result = getCertificateContent(certPath);
|
|
281
|
+
expect(result).toBe(testCert);
|
|
282
|
+
}
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
test("should handle proxy scenarios with custom certificates", async () => {
|
|
286
|
+
// Test that certificates work properly when proxy might be involved
|
|
287
|
+
const proxyCaCert = `-----BEGIN CERTIFICATE-----
|
|
288
|
+
MIIDProxyCA1234567890abcdefghijklmnopqrstuvwxyz
|
|
289
|
+
-----END CERTIFICATE-----`;
|
|
290
|
+
|
|
291
|
+
const proxyCaPath = path.join(tempDir, "proxy-ca.pem");
|
|
292
|
+
fs.writeFileSync(proxyCaPath, proxyCaCert);
|
|
293
|
+
|
|
294
|
+
const options = await getAgentOptions({ caBundlePath: proxyCaPath });
|
|
295
|
+
|
|
296
|
+
expect(options.ca).toBeDefined();
|
|
297
|
+
expect(options.ca).toContain(proxyCaCert);
|
|
298
|
+
expect(options.keepAlive).toBe(true); // Should work with keep-alive for proxy scenarios
|
|
299
|
+
});
|
|
300
|
+
});
|
|
301
|
+
});
|
package/src/stream.test.ts
CHANGED
|
@@ -90,6 +90,13 @@ describe("parseDataLine", () => {
|
|
|
90
90
|
);
|
|
91
91
|
});
|
|
92
92
|
|
|
93
|
+
test("parseDataLine should throw error when data contains error object with message", () => {
|
|
94
|
+
const line = 'data: {"error":{"message":"detailed error message"}}';
|
|
95
|
+
expect(() => parseDataLine(line)).toThrow(
|
|
96
|
+
"Error streaming response: detailed error message",
|
|
97
|
+
);
|
|
98
|
+
});
|
|
99
|
+
|
|
93
100
|
test("parseDataLine should handle empty objects", () => {
|
|
94
101
|
const line = "data: {}";
|
|
95
102
|
const result = parseDataLine(line);
|
package/vitest.config.ts
CHANGED
|
@@ -5,6 +5,7 @@ export default defineConfig({
|
|
|
5
5
|
environment: "node",
|
|
6
6
|
timeout: 10000,
|
|
7
7
|
globals: true,
|
|
8
|
+
include: ["**/*.{test,spec}.?(c|m)[jt]s?(x)"],
|
|
8
9
|
},
|
|
9
10
|
resolve: {
|
|
10
11
|
alias: {
|
|
@@ -12,6 +13,8 @@ export default defineConfig({
|
|
|
12
13
|
"./getAgentOptions.js": "./getAgentOptions.ts",
|
|
13
14
|
"./stream.js": "./stream.ts",
|
|
14
15
|
"./util.js": "./util.ts",
|
|
16
|
+
"./certs.js": "./certs.ts",
|
|
17
|
+
"./fetch.js": "./fetch.ts",
|
|
15
18
|
},
|
|
16
19
|
},
|
|
17
20
|
});
|
package/dist/fetch.test.js
DELETED
|
@@ -1,131 +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
|
-
// Store original env
|
|
8
|
-
const originalEnv = process.env;
|
|
9
|
-
const originalGlobalAgentOptions = { ...globalAgent.options };
|
|
10
|
-
// Temporary directory for test certificate files
|
|
11
|
-
let tempDir;
|
|
12
|
-
beforeEach(() => {
|
|
13
|
-
// Create a temporary directory for test files
|
|
14
|
-
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "fetch-test-"));
|
|
15
|
-
process.env = { ...originalEnv };
|
|
16
|
-
// Reset globalAgent for each test
|
|
17
|
-
globalAgent.options = { ...originalGlobalAgentOptions };
|
|
18
|
-
});
|
|
19
|
-
afterEach(() => {
|
|
20
|
-
process.env = originalEnv;
|
|
21
|
-
globalAgent.options = originalGlobalAgentOptions;
|
|
22
|
-
// Clean up temporary directory
|
|
23
|
-
try {
|
|
24
|
-
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
25
|
-
}
|
|
26
|
-
catch (error) {
|
|
27
|
-
console.error(`Failed to remove temp directory: ${error}`);
|
|
28
|
-
}
|
|
29
|
-
});
|
|
30
|
-
// Helper function to create test certificate files
|
|
31
|
-
function createTestCertFile(filename, content) {
|
|
32
|
-
const filePath = path.join(tempDir, filename);
|
|
33
|
-
fs.writeFileSync(filePath, content, "utf8");
|
|
34
|
-
return filePath;
|
|
35
|
-
}
|
|
36
|
-
test("getAgentOptions returns basic configuration with default values", () => {
|
|
37
|
-
const options = getAgentOptions();
|
|
38
|
-
// Check default timeout (7200 seconds = 2 hours = 7,200,000 ms)
|
|
39
|
-
expect(options.timeout).toBe(7200000);
|
|
40
|
-
expect(options.sessionTimeout).toBe(7200000);
|
|
41
|
-
expect(options.keepAliveMsecs).toBe(7200000);
|
|
42
|
-
expect(options.keepAlive).toBe(true);
|
|
43
|
-
// Verify certificates array exists and contains items
|
|
44
|
-
expect(options.ca).toBeInstanceOf(Array);
|
|
45
|
-
expect(options.ca.length).toBeGreaterThan(0);
|
|
46
|
-
// Verify at least one of the real TLS root certificates is included
|
|
47
|
-
// This assumes there's at least one certificate with "CERTIFICATE" in it
|
|
48
|
-
expect(options.ca.some((cert) => cert.includes("CERTIFICATE"))).toBe(true);
|
|
49
|
-
});
|
|
50
|
-
test("getAgentOptions respects custom timeout", () => {
|
|
51
|
-
const customTimeout = 300; // 5 minutes
|
|
52
|
-
const options = getAgentOptions({ timeout: customTimeout });
|
|
53
|
-
// Check timeout values (300 seconds = 300,000 ms)
|
|
54
|
-
expect(options.timeout).toBe(300000);
|
|
55
|
-
expect(options.sessionTimeout).toBe(300000);
|
|
56
|
-
expect(options.keepAliveMsecs).toBe(300000);
|
|
57
|
-
});
|
|
58
|
-
test("getAgentOptions uses verifySsl setting", () => {
|
|
59
|
-
// With verifySsl true
|
|
60
|
-
let options = getAgentOptions({ verifySsl: true });
|
|
61
|
-
expect(options.rejectUnauthorized).toBe(true);
|
|
62
|
-
// With verifySsl false
|
|
63
|
-
options = getAgentOptions({ verifySsl: false });
|
|
64
|
-
expect(options.rejectUnauthorized).toBe(false);
|
|
65
|
-
});
|
|
66
|
-
test("getAgentOptions incorporates custom CA bundle paths", () => {
|
|
67
|
-
// Create a test CA bundle file
|
|
68
|
-
const caBundleContent = "-----BEGIN CERTIFICATE-----\nMIIDtTCCAp2gAwIBAgIJAMcuSp7chAYdMA==\n-----END CERTIFICATE-----";
|
|
69
|
-
const caBundlePath = createTestCertFile("ca-bundle.pem", caBundleContent);
|
|
70
|
-
// Single string path
|
|
71
|
-
let options = getAgentOptions({ caBundlePath });
|
|
72
|
-
// Verify that our test certificate is included in the CA list
|
|
73
|
-
expect(options.ca).toContain(caBundleContent);
|
|
74
|
-
// Create multiple test CA bundle files
|
|
75
|
-
const caContent1 = "-----BEGIN CERTIFICATE-----\nABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\n-----END CERTIFICATE-----";
|
|
76
|
-
const caContent2 = "-----BEGIN CERTIFICATE-----\n0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\n-----END CERTIFICATE-----";
|
|
77
|
-
const caPath1 = createTestCertFile("ca1.pem", caContent1);
|
|
78
|
-
const caPath2 = createTestCertFile("ca2.pem", caContent2);
|
|
79
|
-
// Array of paths
|
|
80
|
-
options = getAgentOptions({
|
|
81
|
-
caBundlePath: [caPath1, caPath2],
|
|
82
|
-
});
|
|
83
|
-
// Verify that both test certificates are included in the CA list
|
|
84
|
-
expect(options.ca).toContain(caContent1);
|
|
85
|
-
expect(options.ca).toContain(caContent2);
|
|
86
|
-
});
|
|
87
|
-
test("getAgentOptions includes global certs when running as binary", () => {
|
|
88
|
-
// Set up test certs in globalAgent
|
|
89
|
-
globalAgent.options.ca = ["global-cert-1", "global-cert-2"];
|
|
90
|
-
// Set IS_BINARY environment variable
|
|
91
|
-
process.env.IS_BINARY = "true";
|
|
92
|
-
const options = getAgentOptions();
|
|
93
|
-
// Test for global certs
|
|
94
|
-
expect(options.ca).toContain("global-cert-1");
|
|
95
|
-
expect(options.ca).toContain("global-cert-2");
|
|
96
|
-
});
|
|
97
|
-
test("getAgentOptions handles client certificate configuration", () => {
|
|
98
|
-
// Create test certificate files
|
|
99
|
-
const clientCertContent = "-----BEGIN CERTIFICATE-----\nCLIENTCERT\n-----END CERTIFICATE-----";
|
|
100
|
-
const clientKeyContent = "-----BEGIN PRIVATE KEY-----\nCLIENTKEY\n-----END PRIVATE KEY-----";
|
|
101
|
-
const certPath = createTestCertFile("client.cert", clientCertContent);
|
|
102
|
-
const keyPath = createTestCertFile("client.key", clientKeyContent);
|
|
103
|
-
const clientCertOptions = {
|
|
104
|
-
clientCertificate: {
|
|
105
|
-
cert: certPath,
|
|
106
|
-
key: keyPath,
|
|
107
|
-
passphrase: "secret-passphrase",
|
|
108
|
-
},
|
|
109
|
-
};
|
|
110
|
-
const options = getAgentOptions(clientCertOptions);
|
|
111
|
-
expect(options.cert).toBe(clientCertContent);
|
|
112
|
-
expect(options.key).toBe(clientKeyContent);
|
|
113
|
-
expect(options.passphrase).toBe("secret-passphrase");
|
|
114
|
-
});
|
|
115
|
-
test("getAgentOptions handles client certificate without passphrase", () => {
|
|
116
|
-
// Create test certificate files
|
|
117
|
-
const clientCertContent = "-----BEGIN CERTIFICATE-----\nCLIENTCERT2\n-----END CERTIFICATE-----";
|
|
118
|
-
const clientKeyContent = "-----BEGIN PRIVATE KEY-----\nCLIENTKEY2\n-----END PRIVATE KEY-----";
|
|
119
|
-
const certPath = createTestCertFile("client2.cert", clientCertContent);
|
|
120
|
-
const keyPath = createTestCertFile("client2.key", clientKeyContent);
|
|
121
|
-
const clientCertOptions = {
|
|
122
|
-
clientCertificate: {
|
|
123
|
-
cert: certPath,
|
|
124
|
-
key: keyPath,
|
|
125
|
-
},
|
|
126
|
-
};
|
|
127
|
-
const options = getAgentOptions(clientCertOptions);
|
|
128
|
-
expect(options.cert).toBe(clientCertContent);
|
|
129
|
-
expect(options.key).toBe(clientKeyContent);
|
|
130
|
-
expect(options.passphrase).toBeUndefined();
|
|
131
|
-
});
|
|
File without changes
|