mirror of
				https://github.com/therootcompany/greenlock-express.js.git
				synced 2024-11-16 17:28:59 +00:00 
			
		
		
		
	w00tgit add package.json
This commit is contained in:
		
							parent
							
								
									f227a3ea6c
								
							
						
					
					
						commit
						822650936a
					
				
							
								
								
									
										19
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								README.md
									
									
									
									
									
								
							@ -32,7 +32,24 @@ app.use('/', function (req, res) {
 | 
				
			|||||||
  res.send({ success: true });
 | 
					  res.send({ success: true });
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
lex.create('/etc/letsencrypt', app).listen([80], [443, 5001], function () {
 | 
					lex.create(app).listen();
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Slightly more verbose
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```javascript
 | 
				
			||||||
 | 
					'use strict';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Note: using staging server url, remove .testing() for production
 | 
				
			||||||
 | 
					var lex = require('letsencrypt-express').testing();
 | 
				
			||||||
 | 
					var express = require('express');
 | 
				
			||||||
 | 
					var app = express();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					app.use('/', function (req, res) {
 | 
				
			||||||
 | 
					  res.send({ success: true });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					lex.create('./letsencrypt.config', app).listen([80], [443, 5001], function () {
 | 
				
			||||||
  console.log("ENCRYPT __ALL__ THE DOMAINS!");
 | 
					  console.log("ENCRYPT __ALL__ THE DOMAINS!");
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										9
									
								
								examples/116.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								examples/116.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					'use strict';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Don't try this at home kids, it's just for fun
 | 
				
			||||||
 | 
					// 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// require('letsencrypt-express')
 | 
				
			||||||
 | 
					require('../').testing().create(require('express')().use(function (_, r) {
 | 
				
			||||||
 | 
					  r.end('Hi!');
 | 
				
			||||||
 | 
					})).listen();
 | 
				
			||||||
@ -1,12 +1,14 @@
 | 
				
			|||||||
'use strict';
 | 
					'use strict';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//var le = require('letsencrypt-express');
 | 
					// Note: using staging server url, remove .testing() for production
 | 
				
			||||||
var le = require('../').testing();
 | 
					var lex = require('letsencrypt-express').testing();
 | 
				
			||||||
var express = require('express');
 | 
					var express = require('express');
 | 
				
			||||||
var app = express();
 | 
					var app = express();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
app.use(function (req, res) {
 | 
					app.use('/', function (req, res) {
 | 
				
			||||||
  res.send({ success: true });
 | 
					  res.send({ success: true });
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
le.create('./letsencrypt.config', app).listen([80], [443, 5001]);
 | 
					lex.create('./letsencrypt.config', app).listen([80], [443, 5001], function () {
 | 
				
			||||||
 | 
					  console.log("ENCRYPT __ALL__ THE DOMAINS!");
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										1
									
								
								examples/tweet.js
									
									
									
									
									
										Symbolic link
									
								
							
							
						
						
									
										1
									
								
								examples/tweet.js
									
									
									
									
									
										Symbolic link
									
								
							@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					116.js
 | 
				
			||||||
@ -11,18 +11,20 @@ var mkdirp = require('mkdirp');
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
module.exports = {
 | 
					module.exports = {
 | 
				
			||||||
  set: function setChallenge(args, hostname, key, value, cb) {
 | 
					  set: function setChallenge(args, hostname, key, value, cb) {
 | 
				
			||||||
    var webrootPath = (args.webrootPath || args.webrootTpl).replace(':hostname', hostname);
 | 
					    var webrootPath = args.webrootPath;
 | 
				
			||||||
    var keyfile = path.join(webrootPath, key);
 | 
					    var keyfile = path.join(webrootPath, key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (args.debug) {
 | 
					    if (args.debug) {
 | 
				
			||||||
      console.log('[LEX] write file', hostname, webrootPath, key);
 | 
					      console.debug('[LEX] write file', hostname, webrootPath);
 | 
				
			||||||
 | 
					      console.debug('challenge:', key);
 | 
				
			||||||
 | 
					      console.debug('response:', value);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    fs.writeFile(keyfile, value, 'utf8', function (err) {
 | 
					    fs.writeFile(keyfile, value, 'utf8', function (err) {
 | 
				
			||||||
      if (!err) { cb(null); return; }
 | 
					      if (!err) { cb(null); return; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (args.debug) {
 | 
					      if (args.debug) {
 | 
				
			||||||
        console.log('[LEX] mkdirp', webrootPath);
 | 
					        console.debug('[LEX] mkdirp', webrootPath);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      mkdirp(webrootPath, function () {
 | 
					      mkdirp(webrootPath, function () {
 | 
				
			||||||
        if (err) { cb(err); return; }
 | 
					        if (err) { cb(err); return; }
 | 
				
			||||||
@ -33,10 +35,10 @@ module.exports = {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
, get: function getChallenge(args, hostname, key, cb) {
 | 
					, get: function getChallenge(args, hostname, key, cb) {
 | 
				
			||||||
    var keyfile = path.join((args.webrootPath || args.webrootTpl).replace(':hostname', hostname), key);
 | 
					    var keyfile = path.join(args.webrootPath, key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (args.debug) {
 | 
					    if (args.debug) {
 | 
				
			||||||
      console.log('[LEX] getChallenge', hostname, key);
 | 
					      console.debug('[LEX] getChallenge', keyfile, hostname, key);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    fs.readFile(keyfile, 'utf8', function (err, text) {
 | 
					    fs.readFile(keyfile, 'utf8', function (err, text) {
 | 
				
			||||||
      cb(null, text);
 | 
					      cb(null, text);
 | 
				
			||||||
@ -44,12 +46,12 @@ module.exports = {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
, remove: function removeChallenge(args, hostname, key, cb) {
 | 
					, remove: function removeChallenge(args, hostname, key, cb) {
 | 
				
			||||||
    var keyfile = path.join((args.webrootPath || args.webrootTpl).replace(':hostname', hostname), key);
 | 
					    var keyfile = path.join(args.webrootPath, key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Note: it's not actually terribly important that we wait for the unlink callback
 | 
					    // Note: it's not actually terribly important that we wait for the unlink callback
 | 
				
			||||||
    // but it's a polite thing to do - and we're polite people!
 | 
					    // but it's a polite thing to do - and we're polite people!
 | 
				
			||||||
    if (args.debug) {
 | 
					    if (args.debug) {
 | 
				
			||||||
      console.log('[LEX] removeChallenge', hostname, key);
 | 
					      console.debug('[LEX] removeChallenge', keyfile, hostname, key);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    fs.unlink(keyfile, function (err) {
 | 
					    fs.unlink(keyfile, function (err) {
 | 
				
			||||||
      if (err) { console.warn(err.stack); }
 | 
					      if (err) { console.warn(err.stack); }
 | 
				
			||||||
 | 
				
			|||||||
@ -5,7 +5,7 @@ var tls = require('tls');
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
module.exports.create = function (opts) {
 | 
					module.exports.create = function (opts) {
 | 
				
			||||||
  if (opts.debug) {
 | 
					  if (opts.debug) {
 | 
				
			||||||
    console.log("[LEX] creating sniCallback", JSON.stringify(opts, null, '  '));
 | 
					    console.debug("[LEX] creating sniCallback", JSON.stringify(opts, null, '  '));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  var ipc = {}; // in-process cache
 | 
					  var ipc = {}; // in-process cache
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -23,7 +23,7 @@ module.exports.create = function (opts) {
 | 
				
			|||||||
  function assignBestByDates(now, certInfo) {
 | 
					  function assignBestByDates(now, certInfo) {
 | 
				
			||||||
    certInfo = certInfo || { loadedAt: now, expiresAt: 0, issuedAt: 0, lifetime: 0 };
 | 
					    certInfo = certInfo || { loadedAt: now, expiresAt: 0, issuedAt: 0, lifetime: 0 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    var rnds = crypto.randomBytes(3)[0];
 | 
					    var rnds = crypto.randomBytes(3);
 | 
				
			||||||
    var rnd1 = ((rnds[0] + 1) / 257);
 | 
					    var rnd1 = ((rnds[0] + 1) / 257);
 | 
				
			||||||
    var rnd2 = ((rnds[1] + 1) / 257);
 | 
					    var rnd2 = ((rnds[1] + 1) / 257);
 | 
				
			||||||
    var rnd3 = ((rnds[2] + 1) / 257);
 | 
					    var rnd3 = ((rnds[2] + 1) / 257);
 | 
				
			||||||
@ -41,6 +41,8 @@ module.exports.create = function (opts) {
 | 
				
			|||||||
    certInfo.memorizeFor = memorizeFor;
 | 
					    certInfo.memorizeFor = memorizeFor;
 | 
				
			||||||
    certInfo.bestIfUsedBy = bestIfUsedBy;
 | 
					    certInfo.bestIfUsedBy = bestIfUsedBy;
 | 
				
			||||||
    certInfo.renewTimeout = renewTimeout;
 | 
					    certInfo.renewTimeout = renewTimeout;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return certInfo;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function renewInBackground(now, hostname, certInfo) {
 | 
					  function renewInBackground(now, hostname, certInfo) {
 | 
				
			||||||
@ -57,7 +59,7 @@ module.exports.create = function (opts) {
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (opts.debug) {
 | 
					      if (opts.debug) {
 | 
				
			||||||
        console.log("[LEX] skipping stagger '" + certInfo.renewTimeout + "' and renewing '" + hostname + "' now");
 | 
					        console.debug("[LEX] skipping stagger '" + certInfo.renewTimeout + "' and renewing '" + hostname + "' now");
 | 
				
			||||||
        certInfo.renewTimeout = 500;
 | 
					        certInfo.renewTimeout = 500;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -73,71 +75,88 @@ module.exports.create = function (opts) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function fetch(hostname, cb) {
 | 
					  function cacheResult(err, hostname, certInfo, sniCb) {
 | 
				
			||||||
 | 
					    if (certInfo && certInfo.fullchain && certInfo.privkey) {
 | 
				
			||||||
 | 
					      if (opts.debug) {
 | 
				
			||||||
 | 
					        console.debug('cert is looking good');
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      try {
 | 
				
			||||||
 | 
					        certInfo.tlsContext = tls.createSecureContext({
 | 
				
			||||||
 | 
					          key: certInfo.privkey || certInfo.key         // privkey.pem
 | 
				
			||||||
 | 
					        , cert: certInfo.fullchain || certInfo.cert     // fullchain.pem (cert.pem + '\n' + chain.pem)
 | 
				
			||||||
 | 
					        });  
 | 
				
			||||||
 | 
					      } catch(e) {
 | 
				
			||||||
 | 
					        console.warn("[Sanity Check Fail]: a weird object was passed back through le.fetch to lex.fetch");
 | 
				
			||||||
 | 
					        console.warn("(either missing or malformed certInfo.key and / or certInfo.fullchain)");
 | 
				
			||||||
 | 
					        err = e;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      sniCb(err, certInfo.tlsContext);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      if (opts.debug) {
 | 
				
			||||||
 | 
					        console.debug('cert is NOT looking good');
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      sniCb(err || new Error("couldn't get certInfo: unknown"), null);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    var now = Date.now();
 | 
				
			||||||
 | 
					    certInfo = ipc[hostname] = assignBestByDates(now, certInfo);
 | 
				
			||||||
 | 
					    renewInBackground(now, hostname, certInfo);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function registerCert(hostname, sniCb) {
 | 
				
			||||||
 | 
					    if (opts.debug) {
 | 
				
			||||||
 | 
					      console.debug("[LEX] '" + hostname + "' is not registered, requesting approval");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    opts.approveRegistration(hostname, function (err, args) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (opts.debug) {
 | 
				
			||||||
 | 
					        console.debug("[LEX] '" + hostname + "' registration approved, attempting register");
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (err) {
 | 
				
			||||||
 | 
					        cacheResult(err, hostname, null, sniCb);
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (!(args && args.agreeTos && args.email && args.domains)) {
 | 
				
			||||||
 | 
					        cacheResult(new Error("not approved or approval is missing arguments - such as agreeTos, email, domains"), hostname, null, sniCb);
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      opts.letsencrypt.register(args, function (err, certInfo) {
 | 
				
			||||||
 | 
					        if (opts.debug) {
 | 
				
			||||||
 | 
					          console.debug("[LEX] '" + hostname + "' register completed", err && err.stack || null, certInfo);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        cacheResult(err, hostname, certInfo, sniCb);
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function fetch(hostname, sniCb) {
 | 
				
			||||||
    opts.letsencrypt.fetch({ domains: [hostname] }, function (err, certInfo) {
 | 
					    opts.letsencrypt.fetch({ domains: [hostname] }, function (err, certInfo) {
 | 
				
			||||||
      if (opts.debug) {
 | 
					      if (opts.debug) {
 | 
				
			||||||
        console.log("[LEX] fetch result '" + hostname + "':");
 | 
					        console.debug("[LEX] fetch from disk result '" + hostname + "':");
 | 
				
			||||||
        console.log(err, certInfo);
 | 
					        console.debug(certInfo && Object.keys(certInfo));
 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      if (err) {
 | 
					 | 
				
			||||||
        cb(err);
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      var now = Date.now();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      if (!certInfo) {
 | 
					 | 
				
			||||||
        // handles registration
 | 
					 | 
				
			||||||
        if (opts.debug) {
 | 
					 | 
				
			||||||
          console.log("[LEX] '" + hostname + "' is not registered, requesting approval");
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        opts.approveRegistration(hostname, function (err, args) {
 | 
					 | 
				
			||||||
          if (opts.debug) {
 | 
					 | 
				
			||||||
            console.log("[LEX] '" + hostname + "' registration approved, attempting register");
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
          if (err || !(args && args.agreeTos)) {
 | 
					 | 
				
			||||||
            done(err, certInfo);
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
          opts.letsencrypt.register(args, function (err, certInfo) {
 | 
					 | 
				
			||||||
            if (opts.debug) {
 | 
					 | 
				
			||||||
              console.log("[LEX] '" + hostname + "' register completed", err, certInfo);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            done(err, certInfo);
 | 
					 | 
				
			||||||
          });
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      done(err, certInfo);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      function done(err, certInfo) {
 | 
					 | 
				
			||||||
        ipc[hostname] = assignBestByDates(now, certInfo);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // handles renewals
 | 
					 | 
				
			||||||
        renewInBackground(now, hostname, certInfo);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (err) {
 | 
					        if (err) {
 | 
				
			||||||
          cb(err);
 | 
					          console.error(err.stack || err);
 | 
				
			||||||
          return;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (!certInfo.tlsContext && null !== certInfo.tlsContext) {
 | 
					 | 
				
			||||||
          try {
 | 
					 | 
				
			||||||
            certInfo.tlsContext = tls.createSecureContext({
 | 
					 | 
				
			||||||
              key: certInfo.key                             // privkey.pem
 | 
					 | 
				
			||||||
            , cert: certInfo.cert                           // fullchain.pem (cert.pem + '\n' + chain.pem)
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
          } catch(e) {
 | 
					 | 
				
			||||||
            certInfo.tlsContext = null;
 | 
					 | 
				
			||||||
            console.warn("[Sanity Check Fail]: a weird object was passed back through le.fetch to lex.fetch");
 | 
					 | 
				
			||||||
            cb(e);
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        cb(null, certInfo.tlsContext);
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (err) {
 | 
				
			||||||
 | 
					        sniCb(err, null);
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (certInfo) {
 | 
				
			||||||
 | 
					        cacheResult(err, hostname, certInfo, sniCb);
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      registerCert(hostname, sniCb);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -145,29 +164,44 @@ module.exports.create = function (opts) {
 | 
				
			|||||||
    var now = Date.now();
 | 
					    var now = Date.now();
 | 
				
			||||||
    var certInfo = ipc[hostname];
 | 
					    var certInfo = ipc[hostname];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // TODO once ECDSA is available, wait for cert renewal if its due
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //
 | 
				
			||||||
 | 
					    // No cert is available in cache.
 | 
				
			||||||
 | 
					    // try to fetch it from disk quickly
 | 
				
			||||||
 | 
					    // and return to the browser
 | 
				
			||||||
 | 
					    //
 | 
				
			||||||
    if (!certInfo) {
 | 
					    if (!certInfo) {
 | 
				
			||||||
      if (opts.debug) {
 | 
					      if (opts.debug) {
 | 
				
			||||||
        console.log("[LEX] no certs loaded for '" + hostname + "'");
 | 
					        console.debug("[LEX] no certs loaded for '" + hostname + "'");
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      fetch(hostname, cb);
 | 
					      fetch(hostname, cb);
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //
 | 
				
			||||||
 | 
					    // A cert is available
 | 
				
			||||||
 | 
					    // See if it's old enough that
 | 
				
			||||||
 | 
					    // we should refresh it from disk
 | 
				
			||||||
 | 
					    // (in the background)
 | 
				
			||||||
 | 
					    // 
 | 
				
			||||||
 | 
					    // TODO once ECDSA is available, wait for cert renewal if its due (maybe?)
 | 
				
			||||||
    if (certInfo.tlsContext) {
 | 
					    if (certInfo.tlsContext) {
 | 
				
			||||||
      cb(null, certInfo.tlsContext);
 | 
					      cb(null, certInfo.tlsContext);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if ((now - certInfo.loadedAt) < (certInfo.memorizeFor)) {
 | 
					      if ((now - certInfo.loadedAt) < (certInfo.memorizeFor)) {
 | 
				
			||||||
        // these aren't stale, so don't fall through
 | 
					        // these aren't stale, so don't fall through
 | 
				
			||||||
        if (opts.debug) {
 | 
					        if (opts.debug) {
 | 
				
			||||||
          console.log("[LEX] certs for '" + hostname + "' are fresh from disk");
 | 
					          console.debug("[LEX] certs for '" + hostname + "' are fresh from disk");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else if ((now - certInfo.loadedAt) < opts.failedWait) {
 | 
					    else if ((now - certInfo.loadedAt) < opts.failedWait) {
 | 
				
			||||||
      if (opts.debug) {
 | 
					      if (opts.debug) {
 | 
				
			||||||
        console.log("[LEX] certs for '" + hostname + "' recently failed and are still in cool down");
 | 
					        console.debug("[LEX] certs for '" + hostname + "' recently failed and are still in cool down");
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      // this was just fetched and failed, wait a few minutes
 | 
					      // this was just fetched and failed, wait a few minutes
 | 
				
			||||||
      cb(null, null);
 | 
					      cb(null, null);
 | 
				
			||||||
@ -175,7 +209,19 @@ module.exports.create = function (opts) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (opts.debug) {
 | 
					    if (opts.debug) {
 | 
				
			||||||
      console.log("[LEX] certs for '" + hostname + "' are stale on disk and should be will be fetched again");
 | 
					      console.debug("[LEX] certs for '" + hostname + "' are stale on disk and should be will be fetched again");
 | 
				
			||||||
 | 
					      console.debug({
 | 
				
			||||||
 | 
					        age: now - certInfo.loadedAt
 | 
				
			||||||
 | 
					      , loadedAt: certInfo.loadedAt
 | 
				
			||||||
 | 
					      , issuedAt: certInfo.issuedAt
 | 
				
			||||||
 | 
					      , expiresAt: certInfo.expiresAt
 | 
				
			||||||
 | 
					      , privkey: !!certInfo.privkey
 | 
				
			||||||
 | 
					      , chain: !!certInfo.chain
 | 
				
			||||||
 | 
					      , fullchain: !!certInfo.fullchain
 | 
				
			||||||
 | 
					      , cert: !!certInfo.cert
 | 
				
			||||||
 | 
					      , memorizeFor: certInfo.memorizeFor
 | 
				
			||||||
 | 
					      , failedWait: opts.failedWait
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    fetch(hostname, cb);
 | 
					    fetch(hostname, cb);
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
				
			|||||||
@ -48,7 +48,19 @@ function LEX(obj, app) {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (!obj.configDir) {
 | 
					  if (!obj.configDir) {
 | 
				
			||||||
    obj.configDir = require('os').homedir() + '/letsencrypt/etc';
 | 
					    obj.configDir = path.join(require('homedir')(), '/letsencrypt/etc');
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (!obj.privkeyPath) {
 | 
				
			||||||
 | 
					    obj.privkeyPath = ':config/live/:hostname/privkey.pem';
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (!obj.fullchainPath) {
 | 
				
			||||||
 | 
					    obj.fullchainPath = ':config/live/:hostname/fullchain.pem';
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (!obj.certPath) {
 | 
				
			||||||
 | 
					    obj.certPath = ':config/live/:hostname/cert.pem';
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (!obj.chainPath) {
 | 
				
			||||||
 | 
					    obj.chainPath = ':config/live/:hostname/chain.pem';
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (!obj.server) {
 | 
					  if (!obj.server) {
 | 
				
			||||||
@ -66,7 +78,7 @@ function LEX(obj, app) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  function acmeResponder(req, res) {
 | 
					  function acmeResponder(req, res) {
 | 
				
			||||||
    if (LEX.debug) {
 | 
					    if (LEX.debug) {
 | 
				
			||||||
      console.log('[LEX] ', req.method, req.headers.host, req.url);
 | 
					      console.debug('[LEX] ', req.method, req.headers.host, req.url);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    var acmeChallengePrefix = '/.well-known/acme-challenge/';
 | 
					    var acmeChallengePrefix = '/.well-known/acme-challenge/';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -79,7 +91,12 @@ function LEX(obj, app) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    obj.getChallenge(obj, req.headers.host, key, function (err, val) {
 | 
					    obj.getChallenge(obj, req.headers.host, key, function (err, val) {
 | 
				
			||||||
      if (LEX.debug) {
 | 
					      if (LEX.debug) {
 | 
				
			||||||
        console.log('[LEX] challenge response:', key, err, val);
 | 
					        console.debug('[LEX] GET challenge, response:');
 | 
				
			||||||
 | 
					        console.debug('challenge:', key);
 | 
				
			||||||
 | 
					        console.debug('response:', val);
 | 
				
			||||||
 | 
					        if (err) {
 | 
				
			||||||
 | 
					          console.debug(err.stack);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      res.end(val || '_');
 | 
					      res.end(val || '_');
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
@ -109,7 +126,7 @@ function LEX(obj, app) {
 | 
				
			|||||||
  if (!obj.approveRegistration && LEX.defaultApproveRegistration) {
 | 
					  if (!obj.approveRegistration && LEX.defaultApproveRegistration) {
 | 
				
			||||||
    obj.approveRegistration = function (domain, cb) {
 | 
					    obj.approveRegistration = function (domain, cb) {
 | 
				
			||||||
      if (LEX.debug) {
 | 
					      if (LEX.debug) {
 | 
				
			||||||
        console.log('[LEX] auto register against staging server');
 | 
					        console.debug('[LEX] auto register against staging server');
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      cb(null, {
 | 
					      cb(null, {
 | 
				
			||||||
        email: 'example@gmail.com'
 | 
					        email: 'example@gmail.com'
 | 
				
			||||||
@ -130,7 +147,6 @@ function LEX(obj, app) {
 | 
				
			|||||||
  else if (sniCallback) {
 | 
					  else if (sniCallback) {
 | 
				
			||||||
    obj._sniCallback = createSniCallback(obj);
 | 
					    obj._sniCallback = createSniCallback(obj);
 | 
				
			||||||
    httpsOptions.SNICallback = function (domain, cb) {
 | 
					    httpsOptions.SNICallback = function (domain, cb) {
 | 
				
			||||||
      console.log('[LEX] auto register against staging server');
 | 
					 | 
				
			||||||
      sniCallback(domain, function (err, context) {
 | 
					      sniCallback(domain, function (err, context) {
 | 
				
			||||||
        if (context) {
 | 
					        if (context) {
 | 
				
			||||||
          cb(err, context);
 | 
					          cb(err, context);
 | 
				
			||||||
@ -220,6 +236,41 @@ LEX.setChallenge = challengeStore.set;
 | 
				
			|||||||
LEX.getChallenge = challengeStore.get;
 | 
					LEX.getChallenge = challengeStore.get;
 | 
				
			||||||
LEX.removeChallenge = challengeStore.remove;
 | 
					LEX.removeChallenge = challengeStore.remove;
 | 
				
			||||||
LEX.createSniCallback = createSniCallback;
 | 
					LEX.createSniCallback = createSniCallback;
 | 
				
			||||||
 | 
					// TODO not sure how well this works
 | 
				
			||||||
 | 
					LEX.middleware = function (defaults) {
 | 
				
			||||||
 | 
					  var leCore = require('letiny-core');
 | 
				
			||||||
 | 
					  var merge = require('letsencrypt/common').merge;
 | 
				
			||||||
 | 
					  var tplConfigDir = require('letsencrypt/common').tplConfigDir;
 | 
				
			||||||
 | 
					  var tplHostname = require('letsencrypt/common').tplHostname;
 | 
				
			||||||
 | 
					  var prefix = leCore.acmeChallengePrefix;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  tplConfigDir(defaults.configDir || '', defaults);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return function (req, res, next) {
 | 
				
			||||||
 | 
					    if (LEX.debug) {
 | 
				
			||||||
 | 
					      console.debug('[LEX middleware]:', req.hostname, req.url, req.url.slice(prefix.length));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (0 !== req.url.indexOf(prefix)) {
 | 
				
			||||||
 | 
					      next();
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function done(err, token) {
 | 
				
			||||||
 | 
					      if (err) {
 | 
				
			||||||
 | 
					        res.send("Error: These aren't the tokens you're looking for. Move along.");
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      res.send(token);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    var copy = merge(defaults, { domains: [req.hostname] });
 | 
				
			||||||
 | 
					    tplHostname(req.hostname, copy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    LEX.getChallenge(copy, req.hostname, req.url.slice(prefix.length), done);
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
LEX.stagingServerUrl = LE.stagingServerUrl;
 | 
					LEX.stagingServerUrl = LE.stagingServerUrl;
 | 
				
			||||||
LEX.productionServerUrl = LE.productionServerUrl || LE.liveServerUrl;
 | 
					LEX.productionServerUrl = LE.productionServerUrl || LE.liveServerUrl;
 | 
				
			||||||
@ -228,9 +279,24 @@ LEX.testing = function () {
 | 
				
			|||||||
  LEX.debug = true;
 | 
					  LEX.debug = true;
 | 
				
			||||||
  LEX.defaultServerUrl = LEX.stagingServerUrl;
 | 
					  LEX.defaultServerUrl = LEX.stagingServerUrl;
 | 
				
			||||||
  LEX.defaultApproveRegistration = true;
 | 
					  LEX.defaultApproveRegistration = true;
 | 
				
			||||||
  console.log('[LEX] testing mode turned on');
 | 
					  console.debug = console.log;
 | 
				
			||||||
  console.log('[LEX] default server: ' + LEX.defaultServerUrl);
 | 
					  console.debug('[LEX] testing mode turned on');
 | 
				
			||||||
  console.log('[LEX] automatic registration handling turned on for testing.');
 | 
					  console.debug('[LEX] default server: ' + LEX.defaultServerUrl);
 | 
				
			||||||
 | 
					  console.debug('\n');
 | 
				
			||||||
 | 
					  console.debug('###################################################');
 | 
				
			||||||
 | 
					  console.debug('#                                                 #');
 | 
				
			||||||
 | 
					  console.debug('#     Open up a browser and visit this server     #');
 | 
				
			||||||
 | 
					  console.debug('#     at its domain name.                         #');
 | 
				
			||||||
 | 
					  console.debug('#                                                 #');
 | 
				
			||||||
 | 
					  console.debug('#                                 ENJOY!          #');
 | 
				
			||||||
 | 
					  console.debug('#                                                 #');
 | 
				
			||||||
 | 
					  console.debug('###################################################');
 | 
				
			||||||
 | 
					  console.debug('\n');
 | 
				
			||||||
 | 
					  console.debug('Note: testing certs will be installed because .testing() was called.');
 | 
				
			||||||
 | 
					  console.debug('      remove .testing() to get live certs.');
 | 
				
			||||||
 | 
					  console.debug('\n');
 | 
				
			||||||
 | 
					  console.debug('[LEX] automatic registration handling turned on for testing.');
 | 
				
			||||||
 | 
					  console.debug('\n');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return module.exports;
 | 
					  return module.exports;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -34,6 +34,7 @@
 | 
				
			|||||||
  },
 | 
					  },
 | 
				
			||||||
  "homepage": "https://github.com/Daplie/letsencrypt-express#readme",
 | 
					  "homepage": "https://github.com/Daplie/letsencrypt-express#readme",
 | 
				
			||||||
  "dependencies": {
 | 
					  "dependencies": {
 | 
				
			||||||
 | 
					    "homedir": "^0.6.0",
 | 
				
			||||||
    "letsencrypt": "^1.1.0",
 | 
					    "letsencrypt": "^1.1.0",
 | 
				
			||||||
    "mkdirp": "^0.5.1"
 | 
					    "mkdirp": "^0.5.1"
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user