UNPKG

9.94 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const tslib_1 = require("tslib");
4const fs_1 = require("fs");
5const createDebug = require("debug");
6const command_exists_1 = require("command-exists");
7const constants_1 = require("./constants");
8const root_authority_1 = require("./root-authority");
9const utils_1 = require("./utils");
10const debug = createDebug('devcert');
11/**
12 * Request an SSL certificate for the given app name signed by the devcert root certificate
13 * authority. If devcert has previously generated a certificate for that app name on this machine,
14 * it will reuse that certificate.
15 *
16 * If this is the first time devcert is being run on this machine, it will generate and attempt to
17 * install a root certificate authority.
18 *
19 * Returns a promise that resolves with { keyPath, certPath, key, cert }, where `key` and `cert` are
20 * Buffers with the contents of `keyPath` and `certPath`, respectively.
21 */
22function devcert(appName, options = {}) {
23 return tslib_1.__awaiter(this, void 0, void 0, function* () {
24 debug(`development cert requested for ${appName}`);
25 if (!constants_1.isMac && !constants_1.isLinux && !constants_1.isWindows) {
26 throw new Error(`devcert: "${process.platform}" platform not supported`);
27 }
28 if (!command_exists_1.sync('openssl')) {
29 throw new Error('Unable to find openssl - make sure it is installed and available in your PATH');
30 }
31 let appKeyPath = constants_1.configPath(`${appName}.key`);
32 let appCertPath = constants_1.configPath(`${appName}.crt`);
33 if (!fs_1.existsSync(constants_1.rootCertPath)) {
34 debug('devcert root CA not installed yet, must be first run; installing root CA ...');
35 yield root_authority_1.default(options.installCertutil);
36 }
37 if (!fs_1.existsSync(constants_1.configPath(`${appName}.crt`))) {
38 debug(`first request for ${appName} cert, generating and caching ...`);
39 utils_1.generateKey(constants_1.configPath(`${appName}.key`));
40 generateSignedCertificate(appName, appKeyPath);
41 }
42 debug(`returning app cert`);
43 return {
44 keyPath: appKeyPath,
45 certPath: appCertPath,
46 key: fs_1.readFileSync(appKeyPath),
47 cert: fs_1.readFileSync(appCertPath)
48 };
49 });
50}
51exports.default = devcert;
52// Generate an app certificate signed by the devcert root CA
53function generateSignedCertificate(name, keyPath) {
54 debug(`generating certificate signing request for ${name}`);
55 let csrFile = constants_1.configPath(`${name}.csr`);
56 utils_1.openssl(`req -config ${constants_1.opensslConfPath} -subj "/CN=${name}" -key ${keyPath} -out ${csrFile} -new`);
57 debug(`generating certificate for ${name} from signing request; signing with devcert root CA`);
58 let certPath = constants_1.configPath(`${name}.crt`);
59 utils_1.openssl(`ca -config ${constants_1.opensslConfPath} -in ${csrFile} -out ${certPath} -outdir ${constants_1.caCertsDir} -keyfile ${constants_1.rootKeyPath} -cert ${constants_1.rootCertPath} -notext -md sha256 -days 7000 -batch -extensions server_cert`);
60}
61//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL2phc29ubWlsbGVyL1Byb2plY3RzL2l0YWx5L2RldmNlcnQvIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSwyQkFPWTtBQU1aLHFDQUFxQztBQUNyQyxtREFBdUQ7QUFFdkQsMkNBV3FCO0FBQ3JCLHFEQUEyRDtBQUMzRCxtQ0FBK0M7QUFFL0MsTUFBTSxLQUFLLEdBQUcsV0FBVyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0FBRXJDOzs7Ozs7Ozs7O0dBVUc7QUFDSCxpQkFBc0MsT0FBZSxFQUFFLFVBQXlDLEVBQUU7O1FBQ2hHLEtBQUssQ0FBQyxrQ0FBbUMsT0FBUSxFQUFFLENBQUMsQ0FBQztRQUVyRCxFQUFFLENBQUMsQ0FBQyxDQUFDLGlCQUFLLElBQUksQ0FBQyxtQkFBTyxJQUFJLENBQUMscUJBQVMsQ0FBQyxDQUFDLENBQUM7WUFDckMsTUFBTSxJQUFJLEtBQUssQ0FBQyxhQUFjLE9BQU8sQ0FBQyxRQUFTLDBCQUEwQixDQUFDLENBQUM7UUFDN0UsQ0FBQztRQUVELEVBQUUsQ0FBQyxDQUFDLENBQUMscUJBQWEsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDOUIsTUFBTSxJQUFJLEtBQUssQ0FBQywrRUFBK0UsQ0FBQyxDQUFDO1FBQ25HLENBQUM7UUFFRCxJQUFJLFVBQVUsR0FBRyxzQkFBVSxDQUFDLEdBQUksT0FBUSxNQUFNLENBQUMsQ0FBQztRQUNoRCxJQUFJLFdBQVcsR0FBRyxzQkFBVSxDQUFDLEdBQUksT0FBUSxNQUFNLENBQUMsQ0FBQztRQUVqRCxFQUFFLENBQUMsQ0FBQyxDQUFDLGVBQVUsQ0FBQyx3QkFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzlCLEtBQUssQ0FBQyw4RUFBOEUsQ0FBQyxDQUFDO1lBQ3RGLE1BQU0sd0JBQTJCLENBQUMsT0FBTyxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQzdELENBQUM7UUFFRCxFQUFFLENBQUMsQ0FBQyxDQUFDLGVBQVUsQ0FBQyxzQkFBVSxDQUFDLEdBQUksT0FBUSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNoRCxLQUFLLENBQUMscUJBQXNCLE9BQVEsbUNBQW1DLENBQUMsQ0FBQztZQUN6RSxtQkFBVyxDQUFDLHNCQUFVLENBQUMsR0FBSSxPQUFRLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFDNUMseUJBQXlCLENBQUMsT0FBTyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBQ2pELENBQUM7UUFFRCxLQUFLLENBQUMsb0JBQW9CLENBQUMsQ0FBQztRQUM1QixNQUFNLENBQUM7WUFDTCxPQUFPLEVBQUUsVUFBVTtZQUNuQixRQUFRLEVBQUUsV0FBVztZQUNyQixHQUFHLEVBQUUsaUJBQVksQ0FBQyxVQUFVLENBQUM7WUFDN0IsSUFBSSxFQUFFLGlCQUFZLENBQUMsV0FBVyxDQUFDO1NBQ2hDLENBQUM7SUFFSixDQUFDO0NBQUE7QUFqQ0QsMEJBaUNDO0FBRUQsNERBQTREO0FBQzVELG1DQUFtQyxJQUFZLEVBQUUsT0FBZTtJQUM5RCxLQUFLLENBQUMsOENBQStDLElBQUssRUFBRSxDQUFDLENBQUM7SUFDOUQsSUFBSSxPQUFPLEdBQUcsc0JBQVUsQ0FBQyxHQUFJLElBQUssTUFBTSxDQUFDLENBQUE7SUFDekMsZUFBTyxDQUFDLGVBQWdCLDJCQUFnQixlQUFnQixJQUFLLFVBQVcsT0FBUSxTQUFVLE9BQVEsT0FBTyxDQUFDLENBQUM7SUFDM0csS0FBSyxDQUFDLDhCQUErQixJQUFLLHFEQUFxRCxDQUFDLENBQUM7SUFDakcsSUFBSSxRQUFRLEdBQUcsc0JBQVUsQ0FBQyxHQUFJLElBQUssTUFBTSxDQUFDLENBQUM7SUFDM0MsZUFBTyxDQUFDLGNBQWUsMkJBQWdCLFFBQVMsT0FBUSxTQUFVLFFBQVMsWUFBYSxzQkFBVyxhQUFjLHVCQUFZLFVBQVcsd0JBQWEsK0RBQStELENBQUMsQ0FBQTtBQUN2TixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgcmVhZEZpbGVTeW5jLFxuICByZWFkZGlyU3luYyxcbiAgd3JpdGVGaWxlU3luYyxcbiAgdW5saW5rU3luYyxcbiAgY2htb2RTeW5jLFxuICBleGlzdHNTeW5jXG59IGZyb20gJ2ZzJztcbmltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgeyBleGVjLCBleGVjU3luYywgRXhlY1N5bmNPcHRpb25zIH0gZnJvbSAnY2hpbGRfcHJvY2Vzcyc7XG5pbXBvcnQgKiBhcyB0bXAgZnJvbSAndG1wJztcbmltcG9ydCAqIGFzIENvbmZpZ3N0b3JlIGZyb20gJ2NvbmZpZ3N0b3JlJztcbmltcG9ydCAqIGFzIG1rZGlycCBmcm9tICdta2RpcnAnO1xuaW1wb3J0ICogYXMgY3JlYXRlRGVidWcgZnJvbSAnZGVidWcnO1xuaW1wb3J0IHsgc3luYyBhcyBjb21tYW5kRXhpc3RzIH0gZnJvbSAnY29tbWFuZC1leGlzdHMnO1xuXG5pbXBvcnQge1xuICBpc01hYyxcbiAgaXNMaW51eCxcbiAgaXNXaW5kb3dzLFxuICBjb25maWdEaXIsXG4gIGNvbmZpZ1BhdGgsXG4gIG9wZW5zc2xDb25mVGVtcGxhdGUsXG4gIG9wZW5zc2xDb25mUGF0aCxcbiAgcm9vdEtleVBhdGgsXG4gIHJvb3RDZXJ0UGF0aCxcbiAgY2FDZXJ0c0RpclxufSBmcm9tICcuL2NvbnN0YW50cyc7XG5pbXBvcnQgaW5zdGFsbENlcnRpZmljYXRlQXV0aG9yaXR5IGZyb20gJy4vcm9vdC1hdXRob3JpdHknO1xuaW1wb3J0IHsgb3BlbnNzbCwgZ2VuZXJhdGVLZXkgfSBmcm9tICcuL3V0aWxzJztcblxuY29uc3QgZGVidWcgPSBjcmVhdGVEZWJ1ZygnZGV2Y2VydCcpO1xuXG4vKipcbiAqIFJlcXVlc3QgYW4gU1NMIGNlcnRpZmljYXRlIGZvciB0aGUgZ2l2ZW4gYXBwIG5hbWUgc2lnbmVkIGJ5IHRoZSBkZXZjZXJ0IHJvb3QgY2VydGlmaWNhdGVcbiAqIGF1dGhvcml0eS4gSWYgZGV2Y2VydCBoYXMgcHJldmlvdXNseSBnZW5lcmF0ZWQgYSBjZXJ0aWZpY2F0ZSBmb3IgdGhhdCBhcHAgbmFtZSBvbiB0aGlzIG1hY2hpbmUsXG4gKiBpdCB3aWxsIHJldXNlIHRoYXQgY2VydGlmaWNhdGUuXG4gKlxuICogSWYgdGhpcyBpcyB0aGUgZmlyc3QgdGltZSBkZXZjZXJ0IGlzIGJlaW5nIHJ1biBvbiB0aGlzIG1hY2hpbmUsIGl0IHdpbGwgZ2VuZXJhdGUgYW5kIGF0dGVtcHQgdG9cbiAqIGluc3RhbGwgYSByb290IGNlcnRpZmljYXRlIGF1dGhvcml0eS5cbiAqXG4gKiBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGggeyBrZXlQYXRoLCBjZXJ0UGF0aCwga2V5LCBjZXJ0IH0sIHdoZXJlIGBrZXlgIGFuZCBgY2VydGAgYXJlXG4gKiBCdWZmZXJzIHdpdGggdGhlIGNvbnRlbnRzIG9mIGBrZXlQYXRoYCBhbmQgYGNlcnRQYXRoYCwgcmVzcGVjdGl2ZWx5LlxuICovXG5leHBvcnQgZGVmYXVsdCBhc3luYyBmdW5jdGlvbiBkZXZjZXJ0KGFwcE5hbWU6IHN0cmluZywgb3B0aW9uczogeyBpbnN0YWxsQ2VydHV0aWw/OiBib29sZWFuIH0gPSB7fSkge1xuICBkZWJ1ZyhgZGV2ZWxvcG1lbnQgY2VydCByZXF1ZXN0ZWQgZm9yICR7IGFwcE5hbWUgfWApO1xuXG4gIGlmICghaXNNYWMgJiYgIWlzTGludXggJiYgIWlzV2luZG93cykge1xuICAgIHRocm93IG5ldyBFcnJvcihgZGV2Y2VydDogXCIkeyBwcm9jZXNzLnBsYXRmb3JtIH1cIiBwbGF0Zm9ybSBub3Qgc3VwcG9ydGVkYCk7XG4gIH1cblxuICBpZiAoIWNvbW1hbmRFeGlzdHMoJ29wZW5zc2wnKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignVW5hYmxlIHRvIGZpbmQgb3BlbnNzbCAtIG1ha2Ugc3VyZSBpdCBpcyBpbnN0YWxsZWQgYW5kIGF2YWlsYWJsZSBpbiB5b3VyIFBBVEgnKTtcbiAgfVxuXG4gIGxldCBhcHBLZXlQYXRoID0gY29uZmlnUGF0aChgJHsgYXBwTmFtZSB9LmtleWApO1xuICBsZXQgYXBwQ2VydFBhdGggPSBjb25maWdQYXRoKGAkeyBhcHBOYW1lIH0uY3J0YCk7XG5cbiAgaWYgKCFleGlzdHNTeW5jKHJvb3RDZXJ0UGF0aCkpIHtcbiAgICBkZWJ1ZygnZGV2Y2VydCByb290IENBIG5vdCBpbnN0YWxsZWQgeWV0LCBtdXN0IGJlIGZpcnN0IHJ1bjsgaW5zdGFsbGluZyByb290IENBIC4uLicpO1xuICAgIGF3YWl0IGluc3RhbGxDZXJ0aWZpY2F0ZUF1dGhvcml0eShvcHRpb25zLmluc3RhbGxDZXJ0dXRpbCk7XG4gIH1cblxuICBpZiAoIWV4aXN0c1N5bmMoY29uZmlnUGF0aChgJHsgYXBwTmFtZSB9LmNydGApKSkge1xuICAgIGRlYnVnKGBmaXJzdCByZXF1ZXN0IGZvciAkeyBhcHBOYW1lIH0gY2VydCwgZ2VuZXJhdGluZyBhbmQgY2FjaGluZyAuLi5gKTtcbiAgICBnZW5lcmF0ZUtleShjb25maWdQYXRoKGAkeyBhcHBOYW1lIH0ua2V5YCkpO1xuICAgIGdlbmVyYXRlU2lnbmVkQ2VydGlmaWNhdGUoYXBwTmFtZSwgYXBwS2V5UGF0aCk7XG4gIH1cblxuICBkZWJ1ZyhgcmV0dXJuaW5nIGFwcCBjZXJ0YCk7XG4gIHJldHVybiB7XG4gICAga2V5UGF0aDogYXBwS2V5UGF0aCxcbiAgICBjZXJ0UGF0aDogYXBwQ2VydFBhdGgsXG4gICAga2V5OiByZWFkRmlsZVN5bmMoYXBwS2V5UGF0aCksXG4gICAgY2VydDogcmVhZEZpbGVTeW5jKGFwcENlcnRQYXRoKVxuICB9O1xuXG59XG5cbi8vIEdlbmVyYXRlIGFuIGFwcCBjZXJ0aWZpY2F0ZSBzaWduZWQgYnkgdGhlIGRldmNlcnQgcm9vdCBDQVxuZnVuY3Rpb24gZ2VuZXJhdGVTaWduZWRDZXJ0aWZpY2F0ZShuYW1lOiBzdHJpbmcsIGtleVBhdGg6IHN0cmluZyk6IHZvaWQge1xuICBkZWJ1ZyhgZ2VuZXJhdGluZyBjZXJ0aWZpY2F0ZSBzaWduaW5nIHJlcXVlc3QgZm9yICR7IG5hbWUgfWApO1xuICBsZXQgY3NyRmlsZSA9IGNvbmZpZ1BhdGgoYCR7IG5hbWUgfS5jc3JgKVxuICBvcGVuc3NsKGByZXEgLWNvbmZpZyAkeyBvcGVuc3NsQ29uZlBhdGggfSAtc3ViaiBcIi9DTj0keyBuYW1lIH1cIiAta2V5ICR7IGtleVBhdGggfSAtb3V0ICR7IGNzckZpbGUgfSAtbmV3YCk7XG4gIGRlYnVnKGBnZW5lcmF0aW5nIGNlcnRpZmljYXRlIGZvciAkeyBuYW1lIH0gZnJvbSBzaWduaW5nIHJlcXVlc3Q7IHNpZ25pbmcgd2l0aCBkZXZjZXJ0IHJvb3QgQ0FgKTtcbiAgbGV0IGNlcnRQYXRoID0gY29uZmlnUGF0aChgJHsgbmFtZSB9LmNydGApO1xuICBvcGVuc3NsKGBjYSAtY29uZmlnICR7IG9wZW5zc2xDb25mUGF0aCB9IC1pbiAkeyBjc3JGaWxlIH0gLW91dCAkeyBjZXJ0UGF0aCB9IC1vdXRkaXIgJHsgY2FDZXJ0c0RpciB9IC1rZXlmaWxlICR7IHJvb3RLZXlQYXRoIH0gLWNlcnQgJHsgcm9vdENlcnRQYXRoIH0gLW5vdGV4dCAtbWQgc2hhMjU2IC1kYXlzIDcwMDAgLWJhdGNoIC1leHRlbnNpb25zIHNlcnZlcl9jZXJ0YClcbn1cbiJdfQ==
\No newline at end of file