more network handling stuff

This commit is contained in:
AJ ONeal 2017-03-18 14:48:49 -06:00
parent 3b5d7a49d4
commit 54a8bc15d9
4 changed files with 146 additions and 46 deletions

View File

@ -12,6 +12,12 @@
Server Name: '<span ng-bind="vm.config.device.hostname"></span>' running from Server Name: '<span ng-bind="vm.config.device.hostname"></span>' running from
<br/> <br/>
<code><span ng-bind="vm.config.cwd"></span>/</code> <code><span ng-bind="vm.config.cwd"></span>/</code>
<br/>
iface: <span ng-bind="vm.admin.network.iface"></span>
<br/>
ipv4: <span ng-bind="vm.admin.network.ipv4"></span>
<br/>
ipv6: <span ng-bind="vm.admin.network.ipv6"></span>
</span> </span>
<br/> <br/>
<br/> <br/>
@ -20,7 +26,7 @@
<div class="container"> <div class="container">
<div class="row"> <div class="row">
<div class="col-md-4"> <div class="col-sm-3">
<ul class="nav nav-pills nav-stacked" ng-init="vm.admin.page = 'authn'"> <ul class="nav nav-pills nav-stacked" ng-init="vm.admin.page = 'authn'">
<li <li
role="presentation" role="presentation"
@ -104,7 +110,7 @@
</div> </div>
</div> </div>
<div class="col-md-8"> <div class="col-sm-9">
<div ng-if="!vm.config || 'authn' === vm.admin.page"> <div ng-if="!vm.config || 'authn' === vm.admin.page">
<p>In order to administer this server you must authenticate.</p> <p>In order to administer this server you must authenticate.</p>
@ -155,6 +161,7 @@
/> />
<button <button
type="button" type="button"
class="btn btn-primary"
ng-click="vm.admin.setDeviceName(vm.admin.servername)" ng-click="vm.admin.setDeviceName(vm.admin.servername)"
ng-disabled="vm.config.device.hostname === vm.admin.servername" ng-disabled="vm.config.device.hostname === vm.admin.servername"
>Save</button> >Save</button>
@ -214,6 +221,11 @@
<div ng-if="'oauth3-tunnel' === vm.admin.network.iface"> <div ng-if="'oauth3-tunnel' === vm.admin.network.iface">
<div ng-if="vm.admin.tunnel.advanced"> <div ng-if="vm.admin.tunnel.advanced">
<h2>OAuth3 Tunnel Options</h2> <h2>OAuth3 Tunnel Options</h2>
<label><input
type="checkbox"
ng-model="vm.admin.tunnel.optimistic"
ng-change="vm.setTunnel()"> Prefer local network when available</label>
<br/>
<label>URL</label> <input <label>URL</label> <input
class"form-input" class"form-input"
type="url" type="url"

View File

@ -19,7 +19,9 @@ angular.module('com.daplie.cloud', [ 'org.oauth3' ])
var vm = this; var vm = this;
var OAUTH3 = window.OAUTH3; var OAUTH3 = window.OAUTH3;
vm.hello = 'Hello!'; vm.admin = { network: { iface: null, ipv4: null, ipv6: null } };
vm.admin.ipify = 'https://api.ipify.org?format=json';
vm.clientUri = OAUTH3.clientUri(window.location); vm.clientUri = OAUTH3.clientUri(window.location);
vm.setSimple = function () { vm.setSimple = function () {
@ -178,10 +180,52 @@ angular.module('com.daplie.cloud', [ 'org.oauth3' ])
}).then(function (configResp) { }).then(function (configResp) {
console.log('config', configResp.data); console.log('config', configResp.data);
vm.config = configResp.data; vm.config = configResp.data;
vm.config.addresses.forEach(function (addr) {
if (/unicast/.test(addr.range) || /internet/i.test(addr.range)) {
// TODO
// there could be more than one iface (ipv4 on one and ipv6 on the other)
// there could also be more than one valid public ip
if ("IPv4" === addr.family) {
vm.admin.network.iface = addr.iface;
vm.admin.network.ipv4 = addr.address;
}
else if ("IPv6" === addr.family) {
// IPv6 gives valid internet address even when behind a firewall
// IPv6 requires a loopback test
// TODO always do the loopback / firewall test anyway
vm.admin.network.ipv6 = addr.address;
}
}
});
vm.admin.servername = vm.config.device.hostname;
//vm.config.ifaces //vm.config.ifaces
//vm.config.addresses = []; //vm.config.addresses = [];
vm.viewDomains(vm.config, domains, dns); vm.viewDomains(vm.config, domains, dns);
if (vm.admin.network.iface) {
return resp; return resp;
}
// TODO try UPnP IGD / NAT-PMP / DNS-SD / PCP (ipv6) here
// TODO two requests - one to {{ipv4.ipify.org}}, the other to {{ipv6.ipify.org}}
vm.admin.network.iface = 'gateway';
return OAUTH3.request({
method: 'POST'
, url: 'https://' + vm.clientUri + '/api/com.daplie.caddy/request'
, session: session
, data: {
method: 'GET'
, url: 'https://api.ipify.org?format=json'
}
}).then(function (ipResp) {
console.log('ip-response', ipResp);
vm.admin.network.ipv4 = ipResp.data.body.ipv4 || ipResp.data.body.ip;
vm.admin.network.ipv6 = ipResp.data.body.ipv6;
return resp;
});
}); });
}, function (err) { }, function (err) {
console.error(err); console.error(err);

View File

@ -75,6 +75,7 @@ module.exports = function (opts) {
} }
} }
, recase: require('recase').create({}) , recase: require('recase').create({})
, request: PromiseA.promisify(require('request'))
, options: opts , options: opts
}); });
} }
@ -163,6 +164,10 @@ module.exports = function (opts) {
serveInit.config(req, res); serveInit.config(req, res);
return; return;
} }
if ('/api/com.daplie.caddy/request' === req.url) {
serveInit.request(req, res);
return;
}
if (content && '/' === req.url) { if (content && '/' === req.url) {
// res.setHeader('Content-Type', 'application/octet-stream'); // res.setHeader('Content-Type', 'application/octet-stream');

View File

@ -48,6 +48,8 @@ module.exports.create = function (deps) {
init: function (req, res) { init: function (req, res) {
jsonParser(req, res, function () { jsonParser(req, res, function () {
return deps.PromiseA.resolve().then(function () {
console.log('req.body', req.body); console.log('req.body', req.body);
var auth = jwt.decode((req.headers.authorization||'').replace(/^bearer\s+/i, '')); var auth = jwt.decode((req.headers.authorization||'').replace(/^bearer\s+/i, ''));
var token = jwt.decode(req.body.access_token); var token = jwt.decode(req.body.access_token);
@ -62,6 +64,12 @@ module.exports.create = function (deps) {
var rid = crypto.createHash('sha256').update(refresh.sub).digest('hex'); var rid = crypto.createHash('sha256').update(refresh.sub).digest('hex');
console.log('ids', id, tid, rid); console.log('ids', id, tid, rid);
if (req.body.ip_url) {
// TODO set options / GunDB
deps.options.ip_url = req.body.ip_url;
}
return deps.storage.owners.all().then(function (results) { return deps.storage.owners.all().then(function (results) {
console.log('results', results); console.log('results', results);
var err; var err;
@ -69,7 +77,9 @@ module.exports.create = function (deps) {
// There is no owner yet. First come, first serve. // There is no owner yet. First come, first serve.
if (!results || !results.length) { if (!results || !results.length) {
if (tid !== id || rid !== id) { if (tid !== id || rid !== id) {
err = new Error("When creating an owner the Authorization Bearer and Token and Refresh must all match"); err = new Error(
"When creating an owner the Authorization Bearer and Token and Refresh must all match"
);
return deps.PromiseA.reject(err); return deps.PromiseA.reject(err);
} }
console.log('no owner, creating'); console.log('no owner, creating');
@ -96,6 +106,7 @@ module.exports.create = function (deps) {
}).then(function () { }).then(function () {
res.setHeader('Content-Type', 'application/json;'); res.setHeader('Content-Type', 'application/json;');
res.end(JSON.stringify({ success: true })); res.end(JSON.stringify({ success: true }));
});
}, function (err) { }, function (err) {
res.setHeader('Content-Type', 'application/json;'); res.setHeader('Content-Type', 'application/json;');
res.end(JSON.stringify({ error: { message: err.message, code: err.code, uri: err.uri } })); res.end(JSON.stringify({ error: { message: err.message, code: err.code, uri: err.uri } }));
@ -120,5 +131,33 @@ module.exports.create = function (deps) {
}); });
}); });
} }
, request: function (req, res) {
jsonParser(req, res, function () {
isAuthorized(req, res, function () {
deps.request({
method: req.body.method || 'GET'
, url: req.body.url
, headers: req.body.headers
, body: req.body.data
}).then(function (resp) {
if (resp.body instanceof Buffer || 'string' === typeof resp.body) {
resp.body = JSON.parse(resp.body);
}
return {
statusCode: resp.statusCode
, status: resp.status
, headers: resp.headers
, body: resp.body
, data: resp.data
};
}).then(function (result) {
res.send(result);
});
});
});
}
}; };
}; };