@getflywheel/localcert
Version:
Generate and trust SSL certificates locally.
284 lines (223 loc) • 7.11 kB
JavaScript
;
const fs = require('fs');
const os = require('os');
const Darwin = require('./truststores/darwin');
const Linux = require('./truststores/linux');
const NSSBrowsers = require('./truststores/NSSBrowsers');
const path = require('path');
const Windows = require('./truststores/windows');
const X509Certificate = require('./helpers/x509certificate');
class localcert {
/**
* Constructor for the localcert module
*
* Sets up the localcert for processing SSL certificates on the primary operating systems
* (Linux, mac and windows).
*
* @since 1.0.0
* @constructor
* @param {string} certsPath The path to save or look for any certificates.
*/
constructor (certsPath = '') {
if (certsPath === '') {
certsPath = path.join(os.homedir(), '.localcerts');
if (!fs.existsSync(certsPath)) {
fs.mkdirSync(certsPath, { recursive: true });
}
}
fs.stat(certsPath, (err, stats) => {
if (err || !stats.isDirectory()) {
throw new Error('Invalid cert path specified');
}
});
this.certsPath = certsPath;
switch (os.platform()) {
case 'darwin':
this.processor = new Darwin();
break;
case 'win32':
this.processor = new Windows();
break;
case 'linux':
this.processor = new Linux();
break;
default:
break;
}
this.nssbrowsers = new NSSBrowsers();
this.certGenerator = new X509Certificate();
}
/**
* Returns true if the user has an NSS browser installed.
*
* @since 1.0.8
* @return {bool} True if the user has an NSS browser or false.
*/
hasNSS () {
return this.nssbrowsers.hasNSS;
}
/**
* Returns true if the user has certutil installed.
*
* @since 1.0.8
* @return {bool} True if the user has certutil installed or false.
*/
hasCertUtil () {
return this.nssbrowsers.hasCertutil;
}
/**
* Retrieve the list of NSS Databases.
*
* @since 1.0.8
* @return {array} An array containing all NSS Databases needed for trusting.
*/
async getNSSDatabases () {
const NSSDatabases = await this.nssbrowsers.getNSSDatabases(this.processor);
return NSSDatabases;
}
/**
* Loads an existing certificate to trust.
*
* @since 1.0.1
* @param {string} certPath The path to the certificate.
* @param {string} privateKeyPath The path to the private key.
* @return {object} The paths to the certificate files.
*/
async loadCertificate (certPath, privateKeyPath) {
fs.stat(certPath, (err, stats) => {
if (err || !stats.isFile()) {
throw new Error('Invalid cert path specified');
}
});
fs.stat(privateKeyPath, (err, stats) => {
if (err || !stats.isFile()) {
throw new Error('Invalid private key path specified');
}
});
return await this.certGenerator.setCertificate(certPath, privateKeyPath);
}
/**
* Vefifies the loaded certificate is trusted in the system.
*
* @since 1.1.4
* @return {bool} true if trust can be verified or false.
*/
async verifySystemTrust () {
const verified = await this.processor.verifyPlatformTrust(this.certGenerator);
return verified;
}
/**
* * Generates and trusts a self-signed certificate.
*
* Will generate a new self-signed certificate and trust it on the local
* operating system.
*
* @since 1.0.0
* @param {string|Array} domains Domain or domains to generate a certificate for.
* @param {string} countryName Two-letter country name
* @param {string} stateOrProvinceName Two-letter state
* @param {string} localityName Locality name
* @param {string} organizationName Organization name
* @param {string} organizationalUnitName Unit name
* @return {void}
*/
async generate (domains, countryName, stateOrProvinceName, localityName, organizationName, organizationalUnitName) {
return await this.certGenerator.generateCertificate(domains, countryName, stateOrProvinceName, localityName, organizationName, organizationalUnitName);
}
/**
* Saves the certificate and its private key to disk.
*
* @since 1.0.0
* @param {string} certsPath The path to save or look for any certificates.
* @return {object} JavaScript object containing the certificate paths.
*/
async saveCertificate (certsPath = '') {
if (certsPath === '') {
certsPath = this.certsPath;
}
fs.stat(certsPath, (err, stats) => {
if (err || !stats.isDirectory()) {
throw new Error('Invalid cert path specified');
}
});
return await this.certGenerator.saveCertificate(certsPath);
}
/**
* Trust a specified certificate on the local system store.
*
* @since 1.0.0
* @param {string} certPath The path to the certificate to trust.
* @param {bool} execute Set to false to return the command for your own sudo wrapper.
* @return {array} Array of sudo commands.
*/
async trustCertificatePlatform (certPath = '', execute = true) {
if (certPath === '') {
certPath = this.certGenerator.certPath;
}
fs.stat(certPath, (err, stats) => {
if (err || !stats.isFile()) {
throw new Error('Invalid cert path specified');
}
});
const success = await this.processor.installPlatform(certPath, execute);
return success;
}
/**
* Trust a specified certificate in local browsers that don't use the system store.
*
* @since 1.0.0
* @param {string} certPath The path to the certificate to trust.
* @param {bool} execute Set to false to return the command for your own sudo wrapper.
* @return {array} Array of trust commands.
*/
async trustCertificateNSS (certPath = '', execute = true) {
if (certPath === '') {
certPath = this.certGenerator.certPath;
}
fs.stat(certPath, (err, stats) => {
if (err || !stats.isFile()) {
throw new Error('Invalid cert path specified');
}
});
return await this.nssbrowsers.installPlatform(this.processor, certPath, execute);
}
/**
* Untrust a specified certificate on the local system.
*
* @since 1.0.0
* @param {string} certPath The path to the certificate to trust.
* @param {bool} execute Set to false to return the command for your own sudo wrapper.
* @return {array} Array of sudo commands.
*/
async removeCertificateTrustPlatform (certPath = '', execute = true) {
if (certPath === '') {
certPath = this.certGenerator.certPath;
}
fs.stat(certPath, (err, stats) => {
if (err || !stats.isFile()) {
throw new Error('Invalid cert path specified');
}
});
return await this.processor.uninstallPlatform(certPath, execute);
}
/**
* Untrust a specified certificate on the local system.
*
* @since 1.0.0
* @param {string} certPath The path to the certificate to trust.
* @param {bool} execute Set to false to return the command for your own sudo wrapper.
* @return {array} Array of sudo commands.
*/
async removeCertificateTrustNSS (certPath = '', execute = true) {
if (certPath === '') {
certPath = this.certGenerator.certPath;
}
fs.stat(certPath, (err, stats) => {
if (err || !stats.isFile()) {
throw new Error('Invalid cert path specified');
}
});
return await this.nssbrowsers.uninstallPlatform(this.processor, certPath, execute);
}
}
module.exports = localcert;