roster-server 2.2.9 → 2.2.12
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/index.js +2 -2
- package/package.json +12 -3
- package/tasks/lessons.md +2 -1
- package/test/roster-server.test.js +5 -6
- 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
|
@@ -0,0 +1,625 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var U = require('../utils.js');
|
|
4
|
+
var E = require('../errors.js');
|
|
5
|
+
var log = require('lemonlog')('greenlock-manager');
|
|
6
|
+
|
|
7
|
+
var warned = {};
|
|
8
|
+
|
|
9
|
+
// The purpose of this file is to try to auto-build
|
|
10
|
+
// partial managers so that the external API can be smaller.
|
|
11
|
+
|
|
12
|
+
module.exports.wrap = function(greenlock, gconf) {
|
|
13
|
+
var myFind = gconf.find;
|
|
14
|
+
delete gconf.find;
|
|
15
|
+
|
|
16
|
+
var mega = mergeManager(greenlock, gconf);
|
|
17
|
+
|
|
18
|
+
greenlock.manager = {};
|
|
19
|
+
greenlock.sites = {};
|
|
20
|
+
//greenlock.accounts = {};
|
|
21
|
+
//greenlock.certs = {};
|
|
22
|
+
|
|
23
|
+
greenlock.manager._modulename = gconf.manager.module;
|
|
24
|
+
if ('/' === String(gconf.manager.module)[0]) {
|
|
25
|
+
greenlock.manager._modulename = require('path').relative(
|
|
26
|
+
gconf.packageRoot,
|
|
27
|
+
greenlock.manager._modulename
|
|
28
|
+
);
|
|
29
|
+
if ('.' !== String(greenlock.manager._modulename)[0]) {
|
|
30
|
+
greenlock.manager._modulename =
|
|
31
|
+
'./' + greenlock.manager._modulename;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
var allowed = [
|
|
36
|
+
'accountKeyType', //: ["P-256", "RSA-2048"],
|
|
37
|
+
'serverKeyType', //: ["RSA-2048", "P-256"],
|
|
38
|
+
'store', // : { module, specific opts },
|
|
39
|
+
'challenges', // : { "http-01", "dns-01", "tls-alpn-01" },
|
|
40
|
+
'subscriberEmail',
|
|
41
|
+
'agreeToTerms',
|
|
42
|
+
'agreeTos',
|
|
43
|
+
'customerEmail',
|
|
44
|
+
'renewOffset',
|
|
45
|
+
'renewStagger',
|
|
46
|
+
'module', // not allowed, just ignored
|
|
47
|
+
'manager'
|
|
48
|
+
];
|
|
49
|
+
|
|
50
|
+
// get / set default site settings such as
|
|
51
|
+
// subscriberEmail, store, challenges, renewOffset, renewStagger
|
|
52
|
+
greenlock.manager.defaults = function(conf) {
|
|
53
|
+
return greenlock._init().then(function() {
|
|
54
|
+
if (!conf) {
|
|
55
|
+
return mega.defaults();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (conf.sites) {
|
|
59
|
+
throw new Error('cannot set sites as global config');
|
|
60
|
+
}
|
|
61
|
+
if (conf.routes) {
|
|
62
|
+
throw new Error('cannot set routes as global config');
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// disallow keys we know to be bad
|
|
66
|
+
[
|
|
67
|
+
'subject',
|
|
68
|
+
'deletedAt',
|
|
69
|
+
'altnames',
|
|
70
|
+
'lastAttemptAt',
|
|
71
|
+
'expiresAt',
|
|
72
|
+
'issuedAt',
|
|
73
|
+
'renewAt',
|
|
74
|
+
'sites',
|
|
75
|
+
'routes'
|
|
76
|
+
].some(function(k) {
|
|
77
|
+
if (k in conf) {
|
|
78
|
+
throw new Error(
|
|
79
|
+
'`' + k + '` not allowed as a default setting'
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
Object.keys(conf).forEach(function(k) {
|
|
84
|
+
if (!allowed.includes(k) && !warned[k]) {
|
|
85
|
+
warned[k] = true;
|
|
86
|
+
log.warn("Unknown config key '%s'; open an issue if you need it", k);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
Object.keys(conf).forEach(function(k) {
|
|
91
|
+
if (-1 !== ['module', 'manager'].indexOf(k)) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if ('undefined' === typeof k) {
|
|
96
|
+
throw new Error(
|
|
97
|
+
"'" +
|
|
98
|
+
k +
|
|
99
|
+
"' should be set to a value, or `null`, but not left `undefined`"
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
return mega.defaults(conf);
|
|
105
|
+
});
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
greenlock.manager._defaults = function(opts) {
|
|
109
|
+
return mega.defaults(opts);
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
greenlock.manager.add = function(args) {
|
|
113
|
+
if (!args || !Array.isArray(args.altnames) || !args.altnames.length) {
|
|
114
|
+
throw new Error(
|
|
115
|
+
'you must specify `altnames` when adding a new site'
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
if (args.renewAt) {
|
|
119
|
+
throw new Error(
|
|
120
|
+
'you cannot specify `renewAt` when adding a new site'
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return greenlock.manager.set(args);
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
// TODO agreeToTerms should be handled somewhere... maybe?
|
|
128
|
+
|
|
129
|
+
// Add and update remains because I said I had locked the API
|
|
130
|
+
greenlock.manager.set = greenlock.manager.update = function(args) {
|
|
131
|
+
return greenlock._init().then(function() {
|
|
132
|
+
// The goal is to make this decently easy to manage by hand without mistakes
|
|
133
|
+
// but also reasonably easy to error check and correct
|
|
134
|
+
// and to make deterministic auto-corrections
|
|
135
|
+
|
|
136
|
+
args.subject = checkSubject(args);
|
|
137
|
+
|
|
138
|
+
//var subscriberEmail = args.subscriberEmail;
|
|
139
|
+
|
|
140
|
+
// TODO shortcut the other array checks when not necessary
|
|
141
|
+
if (Array.isArray(args.altnames)) {
|
|
142
|
+
args.altnames = checkAltnames(args.subject, args);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// at this point we know that subject is the first of altnames
|
|
146
|
+
return Promise.all(
|
|
147
|
+
(args.altnames || []).map(function(d) {
|
|
148
|
+
d = d.replace('*.', '');
|
|
149
|
+
return U._validDomain(d);
|
|
150
|
+
})
|
|
151
|
+
).then(function() {
|
|
152
|
+
if (!U._uniqueNames(args.altnames || [])) {
|
|
153
|
+
throw E.NOT_UNIQUE(
|
|
154
|
+
'add',
|
|
155
|
+
"'" + args.altnames.join("' '") + "'"
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// durations
|
|
160
|
+
if (args.renewOffset) {
|
|
161
|
+
args.renewOffset = U._parseDuration(args.renewOffset);
|
|
162
|
+
}
|
|
163
|
+
if (args.renewStagger) {
|
|
164
|
+
args.renewStagger = U._parseDuration(args.renewStagger);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return mega.set(args).then(function(result) {
|
|
168
|
+
if (!gconf._bin_mode) {
|
|
169
|
+
greenlock.renew({}).catch(function(err) {
|
|
170
|
+
if (!err.context) {
|
|
171
|
+
err.contxt = 'renew';
|
|
172
|
+
}
|
|
173
|
+
greenlock._notify('error', err);
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
return result;
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
greenlock.manager.get = greenlock.sites.get = function(args) {
|
|
183
|
+
return Promise.resolve().then(function() {
|
|
184
|
+
if (args.subject) {
|
|
185
|
+
throw new Error(
|
|
186
|
+
'get({ servername }) searches certificates by altnames, not by subject specifically'
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
if (args.servernames || args.altnames || args.renewBefore) {
|
|
190
|
+
throw new Error(
|
|
191
|
+
'get({ servername }) does not take arguments that could lead to multiple results'
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
return mega.get(args);
|
|
195
|
+
});
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
greenlock.manager.remove = function(args) {
|
|
199
|
+
return Promise.resolve().then(function() {
|
|
200
|
+
args.subject = checkSubject(args);
|
|
201
|
+
if (args.servername) {
|
|
202
|
+
throw new Error(
|
|
203
|
+
'remove() should be called with `subject` only, if you wish to remove altnames use `update()`'
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
if (args.altnames) {
|
|
207
|
+
throw new Error(
|
|
208
|
+
'remove() should be called with `subject` only, not `altnames`'
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
// TODO check no altnames
|
|
212
|
+
return mega.remove(args);
|
|
213
|
+
});
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
/*
|
|
217
|
+
{
|
|
218
|
+
subject: site.subject,
|
|
219
|
+
altnames: site.altnames,
|
|
220
|
+
//issuedAt: site.issuedAt,
|
|
221
|
+
//expiresAt: site.expiresAt,
|
|
222
|
+
renewOffset: site.renewOffset,
|
|
223
|
+
renewStagger: site.renewStagger,
|
|
224
|
+
renewAt: site.renewAt,
|
|
225
|
+
subscriberEmail: site.subscriberEmail,
|
|
226
|
+
customerEmail: site.customerEmail,
|
|
227
|
+
challenges: site.challenges,
|
|
228
|
+
store: site.store
|
|
229
|
+
};
|
|
230
|
+
*/
|
|
231
|
+
|
|
232
|
+
// no transaction promise here because it calls set
|
|
233
|
+
greenlock._find = async function(args) {
|
|
234
|
+
args = _mangleFindArgs(args);
|
|
235
|
+
var ours = await mega.find(args);
|
|
236
|
+
if (!myFind) {
|
|
237
|
+
return ours;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// if the user has an overlay find function we'll do a diff
|
|
241
|
+
// between the managed state and the overlay, and choose
|
|
242
|
+
// what was found.
|
|
243
|
+
var theirs = await myFind(args);
|
|
244
|
+
theirs = theirs.filter(function(site) {
|
|
245
|
+
if (!site || 'string' !== typeof site.subject) {
|
|
246
|
+
throw new Error('found site is missing subject');
|
|
247
|
+
}
|
|
248
|
+
if (
|
|
249
|
+
!Array.isArray(site.altnames) ||
|
|
250
|
+
!site.altnames.length ||
|
|
251
|
+
!site.altnames[0] ||
|
|
252
|
+
site.altnames[0] !== site.subject
|
|
253
|
+
) {
|
|
254
|
+
throw new Error('missing or malformed altnames');
|
|
255
|
+
}
|
|
256
|
+
['renewAt', 'issuedAt', 'expiresAt'].forEach(function(k) {
|
|
257
|
+
if (site[k]) {
|
|
258
|
+
throw new Error(
|
|
259
|
+
'`' +
|
|
260
|
+
k +
|
|
261
|
+
'` should be updated by `set()`, not by `find()`'
|
|
262
|
+
);
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
if (!site) {
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
if (args.subject && site.subject !== args.subject) {
|
|
269
|
+
return false;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
var servernames = args.servernames || args.altnames;
|
|
273
|
+
if (
|
|
274
|
+
servernames &&
|
|
275
|
+
!site.altnames.some(function(altname) {
|
|
276
|
+
return servernames.includes(altname);
|
|
277
|
+
})
|
|
278
|
+
) {
|
|
279
|
+
return false;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
return site.renewAt < (args.renewBefore || Infinity);
|
|
283
|
+
});
|
|
284
|
+
return _mergeFind(ours, theirs);
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
function _mergeFind(ours, theirs) {
|
|
288
|
+
var toUpdate = [];
|
|
289
|
+
theirs.forEach(function(_newer) {
|
|
290
|
+
var hasCurrent = ours.some(function(_older) {
|
|
291
|
+
var changed = false;
|
|
292
|
+
if (_newer.subject !== _older.subject) {
|
|
293
|
+
return false;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// BE SURE TO SET THIS UNDEFINED AFTERWARDS
|
|
297
|
+
_older._exists = true;
|
|
298
|
+
|
|
299
|
+
_newer.deletedAt = _newer.deletedAt || 0;
|
|
300
|
+
Object.keys(_newer).forEach(function(k) {
|
|
301
|
+
if (_older[k] !== _newer[k]) {
|
|
302
|
+
changed = true;
|
|
303
|
+
_older[k] = _newer[k];
|
|
304
|
+
}
|
|
305
|
+
});
|
|
306
|
+
if (changed) {
|
|
307
|
+
toUpdate.push(_older);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// handled the (only) match
|
|
311
|
+
return true;
|
|
312
|
+
});
|
|
313
|
+
if (!hasCurrent) {
|
|
314
|
+
toUpdate.push(_newer);
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
// delete the things that are gone
|
|
319
|
+
ours.forEach(function(_older) {
|
|
320
|
+
if (!_older._exists) {
|
|
321
|
+
_older.deletedAt = Date.now();
|
|
322
|
+
toUpdate.push(_older);
|
|
323
|
+
}
|
|
324
|
+
_older._exists = undefined;
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
Promise.all(
|
|
328
|
+
toUpdate.map(function(site) {
|
|
329
|
+
return greenlock.sites.update(site).catch(function(err) {
|
|
330
|
+
log.error('Cannot update sites from user find():', err);
|
|
331
|
+
});
|
|
332
|
+
})
|
|
333
|
+
);
|
|
334
|
+
|
|
335
|
+
// ours is updated from theirs
|
|
336
|
+
return ours;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
greenlock.manager.init = mega.init;
|
|
340
|
+
};
|
|
341
|
+
|
|
342
|
+
function checkSubject(args) {
|
|
343
|
+
if (!args || !args.subject) {
|
|
344
|
+
throw new Error('you must specify `subject` when configuring a site');
|
|
345
|
+
}
|
|
346
|
+
/*
|
|
347
|
+
if (!args.subject) {
|
|
348
|
+
throw E.NO_SUBJECT('add');
|
|
349
|
+
}
|
|
350
|
+
*/
|
|
351
|
+
|
|
352
|
+
var subject = (args.subject || '').toLowerCase();
|
|
353
|
+
if (subject !== args.subject) {
|
|
354
|
+
log.warn('subject must be lowercase:', args.subject);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
return U._encodeName(subject);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
function checkAltnames(subject, args) {
|
|
361
|
+
// the things we have to check and get right
|
|
362
|
+
var altnames = (args.altnames || []).map(function(name) {
|
|
363
|
+
return String(name || '').toLowerCase();
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
// punycode BEFORE validation
|
|
367
|
+
// (set, find, remove)
|
|
368
|
+
if (altnames.join() !== args.altnames.join()) {
|
|
369
|
+
log.warn('altnames must be lowercase:', args.altnames);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
args.altnames = args.altnames.map(U._encodeName);
|
|
373
|
+
if (
|
|
374
|
+
!args.altnames.every(function(d) {
|
|
375
|
+
return U._validName(d);
|
|
376
|
+
})
|
|
377
|
+
) {
|
|
378
|
+
throw E.INVALID_HOSTNAME('add', "'" + args.altnames.join("' '") + "'");
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
if (subject && subject !== args.altnames[0]) {
|
|
382
|
+
throw E.BAD_ORDER(
|
|
383
|
+
'add',
|
|
384
|
+
'(' + args.subject + ") '" + args.altnames.join("' '") + "'"
|
|
385
|
+
);
|
|
386
|
+
}
|
|
387
|
+
/*
|
|
388
|
+
if (subject && subject !== altnames[0]) {
|
|
389
|
+
throw new Error(
|
|
390
|
+
'`subject` must be the first domain in `altnames`',
|
|
391
|
+
args.subject,
|
|
392
|
+
altnames.join(' ')
|
|
393
|
+
);
|
|
394
|
+
}
|
|
395
|
+
*/
|
|
396
|
+
|
|
397
|
+
return altnames;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
function loadManager(gconf) {
|
|
401
|
+
var m;
|
|
402
|
+
// 1. Get the manager
|
|
403
|
+
// 2. Figure out if we need to wrap it
|
|
404
|
+
|
|
405
|
+
/*
|
|
406
|
+
if (!gconf.manager) {
|
|
407
|
+
gconf.manager = '@greenlock/manager';
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
if ('string' !== typeof gconf.manager) {
|
|
411
|
+
throw new Error(
|
|
412
|
+
'`manager` should be a string representing the npm name or file path of the module'
|
|
413
|
+
);
|
|
414
|
+
}
|
|
415
|
+
*/
|
|
416
|
+
|
|
417
|
+
try {
|
|
418
|
+
m = require(gconf.manager.module).create(gconf.manager);
|
|
419
|
+
} catch (e) {
|
|
420
|
+
log.error('Error loading manager:', e.code, e.message);
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
if (!m) {
|
|
424
|
+
log.error('Failed to load manager plugin:', gconf.manager);
|
|
425
|
+
process.exit(1);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
return m;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
function mergeManager(greenlock, gconf) {
|
|
432
|
+
var mng;
|
|
433
|
+
function m() {
|
|
434
|
+
if (mng) {
|
|
435
|
+
return mng;
|
|
436
|
+
}
|
|
437
|
+
mng = require('@greenlock/manager').create(gconf);
|
|
438
|
+
return mng;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
var mini = loadManager(gconf);
|
|
442
|
+
var mega = {};
|
|
443
|
+
// optional
|
|
444
|
+
if (mini.defaults) {
|
|
445
|
+
mega.defaults = function(opts) {
|
|
446
|
+
return mini.defaults(opts);
|
|
447
|
+
};
|
|
448
|
+
} else {
|
|
449
|
+
mega.defaults = m().defaults;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
// optional
|
|
453
|
+
if (mini.remove) {
|
|
454
|
+
mega.remove = function(opts) {
|
|
455
|
+
return mini.remove(opts);
|
|
456
|
+
};
|
|
457
|
+
} else {
|
|
458
|
+
mega.remove = function(opts) {
|
|
459
|
+
mega.get(opts).then(function(site) {
|
|
460
|
+
if (!site) {
|
|
461
|
+
return null;
|
|
462
|
+
}
|
|
463
|
+
site.deletedAt = Date.now();
|
|
464
|
+
return mega.set(site).then(function() {
|
|
465
|
+
return site;
|
|
466
|
+
});
|
|
467
|
+
});
|
|
468
|
+
};
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
if (mini.find) {
|
|
472
|
+
// without this there cannot be fully automatic renewal
|
|
473
|
+
mega.find = function(opts) {
|
|
474
|
+
return mini.find(opts);
|
|
475
|
+
};
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
// set and (find and/or get) should be from the same set
|
|
479
|
+
if (mini.set) {
|
|
480
|
+
mega.set = function(opts) {
|
|
481
|
+
if (!mini.find) {
|
|
482
|
+
// TODO create the list so that find can be implemented
|
|
483
|
+
}
|
|
484
|
+
return mini.set(opts);
|
|
485
|
+
};
|
|
486
|
+
} else {
|
|
487
|
+
mega.set = m().set;
|
|
488
|
+
mega.get = m().get;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
if (mini.get) {
|
|
492
|
+
mega.get = async function(opts) {
|
|
493
|
+
if (mini.set) {
|
|
494
|
+
return mini.get(opts);
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
if (!mega._get) {
|
|
498
|
+
mega._get = m().get;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
var existing = await mega._get(opts);
|
|
502
|
+
var site = await mini.get(opts);
|
|
503
|
+
if (!existing) {
|
|
504
|
+
// Add
|
|
505
|
+
if (!site) {
|
|
506
|
+
return;
|
|
507
|
+
}
|
|
508
|
+
site.renewAt = 1;
|
|
509
|
+
site.deletedAt = 0;
|
|
510
|
+
await mega.set(site);
|
|
511
|
+
existing = await mega._get(opts);
|
|
512
|
+
} else if (!site) {
|
|
513
|
+
// Delete
|
|
514
|
+
existing.deletedAt = site.deletedAt || Date.now();
|
|
515
|
+
await mega.set(existing);
|
|
516
|
+
existing = null;
|
|
517
|
+
} else if (
|
|
518
|
+
site.subject !== existing.subject ||
|
|
519
|
+
site.altnames.join(' ') !== existing.altnames.join(' ')
|
|
520
|
+
) {
|
|
521
|
+
// Update
|
|
522
|
+
site.renewAt = 1;
|
|
523
|
+
site.deletedAt = 0;
|
|
524
|
+
await mega.set(site);
|
|
525
|
+
existing = await mega._get(opts);
|
|
526
|
+
if (!existing) {
|
|
527
|
+
throw new Error('failed to `get` after `set`');
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
return existing;
|
|
532
|
+
};
|
|
533
|
+
} else if (mini.find) {
|
|
534
|
+
mega.get = function(opts) {
|
|
535
|
+
var servername = opts.servername;
|
|
536
|
+
delete opts.servername;
|
|
537
|
+
opts.servernames = (servername && [servername]) || undefined;
|
|
538
|
+
return mini.find(opts).then(function(sites) {
|
|
539
|
+
return sites.filter(function(site) {
|
|
540
|
+
return site.altnames.include(servername);
|
|
541
|
+
})[0];
|
|
542
|
+
});
|
|
543
|
+
};
|
|
544
|
+
} else if (mini.set) {
|
|
545
|
+
throw new Error(
|
|
546
|
+
gconf.manager.module +
|
|
547
|
+
' implements `set()`, but not `get()` or `find()`'
|
|
548
|
+
);
|
|
549
|
+
} else {
|
|
550
|
+
mega.find = m().find;
|
|
551
|
+
mega.get = m().get;
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
if (!mega.find) {
|
|
555
|
+
mega._nofind = false;
|
|
556
|
+
mega.find = async function(opts) {
|
|
557
|
+
if (!mega._nofind) {
|
|
558
|
+
log.warn('Manager %s does not implement find({})', greenlock.manager._modulename);
|
|
559
|
+
mega._nofind = true;
|
|
560
|
+
}
|
|
561
|
+
return [];
|
|
562
|
+
};
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
if (!mega.get) {
|
|
566
|
+
mega.get = function(opts) {
|
|
567
|
+
var servername = opts.servername;
|
|
568
|
+
delete opts.servername;
|
|
569
|
+
opts.servernames = (servername && [servername]) || undefined;
|
|
570
|
+
return mega.find(opts).then(function(sites) {
|
|
571
|
+
return sites.filter(function(site) {
|
|
572
|
+
return site.altnames.include(servername);
|
|
573
|
+
})[0];
|
|
574
|
+
});
|
|
575
|
+
};
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
mega.init = function(deps) {
|
|
579
|
+
if (mini.init) {
|
|
580
|
+
return mini.init(deps).then(function() {
|
|
581
|
+
if (mng) {
|
|
582
|
+
return mng.init(deps);
|
|
583
|
+
}
|
|
584
|
+
});
|
|
585
|
+
} else if (mng) {
|
|
586
|
+
return mng.init(deps);
|
|
587
|
+
} else {
|
|
588
|
+
return Promise.resolve(null);
|
|
589
|
+
}
|
|
590
|
+
};
|
|
591
|
+
|
|
592
|
+
return mega;
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
function _mangleFindArgs(args) {
|
|
596
|
+
var servernames = (args.servernames || [])
|
|
597
|
+
.concat(args.altnames || [])
|
|
598
|
+
.filter(Boolean)
|
|
599
|
+
.slice(0);
|
|
600
|
+
var modified = servernames.slice(0);
|
|
601
|
+
|
|
602
|
+
// servername, wildname, and altnames are all the same
|
|
603
|
+
['wildname', 'servername'].forEach(function(k) {
|
|
604
|
+
var altname = args[k] || '';
|
|
605
|
+
if (altname && !modified.includes(altname)) {
|
|
606
|
+
modified.push(altname);
|
|
607
|
+
}
|
|
608
|
+
});
|
|
609
|
+
|
|
610
|
+
if (modified.length) {
|
|
611
|
+
servernames = modified;
|
|
612
|
+
servernames = servernames.map(U._encodeName);
|
|
613
|
+
args.altnames = servernames;
|
|
614
|
+
args.servernames = args.altnames = checkAltnames(false, args);
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
// documented as args.servernames
|
|
618
|
+
// preserved as args.altnames for v3 beta backwards compat
|
|
619
|
+
// my only hesitancy in this choice is that a "servername"
|
|
620
|
+
// may NOT contain '*.', in which case `altnames` is a better choice.
|
|
621
|
+
// However, `altnames` is ambiguous - as if it means to find a
|
|
622
|
+
// certificate by that specific collection of altnames.
|
|
623
|
+
// ... perhaps `domains` could work?
|
|
624
|
+
return args;
|
|
625
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var Rc = module.exports;
|
|
4
|
+
var log = require('lemonlog')('greenlock-rc');
|
|
5
|
+
var fs = require('fs');
|
|
6
|
+
var path = require('path');
|
|
7
|
+
|
|
8
|
+
// This is only called if packageRoot is specified
|
|
9
|
+
// (which it should be most of the time)
|
|
10
|
+
Rc._initSync = function(dirname, manager, configDir) {
|
|
11
|
+
if (!dirname) {
|
|
12
|
+
return {};
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// dirname / opts.packageRoot
|
|
16
|
+
var rcpath = path.resolve(dirname, '.greenlockrc');
|
|
17
|
+
var rc;
|
|
18
|
+
|
|
19
|
+
try {
|
|
20
|
+
rc = JSON.parse(fs.readFileSync(rcpath));
|
|
21
|
+
} catch (e) {
|
|
22
|
+
if ('ENOENT' !== e.code) {
|
|
23
|
+
throw e;
|
|
24
|
+
}
|
|
25
|
+
rc = {};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
var changed = true;
|
|
29
|
+
|
|
30
|
+
// In the general case the manager should be specified in the
|
|
31
|
+
// config file, which is in the config dir, but for the specific
|
|
32
|
+
// case in which all custom plugins are being used and no config
|
|
33
|
+
// dir is needed, we allow the manager to be read from the rc.
|
|
34
|
+
// ex: manager: { module: 'name', xxxx: 'xxxx' }
|
|
35
|
+
if (manager) {
|
|
36
|
+
if (rc.manager) {
|
|
37
|
+
if (
|
|
38
|
+
('string' === typeof rc.manager && rc.manager !== manager) ||
|
|
39
|
+
('string' !== typeof rc.manager &&
|
|
40
|
+
rc.manager.module !== manager.module)
|
|
41
|
+
) {
|
|
42
|
+
changed = true;
|
|
43
|
+
log.info('Changing manager from %s to %s', rc.manager.module || rc.manager, manager.module || manager);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
rc.manager = manager;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (!configDir) {
|
|
50
|
+
configDir = rc.configDir;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (configDir && configDir !== rc.configDir) {
|
|
54
|
+
if (rc.configDir) {
|
|
55
|
+
log.info('Changing configDir from %s to %s', rc.configDir, configDir);
|
|
56
|
+
}
|
|
57
|
+
changed = true;
|
|
58
|
+
rc.configDir = configDir;
|
|
59
|
+
} else if (!rc.configDir) {
|
|
60
|
+
changed = true;
|
|
61
|
+
configDir = './greenlock.d';
|
|
62
|
+
rc.configDir = configDir;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (changed) {
|
|
66
|
+
fs.writeFileSync(rcpath, JSON.stringify(rc));
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return rc;
|
|
70
|
+
};
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|