more
This commit is contained in:
		
							parent
							
								
									260f0592be
								
							
						
					
					
						commit
						419b84a1ab
					
				
							
								
								
									
										87
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										87
									
								
								README.md
									
									
									
									
									
								
							| @ -1,4 +1,5 @@ | |||||||
| # letsencrypt-express | # letsencrypt-express | ||||||
|  | 
 | ||||||
| Free SSL and Automatic HTTPS for node.js with Express, Connect, and other middleware systems | Free SSL and Automatic HTTPS for node.js with Express, Connect, and other middleware systems | ||||||
| 
 | 
 | ||||||
| ## Coming Soon | ## Coming Soon | ||||||
| @ -9,6 +10,78 @@ We're working on it | |||||||
| 
 | 
 | ||||||
| See [examples/express-minimal.js](https://github.com/Daplie/node-letsencrypt/blob/master/examples/express-minimal.js) | See [examples/express-minimal.js](https://github.com/Daplie/node-letsencrypt/blob/master/examples/express-minimal.js) | ||||||
| 
 | 
 | ||||||
|  | ## Install | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | npm install --save letsencrypt-express | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ## Examples | ||||||
|  | 
 | ||||||
|  | **Minimal** | ||||||
|  | 
 | ||||||
|  | ```javascript | ||||||
|  | 'use strict'; | ||||||
|  | 
 | ||||||
|  | var le = require('letsencrypt-express'); | ||||||
|  | var express = require('express'); | ||||||
|  | var app = express(); | ||||||
|  | 
 | ||||||
|  | app.use('/', function (req, res) { | ||||||
|  |   res.send({ success: true }); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | le.create('/etc/letsencrypt', app).listen([80], [443, 5001], function () { | ||||||
|  |   console.log("ENCRYPT **ALL** THE DOMAINS!"); | ||||||
|  | }); | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### More Options Exposed | ||||||
|  | 
 | ||||||
|  | ```javascript | ||||||
|  | 'use strict'; | ||||||
|  | 
 | ||||||
|  | var le = require('letsencrypt-express'); | ||||||
|  | var express = require('express'); | ||||||
|  | var app = express(); | ||||||
|  | 
 | ||||||
|  | app.use('/', function (req, res) { | ||||||
|  |   res.send({ success: true }); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | var results = le.create({ | ||||||
|  |   configDir: '/etc/letsencrypt' | ||||||
|  | , onRequest: app | ||||||
|  | }).listen( | ||||||
|  | 
 | ||||||
|  |   // you can give just the port, or expand out to the full options | ||||||
|  |   [80, { port: 8080, address: 'localhost', onListening: function () { console.log('http://localhost'); } }] | ||||||
|  | 
 | ||||||
|  |   // you can give just the port, or expand out to the full options | ||||||
|  | , [443, 5001, { port: 8443, address: 'localhost' }] | ||||||
|  | 
 | ||||||
|  |   // this is pretty much the default onListening handler | ||||||
|  | , function onListening() { | ||||||
|  |     var server = this; | ||||||
|  |     var protocol = ('requestCert' in server) ? 'https': 'http'; | ||||||
|  |     console.log("Listening at " + protocol + '://localhost:' + this.address().port); | ||||||
|  |   } | ||||||
|  | ); | ||||||
|  | 
 | ||||||
|  | // In case you need access to the raw servers (i.e. using websockets) | ||||||
|  | console.log(results.plainServers); | ||||||
|  | console.log(results.tlsServers); | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### WebSockets with Let's Encrypt | ||||||
|  | 
 | ||||||
|  | Note: you don't need to create websockets for the plain ports. | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | results.tlsServers.forEach(function (server) { | ||||||
|  | }); | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
| ## Options | ## Options | ||||||
| 
 | 
 | ||||||
| If any of these values are `undefined` or `null` the will assume use reasonable defaults. | If any of these values are `undefined` or `null` the will assume use reasonable defaults. | ||||||
| @ -18,6 +91,9 @@ Partially defined values will be merged with the defaults. | |||||||
| Setting the value to `false` will, in many cases (as documented), disable the defaults. | Setting the value to `false` will, in many cases (as documented), disable the defaults. | ||||||
| 
 | 
 | ||||||
| ``` | ``` | ||||||
|  | configDir: string               // | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| webrootPath: string             // string     a path to a folder where temporary challenge files will be stored and read | webrootPath: string             // string     a path to a folder where temporary challenge files will be stored and read | ||||||
|                                 // default    os.tmpdir() + path.sep + 'acme-challenge' |                                 // default    os.tmpdir() + path.sep + 'acme-challenge' | ||||||
| 
 | 
 | ||||||
| @ -45,4 +121,15 @@ httpsOptions: object            // object     will be merged with internal defau | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| sniCallback: func               // func       replace the default sniCallback handler (which manages certificates) with your own | sniCallback: func               // func       replace the default sniCallback handler (which manages certificates) with your own | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | letsencrypt: object             // object     configure the letsencrypt object yourself and pass it in directly | ||||||
|  |                                 // | ||||||
|  |                                 // default    we create the letsencrypt object using parameters you specify | ||||||
| ``` | ``` | ||||||
|  | 
 | ||||||
|  | ## Heroku? | ||||||
|  | 
 | ||||||
|  | This doesn't work on heroku because heroku uses a proxy with built-in https | ||||||
|  | (which is a smart thing to do) and besides, they want you to pay big bucks | ||||||
|  | for https. (hopefully not for long?...) | ||||||
|  | |||||||
							
								
								
									
										31
									
								
								lib/challenge-handlers.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								lib/challenge-handlers.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | |||||||
|  | 'use strict'; | ||||||
|  | 
 | ||||||
|  | var fs = require('fs'); | ||||||
|  | var path = require('path'); | ||||||
|  | 
 | ||||||
|  | // TODO handle templating :hostname in letsencrypt proper
 | ||||||
|  | 
 | ||||||
|  | // Note: we're explicitly doing this on the filesystem
 | ||||||
|  | // rather than in-memory to support node cluster
 | ||||||
|  | 
 | ||||||
|  | module.exports = { | ||||||
|  |   set: function setChallenge(args, hostname, key, value, cb) { | ||||||
|  |     var keyfile = path.join((args.webrootPath || args.webrootTpl).replace(':hostname', hostname), key); | ||||||
|  | 
 | ||||||
|  |     fs.writeFile(keyfile, value, 'utf8', cb); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  | , get: function getChallenge(args, hostname, key, cb) { | ||||||
|  |     var keyfile = path.join((args.webrootPath || args.webrootTpl).replace(':hostname', hostname), key); | ||||||
|  | 
 | ||||||
|  |     fs.readFile(keyfile, 'utf8', cb); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  | , remove: function removeChallenge(args, hostname, key, cb) { | ||||||
|  |     var keyfile = path.join((args.webrootPath || args.webrootTpl).replace(':hostname', hostname), key); | ||||||
|  | 
 | ||||||
|  |     // 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!
 | ||||||
|  |     fs.unlink(keyfile, cb); | ||||||
|  |   } | ||||||
|  | }; | ||||||
| @ -1,22 +1,10 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
| 
 | 
 | ||||||
| var path = require('path'); | var path = require('path'); | ||||||
|  | var challengeStore = require('./lib/challange-handlers'); | ||||||
| 
 | 
 | ||||||
| function getChallenge(args, hostname, key, cb) { | function create(obj, app) { | ||||||
|   var fs = require('fs'); |   var LE = require('letsencrypt'); | ||||||
|   var keyfile = path.join((args.webrootPath || args.webrootTpl).replace(':hostname', hostname), key); |  | ||||||
| 
 |  | ||||||
|   fs.readFile(keyfile, 'utf8', function (err, text) { |  | ||||||
|     if (err) { |  | ||||||
|       cb(err); |  | ||||||
|       return; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     cb(null, text); |  | ||||||
|   }); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| function create(obj) { |  | ||||||
|   var https = require('https'); |   var https = require('https'); | ||||||
|   var http = require('http'); |   var http = require('http'); | ||||||
| 
 | 
 | ||||||
| @ -26,12 +14,23 @@ function create(obj) { | |||||||
|   if (!obj) { |   if (!obj) { | ||||||
|     obj = {}; |     obj = {}; | ||||||
|   } |   } | ||||||
|   else if ('function' === typeof obj) { | 
 | ||||||
|  |   if ('string' === typeof obj) { | ||||||
|  |     obj = { | ||||||
|  |       configDir: obj | ||||||
|  |     }; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   if ('function' === typeof obj) { | ||||||
|     obj = { |     obj = { | ||||||
|       onRequest: obj |       onRequest: obj | ||||||
|     }; |     }; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   if ('function' === typeof app) { | ||||||
|  |     obj.onRequest = obj.onRequest || app; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   if (!obj.getChallenge) { |   if (!obj.getChallenge) { | ||||||
|     if (false !== obj.getChallenge) { |     if (false !== obj.getChallenge) { | ||||||
|       obj.getChallenge = getChallenge; |       obj.getChallenge = getChallenge; | ||||||
| @ -41,11 +40,18 @@ function create(obj) { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   if (!obj.onRequest) { |   if (!obj.onRequest && false !== obj.onRequest) { | ||||||
|     console.warn("You did not specify args.onRequest, using 'Hello, World!'"); |     console.warn("You should either do args.onRequest = app or server.on('request', app)," | ||||||
|     obj.onRequest = function (req, res) { |       + " otherwise only acme-challenge requests will be handled (and the rest will hang)"); | ||||||
|       res.end('Hello, World!'); |     console.warn("You can silence this warning by setting args.onRequest = false"); | ||||||
|     }; |   } | ||||||
|  | 
 | ||||||
|  |   if (!obj.letsencrypt) { | ||||||
|  |     //LE.merge(obj, );
 | ||||||
|  |     obj.letsencrypt = LE.create(obj, { | ||||||
|  |       setChallenge: setChallenge | ||||||
|  |     , removeChallenge: removeChallenge | ||||||
|  |     }); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   function acmeResponder(req, res) { |   function acmeResponder(req, res) { | ||||||
| @ -142,7 +148,7 @@ function create(obj) { | |||||||
| 
 | 
 | ||||||
|     // deleting creates a "slow object", but that's okay (we only use it once)
 |     // deleting creates a "slow object", but that's okay (we only use it once)
 | ||||||
|     return results; |     return results; | ||||||
|   }; |   } | ||||||
| 
 | 
 | ||||||
|   return { |   return { | ||||||
|     listen: listen |     listen: listen | ||||||
| @ -151,4 +157,6 @@ function create(obj) { | |||||||
| 
 | 
 | ||||||
| module.exports = create; | module.exports = create; | ||||||
| module.exports.create = create; | module.exports.create = create; | ||||||
| module.exports.getChallenge = getChallenge; | module.exports.setChallenge = challengeStore.set; | ||||||
|  | module.exports.getChallenge = challengeStore.get; | ||||||
|  | module.exports.removeChallenge = challengeStore.remove; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user