w00t!
This commit is contained in:
		
							parent
							
								
									f227a3ea6c
								
							
						
					
					
						commit
						765293de3f
					
				
							
								
								
									
										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