a special treat
This commit is contained in:
		
							parent
							
								
									7a208b0308
								
							
						
					
					
						commit
						8ccd89ddfd
					
				
							
								
								
									
										222
									
								
								bin/lex.js
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										222
									
								
								bin/lex.js
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,222 @@ | |||||||
|  | #!/usr/bin/env node
 | ||||||
|  | 'use strict'; | ||||||
|  | 
 | ||||||
|  | var fs = require('fs'); | ||||||
|  | var path = require('path'); | ||||||
|  | var mkdirp = require('fs'); | ||||||
|  | var cli = require('cli'); | ||||||
|  | var mkdirp = require('mkdirp'); | ||||||
|  | var homedir = require('os').homedir(); | ||||||
|  | var configDir = path.join(homedir, 'letsencrypt'); | ||||||
|  | var desktop = path.join(homedir, 'Desktop'); | ||||||
|  | var vhostDir = path.join(fs.existsSync(desktop) ? desktop : configDir, 'www'); | ||||||
|  | var welcomeHtml = fs.readFileSync(path.join(__dirname, '..', 'lib', 'public', 'welcome.html'), 'utf8'); | ||||||
|  | var express = require('express'); | ||||||
|  | 
 | ||||||
|  | cli.parse({ | ||||||
|  |   'agree-tos': [ false, " Agree to the Let's Encrypt Subscriber Agreement", 'boolean', false ] | ||||||
|  | , email: [ false, " Email used for registration and recovery contact. (default: null)", 'email' ] | ||||||
|  | , domains: [ false, " Domain names to apply. To include the www domain with your main domain your can enter both with a comma. Ex --domains example.com,www.example.com (default: [])", 'string' ] | ||||||
|  | , debug: [ false, " show traces and logs", 'boolean', false ] | ||||||
|  | , server: [ false, " ACME Directory Resource URI.", 'string', 'https://acme-v01.api.letsencrypt.org/directory)' ] | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | // ignore certonly and extraneous arguments
 | ||||||
|  | cli.main(function(_, options) { | ||||||
|  |   console.log(''); | ||||||
|  |   var args = {}; | ||||||
|  | 
 | ||||||
|  |   Object.keys(options).forEach(function (key) { | ||||||
|  |     var val = options[key]; | ||||||
|  | 
 | ||||||
|  |     if ('string' === typeof val) { | ||||||
|  |       val = val.replace(/^~/, homedir); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     key = key.replace(/\-([a-z0-9A-Z])/g, function (c) { return c[1].toUpperCase(); }); | ||||||
|  |     args[key] = val; | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   if (args.domains) { | ||||||
|  |     args.domains = args.domains.split(','); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   makeDirectories(); | ||||||
|  | 
 | ||||||
|  |   function makeDirectories() { | ||||||
|  |     mkdirp(configDir, function (err) { | ||||||
|  |       if (err) { | ||||||
|  |         console.error("Could not create config directory '" + configDir + "':", err.code); | ||||||
|  |         console.error(err.stack); | ||||||
|  |         return; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       mkdirp(vhostDir, function (err) { | ||||||
|  |         if (err) { | ||||||
|  |           console.error("Could not create vhost directory '" + vhostDir + "':", err.code); | ||||||
|  |           console.error(err.stack); | ||||||
|  |           return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         startServers(); | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   function configure(le, args, cb) { | ||||||
|  |     var vhost; | ||||||
|  |     var pubDir; | ||||||
|  |     var index; | ||||||
|  | 
 | ||||||
|  |     if (!(args.email && args.agreeTos && args.server && args.domains)) { | ||||||
|  |       cb({ error : { message: "missing one or more of agreeTos,domains,email,server" } }); | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     vhost = args.domains[0]; | ||||||
|  |     pubDir = path.join(vhostDir, vhost); | ||||||
|  |     index = path.join(pubDir, 'index.html'); | ||||||
|  | 
 | ||||||
|  |     makeLandingPage(); | ||||||
|  | 
 | ||||||
|  |     function makeLandingPage() { | ||||||
|  |       mkdirp(pubDir, function (err) { | ||||||
|  |         if (err) { | ||||||
|  |           cb(err); | ||||||
|  |           return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         fs.exists(index, function (exists) { | ||||||
|  |           if (exists) { | ||||||
|  |             configureForHttps(); | ||||||
|  |             return; | ||||||
|  |           } | ||||||
|  | 
 | ||||||
|  |           fs.writeFile(path.join(pubDir, 'index.html'), welcomeHtml.replace(/:hostname/g, vhost), 'utf8', function (err) { | ||||||
|  |             if (err) { | ||||||
|  |               cb(err); | ||||||
|  |               return; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             configureForHttps(); | ||||||
|  |           }); | ||||||
|  |         }); | ||||||
|  |       }); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function configureForHttps() { | ||||||
|  |       le.setConfig(args, cb); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   function createConfigurator(le) { | ||||||
|  |     var app = express(); | ||||||
|  | 
 | ||||||
|  |     app.use('/', express.static(path.join(__dirname, '..', 'lib', 'configurator'))); | ||||||
|  | 
 | ||||||
|  |     app.use(require('body-parser').json()); | ||||||
|  | 
 | ||||||
|  |     app.get('/api/com.daplie.lex/sites', function (req, res, next) { | ||||||
|  |       le.getConfigs({ configDir: configDir }, function (err, configs) { | ||||||
|  |         if (err) { | ||||||
|  |           next(err); | ||||||
|  |           return; | ||||||
|  |         } | ||||||
|  |         res.send(configs); | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     app.post('/api/com.daplie.lex/sites', function (req, res, next) { | ||||||
|  |       var data = req.body; | ||||||
|  | 
 | ||||||
|  |       configure(le, data, function (err, configs) { | ||||||
|  |         if (err) { | ||||||
|  |           console.error(err.stack); | ||||||
|  |           next(err); | ||||||
|  |           return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         res.send(configs); | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     return app; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   function startServers() { | ||||||
|  |     // Note: using staging server url, remove .testing() for production
 | ||||||
|  |     var LE = require('letsencrypt'); | ||||||
|  |     var challengeStore = require('../lib/challenge-handlers'); | ||||||
|  |     var le = LE.create({ | ||||||
|  |       configDir: configDir | ||||||
|  |     , manual: true | ||||||
|  | 
 | ||||||
|  |     , privkeyPath: LE.privkeyPath | ||||||
|  |     , fullchainPath: LE.fullchainPath | ||||||
|  |     , certPath: LE.certPath | ||||||
|  |     , chainPath: LE.chainPath | ||||||
|  |     }, { | ||||||
|  |       setChallenge: challengeStore.set | ||||||
|  |     , removeChallenge: challengeStore.remove | ||||||
|  |     }); | ||||||
|  |     var lex = require('../'); | ||||||
|  |     var app = express(); | ||||||
|  |     var vhosts = {}; | ||||||
|  | 
 | ||||||
|  |     vhosts['localhost.daplie.com'] = createConfigurator(le, vhosts); | ||||||
|  | 
 | ||||||
|  |     app.use('/', function (req, res, next) { | ||||||
|  |       var hostname = req.hostname.replace(/^www\./, ''); | ||||||
|  |       var pubDir = path.join(vhostDir, hostname); | ||||||
|  | 
 | ||||||
|  |       if (vhosts[hostname]) { | ||||||
|  |         vhosts[hostname](req, res, next); | ||||||
|  |         return; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       fs.exists(pubDir, function (exists) { | ||||||
|  |         if (exists) { | ||||||
|  |           vhosts[hostname] = express().use('/', express.static(pubDir)); | ||||||
|  |           vhosts[hostname](req, res, next); | ||||||
|  |         } else { | ||||||
|  |           vhosts['localhost.daplie.com'](req, res, next); | ||||||
|  |         } | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|  |     app.use('/', express.static(path.join(__dirname, '..', 'lib', 'public'))); | ||||||
|  | 
 | ||||||
|  |     lex.create({ | ||||||
|  |       onRequest: app | ||||||
|  |     , configDir: configDir | ||||||
|  |     , letsencrypt: le | ||||||
|  |     , approveRegistration: function (domain, cb) { | ||||||
|  |         le.getConfig({ domains: [domain] }, function (err, config) { | ||||||
|  |           if (!(config && config.checkpoints >= 0)) { | ||||||
|  |             cb(null, null); | ||||||
|  |             return; | ||||||
|  |           } | ||||||
|  | 
 | ||||||
|  |           cb(null, { | ||||||
|  |             email: config.email | ||||||
|  |                 // can't remember which it is, but the pyconf is different that the regular variable
 | ||||||
|  |           , agreeTos: config.tos || config.agree || config.agreeTos | ||||||
|  |           , server: config.server || LE.productionServerUrl | ||||||
|  |           , domains: config.domains || [domain] | ||||||
|  |           }); | ||||||
|  |         }); | ||||||
|  |       } | ||||||
|  |     }).listen([80], [443, 5001], function () { | ||||||
|  |       console.log("ENCRYPT __ALL__ THE DOMAINS!"); | ||||||
|  |     }); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   /* | ||||||
|  |       // should get back account, path to certs, pems, etc?
 | ||||||
|  |       console.log('\nCertificates installed at:'); | ||||||
|  |       console.log(Object.keys(results).filter(function (key) { | ||||||
|  |         return /Path/.test(key); | ||||||
|  |       }).map(function (key) { | ||||||
|  |         return results[key]; | ||||||
|  |       }).join('\n')); | ||||||
|  |   */ | ||||||
|  | }); | ||||||
							
								
								
									
										41
									
								
								lib/configurator/app.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								lib/configurator/app.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,41 @@ | |||||||
|  | $(function () { | ||||||
|  |   'use strict'; | ||||||
|  | 
 | ||||||
|  |   var tpl = $('.js-hostnames').html(); | ||||||
|  |   $('.js-hostnames').html(''); | ||||||
|  | 
 | ||||||
|  |   $('body').on('submit', 'form.js-add-site', function (ev) { | ||||||
|  |     ev.preventDefault(); | ||||||
|  |     // I don't think this actually has any meaning when listening on body
 | ||||||
|  |     ev.stopPropagation(); | ||||||
|  | 
 | ||||||
|  |     var data = { | ||||||
|  |       email: $('.js-email').val() | ||||||
|  |     , agreeTos: !!$('.js-agree-tos').prop('checked') | ||||||
|  |     , server: $('.js-server').val() | ||||||
|  |     , domains: $('.js-domains').val().split(/\s*,\s*/) | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     $.ajax({ | ||||||
|  |       method: 'POST' | ||||||
|  |     , url: '/api/com.daplie.lex/sites' | ||||||
|  |     , data: JSON.stringify(data) | ||||||
|  |     , headers: { 'Content-Type': 'application/json; charset=utf-8' } | ||||||
|  |     }).then(function (data) { | ||||||
|  |       console.log(data); | ||||||
|  |     }); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   $.ajax({ | ||||||
|  |     method: 'GET' | ||||||
|  |   , url: '/api/com.daplie.lex/sites' | ||||||
|  |   }).then(function (data) { | ||||||
|  |     var $hostnames = $('.js-hostnames'); | ||||||
|  |     $hostnames.html(''); | ||||||
|  |     data.forEach(function (config) { | ||||||
|  |       var $conf = $(tpl); | ||||||
|  |       $conf.text(config.domains); | ||||||
|  |       $hostnames.append($conf); | ||||||
|  |     }); | ||||||
|  |   }); | ||||||
|  | }); | ||||||
							
								
								
									
										37
									
								
								lib/configurator/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								lib/configurator/index.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,37 @@ | |||||||
|  | <!DOCTYPE html> | ||||||
|  | <html> | ||||||
|  |   <head> | ||||||
|  |     <title>Welcome to :hostname!</title> | ||||||
|  |     <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> | ||||||
|  |     <meta http-equiv="Content-Security-Policy" content="default-src 'self';"> | ||||||
|  |     <link rel="stylesheet" type="text/css" href="./bootstrap.css"> | ||||||
|  |   </head> | ||||||
|  |   <body> | ||||||
|  |     <div class="container"> | ||||||
|  |       <div class="jumbotron"> | ||||||
|  |         <h1>Add a Site</h1> | ||||||
|  |         <form class="js-add-site"> | ||||||
|  |           <label>Domain</label>: <input type="text" class="js-domains" placeholder="ex: example.com,www.example.com"> | ||||||
|  |           <br/> | ||||||
|  |           <label>Email</label>: <input type="email" class="js-email" placeholder="ex: user@example.com"> | ||||||
|  |           <br/> | ||||||
|  |           <label>LE Server</label>: <input type="text" class="js-server" placeholder="ex: https://acme-staging.api.letsencrypt.org/directory" value="https://acme-v01.api.letsencrypt.org/directory"> | ||||||
|  |           <br/> | ||||||
|  |           <label><input type="checkbox" class="js-agree-tos"> Agree to Let's Encrypt Terms of Service?</label> | ||||||
|  |           <br/> | ||||||
|  |           <button class="btn btn-primary" type="submit">Add Site</button> | ||||||
|  |         </form> | ||||||
|  |       </div> | ||||||
|  |       <div class="row"> | ||||||
|  |         <p>Sites: | ||||||
|  |         <div class="js-hostnames-container"> | ||||||
|  |           <ul class="js-hostnames"> | ||||||
|  |             <li class="js-hostname"></li> | ||||||
|  |           </ul> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |     <script src="./jquery.js"></script> | ||||||
|  |     <script src="./app.js"></script> | ||||||
|  |   </body> | ||||||
|  | </html> | ||||||
							
								
								
									
										6961
									
								
								lib/public/bootstrap.css
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6961
									
								
								lib/public/bootstrap.css
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										9210
									
								
								lib/public/jquery.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9210
									
								
								lib/public/jquery.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										24
									
								
								lib/public/welcome.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								lib/public/welcome.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | |||||||
|  | <!DOCTYPE html> | ||||||
|  | <html> | ||||||
|  |   <head> | ||||||
|  |     <title>Welcome to :hostname!</title> | ||||||
|  |     <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> | ||||||
|  |     <meta http-equiv="Content-Security-Policy" content="default-src 'self';"> | ||||||
|  |     <link rel="stylesheet" type="text/css" href="./bootstrap.css"> | ||||||
|  |   </head> | ||||||
|  |   <body> | ||||||
|  |     <div class="container"> | ||||||
|  |       <div class="jumbotron"> | ||||||
|  |         <h1>Hello, world!</h1> | ||||||
|  |         <p>Your website is located in one of two places:</p> | ||||||
|  |         <ul> | ||||||
|  |           <li>on your <code>Desktop</code> inside of the <code>www</code> directory and <code>:hostname</code></li> | ||||||
|  |           <li><code>~/www/:hostname</code> (your home folder, under <code>www/:hostname</code></li> | ||||||
|  |         <ul> | ||||||
|  |         <p>This very file is called <code>index.html</code>. | ||||||
|  |         You can open it up in <code>notepad</code> and change it up a little if you'd like.</p> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |     <script src="./jquery.js"></script> | ||||||
|  |   </body> | ||||||
|  | </html> | ||||||
							
								
								
									
										22
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								package.json
									
									
									
									
									
								
							| @ -3,6 +3,16 @@ | |||||||
|   "version": "1.0.2", |   "version": "1.0.2", | ||||||
|   "description": "Free SSL and Automatic HTTPS for node.js with Express, Connect, and other middleware systems", |   "description": "Free SSL and Automatic HTTPS for node.js with Express, Connect, and other middleware systems", | ||||||
|   "main": "index.js", |   "main": "index.js", | ||||||
|  |   "bin": { | ||||||
|  |     "letsencrypt-express": "bin/lex.js", | ||||||
|  |     "lex": "bin/lex.js" | ||||||
|  |   }, | ||||||
|  |   "files": [ | ||||||
|  |     "lib/", | ||||||
|  |     "bin/", | ||||||
|  |     "examples/", | ||||||
|  |     "index.js" | ||||||
|  |   ], | ||||||
|   "directories": { |   "directories": { | ||||||
|     "example": "examples" |     "example": "examples" | ||||||
|   }, |   }, | ||||||
| @ -33,9 +43,15 @@ | |||||||
|     "url": "https://github.com/Daplie/letsencrypt-express/issues" |     "url": "https://github.com/Daplie/letsencrypt-express/issues" | ||||||
|   }, |   }, | ||||||
|   "homepage": "https://github.com/Daplie/letsencrypt-express#readme", |   "homepage": "https://github.com/Daplie/letsencrypt-express#readme", | ||||||
|   "dependencies": { |   "devDependencies": { | ||||||
|     "homedir": "^0.6.0", |     "body-parser": "^1.14.2", | ||||||
|     "letsencrypt": "^1.3.0", |     "cli": "^0.11.1", | ||||||
|  |     "express": "^4.13.3", | ||||||
|  |     "localhost.daplie.com-certificates": "^1.1.2", | ||||||
|     "mkdirp": "^0.5.1" |     "mkdirp": "^0.5.1" | ||||||
|   } |   } | ||||||
|  |   "dependencies": { | ||||||
|  |     "homedir": "^0.6.0", | ||||||
|  |     "letsencrypt": "^1.3.0" | ||||||
|  |   } | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user