UNPKG

homebridge-config-ui-x

Version:

A web based management, configuration and control platform for Homebridge.

126 lines 5.73 kB
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var SslCertGeneratorService_1; import { Buffer } from 'node:buffer'; import { existsSync } from 'node:fs'; import { readFile, writeFile } from 'node:fs/promises'; import { homedir } from 'node:os'; import { join, resolve } from 'node:path'; import process from 'node:process'; import { Injectable } from '@nestjs/common'; import { ensureDir } from 'fs-extra/esm'; import forge from 'node-forge'; import { Logger } from '../logger/logger.service.js'; import { RE_IPV4, RE_IPV6 } from '../regex.constants.js'; let SslCertGeneratorService = SslCertGeneratorService_1 = class SslCertGeneratorService { logger = new Logger(SslCertGeneratorService_1.name); certDir; privateKeyPath; certificatePath; constructor() { const storagePath = process.env.UIX_STORAGE_PATH || resolve(homedir(), '.homebridge'); this.certDir = join(storagePath, 'ssl-certs'); this.privateKeyPath = join(this.certDir, 'private-key.pem'); this.certificatePath = join(this.certDir, 'certificate.pem'); } async generateOrLoadCertificate(hostnames = ['localhost']) { if (existsSync(this.privateKeyPath) && existsSync(this.certificatePath)) { try { const privateKey = await readFile(this.privateKeyPath); const certificate = await readFile(this.certificatePath); this.logger.log('Loaded existing self-signed certificate'); return { privateKey, certificate }; } catch (error) { this.logger.warn('Failed to load existing certificate, generating new one:', error.message); } } return this.generateCertificate(hostnames); } async generateCertificate(hostnames) { this.logger.log('Generating self-signed certificate...'); try { await ensureDir(this.certDir); const keys = forge.pki.rsa.generateKeyPair(2048); const cert = forge.pki.createCertificate(); cert.publicKey = keys.publicKey; cert.serialNumber = '01'; cert.validity.notBefore = new Date(); cert.validity.notAfter = new Date('2050-01-01T00:00:00Z'); const attrs = [ { name: 'commonName', value: hostnames[0] || 'localhost' }, { name: 'countryName', value: 'US' }, { shortName: 'ST', value: 'State' }, { name: 'localityName', value: 'City' }, { name: 'organizationName', value: 'Homebridge' }, { shortName: 'OU', value: 'Homebridge UI' }, ]; cert.setSubject(attrs); cert.setIssuer(attrs); const extensions = [ { name: 'basicConstraints', cA: true, }, { name: 'keyUsage', keyCertSign: true, digitalSignature: true, nonRepudiation: true, keyEncipherment: true, dataEncipherment: true, }, { name: 'extKeyUsage', serverAuth: true, clientAuth: true, }, { name: 'subjectAltName', altNames: hostnames.map((hostname) => { if (RE_IPV4.test(hostname) || RE_IPV6.test(hostname)) { return { type: 7, ip: hostname, }; } else { return { type: 2, value: hostname, }; } }), }, ]; cert.setExtensions(extensions); cert.sign(keys.privateKey, forge.md.sha256.create()); const privateKeyPem = forge.pki.privateKeyToPem(keys.privateKey); const certificatePem = forge.pki.certificateToPem(cert); await writeFile(this.privateKeyPath, privateKeyPem, 'utf8'); await writeFile(this.certificatePath, certificatePem, 'utf8'); this.logger.log(`Self-signed certificate generated successfully for: ${hostnames.join(', ')}`); return { privateKey: Buffer.from(privateKeyPem), certificate: Buffer.from(certificatePem), }; } catch (error) { this.logger.error('Failed to generate self-signed certificate:', error); throw error; } } }; SslCertGeneratorService = SslCertGeneratorService_1 = __decorate([ Injectable(), __metadata("design:paramtypes", []) ], SslCertGeneratorService); export { SslCertGeneratorService }; //# sourceMappingURL=ssl-cert-generator.service.js.map