making it work standalone again
This commit is contained in:
parent
5ce28e5f90
commit
9d2e89a1c7
|
@ -15,15 +15,14 @@ module.exports.create = function (app, xconfx, models) {
|
||||||
function isInitialized () {
|
function isInitialized () {
|
||||||
// TODO read from file only, not db
|
// TODO read from file only, not db
|
||||||
return models.ComDaplieWalnutConfig.get('config').then(function (conf) {
|
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);
|
console.log('DEBUG incomplete conf', conf);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
xconfx.primaryDomain = xconfx.primaryDomain || conf.primaryDomain;
|
xconfx.primaryDomain = xconfx.primaryDomain || conf.primaryDomain;
|
||||||
|
|
||||||
var configname = conf.primaryDomain + '.json';
|
var configpath = path.join(__dirname, '..', '..', 'config', conf.primaryDomain + '.json');
|
||||||
var configpath = path.join(__dirname, '..', '..', 'config', configname);
|
|
||||||
|
|
||||||
return fs.readFileAsync(configpath, 'utf8').then(function (text) {
|
return fs.readFileAsync(configpath, 'utf8').then(function (text) {
|
||||||
return JSON.parse(text);
|
return JSON.parse(text);
|
||||||
|
@ -31,11 +30,6 @@ module.exports.create = function (app, xconfx, models) {
|
||||||
console.log('DEBUG not exists leconf', configpath);
|
console.log('DEBUG not exists leconf', configpath);
|
||||||
return false;
|
return false;
|
||||||
}).then(function (data) {
|
}).then(function (data) {
|
||||||
if (!data || !data.email || !data.agreeTos) {
|
|
||||||
console.log('DEBUG incomplete leconf', data);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -44,7 +38,7 @@ module.exports.create = function (app, xconfx, models) {
|
||||||
function initialize() {
|
function initialize() {
|
||||||
var express = require('express');
|
var express = require('express');
|
||||||
var getIpAddresses = require('./ip-checker').getExternalAddresses;
|
var getIpAddresses = require('./ip-checker').getExternalAddresses;
|
||||||
var resolve;
|
var resolveInit;
|
||||||
|
|
||||||
function errorIfNotApi(req, res, next) {
|
function errorIfNotApi(req, res, next) {
|
||||||
var hostname = req.hostname || req.headers.host;
|
var hostname = req.hostname || req.headers.host;
|
||||||
|
@ -142,106 +136,35 @@ module.exports.create = function (app, xconfx, models) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function setConfig(req, res) {
|
function setConfig(req, res) {
|
||||||
var config = req.body;
|
|
||||||
var results = {};
|
|
||||||
|
|
||||||
return PromiseA.resolve().then(function () {
|
return PromiseA.resolve().then(function () {
|
||||||
if (!config.agreeTos && !config.tls) {
|
// TODO expect authenticated oauth3 user
|
||||||
return PromiseA.reject(new Error("To enable encryption you must agree to the LetsEncrypt terms of service"));
|
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) {
|
config.domain = (config.domain||'').replace(/^www\./, '');
|
||||||
return PromiseA.reject(new Error("You must specify a valid domain name"));
|
|
||||||
}
|
|
||||||
config.domain = config.domain.replace(/^www\./, '');
|
|
||||||
|
|
||||||
return getIpAddresses().then(function (inet) {
|
// TODO url-testing lib
|
||||||
if (!inet.addresses.length) {
|
if (!/\w+\.\w+/.test(config.domain)) {
|
||||||
return PromiseA.reject(new Error("no ip addresses"));
|
return PromiseA.reject(new Error("'domain' should be a string specifying a valid domain name"));
|
||||||
}
|
}
|
||||||
|
|
||||||
results.inets = inet.addresses.map(function (a) {
|
|
||||||
a.time = undefined;
|
|
||||||
return a;
|
|
||||||
});
|
|
||||||
|
|
||||||
results.resolutions = [];
|
var configpath = path.join(__dirname, '..', '..', 'config', config.domain + '.json');
|
||||||
return PromiseA.all([
|
safeConfig = { primaryDomain: config.domain };
|
||||||
// for static content
|
return fs.writeFileAsync(configpath, JSON.stringify(safeConfig, null, ' '), 'utf8').then(function () {
|
||||||
verifyIps(inet.addresses, config.domain).then(function (ips) {
|
// TODO nix SQL
|
||||||
results.resolutions.push({ hostname: config.domain, ips: ips });
|
return models.ComDaplieWalnutConfig.upsert('config', safeConfig);
|
||||||
})
|
|
||||||
// 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" };
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
if (results.error) {
|
if (resolveInit) {
|
||||||
return;
|
resolveInit();
|
||||||
|
resolveInit = null;
|
||||||
}
|
}
|
||||||
|
res.send({ success: true });
|
||||||
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);
|
|
||||||
}, function (err) {
|
}, function (err) {
|
||||||
console.error('Error lib/bootstrap.js');
|
console.error('Error lib/bootstrap.js');
|
||||||
console.error(err.stack || err);
|
console.error(err.stack || err);
|
||||||
|
@ -259,19 +182,21 @@ module.exports.create = function (app, xconfx, models) {
|
||||||
], methods: [ "GET", "POST", "PATCH", "PUT", "DELETE" ] });
|
], methods: [ "GET", "POST", "PATCH", "PUT", "DELETE" ] });
|
||||||
|
|
||||||
app.use('/', function (req, res, next) {
|
app.use('/', function (req, res, next) {
|
||||||
|
console.log('[lib/bootstrap.js] req.url', req.url);
|
||||||
|
|
||||||
return isInitialized().then(function (initialized) {
|
return isInitialized().then(function (initialized) {
|
||||||
if (!initialized) {
|
if (!initialized) {
|
||||||
next();
|
next();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
resolve(true);
|
// init is always considered to be
|
||||||
|
resolveInit(true);
|
||||||
|
|
||||||
// force page refresh
|
// TODO feed this request back through the route stack from the top to avoid forced refresh?
|
||||||
// TODO goto top of routes?
|
|
||||||
res.statusCode = 302;
|
res.statusCode = 302;
|
||||||
res.setHeader('Location', req.url);
|
res.setHeader('Location', req.url);
|
||||||
res.end();
|
res.end("<!-- App bootstraping complete, but you got here somehow anyway. Let's redirect you so you get to the main app. -->");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
app.use('/api', errorIfNotApi);
|
app.use('/api', errorIfNotApi);
|
||||||
|
@ -283,10 +208,17 @@ module.exports.create = function (app, xconfx, models) {
|
||||||
app.get('/api/com.daplie.walnut.init', getConfig);
|
app.get('/api/com.daplie.walnut.init', getConfig);
|
||||||
app.post('/api/com.daplie.walnut.init', setConfig);
|
app.post('/api/com.daplie.walnut.init', setConfig);
|
||||||
app.use('/', errorIfApi);
|
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) {
|
return new PromiseA(function (_resolve) {
|
||||||
resolve = _resolve;
|
resolveInit = _resolve;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -157,15 +157,23 @@ module.exports.create = function (webserver, xconfx, state) {
|
||||||
};
|
};
|
||||||
|
|
||||||
var hostsmap = {};
|
var hostsmap = {};
|
||||||
|
|
||||||
function log(req, res, next) {
|
function log(req, res, next) {
|
||||||
var hostname = (req.hostname || req.headers.host || '').split(':').shift();
|
var hostname = (req.hostname || req.headers.host || '').split(':').shift();
|
||||||
|
|
||||||
|
// Printing all incoming requests for debugging
|
||||||
console.log('[worker/log]', req.method, hostname, req.url);
|
console.log('[worker/log]', req.method, hostname, req.url);
|
||||||
|
|
||||||
|
// logging all the invalid hostnames that come here out of curiousity
|
||||||
if (hostname && !hostsmap[hostname]) {
|
if (hostname && !hostsmap[hostname]) {
|
||||||
hostsmap[hostname] = true;
|
hostsmap[hostname] = true;
|
||||||
require('fs').writeFile(
|
require('fs').writeFile(
|
||||||
require('path').join(__dirname, '..', '..', 'var', 'hostnames', hostname)
|
require('path').join(__dirname, '..', '..', 'var', 'hostnames', hostname)
|
||||||
, hostname, function () {});
|
, hostname
|
||||||
|
, function () {}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,6 +225,7 @@ module.exports.create = function (webserver, xconfx, state) {
|
||||||
require('./unbrick-appcache').unbrick(req, res);
|
require('./unbrick-appcache').unbrick(req, res);
|
||||||
return;
|
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!");
|
res.end("Connection is not encrypted. That's no bueno or, as we say in Hungarian, nem szabad!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue