From 3257a341e45a8543f01b0029e4aea129c9b06775 Mon Sep 17 00:00:00 2001 From: neverland Date: Sun, 4 Oct 2026 19:45:48 +0800 Subject: [PATCH 1/2] fix: include IPv6 loopback in default certificate SANs --- src/util.ts | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/src/util.ts b/src/util.ts index e294f01..59f5362 100644 --- a/src/util.ts +++ b/src/util.ts @@ -46,12 +46,40 @@ export const resolveHttpsConfig = async ( options.filename ?? 'fake-cert.pem', ); + const selfsignedAttrs = options.selfsignedAttrs ?? [ + { name: 'commonName', value: 'localhost' }, + ]; + const commonName = + selfsignedAttrs.find( + (attr) => attr.name === 'commonName' || attr.shortName === 'CN', + )?.value ?? 'localhost'; const selfsignedOptions = { keySize: 2048, notAfterDate: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000), ...options.selfsignedOptions, }; + if (commonName === 'localhost' && !selfsignedOptions.extensions?.length) { + selfsignedOptions.extensions = [ + { name: 'basicConstraints', cA: false, critical: true }, + { + name: 'keyUsage', + digitalSignature: true, + keyEncipherment: true, + critical: true, + }, + { name: 'extKeyUsage', serverAuth: true, clientAuth: true }, + { + name: 'subjectAltName', + altNames: [ + { type: 2, value: 'localhost' }, + { type: 7, ip: '127.0.0.1' }, + { type: 7, ip: '::1' }, + ], + }, + ]; + } + if (fs.existsSync(certPath)) { const content = await fs.promises.readFile(certPath, { encoding: 'utf-8', @@ -66,10 +94,7 @@ export const resolveHttpsConfig = async ( } } - const pem = await selfsigned.generate( - options.selfsignedAttrs ?? [{ name: 'commonName', value: 'localhost' }], - selfsignedOptions, - ); + const pem = await selfsigned.generate(selfsignedAttrs, selfsignedOptions); const content = pem.private + pem.cert; From 4436c33d585c072ad5239ca1755c11baa6ae0fde Mon Sep 17 00:00:00 2001 From: neverland Date: Sun, 4 Oct 2026 19:49:40 +0800 Subject: [PATCH 2/2] refactor: limit IPv6 changes to certificate defaults --- src/util.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/util.ts b/src/util.ts index 59f5362..0e0d1c4 100644 --- a/src/util.ts +++ b/src/util.ts @@ -46,11 +46,8 @@ export const resolveHttpsConfig = async ( options.filename ?? 'fake-cert.pem', ); - const selfsignedAttrs = options.selfsignedAttrs ?? [ - { name: 'commonName', value: 'localhost' }, - ]; const commonName = - selfsignedAttrs.find( + options.selfsignedAttrs?.find( (attr) => attr.name === 'commonName' || attr.shortName === 'CN', )?.value ?? 'localhost'; const selfsignedOptions = { @@ -94,7 +91,10 @@ export const resolveHttpsConfig = async ( } } - const pem = await selfsigned.generate(selfsignedAttrs, selfsignedOptions); + const pem = await selfsigned.generate( + options.selfsignedAttrs ?? [{ name: 'commonName', value: 'localhost' }], + selfsignedOptions, + ); const content = pem.private + pem.cert;