fix(tls): load client certs into secureContext to prevent silent drop

Add Cache tab to Preferences UI
This commit is contained in:
lohit-bruno
2026-03-04 20:24:38 +05:30
parent 41f3519dcc
commit 070c840e52
2 changed files with 38 additions and 1 deletions

View File

@@ -9,7 +9,8 @@ import {
IconUserCircle,
IconKeyboard,
IconZoomQuestion,
IconSquareLetterB
IconSquareLetterB,
IconDatabase
} from '@tabler/icons';
import Support from './Support';
@@ -21,6 +22,7 @@ import Keybindings from './Keybindings';
import Beta from './Beta';
import StyledWrapper from './StyledWrapper';
import Cache from './Cache/index';
const Preferences = () => {
const dispatch = useDispatch();
@@ -65,6 +67,10 @@ const Preferences = () => {
case 'support': {
return <Support />;
}
case 'cache': {
return <Cache />;
}
}
};
@@ -100,6 +106,10 @@ const Preferences = () => {
<IconSquareLetterB size={16} strokeWidth={1.5} />
Beta
</div>
<div className={getTabClassname('cache')} role="tab" onClick={() => setTab('cache')}>
<IconDatabase size={16} strokeWidth={1.5} />
Cache
</div>
</div>
<section
className="flex flex-grow ps-2 pe-4 pt-2 pb-6 p-[12px] tab-panel"

View File

@@ -98,10 +98,37 @@ function buildSecureContext(ca: string | Buffer | (string | Buffer)[]): tls.Secu
* Convert agent options to use a secureContext instead of raw `ca`.
* This ensures custom CAs are added on top of the OpenSSL defaults
* rather than replacing the default CA store.
*
* When client certificates (pfx/cert/key) are also present, they are loaded
* into the secure context so they aren't silently ignored by Node.js
* (Node.js skips pfx/cert/key/ca when a secureContext is provided).
*/
function applySecureContext<T extends AgentOptions | HttpAgentOptions>(options: T): T {
if ('ca' in options && (options as AgentOptions).ca) {
const { ca, ...rest } = options as AgentOptions;
// When client certs are present alongside CA, build a combined context
// that includes both. This context can't be CA-cached since it's unique
// per client cert + CA combination.
const hasClientCert = rest.pfx || rest.cert || rest.key;
if (hasClientCert) {
const ctxOptions: Record<string, any> = {};
if (rest.pfx) ctxOptions.pfx = rest.pfx;
if (rest.cert) ctxOptions.cert = rest.cert;
if (rest.key) ctxOptions.key = rest.key;
if (rest.passphrase) ctxOptions.passphrase = rest.passphrase;
const ctx = tls.createSecureContext(ctxOptions);
const caList = Array.isArray(ca) ? ca : [ca!];
for (const caCert of caList) {
if (caCert) ctx.context.addCACert(caCert);
}
const { pfx: _pfx, cert: _cert, key: _key, passphrase: _pass, ...cleanRest } = rest;
return { ...cleanRest, secureContext: ctx } as unknown as T;
}
// CA-only case: use cached secure context
return { ...rest, secureContext: buildSecureContext(ca!) } as unknown as T;
}
return options;