From b4eb57a56c047beeeb3cc7032cfa94f7c987910d Mon Sep 17 00:00:00 2001 From: Austin Burdine Date: Mon, 3 Jul 2017 00:35:39 -0400 Subject: [PATCH] feat(nginx): move letsencrypt to its own file, add ssl renew command refs #190 - adds ssl-renew command --- extensions/nginx/commands/ssl-renew.js | 22 ++++++++++++++++++++++ extensions/nginx/index.js | 15 +++------------ extensions/nginx/letsencrypt.js | 20 ++++++++++++++++++++ 3 files changed, 45 insertions(+), 12 deletions(-) create mode 100644 extensions/nginx/commands/ssl-renew.js create mode 100644 extensions/nginx/letsencrypt.js diff --git a/extensions/nginx/commands/ssl-renew.js b/extensions/nginx/commands/ssl-renew.js new file mode 100644 index 000000000..4e886b228 --- /dev/null +++ b/extensions/nginx/commands/ssl-renew.js @@ -0,0 +1,22 @@ +'use strict'; +const cli = require('../../../lib'); +const letsencrypt = require('../letsencrypt'); + +class SslRenewCommand extends cli.Command { + run() { + let instance = this.system.getInstance(); + + if (!instance.cliConfig.has('extension.sslemail')) { + return Promise.reject(new cli.errors.SystemError('No saved email found, skipping automatic letsencrypt renewal')); + } + + let email = instance.cliConfig.get('extension.sslemail'); + return this.ui.run(letsencrypt(instance, email, false), 'Renewing SSL certificate') + .catch((error) => Promise.reject(new cli.errors.ProcessError(error))); + } +} + +SslRenewCommand.description = 'Renew an SSL certificate for a Ghost installation'; + +module.exports = SslRenewCommand; + diff --git a/extensions/nginx/index.js b/extensions/nginx/index.js index 873b10929..64c1bca81 100644 --- a/extensions/nginx/index.js +++ b/extensions/nginx/index.js @@ -12,9 +12,6 @@ const NginxConfFile = require('nginx-conf').NginxConfFile; const cli = require('../../lib'); -const LIVE_URL = 'https://acme-v01.api.letsencrypt.org/directory'; -const STAGING_URL = 'https://acme-staging.api.letsencrypt.org/directory'; - class NginxExtension extends cli.Extension { setup(cmd, argv) { // ghost setup --local, skip @@ -106,6 +103,7 @@ class NginxExtension extends cli.Extension { } let rootPath = path.resolve(ctx.instance.dir, 'system', 'nginx-root'); + const letsencrypt = require('./letsencrypt'); return this.ui.listr([{ title: 'Checking DNS resolution', @@ -155,15 +153,8 @@ class NginxExtension extends cli.Extension { }, { title: 'Getting SSL Certificate', task: () => { - let letsencryptFolder = path.join(ctx.instance.dir, 'system', 'letsencrypt'); - let sslGenArgs = `certonly --agree-tos --email ${argv.sslemail} --webroot --webroot-path ${rootPath}` + - ` --config-dir ${letsencryptFolder} --domains ${parsedUrl.hostname} --server ${argv.sslStaging ? STAGING_URL : LIVE_URL}`; - - return execa('greenlock', sslGenArgs.split(' '), { - stdio: 'ignore', - preferLocal: true, - localDir: __dirname - }).catch((error) => Promise.reject(new cli.errors.ProcessError(error))); + return letsencrypt(ctx.instance, argv.sslemail, argv.sslstaging) + .catch((error) => Promise.reject(new cli.errors.ProcessError(error))); } }, { title: 'Generating Encryption Key (may take a few minutes)', diff --git a/extensions/nginx/letsencrypt.js b/extensions/nginx/letsencrypt.js new file mode 100644 index 000000000..92ef5e7d7 --- /dev/null +++ b/extensions/nginx/letsencrypt.js @@ -0,0 +1,20 @@ +'use strict'; +const url = require('url'); +const path = require('path'); +const execa = require('execa'); + +const LIVE_URL = 'https://acme-v01.api.letsencrypt.org/directory'; +const STAGING_URL = 'https://acme-staging.api.letsencrypt.org/directory'; + +module.exports = function letsencrypt(instance, email, staging) { + let hostname = url.parse(instance.config.get('url')).hostname; + let rootPath = path.resolve(instance.dir, 'system', 'nginx-root'); + let letsencryptFolder = path.join(instance.dir, 'system', 'letsencrypt'); + let sslGenArgs = `certonly --agree-tos --email ${email} --webroot --webroot-path ${rootPath}` + + ` --config-dir ${letsencryptFolder} --domains ${hostname} --server ${staging ? STAGING_URL : LIVE_URL}`; + + return execa('greenlock', sslGenArgs.split(' '), { + preferLocal: true, + localDir: __dirname + }); +};