mirror of
				https://github.com/therootcompany/greenlock.js.git
				synced 2024-11-16 17:29:00 +00:00 
			
		
		
		
	Compare commits
	
		
			12 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| f01286d5b1 | |||
| aea967e210 | |||
| 89e2fec39f | |||
|  | 1a60d53c32 | ||
| 6dc711b880 | |||
| d78e437ec0 | |||
| 6df8692385 | |||
| 8ab7ad25f2 | |||
| 8c11b56aa9 | |||
| 18e39905ba | |||
| f913f8d193 | |||
| 08743cc6ba | 
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -1,5 +1,5 @@ | |||||||
| greenlock.json* | greenlock.json* | ||||||
| TODO.txt | TODO* | ||||||
| link.sh | link.sh | ||||||
| .env | .env | ||||||
| .greenlockrc | .greenlockrc | ||||||
|  | |||||||
| @ -1,4 +1,36 @@ | |||||||
| # Migrating from Greenlock v2 to v3 | # Migrating Guide | ||||||
|  | 
 | ||||||
|  | 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. | ||||||
| 
 | 
 | ||||||
| @ -195,11 +227,11 @@ as well as a set of callbacks for easy configurability. | |||||||
| 
 | 
 | ||||||
| ### Default Manager | ### Default Manager | ||||||
| 
 | 
 | ||||||
| The default manager is `greenlock-manager-fs` and the default `configFile` is `~/.config/greenlock/manager.json`. | The default manager is `@greenlock/manager` and the default `configDir` is `./.greenlock.d`. | ||||||
| 
 | 
 | ||||||
| The config file should look something like this: | The config file should look something like this: | ||||||
| 
 | 
 | ||||||
| `~/.config/greenlock/manager.json`: | `./greenlock.d/config.json`: | ||||||
| 
 | 
 | ||||||
| ```json | ```json | ||||||
| { | { | ||||||
| @ -256,28 +288,19 @@ 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 `find({ servername })`. | At the very least you have to implement `get({ servername, wildname })`. | ||||||
| 
 |  | ||||||
| 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 |  | ||||||
| }); |  | ||||||
| 
 | 
 | ||||||
| // In the simplest case you can ignore all incoming options |     packageRoot: __dirname, | ||||||
| // and return a single site config in the same format as the config file |     manager: { | ||||||
| 
 |         module: './manager.js' | ||||||
| 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) { | ||||||
| @ -288,102 +311,61 @@ function notify(ev, args) { | |||||||
| } | } | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| If you want to use wildcards or local domains, you must specify the `dns-01` challenge plugin to use: | In the simplest case you can ignore all incoming options | ||||||
|  | and return a single site config in the same format as the config file | ||||||
| 
 | 
 | ||||||
| ```js | `./manager.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() { | ||||||
|     var manager = {}; |     return { | ||||||
| 
 |         get: async function({ servername }) { | ||||||
|     manager.find = async function({ subject, altnames, renewBefore }) { |             // do something to fetch the site | ||||||
|         if (subject) { |             var site = { | ||||||
|             return getSiteConfigBySubject(subject); |                 subject: 'example.com', | ||||||
|         } |                 altnames: ['example.com', 'www.example.com'] | ||||||
| 
 |  | ||||||
|         if (altnames) { |  | ||||||
|             // may include wildcards |  | ||||||
|             return getSiteConfigByAnyAltname(altnames); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (renewBefore) { |  | ||||||
|             return getSiteConfigsWhereRenewAtIsLessThan(renewBefore); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return []; |  | ||||||
|             }; |             }; | ||||||
| 
 | 
 | ||||||
|     manage.set = function(opts) { |             return site; | ||||||
|         // 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: | ||||||
| @ -419,99 +401,3 @@ 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" |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| ``` |  | ||||||
							
								
								
									
										21
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								README.md
									
									
									
									
									
								
							| @ -1,12 +1,10 @@ | |||||||
| # New Documentation & [v2/v3 Migration Guide](https://git.rootprojects.org/root/greenlock.js/src/branch/v3/MIGRATION_GUIDE_V2_V3.md) | # New Documentation & [v4 Migration Guide](https://git.rootprojects.org/root/greenlock.js/src/branch/master/MIGRATION_GUIDE.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/v3/MIGRATION_GUIDE_V2_V3.md). | [Migration Guide](https://git.rootprojects.org/root/greenlock.js/src/branch/master/MIGRATION_GUIDE.md). | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
| 
 | 
 | ||||||
| @ -85,12 +83,11 @@ 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({ | ||||||
|  |     packageRoot: __dirname, | ||||||
|  |     configDir: "./greenlock.d/", | ||||||
|     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 | ||||||
| @ -171,7 +168,7 @@ greenlock | |||||||
| --> | --> | ||||||
| 
 | 
 | ||||||
| <details> | <details> | ||||||
| <summary>Greenlock.create({ packageAgent, maintainerEmail, staging })</summary> | <summary>Greenlock.create({ configDir, packageAgent, maintainerEmail, staging })</summary> | ||||||
| 
 | 
 | ||||||
| ## Greenlock.create() | ## Greenlock.create() | ||||||
| 
 | 
 | ||||||
| @ -181,12 +178,15 @@ 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/', | ||||||
|  | 
 | ||||||
|     // 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 | ||||||
| }); | }); | ||||||
| @ -194,6 +194,7 @@ 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                      | | ||||||
| @ -402,8 +403,8 @@ Greenlock comes with reasonable defaults but when you install it, | |||||||
| you should also install any plugins that you need. | you should also install any plugins that you need. | ||||||
| 
 | 
 | ||||||
| ```bash | ```bash | ||||||
| npm install --save @root/greenlock | npm install --save @root/greenlock@v4 | ||||||
| npm install --save greenlock-manager-fs | npm install --save @greenlock/manager | ||||||
| npm install --save greenlock-store-fs | npm install --save greenlock-store-fs | ||||||
| npm install --save acme-http-01-standalone | npm install --save acme-http-01-standalone | ||||||
| ``` | ``` | ||||||
|  | |||||||
| @ -5,14 +5,20 @@ var args = process.argv.slice(2); | |||||||
| var arg0 = args[0]; | var arg0 = args[0]; | ||||||
| //console.log(args);
 | //console.log(args);
 | ||||||
| 
 | 
 | ||||||
| var found = ['certonly', 'add', 'update', 'config', 'defaults', 'remove', 'init'].some( | var found = [ | ||||||
|     function(k) { |     'certonly', | ||||||
|  |     'add', | ||||||
|  |     'update', | ||||||
|  |     'config', | ||||||
|  |     'defaults', | ||||||
|  |     'remove', | ||||||
|  |     'init' | ||||||
|  | ].some(function(k) { | ||||||
|     if (k === arg0) { |     if (k === arg0) { | ||||||
|         require('./' + k); |         require('./' + k); | ||||||
|         return true; |         return true; | ||||||
|     } |     } | ||||||
|     } | }); | ||||||
| ); |  | ||||||
| 
 | 
 | ||||||
| if (!found) { | if (!found) { | ||||||
|     console.error(arg0 + ': command not yet implemented'); |     console.error(arg0 + ': command not yet implemented'); | ||||||
|  | |||||||
| @ -36,6 +36,9 @@ cli.main(async function(argList, flags) { | |||||||
|     flags.manager.module = manager; |     flags.manager.module = manager; | ||||||
| 
 | 
 | ||||||
|     try { |     try { | ||||||
|  |         if ('.' === String(manager)[0]) { | ||||||
|  |             manager = require('path').resolve(pkgRoot, manager); | ||||||
|  |         } | ||||||
|         P._loadSync(manager); |         P._loadSync(manager); | ||||||
|     } catch (e) { |     } catch (e) { | ||||||
|         try { |         try { | ||||||
|  | |||||||
| @ -14,7 +14,7 @@ require('greenlock-express') | |||||||
|             // contact for security and critical bug notices
 |             // contact for security and critical bug notices
 | ||||||
|             //maintainerEmail: pkg.author,
 |             //maintainerEmail: pkg.author,
 | ||||||
| 
 | 
 | ||||||
|             // contact for security and critical bug notices
 |             // where to look for configuration
 | ||||||
|             configDir: './greenlock.d', |             configDir: './greenlock.d', | ||||||
| 
 | 
 | ||||||
|             // whether or not to run at cloudscale
 |             // whether or not to run at cloudscale
 | ||||||
|  | |||||||
| @ -9,7 +9,7 @@ require('greenlock-express') | |||||||
|         // contact for security and critical bug notices
 |         // contact for security and critical bug notices
 | ||||||
|         //maintainerEmail: pkg.author,
 |         //maintainerEmail: pkg.author,
 | ||||||
| 
 | 
 | ||||||
|         // contact for security and critical bug notices
 |         // where to look for configuration
 | ||||||
|         configDir: './greenlock.d', |         configDir: './greenlock.d', | ||||||
| 
 | 
 | ||||||
|         // whether or not to run at cloudscale
 |         // whether or not to run at cloudscale
 | ||||||
|  | |||||||
							
								
								
									
										30
									
								
								greenlock.js
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								greenlock.js
									
									
									
									
									
								
							| @ -55,15 +55,6 @@ 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
 | ||||||
| @ -71,6 +62,12 @@ 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); | ||||||
|         } |         } | ||||||
| @ -426,14 +423,23 @@ 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( | 
 | ||||||
|             gconf.packageRoot || process.cwd(), |         if ('.' === (storeConf.basePath || '')[0]) { | ||||||
|  |             if (!gconf.packageRoot) { | ||||||
|  |                 gconf.packageRoot = process.cwd(); | ||||||
|  |                 console.warn( | ||||||
|  |                     '`packageRoot` not defined, trying ' + gconf.packageRoot | ||||||
|  |                 ); | ||||||
|  |             } | ||||||
|  |             storeConf.basePath = require('path').resolve( | ||||||
|  |                 gconf.packageRoot || '', | ||||||
|                 storeConf.basePath |                 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( | ||||||
|  | |||||||
| @ -124,8 +124,10 @@ Init._init = function(opts) { | |||||||
|         ); |         ); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     //var mkdirp = promisify(require("@root/mkdirp"));
 |     opts.configFile = path.join( | ||||||
|     opts.configFile = path.join(opts.configDir, 'config.json'); |         path.resolve(opts.packageRoot, opts.configDir), | ||||||
|  |         'config.json' | ||||||
|  |     ); | ||||||
|     var config; |     var config; | ||||||
|     try { |     try { | ||||||
|         config = JSON.parse(fs.readFileSync(opts.configFile)); |         config = JSON.parse(fs.readFileSync(opts.configFile)); | ||||||
|  | |||||||
| @ -12,13 +12,25 @@ module.exports.wrap = function(greenlock, gconf) { | |||||||
|     var myFind = gconf.find; |     var myFind = gconf.find; | ||||||
|     delete gconf.find; |     delete gconf.find; | ||||||
| 
 | 
 | ||||||
|     var mega = mergeManager(gconf); |     var mega = mergeManager(greenlock, gconf); | ||||||
| 
 | 
 | ||||||
|     greenlock.manager = {}; |     greenlock.manager = {}; | ||||||
|     greenlock.sites = {}; |     greenlock.sites = {}; | ||||||
|     //greenlock.accounts = {};
 |     //greenlock.accounts = {};
 | ||||||
|     //greenlock.certs = {};
 |     //greenlock.certs = {};
 | ||||||
| 
 | 
 | ||||||
|  |     greenlock.manager._modulename = gconf.manager.module; | ||||||
|  |     if ('/' === String(gconf.manager.module)[0]) { | ||||||
|  |         greenlock.manager._modulename = require('path').relative( | ||||||
|  |             gconf.packageRoot, | ||||||
|  |             greenlock.manager._modulename | ||||||
|  |         ); | ||||||
|  |         if ('.' !== String(greenlock.manager._modulename)[0]) { | ||||||
|  |             greenlock.manager._modulename = | ||||||
|  |                 './' + greenlock.manager._modulename; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     var allowed = [ |     var allowed = [ | ||||||
|         'accountKeyType', //: ["P-256", "RSA-2048"],
 |         'accountKeyType', //: ["P-256", "RSA-2048"],
 | ||||||
|         'serverKeyType', //: ["RSA-2048", "P-256"],
 |         'serverKeyType', //: ["RSA-2048", "P-256"],
 | ||||||
| @ -409,6 +421,7 @@ function loadManager(gconf) { | |||||||
|         ); |         ); | ||||||
|     } |     } | ||||||
|     */ |     */ | ||||||
|  | 
 | ||||||
|     try { |     try { | ||||||
|         // wrap this to be safe for @greenlock/manager
 |         // wrap this to be safe for @greenlock/manager
 | ||||||
|         m = require(gconf.manager.module).create(gconf.manager); |         m = require(gconf.manager.module).create(gconf.manager); | ||||||
| @ -431,7 +444,7 @@ function loadManager(gconf) { | |||||||
|     return m; |     return m; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function mergeManager(gconf) { | function mergeManager(greenlock, gconf) { | ||||||
|     var mng; |     var mng; | ||||||
|     function m() { |     function m() { | ||||||
|         if (mng) { |         if (mng) { | ||||||
| @ -492,8 +505,46 @@ function mergeManager(gconf) { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (mini.get) { |     if (mini.get) { | ||||||
|         mega.get = function(opts) { |         mega.get = async 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) { | ||||||
| @ -516,6 +567,21 @@ function mergeManager(gconf) { | |||||||
|         mega.get = m().get; |         mega.get = m().get; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     if (!mega.find) { | ||||||
|  |         mega._nofind = false; | ||||||
|  |         mega.find = async function(opts) { | ||||||
|  |             if (!mega._nofind) { | ||||||
|  |                 console.warn( | ||||||
|  |                     'Warning: manager `' + | ||||||
|  |                         greenlock.manager._modulename + | ||||||
|  |                         '` does not implement `find({})`\n' | ||||||
|  |                 ); | ||||||
|  |                 mega._nofind = true; | ||||||
|  |             } | ||||||
|  |             return []; | ||||||
|  |         }; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     if (!mega.get) { |     if (!mega.get) { | ||||||
|         mega.get = function(opts) { |         mega.get = function(opts) { | ||||||
|             var servername = opts.servername; |             var servername = opts.servername; | ||||||
|  | |||||||
							
								
								
									
										32
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										32
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @ -1,6 +1,6 @@ | |||||||
| { | { | ||||||
|     "name": "@root/greenlock", |     "name": "@root/greenlock", | ||||||
|     "version": "4.0.0", |     "version": "4.0.5", | ||||||
|     "lockfileVersion": 1, |     "lockfileVersion": 1, | ||||||
|     "requires": true, |     "requires": true, | ||||||
|     "dependencies": { |     "dependencies": { | ||||||
| @ -24,15 +24,23 @@ | |||||||
|             } |             } | ||||||
|         }, |         }, | ||||||
|         "@root/acme": { |         "@root/acme": { | ||||||
|             "version": "3.0.8", |             "version": "3.1.0", | ||||||
|             "resolved": "https://registry.npmjs.org/@root/acme/-/acme-3.0.8.tgz", |             "resolved": "https://registry.npmjs.org/@root/acme/-/acme-3.1.0.tgz", | ||||||
|             "integrity": "sha512-VmBvLvWdCDkolkanI9Dzm1ouSWPaAa2eCCwcDZcVQbWoNiUIOqbbd57fcMA/gZxLyuJPStD2WXFuEuSMPDxcww==", |             "integrity": "sha512-GAyaW63cpSYd2KvVp5lHLbCWeEhJPKZK9nsJvZJOKsD9Uv88KEttn4FpDZEJ+2q3Jsey0DWpuQ2I4ft0JV9p2w==", | ||||||
|             "requires": { |             "requires": { | ||||||
|  |                 "@root/csr": "^0.8.1", | ||||||
|                 "@root/encoding": "^1.0.1", |                 "@root/encoding": "^1.0.1", | ||||||
|                 "@root/keypairs": "^0.9.0", |                 "@root/keypairs": "^0.10.0", | ||||||
|                 "@root/pem": "^1.0.4", |                 "@root/pem": "^1.0.4", | ||||||
|                 "@root/request": "^1.3.11", |                 "@root/request": "^1.6.1", | ||||||
|                 "@root/x509": "^0.7.2" |                 "@root/x509": "^0.7.2" | ||||||
|  |             }, | ||||||
|  |             "dependencies": { | ||||||
|  |                 "@root/request": { | ||||||
|  |                     "version": "1.6.1", | ||||||
|  |                     "resolved": "https://registry.npmjs.org/@root/request/-/request-1.6.1.tgz", | ||||||
|  |                     "integrity": "sha512-8wrWyeBLRp7T8J36GkT3RODJ6zYmL0/maWlAUD5LOXT28D3TDquUepyYDKYANNA3Gc8R5ZCgf+AXvSTYpJEWwQ==" | ||||||
|  |                 } | ||||||
|             } |             } | ||||||
|         }, |         }, | ||||||
|         "@root/asn1": { |         "@root/asn1": { | ||||||
| @ -59,9 +67,9 @@ | |||||||
|             "integrity": "sha512-OaEub02ufoU038gy6bsNHQOjIn8nUjGiLcaRmJ40IUykneJkIW5fxDqKxQx48cszuNflYldsJLPPXCrGfHs8yQ==" |             "integrity": "sha512-OaEub02ufoU038gy6bsNHQOjIn8nUjGiLcaRmJ40IUykneJkIW5fxDqKxQx48cszuNflYldsJLPPXCrGfHs8yQ==" | ||||||
|         }, |         }, | ||||||
|         "@root/keypairs": { |         "@root/keypairs": { | ||||||
|             "version": "0.9.0", |             "version": "0.10.0", | ||||||
|             "resolved": "https://registry.npmjs.org/@root/keypairs/-/keypairs-0.9.0.tgz", |             "resolved": "https://registry.npmjs.org/@root/keypairs/-/keypairs-0.10.0.tgz", | ||||||
|             "integrity": "sha512-NXE2L9Gv7r3iC4kB/gTPZE1vO9Ox/p14zDzAJ5cGpTpytbWOlWF7QoHSJbtVX4H7mRG/Hp7HR3jWdWdb2xaaXg==", |             "integrity": "sha512-t8VocY46Mtb0NTsxzyLLf5tsgfw0BXLYVADAyiRdEdqHcvPFGJdjkXNtHVQuSV/FMaC65iTOHVP4E6X8iT3Ikg==", | ||||||
|             "requires": { |             "requires": { | ||||||
|                 "@root/encoding": "^1.0.1", |                 "@root/encoding": "^1.0.1", | ||||||
|                 "@root/pem": "^1.0.4", |                 "@root/pem": "^1.0.4", | ||||||
| @ -79,9 +87,9 @@ | |||||||
|             "integrity": "sha512-rEUDiUsHtild8GfIjFE9wXtcVxeS+ehCJQBwbQQ3IVfORKHK93CFnRtkr69R75lZFjcmKYVc+AXDB+AeRFOULA==" |             "integrity": "sha512-rEUDiUsHtild8GfIjFE9wXtcVxeS+ehCJQBwbQQ3IVfORKHK93CFnRtkr69R75lZFjcmKYVc+AXDB+AeRFOULA==" | ||||||
|         }, |         }, | ||||||
|         "@root/request": { |         "@root/request": { | ||||||
|             "version": "1.4.2", |             "version": "1.6.1", | ||||||
|             "resolved": "https://registry.npmjs.org/@root/request/-/request-1.4.2.tgz", |             "resolved": "https://registry.npmjs.org/@root/request/-/request-1.6.1.tgz", | ||||||
|             "integrity": "sha512-J8FM4+SJuc7WRC+Jz17m+VT2lgI7HtatHhxN1F2ck5aIKUAxJEaR4u/gLBsgT60mVHevKCjKN0O8115UtJjwLw==" |             "integrity": "sha512-8wrWyeBLRp7T8J36GkT3RODJ6zYmL0/maWlAUD5LOXT28D3TDquUepyYDKYANNA3Gc8R5ZCgf+AXvSTYpJEWwQ==" | ||||||
|         }, |         }, | ||||||
|         "@root/x509": { |         "@root/x509": { | ||||||
|             "version": "0.7.2", |             "version": "0.7.2", | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| { | { | ||||||
|     "name": "@root/greenlock", |     "name": "@root/greenlock", | ||||||
|     "version": "4.0.0", |     "version": "4.0.5", | ||||||
|     "description": "The easiest Let's Encrypt client for Node.js and Browsers", |     "description": "The easiest Let's Encrypt client for Node.js and Browsers", | ||||||
|     "homepage": "https://rootprojects.org/greenlock/", |     "homepage": "https://rootprojects.org/greenlock/", | ||||||
|     "main": "greenlock.js", |     "main": "greenlock.js", | ||||||
| @ -39,11 +39,11 @@ | |||||||
|     "license": "MPL-2.0", |     "license": "MPL-2.0", | ||||||
|     "dependencies": { |     "dependencies": { | ||||||
|         "@greenlock/manager": "^3.1.0", |         "@greenlock/manager": "^3.1.0", | ||||||
|         "@root/acme": "^3.0.8", |         "@root/acme": "^3.1.0", | ||||||
|         "@root/csr": "^0.8.1", |         "@root/csr": "^0.8.1", | ||||||
|         "@root/keypairs": "^0.9.0", |         "@root/keypairs": "^0.10.0", | ||||||
|         "@root/mkdirp": "^1.0.0", |         "@root/mkdirp": "^1.0.0", | ||||||
|         "@root/request": "^1.4.2", |         "@root/request": "^1.6.1", | ||||||
|         "acme-http-01-standalone": "^3.0.5", |         "acme-http-01-standalone": "^3.0.5", | ||||||
|         "cert-info": "^1.5.1", |         "cert-info": "^1.5.1", | ||||||
|         "greenlock-store-fs": "^3.2.2", |         "greenlock-store-fs": "^3.2.2", | ||||||
|  | |||||||
| @ -146,7 +146,7 @@ P._normalizeChallenge = function(name, ch) { | |||||||
|         }; |         }; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // init, zones, set, get, remove
 |     // init, zones, set, get, remove, propagationDelay
 | ||||||
|     if (ch.init) { |     if (ch.init) { | ||||||
|         if (2 === ch.init.length) { |         if (2 === ch.init.length) { | ||||||
|             warn(); |             warn(); | ||||||
| @ -183,6 +183,9 @@ P._normalizeChallenge = function(name, ch) { | |||||||
|         } |         } | ||||||
|         gch.get = wrappy(ch.get); |         gch.get = wrappy(ch.get); | ||||||
|     } |     } | ||||||
|  |     if("number" === typeof ch.propagationDelay) { | ||||||
|  |         gch.propagationDelay = ch.propagationDelay; | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     return gch; |     return gch; | ||||||
| }; | }; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user