Comparing version 0.9.0 to 1.0.1
@@ -13,6 +13,10 @@ 'use strict'; | ||
return function (err) { | ||
console.log('reject something or other:'); | ||
console.log(err.stack); | ||
console.error('[acme-v2] handled(?) rejection as errback:'); | ||
console.error(err.stack); | ||
// nextTick to get out of Promise chain | ||
process.nextTick(function () { cb(err); }); | ||
// do not resolve promise further | ||
return new Promise(function () {}); | ||
}; | ||
@@ -54,2 +58,3 @@ } | ||
acme2.productionServerUrl = module.exports.defaults.productionServerUrl; | ||
acme2.acmeChallengePrefix = module.exports.defaults.acmeChallengePrefix; | ||
return acme2; | ||
@@ -68,2 +73,3 @@ } | ||
, rsaKeySize: 2048 // 256 | ||
, acmeChallengePrefix: '/.well-known/acme-challenge/' | ||
}; | ||
@@ -75,3 +81,3 @@ Object.keys(module.exports.defaults).forEach(function (key) { | ||
module.exports.ACME[key] = ACME2[key]; | ||
module.exports.ACME.create = create; | ||
}); | ||
module.exports.ACME.create = create; |
103
node.js
@@ -11,5 +11,3 @@ /*! | ||
ACME.acmeChallengePrefix = '/.well-known/acme-challenge/'; | ||
ACME.acmeChallengeDnsPrefix = '_acme-challenge'; | ||
ACME.acmeChallengePrefixes = { | ||
ACME.challengePrefixes = { | ||
'http-01': '/.well-known/acme-challenge' | ||
@@ -20,3 +18,3 @@ , 'dns-01': '_acme-challenge' | ||
'http-01': function (me, auth) { | ||
var url = 'http://' + auth.hostname + ACME.acmeChallengePrefixes['http-01'] + '/' + auth.token; | ||
var url = 'http://' + auth.hostname + ACME.challengePrefixes['http-01'] + '/' + auth.token; | ||
return me._request({ url: url }).then(function (resp) { | ||
@@ -37,3 +35,3 @@ var err; | ||
type: 'TXT' | ||
, name: ACME.acmeChallengePrefixes['dns-01'] + '.' + auth.hostname | ||
, name: ACME.challengePrefixes['dns-01'] + '.' + auth.hostname | ||
}).then(function (ans) { | ||
@@ -105,3 +103,3 @@ var err; | ||
ACME._registerAccount = function (me, options) { | ||
if (me.debug) { console.log('[acme-v2] accounts.create'); } | ||
if (me.debug) console.debug('[acme-v2] accounts.create'); | ||
@@ -150,4 +148,4 @@ return ACME._getNonce(me).then(function () { | ||
delete jws.header; | ||
if (me.debug) { console.log('[acme-v2] accounts.create JSON body:'); } | ||
if (me.debug) { console.log(jws); } | ||
if (me.debug) console.debug('[acme-v2] accounts.create JSON body:'); | ||
if (me.debug) console.debug(jws); | ||
me._nonce = null; | ||
@@ -162,9 +160,7 @@ return me._request({ | ||
var location = resp.toJSON().headers.location; | ||
if (me.debug) { | ||
// the account id url | ||
console.log('[DEBUG] new account location:'); | ||
console.log(location); // the account id url | ||
console.log(resp.toJSON()); | ||
} | ||
// the account id url | ||
me._kid = location; | ||
if (me.debug) console.debug('[DEBUG] new account location:'); | ||
if (me.debug) console.debug(location); | ||
if (me.debug) console.debug(resp.toJSON()); | ||
return resp.body; | ||
@@ -174,3 +170,3 @@ }).then(resolve, reject); | ||
if (me.debug) { console.log('[acme-v2] agreeToTerms'); } | ||
if (me.debug) console.debug('[acme-v2] agreeToTerms'); | ||
if (1 === options.agreeToTerms.length) { | ||
@@ -213,3 +209,3 @@ return options.agreeToTerms(me._tos).then(agree, reject); | ||
ACME._getChallenges = function (me, options, auth) { | ||
if (me.debug) { console.log('\n[DEBUG] getChallenges\n'); } | ||
if (me.debug) console.debug('\n[DEBUG] getChallenges\n'); | ||
return me._request({ method: 'GET', url: auth, json: true }).then(function (resp) { | ||
@@ -277,10 +273,10 @@ return resp.body; | ||
}).then(function (resp) { | ||
console.log('[acme-v2.js] deactivate:'); | ||
console.log(resp.headers); | ||
console.log(resp.body); | ||
console.log(); | ||
if (me.debug) console.debug('[acme-v2.js] deactivate:'); | ||
if (me.debug) console.debug(resp.headers); | ||
if (me.debug) console.debug(resp.body); | ||
if (me.debug) console.debug(); | ||
me._nonce = resp.toJSON().headers['replay-nonce']; | ||
if (me.debug) { console.log('deactivate challenge: resp.body:'); } | ||
if (me.debug) { console.log(resp.body); } | ||
if (me.debug) console.debug('deactivate challenge: resp.body:'); | ||
if (me.debug) console.debug(resp.body); | ||
return ACME._wait(10 * 1000); | ||
@@ -297,3 +293,3 @@ }); | ||
if (me.debug) { console.log('\n[DEBUG] statusChallenge\n'); } | ||
if (me.debug) console.debug('\n[DEBUG] statusChallenge\n'); | ||
return me._request({ method: 'GET', url: ch.url, json: true }).then(function (resp) { | ||
@@ -304,3 +300,3 @@ console.error('poll: resp.body:'); | ||
if ('processing' === resp.body.status) { | ||
if (me.debug) { console.log('poll: again'); } | ||
if (me.debug) console.debug('poll: again'); | ||
return ACME._wait(1 * 1000).then(pollStatus); | ||
@@ -314,3 +310,3 @@ } | ||
} | ||
if (me.debug) { console.log('poll: again'); } | ||
if (me.debug) console.debug('poll: again'); | ||
return ACME._wait(1 * 1000).then(testChallenge); | ||
@@ -320,3 +316,3 @@ } | ||
if ('valid' === resp.body.status) { | ||
if (me.debug) { console.log('poll: valid'); } | ||
if (me.debug) console.debug('poll: valid'); | ||
@@ -363,10 +359,10 @@ try { | ||
}).then(function (resp) { | ||
console.log('[acme-v2.js] challenge accepted!'); | ||
console.log(resp.headers); | ||
console.log(resp.body); | ||
console.log(); | ||
if (me.debug) console.debug('[acme-v2.js] challenge accepted!'); | ||
if (me.debug) console.debug(resp.headers); | ||
if (me.debug) console.debug(resp.body); | ||
if (me.debug) console.debug(); | ||
me._nonce = resp.toJSON().headers['replay-nonce']; | ||
if (me.debug) { console.log('respond to challenge: resp.body:'); } | ||
if (me.debug) { console.log(resp.body); } | ||
if (me.debug) console.debug('respond to challenge: resp.body:'); | ||
if (me.debug) console.debug(resp.body); | ||
return ACME._wait(1 * 1000).then(pollStatus).then(resolve, reject); | ||
@@ -386,4 +382,4 @@ }); | ||
if (me.debug) {console.log('\n[DEBUG] postChallenge\n'); } | ||
//console.log('\n[DEBUG] stop to fix things\n'); return; | ||
if (me.debug) {console.debug('\n[DEBUG] postChallenge\n'); } | ||
//if (me.debug) console.debug('\n[DEBUG] stop to fix things\n'); return; | ||
@@ -411,3 +407,3 @@ return ACME._wait(1 * 1000).then(function () { | ||
ACME._finalizeOrder = function (me, options, validatedDomains) { | ||
if (me.debug) { console.log('finalizeOrder:'); } | ||
if (me.debug) console.debug('finalizeOrder:'); | ||
var csr = me.RSA.generateCsrWeb64(options.domainKeypair, validatedDomains); | ||
@@ -425,3 +421,3 @@ var body = { csr: csr }; | ||
if (me.debug) { console.log('finalize:', me._finalize); } | ||
if (me.debug) console.debug('finalize:', me._finalize); | ||
me._nonce = null; | ||
@@ -436,4 +432,4 @@ return me._request({ | ||
if (me.debug) { console.log('order finalized: resp.body:'); } | ||
if (me.debug) { console.log(resp.body); } | ||
if (me.debug) console.debug('order finalized: resp.body:'); | ||
if (me.debug) console.debug(resp.body); | ||
@@ -464,3 +460,3 @@ if ('processing' === resp.body.status) { | ||
ACME._getCertificate = function (me, options) { | ||
if (me.debug) { console.log('[acme-v2] DEBUG get cert 1'); } | ||
if (me.debug) console.debug('[acme-v2] DEBUG get cert 1'); | ||
@@ -485,3 +481,3 @@ if (!options.challengeTypes) { | ||
if (me.debug) { console.log('[acme-v2] certificates.create'); } | ||
if (me.debug) console.debug('[acme-v2] certificates.create'); | ||
return ACME._getNonce(me).then(function () { | ||
@@ -504,3 +500,3 @@ var body = { | ||
if (me.debug) { console.log('\n[DEBUG] newOrder\n'); } | ||
if (me.debug) console.debug('\n[DEBUG] newOrder\n'); | ||
me._nonce = null; | ||
@@ -516,10 +512,8 @@ return me._request({ | ||
var auths; | ||
if (me.debug) { | ||
console.log(location); // the account id url | ||
console.log(resp.toJSON()); | ||
} | ||
if (me.debug) console.debug(location); // the account id url | ||
if (me.debug) console.debug(resp.toJSON()); | ||
me._authorizations = resp.body.authorizations; | ||
me._order = location; | ||
me._finalize = resp.body.finalize; | ||
//console.log('[DEBUG] finalize:', me._finalize); return; | ||
//if (me.debug) console.debug('[DEBUG] finalize:', me._finalize); return; | ||
@@ -531,3 +525,3 @@ if (!me._authorizations) { | ||
} | ||
if (me.debug) { console.log("47 &#&#&#&#&#&#&&##&#&#&#&#&#&#&#&"); } | ||
if (me.debug) console.debug("47 &#&#&#&#&#&#&&##&#&#&#&#&#&#&#&"); | ||
@@ -566,3 +560,3 @@ //return resp.body; | ||
return next().then(function () { | ||
if (me.debug) { console.log("37 &#&#&#&#&#&#&&##&#&#&#&#&#&#&#&"); } | ||
if (me.debug) console.debug("37 &#&#&#&#&#&#&&##&#&#&#&#&#&#&#&"); | ||
var validatedDomains = body.identifiers.map(function (ident) { | ||
@@ -574,6 +568,6 @@ return ident.value; | ||
}).then(function () { | ||
console.log('acme-v2: order was finalized'); | ||
if (me.debug) console.debug('acme-v2: order was finalized'); | ||
return me._request({ method: 'GET', url: me._certificate, json: true }).then(function (resp) { | ||
console.log('acme-v2: csr submitted and cert received:'); | ||
console.log(resp.body); | ||
if (me.debug) console.debug('acme-v2: csr submitted and cert received:'); | ||
if (me.debug) console.debug(resp.body); | ||
return resp.body; | ||
@@ -588,7 +582,4 @@ }); | ||
if (!me) { me = {}; } | ||
// | ||
me.debug = true; | ||
me.acmeChallengePrefix = ACME.acmeChallengePrefix; | ||
me.acmeChallengeDnsPrefix = ACME.acmeChallengeDnsPrefix; | ||
me.acmeChallengePrefixes = ACME.acmeChallengePrefixes; | ||
// me.debug = true; | ||
me.challengePrefixes = ACME.challengePrefixes; | ||
me.RSA = me.RSA || require('rsa-compat').RSA; | ||
@@ -595,0 +586,0 @@ me.request = me.request || require('request'); |
{ | ||
"name": "acme-v2", | ||
"version": "0.9.0", | ||
"description": "A framework for building letsencrypt clients (and other ACME v2 clients), forked from le-acme-core.js.", | ||
"version": "1.0.1", | ||
"description": "Free SSL. A framework for building Let's Encrypt v2 clients, and other ACME v2 (draft 11) clients. Successor to le-acme-core.js", | ||
"homepage": "https://git.coolaj86.com/coolaj86/acme-v2.js", | ||
@@ -16,5 +16,12 @@ "main": "node.js", | ||
"acmev2", | ||
"acmev02", | ||
"acme-v2", | ||
"acme-v02", | ||
"acme", | ||
"acme2", | ||
"acme11", | ||
"acme-draft11", | ||
"acme-draft-11", | ||
"draft", | ||
"11", | ||
"ssl", | ||
@@ -26,3 +33,5 @@ "tls", | ||
"letsencrypt-v2", | ||
"letsencrypt-v02", | ||
"letsencryptv2", | ||
"letsencryptv02", | ||
"letsencrypt2", | ||
@@ -29,0 +38,0 @@ "greenlock", |
113
README.md
@@ -1,2 +0,2 @@ | ||
acme-v2.js | ||
acme-v2.js (draft 11) | ||
========== | ||
@@ -6,35 +6,6 @@ | ||
A framework for building letsencrypt clients (and other ACME v2 clients), forked from `le-acme-core.js`. | ||
A framework for building letsencrypt v2 (IETF ACME draft 11) clients, successor to `le-acme-core.js`. | ||
Summary of spec that I'm working off of here: https://git.coolaj86.com/coolaj86/greenlock.js/issues/5#issuecomment-8 | ||
In progress | ||
* Mar 15, 2018 - get directory | ||
* Mar 15, 2018 - get nonce | ||
* Mar 15, 2018 - generate account keypair | ||
* Mar 15, 2018 - create account | ||
* Mar 16, 2018 - new order | ||
* Mar 16, 2018 - get challenges | ||
* Mar 20, 2018 - respond to challenges | ||
* Mar 20, 2018 - generate domain keypair | ||
* Mar 20, 2018 - finalize order (submit csr) | ||
* Mar 20, 2018 - poll for status | ||
* Mar 20, 2018 - download certificate | ||
* Mar 20, 2018 - SUCCESS - got a test certificate (hard-coded) | ||
* Mar 21, 2018 - can now accept values (not hard coded) | ||
* Mar 21, 2018 - *mostly* matches le-acme-core.js API | ||
* Apr 5, 2018 - completely match api for acme v1 (le-acme-core.js) | ||
* Apr 5, 2018 - test wildcard | ||
* Apr 5, 2018 - test two subdomains | ||
* Apr 5, 2018 - test subdomains and its wildcard | ||
* Apr 5, 2018 - test http and dns challenges (success and failure) | ||
* Apr 5, 2018 - export http and dns challenge tests | ||
* Apr 10, 2018 - tested backwards-compatibility using greenlock.js | ||
Todo | ||
* support ECDSA keys | ||
* Apr 5, 2018 - appears that sometimes 'pending' status cannot be progressed to 'processing' nor 'deactivated' | ||
## Let's Encrypt Directory URLs | ||
@@ -52,5 +23,46 @@ | ||
## API | ||
## Two API versions, Two Implementations | ||
This library (acme-v2.js) supports ACME [*draft 11*](https://tools.ietf.org/html/draft-ietf-acme-acme-11), | ||
otherwise known as Let's Encrypt v2 (or v02). | ||
* ACME draft 11 | ||
* Let's Encrypt v2 | ||
* Let's Encrypt v02 | ||
The predecessor (le-acme-core) supports Let's Encrypt v1 (or v01), which was a | ||
[hodge-podge of various drafts](https://github.com/letsencrypt/boulder/blob/master/docs/acme-divergences.md) | ||
of the ACME spec early on. | ||
* ACME early draft | ||
* Let's Encrypt v1 | ||
* Let's Encrypt v01 | ||
This library maintains compatibility with le-acme-core so that it can be used as a **drop-in replacement** | ||
and requires **no changes to existing code**, | ||
but also provides an updated API more congruent with draft 11. | ||
## le-acme-core-compatible API (recommended) | ||
Status: Stable, Locked, Bugfix-only | ||
``` | ||
var RSA = require('rsa-compat').RSA; | ||
var acme = require('acme-v2/compat.js').ACME.create({ RSA: RSA }); | ||
// | ||
// Use exactly the same as le-acme-core | ||
// | ||
``` | ||
See documentation at <https://git.coolaj86.com/coolaj86/le-acme-core.js> | ||
## draft API (dev) | ||
Status: Almost stable, not locked | ||
This API is a simple evolution of le-acme-core, | ||
but tries to provide a better mapping to the new draft 11 APIs. | ||
``` | ||
var ACME = require('acme-v2').ACME.create({ | ||
@@ -115,4 +127,39 @@ RSA: require('rsa-compat').RSA | ||
// Constants | ||
ACME.acmeChallengePrefix // /.well-known/acme-challenge/ | ||
ACME.challengePrefixes['http-01'] // '/.well-known/acme-challenge' | ||
ACME.challengePrefixes['dns-01'] // '_acme-challenge' | ||
``` | ||
Todo | ||
---- | ||
* support ECDSA keys | ||
* Apr 5, 2018 - appears that sometimes 'pending' status cannot be progressed to 'processing' nor 'deactivated' | ||
* this may be a bug in the staging API as it appears it cannot be cancelled either, but returns success status code | ||
Changelog | ||
--------- | ||
* v1.0.0 | ||
* Compat API is ready for use | ||
* Eliminate debug logging | ||
* Apr 10, 2018 - tested backwards-compatibility using greenlock.js | ||
* Apr 5, 2018 - export http and dns challenge tests | ||
* Apr 5, 2018 - test http and dns challenges (success and failure) | ||
* Apr 5, 2018 - test subdomains and its wildcard | ||
* Apr 5, 2018 - test two subdomains | ||
* Apr 5, 2018 - test wildcard | ||
* Apr 5, 2018 - completely match api for acme v1 (le-acme-core.js) | ||
* Mar 21, 2018 - *mostly* matches le-acme-core.js API | ||
* Mar 21, 2018 - can now accept values (not hard coded) | ||
* Mar 20, 2018 - SUCCESS - got a test certificate (hard-coded) | ||
* Mar 20, 2018 - download certificate | ||
* Mar 20, 2018 - poll for status | ||
* Mar 20, 2018 - finalize order (submit csr) | ||
* Mar 20, 2018 - generate domain keypair | ||
* Mar 20, 2018 - respond to challenges | ||
* Mar 16, 2018 - get challenges | ||
* Mar 16, 2018 - new order | ||
* Mar 15, 2018 - create account | ||
* Mar 15, 2018 - generate account keypair | ||
* Mar 15, 2018 - get nonce | ||
* Mar 15, 2018 - get directory |
@@ -34,7 +34,7 @@ 'use strict'; | ||
if ('http-01' === opts.type) { | ||
pathname = opts.hostname + acme2.acmeChallengePrefixes['http-01'] + "/" + opts.token; | ||
pathname = opts.hostname + acme2.challengePrefixes['http-01'] + "/" + opts.token; | ||
console.log("Put the string '" + opts.keyAuthorization + "' into a file at '" + pathname + "'"); | ||
console.log("echo '" + opts.keyAuthorization + "' > '" + pathname + "'"); | ||
} else if ('dns-01' === opts.type) { | ||
pathname = acme2.acmeChallengeDnsPrefix + "." + opts.hostname.replace(/^\*\./, ''); | ||
pathname = acme2.challengePrefixes['dns-01'] + "." + opts.hostname.replace(/^\*\./, ''); | ||
console.log("Put the string '" + opts.dnsAuthorization + "' into the TXT record '" + pathname + "'"); | ||
@@ -41,0 +41,0 @@ console.log("ddig TXT " + pathname + " '" + opts.dnsAuthorization + "'"); |
@@ -36,7 +36,7 @@ 'use strict'; | ||
if ('http-01' === opts.type) { | ||
pathname = opts.hostname + acme2.acmeChallengePrefixes['http-01'] + "/" + opts.token; | ||
pathname = opts.hostname + acme2.challengePrefixes['http-01'] + "/" + opts.token; | ||
console.log("Put the string '" + opts.keyAuthorization + "' into a file at '" + pathname + "'"); | ||
console.log("echo '" + opts.keyAuthorization + "' > '" + pathname + "'"); | ||
} else if ('dns-01' === opts.type) { | ||
pathname = acme2.acmeChallengeDnsPrefix + "." + opts.hostname.replace(/^\*\./, '');; | ||
pathname = acme2.challengePrefixes['dns-01'] + "." + opts.hostname.replace(/^\*\./, '');; | ||
console.log("Put the string '" + opts.dnsAuthorization + "' into the TXT record '" + pathname + "'"); | ||
@@ -43,0 +43,0 @@ console.log("ddig TXT " + pathname + " '" + opts.dnsAuthorization + "'"); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
38105
1
163
1
881