quasar
113 строк · 2.4 Кб
1import { existsSync, readFileSync, writeFileSync, statSync } from 'node:fs'2import fse from 'fs-extra'3import { generate } from 'selfsigned'4
5const certPath = new URL('../ssl-server.pem', import.meta.url)6
7export function generateCertificate ({8log,9fatal
10}) {11log('Generating self signed localhost SSL Certificate...')12
13const attrs = [14{ name: 'commonName', value: 'localhost' }15]16
17const pems = generate(attrs, {18algorithm: 'sha256',19days: 30,20keySize: 2048,21extensions: [22{23name: 'basicConstraints',24cA: true25},26{27name: 'keyUsage',28keyCertSign: true,29digitalSignature: true,30nonRepudiation: true,31keyEncipherment: true,32dataEncipherment: true33},34{35name: 'extKeyUsage',36serverAuth: true,37clientAuth: true,38codeSigning: true,39timeStamping: true40},41{42name: 'subjectAltName',43altNames: [44{45// type 2 is DNS46type: 2,47value: 'localhost'48},49{50type: 2,51value: 'localhost.localdomain'52},53{54type: 2,55value: 'lvh.me'56},57{58type: 2,59value: '*.lvh.me'60},61{62type: 2,63value: '[::1]'64},65{66// type 7 is IP67type: 7,68ip: '127.0.0.1'69},70{71type: 7,72ip: 'fe80::1'73}74]75}76]77})78
79const certContent = pems.private + pems.cert80try {81writeFileSync(certPath, certContent, 'utf-8')82}83catch (err) {84console.error(err)85fatal('Cannot write localhost SSL certificate to: ' + certPath + '. Aborting...')86}87
88return certContent89}
90
91export function getCertificate ({92log,93fatal
94}) {95let certExists = existsSync(certPath)96
97if (certExists === true) {98const certStat = statSync(certPath)99const certTtl = 1000 * 60 * 60 * 24100const now = new Date()101
102// cert is more than 30 days old103if ((now - certStat.ctime) / certTtl > 30) {104log('Localhost SSL Certificate is more than 30 days old. Removing.')105fse.removeSync(certPath)106certExists = false107}108}109
110return certExists === true111? readFileSync(certPath, 'utf-8')112: generateCertificate({ log, fatal })113}
114