server will wait for token
This commit is contained in:
		
							parent
							
								
									2456228ae5
								
							
						
					
					
						commit
						02a89b52a4
					
				@ -325,7 +325,7 @@ function askForConfig(answers, mainCb) {
 | 
				
			|||||||
    var q = nextSet.shift();
 | 
					    var q = nextSet.shift();
 | 
				
			||||||
    if (!q) {
 | 
					    if (!q) {
 | 
				
			||||||
      // https://github.com/nodejs/node/issues/21319
 | 
					      // https://github.com/nodejs/node/issues/21319
 | 
				
			||||||
      if (useTty) { stdin.push(null); }
 | 
					      if (useTty) { try { stdin.push(null); } catch(e) { /*ignore*/ } }
 | 
				
			||||||
      rl.close();
 | 
					      rl.close();
 | 
				
			||||||
      if (useTty) { try { stdin.close(); } catch(e) { /*ignore*/ } }
 | 
					      if (useTty) { try { stdin.close(); } catch(e) { /*ignore*/ } }
 | 
				
			||||||
      mainCb(null, answers);
 | 
					      mainCb(null, answers);
 | 
				
			||||||
@ -531,11 +531,34 @@ function parseConfig(err, text) {
 | 
				
			|||||||
  if (-1 !== argv.indexOf('init')) {
 | 
					  if (-1 !== argv.indexOf('init')) {
 | 
				
			||||||
    parsers.init(argv, function (err, answers) {
 | 
					    parsers.init(argv, function (err, answers) {
 | 
				
			||||||
      if (err) {
 | 
					      if (err) {
 | 
				
			||||||
        console.error("Error while initializing config:");
 | 
					        console.error("Error while initializing config [init]:");
 | 
				
			||||||
        throw err;
 | 
					        throw err;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      // TODO make one request to set and then poll for readiness
 | 
					      common.api.token(state, {
 | 
				
			||||||
 | 
					        error: function (err/*, next*/) {
 | 
				
			||||||
 | 
					          console.error("[Error] common.api.token:");
 | 
				
			||||||
 | 
					          console.error(err);
 | 
				
			||||||
 | 
					          return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      , directory: function (dir, next) {
 | 
				
			||||||
 | 
					          //console.log('Telebit Relay Discovered:');
 | 
				
			||||||
 | 
					          state._apiDirectory = dir;
 | 
				
			||||||
 | 
					          //console.log(dir);
 | 
				
			||||||
 | 
					          //console.log();
 | 
				
			||||||
 | 
					          next();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      , tunnelUrl: function (tunnelUrl, next) {
 | 
				
			||||||
 | 
					          //console.log('Telebit Relay Tunnel Socket:', tunnelUrl);
 | 
				
			||||||
 | 
					          state.wss = tunnelUrl;
 | 
				
			||||||
 | 
					          next();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      , requested: function (authReq, next) {
 | 
				
			||||||
 | 
					          //console.log("Pairing Requested");
 | 
				
			||||||
 | 
					          var pin = authReq.pin || authReq.otp || authReq.pairCode;
 | 
				
			||||||
 | 
					          state.otp = state._otp = pin;
 | 
				
			||||||
 | 
					          state.auth = state.authRequest = state._auth = authReq;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          if (!answers.token && answers._can_pair) {
 | 
					          if (!answers.token && answers._can_pair) {
 | 
				
			||||||
            console.info("");
 | 
					            console.info("");
 | 
				
			||||||
            console.info("==============================================");
 | 
					            console.info("==============================================");
 | 
				
			||||||
@ -550,17 +573,54 @@ function parseConfig(err, text) {
 | 
				
			|||||||
            console.info("");
 | 
					            console.info("");
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          next();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      , connect: function (pretoken, next) {
 | 
				
			||||||
 | 
					          //console.log("Enabling Pairing Locally...");
 | 
				
			||||||
 | 
					          answers.token = pretoken;
 | 
				
			||||||
 | 
					          answers._connecting = true;
 | 
				
			||||||
          // TODO use php-style object querification
 | 
					          // TODO use php-style object querification
 | 
				
			||||||
          utils.putConfig('config', Object.keys(answers).map(function (key) {
 | 
					          utils.putConfig('config', Object.keys(answers).map(function (key) {
 | 
				
			||||||
            return key + ':' + answers[key];
 | 
					            return key + ':' + answers[key];
 | 
				
			||||||
          }), function (err/*, body*/) {
 | 
					          }), function (err/*, body*/) {
 | 
				
			||||||
            if (err) {
 | 
					            if (err) {
 | 
				
			||||||
          console.error("Error while initializing config:");
 | 
					              answers._error = err;
 | 
				
			||||||
          throw err;
 | 
					              console.error("Error while initializing config [connect]:");
 | 
				
			||||||
 | 
					              console.error(err);
 | 
				
			||||||
 | 
					              return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            //console.log("Pairing Enabled Locally");
 | 
				
			||||||
        // need just a little time to let the grants occur
 | 
					            next();
 | 
				
			||||||
        setTimeout(function () {
 | 
					          });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      , offer: function (token, next) {
 | 
				
			||||||
 | 
					          //console.log("Pairing Enabled by Relay");
 | 
				
			||||||
 | 
					          answers.token = token;
 | 
				
			||||||
 | 
					          if (answers._error) {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          if (answers._connecting) {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          answers._connecting = true;
 | 
				
			||||||
 | 
					          utils.putConfig('config', Object.keys(answers).map(function (key) {
 | 
				
			||||||
 | 
					            return key + ':' + answers[key];
 | 
				
			||||||
 | 
					          }), function (err/*, body*/) {
 | 
				
			||||||
 | 
					            if (err) {
 | 
				
			||||||
 | 
					              answers._error = err;
 | 
				
			||||||
 | 
					              console.error("Error while initializing config [offer]:");
 | 
				
			||||||
 | 
					              console.error(err);
 | 
				
			||||||
 | 
					              return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            //console.log("Pairing Enabled Locally");
 | 
				
			||||||
 | 
					            next();
 | 
				
			||||||
 | 
					          });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      , granted: function (_, next) {
 | 
				
			||||||
 | 
					          //console.log("Token has been granted!");
 | 
				
			||||||
 | 
					          next();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      , end: function () {
 | 
				
			||||||
          utils.putConfig('enable', [], function () {
 | 
					          utils.putConfig('enable', [], function () {
 | 
				
			||||||
            utils.putConfig('list', [], function (err) {
 | 
					            utils.putConfig('list', [], function (err) {
 | 
				
			||||||
              if (err) { console.error(err); return; }
 | 
					              if (err) { console.error(err); return; }
 | 
				
			||||||
@ -577,8 +637,7 @@ function parseConfig(err, text) {
 | 
				
			|||||||
              // end workaround
 | 
					              // end workaround
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
          });
 | 
					          });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        }, 1 * 1000);
 | 
					 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										235
									
								
								bin/telebitd.js
									
									
									
									
									
								
							
							
						
						
									
										235
									
								
								bin/telebitd.js
									
									
									
									
									
								
							@ -29,7 +29,7 @@ if (-1 !== confIndex) {
 | 
				
			|||||||
  confpath = confargs[1];
 | 
					  confpath = confargs[1];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
require('../lib/updater')(pkg);
 | 
					var cancelUpdater = require('../lib/updater')(pkg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function help() {
 | 
					function help() {
 | 
				
			||||||
  console.info('');
 | 
					  console.info('');
 | 
				
			||||||
@ -54,7 +54,7 @@ if (-1 === confIndex) {
 | 
				
			|||||||
  //   * {install}/etc/telebitd.yml
 | 
					  //   * {install}/etc/telebitd.yml
 | 
				
			||||||
  //   * ~/.config/telebit/telebitd.yml
 | 
					  //   * ~/.config/telebit/telebitd.yml
 | 
				
			||||||
  // We'll asume the later since the installers include --config in the system launcher script
 | 
					  // We'll asume the later since the installers include --config in the system launcher script
 | 
				
			||||||
  confpath = path.join(state.homedir, '.config/telebit/telebitd.yml');
 | 
					  confpath = common.DEFAULT_CONFIG_PATH;
 | 
				
			||||||
  verstr.push('(--config "' + confpath + '")');
 | 
					  verstr.push('(--config "' + confpath + '")');
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -69,12 +69,11 @@ if (!confpath || /^--/.test(confpath)) {
 | 
				
			|||||||
var tokenpath = path.join(path.dirname(confpath), 'access_token.txt');
 | 
					var tokenpath = path.join(path.dirname(confpath), 'access_token.txt');
 | 
				
			||||||
var token;
 | 
					var token;
 | 
				
			||||||
try {
 | 
					try {
 | 
				
			||||||
  token = require('fs').readFileSync(tokenpath, 'ascii').trim();
 | 
					  token = fs.readFileSync(tokenpath, 'ascii').trim();
 | 
				
			||||||
} catch(e) {
 | 
					} catch(e) {
 | 
				
			||||||
  // ignore
 | 
					  // ignore
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
var controlServer;
 | 
					var controlServer;
 | 
				
			||||||
 | 
					 | 
				
			||||||
var tun;
 | 
					var tun;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function serveControlsHelper() {
 | 
					function serveControlsHelper() {
 | 
				
			||||||
@ -103,12 +102,7 @@ function serveControlsHelper() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      if (state._can_pair && state.config.email && !state.token) {
 | 
					      if (state._can_pair && state.config.email && !state.token) {
 | 
				
			||||||
        dumpy.code = "AWAIT_AUTH";
 | 
					        dumpy.code = "AWAIT_AUTH";
 | 
				
			||||||
        dumpy.message = [
 | 
					        dumpy.message = "Please run 'telebit init' to authenticate.";
 | 
				
			||||||
          "Check your email."
 | 
					 | 
				
			||||||
        , "You must verify your email address to activate this device."
 | 
					 | 
				
			||||||
        , ""
 | 
					 | 
				
			||||||
        , "    Device Pairing Code: " + state.otp
 | 
					 | 
				
			||||||
        ].join('\n');
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      res.end(JSON.stringify(dumpy));
 | 
					      res.end(JSON.stringify(dumpy));
 | 
				
			||||||
@ -134,9 +128,23 @@ function serveControlsHelper() {
 | 
				
			|||||||
    //
 | 
					    //
 | 
				
			||||||
    // without proper config
 | 
					    // without proper config
 | 
				
			||||||
    //
 | 
					    //
 | 
				
			||||||
 | 
					    function saveAndReport(err, _tun) {
 | 
				
			||||||
 | 
					      if (err) { throw err; }
 | 
				
			||||||
 | 
					      tun = _tun;
 | 
				
			||||||
 | 
					      fs.writeFile(confpath, YAML.safeDump(snakeCopy(state.config)), function (err) {
 | 
				
			||||||
 | 
					        if (err) {
 | 
				
			||||||
 | 
					          res.statusCode = 500;
 | 
				
			||||||
 | 
					          res.setHeader('Content-Type', 'application/json');
 | 
				
			||||||
 | 
					          res.end('{"error":{"message":"Could not save config file after init: ' + err.message.replace(/"/g, "'")
 | 
				
			||||||
 | 
					            + '.\nPerhaps check that the file exists and your user has permissions to write it?"}}');
 | 
				
			||||||
 | 
					          return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        listSuccess();
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    if (/\b(init|config)\b/.test(opts.pathname)) {
 | 
					    if (/\b(init|config)\b/.test(opts.pathname)) {
 | 
				
			||||||
      var conf = {};
 | 
					      var conf = {};
 | 
				
			||||||
      var fresh;
 | 
					 | 
				
			||||||
      if (!opts.body) {
 | 
					      if (!opts.body) {
 | 
				
			||||||
        res.statusCode = 422;
 | 
					        res.statusCode = 422;
 | 
				
			||||||
        res.end('{"error":{"message":"module \'init\' needs more arguments"}}');
 | 
					        res.end('{"error":{"message":"module \'init\' needs more arguments"}}');
 | 
				
			||||||
@ -157,9 +165,6 @@ function serveControlsHelper() {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        conf[parts[0]] = parts[1];
 | 
					        conf[parts[0]] = parts[1];
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
      if (!state.config.relay || !state.config.email || !state.config.agreeTos) {
 | 
					 | 
				
			||||||
        fresh = true;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      // TODO camelCase query
 | 
					      // TODO camelCase query
 | 
				
			||||||
      state.config.email = conf.email || state.config.email || '';
 | 
					      state.config.email = conf.email || state.config.email || '';
 | 
				
			||||||
@ -170,6 +175,10 @@ function serveControlsHelper() {
 | 
				
			|||||||
      state.config.relay = conf.relay || state.config.relay || '';
 | 
					      state.config.relay = conf.relay || state.config.relay || '';
 | 
				
			||||||
      state.config.token = conf.token || state.config.token || null;
 | 
					      state.config.token = conf.token || state.config.token || null;
 | 
				
			||||||
      state.config.secret = conf.secret || state.config.secret || null;
 | 
					      state.config.secret = conf.secret || state.config.secret || null;
 | 
				
			||||||
 | 
					      state.pretoken = conf.pretoken || state.config.pretoken || null;
 | 
				
			||||||
 | 
					      if (state.secret) {
 | 
				
			||||||
 | 
					        state.token = common.signToken(state);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
      if ('undefined' !== typeof conf.newsletter) {
 | 
					      if ('undefined' !== typeof conf.newsletter) {
 | 
				
			||||||
        state.config.newsletter = conf.newsletter;
 | 
					        state.config.newsletter = conf.newsletter;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
@ -197,6 +206,7 @@ function serveControlsHelper() {
 | 
				
			|||||||
      if (!state.config.relay || !state.config.email || !state.config.agreeTos) {
 | 
					      if (!state.config.relay || !state.config.email || !state.config.agreeTos) {
 | 
				
			||||||
        res.statusCode = 400;
 | 
					        res.statusCode = 400;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        res.setHeader('Content-Type', 'application/json');
 | 
				
			||||||
        res.end(JSON.stringify({
 | 
					        res.end(JSON.stringify({
 | 
				
			||||||
          error: {
 | 
					          error: {
 | 
				
			||||||
            code: "E_INIT"
 | 
					            code: "E_INIT"
 | 
				
			||||||
@ -222,28 +232,13 @@ function serveControlsHelper() {
 | 
				
			|||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        rawTunnel(saveAndReport);
 | 
					        rawTunnel(saveAndReport);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					 | 
				
			||||||
      function saveAndReport(err, _tun) {
 | 
					 | 
				
			||||||
        if (err) { throw err; }
 | 
					 | 
				
			||||||
        tun = _tun;
 | 
					 | 
				
			||||||
        fs.writeFile(confpath, YAML.safeDump(snakeCopy(state.config)), function (err) {
 | 
					 | 
				
			||||||
          if (err) {
 | 
					 | 
				
			||||||
            res.statusCode = 500;
 | 
					 | 
				
			||||||
            res.end('{"error":{"message":"Could not save config file after init: ' + err.message.replace(/"/g, "'")
 | 
					 | 
				
			||||||
              + '.\nPerhaps check that the file exists and your user has permissions to write it?"}}');
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          listSuccess();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (/restart/.test(opts.pathname)) {
 | 
					    if (/restart/.test(opts.pathname)) {
 | 
				
			||||||
      tun.end();
 | 
					      tun.end();
 | 
				
			||||||
      res.end('{"success":true}');
 | 
					      res.setHeader('Content-Type', 'application/json');
 | 
				
			||||||
 | 
					      res.end(JSON.stringify({ success: true }));
 | 
				
			||||||
      controlServer.close(function () {
 | 
					      controlServer.close(function () {
 | 
				
			||||||
        // TODO closeAll other things
 | 
					        // TODO closeAll other things
 | 
				
			||||||
        process.nextTick(function () {
 | 
					        process.nextTick(function () {
 | 
				
			||||||
@ -259,7 +254,10 @@ function serveControlsHelper() {
 | 
				
			|||||||
    //
 | 
					    //
 | 
				
			||||||
    if (!state.config.relay || !state.config.email || !state.config.agreeTos) {
 | 
					    if (!state.config.relay || !state.config.email || !state.config.agreeTos) {
 | 
				
			||||||
      res.statusCode = 400;
 | 
					      res.statusCode = 400;
 | 
				
			||||||
      res.end('{"error":{"code":"E_CONFIG","message":"Invalid config file. Please run \'telebit init\'"}}');
 | 
					      res.setHeader('Content-Type', 'application/json');
 | 
				
			||||||
 | 
					      res.end(JSON.stringify({
 | 
				
			||||||
 | 
					        error: { code: "E_CONFIG", message: "Invalid config file. Please run 'telebit init'" }
 | 
				
			||||||
 | 
					      }));
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -269,13 +267,15 @@ function serveControlsHelper() {
 | 
				
			|||||||
    if (/http/.test(opts.pathname)) {
 | 
					    if (/http/.test(opts.pathname)) {
 | 
				
			||||||
      if (!opts.body) {
 | 
					      if (!opts.body) {
 | 
				
			||||||
        res.statusCode = 422;
 | 
					        res.statusCode = 422;
 | 
				
			||||||
        res.end('{"error":{"message":"module \'http\' needs more arguments"}}');
 | 
					        res.setHeader('Content-Type', 'application/json');
 | 
				
			||||||
 | 
					        res.end(JSON.stringify({"error":{"message":"module \'http\' needs more arguments"}}));
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      if (opts.body[1]) {
 | 
					      if (opts.body[1]) {
 | 
				
			||||||
        if (!state.servernames[opts.body[1]]) {
 | 
					        if (!state.servernames[opts.body[1]]) {
 | 
				
			||||||
          res.statusCode = 400;
 | 
					          res.statusCode = 400;
 | 
				
			||||||
          res.end('{"error":{"message":"bad servername \'' + opts.body[1] + '\'"');
 | 
					          res.setHeader('Content-Type', 'application/json');
 | 
				
			||||||
 | 
					          res.end(JSON.stringify({ error: { "message":"bad servername '" + opts.body[1] + "'" } }));
 | 
				
			||||||
          return;
 | 
					          return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        state.servernames[opts.body[1]].handler = opts.body[0];
 | 
					        state.servernames[opts.body[1]].handler = opts.body[0];
 | 
				
			||||||
@ -284,14 +284,16 @@ function serveControlsHelper() {
 | 
				
			|||||||
          state.servernames[key].handler = opts.body[0];
 | 
					          state.servernames[key].handler = opts.body[0];
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      res.end('{"success":true}');
 | 
					      res.setHeader('Content-Type', 'application/json');
 | 
				
			||||||
 | 
					      res.end(JSON.stringify({ success: true }));
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (/tcp/.test(opts.pathname)) {
 | 
					    if (/tcp/.test(opts.pathname)) {
 | 
				
			||||||
      if (!opts.body) {
 | 
					      if (!opts.body) {
 | 
				
			||||||
        res.statusCode = 422;
 | 
					        res.statusCode = 422;
 | 
				
			||||||
        res.end('{"error":{"message":"module \'tcp\' needs more arguments"}}');
 | 
					        res.setHeader('Content-Type', 'application/json');
 | 
				
			||||||
 | 
					        res.end(JSON.stringify({ error: { message: "module 'tcp' needs more arguments" } }));
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -299,7 +301,8 @@ function serveControlsHelper() {
 | 
				
			|||||||
      if (opts.body[1]) {
 | 
					      if (opts.body[1]) {
 | 
				
			||||||
        if (!state.ports[opts.body[1]]) {
 | 
					        if (!state.ports[opts.body[1]]) {
 | 
				
			||||||
          res.statusCode = 400;
 | 
					          res.statusCode = 400;
 | 
				
			||||||
          res.end('{"error":{"message":"bad port \'' + opts.body[1] + '\'"');
 | 
					          res.setHeader('Content-Type', 'application/json');
 | 
				
			||||||
 | 
					          res.end(JSON.stringify({ error: { "message":"bad port '" + opts.body[1] + "'" } }));
 | 
				
			||||||
          return;
 | 
					          return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        // forward-to port-or-module
 | 
					        // forward-to port-or-module
 | 
				
			||||||
@ -309,7 +312,8 @@ function serveControlsHelper() {
 | 
				
			|||||||
          state.ports[key].handler = opts.body[0];
 | 
					          state.ports[key].handler = opts.body[0];
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      res.end('{"success":true}');
 | 
					      res.setHeader('Content-Type', 'application/json');
 | 
				
			||||||
 | 
					      res.end(JSON.stringify({ success: true }));
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -319,7 +323,10 @@ function serveControlsHelper() {
 | 
				
			|||||||
      fs.writeFile(confpath, YAML.safeDump(snakeCopy(state.config)), function (err) {
 | 
					      fs.writeFile(confpath, YAML.safeDump(snakeCopy(state.config)), function (err) {
 | 
				
			||||||
        if (err) {
 | 
					        if (err) {
 | 
				
			||||||
          res.statusCode = 500;
 | 
					          res.statusCode = 500;
 | 
				
			||||||
          res.end('{"error":{"message":"Could not save config file. Perhaps you\'re not running as root?"}}');
 | 
					          res.setHeader('Content-Type', 'application/json');
 | 
				
			||||||
 | 
					          res.end(JSON.stringify({
 | 
				
			||||||
 | 
					            "error":{"message":"Could not save config file. Perhaps you're not running as root?"}
 | 
				
			||||||
 | 
					          }));
 | 
				
			||||||
          return;
 | 
					          return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        listSuccess();
 | 
					        listSuccess();
 | 
				
			||||||
@ -331,7 +338,8 @@ function serveControlsHelper() {
 | 
				
			|||||||
      var sshAuto;
 | 
					      var sshAuto;
 | 
				
			||||||
      if (!opts.body) {
 | 
					      if (!opts.body) {
 | 
				
			||||||
        res.statusCode = 422;
 | 
					        res.statusCode = 422;
 | 
				
			||||||
        res.end('{"error":{"message":"module \'ssh\' needs more arguments"}}');
 | 
					        res.setHeader('Content-Type', 'application/json');
 | 
				
			||||||
 | 
					        res.end(JSON.stringify({"error":{"message":"module 'ssh' needs more arguments"}}));
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -349,7 +357,8 @@ function serveControlsHelper() {
 | 
				
			|||||||
      sshAuto = parseInt(sshAuto, 10);
 | 
					      sshAuto = parseInt(sshAuto, 10);
 | 
				
			||||||
      if (!sshAuto || sshAuto <= 0 || sshAuto > 65535) {
 | 
					      if (!sshAuto || sshAuto <= 0 || sshAuto > 65535) {
 | 
				
			||||||
        res.statusCode = 400;
 | 
					        res.statusCode = 400;
 | 
				
			||||||
        res.end('{"error":{"message":"bad ssh_auto option \'' + opts.body[0] + '\'"');
 | 
					        res.setHeader('Content-Type', 'application/json');
 | 
				
			||||||
 | 
					        res.end(JSON.stringify({ error: { message: "bad ssh_auto option '" + opts.body[0] + "'" } }));
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      state.config.sshAuto = sshAuto;
 | 
					      state.config.sshAuto = sshAuto;
 | 
				
			||||||
@ -369,7 +378,10 @@ function serveControlsHelper() {
 | 
				
			|||||||
        fs.writeFile(confpath, YAML.safeDump(snakeCopy(state.config)), function (err) {
 | 
					        fs.writeFile(confpath, YAML.safeDump(snakeCopy(state.config)), function (err) {
 | 
				
			||||||
          if (err) {
 | 
					          if (err) {
 | 
				
			||||||
            res.statusCode = 500;
 | 
					            res.statusCode = 500;
 | 
				
			||||||
            res.end('{"error":{"message":"Could not save config file. Perhaps you\'re user doesn\'t have permission?"}}');
 | 
					            res.setHeader('Content-Type', 'application/json');
 | 
				
			||||||
 | 
					            res.end(JSON.stringify({
 | 
				
			||||||
 | 
					              error: { message: "Could not save config file. Perhaps you're user doesn't have permission?" }
 | 
				
			||||||
 | 
					            }));
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
          listSuccess();
 | 
					          listSuccess();
 | 
				
			||||||
@ -382,9 +394,12 @@ function serveControlsHelper() {
 | 
				
			|||||||
      state.config.disable = true;
 | 
					      state.config.disable = true;
 | 
				
			||||||
      if (tun) { tun.end(); tun = null; }
 | 
					      if (tun) { tun.end(); tun = null; }
 | 
				
			||||||
      fs.writeFile(confpath, YAML.safeDump(snakeCopy(state.config)), function (err) {
 | 
					      fs.writeFile(confpath, YAML.safeDump(snakeCopy(state.config)), function (err) {
 | 
				
			||||||
 | 
					        res.setHeader('Content-Type', 'application/json');
 | 
				
			||||||
        if (err) {
 | 
					        if (err) {
 | 
				
			||||||
          res.statusCode = 500;
 | 
					          res.statusCode = 500;
 | 
				
			||||||
          res.end('{"error":{"message":"Could not save config file. Perhaps you\'re not running as root?"}}');
 | 
					          res.end(JSON.stringify({
 | 
				
			||||||
 | 
					            "error":{"message":"Could not save config file. Perhaps you're not running as root?"}
 | 
				
			||||||
 | 
					          }));
 | 
				
			||||||
          return;
 | 
					          return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        res.end('{"success":true}');
 | 
					        res.end('{"success":true}');
 | 
				
			||||||
@ -393,6 +408,7 @@ function serveControlsHelper() {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (/status/.test(opts.pathname)) {
 | 
					    if (/status/.test(opts.pathname)) {
 | 
				
			||||||
 | 
					      res.setHeader('Content-Type', 'application/json');
 | 
				
			||||||
      res.end(JSON.stringify(
 | 
					      res.end(JSON.stringify(
 | 
				
			||||||
        { status: (state.config.disable ? 'disabled' : 'enabled')
 | 
					        { status: (state.config.disable ? 'disabled' : 'enabled')
 | 
				
			||||||
        , ready: ((state.config.relay && (state.config.token || state.config.agreeTos)) ? true : false)
 | 
					        , ready: ((state.config.relay && (state.config.token || state.config.agreeTos)) ? true : false)
 | 
				
			||||||
@ -406,7 +422,8 @@ function serveControlsHelper() {
 | 
				
			|||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    res.end('{"error":{"message":"unrecognized rpc"}}');
 | 
					    res.setHeader('Content-Type', 'application/json');
 | 
				
			||||||
 | 
					    res.end(JSON.stringify({"error":{"message":"unrecognized rpc"}}));
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
  if (fs.existsSync(state._ipc.path)) {
 | 
					  if (fs.existsSync(state._ipc.path)) {
 | 
				
			||||||
    fs.unlinkSync(state._ipc.path);
 | 
					    fs.unlinkSync(state._ipc.path);
 | 
				
			||||||
@ -422,24 +439,32 @@ function serveControlsHelper() {
 | 
				
			|||||||
  , exclusive: false
 | 
					  , exclusive: false
 | 
				
			||||||
  }, function () {
 | 
					  }, function () {
 | 
				
			||||||
    process.umask(oldUmask);
 | 
					    process.umask(oldUmask);
 | 
				
			||||||
 | 
					    //console.log(this.address());
 | 
				
			||||||
 | 
					    console.info("[info] Listening for commands on " + state._ipc.path);
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function serveControls() {
 | 
					function serveControls() {
 | 
				
			||||||
  if (!state.config.disable) {
 | 
					  if (state.config.disable) {
 | 
				
			||||||
    if (state.config.relay && (state.config.token || state.config.agreeTos)) {
 | 
					    console.info("[info] starting disabled");
 | 
				
			||||||
      setTimeout(function () {
 | 
					 | 
				
			||||||
        // TODO move back to callback once mutual-dependency on clientside init is resolved
 | 
					 | 
				
			||||||
        // (requires moving token fetching to clientside)
 | 
					 | 
				
			||||||
        serveControlsHelper();
 | 
					 | 
				
			||||||
      }, 350);
 | 
					 | 
				
			||||||
      rawTunnel(function (err, _tun) {
 | 
					 | 
				
			||||||
        if (err) { throw err; }
 | 
					 | 
				
			||||||
        tun = _tun;
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (state.config.relay && (state.config.token || state.config.pretoken)) {
 | 
				
			||||||
 | 
					    console.info("[info] connecting with stored token");
 | 
				
			||||||
 | 
					    rawTunnel(function (err, _tun) {
 | 
				
			||||||
 | 
					      if (err) { throw err; }
 | 
				
			||||||
 | 
					      if (_tun) { tun = _tun; }
 | 
				
			||||||
 | 
					      setTimeout(function () {
 | 
				
			||||||
 | 
					        // TODO attach handler to tunnel
 | 
				
			||||||
 | 
					        serveControlsHelper();
 | 
				
			||||||
 | 
					      }, 150);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    console.info("[info] waiting for init/authentication (missing relay and/or token)");
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  serveControlsHelper();
 | 
					  serveControlsHelper();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -451,7 +476,7 @@ function parseConfig(err, text) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    common._init(
 | 
					    common._init(
 | 
				
			||||||
      state.config.root || path.join(__dirname, '..')
 | 
					      state.config.root || path.join(__dirname, '..')
 | 
				
			||||||
    , (state.config.root && path.join(state.config.root, 'etc')) || path.join(os.homedir(), '.config/telebit')
 | 
					    , (state.config.root && path.join(state.config.root, 'etc')) || path.resolve(common.DEFAULT_CONFIG_PATH, '..')
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
    state._ipc = common.pipename(state.config, true);
 | 
					    state._ipc = common.pipename(state.config, true);
 | 
				
			||||||
    console.info('');
 | 
					    console.info('');
 | 
				
			||||||
@ -461,6 +486,7 @@ function parseConfig(err, text) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    console.info('');
 | 
					    console.info('');
 | 
				
			||||||
    state.token = state.token || state.config.token || token;
 | 
					    state.token = state.token || state.config.token || token;
 | 
				
			||||||
 | 
					    state.pretoken = state.pretoken || state.config.pretoken;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    state._confpath = confpath;
 | 
					    state._confpath = confpath;
 | 
				
			||||||
    if (!state.config.servernames) {
 | 
					    if (!state.config.servernames) {
 | 
				
			||||||
@ -513,82 +539,25 @@ function rawTunnel(rawCb) {
 | 
				
			|||||||
    return;
 | 
					    return;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // TODO move to client bin/telebit.js
 | 
					  if (!(state.token || state.pretoken)) {
 | 
				
			||||||
  common.api.token(state, {
 | 
					    rawCb(null, null);
 | 
				
			||||||
    error: function (err/*, next*/) {
 | 
					 | 
				
			||||||
      console.error("[Error] common.api.token:");
 | 
					 | 
				
			||||||
      console.error(err);
 | 
					 | 
				
			||||||
      rawCb(err);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  , directory: function (dir, next) {
 | 
					 | 
				
			||||||
      console.log('Telebit Relay Discovered:');
 | 
					 | 
				
			||||||
      state._apiDirectory = dir;
 | 
					 | 
				
			||||||
      console.log(dir);
 | 
					 | 
				
			||||||
      console.log();
 | 
					 | 
				
			||||||
      next();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  , tunnelUrl: function (tunnelUrl, next) {
 | 
					 | 
				
			||||||
      console.log('Telebit Relay Tunnel Socket:', tunnelUrl);
 | 
					 | 
				
			||||||
      state.wss = tunnelUrl;
 | 
					 | 
				
			||||||
      next();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  , requested: function (authReq, next) {
 | 
					 | 
				
			||||||
      console.log("Pairing Requested");
 | 
					 | 
				
			||||||
      var pin = authReq.pin || authReq.otp || authReq.pairCode;
 | 
					 | 
				
			||||||
      state.otp = state._otp = pin;
 | 
					 | 
				
			||||||
      state.auth = state.authRequest = state._auth = authReq;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      console.info();
 | 
					 | 
				
			||||||
      console.info('====================================');
 | 
					 | 
				
			||||||
      console.info('=           HEY! LISTEN!           =');
 | 
					 | 
				
			||||||
      console.info('====================================');
 | 
					 | 
				
			||||||
      console.info('=                                  =');
 | 
					 | 
				
			||||||
      console.info('= 1. CHECK YOUR EMAIL              =');
 | 
					 | 
				
			||||||
      console.info('=                                  =');
 | 
					 | 
				
			||||||
      console.info('= 2. DEVICE PAIRING CODE: 0000     ='.replace('0000', pin));
 | 
					 | 
				
			||||||
      console.info('=                                  =');
 | 
					 | 
				
			||||||
      console.info('====================================');
 | 
					 | 
				
			||||||
      console.info();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      next();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  , connect: function (pretoken, next) {
 | 
					 | 
				
			||||||
      console.log("Enabling Pairing Locally...");
 | 
					 | 
				
			||||||
      connectTunnel(pretoken, function (err, _tun) {
 | 
					 | 
				
			||||||
        console.log("Pairing Enabled Locally");
 | 
					 | 
				
			||||||
        tun = _tun;
 | 
					 | 
				
			||||||
        next();
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  , offer: function (token, next) {
 | 
					 | 
				
			||||||
      console.log("Pairing Enabled by Relay");
 | 
					 | 
				
			||||||
      state.token = token;
 | 
					 | 
				
			||||||
      state.config.token = token;
 | 
					 | 
				
			||||||
      state.handlers.access_token({ jwt: token });
 | 
					 | 
				
			||||||
      if (tun) {
 | 
					 | 
				
			||||||
        tun.append(token);
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        connectTunnel(token, function (err, _tun) {
 | 
					 | 
				
			||||||
          tun = _tun;
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      next();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  , granted: function (token, next) {
 | 
					 | 
				
			||||||
      console.log("Relay-Remote Pairing Complete");
 | 
					 | 
				
			||||||
      next();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  , end: function () {
 | 
					 | 
				
			||||||
      rawCb(null, tun);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function connectTunnel(token, cb) {
 | 
					 | 
				
			||||||
  if (tun) {
 | 
					 | 
				
			||||||
    cb(null, tun);
 | 
					 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (tun) {
 | 
				
			||||||
 | 
					    rawCb(null, tun);
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  common.api.wss(state, function (err, wss) {
 | 
				
			||||||
 | 
					    if (err) { rawCb(err); return; }
 | 
				
			||||||
 | 
					    state.wss = wss;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Saves the token
 | 
				
			||||||
 | 
					    // state.handlers.access_token({ jwt: token });
 | 
				
			||||||
 | 
					    // Adds the token to the connection
 | 
				
			||||||
 | 
					    // tun.append(token);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    state.greenlockConf = state.config.greenlock || {};
 | 
					    state.greenlockConf = state.config.greenlock || {};
 | 
				
			||||||
    state.sortingHat = state.config.sortingHat;
 | 
					    state.sortingHat = state.config.sortingHat;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -636,14 +605,15 @@ function connectTunnel(token, cb) {
 | 
				
			|||||||
    , sortingHat: state.sortingHat
 | 
					    , sortingHat: state.sortingHat
 | 
				
			||||||
    , net: state.net
 | 
					    , net: state.net
 | 
				
			||||||
    , insecure: state.insecure
 | 
					    , insecure: state.insecure
 | 
				
			||||||
  , token: token // instance
 | 
					    , token: state.token || state.pretoken // instance
 | 
				
			||||||
    , servernames: state.servernames
 | 
					    , servernames: state.servernames
 | 
				
			||||||
    , ports: state.ports
 | 
					    , ports: state.ports
 | 
				
			||||||
    , handlers: state.handlers
 | 
					    , handlers: state.handlers
 | 
				
			||||||
    , greenlockConfig: state.greenlockConfig
 | 
					    , greenlockConfig: state.greenlockConfig
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  cb(null, tun);
 | 
					    rawCb(null, tun);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
state.handlers = {
 | 
					state.handlers = {
 | 
				
			||||||
@ -709,6 +679,7 @@ function sigHandler() {
 | 
				
			|||||||
  if (controlServer) {
 | 
					  if (controlServer) {
 | 
				
			||||||
    controlServer.close();
 | 
					    controlServer.close();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  cancelUpdater();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
// reverse 2FA otp
 | 
					// reverse 2FA otp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -9,12 +9,9 @@ var os = require('os');
 | 
				
			|||||||
var homedir = os.homedir();
 | 
					var homedir = os.homedir();
 | 
				
			||||||
var urequest = require('@coolaj86/urequest');
 | 
					var urequest = require('@coolaj86/urequest');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var localshare = '.local/share/telebit';
 | 
					 | 
				
			||||||
var localconf = '.config/telebit';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
common.pipename = function (config, newApi) {
 | 
					common.pipename = function (config, newApi) {
 | 
				
			||||||
  var _ipc = {
 | 
					  var _ipc = {
 | 
				
			||||||
    path: (config.sock || common.DEFAULT_SOCK_NAME)
 | 
					    path: (config.sock || common.DEFAULT_SOCK_PATH)
 | 
				
			||||||
  , comment: (/^win/i.test(os.platform()) ? 'windows pipe' : 'unix socket')
 | 
					  , comment: (/^win/i.test(os.platform()) ? 'windows pipe' : 'unix socket')
 | 
				
			||||||
  , type: (/^win/i.test(os.platform()) ? 'pipe' : 'socket')
 | 
					  , type: (/^win/i.test(os.platform()) ? 'pipe' : 'socket')
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
@ -26,7 +23,8 @@ common.pipename = function (config, newApi) {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
  return _ipc.path;
 | 
					  return _ipc.path;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
common.DEFAULT_SOCK_NAME = path.join(homedir, localshare, 'var', 'run', 'telebit.sock');
 | 
					common.DEFAULT_SOCK_PATH = path.join(homedir, '.local/share/telebit/var/run', 'telebit.sock');
 | 
				
			||||||
 | 
					common.DEFAULT_CONFIG_PATH = path.join(homedir, '.config/telebit', 'telebitd.yml');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
common.parseUrl = function (hostname) {
 | 
					common.parseUrl = function (hostname) {
 | 
				
			||||||
  var location = url.parse(hostname);
 | 
					  var location = url.parse(hostname);
 | 
				
			||||||
@ -54,24 +52,7 @@ common.apiDirectory = '_apis/telebit.cloud/index.json';
 | 
				
			|||||||
common.otp = function getOtp() {
 | 
					common.otp = function getOtp() {
 | 
				
			||||||
  return Math.round(Math.random() * 9999).toString().padStart(4, '0');
 | 
					  return Math.round(Math.random() * 9999).toString().padStart(4, '0');
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
common.api = {};
 | 
					common.signToken = function (state) {
 | 
				
			||||||
common.api.directory = function (state, next) {
 | 
					 | 
				
			||||||
  state.relayUrl = common.parseUrl(state.relay);
 | 
					 | 
				
			||||||
  urequest({ url: state.relayUrl + common.apiDirectory, json: true }, function (err, resp, body) {
 | 
					 | 
				
			||||||
    next(err, body);
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
common.api.token = function (state, handlers) {
 | 
					 | 
				
			||||||
  common.api.directory(state, function (err, dir) {
 | 
					 | 
				
			||||||
    // directory, requested, connect, tunnelUrl, offer, granted, end
 | 
					 | 
				
			||||||
    function afterDir() {
 | 
					 | 
				
			||||||
      //console.log('[debug] after dir');
 | 
					 | 
				
			||||||
      state.relayHostname = common.parseHostname(state.relay);
 | 
					 | 
				
			||||||
      state.wss = dir.tunnel.method + '://' + dir.api_host.replace(/:hostname/g, state.relayHostname) + dir.tunnel.pathname;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      handlers.tunnelUrl(state.wss, function () {
 | 
					 | 
				
			||||||
        //console.log('[debug] after tunnelUrl');
 | 
					 | 
				
			||||||
        if (!state.config.token && state.config.secret) {
 | 
					 | 
				
			||||||
  var jwt = require('jsonwebtoken');
 | 
					  var jwt = require('jsonwebtoken');
 | 
				
			||||||
  var tokenData = {
 | 
					  var tokenData = {
 | 
				
			||||||
    domains: Object.keys(state.config.servernames || {}).filter(function (name) {
 | 
					    domains: Object.keys(state.config.servernames || {}).filter(function (name) {
 | 
				
			||||||
@ -85,7 +66,41 @@ common.api.token = function (state, handlers) {
 | 
				
			|||||||
  , iss: Math.round(Date.now() / 1000)
 | 
					  , iss: Math.round(Date.now() / 1000)
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          state.token = jwt.sign(tokenData, state.config.secret);
 | 
					  return jwt.sign(tokenData, state.config.secret);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					common.api = {};
 | 
				
			||||||
 | 
					common.api.directory = function (state, next) {
 | 
				
			||||||
 | 
					  state.relayUrl = common.parseUrl(state.relay);
 | 
				
			||||||
 | 
					  urequest({ url: state.relayUrl + common.apiDirectory, json: true }, function (err, resp, dir) {
 | 
				
			||||||
 | 
					    if (!dir) { dir = { api_host: ':hostname', tunnel: { method: "wss", pathname: "" } }; }
 | 
				
			||||||
 | 
					    state._apiDirectory = dir;
 | 
				
			||||||
 | 
					    next(err, dir);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					common.api._parseWss = function (state, dir) {
 | 
				
			||||||
 | 
					  if (!dir || !dir.api_host) {
 | 
				
			||||||
 | 
					    dir = { api_host: ':hostname', tunnel: { method: "wss", pathname: "" } };
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  state.relayHostname = common.parseHostname(state.relay);
 | 
				
			||||||
 | 
					  state.wss = dir.tunnel.method + '://' + dir.api_host.replace(/:hostname/g, state.relayHostname) + dir.tunnel.pathname;
 | 
				
			||||||
 | 
					  return state.wss;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					common.api.wss = function (state, cb) {
 | 
				
			||||||
 | 
					  common.api.directory(state, function (err, dir) {
 | 
				
			||||||
 | 
					    cb(err, common.api._parseWss(state, dir));
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					common.api.token = function (state, handlers) {
 | 
				
			||||||
 | 
					  common.api.directory(state, function (err, dir) {
 | 
				
			||||||
 | 
					    // directory, requested, connect, tunnelUrl, offer, granted, end
 | 
				
			||||||
 | 
					    function afterDir() {
 | 
				
			||||||
 | 
					      //console.log('[debug] after dir');
 | 
				
			||||||
 | 
					      state.wss = common.api._parseWss(state, dir);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      handlers.tunnelUrl(state.wss, function () {
 | 
				
			||||||
 | 
					        //console.log('[debug] after tunnelUrl');
 | 
				
			||||||
 | 
					        if (/*!state.config.token &&*/ state.config.secret) {
 | 
				
			||||||
 | 
					          state.token = common.signToken(state);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        state.token = state.token || state.config.token;
 | 
					        state.token = state.token || state.config.token;
 | 
				
			||||||
        if (state.token) {
 | 
					        if (state.token) {
 | 
				
			||||||
 | 
				
			|||||||
@ -128,8 +128,13 @@ module.exports = function (pkg) {
 | 
				
			|||||||
      });
 | 
					      });
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  setInterval(checkUpgrade, 2 * 60 * 60 * 1000);
 | 
					
 | 
				
			||||||
 | 
					  var _interval = setInterval(checkUpgrade, 2 * 60 * 60 * 1000);
 | 
				
			||||||
  process.nextTick(function () {
 | 
					  process.nextTick(function () {
 | 
				
			||||||
    checkUpgrade();
 | 
					    checkUpgrade();
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return function cancel() {
 | 
				
			||||||
 | 
					    clearInterval(_interval);
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user