forkattu lähteestä coolaj86/goldilocks.js
		
	more network handling stuff
This commit is contained in:
		
							vanhempi
							
								
									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);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
      });
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
		Ladataan…
	
	
			
			x
			
			
		
	
		Viittaa uudesa ongelmassa
	
	Block a user