diff --git a/manager.js b/manager.js index d749872..365a9a4 100644 --- a/manager.js +++ b/manager.js @@ -111,9 +111,10 @@ Manage.create = function(opts) { config.sites = {}; } - var site = config.sites[primary]; - if (!site) { - site = config.sites[primary] = { altnames: [] }; + var existing = config.sites[primary]; + var site = existing; + if (!existing) { + site = config.sites[primary] = { altnames: [primary] }; } // The goal is to make this decently easy to manage by hand without mistakes @@ -125,6 +126,17 @@ Manage.create = function(opts) { site.subscriberEmail = subscriberEmail; } site.subject = subject; + site.renewAt = args.renewAt || site.renewAt || 0; + if ( + altnames + .slice(0) + .sort() + .join(' ') !== site.altnames.slice(0).sort.join(' ') + ) { + // TODO signal to wait for renewal? + // it will definitely be renewed on the first request anyway + site.renewAt = 0; + } site.altnames = altnames; if (!site.issuedAt) { site.issuedAt = 0; @@ -167,13 +179,85 @@ Manage.create = function(opts) { }; manage.find = function(args) { - var some = _find(args); - if (!opts.find) { - return some; - } - // TODO function to always add - throw new Error('TODO: use the given find'); + return _find(args).then(function(existing) { + if (!opts.find) { + return existing; + } + + return Promise.resolve(opts.find(args)).then(function(results) { + // TODO also detect and delete stale (just ignoring them for now) + var changed = []; + var same = []; + results.forEach(function(_newer) { + // Check lowercase subject names + var subject = (_newer.subject || '').toLowerCase(); + // Set the default altnames to the subject, just in case + var altnames = _newer.altnames || []; + if (!altnames.includes(subject)) { + console.warn( + "all site configs should include 'subject' and 'altnames': " + + subject + ); + altnames.push(subject); + } + + existing.some(function(_older) { + if (subject !== (_older.subject || '').toLowerCase()) { + return false; + } + _newer._exists = true; + + // Compare the altnames and update if needed + if ( + altnames + .slice(0) + .sort() + .join(' ') !== + (_older.altnames || []) + .slice(0) + .sort() + .join(' ') + ) { + _older.renewAt = 0; + _older.altnames = altnames; + // TODO signal waitForRenewal (although it'll update on the first access automatically) + changed.push(_older); + } else { + same.push(_older); + } + + return true; + }); + + if (!_newer._exists) { + changed.push({ + subject: subject, + altnames: altnames, + renewAt: 0 + }); + } + }); + + if (!changed.length) { + return same; + } + + // kinda redundant to pull again, but whatever... + return Manage._getLatest(manage, opts).then(function(config) { + changed.forEach(function(site) { + config.sites[site.subject] = site; + }); + return manage._save(config).then(function() { + // everything was either added, updated, or not different + // hence, this is everything + var all = changed.concat(same); + return all; + }); + }); + }); + }); }; + function _find(args) { return Manage._getLatest(manage, opts).then(function(config) { // i.e. find certs more than 30 days old diff --git a/package.json b/package.json index 7e2a1bc..0efcd06 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "greenlock-manager-fs", - "version": "0.6.3", + "version": "0.6.4", "description": "A simple file-based management strategy for Greenlock", "main": "manager.js", "scripts": {