more network handling stuff
This commit is contained in:
parent
3b5d7a49d4
commit
54a8bc15d9
|
@ -12,6 +12,12 @@
|
|||
Server Name: '<span ng-bind="vm.config.device.hostname"></span>' running from
|
||||
<br/>
|
||||
<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>
|
||||
<br/>
|
||||
<br/>
|
||||
|
@ -20,7 +26,7 @@
|
|||
|
||||
<div class="container">
|
||||
<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'">
|
||||
<li
|
||||
role="presentation"
|
||||
|
@ -104,7 +110,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-8">
|
||||
<div class="col-sm-9">
|
||||
|
||||
<div ng-if="!vm.config || 'authn' === vm.admin.page">
|
||||
<p>In order to administer this server you must authenticate.</p>
|
||||
|
@ -155,6 +161,7 @@
|
|||
/>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-primary"
|
||||
ng-click="vm.admin.setDeviceName(vm.admin.servername)"
|
||||
ng-disabled="vm.config.device.hostname === vm.admin.servername"
|
||||
>Save</button>
|
||||
|
@ -214,6 +221,11 @@
|
|||
<div ng-if="'oauth3-tunnel' === vm.admin.network.iface">
|
||||
<div ng-if="vm.admin.tunnel.advanced">
|
||||
<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
|
||||
class"form-input"
|
||||
type="url"
|
||||
|
|
|
@ -19,7 +19,9 @@ angular.module('com.daplie.cloud', [ 'org.oauth3' ])
|
|||
var vm = this;
|
||||
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.setSimple = function () {
|
||||
|
@ -178,10 +180,52 @@ angular.module('com.daplie.cloud', [ 'org.oauth3' ])
|
|||
}).then(function (configResp) {
|
||||
console.log('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.addresses = [];
|
||||
vm.viewDomains(vm.config, domains, dns);
|
||||
return resp;
|
||||
|
||||
if (vm.admin.network.iface) {
|
||||
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) {
|
||||
console.error(err);
|
||||
|
|
|
@ -75,6 +75,7 @@ module.exports = function (opts) {
|
|||
}
|
||||
}
|
||||
, recase: require('recase').create({})
|
||||
, request: PromiseA.promisify(require('request'))
|
||||
, options: opts
|
||||
});
|
||||
}
|
||||
|
@ -163,6 +164,10 @@ module.exports = function (opts) {
|
|||
serveInit.config(req, res);
|
||||
return;
|
||||
}
|
||||
if ('/api/com.daplie.caddy/request' === req.url) {
|
||||
serveInit.request(req, res);
|
||||
return;
|
||||
}
|
||||
|
||||
if (content && '/' === req.url) {
|
||||
// res.setHeader('Content-Type', 'application/octet-stream');
|
||||
|
|
|
@ -48,54 +48,65 @@ module.exports.create = function (deps) {
|
|||
init: function (req, res) {
|
||||
jsonParser(req, res, function () {
|
||||
|
||||
console.log('req.body', req.body);
|
||||
var auth = jwt.decode((req.headers.authorization||'').replace(/^bearer\s+/i, ''));
|
||||
var token = jwt.decode(req.body.access_token);
|
||||
var refresh = jwt.decode(req.body.refresh_token);
|
||||
auth.sub = auth.sub || auth.acx.id;
|
||||
token.sub = token.sub || token.acx.id;
|
||||
refresh.sub = refresh.sub || refresh.acx.id;
|
||||
return deps.PromiseA.resolve().then(function () {
|
||||
|
||||
// TODO validate token with issuer, but as-is the sub is already a secret
|
||||
var id = crypto.createHash('sha256').update(auth.sub).digest('hex');
|
||||
var tid = crypto.createHash('sha256').update(token.sub).digest('hex');
|
||||
var rid = crypto.createHash('sha256').update(refresh.sub).digest('hex');
|
||||
console.log('req.body', req.body);
|
||||
var auth = jwt.decode((req.headers.authorization||'').replace(/^bearer\s+/i, ''));
|
||||
var token = jwt.decode(req.body.access_token);
|
||||
var refresh = jwt.decode(req.body.refresh_token);
|
||||
auth.sub = auth.sub || auth.acx.id;
|
||||
token.sub = token.sub || token.acx.id;
|
||||
refresh.sub = refresh.sub || refresh.acx.id;
|
||||
|
||||
console.log('ids', id, tid, rid);
|
||||
return deps.storage.owners.all().then(function (results) {
|
||||
console.log('results', results);
|
||||
var err;
|
||||
// TODO validate token with issuer, but as-is the sub is already a secret
|
||||
var id = crypto.createHash('sha256').update(auth.sub).digest('hex');
|
||||
var tid = crypto.createHash('sha256').update(token.sub).digest('hex');
|
||||
var rid = crypto.createHash('sha256').update(refresh.sub).digest('hex');
|
||||
|
||||
// There is no owner yet. First come, first serve.
|
||||
if (!results || !results.length) {
|
||||
if (tid !== id || rid !== id) {
|
||||
err = new Error("When creating an owner the Authorization Bearer and Token and Refresh must all match");
|
||||
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) {
|
||||
console.log('results', results);
|
||||
var err;
|
||||
|
||||
// There is no owner yet. First come, first serve.
|
||||
if (!results || !results.length) {
|
||||
if (tid !== id || rid !== id) {
|
||||
err = new Error(
|
||||
"When creating an owner the Authorization Bearer and Token and Refresh must all match"
|
||||
);
|
||||
return deps.PromiseA.reject(err);
|
||||
}
|
||||
console.log('no owner, creating');
|
||||
return deps.storage.owners.set(id, { token: token, refresh: refresh });
|
||||
}
|
||||
console.log('has results');
|
||||
|
||||
// There are onwers. Is this one of them?
|
||||
if (!results.some(function (token) {
|
||||
return scmp(id, token.id);
|
||||
})) {
|
||||
err = new Error("Authorization token does not belong to an existing owner.");
|
||||
return deps.PromiseA.reject(err);
|
||||
}
|
||||
console.log('no owner, creating');
|
||||
return deps.storage.owners.set(id, { token: token, refresh: refresh });
|
||||
}
|
||||
console.log('has results');
|
||||
console.log('has correct owner');
|
||||
|
||||
// There are onwers. Is this one of them?
|
||||
if (!results.some(function (token) {
|
||||
return scmp(id, token.id);
|
||||
})) {
|
||||
err = new Error("Authorization token does not belong to an existing owner.");
|
||||
return deps.PromiseA.reject(err);
|
||||
}
|
||||
console.log('has correct owner');
|
||||
|
||||
// We're adding an owner, unless it already exists
|
||||
if (!results.some(function (token) {
|
||||
return scmp(tid, token.id);
|
||||
})) {
|
||||
console.log('adds new owner with existing owner');
|
||||
return deps.storage.owners.set(id, { token: token, refresh: refresh });
|
||||
}
|
||||
}).then(function () {
|
||||
res.setHeader('Content-Type', 'application/json;');
|
||||
res.end(JSON.stringify({ success: true }));
|
||||
// We're adding an owner, unless it already exists
|
||||
if (!results.some(function (token) {
|
||||
return scmp(tid, token.id);
|
||||
})) {
|
||||
console.log('adds new owner with existing owner');
|
||||
return deps.storage.owners.set(id, { token: token, refresh: refresh });
|
||||
}
|
||||
}).then(function () {
|
||||
res.setHeader('Content-Type', 'application/json;');
|
||||
res.end(JSON.stringify({ success: true }));
|
||||
});
|
||||
}, function (err) {
|
||||
res.setHeader('Content-Type', 'application/json;');
|
||||
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);
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue