mirror of
				https://github.com/therootcompany/greenlock.js.git
				synced 2024-11-16 17:29:00 +00:00 
			
		
		
		
	Compare commits
	
		
			No commits in common. "f913f8d19339f83afce300c41da9f0802e41bf67" and "bba2e2012d004c26fbb3feafdc4ce3fa2b38963d" have entirely different histories.
		
	
	
		
			f913f8d193
			...
			bba2e2012d
		
	
		
| @ -1,36 +1,4 @@ | |||||||
| # Migrating Guide | # Migrating from Greenlock v2 to v3 | ||||||
| 
 |  | ||||||
| Greenlock v4 is the current version. |  | ||||||
| 
 |  | ||||||
| # v3 to v4 |  | ||||||
| 
 |  | ||||||
| v4 is a very minor, but breaking, change from v3 |  | ||||||
| 
 |  | ||||||
| ### `configFile` is replaced with `configDir` |  | ||||||
| 
 |  | ||||||
| The default config file `./greenlock.json` is now `./greenlock.d/config.json`. |  | ||||||
| 
 |  | ||||||
| This was change was mode to eliminate unnecessary configuration that was inadvertantly introduced in v3. |  | ||||||
| 
 |  | ||||||
| ### `.greenlockrc` is auto-generated |  | ||||||
| 
 |  | ||||||
| `.greenlockrc` exists for the sake of tooling - so that the CLI, Web API, and your code naturally stay in sync. |  | ||||||
| 
 |  | ||||||
| It looks like this: |  | ||||||
| 
 |  | ||||||
| ```json |  | ||||||
| { |  | ||||||
|     "manager": { |  | ||||||
|         "module": "@greenlock/manager" |  | ||||||
|     }, |  | ||||||
|     "configDir": "./greenlock.d" |  | ||||||
| } |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| If you deploy to a read-only filesystem, it is best that you create the `.greenlockrc` file as part |  | ||||||
| of your image and use that rather than including any configuration in your code. |  | ||||||
| 
 |  | ||||||
| # v2 to v4 |  | ||||||
| 
 | 
 | ||||||
| **Greenlock Express** uses Greenlock directly, the same as before. | **Greenlock Express** uses Greenlock directly, the same as before. | ||||||
| 
 | 
 | ||||||
| @ -227,11 +195,11 @@ as well as a set of callbacks for easy configurability. | |||||||
| 
 | 
 | ||||||
| ### Default Manager | ### Default Manager | ||||||
| 
 | 
 | ||||||
| The default manager is `@greenlock/manager` and the default `configDir` is `./.greenlock.d`. | The default manager is `greenlock-manager-fs` and the default `configFile` is `~/.config/greenlock/manager.json`. | ||||||
| 
 | 
 | ||||||
| The config file should look something like this: | The config file should look something like this: | ||||||
| 
 | 
 | ||||||
| `./greenlock.d/config.json`: | `~/.config/greenlock/manager.json`: | ||||||
| 
 | 
 | ||||||
| ```json | ```json | ||||||
| { | { | ||||||
| @ -288,20 +256,29 @@ The same is true with `greenlock-store-*` plugins: | |||||||
| 
 | 
 | ||||||
| ### Customer Manager, the lazy way | ### Customer Manager, the lazy way | ||||||
| 
 | 
 | ||||||
| At the very least you have to implement `get({ servername, wildname })`. | At the very least you have to implement `find({ servername })`. | ||||||
|  | 
 | ||||||
|  | Since this is a very common use case, it's supported out of the box as part of the default manager plugin: | ||||||
| 
 | 
 | ||||||
| ```js | ```js | ||||||
| var greenlock = Greenlock.create({ | var greenlock = Greenlock.create({ | ||||||
|     packageAgent: pkg.name + '/' + pkg.version, |     packageAgent: pkg.name + '/' + pkg.version, | ||||||
|     maintainerEmail: 'jon@example.com', |     maintainerEmail: 'jon@example.com', | ||||||
|     notify: notify, |     notify: notify, | ||||||
| 
 |     find: find | ||||||
|     packageRoot: __dirname, |  | ||||||
|     manager: { |  | ||||||
|         module: './manager.js' |  | ||||||
|     } |  | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
|  | // In the simplest case you can ignore all incoming options | ||||||
|  | // and return a single site config in the same format as the config file | ||||||
|  | 
 | ||||||
|  | function find(options) { | ||||||
|  |     var servername = options.servername; // www.example.com | ||||||
|  |     var wildname = options.wildname; // *.example.com | ||||||
|  |     return Promise.resolve([ | ||||||
|  |         { subject: 'example.com', altnames: ['example.com', 'www.example.com'] } | ||||||
|  |     ]); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| function notify(ev, args) { | function notify(ev, args) { | ||||||
|     if ('error' === ev || 'warning' === ev) { |     if ('error' === ev || 'warning' === ev) { | ||||||
|         console.error(ev, args); |         console.error(ev, args); | ||||||
| @ -311,61 +288,102 @@ function notify(ev, args) { | |||||||
| } | } | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| In the simplest case you can ignore all incoming options | If you want to use wildcards or local domains, you must specify the `dns-01` challenge plugin to use: | ||||||
| and return a single site config in the same format as the config file |  | ||||||
| 
 | 
 | ||||||
| `./manager.js`: | ```js | ||||||
|  | function find(options) { | ||||||
|  |     var subject = options.subject; | ||||||
|  |     // may include wildcard | ||||||
|  |     var altnames = options.altnames; | ||||||
|  |     var wildname = options.wildname; // *.example.com | ||||||
|  |     return Promise.resolve([ | ||||||
|  |         { | ||||||
|  |             subject: 'example.com', | ||||||
|  |             altnames: ['example.com', 'www.example.com'], | ||||||
|  |             challenges: { | ||||||
|  |                 'dns-01': { module: 'acme-dns-01-namedotcom', apikey: 'xxxx' } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     ]); | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### Customer Manager, complete | ||||||
|  | 
 | ||||||
|  | To use a fully custom manager, you give the npm package name, or absolute path to the file to load | ||||||
|  | 
 | ||||||
|  | ```js | ||||||
|  | Greenlock.create({ | ||||||
|  |     // Greenlock Options | ||||||
|  |     maintainerEmail: 'jon@example.com', | ||||||
|  |     packageAgent: 'my-package/v2.1.1', | ||||||
|  |     notify: notify, | ||||||
|  | 
 | ||||||
|  |     // file path or npm package name | ||||||
|  |     manager: '/path/to/manager.js', | ||||||
|  |     // options that get passed to the manager | ||||||
|  |     myFooOption: 'whatever' | ||||||
|  | }); | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | The manager itself is, again relatively simple: | ||||||
|  | 
 | ||||||
|  | -   find(options) | ||||||
|  | -   set(siteConfig) | ||||||
|  | -   remove(options) | ||||||
|  | -   defaults(globalOptions) (as setter) | ||||||
|  |     -   defaults() => globalOptions (as getter) | ||||||
|  | 
 | ||||||
|  | `/path/to/manager.js`: | ||||||
| 
 | 
 | ||||||
| ```js | ```js | ||||||
| 'use strict'; | 'use strict'; | ||||||
| 
 | 
 | ||||||
| module.exports.create = function() { | module.exports.create = function() { | ||||||
|     return { |     var manager = {}; | ||||||
|         get: async function({ servername }) { |  | ||||||
|             // do something to fetch the site |  | ||||||
|             var site = { |  | ||||||
|                 subject: 'example.com', |  | ||||||
|                 altnames: ['example.com', 'www.example.com'] |  | ||||||
|             }; |  | ||||||
| 
 | 
 | ||||||
|             return site; |     manager.find = async function({ subject, altnames, renewBefore }) { | ||||||
|  |         if (subject) { | ||||||
|  |             return getSiteConfigBySubject(subject); | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|  |         if (altnames) { | ||||||
|  |             // may include wildcards | ||||||
|  |             return getSiteConfigByAnyAltname(altnames); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if (renewBefore) { | ||||||
|  |             return getSiteConfigsWhereRenewAtIsLessThan(renewBefore); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return []; | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     manage.set = function(opts) { | ||||||
|  |         // this is called by greenlock.add({ subject, altnames }) | ||||||
|  |         // it's also called by greenlock._update({ subject, renewAt }) | ||||||
|  | 
 | ||||||
|  |         return mergSiteConfig(subject, opts); | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     manage.remove = function({ subject, altname }) { | ||||||
|  |         if (subject) { | ||||||
|  |             return removeSiteConfig(subject); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return removeFromSiteConfigAndResetRenewAtToZero(altname); | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     // set the global config | ||||||
|  |     manage.defaults = function(options) { | ||||||
|  |         if (!options) { | ||||||
|  |             return getGlobalConfig(); | ||||||
|  |         } | ||||||
|  |         return mergeGlobalConfig(options); | ||||||
|     }; |     }; | ||||||
| }; | }; | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| If you want to use wildcards or local domains for a specific domain, you must specify the `dns-01` challenge plugin to use: |  | ||||||
| 
 |  | ||||||
| ```js |  | ||||||
| 'use strict'; |  | ||||||
| 
 |  | ||||||
| module.exports.create = function() { |  | ||||||
|     return { |  | ||||||
|         get: async function({ servername }) { |  | ||||||
|             // do something to fetch the site |  | ||||||
|             var site = { |  | ||||||
|                 subject: 'example.com', |  | ||||||
|                 altnames: ['example.com', 'www.example.com'], |  | ||||||
| 
 |  | ||||||
|                 // dns-01 challenge |  | ||||||
|                 challenges: { |  | ||||||
|                     'dns-01': { |  | ||||||
|                         module: 'acme-dns-01-namedotcom', |  | ||||||
|                         apikey: 'xxxx' |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             }; |  | ||||||
| 
 |  | ||||||
|             return site; |  | ||||||
|         } |  | ||||||
|     }; |  | ||||||
| }; |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| ### Customer Manager, Complete |  | ||||||
| 
 |  | ||||||
| See <https://git.rootprojects.org/root/greenlock-manager-test.js#quick-start> |  | ||||||
| 
 |  | ||||||
| # ACME Challenge Plugins | # ACME Challenge Plugins | ||||||
| 
 | 
 | ||||||
| The ACME challenge plugins are just a few simple callbacks: | The ACME challenge plugins are just a few simple callbacks: | ||||||
| @ -401,3 +419,99 @@ They are described here: | |||||||
| -   [greenlock store documentation](https://git.rootprojects.org/root/greenlock-store-test.js) | -   [greenlock store documentation](https://git.rootprojects.org/root/greenlock-store-test.js) | ||||||
| 
 | 
 | ||||||
| If you are just implenting in-house and are not going to publish a module, you can also do some hack things like this: | If you are just implenting in-house and are not going to publish a module, you can also do some hack things like this: | ||||||
|  | 
 | ||||||
|  | ### Custome Store, The hacky / lazy way | ||||||
|  | 
 | ||||||
|  | `/path/to/project/my-hacky-store.js`: | ||||||
|  | 
 | ||||||
|  | ```js | ||||||
|  | 'use strict'; | ||||||
|  | 
 | ||||||
|  | module.exports.create = function(options) { | ||||||
|  |     // ex: /path/to/account.ecdsa.jwk.json | ||||||
|  |     var accountJwk = require(options.accountJwkPath); | ||||||
|  |     // ex: /path/to/privkey.rsa.pem | ||||||
|  |     var serverPem = fs.readFileSync(options.serverPemPath, 'ascii'); | ||||||
|  |     var accounts = {}; | ||||||
|  |     var certificates = {}; | ||||||
|  |     var store = { accounts, certificates }; | ||||||
|  | 
 | ||||||
|  |     // bare essential account callbacks | ||||||
|  |     accounts.checkKeypair = function() { | ||||||
|  |         // ignore all options and just return a single, global keypair | ||||||
|  | 
 | ||||||
|  |         return Promise.resolve({ | ||||||
|  |             privateKeyJwk: accountJwk | ||||||
|  |         }); | ||||||
|  |     }; | ||||||
|  |     accounts.setKeypair = function() { | ||||||
|  |         // this will never get called if checkKeypair always returns | ||||||
|  | 
 | ||||||
|  |         return Promise.resolve({}); | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     // bare essential cert and key callbacks | ||||||
|  |     certificates.checkKeypair = function() { | ||||||
|  |         // ignore all options and just return a global server keypair | ||||||
|  | 
 | ||||||
|  |         return { | ||||||
|  |             privateKeyPem: serverPem | ||||||
|  |         }; | ||||||
|  |     }; | ||||||
|  |     certificates.setKeypair = function() { | ||||||
|  |         // never gets called if checkKeypair always returns an existing key | ||||||
|  | 
 | ||||||
|  |         return Promise.resolve(null); | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     certificates.check = function(args) { | ||||||
|  |         var subject = args.subject; | ||||||
|  |         // make a database call or whatever to get a certificate | ||||||
|  |         return goGetCertBySubject(subject).then(function() { | ||||||
|  |             return { | ||||||
|  |                 pems: { | ||||||
|  |                     chain: '<PEM>', | ||||||
|  |                     cert: '<PEM>' | ||||||
|  |                 } | ||||||
|  |             }; | ||||||
|  |         }); | ||||||
|  |     }; | ||||||
|  |     certificates.set = function(args) { | ||||||
|  |         var subject = args.subject; | ||||||
|  |         var cert = args.pems.cert; | ||||||
|  |         var chain = args.pems.chain; | ||||||
|  | 
 | ||||||
|  |         // make a database call or whatever to get a certificate | ||||||
|  |         return goSaveCert({ | ||||||
|  |             subject, | ||||||
|  |             cert, | ||||||
|  |             chain | ||||||
|  |         }); | ||||||
|  |     }; | ||||||
|  | }; | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### Using the hacky / lazy store plugin | ||||||
|  | 
 | ||||||
|  | That sort of implementation won't pass the test suite, but it'll work just fine a use case where you only have one subscriber email (most of the time), | ||||||
|  | you only have one server key (not recommended, but works), and you only really want to worry about storing cetificates. | ||||||
|  | 
 | ||||||
|  | Then you could assign it as the default for all of your sites: | ||||||
|  | 
 | ||||||
|  | ```json | ||||||
|  | { | ||||||
|  |     "subscriberEmail": "jon@example.com", | ||||||
|  |     "agreeToTerms": true, | ||||||
|  |     "sites": { | ||||||
|  |         "example.com": { | ||||||
|  |             "subject": "example.com", | ||||||
|  |             "altnames": ["example.com", "www.example.com"] | ||||||
|  |         } | ||||||
|  |     }, | ||||||
|  |     "store": { | ||||||
|  |         "module": "/path/to/project/my-hacky-store.js", | ||||||
|  |         "accountJwkPath": "/path/to/account.ecdsa.jwk.json", | ||||||
|  |         "serverPemPath": "/path/to/privkey.rsa.pem" | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | ``` | ||||||
							
								
								
									
										16
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								README.md
									
									
									
									
									
								
							| @ -1,10 +1,12 @@ | |||||||
| # New Documentation & [v4 Migration Guide](https://git.rootprojects.org/root/greenlock.js/src/branch/master/MIGRATION_GUIDE.md) | # New Documentation & [v2/v3 Migration Guide](https://git.rootprojects.org/root/greenlock.js/src/branch/v3/MIGRATION_GUIDE_V2_V3.md) | ||||||
|  | 
 | ||||||
|  | Greenlock v3 was just released from private beta **today** (Nov 1st, 2019). | ||||||
| 
 | 
 | ||||||
| We're still working on the full documentation for this new version, | We're still working on the full documentation for this new version, | ||||||
| so please be patient. | so please be patient. | ||||||
| 
 | 
 | ||||||
| To start, check out the | To start, check out the | ||||||
| [Migration Guide](https://git.rootprojects.org/root/greenlock.js/src/branch/master/MIGRATION_GUIDE.md). | [Migration Guide](https://git.rootprojects.org/root/greenlock.js/src/branch/v3/MIGRATION_GUIDE_V2_V3.md). | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
| 
 | 
 | ||||||
| @ -83,10 +85,12 @@ Certificates are renewed every 45 days by default, and renewal checks will happe | |||||||
| var pkg = require('./package.json'); | var pkg = require('./package.json'); | ||||||
| var Greenlock = require('greenlock'); | var Greenlock = require('greenlock'); | ||||||
| var greenlock = Greenlock.create({ | var greenlock = Greenlock.create({ | ||||||
|     configDir: './greenlock.d/config.json', |  | ||||||
|     packageAgent: pkg.name + '/' + pkg.version, |     packageAgent: pkg.name + '/' + pkg.version, | ||||||
|     maintainerEmail: pkg.author, |     maintainerEmail: pkg.author, | ||||||
|     staging: true, |     staging: true, | ||||||
|  |     manager: require('greenlock-manager-fs').create({ | ||||||
|  |         configFile: '~/.config/greenlock/manager.json' | ||||||
|  |     }), | ||||||
|     notify: function(event, details) { |     notify: function(event, details) { | ||||||
|         if ('error' === event) { |         if ('error' === event) { | ||||||
|             // `details` is an error object in this case |             // `details` is an error object in this case | ||||||
| @ -167,7 +171,7 @@ greenlock | |||||||
| --> | --> | ||||||
| 
 | 
 | ||||||
| <details> | <details> | ||||||
| <summary>Greenlock.create({ configDir, packageAgent, maintainerEmail, staging })</summary> | <summary>Greenlock.create({ packageAgent, maintainerEmail, staging })</summary> | ||||||
| 
 | 
 | ||||||
| ## Greenlock.create() | ## Greenlock.create() | ||||||
| 
 | 
 | ||||||
| @ -177,15 +181,12 @@ Creates an instance of greenlock with _environment_-level values. | |||||||
| 
 | 
 | ||||||
| var pkg = require('./package.json'); | var pkg = require('./package.json'); | ||||||
| var gl = Greenlock.create({ | var gl = Greenlock.create({ | ||||||
|     configDir: './greenlock.d/config.json', |  | ||||||
| 
 |  | ||||||
|     // Staging for testing environments |     // Staging for testing environments | ||||||
|     staging: true, |     staging: true, | ||||||
| 
 | 
 | ||||||
|     // This should be the contact who receives critical bug and security notifications |     // This should be the contact who receives critical bug and security notifications | ||||||
|     // Optionally, you may receive other (very few) updates, such as important new features |     // Optionally, you may receive other (very few) updates, such as important new features | ||||||
|     maintainerEmail: 'jon@example.com', |     maintainerEmail: 'jon@example.com', | ||||||
| 
 |  | ||||||
|     // for an RFC 8555 / RFC 7231 ACME client user agent |     // for an RFC 8555 / RFC 7231 ACME client user agent | ||||||
|     packageAgent: pkg.name + '/' pkg.version |     packageAgent: pkg.name + '/' pkg.version | ||||||
| }); | }); | ||||||
| @ -193,7 +194,6 @@ var gl = Greenlock.create({ | |||||||
| 
 | 
 | ||||||
| | Parameter       | Description                                                                          | | | Parameter       | Description                                                                          | | ||||||
| | --------------- | ------------------------------------------------------------------------------------ | | | --------------- | ------------------------------------------------------------------------------------ | | ||||||
| | configDir       | the directory to use for file-based plugins                                          | |  | ||||||
| | maintainerEmail | the developer contact for critical bug and security notifications                    | | | maintainerEmail | the developer contact for critical bug and security notifications                    | | ||||||
| | packageAgent    | if you publish your package for others to use, `require('./package.json').name` here | | | packageAgent    | if you publish your package for others to use, `require('./package.json').name` here | | ||||||
| | staging         | use the Let's Encrypt staging URL instead of the production URL                      | | | staging         | use the Let's Encrypt staging URL instead of the production URL                      | | ||||||
|  | |||||||
							
								
								
									
										34
									
								
								greenlock.js
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								greenlock.js
									
									
									
									
									
								
							| @ -55,6 +55,15 @@ G.create = function(gconf) { | |||||||
|             gdefaults.notify = _notify; |             gdefaults.notify = _notify; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         /* | ||||||
|  |         if (!gconf.packageRoot) { | ||||||
|  |             gconf.packageRoot = process.cwd(); | ||||||
|  |             console.warn( | ||||||
|  |                 '`packageRoot` not defined, trying ' + gconf.packageRoot | ||||||
|  |             ); | ||||||
|  |         } | ||||||
|  |         */ | ||||||
|  | 
 | ||||||
|         gconf = Init._init(gconf); |         gconf = Init._init(gconf); | ||||||
| 
 | 
 | ||||||
|         // OK: /path/to/blah
 |         // OK: /path/to/blah
 | ||||||
| @ -62,12 +71,6 @@ G.create = function(gconf) { | |||||||
|         // NOT OK: ./rel/path/to/blah
 |         // NOT OK: ./rel/path/to/blah
 | ||||||
|         // Error: .blah
 |         // Error: .blah
 | ||||||
|         if ('.' === (gconf.manager.module || '')[0]) { |         if ('.' === (gconf.manager.module || '')[0]) { | ||||||
|             if (!gconf.packageRoot) { |  | ||||||
|                 gconf.packageRoot = process.cwd(); |  | ||||||
|                 console.warn( |  | ||||||
|                     '`packageRoot` not defined, trying ' + gconf.packageRoot |  | ||||||
|                 ); |  | ||||||
|             } |  | ||||||
|             gconf.manager.module = |             gconf.manager.module = | ||||||
|                 gconf.packageRoot + '/' + gconf.manager.module.slice(2); |                 gconf.packageRoot + '/' + gconf.manager.module.slice(2); | ||||||
|         } |         } | ||||||
| @ -423,23 +426,14 @@ G.create = function(gconf) { | |||||||
|         storeConf = JSON.parse(JSON.stringify(storeConf)); |         storeConf = JSON.parse(JSON.stringify(storeConf)); | ||||||
|         storeConf.packageRoot = gconf.packageRoot; |         storeConf.packageRoot = gconf.packageRoot; | ||||||
| 
 | 
 | ||||||
|  |         var path = require('path'); | ||||||
|         if (!storeConf.basePath) { |         if (!storeConf.basePath) { | ||||||
|             storeConf.basePath = gconf.configDir; |             storeConf.basePath = gconf.configDir; | ||||||
|         } |         } | ||||||
| 
 |         storeConf.basePath = path.resolve( | ||||||
|         if ('.' === (storeConf.basePath || '')[0]) { |             gconf.packageRoot || process.cwd(), | ||||||
|             if (!gconf.packageRoot) { |             storeConf.basePath | ||||||
|                 gconf.packageRoot = process.cwd(); |         ); | ||||||
|                 console.warn( |  | ||||||
|                     '`packageRoot` not defined, trying ' + gconf.packageRoot |  | ||||||
|                 ); |  | ||||||
|             } |  | ||||||
|             storeConf.basePath = require('path').resolve( |  | ||||||
|                 gconf.packageRoot || '', |  | ||||||
|                 storeConf.basePath |  | ||||||
|             ); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         storeConf.directoryUrl = dirUrl; |         storeConf.directoryUrl = dirUrl; | ||||||
|         var store = await P._loadStore(storeConf); |         var store = await P._loadStore(storeConf); | ||||||
|         var account = await A._getOrCreate( |         var account = await A._getOrCreate( | ||||||
|  | |||||||
| @ -492,46 +492,8 @@ function mergeManager(gconf) { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (mini.get) { |     if (mini.get) { | ||||||
|         mega.get = async function(opts) { |         mega.get = function(opts) { | ||||||
|             if (mini.set) { |             return mini.get(opts); | ||||||
|                 return mini.get(opts); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             if (!mega._get) { |  | ||||||
|                 mega._get = m().get; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             var existing = await mega._get(opts); |  | ||||||
|             var site = await mini.get(opts); |  | ||||||
|             if (!existing) { |  | ||||||
|                 // Add
 |  | ||||||
|                 if (!site) { |  | ||||||
|                     return; |  | ||||||
|                 } |  | ||||||
|                 site.renewAt = 1; |  | ||||||
|                 site.deletedAt = 0; |  | ||||||
|                 await mega.set(site); |  | ||||||
|                 existing = await mega._get(opts); |  | ||||||
|             } else if (!site) { |  | ||||||
|                 // Delete
 |  | ||||||
|                 existing.deletedAt = site.deletedAt || Date.now(); |  | ||||||
|                 await mega.set(existing); |  | ||||||
|                 existing = null; |  | ||||||
|             } else if ( |  | ||||||
|                 site.subject !== existing.subject || |  | ||||||
|                 site.altnames.join(' ') !== existing.altnames.join(' ') |  | ||||||
|             ) { |  | ||||||
|                 // Update
 |  | ||||||
|                 site.renewAt = 1; |  | ||||||
|                 site.deletedAt = 0; |  | ||||||
|                 await mega.set(site); |  | ||||||
|                 existing = await mega._get(opts); |  | ||||||
|                 if (!existing) { |  | ||||||
|                     throw new Error('failed to `get` after `set`'); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             return existing; |  | ||||||
|         }; |         }; | ||||||
|     } else if (mini.find) { |     } else if (mini.find) { | ||||||
|         mega.get = function(opts) { |         mega.get = function(opts) { | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user