greenlock-challenge-test => acme-challenge-test, make Prettier
This commit is contained in:
		
							parent
							
								
									33cf5a35bb
								
							
						
					
					
						commit
						d30c59d4c7
					
				
							
								
								
									
										4
									
								
								.prettierrc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								.prettierrc
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,4 @@ | |||||||
|  | { | ||||||
|  |   "trailingComma": "none", | ||||||
|  |   "useTabs": true | ||||||
|  | } | ||||||
							
								
								
									
										20
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								README.md
									
									
									
									
									
								
							| @ -1,4 +1,4 @@ | |||||||
| # [greenlock-challenge-test](https://git.rootprojects.org/root/greenlock-challenge-test.js.git) | A [Root](https://rootprojects.org) Project | # [acme-challenge-test](https://git.rootprojects.org/root/acme-challenge-test.js.git) | A [Root](https://rootprojects.org) Project | ||||||
| 
 | 
 | ||||||
| The test harness you should use when writing an ACME challenge strategy | The test harness you should use when writing an ACME challenge strategy | ||||||
| for [Greenlock](https://git.coolaj86.com/coolaj86/greenlock-express.js) v2.7+ (and v3). | for [Greenlock](https://git.coolaj86.com/coolaj86/greenlock-express.js) v2.7+ (and v3). | ||||||
| @ -12,23 +12,23 @@ that's not something you have to take special consideration for - just pass the | |||||||
| ## Install | ## Install | ||||||
| 
 | 
 | ||||||
| ```bash | ```bash | ||||||
| npm install --save-dev greenlock-challenge-test@3.x | npm install --save-dev acme-challenge-test@3.x | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| ## Usage | ## Usage | ||||||
| 
 | 
 | ||||||
| ```js | ```js | ||||||
| var tester = require('greenlock-challenge-test'); | var tester = require("acme-challenge-test"); | ||||||
| 
 | 
 | ||||||
| //var challenger = require('greenlock-challenge-http').create({}); | //var challenger = require('acme-http-01-cli').create({}); | ||||||
| //var challenger = require('greenlock-challenge-dns').create({}); | //var challenger = require('acme-dns-01-cli').create({}); | ||||||
| var challenger = require('./YOUR-CHALLENGE-STRATEGY').create({}); | var challenger = require("./YOUR-CHALLENGE-STRATEGY").create({}); | ||||||
| 
 | 
 | ||||||
| // The dry-run tests can pass on, literally, 'example.com' | // The dry-run tests can pass on, literally, 'example.com' | ||||||
| // but the integration tests require that you have control over the domain | // but the integration tests require that you have control over the domain | ||||||
| var domain = 'example.com'; | var domain = "example.com"; | ||||||
| 
 | 
 | ||||||
| tester.test('http-01', domain, challenger).then(function () { | tester.test("http-01", domain, challenger).then(function() { | ||||||
| 	console.info("PASS"); | 	console.info("PASS"); | ||||||
| }); | }); | ||||||
| ``` | ``` | ||||||
| @ -38,8 +38,8 @@ tester.test('http-01', domain, challenger).then(function () { | |||||||
| These are plugins that use the v2.7+ (v3) API, and pass this test harness, | These are plugins that use the v2.7+ (v3) API, and pass this test harness, | ||||||
| which you should use as a model for any plugins that you create. | which you should use as a model for any plugins that you create. | ||||||
| 
 | 
 | ||||||
| * [`greenlock-challenge-http`](https://git.rootprojects.org/root/greenlock-challenge-http.js) | - [`acme-http-01-cli`](https://git.rootprojects.org/root/acme-http-01-cli.js) | ||||||
| * [`greenlock-challenge-dns`](https://git.rootprojects.org/root/greenlock-challenge-dns.js) | - [`acme-dns-01-cli`](https://git.rootprojects.org/root/acme-dns-01-cli.js) | ||||||
| 
 | 
 | ||||||
| ## Example | ## Example | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										23
									
								
								example.js
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								example.js
									
									
									
									
									
								
							| @ -1,24 +1,27 @@ | |||||||
| 'use strict'; | "use strict"; | ||||||
| 
 | 
 | ||||||
| //var tester = require('greenlock-challenge-test');
 | //var tester = require('acme-challenge-test');
 | ||||||
| var tester = require('./'); | var tester = require("./"); | ||||||
| 
 | 
 | ||||||
| var type = 'http-01'; | var type = "http-01"; | ||||||
| var challenger = require('greenlock-challenge-http').create({}); | var challenger = require("acme-http-01-cli").create({}); | ||||||
| //var type = 'dns-01';
 | //var type = 'dns-01';
 | ||||||
| //var challenger = require('greenlock-challenge-dns').create({});
 | //var challenger = require('acme-dns-01-cli').create({});
 | ||||||
| //var challenger = require('./YOUR-CHALLENGE-STRATEGY').create({});
 | //var challenger = require('./YOUR-CHALLENGE-STRATEGY').create({});
 | ||||||
| //var type = 'YOUR-TYPE-01';
 | //var type = 'YOUR-TYPE-01';
 | ||||||
| 
 | 
 | ||||||
| // The dry-run tests can pass on, literally, 'example.com'
 | // The dry-run tests can pass on, literally, 'example.com'
 | ||||||
| // but the integration tests require that you have control over the domain
 | // but the integration tests require that you have control over the domain
 | ||||||
| var domain = 'example.com'; | var domain = "example.com"; | ||||||
| //var domain = '*.example.com';
 | //var domain = '*.example.com';
 | ||||||
| 
 | 
 | ||||||
| tester.test(type, domain, challenger).then(function () { | tester | ||||||
|  | 	.test(type, domain, challenger) | ||||||
|  | 	.then(function() { | ||||||
| 		console.info("PASS"); | 		console.info("PASS"); | ||||||
| }).catch(function (err) { | 	}) | ||||||
|  | 	.catch(function(err) { | ||||||
| 		console.error("FAIL"); | 		console.error("FAIL"); | ||||||
| 		console.error(err); | 		console.error(err); | ||||||
| 		process.exit(20); | 		process.exit(20); | ||||||
| }); | 	}); | ||||||
|  | |||||||
							
								
								
									
										200
									
								
								index.js
									
									
									
									
									
								
							
							
						
						
									
										200
									
								
								index.js
									
									
									
									
									
								
							| @ -1,14 +1,16 @@ | |||||||
| 'use strict'; | "use strict"; | ||||||
| /*global Promise*/ | /*global Promise*/ | ||||||
| var crypto = require('crypto'); | var crypto = require("crypto"); | ||||||
| 
 | 
 | ||||||
| module.exports.create = function () { | module.exports.create = function() { | ||||||
|   throw new Error("greenlock-challenge-test is a test fixture for greenlock-challenge-* plugins, not a plugin itself"); | 	throw new Error( | ||||||
|  | 		"acme-challenge-test is a test fixture for acme-challenge-* plugins, not a plugin itself" | ||||||
|  | 	); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| // ignore all of this, it's just to normalize Promise vs node-style callback thunk vs synchronous
 | // ignore all of this, it's just to normalize Promise vs node-style callback thunk vs synchronous
 | ||||||
| function promiseCheckAndCatch(obj, name) { | function promiseCheckAndCatch(obj, name) { | ||||||
|   var promisify = require('util').promisify; | 	var promisify = require("util").promisify; | ||||||
| 	// don't loose this-ness, just in case that's important
 | 	// don't loose this-ness, just in case that's important
 | ||||||
| 	var fn = obj[name].bind(obj); | 	var fn = obj[name].bind(obj); | ||||||
| 	var promiser; | 	var promiser; | ||||||
| @ -16,8 +18,8 @@ function promiseCheckAndCatch(obj, name) { | |||||||
| 	// function signature must match, or an error will be thrown
 | 	// function signature must match, or an error will be thrown
 | ||||||
| 	if (1 === fn.length) { | 	if (1 === fn.length) { | ||||||
| 		// wrap so that synchronous errors are caught (alsa handles synchronous results)
 | 		// wrap so that synchronous errors are caught (alsa handles synchronous results)
 | ||||||
|     promiser = function (opts) { | 		promiser = function(opts) { | ||||||
|       return Promise.resolve().then(function () { | 			return Promise.resolve().then(function() { | ||||||
| 				return fn(opts); | 				return fn(opts); | ||||||
| 			}); | 			}); | ||||||
| 		}; | 		}; | ||||||
| @ -25,19 +27,29 @@ function promiseCheckAndCatch(obj, name) { | |||||||
| 		// wrap as a promise
 | 		// wrap as a promise
 | ||||||
| 		promiser = promisify(fn); | 		promiser = promisify(fn); | ||||||
| 	} else { | 	} else { | ||||||
|     return Promise.reject(new Error("'challenge." + name + "' should accept either one argument, the options," | 		return Promise.reject( | ||||||
|       + " and return a Promise or accept two arguments, the options and a node-style callback thunk")); | 			new Error( | ||||||
|  | 				"'challenge." + | ||||||
|  | 					name + | ||||||
|  | 					"' should accept either one argument, the options," + | ||||||
|  | 					" and return a Promise or accept two arguments, the options and a node-style callback thunk" | ||||||
|  | 			) | ||||||
|  | 		); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	function shouldntBeNull(result) { | 	function shouldntBeNull(result) { | ||||||
|     if ('undefined' === typeof result) { | 		if ("undefined" === typeof result) { | ||||||
|       throw new Error("'challenge.'" + name + "' should never return `undefined`. Please explicitly return null" | 			throw new Error( | ||||||
|         + " (or fix the place where a value should have been returned but wasn't)."); | 				"'challenge.'" + | ||||||
|  | 					name + | ||||||
|  | 					"' should never return `undefined`. Please explicitly return null" + | ||||||
|  | 					" (or fix the place where a value should have been returned but wasn't)." | ||||||
|  | 			); | ||||||
| 		} | 		} | ||||||
| 		return result; | 		return result; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|   return function (opts) { | 	return function(opts) { | ||||||
| 		return promiser(opts).then(shouldntBeNull); | 		return promiser(opts).then(shouldntBeNull); | ||||||
| 	}; | 	}; | ||||||
| } | } | ||||||
| @ -45,33 +57,36 @@ function promiseCheckAndCatch(obj, name) { | |||||||
| // Here's the meat, where the tests are happening:
 | // Here's the meat, where the tests are happening:
 | ||||||
| function run(challenger, opts) { | function run(challenger, opts) { | ||||||
| 	var ch = opts.challenge; | 	var ch = opts.challenge; | ||||||
|   if ('http-01' === ch.type && ch.wildname) { | 	if ("http-01" === ch.type && ch.wildname) { | ||||||
| 		throw new Error("http-01 cannot be used for wildcard domains"); | 		throw new Error("http-01 cannot be used for wildcard domains"); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|   var set = promiseCheckAndCatch(challenger, 'set'); | 	var set = promiseCheckAndCatch(challenger, "set"); | ||||||
|   if ('function' !== typeof challenger.get) { | 	if ("function" !== typeof challenger.get) { | ||||||
|     throw new Error("'challenge.get' should be implemented for the sake of testing." | 		throw new Error( | ||||||
|       + " It should be implemented as the internal method for fetching the challenge" | 			"'challenge.get' should be implemented for the sake of testing." + | ||||||
|       + " (i.e. reading from a database, file system or API, not return internal)," | 				" It should be implemented as the internal method for fetching the challenge" + | ||||||
|       + " not the external check (the http call, dns query, etc), which will already be done as part of this test."); | 				" (i.e. reading from a database, file system or API, not return internal)," + | ||||||
|  | 				" not the external check (the http call, dns query, etc), which will already be done as part of this test." | ||||||
|  | 		); | ||||||
| 	} | 	} | ||||||
|   var get = promiseCheckAndCatch(challenger, 'get'); | 	var get = promiseCheckAndCatch(challenger, "get"); | ||||||
|   var remove = promiseCheckAndCatch(challenger, 'remove'); | 	var remove = promiseCheckAndCatch(challenger, "remove"); | ||||||
| 
 | 
 | ||||||
| 	// The first time we just check it against itself
 | 	// The first time we just check it against itself
 | ||||||
| 	// this will cause the prompt to appear
 | 	// this will cause the prompt to appear
 | ||||||
|   return set(opts).then(function () { | 	return set(opts) | ||||||
|  | 		.then(function() { | ||||||
| 			// this will cause the final completion message to appear
 | 			// this will cause the final completion message to appear
 | ||||||
| 			// _test is used by the manual cli reference implementations
 | 			// _test is used by the manual cli reference implementations
 | ||||||
| 			var query = { type: ch.type, /*debug*/ status: ch.status, _test: true }; | 			var query = { type: ch.type, /*debug*/ status: ch.status, _test: true }; | ||||||
|     if ('http-01' === ch.type) { | 			if ("http-01" === ch.type) { | ||||||
| 				query.identifier = ch.identifier; | 				query.identifier = ch.identifier; | ||||||
| 				query.token = ch.token; | 				query.token = ch.token; | ||||||
| 				// For testing only
 | 				// For testing only
 | ||||||
| 				query.url = ch.challengeUrl; | 				query.url = ch.challengeUrl; | ||||||
|     } else if ('dns-01' === ch.type) { | 			} else if ("dns-01" === ch.type) { | ||||||
|       query.identifier = { type: 'dns', value: ch.dnsHost }; | 				query.identifier = { type: "dns", value: ch.dnsHost }; | ||||||
| 				// For testing only
 | 				// For testing only
 | ||||||
| 				query.altname = ch.altname; | 				query.altname = ch.altname; | ||||||
| 				// there should only be two possible TXT records per challenge domain:
 | 				// there should only be two possible TXT records per challenge domain:
 | ||||||
| @ -81,90 +96,133 @@ function run(challenger, opts) { | |||||||
| 				query = JSON.parse(JSON.stringify(ch)); | 				query = JSON.parse(JSON.stringify(ch)); | ||||||
| 				query.comment = "unknown challenge type, supplying everything"; | 				query.comment = "unknown challenge type, supplying everything"; | ||||||
| 			} | 			} | ||||||
|     return get({ challenge: query }).then(function (secret) { | 			return get({ challenge: query }) | ||||||
|       if ('string' === typeof secret) { | 				.then(function(secret) { | ||||||
|         console.info("secret was passed as a string, which works historically, but should be an object instead:"); | 					if ("string" === typeof secret) { | ||||||
|  | 						console.info( | ||||||
|  | 							"secret was passed as a string, which works historically, but should be an object instead:" | ||||||
|  | 						); | ||||||
| 						console.info('{ "keyAuthorization": "' + secret + '" }'); | 						console.info('{ "keyAuthorization": "' + secret + '" }'); | ||||||
| 						console.info("or"); | 						console.info("or"); | ||||||
| 						// TODO this should be "keyAuthorizationDigest"
 | 						// TODO this should be "keyAuthorizationDigest"
 | ||||||
| 						console.info('{ "dnsAuthorization": "' + secret + '" }'); | 						console.info('{ "dnsAuthorization": "' + secret + '" }'); | ||||||
|         console.info("This is to help keep greenlock (and associated plugins) future-proof for new challenge types"); | 						console.info( | ||||||
|  | 							"This is to help keep acme / greenlock (and associated plugins) future-proof for new challenge types" | ||||||
|  | 						); | ||||||
| 					} | 					} | ||||||
| 					// historically 'secret' has been a string, but I'd like it to transition to be an object.
 | 					// historically 'secret' has been a string, but I'd like it to transition to be an object.
 | ||||||
| 					// to make it backwards compatible in v2.7 to change it,
 | 					// to make it backwards compatible in v2.7 to change it,
 | ||||||
| 					// so I'm not sure that we really need to.
 | 					// so I'm not sure that we really need to.
 | ||||||
|       if ('http-01' === ch.type) { | 					if ("http-01" === ch.type) { | ||||||
| 						secret = secret.keyAuthorization || secret; | 						secret = secret.keyAuthorization || secret; | ||||||
| 						if (ch.keyAuthorization !== secret) { | 						if (ch.keyAuthorization !== secret) { | ||||||
|           throw new Error("http-01 challenge.get() returned '" + secret + "', which does not match the keyAuthorization" | 							throw new Error( | ||||||
|             + " saved with challenge.set(), which was '" + ch.keyAuthorization + "'"); | 								"http-01 challenge.get() returned '" + | ||||||
|  | 									secret + | ||||||
|  | 									"', which does not match the keyAuthorization" + | ||||||
|  | 									" saved with challenge.set(), which was '" + | ||||||
|  | 									ch.keyAuthorization + | ||||||
|  | 									"'" | ||||||
|  | 							); | ||||||
| 						} | 						} | ||||||
|       } else if ('dns-01' === ch.type) { | 					} else if ("dns-01" === ch.type) { | ||||||
| 						secret = secret.dnsAuthorization || secret; | 						secret = secret.dnsAuthorization || secret; | ||||||
| 						if (ch.dnsAuthorization !== secret) { | 						if (ch.dnsAuthorization !== secret) { | ||||||
|           throw new Error("dns-01 challenge.get() returned '" + secret + "', which does not match the dnsAuthorization" | 							throw new Error( | ||||||
|             + " (keyAuthDigest) saved with challenge.set(), which was '" + ch.dnsAuthorization + "'"); | 								"dns-01 challenge.get() returned '" + | ||||||
|  | 									secret + | ||||||
|  | 									"', which does not match the dnsAuthorization" + | ||||||
|  | 									" (keyAuthDigest) saved with challenge.set(), which was '" + | ||||||
|  | 									ch.dnsAuthorization + | ||||||
|  | 									"'" | ||||||
|  | 							); | ||||||
| 						} | 						} | ||||||
| 					} else { | 					} else { | ||||||
|         if ('tls-alpn-01' === ch.type) { | 						if ("tls-alpn-01" === ch.type) { | ||||||
|           console.warn("'tls-alpn-01' support is in development" | 							console.warn( | ||||||
|             + " (or developed and we haven't update this yet). Please contact us."); | 								"'tls-alpn-01' support is in development" + | ||||||
|  | 									" (or developed and we haven't update this yet). Please contact us." | ||||||
|  | 							); | ||||||
| 						} else { | 						} else { | ||||||
|           console.warn("We don't know how to test '" + ch.type + "'... are you sure that's a thing?"); | 							console.warn( | ||||||
|  | 								"We don't know how to test '" + | ||||||
|  | 									ch.type + | ||||||
|  | 									"'... are you sure that's a thing?" | ||||||
|  | 							); | ||||||
| 						} | 						} | ||||||
| 						secret = secret.keyAuthorization || secret; | 						secret = secret.keyAuthorization || secret; | ||||||
| 						if (ch.keyAuthorization !== secret) { | 						if (ch.keyAuthorization !== secret) { | ||||||
|           console.warn("The returned value doesn't match keyAuthorization", ch.keyAuthorization, secret); | 							console.warn( | ||||||
|  | 								"The returned value doesn't match keyAuthorization", | ||||||
|  | 								ch.keyAuthorization, | ||||||
|  | 								secret | ||||||
|  | 							); | ||||||
| 						} | 						} | ||||||
| 					} | 					} | ||||||
|     }).then(function () { | 				}) | ||||||
|       return remove(opts).then(function () { | 				.then(function() { | ||||||
|         return get(opts).then(function (result) { | 					return remove(opts).then(function() { | ||||||
|  | 						return get(opts).then(function(result) { | ||||||
| 							if (result) { | 							if (result) { | ||||||
|             throw new Error("challenge.remove() should have made it not possible for challenge.get() to return a value"); | 								throw new Error( | ||||||
|  | 									"challenge.remove() should have made it not possible for challenge.get() to return a value" | ||||||
|  | 								); | ||||||
| 							} | 							} | ||||||
| 							if (null !== result) { | 							if (null !== result) { | ||||||
|             throw new Error("challenge.get() should return null when the value is not set"); | 								throw new Error( | ||||||
|  | 									"challenge.get() should return null when the value is not set" | ||||||
|  | 								); | ||||||
| 							} | 							} | ||||||
| 						}); | 						}); | ||||||
| 					}); | 					}); | ||||||
| 				}); | 				}); | ||||||
|   }).then(function () { | 		}) | ||||||
|  | 		.then(function() { | ||||||
| 			console.info("All soft tests: PASS"); | 			console.info("All soft tests: PASS"); | ||||||
|     console.warn("Hard tests (actually checking http URLs and dns records) is implemented in acme-v2."); | 			console.warn( | ||||||
|     console.warn("We'll copy them over here as well, but that's a TODO for next week."); | 				"Hard tests (actually checking http URLs and dns records) is implemented in acme-v2." | ||||||
|  | 			); | ||||||
|  | 			console.warn( | ||||||
|  | 				"We'll copy them over here as well, but that's a TODO for next week." | ||||||
|  | 			); | ||||||
| 		}); | 		}); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| module.exports.test = function (type, altname, challenger) { | module.exports.test = function(type, altname, challenger) { | ||||||
|   var expires = new Date(Date.now() + (10*60*1000)).toISOString(); | 	var expires = new Date(Date.now() + 10 * 60 * 1000).toISOString(); | ||||||
|   var token = crypto.randomBytes(8).toString('hex'); | 	var token = crypto.randomBytes(8).toString("hex"); | ||||||
|   var thumb = crypto.randomBytes(16).toString('hex'); | 	var thumb = crypto.randomBytes(16).toString("hex"); | ||||||
|   var keyAuth = token + '.' + crypto.randomBytes(16).toString('hex'); | 	var keyAuth = token + "." + crypto.randomBytes(16).toString("hex"); | ||||||
|   var dnsAuth = crypto.createHash('sha256').update(keyAuth).digest('base64') | 	var dnsAuth = crypto | ||||||
|     .replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, ''); | 		.createHash("sha256") | ||||||
|  | 		.update(keyAuth) | ||||||
|  | 		.digest("base64") | ||||||
|  | 		.replace(/\+/g, "-") | ||||||
|  | 		.replace(/\//g, "_") | ||||||
|  | 		.replace(/=/g, ""); | ||||||
| 
 | 
 | ||||||
| 	var challenge = { | 	var challenge = { | ||||||
|     type: type | 		type: type, | ||||||
|   , identifier: { type: 'dns', value: null }  // completed below
 | 		identifier: { type: "dns", value: null }, // completed below
 | ||||||
|   , wildcard: false                           // completed below
 | 		wildcard: false, // completed below
 | ||||||
|   , status: 'pending' | 		status: "pending", | ||||||
|   , expires: expires | 		expires: expires, | ||||||
|   , token: token | 		token: token, | ||||||
|   , thumbprint: thumb | 		thumbprint: thumb, | ||||||
|   , keyAuthorization: keyAuth | 		keyAuthorization: keyAuth, | ||||||
|   , url: null                                 // completed below
 | 		url: null, // completed below
 | ||||||
|   , dnsHost: '_acme-challenge.'               // completed below
 | 		dnsHost: "_acme-challenge.", // completed below
 | ||||||
|   , dnsAuthorization: dnsAuth | 		dnsAuthorization: dnsAuth, | ||||||
|   , altname: altname | 		altname: altname, | ||||||
|   , _test: true                               // used by CLI referenced implementations
 | 		_test: true // used by CLI referenced implementations
 | ||||||
| 	}; | 	}; | ||||||
|   if ('*.' === altname.slice(0, 2)) { | 	if ("*." === altname.slice(0, 2)) { | ||||||
| 		challenge.wildcard = true; | 		challenge.wildcard = true; | ||||||
| 		altname = altname.slice(2); | 		altname = altname.slice(2); | ||||||
| 	} | 	} | ||||||
| 	challenge.identifier.value = altname; | 	challenge.identifier.value = altname; | ||||||
|   challenge.url = 'http://' + altname + '/.well-known/acme-challenge/' + challenge.token; | 	challenge.url = | ||||||
|  | 		"http://" + altname + "/.well-known/acme-challenge/" + challenge.token; | ||||||
| 	challenge.dnsHost += altname; | 	challenge.dnsHost += altname; | ||||||
| 
 | 
 | ||||||
| 	return run(challenger, { challenge: challenge }); | 	return run(challenger, { challenge: challenge }); | ||||||
|  | |||||||
| @ -1,9 +1,9 @@ | |||||||
| { | { | ||||||
| 	"name": "greenlock-challenge-test", | 	"name": "greenlock-challenge-test", | ||||||
|   "version": "3.0.2", | 	"version": "3.0.3", | ||||||
|   "description": "The base set of tests for all ACME challenge strategies. Any `greenlock-challenge-` plugin should be able to pass these tests.", | 	"description": "The base set of tests for all ACME challenge strategies. Any `acme-challenge-` or greenlock plugin should be able to pass these tests.", | ||||||
| 	"main": "index.js", | 	"main": "index.js", | ||||||
|   "homepage": "https://git.rootprojects.org/root/greenlock-challenge-test.js", | 	"homepage": "https://git.rootprojects.org/root/acme-challenge-test.js", | ||||||
| 	"dependencies": {}, | 	"dependencies": {}, | ||||||
| 	"devDependencies": {}, | 	"devDependencies": {}, | ||||||
| 	"scripts": { | 	"scripts": { | ||||||
| @ -11,7 +11,7 @@ | |||||||
| 	}, | 	}, | ||||||
| 	"repository": { | 	"repository": { | ||||||
| 		"type": "git", | 		"type": "git", | ||||||
|     "url": "https://git.rootprojects.org/root/greenlock-challenge-test.js.git" | 		"url": "https://git.rootprojects.org/root/acme-challenge-test.js.git" | ||||||
| 	}, | 	}, | ||||||
| 	"keywords": [ | 	"keywords": [ | ||||||
| 		"Let's Encrypt", | 		"Let's Encrypt", | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user