diff --git a/packages/vite/LICENSE.md b/packages/vite/LICENSE.md index 57390f20204853..95cd9f34ffdfd0 100644 --- a/packages/vite/LICENSE.md +++ b/packages/vite/LICENSE.md @@ -3439,35 +3439,6 @@ Repository: git://github.com/feross/safe-buffer.git --------------------------------------- -## selfsigned -License: MIT -By: José F. Romaniello, Paolo Fragomeni, Charles Bushong -Repository: git://github.com/jfromaniello/selfsigned.git - -> MIT License -> -> Copyright (c) 2013 José F. Romaniello -> -> Permission is hereby granted, free of charge, to any person obtaining a copy -> of this software and associated documentation files (the "Software"), to deal -> in the Software without restriction, including without limitation the rights -> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -> copies of the Software, and to permit persons to whom the Software is -> furnished to do so, subject to the following conditions: -> -> The above copyright notice and this permission notice shall be included in all -> copies or substantial portions of the Software. -> -> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -> SOFTWARE. - ---------------------------------------- - ## shebang-command License: MIT By: Kevin Mårtensson diff --git a/packages/vite/package.json b/packages/vite/package.json index 32261eba58fd87..f1b73c2d873c2e 100644 --- a/packages/vite/package.json +++ b/packages/vite/package.json @@ -99,6 +99,7 @@ "magic-string": "^0.25.7", "micromatch": "^4.0.4", "mrmime": "^1.0.0", + "node-forge": "^0.10.0", "okie": "^1.0.1", "open": "^8.4.0", "periscopic": "^2.0.3", @@ -108,7 +109,6 @@ "postcss-modules": "^4.3.0", "resolve.exports": "^1.1.0", "rollup-plugin-license": "^2.6.0", - "selfsigned": "^1.10.11", "sirv": "^1.0.19", "source-map": "^0.6.1", "source-map-support": "^0.5.21", diff --git a/packages/vite/src/node/certificate.ts b/packages/vite/src/node/certificate.ts new file mode 100644 index 00000000000000..b4f442cf265885 --- /dev/null +++ b/packages/vite/src/node/certificate.ts @@ -0,0 +1,145 @@ +// simplified fork of +// https://github.com/jfromaniello/selfsigned/blob/da38146f8d02183c35f49f91659a744a243e8707/index.js +// with inlined options and partial node-forge usage +// to achieve smaller bundle +// +// this utility create untrusted certificate which still +// allows to access page after proceeding a wall with warning +// +// should be deprecated eventually and replaced with recipes +// about generating secure trusted certificates + +// @ts-ignore +import forge from 'node-forge/lib/forge' +// @ts-ignore +import 'node-forge/lib/pki' + +// a hexString is considered negative if it's most significant bit is 1 +// because serial numbers use ones' complement notation +// this RFC in section 4.1.2.2 requires serial numbers to be positive +// http://www.ietf.org/rfc/rfc5280.txt +function toPositiveHex(hexString: string) { + let mostSiginficativeHexAsInt = parseInt(hexString[0], 16) + if (mostSiginficativeHexAsInt < 8) { + return hexString + } + + mostSiginficativeHexAsInt -= 8 + return mostSiginficativeHexAsInt.toString() + hexString.substring(1) +} + +export function createCertificate(): string { + const days = 30 + const keySize = 2048 + + const extensions = [ + // { + // name: 'basicConstraints', + // cA: true, + // }, + { + name: 'keyUsage', + keyCertSign: true, + digitalSignature: true, + nonRepudiation: true, + keyEncipherment: true, + dataEncipherment: true + }, + { + name: 'extKeyUsage', + serverAuth: true, + clientAuth: true, + codeSigning: true, + timeStamping: true + }, + { + name: 'subjectAltName', + altNames: [ + { + // type 2 is DNS + type: 2, + value: 'localhost' + }, + { + type: 2, + value: 'localhost.localdomain' + }, + { + type: 2, + value: 'lvh.me' + }, + { + type: 2, + value: '*.lvh.me' + }, + { + type: 2, + value: '[::1]' + }, + { + // type 7 is IP + type: 7, + ip: '127.0.0.1' + }, + { + type: 7, + ip: 'fe80::1' + } + ] + } + ] + + const attrs = [ + { + name: 'commonName', + value: 'example.org' + }, + { + name: 'countryName', + value: 'US' + }, + { + shortName: 'ST', + value: 'Virginia' + }, + { + name: 'localityName', + value: 'Blacksburg' + }, + { + name: 'organizationName', + value: 'Test' + }, + { + shortName: 'OU', + value: 'Test' + } + ] + + const keyPair = forge.pki.rsa.generateKeyPair(keySize) + + const cert = forge.pki.createCertificate() + + cert.serialNumber = toPositiveHex( + forge.util.bytesToHex(forge.random.getBytesSync(9)) + ) // the serial number can be decimal or hex (if preceded by 0x) + + cert.validity.notBefore = new Date() + cert.validity.notAfter = new Date() + cert.validity.notAfter.setDate(cert.validity.notBefore.getDate() + days) + + cert.setSubject(attrs) + cert.setIssuer(attrs) + + cert.publicKey = keyPair.publicKey + + cert.setExtensions(extensions) + + const algorithm = forge.md.sha256.create() + cert.sign(keyPair.privateKey, algorithm) + + const privateKeyPem = forge.pki.privateKeyToPem(keyPair.privateKey) + const certPem = forge.pki.certificateToPem(cert) + + return privateKeyPem + certPem +} diff --git a/packages/vite/src/node/http.ts b/packages/vite/src/node/http.ts index 06980b3e2884d8..28be35c276c6c8 100644 --- a/packages/vite/src/node/http.ts +++ b/packages/vite/src/node/http.ts @@ -152,82 +152,13 @@ function readFileIfExists(value?: string | Buffer | any[]) { return value } -/** - * https://github.com/webpack/webpack-dev-server/blob/master/lib/utils/createCertificate.js - * - * Copyright JS Foundation and other contributors - * This source code is licensed under the MIT license found in the - * LICENSE file at - * https://github.com/webpack/webpack-dev-server/blob/master/LICENSE - */ -async function createCertificate() { - const { generate } = await import('selfsigned') - const pems = generate(null, { - algorithm: 'sha256', - days: 30, - keySize: 2048, - extensions: [ - // { - // name: 'basicConstraints', - // cA: true, - // }, - { - name: 'keyUsage', - keyCertSign: true, - digitalSignature: true, - nonRepudiation: true, - keyEncipherment: true, - dataEncipherment: true - }, - { - name: 'extKeyUsage', - serverAuth: true, - clientAuth: true, - codeSigning: true, - timeStamping: true - }, - { - name: 'subjectAltName', - altNames: [ - { - // type 2 is DNS - type: 2, - value: 'localhost' - }, - { - type: 2, - value: 'localhost.localdomain' - }, - { - type: 2, - value: 'lvh.me' - }, - { - type: 2, - value: '*.lvh.me' - }, - { - type: 2, - value: '[::1]' - }, - { - // type 7 is IP - type: 7, - ip: '127.0.0.1' - }, - { - type: 7, - ip: 'fe80::1' - } - ] - } - ] - }) - return pems.private + pems.cert +async function createCertificateLazily() { + const { createCertificate } = await import('./certificate') + return createCertificate() } async function getCertificate(cacheDir?: string) { - if (!cacheDir) return await createCertificate() + if (!cacheDir) return await createCertificateLazily() const cachePath = path.join(cacheDir, '_cert.pem') @@ -243,7 +174,7 @@ async function getCertificate(cacheDir?: string) { return content } catch { - const content = await createCertificate() + const content = await createCertificateLazily() fsp .mkdir(cacheDir, { recursive: true }) .then(() => fsp.writeFile(cachePath, content)) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 18a7f91269e990..bf47e7009e2dc0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -763,6 +763,7 @@ importers: magic-string: ^0.25.7 micromatch: ^4.0.4 mrmime: ^1.0.0 + node-forge: ^0.10.0 okie: ^1.0.1 open: ^8.4.0 periscopic: ^2.0.3 @@ -775,7 +776,6 @@ importers: resolve.exports: ^1.1.0 rollup: ^2.59.0 rollup-plugin-license: ^2.6.0 - selfsigned: ^1.10.11 sirv: ^1.0.19 source-map: ^0.6.1 source-map-support: ^0.5.21 @@ -839,6 +839,7 @@ importers: magic-string: 0.25.7 micromatch: 4.0.4 mrmime: 1.0.0 + node-forge: 0.10.0 okie: 1.0.1 open: 8.4.0 periscopic: 2.0.3 @@ -848,7 +849,6 @@ importers: postcss-modules: 4.3.0_postcss@8.4.5 resolve.exports: 1.1.0 rollup-plugin-license: 2.6.0_rollup@2.62.0 - selfsigned: 1.10.11 sirv: 1.0.19 source-map: 0.6.1 source-map-support: 0.5.21