| 
									
										
										
										
											2015-11-06 11:05:32 +00:00
										 |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-09 19:14:00 -04:00
										 |  |  | module.exports.create = function (webserver, xconfx, state) { | 
					
						
							| 
									
										
										
										
											2017-05-10 23:26:25 +00:00
										 |  |  |   console.log('[worker] create'); | 
					
						
							|  |  |  |   xconfx.debug = true; | 
					
						
							| 
									
										
										
										
											2016-04-09 19:14:00 -04:00
										 |  |  |   console.log('DEBUG create worker'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-12 11:14:59 +00:00
										 |  |  |   if (!state) { | 
					
						
							|  |  |  |     state = {}; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   var PromiseA = state.Promise || require('bluebird'); | 
					
						
							|  |  |  |   var memstore; | 
					
						
							|  |  |  |   var sqlstores = {}; | 
					
						
							|  |  |  |   var systemFactory = require('sqlite3-cluster/client').createClientFactory({ | 
					
						
							| 
									
										
										
										
											2016-04-09 19:14:00 -04:00
										 |  |  |       dirname: xconfx.varpath | 
					
						
							| 
									
										
										
										
											2017-07-31 22:46:03 +00:00
										 |  |  |     , prefix: 'walnut+' | 
					
						
							| 
									
										
										
										
											2015-11-12 11:14:59 +00:00
										 |  |  |     //, dbname: 'config'
 | 
					
						
							| 
									
										
										
										
											2017-07-31 22:46:03 +00:00
										 |  |  |     , suffix: '@daplie.com' | 
					
						
							| 
									
										
										
										
											2015-11-12 11:14:59 +00:00
										 |  |  |     , ext: '.sqlite3' | 
					
						
							| 
									
										
										
										
											2016-04-09 19:14:00 -04:00
										 |  |  |     , sock: xconfx.sqlite3Sock | 
					
						
							|  |  |  |     , ipcKey: xconfx.ipcKey | 
					
						
							| 
									
										
										
										
											2015-11-12 11:14:59 +00:00
										 |  |  |   }); | 
					
						
							| 
									
										
										
										
											2016-04-09 19:14:00 -04:00
										 |  |  |   /* | 
					
						
							| 
									
										
										
										
											2015-11-12 11:14:59 +00:00
										 |  |  |   var clientFactory = require('sqlite3-cluster/client').createClientFactory({ | 
					
						
							|  |  |  |       algorithm: 'aes' | 
					
						
							|  |  |  |     , bits: 128 | 
					
						
							|  |  |  |     , mode: 'cbc' | 
					
						
							| 
									
										
										
										
											2016-04-09 19:14:00 -04:00
										 |  |  |     , dirname: xconfx.varpath // TODO conf
 | 
					
						
							|  |  |  |     , prefix: 'com.daplie.walnut.' | 
					
						
							| 
									
										
										
										
											2015-11-12 11:14:59 +00:00
										 |  |  |     //, dbname: 'cluster'
 | 
					
						
							|  |  |  |     , suffix: '' | 
					
						
							|  |  |  |     , ext: '.sqlcipher' | 
					
						
							| 
									
										
										
										
											2016-04-09 19:14:00 -04:00
										 |  |  |     , sock: xconfx.sqlite3Sock | 
					
						
							|  |  |  |     , ipcKey: xconfx.ipcKey | 
					
						
							| 
									
										
										
										
											2015-11-12 11:14:59 +00:00
										 |  |  |   }); | 
					
						
							| 
									
										
										
										
											2015-11-06 11:05:32 +00:00
										 |  |  |   */ | 
					
						
							| 
									
										
										
										
											2016-04-09 19:14:00 -04:00
										 |  |  |   var cstore = require('cluster-store'); | 
					
						
							| 
									
										
										
										
											2015-11-06 11:05:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-10 23:26:25 +00:00
										 |  |  |   console.log('[worker] creating data stores...'); | 
					
						
							| 
									
										
										
										
											2015-11-12 11:14:59 +00:00
										 |  |  |   return PromiseA.all([ | 
					
						
							| 
									
										
										
										
											2015-11-18 11:44:22 +00:00
										 |  |  |     // TODO security on memstore
 | 
					
						
							|  |  |  |     // TODO memstoreFactory.create
 | 
					
						
							| 
									
										
										
										
											2015-11-12 11:14:59 +00:00
										 |  |  |     cstore.create({ | 
					
						
							| 
									
										
										
										
											2016-04-09 19:14:00 -04:00
										 |  |  |       sock: xconfx.memstoreSock | 
					
						
							|  |  |  |     , connect: xconfx.memstoreSock | 
					
						
							| 
									
										
										
										
											2015-11-12 11:14:59 +00:00
										 |  |  |       // TODO implement
 | 
					
						
							| 
									
										
										
										
											2016-04-09 19:14:00 -04:00
										 |  |  |     , key: xconfx.ipcKey | 
					
						
							| 
									
										
										
										
											2015-11-12 11:14:59 +00:00
										 |  |  |     }).then(function (_memstore) { | 
					
						
							| 
									
										
										
										
											2017-05-10 23:26:25 +00:00
										 |  |  |       console.log('[worker] cstore created'); | 
					
						
							| 
									
										
										
										
											2016-04-09 19:14:00 -04:00
										 |  |  |       memstore = PromiseA.promisifyAll(_memstore); | 
					
						
							| 
									
										
										
										
											2015-11-12 11:14:59 +00:00
										 |  |  |       return memstore; | 
					
						
							|  |  |  |     }) | 
					
						
							|  |  |  |     // TODO mark a device as lost, stolen, missing in DNS records
 | 
					
						
							|  |  |  |     // (and in turn allow other devices to lock it, turn on location reporting, etc)
 | 
					
						
							|  |  |  |   , systemFactory.create({ | 
					
						
							|  |  |  |         init: true | 
					
						
							|  |  |  |       , dbname: 'config' | 
					
						
							| 
									
										
										
										
											2017-05-10 23:26:25 +00:00
										 |  |  |     }).then(function (sysdb) { | 
					
						
							|  |  |  |       console.log('[worker] sysdb created'); | 
					
						
							|  |  |  |       return sysdb; | 
					
						
							| 
									
										
										
										
											2015-11-12 11:14:59 +00:00
										 |  |  |     }) | 
					
						
							|  |  |  |   ]).then(function (args) { | 
					
						
							| 
									
										
										
										
											2017-05-10 23:26:25 +00:00
										 |  |  |     console.log('[worker] database factories created'); | 
					
						
							| 
									
										
										
										
											2015-11-12 11:14:59 +00:00
										 |  |  |     memstore = args[0]; | 
					
						
							|  |  |  |     sqlstores.config = args[1]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-09 19:14:00 -04:00
										 |  |  |     var wrap = require('masterquest-sqlite3'); | 
					
						
							|  |  |  |     var dir = [ | 
					
						
							|  |  |  |       { tablename: 'com_daplie_walnut_config' | 
					
						
							|  |  |  |       , idname: 'id' | 
					
						
							|  |  |  |       , unique: [ 'id' ] | 
					
						
							|  |  |  |       , indices: [ 'createdAt', 'updatedAt' ] | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     , { tablename: 'com_daplie_walnut_redirects' | 
					
						
							|  |  |  |       , idname: 'id'      // blog.example.com:sample.net/blog
 | 
					
						
							|  |  |  |       , unique: [ 'id' ] | 
					
						
							|  |  |  |       , indices: [ 'createdAt', 'updatedAt' ] | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     ]; | 
					
						
							| 
									
										
										
										
											2015-11-14 04:25:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-09 19:14:00 -04:00
										 |  |  |     function scopeMemstore(expId) { | 
					
						
							|  |  |  |       var scope = expId + '|'; | 
					
						
							|  |  |  |       return { | 
					
						
							|  |  |  |         getAsync: function (id) { | 
					
						
							|  |  |  |           return memstore.getAsync(scope + id); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       , setAsync: function (id, data) { | 
					
						
							|  |  |  |           return memstore.setAsync(scope + id, data); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       , touchAsync: function (id, data) { | 
					
						
							|  |  |  |           return memstore.touchAsync(scope + id, data); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       , destroyAsync: function (id) { | 
					
						
							|  |  |  |           return memstore.destroyAsync(scope + id); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-11-14 04:25:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-09 19:14:00 -04:00
										 |  |  |       // helpers
 | 
					
						
							|  |  |  |       , allAsync: function () { | 
					
						
							| 
									
										
										
										
											2016-06-07 10:49:26 -04:00
										 |  |  |           return memstore.allAsync().then(function (db) { | 
					
						
							| 
									
										
										
										
											2016-04-09 19:14:00 -04:00
										 |  |  |             return Object.keys(db).filter(function (key) { | 
					
						
							|  |  |  |               return 0 === key.indexOf(scope); | 
					
						
							|  |  |  |             }).map(function (key) { | 
					
						
							|  |  |  |               return db[key]; | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       , lengthAsync: function () { | 
					
						
							| 
									
										
										
										
											2016-06-07 10:49:26 -04:00
										 |  |  |           return memstore.allAsync().then(function (db) { | 
					
						
							| 
									
										
										
										
											2016-04-09 19:14:00 -04:00
										 |  |  |             return Object.keys(db).filter(function (key) { | 
					
						
							|  |  |  |               return 0 === key.indexOf(scope); | 
					
						
							|  |  |  |             }).length; | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       , clearAsync: function () { | 
					
						
							| 
									
										
										
										
											2016-06-07 10:49:26 -04:00
										 |  |  |           return memstore.allAsync().then(function (db) { | 
					
						
							| 
									
										
										
										
											2016-04-09 19:14:00 -04:00
										 |  |  |             return Object.keys(db).filter(function (key) { | 
					
						
							|  |  |  |               return 0 === key.indexOf(scope); | 
					
						
							|  |  |  |             }).map(function (key) { | 
					
						
							|  |  |  |               return memstore.destroyAsync(key); | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |           }).then(function () { | 
					
						
							|  |  |  |             return null; | 
					
						
							|  |  |  |           }); | 
					
						
							| 
									
										
										
										
											2015-11-14 04:25:12 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2016-04-09 19:14:00 -04:00
										 |  |  |       }; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return wrap.wrap(sqlstores.config, dir).then(function (models) { | 
					
						
							| 
									
										
										
										
											2017-05-10 23:26:25 +00:00
										 |  |  |       console.log('[worker] database wrapped'); | 
					
						
							| 
									
										
										
										
											2016-04-09 19:14:00 -04:00
										 |  |  |       return models.ComDaplieWalnutConfig.find(null, { limit: 100 }).then(function (results) { | 
					
						
							| 
									
										
										
										
											2017-05-10 23:26:25 +00:00
										 |  |  |         console.log('[worker] config query complete'); | 
					
						
							| 
									
										
										
										
											2016-04-09 19:14:00 -04:00
										 |  |  |         return models.ComDaplieWalnutConfig.find(null, { limit: 10000 }).then(function (redirects) { | 
					
						
							| 
									
										
										
										
											2017-05-10 23:26:25 +00:00
										 |  |  |           console.log('[worker] configuring express'); | 
					
						
							| 
									
										
										
										
											2016-04-09 19:14:00 -04:00
										 |  |  |           var express = require('express-lazy'); | 
					
						
							|  |  |  |           var app = express(); | 
					
						
							|  |  |  |           var recase = require('connect-recase')({ | 
					
						
							|  |  |  |             // TODO allow explicit and or default flag
 | 
					
						
							|  |  |  |             explicit: false | 
					
						
							|  |  |  |           , default: 'snake' | 
					
						
							|  |  |  |           , prefixes: ['/api'] | 
					
						
							|  |  |  |             // TODO allow exclude
 | 
					
						
							|  |  |  |           //, exclusions: [config.oauthPrefix]
 | 
					
						
							|  |  |  |           , exceptions: {} | 
					
						
							|  |  |  |           //, cancelParam: 'camel'
 | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |           var bootstrapApp; | 
					
						
							|  |  |  |           var mainApp; | 
					
						
							|  |  |  |           var apiDeps = { | 
					
						
							|  |  |  |             models: models | 
					
						
							|  |  |  |             // TODO don't let packages use this directly
 | 
					
						
							|  |  |  |           , Promise: PromiseA | 
					
						
							| 
									
										
										
										
											2017-08-30 17:47:31 +00:00
										 |  |  |           , dns: PromiseA.promisifyAll(require('dns')) | 
					
						
							|  |  |  |           , crypto: PromiseA.promisifyAll(require('crypto')) | 
					
						
							|  |  |  |           , fs: PromiseA.promisifyAll(require('fs')) | 
					
						
							|  |  |  |           , path: require('path') | 
					
						
							| 
									
										
										
										
											2017-09-12 22:32:33 +00:00
										 |  |  |           , validate: { | 
					
						
							|  |  |  |               isEmail: function (email) { | 
					
						
							|  |  |  |                 return /@/.test(email) && !/\s+/.test(email); | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  |             , email: function (email) { | 
					
						
							|  |  |  |                 if (apiDeps.validate.isEmail(email)) { | 
					
						
							|  |  |  |                   return null; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 return new Error('invalid email address'); | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2016-04-09 19:14:00 -04:00
										 |  |  |           }; | 
					
						
							|  |  |  |           var apiFactories = { | 
					
						
							|  |  |  |             memstoreFactory: { create: scopeMemstore } | 
					
						
							|  |  |  |           , systemSqlFactory: systemFactory | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-07 10:49:26 -04:00
										 |  |  |           var hostsmap = {}; | 
					
						
							| 
									
										
										
										
											2017-05-19 01:00:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-09 19:14:00 -04:00
										 |  |  |           function log(req, res, next) { | 
					
						
							| 
									
										
										
										
											2016-06-07 10:49:26 -04:00
										 |  |  |             var hostname = (req.hostname || req.headers.host || '').split(':').shift(); | 
					
						
							| 
									
										
										
										
											2017-05-19 01:00:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |             // Printing all incoming requests for debugging
 | 
					
						
							| 
									
										
										
										
											2016-06-07 10:49:26 -04:00
										 |  |  |             console.log('[worker/log]', req.method, hostname, req.url); | 
					
						
							| 
									
										
										
										
											2017-05-19 01:00:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-10 12:04:45 -06:00
										 |  |  |             // logging all the invalid hostnames that come here out of curiousity
 | 
					
						
							| 
									
										
										
										
											2016-06-07 10:49:26 -04:00
										 |  |  |             if (hostname && !hostsmap[hostname]) { | 
					
						
							|  |  |  |               hostsmap[hostname] = true; | 
					
						
							|  |  |  |               require('fs').writeFile( | 
					
						
							|  |  |  |                 require('path').join(__dirname, '..', '..', 'var', 'hostnames', hostname) | 
					
						
							| 
									
										
										
										
											2017-05-19 01:00:17 +00:00
										 |  |  |               , hostname | 
					
						
							|  |  |  |               , function () {} | 
					
						
							|  |  |  |               ); | 
					
						
							| 
									
										
										
										
											2016-06-07 10:49:26 -04:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2017-05-19 01:00:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-09 19:14:00 -04:00
										 |  |  |             next(); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           function setupMain() { | 
					
						
							| 
									
										
										
										
											2017-05-10 23:26:25 +00:00
										 |  |  |             if (xconfx.debug) { console.log('[main] setup'); } | 
					
						
							| 
									
										
										
										
											2016-04-09 19:14:00 -04:00
										 |  |  |             mainApp = express(); | 
					
						
							| 
									
										
										
										
											2017-08-30 17:47:31 +00:00
										 |  |  |             require('./main').create(mainApp, xconfx, apiFactories, apiDeps, errorIfApi, errorIfAssets).then(function () { | 
					
						
							| 
									
										
										
										
											2017-05-10 23:26:25 +00:00
										 |  |  |               if (xconfx.debug) { console.log('[main] ready'); } | 
					
						
							| 
									
										
										
										
											2016-04-09 19:14:00 -04:00
										 |  |  |               // TODO process.send({});
 | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           if (!bootstrapApp) { | 
					
						
							| 
									
										
										
										
											2017-05-10 23:26:25 +00:00
										 |  |  |             if (xconfx.debug) { console.log('[bootstrap] setup'); } | 
					
						
							| 
									
										
										
										
											2017-05-24 04:27:52 +00:00
										 |  |  |             if (xconfx.primaryDomain) { | 
					
						
							|  |  |  |               bootstrapApp = true; | 
					
						
							|  |  |  |               setupMain(); | 
					
						
							|  |  |  |               return; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2016-04-09 19:14:00 -04:00
										 |  |  |             bootstrapApp = express(); | 
					
						
							|  |  |  |             require('./bootstrap').create(bootstrapApp, xconfx, models).then(function () { | 
					
						
							| 
									
										
										
										
											2017-05-10 23:26:25 +00:00
										 |  |  |               if (xconfx.debug) { console.log('[bootstrap] ready'); } | 
					
						
							| 
									
										
										
										
											2016-04-09 19:14:00 -04:00
										 |  |  |               // TODO process.send({});
 | 
					
						
							|  |  |  |               setupMain(); | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2015-11-14 04:25:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-09 19:14:00 -04:00
										 |  |  |           process.on('message', function (data) { | 
					
						
							|  |  |  |             if ('com.daplie.walnut.bootstrap' === data.type) { | 
					
						
							|  |  |  |               setupMain(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           }); | 
					
						
							| 
									
										
										
										
											2015-11-14 04:25:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-19 23:37:28 +00:00
										 |  |  |           function errorIfNotApi(req, res, next) { | 
					
						
							|  |  |  |             var hostname = req.hostname || req.headers.host; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (!/^api\.[a-z0-9\-]+/.test(hostname)) { | 
					
						
							|  |  |  |               res.send({ error: | 
					
						
							| 
									
										
										
										
											2017-06-09 22:15:38 +00:00
										 |  |  |                { message: "['" + hostname + req.url + "'] API access is restricted to proper 'api'-prefixed lowercase subdomains." | 
					
						
							| 
									
										
										
										
											2017-05-19 23:37:28 +00:00
										 |  |  |                    + " The HTTP 'Host' header must exist and must begin with 'api.' as in 'api.example.com'." | 
					
						
							|  |  |  |                    + " For development you may test with api.localhost.daplie.me (or any domain by modifying your /etc/hosts)" | 
					
						
							|  |  |  |                , code: 'E_NOT_API' | 
					
						
							|  |  |  |                , _hostname: hostname | 
					
						
							|  |  |  |                } | 
					
						
							|  |  |  |               }); | 
					
						
							|  |  |  |               return; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             next(); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-30 17:47:31 +00:00
										 |  |  |           function errorIfNotAssets(req, res, next) { | 
					
						
							|  |  |  |             var hostname = req.hostname || req.headers.host; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (!/^assets\.[a-z0-9\-]+/.test(hostname)) { | 
					
						
							|  |  |  |               res.send({ error: | 
					
						
							|  |  |  |                { message: "['" + hostname + req.url + "'] protected asset access is restricted to proper 'asset'-prefixed lowercase subdomains." | 
					
						
							|  |  |  |                    + " The HTTP 'Host' header must exist and must begin with 'assets.' as in 'assets.example.com'." | 
					
						
							|  |  |  |                    + " For development you may test with assets.localhost.daplie.me (or any domain by modifying your /etc/hosts)" | 
					
						
							|  |  |  |                , code: 'E_NOT_API' | 
					
						
							|  |  |  |                , _hostname: hostname | 
					
						
							|  |  |  |                } | 
					
						
							|  |  |  |               }); | 
					
						
							|  |  |  |               return; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             next(); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-19 23:37:28 +00:00
										 |  |  |           function errorIfApi(req, res, next) { | 
					
						
							|  |  |  |             if (!/^api\./.test(req.headers.host)) { | 
					
						
							|  |  |  |               next(); | 
					
						
							|  |  |  |               return; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // has api. hostname prefix
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // doesn't have /api url prefix
 | 
					
						
							|  |  |  |             if (!/^\/api\//.test(req.url)) { | 
					
						
							| 
									
										
										
										
											2017-05-24 05:25:11 +00:00
										 |  |  |               console.log('[walnut/worker api] req.url', req.url); | 
					
						
							| 
									
										
										
										
											2017-05-19 23:37:28 +00:00
										 |  |  |               res.send({ error: { message: "missing /api/ url prefix" } }); | 
					
						
							|  |  |  |               return; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-30 17:47:31 +00:00
										 |  |  |             res.send({ error: { code: 'E_NO_IMPL', message: "API not implemented" } }); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           function errorIfAssets(req, res, next) { | 
					
						
							|  |  |  |             if (!/^assets\./.test(req.headers.host)) { | 
					
						
							|  |  |  |               next(); | 
					
						
							|  |  |  |               return; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // has api. hostname prefix
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // doesn't have /api url prefix
 | 
					
						
							|  |  |  |             if (!/^\/assets\//.test(req.url)) { | 
					
						
							|  |  |  |               console.log('[walnut/worker assets] req.url', req.url); | 
					
						
							|  |  |  |               res.send({ error: { message: "missing /assets/ url prefix" } }); | 
					
						
							|  |  |  |               return; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             res.send({ error: { code: 'E_NO_IMPL', message: "assets handler not implemented" } }); | 
					
						
							| 
									
										
										
										
											2017-05-19 23:37:28 +00:00
										 |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-09 19:14:00 -04:00
										 |  |  |           app.disable('x-powered-by'); | 
					
						
							|  |  |  |           app.use('/', log); | 
					
						
							|  |  |  |           app.use('/api', require('body-parser').json({ | 
					
						
							| 
									
										
										
										
											2015-11-14 04:25:12 +00:00
										 |  |  |             strict: true // only objects and arrays
 | 
					
						
							|  |  |  |           , inflate: true | 
					
						
							|  |  |  |             // limited to due performance issues with JSON.parse and JSON.stringify
 | 
					
						
							|  |  |  |             // http://josh.zeigler.us/technology/web-development/how-big-is-too-big-for-json/
 | 
					
						
							|  |  |  |           //, limit: 128 * 1024
 | 
					
						
							|  |  |  |           , limit: 1.5 * 1024 * 1024 | 
					
						
							|  |  |  |           , reviver: undefined | 
					
						
							|  |  |  |           , type: 'json' | 
					
						
							|  |  |  |           , verify: undefined | 
					
						
							| 
									
										
										
										
											2016-04-09 19:14:00 -04:00
										 |  |  |           })); | 
					
						
							|  |  |  |           app.use('/api', recase); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-30 17:47:31 +00:00
										 |  |  |           var cookieParser = require('cookie-parser'); // signing is done in JWT
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-04 23:09:56 -06:00
										 |  |  |           app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal']); | 
					
						
							| 
									
										
										
										
											2017-05-19 23:37:28 +00:00
										 |  |  |           app.use('/api', errorIfNotApi); | 
					
						
							| 
									
										
										
										
											2017-08-30 17:47:31 +00:00
										 |  |  |           app.use('/assets', /*errorIfNotAssets,*/ cookieParser()); // serializer { path: '/assets', httpOnly: true, sameSite: true/*, domain: assets.example.com*/ }
 | 
					
						
							| 
									
										
										
										
											2016-04-09 19:14:00 -04:00
										 |  |  |           app.use('/', function (req, res) { | 
					
						
							| 
									
										
										
										
											2017-05-04 23:09:56 -06:00
										 |  |  |             if (!(req.encrypted || req.secure)) { | 
					
						
							| 
									
										
										
										
											2016-04-09 19:14:00 -04:00
										 |  |  |               // did not come from https
 | 
					
						
							|  |  |  |               if (/\.(appcache|manifest)\b/.test(req.url)) { | 
					
						
							|  |  |  |                 require('./unbrick-appcache').unbrick(req, res); | 
					
						
							|  |  |  |                 return; | 
					
						
							|  |  |  |               } | 
					
						
							| 
									
										
										
										
											2017-05-19 01:00:17 +00:00
										 |  |  |               console.log('[lib/worker] unencrypted:', req.headers); | 
					
						
							| 
									
										
										
										
											2017-05-04 23:09:56 -06:00
										 |  |  |               res.end("Connection is not encrypted. That's no bueno or, as we say in Hungarian, nem szabad!"); | 
					
						
							| 
									
										
										
										
											2016-04-09 19:14:00 -04:00
										 |  |  |               return; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // TODO check https://letsencrypt.status.io to see if https certification is not available
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (mainApp) { | 
					
						
							|  |  |  |               mainApp(req, res); | 
					
						
							|  |  |  |               return; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else { | 
					
						
							|  |  |  |               bootstrapApp(req, res); | 
					
						
							|  |  |  |               return; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           return app; | 
					
						
							| 
									
										
										
										
											2015-11-19 07:42:20 +00:00
										 |  |  |         }); | 
					
						
							| 
									
										
										
										
											2015-11-12 11:14:59 +00:00
										 |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2015-11-06 11:05:32 +00:00
										 |  |  | }; |