From 9d2e89a1c742bf1e5d72bdd2b25a96e43cff3c27 Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Fri, 19 May 2017 01:00:17 +0000 Subject: [PATCH] making it work standalone again --- lib/bootstrap.js | 146 +++++++++++++---------------------------------- lib/worker.js | 11 +++- 2 files changed, 49 insertions(+), 108 deletions(-) diff --git a/lib/bootstrap.js b/lib/bootstrap.js index 671fc9e..34428e9 100644 --- a/lib/bootstrap.js +++ b/lib/bootstrap.js @@ -12,18 +12,17 @@ module.exports.create = function (app, xconfx, models) { var fs = PromiseA.promisifyAll(require('fs')); var dns = PromiseA.promisifyAll(require('dns')); - function isInitialized() { + function isInitialized () { // TODO read from file only, not db return models.ComDaplieWalnutConfig.get('config').then(function (conf) { - if (!conf || !conf.primaryDomain || !conf.primaryEmail) { + if (!conf || !conf.primaryDomain/* || !conf.primaryEmail*/) { console.log('DEBUG incomplete conf', conf); return false; } xconfx.primaryDomain = xconfx.primaryDomain || conf.primaryDomain; - var configname = conf.primaryDomain + '.json'; - var configpath = path.join(__dirname, '..', '..', 'config', configname); + var configpath = path.join(__dirname, '..', '..', 'config', conf.primaryDomain + '.json'); return fs.readFileAsync(configpath, 'utf8').then(function (text) { return JSON.parse(text); @@ -31,11 +30,6 @@ module.exports.create = function (app, xconfx, models) { console.log('DEBUG not exists leconf', configpath); return false; }).then(function (data) { - if (!data || !data.email || !data.agreeTos) { - console.log('DEBUG incomplete leconf', data); - return false; - } - return true; }); }); @@ -44,7 +38,7 @@ module.exports.create = function (app, xconfx, models) { function initialize() { var express = require('express'); var getIpAddresses = require('./ip-checker').getExternalAddresses; - var resolve; + var resolveInit; function errorIfNotApi(req, res, next) { var hostname = req.hostname || req.headers.host; @@ -142,106 +136,35 @@ module.exports.create = function (app, xconfx, models) { } function setConfig(req, res) { - var config = req.body; - var results = {}; - return PromiseA.resolve().then(function () { - if (!config.agreeTos && !config.tls) { - return PromiseA.reject(new Error("To enable encryption you must agree to the LetsEncrypt terms of service")); + // TODO expect authenticated oauth3 user + var config = req.body; + var safeConfig = {}; + + if ('string' !== typeof config.domain) { + return PromiseA.reject(new Error("'domain' should be a string specifying a valid domain name")); } - if (!config.domain) { - return PromiseA.reject(new Error("You must specify a valid domain name")); + config.domain = (config.domain||'').replace(/^www\./, ''); + + // TODO url-testing lib + if (!/\w+\.\w+/.test(config.domain)) { + return PromiseA.reject(new Error("'domain' should be a string specifying a valid domain name")); } - config.domain = config.domain.replace(/^www\./, ''); - return getIpAddresses().then(function (inet) { - if (!inet.addresses.length) { - return PromiseA.reject(new Error("no ip addresses")); - } - results.inets = inet.addresses.map(function (a) { - a.time = undefined; - return a; - }); - - results.resolutions = []; - return PromiseA.all([ - // for static content - verifyIps(inet.addresses, config.domain).then(function (ips) { - results.resolutions.push({ hostname: config.domain, ips: ips }); - }) - // for redirects - , verifyIps(inet.addresses, 'www.' + config.domain).then(function (ips) { - results.resolutions.push({ hostname: 'www.' + config.domain, ips: ips }); - }) - // for api - , verifyIps(inet.addresses, 'api.' + config.domain).then(function (ips) { - results.resolutions.push({ hostname: 'api.' + config.domain, ips: ips }); - }) - // for protected assets - , verifyIps(inet.addresses, 'assets.' + config.domain).then(function (ips) { - results.resolutions.push({ hostname: 'assets.' + config.domain, ips: ips }); - }) - // for the cloud management - , verifyIps(inet.addresses, 'cloud.' + config.domain).then(function (ips) { - results.resolutions.push({ hostname: 'cloud.' + config.domain, ips: ips }); - }) - , verifyIps(inet.addresses, 'api.cloud.' + config.domain).then(function (ips) { - results.resolutions.push({ hostname: 'api.cloud.' + config.domain, ips: ips }); - }) - ]).then(function () { - if (!results.resolutions[0].ips.length) { - results.error = { message: "bare domain could not be resolved to this device" }; - } - else if (!results.resolutions[2].ips.length) { - results.error = { message: "api subdomain could not be resolved to this device" }; - } - /* - else if (!results.resolutions[1].ips.length) { - results.error = { message: "" } - } - else if (!results.resolutions[3].ips.length) { - results.error = { message: "" } - } - else if (!results.resolutions[4].ips.length || !results.resolutions[4].ips.length) { - results.error = { message: "cloud and api.cloud subdomains should be set up" }; - } - */ - }); + var configpath = path.join(__dirname, '..', '..', 'config', config.domain + '.json'); + safeConfig = { primaryDomain: config.domain }; + return fs.writeFileAsync(configpath, JSON.stringify(safeConfig, null, ' '), 'utf8').then(function () { + // TODO nix SQL + return models.ComDaplieWalnutConfig.upsert('config', safeConfig); }); }).then(function () { - if (results.error) { - return; + if (resolveInit) { + resolveInit(); + resolveInit = null; } - - var configname = config.domain + '.json'; - var configpath = path.join(__dirname, '..', '..', 'config', configname); - var leAuth = { - agreeTos: true - , email: config.email // TODO check email - , domain: config.domain - , createdAt: Date.now() - }; - - return dns.resolveMxAsync(config.email.replace(/.*@/, '')).then(function (/*addrs*/) { - // TODO allow private key to be uploaded - return fs.writeFileAsync(configpath, JSON.stringify(leAuth, null, ' '), 'utf8').then(function () { - return models.ComDaplieWalnutConfig.upsert('config', { - letsencrypt: leAuth - , primaryDomain: config.domain - , primaryEmail: config.email - }); - }); - }, function () { - return PromiseA.reject(new Error("invalid email address (MX record lookup failed)")); - }); - }).then(function () { - if (!results.error && results.inets && resolve) { - resolve(); - resolve = null; - } - res.send(results); + res.send({ success: true }); }, function (err) { console.error('Error lib/bootstrap.js'); console.error(err.stack || err); @@ -259,19 +182,21 @@ module.exports.create = function (app, xconfx, models) { ], methods: [ "GET", "POST", "PATCH", "PUT", "DELETE" ] }); app.use('/', function (req, res, next) { + console.log('[lib/bootstrap.js] req.url', req.url); + return isInitialized().then(function (initialized) { if (!initialized) { next(); return; } - resolve(true); + // init is always considered to be + resolveInit(true); - // force page refresh - // TODO goto top of routes? + // TODO feed this request back through the route stack from the top to avoid forced refresh? res.statusCode = 302; res.setHeader('Location', req.url); - res.end(); + res.end(""); }); }); app.use('/api', errorIfNotApi); @@ -283,10 +208,17 @@ module.exports.create = function (app, xconfx, models) { app.get('/api/com.daplie.walnut.init', getConfig); app.post('/api/com.daplie.walnut.init', setConfig); app.use('/', errorIfApi); - app.use('/', express.static(path.join(__dirname, '..', '..', 'packages', 'pages', 'com.daplie.walnut.init'))); + + // TODO use package loader + //app.use('/', express.static(path.join(__dirname, '..', '..', 'packages', 'pages', 'com.daplie.walnut.init'))); + app.use('/', express.static(path.join(__dirname, 'com.daplie.walnut.init'))); + app.use('/', function (req, res, next) { + res.statusCode = 404; + res.end('Walnut Bootstrap Not Found. Mising com.daplie.walnut.init'); + }); return new PromiseA(function (_resolve) { - resolve = _resolve; + resolveInit = _resolve; }); } diff --git a/lib/worker.js b/lib/worker.js index 21c0fc1..152b9ce 100644 --- a/lib/worker.js +++ b/lib/worker.js @@ -157,15 +157,23 @@ module.exports.create = function (webserver, xconfx, state) { }; var hostsmap = {}; + function log(req, res, next) { var hostname = (req.hostname || req.headers.host || '').split(':').shift(); + + // Printing all incoming requests for debugging console.log('[worker/log]', req.method, hostname, req.url); + + // logging all the invalid hostnames that come here out of curiousity if (hostname && !hostsmap[hostname]) { hostsmap[hostname] = true; require('fs').writeFile( require('path').join(__dirname, '..', '..', 'var', 'hostnames', hostname) - , hostname, function () {}); + , hostname + , function () {} + ); } + next(); } @@ -217,6 +225,7 @@ module.exports.create = function (webserver, xconfx, state) { require('./unbrick-appcache').unbrick(req, res); return; } + console.log('[lib/worker] unencrypted:', req.headers); res.end("Connection is not encrypted. That's no bueno or, as we say in Hungarian, nem szabad!"); return; }