forked from root/acme.js
		
	yay for backwards compat tested and working
This commit is contained in:
		
							parent
							
								
									2b09af6137
								
							
						
					
					
						commit
						b12a1a7ea4
					
				
							
								
								
									
										42
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										42
									
								
								README.md
									
									
									
									
									
								
							@ -31,27 +31,52 @@ Todo
 | 
				
			|||||||
* export http and dns challenge tests
 | 
					* export http and dns challenge tests
 | 
				
			||||||
* support ECDSA keys
 | 
					* support ECDSA keys
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Let's Encrypt Directory URLs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					# Production URL
 | 
				
			||||||
 | 
					https://acme-v02.api.letsencrypt.org/directory
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					# Staging URL
 | 
				
			||||||
 | 
					https://acme-staging-v02.api.letsencrypt.org/directory
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## API
 | 
					## API
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
var ACME = require('acme-v2.js').ACME.create({
 | 
					var ACME = require('acme-v2').ACME.create({
 | 
				
			||||||
  RSA: require('rsa-compat').RSA
 | 
					  RSA: require('rsa-compat').RSA
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // other overrides
 | 
				
			||||||
 | 
					, request: require('request')
 | 
				
			||||||
 | 
					, promisify: require('util').promisify
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // used for constructing user-agent
 | 
				
			||||||
 | 
					, os: require('os')
 | 
				
			||||||
 | 
					, process: require('process')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // used for overriding the default user-agent
 | 
				
			||||||
 | 
					, userAgent: 'My custom UA String'
 | 
				
			||||||
 | 
					, getUserAgentString: function (deps) { return 'My custom UA String'; }
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```javascript
 | 
					```javascript
 | 
				
			||||||
// Accounts
 | 
					// Accounts
 | 
				
			||||||
ACME.registerNewAccount(options, cb)        // returns "regr" registration data
 | 
					ACME.accounts.create(options)                 // returns Promise<regr> registration data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    { email: '<email>'                        //    valid email (server checks MX records)
 | 
					    { email: '<email>'                        //    valid email (server checks MX records)
 | 
				
			||||||
    , accountKeypair: {                       //    privateKeyPem or privateKeyJwt
 | 
					    , accountKeypair: {                       //    privateKeyPem or privateKeyJwt
 | 
				
			||||||
        privateKeyPem: '<ASCII PEM>'
 | 
					        privateKeyPem: '<ASCII PEM>'
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    , agreeToTerms: fn (tosUrl, cb) {}        //    must specify agree=tosUrl to continue (or falsey to end)
 | 
					    , agreeToTerms: fn (tosUrl) {}            //    returns Promise with tosUrl
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Registration
 | 
					// Registration
 | 
				
			||||||
ACME.getCertificate(options, cb)            // returns (err, pems={ privkey (key), cert, chain (ca) })
 | 
					ACME.certificates.create(options)             // returns Promise<pems={ privkey (key), cert, chain (ca) }>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    { newAuthzUrl: '<url>'                    //    specify acmeUrls.newAuthz
 | 
					    { newAuthzUrl: '<url>'                    //    specify acmeUrls.newAuthz
 | 
				
			||||||
    , newCertUrl: '<url>'                     //    specify acmeUrls.newCert
 | 
					    , newCertUrl: '<url>'                     //    specify acmeUrls.newCert
 | 
				
			||||||
@ -64,20 +89,19 @@ ACME.getCertificate(options, cb)            // returns (err, pems={ privkey (key
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    , domains: [ 'example.com' ]
 | 
					    , domains: [ 'example.com' ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    , setChallenge: fn (hostname, key, val, cb)
 | 
					    , setChallenge: fn (hostname, key, val)   // return Promise
 | 
				
			||||||
    , removeChallenge: fn (hostname, key, cb)
 | 
					    , removeChallenge: fn (hostname, key)     // return Promise
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Discovery URLs
 | 
					// Discovery URLs
 | 
				
			||||||
ACME.getAcmeUrls(acmeDiscoveryUrl, cb)      // returns (err, acmeUrls={newReg,newAuthz,newCert,revokeCert})
 | 
					ACME.init(acmeDirectoryUrl)                   // returns Promise<acmeUrls={keyChange,meta,newAccount,newNonce,newOrder,revokeCert}>
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Helpers & Stuff
 | 
					Helpers & Stuff
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```javascript
 | 
					```javascript
 | 
				
			||||||
// Constants
 | 
					// Constants
 | 
				
			||||||
ACME.productionServerUrl                // https://acme-v02.api.letsencrypt.org/directory
 | 
					 | 
				
			||||||
ACME.stagingServerUrl                   // https://acme-staging-v02.api.letsencrypt.org/directory
 | 
					 | 
				
			||||||
ACME.acmeChallengePrefix                // /.well-known/acme-challenge/
 | 
					ACME.acmeChallengePrefix                // /.well-known/acme-challenge/
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										53
									
								
								compat.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								compat.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,53 @@
 | 
				
			|||||||
 | 
					'use strict';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var ACME2 = require('./').ACME;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function resolveFn(cb) {
 | 
				
			||||||
 | 
					  return function (val) {
 | 
				
			||||||
 | 
					    // nextTick to get out of Promise chain
 | 
				
			||||||
 | 
					    process.nextTick(function () { cb(null, val); });
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					function rejectFn(cb) {
 | 
				
			||||||
 | 
					  return function (err) {
 | 
				
			||||||
 | 
					    console.log('reject something or other:');
 | 
				
			||||||
 | 
					    console.log(err.stack);
 | 
				
			||||||
 | 
					    // nextTick to get out of Promise chain
 | 
				
			||||||
 | 
					    process.nextTick(function () { cb(err); });
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function create(deps) {
 | 
				
			||||||
 | 
					  deps.LeCore = {};
 | 
				
			||||||
 | 
					  var acme2 = ACME2.create(deps);
 | 
				
			||||||
 | 
					  acme2.registerNewAccount = function (options, cb) {
 | 
				
			||||||
 | 
					    acme2.accounts.create(options).then(resolveFn(cb), rejectFn(cb));
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  acme2.getCertificate = function (options, cb) {
 | 
				
			||||||
 | 
					    acme2.certificates.create(options).then(resolveFn(cb), rejectFn(cb));
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  acme2.getAcmeUrls = function (options, cb) {
 | 
				
			||||||
 | 
					    acme2.init(options).then(resolveFn(cb), rejectFn(cb));
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  acme2.stagingServerUrl = module.exports.defaults.stagingServerUrl;
 | 
				
			||||||
 | 
					  acme2.productionServerUrl = module.exports.defaults.productionServerUrl;
 | 
				
			||||||
 | 
					  return acme2;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module.exports.ACME = { };
 | 
				
			||||||
 | 
					module.exports.defaults = {
 | 
				
			||||||
 | 
					  productionServerUrl:    'https://acme-v02.api.letsencrypt.org/directory'
 | 
				
			||||||
 | 
					, stagingServerUrl:       'https://acme-staging-v02.api.letsencrypt.org/directory'
 | 
				
			||||||
 | 
					, knownEndpoints:         [ 'keyChange', 'meta', 'newAccount', 'newNonce', 'newOrder', 'revokeCert' ]
 | 
				
			||||||
 | 
					, challengeTypes:         [ 'http-01', 'dns-01' ]
 | 
				
			||||||
 | 
					, challengeType:          'http-01'
 | 
				
			||||||
 | 
					, keyType:                'rsa' // ecdsa
 | 
				
			||||||
 | 
					, keySize:                2048 // 256
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					Object.keys(module.exports.defaults).forEach(function (key) {
 | 
				
			||||||
 | 
					  module.exports.ACME[key] = module.exports.defaults[key];
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					Object.keys(ACME2).forEach(function (key) {
 | 
				
			||||||
 | 
					  module.exports.ACME[key] = ACME2[key];
 | 
				
			||||||
 | 
					  module.exports.ACME.create = create;
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
							
								
								
									
										342
									
								
								node.js
									
									
									
									
									
								
							
							
						
						
									
										342
									
								
								node.js
									
									
									
									
									
								
							@ -6,79 +6,41 @@
 | 
				
			|||||||
'use strict';
 | 
					'use strict';
 | 
				
			||||||
/* globals Promise */
 | 
					/* globals Promise */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var defaults = {
 | 
					var ACME = module.exports.ACME = {};
 | 
				
			||||||
  productionServerUrl:    'https://acme-v02.api.letsencrypt.org/directory'
 | 
					 | 
				
			||||||
, stagingServerUrl:       'https://acme-staging-v02.api.letsencrypt.org/directory'
 | 
					 | 
				
			||||||
, acmeChallengePrefix:    '/.well-known/acme-challenge/'
 | 
					 | 
				
			||||||
, knownEndpoints:         [ 'keyChange', 'meta', 'newAccount', 'newNonce', 'newOrder', 'revokeCert' ]
 | 
					 | 
				
			||||||
, challengeType:          'http-01' // dns-01
 | 
					 | 
				
			||||||
, keyType:                'rsa' // ecdsa
 | 
					 | 
				
			||||||
, keySize:                2048 // 256
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
function create(deps) {
 | 
					ACME.acmeChallengePrefix = '/.well-known/acme-challenge/';
 | 
				
			||||||
  if (!deps) { deps = {}; }
 | 
					 | 
				
			||||||
  deps.LeCore = {};
 | 
					 | 
				
			||||||
  deps.pkg = deps.pkg || require('./package.json');
 | 
					 | 
				
			||||||
  deps.os = deps.os || require('os');
 | 
					 | 
				
			||||||
  deps.process = deps.process || require('process');
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ACME._getUserAgentString = function (deps) {
 | 
				
			||||||
  var uaDefaults = {
 | 
					  var uaDefaults = {
 | 
				
			||||||
      pkg: "Greenlock/" + deps.pkg.version
 | 
					      pkg: "Greenlock/" + deps.pkg.version
 | 
				
			||||||
    , os: " (" + deps.os.type() + "; " + deps.process.arch + " " + deps.os.platform() + " " + deps.os.release() + ")"
 | 
					    , os: "(" + deps.os.type() + "; " + deps.process.arch + " " + deps.os.platform() + " " + deps.os.release() + ")"
 | 
				
			||||||
    , node: " Node.js/" + deps.process.version
 | 
					    , node: "Node.js/" + deps.process.version
 | 
				
			||||||
    , user: ''
 | 
					    , user: ''
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  //var currentUAProps;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function getUaString() {
 | 
					  var userAgent = [];
 | 
				
			||||||
    var userAgent = '';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  //Object.keys(currentUAProps)
 | 
					  //Object.keys(currentUAProps)
 | 
				
			||||||
  Object.keys(uaDefaults).forEach(function (key) {
 | 
					  Object.keys(uaDefaults).forEach(function (key) {
 | 
				
			||||||
      userAgent += uaDefaults[key];
 | 
					    if (uaDefaults[key]) {
 | 
				
			||||||
      //userAgent += currentUAProps[key];
 | 
					      userAgent.push(uaDefaults[key]);
 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return userAgent.trim();
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function getRequest(opts) {
 | 
					 | 
				
			||||||
    if (!opts) { opts = {}; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return deps.request.defaults({
 | 
					 | 
				
			||||||
      headers: {
 | 
					 | 
				
			||||||
        'User-Agent': opts.userAgent || getUaString()
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  var RSA = deps.RSA || require('rsa-compat').RSA;
 | 
					  return userAgent.join(' ').trim();
 | 
				
			||||||
  deps.request = deps.request || require('request');
 | 
					};
 | 
				
			||||||
  deps.promisify = deps.promisify || require('util').promisify;
 | 
					ACME._directory = function (me) {
 | 
				
			||||||
 | 
					  return me._request({ url: me.directoryUrl, json: true });
 | 
				
			||||||
  var directoryUrl = deps.directoryUrl || defaults.stagingServerUrl;
 | 
					};
 | 
				
			||||||
  var request = deps.promisify(getRequest({}));
 | 
					ACME._getNonce = function (me) {
 | 
				
			||||||
 | 
					 | 
				
			||||||
  var acme2 = {
 | 
					 | 
				
			||||||
    getAcmeUrls: function (_directoryUrl) {
 | 
					 | 
				
			||||||
      var me = this;
 | 
					 | 
				
			||||||
      return request({ url: _directoryUrl || directoryUrl, json: true }).then(function (resp) {
 | 
					 | 
				
			||||||
        me._directoryUrls = resp.body;
 | 
					 | 
				
			||||||
        me._tos = me._directoryUrls.meta.termsOfService;
 | 
					 | 
				
			||||||
        return me._directoryUrls;
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  , getNonce: function () {
 | 
					 | 
				
			||||||
      var me = this;
 | 
					 | 
				
			||||||
  if (me._nonce) { return new Promise(function (resolve) { resolve(me._nonce); return; }); }
 | 
					  if (me._nonce) { return new Promise(function (resolve) { resolve(me._nonce); return; }); }
 | 
				
			||||||
      return request({ method: 'HEAD', url: me._directoryUrls.newNonce }).then(function (resp) {
 | 
					  return me._request({ method: 'HEAD', url: me._directoryUrls.newNonce }).then(function (resp) {
 | 
				
			||||||
    me._nonce = resp.toJSON().headers['replay-nonce'];
 | 
					    me._nonce = resp.toJSON().headers['replay-nonce'];
 | 
				
			||||||
    return me._nonce;
 | 
					    return me._nonce;
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
    }
 | 
					};
 | 
				
			||||||
    // ACME RFC Section 7.3 Account Creation
 | 
					// ACME RFC Section 7.3 Account Creation
 | 
				
			||||||
    /*
 | 
					/*
 | 
				
			||||||
 {
 | 
					 {
 | 
				
			||||||
   "protected": base64url({
 | 
					   "protected": base64url({
 | 
				
			||||||
     "alg": "ES256",
 | 
					     "alg": "ES256",
 | 
				
			||||||
@ -96,17 +58,15 @@ function create(deps) {
 | 
				
			|||||||
   }),
 | 
					   }),
 | 
				
			||||||
   "signature": "RZPOnYoPs1PhjszF...-nh6X1qtOFPB519I"
 | 
					   "signature": "RZPOnYoPs1PhjszF...-nh6X1qtOFPB519I"
 | 
				
			||||||
 }
 | 
					 }
 | 
				
			||||||
    */
 | 
					*/
 | 
				
			||||||
  , registerNewAccount: function (options) {
 | 
					ACME._registerAccount = function (me, options) {
 | 
				
			||||||
      var me = this;
 | 
					  console.log('[acme-v2] accounts.create');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      console.log('[acme-v2] registerNewAccount');
 | 
					  return ACME._getNonce(me).then(function () {
 | 
				
			||||||
 | 
					 | 
				
			||||||
      return me.getNonce().then(function () {
 | 
					 | 
				
			||||||
    return new Promise(function (resolve, reject) {
 | 
					    return new Promise(function (resolve, reject) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          function agree(err, tosUrl) {
 | 
					      function agree(tosUrl) {
 | 
				
			||||||
            if (err) { reject(err); return; }
 | 
					        var err;
 | 
				
			||||||
        if (me._tos !== tosUrl) {
 | 
					        if (me._tos !== tosUrl) {
 | 
				
			||||||
          err = new Error("You must agree to the ToS at '" + me._tos + "'");
 | 
					          err = new Error("You must agree to the ToS at '" + me._tos + "'");
 | 
				
			||||||
          err.code = "E_AGREE_TOS";
 | 
					          err.code = "E_AGREE_TOS";
 | 
				
			||||||
@ -114,14 +74,14 @@ function create(deps) {
 | 
				
			|||||||
          return;
 | 
					          return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var jwk = RSA.exportPublicJwk(options.accountKeypair);
 | 
					        var jwk = me.RSA.exportPublicJwk(options.accountKeypair);
 | 
				
			||||||
        var body = {
 | 
					        var body = {
 | 
				
			||||||
          termsOfServiceAgreed: tosUrl === me._tos
 | 
					          termsOfServiceAgreed: tosUrl === me._tos
 | 
				
			||||||
        , onlyReturnExisting: false
 | 
					        , onlyReturnExisting: false
 | 
				
			||||||
        , contact: [ 'mailto:' + options.email ]
 | 
					        , contact: [ 'mailto:' + options.email ]
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        if (options.externalAccount) {
 | 
					        if (options.externalAccount) {
 | 
				
			||||||
              body.externalAccountBinding = RSA.signJws(
 | 
					          body.externalAccountBinding = me.RSA.signJws(
 | 
				
			||||||
            options.externalAccount.secret
 | 
					            options.externalAccount.secret
 | 
				
			||||||
          , undefined
 | 
					          , undefined
 | 
				
			||||||
          , { alg: "HS256"
 | 
					          , { alg: "HS256"
 | 
				
			||||||
@ -132,7 +92,7 @@ function create(deps) {
 | 
				
			|||||||
          );
 | 
					          );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        var payload = JSON.stringify(body);
 | 
					        var payload = JSON.stringify(body);
 | 
				
			||||||
            var jws = RSA.signJws(
 | 
					        var jws = me.RSA.signJws(
 | 
				
			||||||
          options.accountKeypair
 | 
					          options.accountKeypair
 | 
				
			||||||
        , undefined
 | 
					        , undefined
 | 
				
			||||||
        , { nonce: me._nonce
 | 
					        , { nonce: me._nonce
 | 
				
			||||||
@ -143,11 +103,11 @@ function create(deps) {
 | 
				
			|||||||
        , new Buffer(payload)
 | 
					        , new Buffer(payload)
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            console.log('[acme-v2] registerNewAccount JSON body:');
 | 
					        console.log('[acme-v2] accounts.create JSON body:');
 | 
				
			||||||
        delete jws.header;
 | 
					        delete jws.header;
 | 
				
			||||||
        console.log(jws);
 | 
					        console.log(jws);
 | 
				
			||||||
        me._nonce = null;
 | 
					        me._nonce = null;
 | 
				
			||||||
            return request({
 | 
					        return me._request({
 | 
				
			||||||
          method: 'POST'
 | 
					          method: 'POST'
 | 
				
			||||||
        , url: me._directoryUrls.newAccount
 | 
					        , url: me._directoryUrls.newAccount
 | 
				
			||||||
        , headers: { 'Content-Type': 'application/jose+json' }
 | 
					        , headers: { 'Content-Type': 'application/jose+json' }
 | 
				
			||||||
@ -160,15 +120,27 @@ function create(deps) {
 | 
				
			|||||||
          console.log(resp.toJSON());
 | 
					          console.log(resp.toJSON());
 | 
				
			||||||
          me._kid = location;
 | 
					          me._kid = location;
 | 
				
			||||||
          return resp.body;
 | 
					          return resp.body;
 | 
				
			||||||
            }).then(resolve);
 | 
					        }).then(resolve, reject);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      console.log('[acme-v2] agreeToTerms');
 | 
					      console.log('[acme-v2] agreeToTerms');
 | 
				
			||||||
          options.agreeToTerms(me._tos, agree);
 | 
					      if (1 === options.agreeToTerms.length) {
 | 
				
			||||||
        });
 | 
					        return options.agreeToTerms(me._tos).then(agree, reject);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      else if (2 === options.agreeToTerms.length) {
 | 
				
			||||||
 | 
					        return options.agreeToTerms(me._tos, function (err, tosUrl) {
 | 
				
			||||||
 | 
					          if (!err) { agree(tosUrl); return; }
 | 
				
			||||||
 | 
					          reject(err);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    /*
 | 
					      else {
 | 
				
			||||||
 | 
					        reject(new Error('agreeToTerms has incorrect function signature.'
 | 
				
			||||||
 | 
					          + ' Should be fn(tos) { return Promise<tos>; }'));
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 POST /acme/new-order HTTP/1.1
 | 
					 POST /acme/new-order HTTP/1.1
 | 
				
			||||||
 Host: example.com
 | 
					 Host: example.com
 | 
				
			||||||
 Content-Type: application/jose+json
 | 
					 Content-Type: application/jose+json
 | 
				
			||||||
@ -187,79 +159,68 @@ function create(deps) {
 | 
				
			|||||||
   }),
 | 
					   }),
 | 
				
			||||||
   "signature": "H6ZXtGjTZyUnPeKn...wEA4TklBdh3e454g"
 | 
					   "signature": "H6ZXtGjTZyUnPeKn...wEA4TklBdh3e454g"
 | 
				
			||||||
 }
 | 
					 }
 | 
				
			||||||
    */
 | 
					*/
 | 
				
			||||||
  , _getChallenges: function (options, auth) {
 | 
					ACME._getChallenges = function (me, options, auth) {
 | 
				
			||||||
  console.log('\n[DEBUG] getChallenges\n');
 | 
					  console.log('\n[DEBUG] getChallenges\n');
 | 
				
			||||||
      return request({ method: 'GET', url: auth, json: true }).then(function (resp) {
 | 
					  return me._request({ method: 'GET', url: auth, json: true }).then(function (resp) {
 | 
				
			||||||
    return resp.body;
 | 
					    return resp.body;
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
    }
 | 
					};
 | 
				
			||||||
    // https://tools.ietf.org/html/draft-ietf-acme-acme-10#section-7.5.1
 | 
					ACME._wait = function wait(ms) {
 | 
				
			||||||
  , _postChallenge: function (options, identifier, ch) {
 | 
					  return new Promise(function (resolve) {
 | 
				
			||||||
      var me = this;
 | 
					    setTimeout(resolve, (ms || 1100));
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					// https://tools.ietf.org/html/draft-ietf-acme-acme-10#section-7.5.1
 | 
				
			||||||
 | 
					ACME._postChallenge = function (me, options, identifier, ch) {
 | 
				
			||||||
  var body = { };
 | 
					  var body = { };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  var payload = JSON.stringify(body);
 | 
					  var payload = JSON.stringify(body);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      var thumbprint = RSA.thumbprint(options.accountKeypair);
 | 
					  var thumbprint = me.RSA.thumbprint(options.accountKeypair);
 | 
				
			||||||
  var keyAuthorization = ch.token + '.' + thumbprint;
 | 
					  var keyAuthorization = ch.token + '.' + thumbprint;
 | 
				
			||||||
  //   keyAuthorization = token || '.' || base64url(JWK_Thumbprint(accountKey))
 | 
					  //   keyAuthorization = token || '.' || base64url(JWK_Thumbprint(accountKey))
 | 
				
			||||||
  //   /.well-known/acme-challenge/:token
 | 
					  //   /.well-known/acme-challenge/:token
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return new Promise(function (resolve, reject) {
 | 
					  return new Promise(function (resolve, reject) {
 | 
				
			||||||
        if (options.setupChallenge) {
 | 
					    function failChallenge(err) {
 | 
				
			||||||
          options.setupChallenge(
 | 
					 | 
				
			||||||
            { identifier: identifier
 | 
					 | 
				
			||||||
            , hostname: identifier.value
 | 
					 | 
				
			||||||
            , type: ch.type
 | 
					 | 
				
			||||||
            , token: ch.token
 | 
					 | 
				
			||||||
            , thumbprint: thumbprint
 | 
					 | 
				
			||||||
            , keyAuthorization: keyAuthorization
 | 
					 | 
				
			||||||
            , dnsAuthorization: RSA.utils.toWebsafeBase64(
 | 
					 | 
				
			||||||
                require('crypto').createHash('sha256').update(keyAuthorization).digest('base64')
 | 
					 | 
				
			||||||
              )
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          , testChallenge
 | 
					 | 
				
			||||||
          );
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
          options.setChallenge(identifier.value, ch.token, keyAuthorization, testChallenge);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        function testChallenge(err) {
 | 
					 | 
				
			||||||
      if (err) { reject(err); return; }
 | 
					      if (err) { reject(err); return; }
 | 
				
			||||||
 | 
					      testChallenge();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function testChallenge() {
 | 
				
			||||||
      // TODO put check dns / http checks here?
 | 
					      // TODO put check dns / http checks here?
 | 
				
			||||||
      // http-01: GET https://example.org/.well-known/acme-challenge/{{token}} => {{keyAuth}}
 | 
					      // http-01: GET https://example.org/.well-known/acme-challenge/{{token}} => {{keyAuth}}
 | 
				
			||||||
      // dns-01: TXT _acme-challenge.example.org. => "{{urlSafeBase64(sha256(keyAuth))}}"
 | 
					      // dns-01: TXT _acme-challenge.example.org. => "{{urlSafeBase64(sha256(keyAuth))}}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          function wait(ms) {
 | 
					 | 
				
			||||||
            return new Promise(function (resolve) {
 | 
					 | 
				
			||||||
              setTimeout(resolve, (ms || 1100));
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      function pollStatus() {
 | 
					      function pollStatus() {
 | 
				
			||||||
        console.log('\n[DEBUG] statusChallenge\n');
 | 
					        console.log('\n[DEBUG] statusChallenge\n');
 | 
				
			||||||
            return request({ method: 'GET', url: ch.url, json: true }).then(function (resp) {
 | 
					        return me._request({ method: 'GET', url: ch.url, json: true }).then(function (resp) {
 | 
				
			||||||
          console.error('poll: resp.body:');
 | 
					          console.error('poll: resp.body:');
 | 
				
			||||||
          console.error(resp.body);
 | 
					          console.error(resp.body);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          if ('pending' === resp.body.status) {
 | 
					          if ('pending' === resp.body.status) {
 | 
				
			||||||
            console.log('poll: again');
 | 
					            console.log('poll: again');
 | 
				
			||||||
                return wait().then(pollStatus);
 | 
					            return ACME._wait(1 * 1000).then(pollStatus);
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          if ('valid' === resp.body.status) {
 | 
					          if ('valid' === resp.body.status) {
 | 
				
			||||||
            console.log('poll: valid');
 | 
					            console.log('poll: valid');
 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
                  if (options.teardownChallenge) {
 | 
					              if (1 === options.removeChallenge.length) {
 | 
				
			||||||
                    options.teardownChallenge(
 | 
					                options.removeChallenge(
 | 
				
			||||||
                  { identifier: identifier
 | 
					                  { identifier: identifier
 | 
				
			||||||
                  , type: ch.type
 | 
					                  , type: ch.type
 | 
				
			||||||
                  , token: ch.token
 | 
					                  , token: ch.token
 | 
				
			||||||
                  }
 | 
					                  }
 | 
				
			||||||
                    , function () {}
 | 
					                ).then(function () {}, function () {});
 | 
				
			||||||
 | 
					              } else if (2 === options.removeChallenge.length) {
 | 
				
			||||||
 | 
					                options.removeChallenge(
 | 
				
			||||||
 | 
					                  { identifier: identifier
 | 
				
			||||||
 | 
					                  , type: ch.type
 | 
				
			||||||
 | 
					                  , token: ch.token
 | 
				
			||||||
 | 
					                  }
 | 
				
			||||||
 | 
					                , function (err) { return err; }
 | 
				
			||||||
                );
 | 
					                );
 | 
				
			||||||
              } else {
 | 
					              } else {
 | 
				
			||||||
                options.removeChallenge(identifier.value, ch.token, function () {});
 | 
					                options.removeChallenge(identifier.value, ch.token, function () {});
 | 
				
			||||||
@ -286,14 +247,14 @@ function create(deps) {
 | 
				
			|||||||
      //console.log('\n[DEBUG] stop to fix things\n'); return;
 | 
					      //console.log('\n[DEBUG] stop to fix things\n'); return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      function post() {
 | 
					      function post() {
 | 
				
			||||||
            var jws = RSA.signJws(
 | 
					        var jws = me.RSA.signJws(
 | 
				
			||||||
          options.accountKeypair
 | 
					          options.accountKeypair
 | 
				
			||||||
        , undefined
 | 
					        , undefined
 | 
				
			||||||
        , { nonce: me._nonce, alg: 'RS256', url: ch.url, kid: me._kid }
 | 
					        , { nonce: me._nonce, alg: 'RS256', url: ch.url, kid: me._kid }
 | 
				
			||||||
        , new Buffer(payload)
 | 
					        , new Buffer(payload)
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        me._nonce = null;
 | 
					        me._nonce = null;
 | 
				
			||||||
            return request({
 | 
					        return me._request({
 | 
				
			||||||
          method: 'POST'
 | 
					          method: 'POST'
 | 
				
			||||||
        , url: ch.url
 | 
					        , url: ch.url
 | 
				
			||||||
        , headers: { 'Content-Type': 'application/jose+json' }
 | 
					        , headers: { 'Content-Type': 'application/jose+json' }
 | 
				
			||||||
@ -302,30 +263,57 @@ function create(deps) {
 | 
				
			|||||||
          me._nonce = resp.toJSON().headers['replay-nonce'];
 | 
					          me._nonce = resp.toJSON().headers['replay-nonce'];
 | 
				
			||||||
          console.log('respond to challenge: resp.body:');
 | 
					          console.log('respond to challenge: resp.body:');
 | 
				
			||||||
          console.log(resp.body);
 | 
					          console.log(resp.body);
 | 
				
			||||||
              return wait().then(pollStatus).then(resolve, reject);
 | 
					          return ACME._wait(1 * 1000).then(pollStatus).then(resolve, reject);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          return wait(20 * 1000).then(post);
 | 
					      return ACME._wait(1 * 1000).then(post);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					      if (1 === options.setChallenge.length) {
 | 
				
			||||||
 | 
					        options.setChallenge(
 | 
				
			||||||
 | 
					          { identifier: identifier
 | 
				
			||||||
 | 
					          , hostname: identifier.value
 | 
				
			||||||
 | 
					          , type: ch.type
 | 
				
			||||||
 | 
					          , token: ch.token
 | 
				
			||||||
 | 
					          , thumbprint: thumbprint
 | 
				
			||||||
 | 
					          , keyAuthorization: keyAuthorization
 | 
				
			||||||
 | 
					          , dnsAuthorization: me.RSA.utils.toWebsafeBase64(
 | 
				
			||||||
 | 
					              require('crypto').createHash('sha256').update(keyAuthorization).digest('base64')
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        ).then(testChallenge, reject);
 | 
				
			||||||
 | 
					      } else if (2 === options.setChallenge.length) {
 | 
				
			||||||
 | 
					        options.setChallenge(
 | 
				
			||||||
 | 
					          { identifier: identifier
 | 
				
			||||||
 | 
					          , hostname: identifier.value
 | 
				
			||||||
 | 
					          , type: ch.type
 | 
				
			||||||
 | 
					          , token: ch.token
 | 
				
			||||||
 | 
					          , thumbprint: thumbprint
 | 
				
			||||||
 | 
					          , keyAuthorization: keyAuthorization
 | 
				
			||||||
 | 
					          , dnsAuthorization: me.RSA.utils.toWebsafeBase64(
 | 
				
			||||||
 | 
					              require('crypto').createHash('sha256').update(keyAuthorization).digest('base64')
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        , failChallenge
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        options.setChallenge(identifier.value, ch.token, keyAuthorization, failChallenge);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    } catch(e) {
 | 
				
			||||||
 | 
					      reject(e);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
    }
 | 
					};
 | 
				
			||||||
  , _finalizeOrder: function (options, validatedDomains) {
 | 
					ACME._finalizeOrder = function (me, options, validatedDomains) {
 | 
				
			||||||
  console.log('finalizeOrder:');
 | 
					  console.log('finalizeOrder:');
 | 
				
			||||||
      var me = this;
 | 
					  var csr = me.RSA.generateCsrWeb64(options.domainKeypair, validatedDomains);
 | 
				
			||||||
 | 
					 | 
				
			||||||
      var csr = RSA.generateCsrWeb64(options.domainKeypair, validatedDomains);
 | 
					 | 
				
			||||||
  var body = { csr: csr };
 | 
					  var body = { csr: csr };
 | 
				
			||||||
  var payload = JSON.stringify(body);
 | 
					  var payload = JSON.stringify(body);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      function wait(ms) {
 | 
					 | 
				
			||||||
        return new Promise(function (resolve) {
 | 
					 | 
				
			||||||
          setTimeout(resolve, (ms || 1100));
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function pollCert() {
 | 
					  function pollCert() {
 | 
				
			||||||
        var jws = RSA.signJws(
 | 
					    var jws = me.RSA.signJws(
 | 
				
			||||||
      options.accountKeypair
 | 
					      options.accountKeypair
 | 
				
			||||||
    , undefined
 | 
					    , undefined
 | 
				
			||||||
    , { nonce: me._nonce, alg: 'RS256', url: me._finalize, kid: me._kid }
 | 
					    , { nonce: me._nonce, alg: 'RS256', url: me._finalize, kid: me._kid }
 | 
				
			||||||
@ -334,7 +322,7 @@ function create(deps) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    console.log('finalize:', me._finalize);
 | 
					    console.log('finalize:', me._finalize);
 | 
				
			||||||
    me._nonce = null;
 | 
					    me._nonce = null;
 | 
				
			||||||
        return request({
 | 
					    return me._request({
 | 
				
			||||||
      method: 'POST'
 | 
					      method: 'POST'
 | 
				
			||||||
    , url: me._finalize
 | 
					    , url: me._finalize
 | 
				
			||||||
    , headers: { 'Content-Type': 'application/jose+json' }
 | 
					    , headers: { 'Content-Type': 'application/jose+json' }
 | 
				
			||||||
@ -346,7 +334,7 @@ function create(deps) {
 | 
				
			|||||||
      console.log(resp.body);
 | 
					      console.log(resp.body);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if ('processing' === resp.body.status) {
 | 
					      if ('processing' === resp.body.status) {
 | 
				
			||||||
            return wait().then(pollCert);
 | 
					        return ACME._wait().then(pollCert);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if ('valid' === resp.body.status) {
 | 
					      if ('valid' === resp.body.status) {
 | 
				
			||||||
@ -367,29 +355,19 @@ function create(deps) {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return pollCert();
 | 
					  return pollCert();
 | 
				
			||||||
    }
 | 
					};
 | 
				
			||||||
  , _getCertificate: function () {
 | 
					ACME._getCertificate = function (me, options) {
 | 
				
			||||||
      var me = this;
 | 
					 | 
				
			||||||
      return request({ method: 'GET', url: me._certificate, json: true }).then(function (resp) {
 | 
					 | 
				
			||||||
        console.log('Certificate:');
 | 
					 | 
				
			||||||
        console.log(resp.body);
 | 
					 | 
				
			||||||
        return resp.body;
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  , getCertificate: function (options, cb) {
 | 
					 | 
				
			||||||
  console.log('[acme-v2] DEBUG get cert 1');
 | 
					  console.log('[acme-v2] DEBUG get cert 1');
 | 
				
			||||||
      var me = this;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (!options.challengeTypes) {
 | 
					  if (!options.challengeTypes) {
 | 
				
			||||||
    if (!options.challengeType) {
 | 
					    if (!options.challengeType) {
 | 
				
			||||||
          cb(new Error("challenge type must be specified"));
 | 
					 | 
				
			||||||
      return Promise.reject(new Error("challenge type must be specified"));
 | 
					      return Promise.reject(new Error("challenge type must be specified"));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    options.challengeTypes = [ options.challengeType ];
 | 
					    options.challengeTypes = [ options.challengeType ];
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      console.log('[acme-v2] getCertificate');
 | 
					  console.log('[acme-v2] certificates.create');
 | 
				
			||||||
      return me.getNonce().then(function () {
 | 
					  return ACME._getNonce(me).then(function () {
 | 
				
			||||||
    var body = {
 | 
					    var body = {
 | 
				
			||||||
      identifiers: options.domains.map(function (hostname) {
 | 
					      identifiers: options.domains.map(function (hostname) {
 | 
				
			||||||
        return { type: "dns" , value: hostname };
 | 
					        return { type: "dns" , value: hostname };
 | 
				
			||||||
@ -399,7 +377,7 @@ function create(deps) {
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    var payload = JSON.stringify(body);
 | 
					    var payload = JSON.stringify(body);
 | 
				
			||||||
        var jws = RSA.signJws(
 | 
					    var jws = me.RSA.signJws(
 | 
				
			||||||
      options.accountKeypair
 | 
					      options.accountKeypair
 | 
				
			||||||
    , undefined
 | 
					    , undefined
 | 
				
			||||||
    , { nonce: me._nonce, alg: 'RS256', url: me._directoryUrls.newOrder, kid: me._kid }
 | 
					    , { nonce: me._nonce, alg: 'RS256', url: me._directoryUrls.newOrder, kid: me._kid }
 | 
				
			||||||
@ -408,7 +386,7 @@ function create(deps) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    console.log('\n[DEBUG] newOrder\n');
 | 
					    console.log('\n[DEBUG] newOrder\n');
 | 
				
			||||||
    me._nonce = null;
 | 
					    me._nonce = null;
 | 
				
			||||||
        return request({
 | 
					    return me._request({
 | 
				
			||||||
      method: 'POST'
 | 
					      method: 'POST'
 | 
				
			||||||
    , url: me._directoryUrls.newOrder
 | 
					    , url: me._directoryUrls.newOrder
 | 
				
			||||||
    , headers: { 'Content-Type': 'application/jose+json' }
 | 
					    , headers: { 'Content-Type': 'application/jose+json' }
 | 
				
			||||||
@ -424,14 +402,16 @@ function create(deps) {
 | 
				
			|||||||
      //console.log('[DEBUG] finalize:', me._finalize); return;
 | 
					      //console.log('[DEBUG] finalize:', me._finalize); return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      //return resp.body;
 | 
					      //return resp.body;
 | 
				
			||||||
          return Promise.all(me._authorizations.map(function (authUrl) {
 | 
					      return Promise.all(me._authorizations.map(function (authUrl, i) {
 | 
				
			||||||
            return me._getChallenges(options, authUrl).then(function (results) {
 | 
					        console.log("Authorizations map #" + i);
 | 
				
			||||||
 | 
					        return ACME._getChallenges(me, options, authUrl).then(function (results) {
 | 
				
			||||||
          // var domain = options.domains[i]; // results.identifier.value
 | 
					          // var domain = options.domains[i]; // results.identifier.value
 | 
				
			||||||
          var chType = options.challengeTypes.filter(function (chType) {
 | 
					          var chType = options.challengeTypes.filter(function (chType) {
 | 
				
			||||||
            return results.challenges.some(function (ch) {
 | 
					            return results.challenges.some(function (ch) {
 | 
				
			||||||
              return ch.type === chType;
 | 
					              return ch.type === chType;
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
          })[0];
 | 
					          })[0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          var challenge = results.challenges.filter(function (ch) {
 | 
					          var challenge = results.challenges.filter(function (ch) {
 | 
				
			||||||
            if (chType === ch.type) {
 | 
					            if (chType === ch.type) {
 | 
				
			||||||
              return ch;
 | 
					              return ch;
 | 
				
			||||||
@ -442,27 +422,71 @@ function create(deps) {
 | 
				
			|||||||
            return Promise.reject(new Error("Server didn't offer any challenge we can handle."));
 | 
					            return Promise.reject(new Error("Server didn't offer any challenge we can handle."));
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
              return me._postChallenge(options, results.identifier, challenge);
 | 
					          return ACME._postChallenge(me, options, results.identifier, challenge);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
      })).then(function () {
 | 
					      })).then(function () {
 | 
				
			||||||
        var validatedDomains = body.identifiers.map(function (ident) {
 | 
					        var validatedDomains = body.identifiers.map(function (ident) {
 | 
				
			||||||
          return ident.value;
 | 
					          return ident.value;
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return me._finalizeOrder(options, validatedDomains);
 | 
					        return ACME._finalizeOrder(me, options, validatedDomains);
 | 
				
			||||||
      }).then(function () {
 | 
					      }).then(function () {
 | 
				
			||||||
            return me._getCertificate().then(function (result) { cb(null, result); return result; }, cb);
 | 
					        return me._request({ method: 'GET', url: me._certificate, json: true }).then(function (resp) {
 | 
				
			||||||
 | 
					          console.log('Certificate:');
 | 
				
			||||||
 | 
					          console.log(resp.body);
 | 
				
			||||||
 | 
					          return resp.body;
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ACME.create = function create(me) {
 | 
				
			||||||
 | 
					  if (!me) { me = {}; }
 | 
				
			||||||
 | 
					  me.acmeChallengePrefix = ACME.acmeChallengePrefix;
 | 
				
			||||||
 | 
					  me.RSA = me.RSA || require('rsa-compat').RSA;
 | 
				
			||||||
 | 
					  me.request = me.request || require('request');
 | 
				
			||||||
 | 
					  me.promisify = me.promisify || require('util').promisify;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if ('function' !== typeof me.getUserAgentString) {
 | 
				
			||||||
 | 
					    me.pkg = me.pkg || require('./package.json');
 | 
				
			||||||
 | 
					    me.os = me.os || require('os');
 | 
				
			||||||
 | 
					    me.process = me.process || require('process');
 | 
				
			||||||
 | 
					    me.userAgent = ACME._getUserAgentString(me);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function getRequest(opts) {
 | 
				
			||||||
 | 
					    if (!opts) { opts = {}; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return me.request.defaults({
 | 
				
			||||||
 | 
					      headers: {
 | 
				
			||||||
 | 
					        'User-Agent': opts.userAgent || me.userAgent || me.getUserAgentString(me)
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
  return acme2;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
module.exports.ACME = {
 | 
					  if ('function' !== typeof me._request) {
 | 
				
			||||||
  create: create
 | 
					    me._request = me.promisify(getRequest({}));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  me.init = function (_directoryUrl) {
 | 
				
			||||||
 | 
					    me.directoryUrl = me.directoryUrl || _directoryUrl;
 | 
				
			||||||
 | 
					    return ACME._directory(me).then(function (resp) {
 | 
				
			||||||
 | 
					      me._directoryUrls = resp.body;
 | 
				
			||||||
 | 
					      me._tos = me._directoryUrls.meta.termsOfService;
 | 
				
			||||||
 | 
					      return me._directoryUrls;
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  me.accounts = {
 | 
				
			||||||
 | 
					    create: function (options) {
 | 
				
			||||||
 | 
					      return ACME._registerAccount(me, options);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  me.certificates = {
 | 
				
			||||||
 | 
					    create: function (options) {
 | 
				
			||||||
 | 
					      return ACME._getCertificate(me, options);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  return me;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
Object.keys(defaults).forEach(function (key) {
 | 
					 | 
				
			||||||
  module.exports.ACME[key] = defaults[key];
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										75
									
								
								test.cb.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								test.cb.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,75 @@
 | 
				
			|||||||
 | 
					'use strict';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module.exports.run = function run(web, chType, email) {
 | 
				
			||||||
 | 
					  var RSA = require('rsa-compat').RSA;
 | 
				
			||||||
 | 
					  var directoryUrl = 'https://acme-staging-v02.api.letsencrypt.org/directory';
 | 
				
			||||||
 | 
					  var acme2 = require('./compat').ACME.create({ RSA: RSA });
 | 
				
			||||||
 | 
					  // [ 'test.ppl.family' ] 'coolaj86@gmail.com''http-01'
 | 
				
			||||||
 | 
						console.log(web, chType, email);
 | 
				
			||||||
 | 
						return;
 | 
				
			||||||
 | 
					  acme2.init(directoryUrl).then(function (body) {
 | 
				
			||||||
 | 
					    console.log(body);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    var options = {
 | 
				
			||||||
 | 
					      agreeToTerms: function (tosUrl, agree) {
 | 
				
			||||||
 | 
					        agree(null, tosUrl);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    , setChallenge: function (opts, cb) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        console.log("");
 | 
				
			||||||
 | 
					        console.log('identifier:');
 | 
				
			||||||
 | 
					        console.log(opts.identifier);
 | 
				
			||||||
 | 
					        console.log('hostname:');
 | 
				
			||||||
 | 
					        console.log(opts.hostname);
 | 
				
			||||||
 | 
					        console.log('type:');
 | 
				
			||||||
 | 
					        console.log(opts.type);
 | 
				
			||||||
 | 
					        console.log('token:');
 | 
				
			||||||
 | 
					        console.log(opts.token);
 | 
				
			||||||
 | 
					        console.log('thumbprint:');
 | 
				
			||||||
 | 
					        console.log(opts.thumbprint);
 | 
				
			||||||
 | 
					        console.log('keyAuthorization:');
 | 
				
			||||||
 | 
					        console.log(opts.keyAuthorization);
 | 
				
			||||||
 | 
					        console.log('dnsAuthorization:');
 | 
				
			||||||
 | 
					        console.log(opts.dnsAuthorization);
 | 
				
			||||||
 | 
					        console.log("");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        console.log("Put the string '" + opts.keyAuthorization + "' into a file at '" + opts.hostname + "/" + opts.token + "'");
 | 
				
			||||||
 | 
					        console.log("\nThen hit the 'any' key to continue (must be specifically the 'any' key)...");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        function onAny() {
 | 
				
			||||||
 | 
					          process.stdin.pause();
 | 
				
			||||||
 | 
					          process.stdin.removeEventListener('data', onAny);
 | 
				
			||||||
 | 
					          process.stdin.setRawMode(false);
 | 
				
			||||||
 | 
					          cb();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        process.stdin.setRawMode(true);
 | 
				
			||||||
 | 
					        process.stdin.resume();
 | 
				
			||||||
 | 
					        process.stdin.on('data', onAny);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    , removeChallenge: function (opts, cb) {
 | 
				
			||||||
 | 
									// hostname, key
 | 
				
			||||||
 | 
					        console.log('[DEBUG] remove challenge', hostname, key);
 | 
				
			||||||
 | 
					        setTimeout(cb, 1 * 1000);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    , challengeType: chType
 | 
				
			||||||
 | 
					    , email: email
 | 
				
			||||||
 | 
					    , accountKeypair: RSA.import({ privateKeyPem: require('fs').readFileSync(__dirname + '/account.privkey.pem') })
 | 
				
			||||||
 | 
					    , domainKeypair: RSA.import({ privateKeyPem: require('fs').readFileSync(__dirname + '/privkey.pem') })
 | 
				
			||||||
 | 
					    , domains: web
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    acme2.registerNewAccount(options).then(function (account) {
 | 
				
			||||||
 | 
					      console.log('account:');
 | 
				
			||||||
 | 
					      console.log(account);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      acme2.getCertificate(options, function (fullchainPem) {
 | 
				
			||||||
 | 
					        console.log('[acme-v2] A fullchain.pem:');
 | 
				
			||||||
 | 
					        console.log(fullchainPem);
 | 
				
			||||||
 | 
					      }).then(function (fullchainPem) {
 | 
				
			||||||
 | 
					        console.log('[acme-v2] B fullchain.pem:');
 | 
				
			||||||
 | 
					        console.log(fullchainPem);
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										57
									
								
								test.compat.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								test.compat.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,57 @@
 | 
				
			|||||||
 | 
					'use strict';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var RSA = require('rsa-compat').RSA;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module.exports.run = function (web, chType, email) {
 | 
				
			||||||
 | 
					  console.log('[DEBUG] run', web, chType, email);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  var acme2 = require('./compat.js').ACME.create({ RSA: RSA });
 | 
				
			||||||
 | 
					  acme2.getAcmeUrls(acme2.stagingServerUrl, function (err, body) {
 | 
				
			||||||
 | 
					    if (err) { console.log('err 1'); throw err; }
 | 
				
			||||||
 | 
					    console.log(body);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    var options = {
 | 
				
			||||||
 | 
					      agreeToTerms: function (tosUrl, agree) {
 | 
				
			||||||
 | 
					        agree(null, tosUrl);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    , setChallenge: function (hostname, token, val, cb) {
 | 
				
			||||||
 | 
					        console.log("Put the string '" + val + "' into a file at '" + hostname + "/" + acme2.acmeChallengePrefix + "/" + token + "'");
 | 
				
			||||||
 | 
					        console.log("echo '" + val + "' > '" + hostname + "/" + acme2.acmeChallengePrefix + "/" + token + "'");
 | 
				
			||||||
 | 
					        console.log("\nThen hit the 'any' key to continue (must be specifically the 'any' key)...");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        function onAny() {
 | 
				
			||||||
 | 
					          console.log("'any' key was hit");
 | 
				
			||||||
 | 
					          process.stdin.pause();
 | 
				
			||||||
 | 
					          process.stdin.removeListener('data', onAny);
 | 
				
			||||||
 | 
					          process.stdin.setRawMode(false);
 | 
				
			||||||
 | 
					          cb();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        process.stdin.setRawMode(true);
 | 
				
			||||||
 | 
					        process.stdin.resume();
 | 
				
			||||||
 | 
					        process.stdin.on('data', onAny);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    , removeChallenge: function (hostname, key, cb) {
 | 
				
			||||||
 | 
					        console.log('[DEBUG] remove challenge', hostname, key);
 | 
				
			||||||
 | 
					        setTimeout(cb, 1 * 1000);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    , challengeType: chType
 | 
				
			||||||
 | 
					    , email: email
 | 
				
			||||||
 | 
					    , accountKeypair: RSA.import({ privateKeyPem: require('fs').readFileSync(__dirname + '/account.privkey.pem') })
 | 
				
			||||||
 | 
					    , domainKeypair: RSA.import({ privateKeyPem: require('fs').readFileSync(__dirname + '/privkey.pem') })
 | 
				
			||||||
 | 
					    , domains: web
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    acme2.registerNewAccount(options, function (err, account) {
 | 
				
			||||||
 | 
					      if (err) { console.log('err 2'); throw err; }
 | 
				
			||||||
 | 
					      console.log('account:');
 | 
				
			||||||
 | 
					      console.log(account);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      acme2.getCertificate(options, function (err, fullchainPem) {
 | 
				
			||||||
 | 
					        if (err) { console.log('err 3'); throw err; }
 | 
				
			||||||
 | 
					        console.log('[acme-v2] A fullchain.pem:');
 | 
				
			||||||
 | 
					        console.log(fullchainPem);
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										95
									
								
								test.js
									
									
									
									
									
								
							
							
						
						
									
										95
									
								
								test.js
									
									
									
									
									
								
							@ -1,56 +1,45 @@
 | 
				
			|||||||
'use strict';
 | 
					'use strict';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var RSA = require('rsa-compat').RSA;
 | 
					var readline = require('readline');
 | 
				
			||||||
var acme2 = require('./').ACME.create({ RSA: RSA });
 | 
					var rl = readline.createInterface({
 | 
				
			||||||
 | 
					  input: process.stdin,
 | 
				
			||||||
acme2.getAcmeUrls(acme2.stagingServerUrl).then(function (body) {
 | 
					  output: process.stdout
 | 
				
			||||||
  console.log(body);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  var options = {
 | 
					 | 
				
			||||||
    agreeToTerms: function (tosUrl, agree) {
 | 
					 | 
				
			||||||
      agree(null, tosUrl);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    /*
 | 
					 | 
				
			||||||
  , setupChallenge: function (opts) {
 | 
					 | 
				
			||||||
      console.log('type:');
 | 
					 | 
				
			||||||
      console.log(ch.type);
 | 
					 | 
				
			||||||
      console.log('ch.token:');
 | 
					 | 
				
			||||||
      console.log(ch.token);
 | 
					 | 
				
			||||||
      console.log('thumbprint:');
 | 
					 | 
				
			||||||
      console.log(thumbprint);
 | 
					 | 
				
			||||||
      console.log('keyAuthorization:');
 | 
					 | 
				
			||||||
      console.log(keyAuthorization);
 | 
					 | 
				
			||||||
      console.log('dnsAuthorization:');
 | 
					 | 
				
			||||||
      console.log(dnsAuthorization);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    */
 | 
					 | 
				
			||||||
    // teardownChallenge
 | 
					 | 
				
			||||||
  , setChallenge: function (hostname, key, val, cb) {
 | 
					 | 
				
			||||||
      console.log('[DEBUG] set challenge', hostname, key, val);
 | 
					 | 
				
			||||||
      console.log("You have 20 seconds to put the string '" + val + "' into a file at '" + hostname + "/" + key + "'");
 | 
					 | 
				
			||||||
      setTimeout(cb, 20 * 1000);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  , removeChallenge: function (hostname, key, cb) {
 | 
					 | 
				
			||||||
      console.log('[DEBUG] remove challenge', hostname, key);
 | 
					 | 
				
			||||||
      setTimeout(cb, 1 * 1000);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  , challengeType: 'http-01'
 | 
					 | 
				
			||||||
  , email: 'coolaj86@gmail.com'
 | 
					 | 
				
			||||||
  , accountKeypair: RSA.import({ privateKeyPem: require('fs').readFileSync(__dirname + '/account.privkey.pem') })
 | 
					 | 
				
			||||||
  , domainKeypair: RSA.import({ privateKeyPem: require('fs').readFileSync(__dirname + '/privkey.pem') })
 | 
					 | 
				
			||||||
  , domains: [ 'test.ppl.family' ]
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  acme2.registerNewAccount(options).then(function (account) {
 | 
					 | 
				
			||||||
    console.log('account:');
 | 
					 | 
				
			||||||
    console.log(account);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    acme2.getCertificate(options, function (fullchainPem) {
 | 
					 | 
				
			||||||
      console.log('[acme-v2] A fullchain.pem:');
 | 
					 | 
				
			||||||
      console.log(fullchainPem);
 | 
					 | 
				
			||||||
    }).then(function (fullchainPem) {
 | 
					 | 
				
			||||||
      console.log('[acme-v2] B fullchain.pem:');
 | 
					 | 
				
			||||||
      console.log(fullchainPem);
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function getWeb() {
 | 
				
			||||||
 | 
						rl.question('What web address(es) would you like to get certificates for? (ex: example.com,*.example.com) ', function (web) {
 | 
				
			||||||
 | 
							web = (web||'').trim().split(/,/g);
 | 
				
			||||||
 | 
							if (!web[0]) { getWeb(); return; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (web.some(function (w) { return '*' === w[0]; })) {
 | 
				
			||||||
 | 
					      console.log('Wildcard domains must use dns-01');
 | 
				
			||||||
 | 
					      getEmail(web, 'dns-01');
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      getChallengeType(web);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function getChallengeType(web) {
 | 
				
			||||||
 | 
						rl.question('What challenge will you be testing today? http-01 or dns-01? [http-01] ', function (chType) {
 | 
				
			||||||
 | 
							chType = (chType||'').trim();
 | 
				
			||||||
 | 
							if (!chType) { chType = 'http-01'; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							getEmail(web, chType);
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function getEmail(web, chType) {
 | 
				
			||||||
 | 
						rl.question('What email should we use? (optional) ', function (email) {
 | 
				
			||||||
 | 
							email = (email||'').trim();
 | 
				
			||||||
 | 
							if (!email) { email = null; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    rl.close();
 | 
				
			||||||
 | 
					    console.log("[DEBUG] rl blah blah");
 | 
				
			||||||
 | 
					    require('./test.compat.js').run(web, chType, email);
 | 
				
			||||||
 | 
					    //require('./test.cb.js').run(web, chType, email);
 | 
				
			||||||
 | 
					    //require('./test.promise.js').run(web, chType, email);
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					getWeb();
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										84
									
								
								test.promise.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								test.promise.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,84 @@
 | 
				
			|||||||
 | 
					'use strict';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* global Promise */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module.exports.run = function run(web, chType, email) {
 | 
				
			||||||
 | 
					  var RSA = require('rsa-compat').RSA;
 | 
				
			||||||
 | 
					  var directoryUrl = 'https://acme-staging-v02.api.letsencrypt.org/directory';
 | 
				
			||||||
 | 
					  var acme2 = require('./compat').ACME.create({ RSA: RSA });
 | 
				
			||||||
 | 
					  // [ 'test.ppl.family' ] 'coolaj86@gmail.com''http-01'
 | 
				
			||||||
 | 
						console.log(web, chType, email);
 | 
				
			||||||
 | 
						return;
 | 
				
			||||||
 | 
					  acme2.init(directoryUrl).then(function (body) {
 | 
				
			||||||
 | 
					    console.log(body);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    var options = {
 | 
				
			||||||
 | 
					      agreeToTerms: function (tosUrl, agree) {
 | 
				
			||||||
 | 
					        agree(null, tosUrl);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    , setChallenge: function (opts) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        console.log("");
 | 
				
			||||||
 | 
					        console.log('identifier:');
 | 
				
			||||||
 | 
					        console.log(opts.identifier);
 | 
				
			||||||
 | 
					        console.log('hostname:');
 | 
				
			||||||
 | 
					        console.log(opts.hostname);
 | 
				
			||||||
 | 
					        console.log('type:');
 | 
				
			||||||
 | 
					        console.log(opts.type);
 | 
				
			||||||
 | 
					        console.log('token:');
 | 
				
			||||||
 | 
					        console.log(opts.token);
 | 
				
			||||||
 | 
					        console.log('thumbprint:');
 | 
				
			||||||
 | 
					        console.log(opts.thumbprint);
 | 
				
			||||||
 | 
					        console.log('keyAuthorization:');
 | 
				
			||||||
 | 
					        console.log(opts.keyAuthorization);
 | 
				
			||||||
 | 
					        console.log('dnsAuthorization:');
 | 
				
			||||||
 | 
					        console.log(opts.dnsAuthorization);
 | 
				
			||||||
 | 
					        console.log("");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        console.log("Put the string '" + opts.keyAuthorization + "' into a file at '" + opts.hostname + "/" + opts.token + "'");
 | 
				
			||||||
 | 
					        console.log("\nThen hit the 'any' key to continue (must be specifically the 'any' key)...");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return new Promise(function (resolve) {
 | 
				
			||||||
 | 
					          function onAny() {
 | 
				
			||||||
 | 
					            process.stdin.pause();
 | 
				
			||||||
 | 
					            process.stdin.removeEventListener('data', onAny);
 | 
				
			||||||
 | 
					            process.stdin.setRawMode(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            resolve();
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          process.stdin.setRawMode(true);
 | 
				
			||||||
 | 
					          process.stdin.resume();
 | 
				
			||||||
 | 
					          process.stdin.on('data', onAny);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    , removeChallenge: function (opts) {
 | 
				
			||||||
 | 
									// hostname, key
 | 
				
			||||||
 | 
					        console.log('[DEBUG] remove challenge', opts.hostname, opts.keyAuthorization);
 | 
				
			||||||
 | 
					        console.log("Remove the file '" + opts.hostname + "/" + opts.token + "'");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return new Promise(function (resolve) {
 | 
				
			||||||
 | 
					          setTimeout(resolve, 1 * 1000);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    , challengeType: chType
 | 
				
			||||||
 | 
					    , email: email
 | 
				
			||||||
 | 
					    , accountKeypair: RSA.import({ privateKeyPem: require('fs').readFileSync(__dirname + '/account.privkey.pem') })
 | 
				
			||||||
 | 
					    , domainKeypair: RSA.import({ privateKeyPem: require('fs').readFileSync(__dirname + '/privkey.pem') })
 | 
				
			||||||
 | 
					    , domains: web
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    acme2.registerNewAccount(options).then(function (account) {
 | 
				
			||||||
 | 
					      console.log('account:');
 | 
				
			||||||
 | 
					      console.log(account);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      acme2.getCertificate(options, function (fullchainPem) {
 | 
				
			||||||
 | 
					        console.log('[acme-v2] A fullchain.pem:');
 | 
				
			||||||
 | 
					        console.log(fullchainPem);
 | 
				
			||||||
 | 
					      }).then(function (fullchainPem) {
 | 
				
			||||||
 | 
					        console.log('[acme-v2] B fullchain.pem:');
 | 
				
			||||||
 | 
					        console.log(fullchainPem);
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user