You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(tls): don't drop Mozilla roots when NODE_EXTRA_CA_CERTS is set on win32
Passing an explicit `connect.ca` to undici replaces Node's default trust
store entirely (Mozilla roots + NODE_EXTRA_CA_CERTS), it does not merge.
The previous change made win32 (and any platform where no system bundle
matched) return only the extra CA, dropping every public root CA — so
any public HTTPS endpoint failed with UNABLE_TO_GET_ISSUER_CERT_LOCALLY.
Narrow the extra-CA merge to the case where a system bundle was already
found (i.e. an explicit `ca` override is already happening). When no
system bundle is found, return `null` so Node's default trust store —
which already honors NODE_EXTRA_CA_CERTS — handles TLS.
Addresses maintainer review on #152.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
assert.equal(touched,false,'win32 skips system bundle discovery and only reads the extra CA path');
85
85
},results);
86
86
87
-
awaittestFunction('getSystemCACerts honors NODE_EXTRA_CA_CERTS on win32 (skips system bundle loop)',()=>{
88
-
constreads: string[]=[];
87
+
awaittestFunction('getSystemCACerts returns null on win32 even with NODE_EXTRA_CA_CERTS (no system bundle → defer to Node default)',()=>{
88
+
lettouched=false;
89
89
constcerts=getSystemCACerts({
90
90
platformName: 'win32',
91
-
fileExists: ()=>{thrownewError('system bundle path should not be probed on win32');},
92
-
readFile: (p)=>{reads.push(p);returnPEM;},
91
+
fileExists: ()=>{touched=true;returntrue;},
92
+
readFile: ()=>{touched=true;returnPEM;},
93
93
caPaths: ['/should/not/be/read'],
94
94
extraCaPath: '/opt/extra.pem',
95
95
});
96
-
assert.equal(certs,PEM,'win32 returns the extra CA bundle');
97
-
assert.deepEqual(reads,['/opt/extra.pem'],'only the extra CA path is read on win32');
96
+
assert.equal(certs,null,'win32 defers to Node default trust store; extra CA is honored via NODE_EXTRA_CA_CERTS at the Node level, not by overriding ca');
97
+
assert.equal(touched,false,'no bundle paths are read on win32; NODE_EXTRA_CA_CERTS is handled by Node itself');
98
+
},results);
99
+
100
+
awaittestFunction('getSystemCACerts returns null when no system bundle is found even if NODE_EXTRA_CA_CERTS is set',()=>{
101
+
// Mirrors the win32 case on a minimal Linux container: no CA_BUNDLE_PATHS
102
+
// match, but NODE_EXTRA_CA_CERTS is set. Returning null lets Node's
103
+
// default trust store (Mozilla + extra) handle TLS, instead of replacing
104
+
// it with the extra CA alone and dropping public roots.
105
+
constcerts=getSystemCACerts({
106
+
platformName: 'linux',
107
+
fileExists: ()=>false,
108
+
readFile: ()=>{thrownewError('should not be called');},
109
+
caPaths: ['/nope/a.crt','/nope/b.crt'],
110
+
extraCaPath: '/opt/extra.pem',
111
+
});
112
+
assert.equal(certs,null,'no system bundle → defer to Node default; do not override ca with extra alone');
98
113
},results);
99
114
100
115
awaittestFunction('getSystemCACerts returns the first readable bundle',()=>{
0 commit comments