Skip to content

Commit 2600a89

Browse files
committed
fix: do not block with execSync when launching firefox, template openssl conf to get config paths
1 parent 18855e2 commit 2600a89

File tree

2 files changed

+23
-17
lines changed

2 files changed

+23
-17
lines changed

openssl.conf

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ default_md = sha256
77
name_opt = ca_default
88
cert_opt = ca_default
99
policy = policy_loose
10-
database = index.txt
11-
serial = serial
10+
database = DIR/index.txt
11+
serial = DIR/serial
1212
prompt = no
1313

1414
[ policy_loose ]

src/index.ts

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
import * as path from 'path';
1010
import * as getPort from 'get-port';
1111
import * as http from 'http';
12-
import { execSync } from 'child_process';
12+
import { exec, execSync } from 'child_process';
1313
import * as tmp from 'tmp';
1414
import * as glob from 'glob';
1515
import * as Configstore from 'configstore';
@@ -32,12 +32,16 @@ if (isWindows && process.env.LOCALAPPDATA) {
3232
let userHome = (isLinux && uid === 0) ? path.resolve('/usr/local/share') : require('os').homedir();
3333
configDir = path.join(userHome, '.config', 'devcert');
3434
}
35-
mkdirp.sync(configDir);
3635
const configPath: (...pathSegments: string[]) => string = path.join.bind(path, configDir);
3736

38-
const opensslConfPath = path.join(__dirname, '..', 'openssl.conf');
37+
const opensslConfTemplate = path.join(__dirname, '..', 'openssl.conf');
38+
const opensslConfPath = configPath('openssl.conf');
3939
const rootKeyPath = configPath('devcert-ca-root.key');
4040
const rootCertPath = configPath('devcert-ca-root.crt');
41+
const caCertsDir = configPath('certs');
42+
43+
mkdirp.sync(configDir);
44+
mkdirp.sync(caCertsDir);
4145

4246
export interface Options {
4347
installCertutil?: boolean;
@@ -57,14 +61,14 @@ export default async function devcert(appName: string, options: Options = {}) {
5761
let appKeyPath = configPath(`${ appName }.key`);
5862
let appCertPath = configPath(`${ appName }.crt`);
5963

60-
if (!existsSync(rootKeyPath)) {
64+
if (!existsSync(rootCertPath)) {
6165
debug('devcert root CA not installed yet, must be first run; installing root CA ...');
6266
await installCertificateAuthority(options.installCertutil);
6367
}
6468

65-
if (!existsSync(configPath(`${ appName }.key`))) {
69+
if (!existsSync(configPath(`${ appName }.crt`))) {
6670
debug(`first request for ${ appName } cert, generating and caching ...`);
67-
generateKey(appName);
71+
generateKey(configPath(`${ appName }.key`));
6872
generateSignedCertificate(appName, appKeyPath);
6973
}
7074

@@ -81,18 +85,21 @@ export default async function devcert(appName: string, options: Options = {}) {
8185
// Install the once-per-machine trusted root CA. We'll use this CA to sign per-app certs, allowing
8286
// us to minimize the need for elevated permissions while still allowing for per-app certificates.
8387
async function installCertificateAuthority(installCertutil: boolean): Promise<void> {
88+
debug(`generating openssl configuration`);
89+
writeFileSync(opensslConfPath, readFileSync(opensslConfTemplate, 'utf-8').replace(/DIR/g, configDir));
8490
debug(`generating root certificate authority key`);
85-
generateKey('devcert-ca-root');
91+
generateKey(rootKeyPath);
8692
debug(`generating root certificate authority certificate`);
8793
execSync(`openssl req -config ${ opensslConfPath } -key ${ rootKeyPath } -out ${ rootCertPath } -new -subj '/CN=devcert' -x509 -days 7000 -extensions v3_ca`);
8894
debug(`adding root certificate authority to trust stores`)
8995
await addCertificateToTrustStores(installCertutil);
96+
writeFileSync(configPath('index.txt'), '');
97+
writeFileSync(configPath('serial'), '01');
9098
}
9199

92100
// Generate a cryptographic key, used to sign certificates or certificate signing requests.
93-
function generateKey(name: string): void {
94-
debug(`generateKey: ${ name }`);
95-
let filename = configPath(`${ name }.key`);
101+
function generateKey(filename: string): void {
102+
debug(`generateKey: ${ filename }`);
96103
execSync(`openssl genrsa -out ${ filename } 2048`);
97104
chmodSync(filename, 400);
98105
}
@@ -104,7 +111,7 @@ function generateSignedCertificate(name: string, keyPath: string): void {
104111
execSync(`openssl req -config ${ opensslConfPath } -subj '/CN=${ name }' -key ${ keyPath } -out ${ csrFile } -new`);
105112
debug(`generating certificate for ${ name } from signing request; signing with devcert root CA`);
106113
let certPath = configPath(`${ name }.crt`);
107-
execSync(`openssl ca -config ${ opensslConfPath } -in ${ csrFile } -out ${ certPath } -keyfile ${ rootKeyPath } -cert ${ rootCertPath } -notext -md sha256 -days 7000 -extensions server_cert`)
114+
execSync(`openssl ca -config ${ opensslConfPath } -in ${ csrFile } -out ${ certPath } -outdir ${ caCertsDir } -keyfile ${ rootKeyPath } -cert ${ rootCertPath } -notext -md sha256 -days 7000 -extensions server_cert`)
108115
}
109116

110117
// Add the devcert root CA certificate to the trust stores for this machine. Adds to OS level trust
@@ -185,12 +192,11 @@ async function openCertificateInFirefox(firefoxPath: string): Promise<void> {
185192
res.end();
186193
}).listen(port);
187194
debug('certificate is hosted, starting firefox at hosted URL');
188-
execSync(`${ firefoxPath } http://localhost:${ port }`);
189195
await new Promise((resolve) => {
190-
console.log('Unable to automatically install SSL certificate - please follow the prompts in Firefox to trust the root certificate');
196+
console.log('Unable to automatically install SSL certificate - please follow the prompts at http://localhost:${ port } in Firefox to trust the root certificate');
191197
console.log('See https://github.com/davewasmer/devcert#how-it-works for more details');
192-
console.log('Press any key once you finish the Firefox prompts');
193-
debug('waiting for user to finish firefox certificate import');
198+
console.log('-- Press <Enter> once you finish the Firefox prompts --');
199+
exec(`${ firefoxPath } http://localhost:${ port }`);
194200
process.stdin.resume();
195201
process.stdin.on('data', resolve);
196202
});

0 commit comments

Comments
 (0)