forked from TryGhost/Ghost-CLI
/
index.js
125 lines (103 loc) · 4.25 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
'use strict';
const fs = require('fs-extra');
const url = require('url');
const path = require('path');
const execa = require('execa');
const template = require('lodash/template');
const validator = require('validator');
const BaseService = require('../base');
class NginxService extends BaseService {
init() {
this.on('setup', 'setup');
}
get parsedUrl() {
return url.parse(this.config.get('url'));
}
setup(context) {
if (!context.nginx) {
return;
}
if (this.parsedUrl.port) {
this.ui.log('Your url contains a port. Skipping automatic nginx setup.', 'yellow');
return;
}
if (this.parsedUrl.pathname !== '/') {
this.ui.log('The Nginx service does not support subdirectory configurations yet. Skipping automatic nginx setup.', 'yellow');
return;
}
let prompts = [{
type: 'confirm',
name: 'ssl',
message: 'Do you want to set up your blog with SSL (using letsencrypt)?',
default: true
}, {
type: 'input',
name: 'email',
message: 'Enter your email (used for ssl registration)',
when: ans => ans.ssl,
validate: email => validator.isEmail(email) || 'Invalid email'
}];
if (this.config.environment === 'development') {
prompts.splice(1, 0, {
type: 'confirm',
name: 'staging',
message: 'You are running in development mode. Would you like to use letsencrypt\'s' +
' staging servers instead of the production servers?',
default: true,
when: ans => ans.ssl
});
}
let answers;
return this.ui.prompt(prompts).then((_answers) => {
answers = _answers;
fs.ensureDirSync(path.join(process.cwd(), 'root'));
let conf = template(fs.readFileSync(path.join(__dirname, 'files', 'site.conf.template'), 'utf8'));
let confFile = `${this.parsedUrl.hostname}.conf`;
fs.writeFileSync(path.join(process.cwd(), confFile), conf({
ssl: answers.ssl,
root: path.join(process.cwd(), 'root'),
url: this.parsedUrl.hostname,
port: this.config.get('server.port')
}));
return this.ui.noSpin(execa.shell(`sudo mv ${confFile} /etc/nginx/sites-available && ` +
`sudo ln -s /etc/nginx/sites-available/${confFile} /etc/nginx/sites-enabled && ` +
'sudo service nginx restart', {stdio: 'inherit'}));
}).then(() => {
if (!answers.ssl) {
return;
}
return this._ssl(answers);
});
}
_ssl(options) {
let letsencrypt = path.resolve(__dirname, '../../../node_modules/.bin/letsencrypt')
let command = `sudo ${letsencrypt} certonly --agree-tos --email ${options.email} --webroot ` +
`--webroot-path ${path.join(process.cwd(), 'root')} --config-dir /etc/letsencrypt ` +
`--domains ${this.parsedUrl.hostname}`;
if (options.staging) {
// Use LetsEncrypt's staging server
command += ' --server https://acme-staging.api.letsencrypt.org/directory';
}
return this.ui.noSpin(execa.shell(command, {stdio: 'inherit'})).then(() => {
if (fs.existsSync('/etc/nginx/snippets/ssl-params.conf')) {
return;
}
return this.ui.noSpin(execa.shell(
`sudo mv ${path.join(__dirname, 'files', 'ssl-params.conf')} /etc/nginx/snippets`,
{stdio: 'inherit'}
));
}).then(() => {
let sslConf = template(fs.readFileSync(path.join(__dirname, 'files', 'ssl-cert.conf.template'), 'utf8'));
let sslConfFile = `ssl-${this.parsedUrl.hostname}.conf`;
fs.writeFileSync(path.join(process.cwd(), sslConfFile), sslConf({
url: this.parsedUrl.hostname
}));
return this.ui.noSpin(execa.shell(`sudo mv ${sslConfFile} /etc/nginx/snippets && ` +
'sudo service nginx restart'));
});
}
}
module.exports = {
name: 'nginx',
class: NginxService
};