roster-server 2.2.10 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -2
- package/index.js +28 -38
- package/lib/resolve-site-app.js +42 -0
- package/lib/static-site-handler.js +122 -0
- package/package.json +12 -3
- package/skills/roster-server/SKILL.md +15 -4
- package/test/roster-server.test.js +87 -0
- package/vendor/greenlock/.prettierrc +8 -0
- package/vendor/greenlock/LICENSE +312 -0
- package/vendor/greenlock/MIGRATION_GUIDE.md +403 -0
- package/vendor/greenlock/README.md +667 -0
- package/vendor/greenlock/accounts.js +218 -0
- package/vendor/greenlock/bin/add.js +72 -0
- package/vendor/greenlock/bin/certonly.js +368 -0
- package/vendor/greenlock/bin/config.js +77 -0
- package/vendor/greenlock/bin/defaults.js +58 -0
- package/vendor/greenlock/bin/greenlock.js +26 -0
- package/vendor/greenlock/bin/init.js +159 -0
- package/vendor/greenlock/bin/lib/cli.js +230 -0
- package/vendor/greenlock/bin/lib/flags.js +385 -0
- package/vendor/greenlock/bin/remove.js +46 -0
- package/vendor/greenlock/bin/tmpl/app.tmpl.js +9 -0
- package/vendor/greenlock/bin/tmpl/cluster.tmpl.js +30 -0
- package/vendor/greenlock/bin/tmpl/greenlock.tmpl.js +13 -0
- package/vendor/greenlock/bin/tmpl/server.tmpl.js +20 -0
- package/vendor/greenlock/bin/update.js +62 -0
- package/vendor/greenlock/certificates.js +324 -0
- package/vendor/greenlock/errors.js +58 -0
- package/vendor/greenlock/greenlock.js +621 -0
- package/vendor/greenlock/greenlockrc.js +169 -0
- package/vendor/greenlock/lib/challenges-wrapper.js +88 -0
- package/vendor/greenlock/lib/directory-url.js +44 -0
- package/vendor/greenlock/lib/init.js +191 -0
- package/vendor/greenlock/lib/manager-wrapper.js +625 -0
- package/vendor/greenlock/lib/rc.js +70 -0
- package/vendor/greenlock/logo/beaker-browser-301x112.png +0 -0
- package/vendor/greenlock/logo/from-not-secure-to-secure-url-bar.png +0 -0
- package/vendor/greenlock/logo/greenlock-1063x250.png +0 -0
- package/vendor/greenlock/logo/greenlock-850x200.png +0 -0
- package/vendor/greenlock/logo/ibm-301x112.png +0 -0
- package/vendor/greenlock/logo/telebit-301x112.png +0 -0
- package/vendor/greenlock/order.js +63 -0
- package/vendor/greenlock/package-lock.json +140 -0
- package/vendor/greenlock/package.json +56 -0
- package/vendor/greenlock/plugins.js +270 -0
- package/vendor/greenlock/tests/cli.sh +31 -0
- package/vendor/greenlock/tests/index.js +53 -0
- package/vendor/greenlock/user-events.js +7 -0
- package/vendor/greenlock/utils.js +281 -0
- package/vendor/greenlock-express/greenlock-shim.js +3 -1
- package/vendor/greenlock-express/package.json +0 -1
- package/tasks/lessons.md +0 -4
|
@@ -0,0 +1,621 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var pkg = require('./package.json');
|
|
4
|
+
var log = require('lemonlog')('greenlock');
|
|
5
|
+
|
|
6
|
+
var ACME = require('@root/acme');
|
|
7
|
+
var Greenlock = module.exports;
|
|
8
|
+
var request = require('@root/request');
|
|
9
|
+
var process = require('process');
|
|
10
|
+
|
|
11
|
+
var G = Greenlock;
|
|
12
|
+
var U = require('./utils.js');
|
|
13
|
+
var E = require('./errors.js');
|
|
14
|
+
var P = require('./plugins.js');
|
|
15
|
+
var A = require('./accounts.js');
|
|
16
|
+
var C = require('./certificates.js');
|
|
17
|
+
|
|
18
|
+
var DIR = require('./lib/directory-url.js');
|
|
19
|
+
var ChWrapper = require('./lib/challenges-wrapper.js');
|
|
20
|
+
var MngWrapper = require('./lib/manager-wrapper.js');
|
|
21
|
+
|
|
22
|
+
var UserEvents = require('./user-events.js');
|
|
23
|
+
var Init = require('./lib/init.js');
|
|
24
|
+
|
|
25
|
+
var caches = {};
|
|
26
|
+
|
|
27
|
+
// { maintainerEmail, directoryUrl, subscriberEmail, store, challenges }
|
|
28
|
+
G.create = function(gconf) {
|
|
29
|
+
var greenlock = {};
|
|
30
|
+
var gdefaults = {};
|
|
31
|
+
if (!gconf) {
|
|
32
|
+
gconf = {};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
greenlock._create = function() {
|
|
36
|
+
if (!gconf._bin_mode) {
|
|
37
|
+
if (!gconf.maintainerEmail) {
|
|
38
|
+
throw E.NO_MAINTAINER('create');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// TODO send welcome message with benefit info
|
|
42
|
+
U._validMx(gconf.maintainerEmail).catch(function() {
|
|
43
|
+
log.error('Invalid maintainer contact:', gconf.maintainerEmail);
|
|
44
|
+
|
|
45
|
+
// maybe move this to init and don't exit the process, just in case
|
|
46
|
+
process.exit(1);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if ('function' === typeof gconf.notify) {
|
|
51
|
+
gdefaults.notify = gconf.notify;
|
|
52
|
+
} else {
|
|
53
|
+
gdefaults.notify = _notify;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
gconf = Init._init(gconf);
|
|
57
|
+
|
|
58
|
+
// OK: /path/to/blah
|
|
59
|
+
// OK: npm-name-blah
|
|
60
|
+
// NOT OK: ./rel/path/to/blah
|
|
61
|
+
// Error: .blah
|
|
62
|
+
if ('.' === (gconf.manager.module || '')[0]) {
|
|
63
|
+
if (!gconf.packageRoot) {
|
|
64
|
+
gconf.packageRoot = process.cwd();
|
|
65
|
+
log.warn('packageRoot not set; using', gconf.packageRoot);
|
|
66
|
+
}
|
|
67
|
+
gconf.manager.module =
|
|
68
|
+
gconf.packageRoot + '/' + gconf.manager.module.slice(2);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Wraps each of the following with appropriate error checking
|
|
72
|
+
// greenlock.manager.defaults
|
|
73
|
+
// greenlock.sites.add
|
|
74
|
+
// greenlock.sites.update
|
|
75
|
+
// greenlock.sites.remove
|
|
76
|
+
// greenlock.sites.find
|
|
77
|
+
// greenlock.sites.get
|
|
78
|
+
MngWrapper.wrap(greenlock, gconf);
|
|
79
|
+
// The goal here is to reduce boilerplate, such as error checking
|
|
80
|
+
// and duration parsing, that a manager must implement
|
|
81
|
+
greenlock.sites.add = greenlock.add = greenlock.manager.add;
|
|
82
|
+
greenlock.sites.update = greenlock.update = greenlock.manager.update;
|
|
83
|
+
greenlock.sites.remove = greenlock.remove = greenlock.manager.remove;
|
|
84
|
+
|
|
85
|
+
// Exports challenges.get for Greenlock Express HTTP-01,
|
|
86
|
+
// and whatever odd use case pops up, I suppose
|
|
87
|
+
// greenlock.challenges.get
|
|
88
|
+
ChWrapper.wrap(greenlock);
|
|
89
|
+
|
|
90
|
+
DIR._getDefaultDirectoryUrl('', gconf.staging, '');
|
|
91
|
+
if (gconf.directoryUrl) {
|
|
92
|
+
gdefaults.directoryUrl = gconf.directoryUrl;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
greenlock._defaults = gdefaults;
|
|
96
|
+
greenlock._defaults.debug = gconf.debug;
|
|
97
|
+
|
|
98
|
+
if (!gconf._bin_mode && false !== gconf.renew) {
|
|
99
|
+
// renew every 90-ish minutes (random for staggering)
|
|
100
|
+
// the weak setTimeout (unref) means that when run as a CLI process this
|
|
101
|
+
// will still finish as expected, and not wait on the timeout
|
|
102
|
+
(function renew() {
|
|
103
|
+
setTimeout(function() {
|
|
104
|
+
greenlock.renew({});
|
|
105
|
+
renew();
|
|
106
|
+
}, Math.PI * 30 * 60 * 1000).unref();
|
|
107
|
+
})();
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
// The purpose of init is to make MCONF the source of truth
|
|
112
|
+
greenlock._init = function() {
|
|
113
|
+
var p;
|
|
114
|
+
greenlock._init = function() {
|
|
115
|
+
return p;
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
p = greenlock.manager
|
|
119
|
+
.init({
|
|
120
|
+
request: request
|
|
121
|
+
//punycode: require('punycode')
|
|
122
|
+
})
|
|
123
|
+
.then(async function() {
|
|
124
|
+
var MCONF = await greenlock.manager._defaults();
|
|
125
|
+
mergeDefaults(MCONF, gconf);
|
|
126
|
+
if (true === MCONF.agreeToTerms) {
|
|
127
|
+
gdefaults.agreeToTerms = function(tos) {
|
|
128
|
+
return Promise.resolve(tos);
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return greenlock.manager._defaults(MCONF);
|
|
133
|
+
})
|
|
134
|
+
.catch(function(err) {
|
|
135
|
+
if ('load_plugin' !== err.context) {
|
|
136
|
+
log.error('Fatal error during greenlock init:', err.message);
|
|
137
|
+
}
|
|
138
|
+
if (!gconf._bin_mode) {
|
|
139
|
+
process.exit(1);
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
return p;
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
greenlock.notify = greenlock._notify = function(ev, params) {
|
|
146
|
+
var mng = greenlock.manager;
|
|
147
|
+
|
|
148
|
+
if ('_' === String(ev)[0]) {
|
|
149
|
+
if ('_cert_issue' === ev) {
|
|
150
|
+
try {
|
|
151
|
+
mng.update({
|
|
152
|
+
subject: params.subject,
|
|
153
|
+
renewAt: params.renewAt
|
|
154
|
+
}).catch(function(e) {
|
|
155
|
+
e.context = '_cert_issue';
|
|
156
|
+
greenlock._notify('error', e);
|
|
157
|
+
});
|
|
158
|
+
} catch (e) {
|
|
159
|
+
e.context = '_cert_issue';
|
|
160
|
+
greenlock._notify('error', e);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
// trap internal events internally
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
try {
|
|
168
|
+
var p = greenlock._defaults.notify(ev, params);
|
|
169
|
+
if (p && p.catch) {
|
|
170
|
+
p.catch(function(e) {
|
|
171
|
+
log.error("Promise rejection on event '" + ev + "':", e);
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
} catch (e) {
|
|
175
|
+
log.error("Exception in notify '" + ev + "':", e, params);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (-1 !== ['cert_issue', 'cert_renewal'].indexOf(ev)) {
|
|
179
|
+
// We will notify all greenlock users of mandatory and security updates
|
|
180
|
+
// We'll keep track of versions and os so we can make sure things work well
|
|
181
|
+
// { name, version, email, domains, action, communityMember, telemetry }
|
|
182
|
+
// TODO look at the other one
|
|
183
|
+
UserEvents.notify({
|
|
184
|
+
/*
|
|
185
|
+
// maintainer should be only on pre-publish, or maybe install, I think
|
|
186
|
+
maintainerEmail: greenlock._defaults._maintainerEmail,
|
|
187
|
+
name: greenlock._defaults._packageAgent,
|
|
188
|
+
version: greenlock._defaults._maintainerPackageVersion,
|
|
189
|
+
//action: params.pems._type,
|
|
190
|
+
domains: params.altnames,
|
|
191
|
+
subscriberEmail: greenlock._defaults._subscriberEmail,
|
|
192
|
+
// TODO enable for Greenlock Pro
|
|
193
|
+
//customerEmail: args.customerEmail
|
|
194
|
+
telemetry: greenlock._defaults.telemetry
|
|
195
|
+
*/
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
// certs.get
|
|
201
|
+
greenlock.get = async function(args) {
|
|
202
|
+
greenlock._single(args);
|
|
203
|
+
args._includePems = true;
|
|
204
|
+
var results = await greenlock.renew(args);
|
|
205
|
+
if (!results || !results.length) {
|
|
206
|
+
// TODO throw an error here?
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// just get the first one
|
|
211
|
+
var result = results[0];
|
|
212
|
+
|
|
213
|
+
// (there should be only one, ideally)
|
|
214
|
+
if (results.length > 1) {
|
|
215
|
+
var err = new Error(
|
|
216
|
+
"a search for '" +
|
|
217
|
+
args.servername +
|
|
218
|
+
"' returned multiple certificates"
|
|
219
|
+
);
|
|
220
|
+
err.context = 'duplicate_certs';
|
|
221
|
+
err.servername = args.servername;
|
|
222
|
+
err.subjects = results.map(function(r) {
|
|
223
|
+
return (r.site || {}).subject || 'N/A';
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
greenlock._notify('warning', err);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if (result.error) {
|
|
230
|
+
return Promise.reject(result.error);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// site for plugin options, such as http-01 challenge
|
|
234
|
+
// pems for the obvious reasons
|
|
235
|
+
return result;
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
// TODO remove async here, it doesn't matter
|
|
239
|
+
greenlock._single = async function(args) {
|
|
240
|
+
if ('string' !== typeof args.servername) {
|
|
241
|
+
throw new Error('no `servername` given');
|
|
242
|
+
}
|
|
243
|
+
// www.example.com => *.example.com
|
|
244
|
+
args.wildname =
|
|
245
|
+
'*.' +
|
|
246
|
+
args.servername
|
|
247
|
+
.split('.')
|
|
248
|
+
.slice(1)
|
|
249
|
+
.join('.');
|
|
250
|
+
if (args.wildname.split('.').length < 3) {
|
|
251
|
+
// No '*.com'
|
|
252
|
+
args.wildname = '';
|
|
253
|
+
}
|
|
254
|
+
if (
|
|
255
|
+
args.servernames ||
|
|
256
|
+
//TODO I think we need to block altnames as well, but I don't want to break anything
|
|
257
|
+
//args.altnames ||
|
|
258
|
+
args.subject ||
|
|
259
|
+
args.renewBefore ||
|
|
260
|
+
args.issueBefore ||
|
|
261
|
+
args.expiresBefore
|
|
262
|
+
) {
|
|
263
|
+
throw new Error(
|
|
264
|
+
'bad arguments, did you mean to call greenlock.renew()?'
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
// duplicate, force, and others still allowed
|
|
268
|
+
return args;
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
greenlock._config = async function(args) {
|
|
272
|
+
greenlock._single(args);
|
|
273
|
+
var sites = await greenlock._configAll(args);
|
|
274
|
+
return sites[0];
|
|
275
|
+
};
|
|
276
|
+
greenlock._configAll = async function(args) {
|
|
277
|
+
var sites = await greenlock._find(args);
|
|
278
|
+
if (!sites || !sites.length) {
|
|
279
|
+
return [];
|
|
280
|
+
}
|
|
281
|
+
sites = JSON.parse(JSON.stringify(sites));
|
|
282
|
+
var mconf = await greenlock.manager._defaults();
|
|
283
|
+
return sites.map(function(site) {
|
|
284
|
+
if (site.store && site.challenges) {
|
|
285
|
+
return site;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
var dconf = site;
|
|
289
|
+
// TODO make cli and api mode the same
|
|
290
|
+
if (gconf._bin_mode) {
|
|
291
|
+
dconf = site.defaults = {};
|
|
292
|
+
}
|
|
293
|
+
if (!site.store) {
|
|
294
|
+
dconf.store = mconf.store;
|
|
295
|
+
}
|
|
296
|
+
if (!site.challenges) {
|
|
297
|
+
dconf.challenges = mconf.challenges;
|
|
298
|
+
}
|
|
299
|
+
return site;
|
|
300
|
+
});
|
|
301
|
+
};
|
|
302
|
+
|
|
303
|
+
// needs to get info about the renewal, such as which store and challenge(s) to use
|
|
304
|
+
greenlock.renew = async function(args) {
|
|
305
|
+
await greenlock._init();
|
|
306
|
+
var mconf = await greenlock.manager._defaults();
|
|
307
|
+
return greenlock._renew(mconf, args);
|
|
308
|
+
};
|
|
309
|
+
greenlock._renew = async function(mconf, args) {
|
|
310
|
+
if (!args) {
|
|
311
|
+
args = {};
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
var renewedOrFailed = [];
|
|
315
|
+
//console.log('greenlock._renew find', args);
|
|
316
|
+
var sites = await greenlock._find(args);
|
|
317
|
+
// Note: the manager must guaranteed that these are mutable copies
|
|
318
|
+
//console.log('greenlock._renew found', sites);;
|
|
319
|
+
|
|
320
|
+
if (!Array.isArray(sites)) {
|
|
321
|
+
throw new Error(
|
|
322
|
+
'Developer Error: not an array of sites returned from find: ' +
|
|
323
|
+
JSON.stringify(sites)
|
|
324
|
+
);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
await (async function next() {
|
|
328
|
+
var site = sites.shift();
|
|
329
|
+
if (!site) {
|
|
330
|
+
return null;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
var order = { site: site };
|
|
334
|
+
renewedOrFailed.push(order);
|
|
335
|
+
// TODO merge args + result?
|
|
336
|
+
return greenlock
|
|
337
|
+
._order(mconf, site)
|
|
338
|
+
.then(function(pems) {
|
|
339
|
+
if (args._includePems) {
|
|
340
|
+
order.pems = pems;
|
|
341
|
+
}
|
|
342
|
+
})
|
|
343
|
+
.catch(function(err) {
|
|
344
|
+
order.error = err;
|
|
345
|
+
|
|
346
|
+
// For greenlock express serialization
|
|
347
|
+
err.toJSON = errorToJSON;
|
|
348
|
+
err.context = err.context || 'cert_order';
|
|
349
|
+
err.subject = site.subject;
|
|
350
|
+
if (args.servername) {
|
|
351
|
+
err.servername = args.servername;
|
|
352
|
+
}
|
|
353
|
+
// for debugging, but not to be relied on
|
|
354
|
+
err._site = site;
|
|
355
|
+
// TODO err.context = err.context || 'renew_certificate'
|
|
356
|
+
greenlock._notify('error', err);
|
|
357
|
+
})
|
|
358
|
+
.then(function() {
|
|
359
|
+
return next();
|
|
360
|
+
});
|
|
361
|
+
})();
|
|
362
|
+
|
|
363
|
+
return renewedOrFailed;
|
|
364
|
+
};
|
|
365
|
+
|
|
366
|
+
greenlock._acme = async function(mconf, args, dirUrl) {
|
|
367
|
+
var packageAgent = gconf.packageAgent || '';
|
|
368
|
+
// because Greenlock_Express/v3.x Greenlock/v3 is redundant
|
|
369
|
+
if (!/greenlock/i.test(packageAgent)) {
|
|
370
|
+
packageAgent = (packageAgent + ' Greenlock/' + pkg.version).trim();
|
|
371
|
+
}
|
|
372
|
+
var acme = ACME.create({
|
|
373
|
+
maintainerEmail: gconf.maintainerEmail,
|
|
374
|
+
packageAgent: packageAgent,
|
|
375
|
+
notify: greenlock._notify,
|
|
376
|
+
debug: greenlock._defaults.debug || args.debug
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
var dir = caches[dirUrl];
|
|
380
|
+
// don't cache more than an hour
|
|
381
|
+
if (dir && Date.now() - dir.ts < 1 * 60 * 60 * 1000) {
|
|
382
|
+
return dir.promise;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
await acme.init(dirUrl).catch(function(err) {
|
|
386
|
+
log.error(
|
|
387
|
+
"ACME init failed (directory may be down or directoryUrl wrong):",
|
|
388
|
+
err.message
|
|
389
|
+
);
|
|
390
|
+
throw err;
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
caches[dirUrl] = {
|
|
394
|
+
promise: Promise.resolve(acme),
|
|
395
|
+
ts: Date.now()
|
|
396
|
+
};
|
|
397
|
+
return acme;
|
|
398
|
+
};
|
|
399
|
+
|
|
400
|
+
greenlock.order = async function(siteConf) {
|
|
401
|
+
await greenlock._init();
|
|
402
|
+
var mconf = await greenlock.manager._defaults();
|
|
403
|
+
return greenlock._order(mconf, siteConf);
|
|
404
|
+
};
|
|
405
|
+
greenlock._order = async function(mconf, siteConf) {
|
|
406
|
+
// packageAgent, maintainerEmail
|
|
407
|
+
|
|
408
|
+
var dirUrl = DIR._getDirectoryUrl(
|
|
409
|
+
siteConf.directoryUrl || mconf.directoryUrl,
|
|
410
|
+
siteConf.subject
|
|
411
|
+
);
|
|
412
|
+
|
|
413
|
+
var acme = await greenlock._acme(mconf, siteConf, dirUrl);
|
|
414
|
+
var storeConf = siteConf.store || mconf.store;
|
|
415
|
+
storeConf = JSON.parse(JSON.stringify(storeConf));
|
|
416
|
+
storeConf.packageRoot = gconf.packageRoot;
|
|
417
|
+
|
|
418
|
+
if (!storeConf.basePath) {
|
|
419
|
+
storeConf.basePath = gconf.configDir;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
if ('.' === (storeConf.basePath || '')[0]) {
|
|
423
|
+
if (!gconf.packageRoot) {
|
|
424
|
+
gconf.packageRoot = process.cwd();
|
|
425
|
+
log.warn('packageRoot not set; using', gconf.packageRoot);
|
|
426
|
+
}
|
|
427
|
+
storeConf.basePath = require('path').resolve(
|
|
428
|
+
gconf.packageRoot || '',
|
|
429
|
+
storeConf.basePath
|
|
430
|
+
);
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
storeConf.directoryUrl = dirUrl;
|
|
434
|
+
var store = await P._loadStore(storeConf);
|
|
435
|
+
var account = await A._getOrCreate(
|
|
436
|
+
greenlock,
|
|
437
|
+
mconf,
|
|
438
|
+
store.accounts,
|
|
439
|
+
acme,
|
|
440
|
+
siteConf
|
|
441
|
+
);
|
|
442
|
+
var challengeConfs = siteConf.challenges || mconf.challenges;
|
|
443
|
+
var challenges = {};
|
|
444
|
+
var arr = await Promise.all(
|
|
445
|
+
Object.keys(challengeConfs).map(function(typ01) {
|
|
446
|
+
return P._loadChallenge(challengeConfs, typ01);
|
|
447
|
+
})
|
|
448
|
+
);
|
|
449
|
+
arr.forEach(function(el) {
|
|
450
|
+
challenges[el._type] = el;
|
|
451
|
+
});
|
|
452
|
+
|
|
453
|
+
var pems = await C._getOrOrder(
|
|
454
|
+
greenlock,
|
|
455
|
+
mconf,
|
|
456
|
+
store.certificates,
|
|
457
|
+
acme,
|
|
458
|
+
challenges,
|
|
459
|
+
account,
|
|
460
|
+
siteConf
|
|
461
|
+
);
|
|
462
|
+
if (!pems) {
|
|
463
|
+
throw new Error('no order result');
|
|
464
|
+
}
|
|
465
|
+
if (!pems.privkey) {
|
|
466
|
+
throw new Error('missing private key, which is kinda important');
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
return pems;
|
|
470
|
+
};
|
|
471
|
+
|
|
472
|
+
greenlock._create();
|
|
473
|
+
|
|
474
|
+
return greenlock;
|
|
475
|
+
};
|
|
476
|
+
|
|
477
|
+
G._loadChallenge = P._loadChallenge;
|
|
478
|
+
|
|
479
|
+
function errorToJSON(e) {
|
|
480
|
+
var error = {};
|
|
481
|
+
Object.getOwnPropertyNames(e).forEach(function(k) {
|
|
482
|
+
error[k] = e[k];
|
|
483
|
+
});
|
|
484
|
+
return error;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
function mergeDefaults(MCONF, gconf) {
|
|
488
|
+
if (
|
|
489
|
+
gconf.agreeToTerms === true ||
|
|
490
|
+
MCONF.agreeToTerms === true ||
|
|
491
|
+
// TODO deprecate
|
|
492
|
+
gconf.agreeTos === true ||
|
|
493
|
+
MCONF.agreeTos === true
|
|
494
|
+
) {
|
|
495
|
+
MCONF.agreeToTerms = true;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
if (!MCONF.subscriberEmail && gconf.subscriberEmail) {
|
|
499
|
+
MCONF.subscriberEmail = gconf.subscriberEmail;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
// Load the default store module
|
|
503
|
+
if (!MCONF.store) {
|
|
504
|
+
if (gconf.store) {
|
|
505
|
+
MCONF.store = gconf.store;
|
|
506
|
+
} else {
|
|
507
|
+
MCONF.store = {
|
|
508
|
+
module: 'greenlock-store-fs'
|
|
509
|
+
};
|
|
510
|
+
log.info('Default store:', MCONF.store.module);
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
/*
|
|
515
|
+
if ('greenlock-store-fs' === MCONF.store.module && !MCONF.store.basePath) {
|
|
516
|
+
//homedir = require('os').homedir();
|
|
517
|
+
if (gconf.configFile) {
|
|
518
|
+
MCONF.store.basePath = gconf.configFile.replace(/\.json$/i, '.d');
|
|
519
|
+
} else {
|
|
520
|
+
MCONF.store.basePath = './greenlock.d';
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
*/
|
|
524
|
+
|
|
525
|
+
// just to test that it loads
|
|
526
|
+
P._loadSync(MCONF.store.module);
|
|
527
|
+
|
|
528
|
+
// Load the default challenge modules
|
|
529
|
+
var challenges = MCONF.challenges || gconf.challenges;
|
|
530
|
+
if (!challenges) {
|
|
531
|
+
challenges = {};
|
|
532
|
+
}
|
|
533
|
+
if (!challenges['http-01'] && !challenges['dns-01']) {
|
|
534
|
+
challenges['http-01'] = { module: 'acme-http-01-standalone' };
|
|
535
|
+
log.info('Default http-01 challenge:', challenges['http-01'].module);
|
|
536
|
+
}
|
|
537
|
+
if (challenges['http-01']) {
|
|
538
|
+
if ('string' !== typeof challenges['http-01'].module) {
|
|
539
|
+
throw new Error(
|
|
540
|
+
'bad challenge http-01 module config:' +
|
|
541
|
+
JSON.stringify(challenges['http-01'])
|
|
542
|
+
);
|
|
543
|
+
}
|
|
544
|
+
P._loadSync(challenges['http-01'].module);
|
|
545
|
+
}
|
|
546
|
+
if (challenges['dns-01']) {
|
|
547
|
+
if ('string' !== typeof challenges['dns-01'].module) {
|
|
548
|
+
throw new Error(
|
|
549
|
+
'bad challenge dns-01 module config' +
|
|
550
|
+
JSON.stringify(challenges['dns-01'])
|
|
551
|
+
);
|
|
552
|
+
}
|
|
553
|
+
P._loadSync(challenges['dns-01'].module);
|
|
554
|
+
}
|
|
555
|
+
MCONF.challenges = challenges;
|
|
556
|
+
|
|
557
|
+
if (!MCONF.renewOffset) {
|
|
558
|
+
MCONF.renewOffset = gconf.renewOffset || '-45d';
|
|
559
|
+
log.info('Default renewOffset:', MCONF.renewOffset);
|
|
560
|
+
}
|
|
561
|
+
if (!MCONF.renewStagger) {
|
|
562
|
+
MCONF.renewStagger = gconf.renewStagger || '3d';
|
|
563
|
+
log.info('Default renewStagger:', MCONF.renewStagger);
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
var vers = process.versions.node.split('.');
|
|
567
|
+
var defaultKeyType = 'EC-P256';
|
|
568
|
+
if (vers[0] < 10 || (vers[0] === '10' && vers[1] < '12')) {
|
|
569
|
+
defaultKeyType = 'RSA-2048';
|
|
570
|
+
}
|
|
571
|
+
if (!MCONF.accountKeyType) {
|
|
572
|
+
MCONF.accountKeyType = gconf.accountKeyType || defaultKeyType;
|
|
573
|
+
log.info('Default accountKeyType:', MCONF.accountKeyType);
|
|
574
|
+
}
|
|
575
|
+
if (!MCONF.serverKeyType) {
|
|
576
|
+
MCONF.serverKeyType = gconf.serverKeyType || 'RSA-2048';
|
|
577
|
+
log.info('Default serverKeyType:', MCONF.serverKeyType);
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
if (!MCONF.subscriberEmail && false !== MCONF.subscriberEmail) {
|
|
581
|
+
MCONF.subscriberEmail =
|
|
582
|
+
gconf.subscriberEmail || gconf.maintainerEmail || undefined;
|
|
583
|
+
MCONF.agreeToTerms = gconf.agreeToTerms || undefined;
|
|
584
|
+
log.info(
|
|
585
|
+
'Defaults: subscriberEmail=%s, agreeToTerms=%s',
|
|
586
|
+
MCONF.subscriberEmail,
|
|
587
|
+
MCONF.agreeToTerms || gconf.agreeToTerms || '(show notice on use)'
|
|
588
|
+
);
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
function _notify(ev, args) {
|
|
593
|
+
if (!args) {
|
|
594
|
+
args = ev;
|
|
595
|
+
ev = args.event;
|
|
596
|
+
delete args.event;
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
if (!_notify._notice) {
|
|
600
|
+
log.info('Set greenlockOptions.notify to override the default logger');
|
|
601
|
+
_notify._notice = true;
|
|
602
|
+
}
|
|
603
|
+
switch (ev) {
|
|
604
|
+
case 'error':
|
|
605
|
+
case 'warning': {
|
|
606
|
+
var msg = (args.context ? args.context + ': ' : '') + (args.message || '');
|
|
607
|
+
log[ev === 'error' ? 'error' : 'warn'](msg);
|
|
608
|
+
if (args.description) log[ev === 'error' ? 'error' : 'warn'](args.description);
|
|
609
|
+
if (args.code) log[ev === 'error' ? 'error' : 'warn']('code:', args.code);
|
|
610
|
+
if (args.stack) log.error(args.stack);
|
|
611
|
+
break;
|
|
612
|
+
}
|
|
613
|
+
default:
|
|
614
|
+
if (/status/.test(ev)) {
|
|
615
|
+
log.info(ev, args.altname || args.subject || '', args.status || '');
|
|
616
|
+
if (!args.status) log.info(args);
|
|
617
|
+
} else {
|
|
618
|
+
log.info(ev, '(details:', Object.keys(args).join(' ') + ')');
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
}
|