| 
									
										
										
										
											2015-02-18 23:06:56 -07:00
										 |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-21 12:36:22 +00:00
										 |  |  | module.exports.create = function (securePort, insecurePort, info, serverCallback) { | 
					
						
							| 
									
										
										
										
											2015-03-06 03:04:51 +00:00
										 |  |  |   var PromiseA = require('bluebird').Promise; | 
					
						
							| 
									
										
										
										
											2015-11-21 12:36:22 +00:00
										 |  |  |   var appPromise; | 
					
						
							|  |  |  |   //var app;
 | 
					
						
							| 
									
										
										
										
											2015-03-06 03:04:51 +00:00
										 |  |  |   var http = require('http'); | 
					
						
							| 
									
										
										
										
											2015-11-21 12:36:22 +00:00
										 |  |  |   var redirectives; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   function useAppInsecurely(req, res) { | 
					
						
							|  |  |  |     if (!appPromise) { | 
					
						
							|  |  |  |       return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     appPromise.then(function (app) { | 
					
						
							|  |  |  |       req._WALNUT_SECURITY_EXCEPTION = true; | 
					
						
							|  |  |  |       app(req, res); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return true; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-03-06 03:04:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-18 23:06:56 -07:00
										 |  |  |   function redirectHttps(req, res) { | 
					
						
							| 
									
										
										
										
											2015-11-21 12:36:22 +00:00
										 |  |  |     // Let it do this once they visit the https site
 | 
					
						
							|  |  |  |     // res.setHeader('Strict-Transport-Security', 'max-age=10886400; includeSubDomains; preload');
 | 
					
						
							| 
									
										
										
										
											2015-09-25 08:06:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-18 23:06:56 -07:00
										 |  |  |     var host = req.headers.host || ''; | 
					
						
							|  |  |  |     var url = req.url; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-21 12:36:22 +00:00
										 |  |  |     // TODO
 | 
					
						
							|  |  |  |     // XXX NOTE: info.conf.redirects may or may not be loaded at first
 | 
					
						
							|  |  |  |     // the object will be modified when the config is loaded
 | 
					
						
							|  |  |  |     if (!redirectives && info.conf.redirects) { | 
					
						
							|  |  |  |       redirectives = require('./hostname-redirects').compile(info.conf.redirects); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (require('./no-www').scrubTheDub(req, res, redirectives)) { | 
					
						
							|  |  |  |       return true; | 
					
						
							| 
									
										
										
										
											2015-11-14 04:25:12 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-21 12:36:22 +00:00
										 |  |  |     // TODO
 | 
					
						
							|  |  |  |     // allow exceptions for the case of arduino and whatnot that cannot handle https?
 | 
					
						
							|  |  |  |     // http://evothings.com/is-it-possible-to-secure-micro-controllers-used-within-iot/
 | 
					
						
							|  |  |  |     // needs ECDSA?
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     console.warn('HARD-CODED HTTPS EXCEPTION in insecure-server.js'); | 
					
						
							| 
									
										
										
										
											2015-11-23 09:31:54 +00:00
										 |  |  |     if (/redirect-www.org$/.test(host) && useAppInsecurely(req, res)) { | 
					
						
							| 
									
										
										
										
											2015-11-21 12:36:22 +00:00
										 |  |  |       return true; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-02-18 23:06:56 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-14 21:44:02 +00:00
										 |  |  |     var escapeHtml = require('escape-html'); | 
					
						
							| 
									
										
										
										
											2015-02-18 23:06:56 -07:00
										 |  |  |     var newLocation = 'https://' | 
					
						
							|  |  |  |       + host.replace(/:\d+/, ':' + securePort) + url | 
					
						
							|  |  |  |       ; | 
					
						
							| 
									
										
										
										
											2015-07-08 21:20:57 -06:00
										 |  |  |     var safeLocation = escapeHtml(newLocation); | 
					
						
							| 
									
										
										
										
											2015-02-18 23:06:56 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     var metaRedirect = '' | 
					
						
							|  |  |  |       + '<html>\n' | 
					
						
							|  |  |  |       + '<head>\n' | 
					
						
							|  |  |  |       + '  <style>* { background-color: white; color: white; text-decoration: none; }</style>\n' | 
					
						
							| 
									
										
										
										
											2015-07-08 21:20:57 -06:00
										 |  |  |       + '  <META http-equiv="refresh" content="0;URL=' + safeLocation + '">\n' | 
					
						
							| 
									
										
										
										
											2015-02-18 23:06:56 -07:00
										 |  |  |       + '</head>\n' | 
					
						
							|  |  |  |       + '<body style="display: none;">\n' | 
					
						
							|  |  |  |       + '  <p>You requested an insecure resource. Please use this instead: \n' | 
					
						
							| 
									
										
										
										
											2015-07-08 21:20:57 -06:00
										 |  |  |       + '    <a href="' + safeLocation + '">' + safeLocation + '</a></p>\n' | 
					
						
							| 
									
										
										
										
											2015-02-18 23:06:56 -07:00
										 |  |  |       + '</body>\n' | 
					
						
							|  |  |  |       + '</html>\n' | 
					
						
							|  |  |  |       ; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // DO NOT HTTP REDIRECT
 | 
					
						
							|  |  |  |     /* | 
					
						
							|  |  |  |     res.setHeader('Location', newLocation); | 
					
						
							|  |  |  |     res.statusCode = 302; | 
					
						
							|  |  |  |     */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // BAD NEWS BEARS
 | 
					
						
							|  |  |  |     //
 | 
					
						
							|  |  |  |     // When people are experimenting with the API and posting tutorials
 | 
					
						
							|  |  |  |     // they'll use cURL and they'll forget to prefix with https://
 | 
					
						
							|  |  |  |     // If we allow that, then many users will be sending private tokens
 | 
					
						
							|  |  |  |     // and such with POSTs in clear text and, worse, it will work!
 | 
					
						
							|  |  |  |     // To minimize this, we give browser users a mostly optimal experience,
 | 
					
						
							|  |  |  |     // but people experimenting with the API get a message letting them know
 | 
					
						
							|  |  |  |     // that they're doing it wrong and thus forces them to ensure they encrypt.
 | 
					
						
							| 
									
										
										
										
											2015-07-08 21:20:57 -06:00
										 |  |  |     res.setHeader('Content-Type', 'text/html; charset=utf-8'); | 
					
						
							| 
									
										
										
										
											2015-02-18 23:06:56 -07:00
										 |  |  |     res.end(metaRedirect); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // TODO localhost-only server shutdown mechanism
 | 
					
						
							|  |  |  |   // that closes all sockets, waits for them to finish,
 | 
					
						
							|  |  |  |   // and then hands control over completely to respawned server
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   //
 | 
					
						
							| 
									
										
										
										
											2015-02-20 22:34:17 +00:00
										 |  |  |   // Redirect HTTP to HTTPS
 | 
					
						
							| 
									
										
										
										
											2015-02-18 23:06:56 -07:00
										 |  |  |   //
 | 
					
						
							|  |  |  |   // This simply redirects from the current insecure location to the encrypted location
 | 
					
						
							|  |  |  |   //
 | 
					
						
							| 
									
										
										
										
											2015-02-20 22:34:17 +00:00
										 |  |  |   var insecureServer; | 
					
						
							| 
									
										
										
										
											2015-02-18 23:06:56 -07:00
										 |  |  |   insecureServer = http.createServer(); | 
					
						
							| 
									
										
										
										
											2015-02-20 22:34:17 +00:00
										 |  |  |   insecureServer.listen(insecurePort, function () { | 
					
						
							| 
									
										
										
										
											2015-11-21 12:36:22 +00:00
										 |  |  |     console.log("\nListening on http://localhost:" + insecureServer.address().port); | 
					
						
							|  |  |  |     console.log("(handling any explicit redirects and redirecting all other traffic to https)\n"); | 
					
						
							|  |  |  |     if (serverCallback) { | 
					
						
							|  |  |  |       appPromise = serverCallback(null, insecureServer); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-02-18 23:06:56 -07:00
										 |  |  |   }); | 
					
						
							| 
									
										
										
										
											2015-11-21 12:36:22 +00:00
										 |  |  |   insecureServer.on('request', redirectHttps); | 
					
						
							| 
									
										
										
										
											2015-03-06 03:04:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return PromiseA.resolve(insecureServer); | 
					
						
							| 
									
										
										
										
											2015-02-18 23:06:56 -07:00
										 |  |  | }; |