working: manage token with client
This commit is contained in:
parent
fce8e366c6
commit
5584638907
|
@ -1,5 +1,6 @@
|
||||||
node_modules.*
|
node_modules.*
|
||||||
*.*.sw*
|
*.*.sw*
|
||||||
|
etc/acme/
|
||||||
bin/node
|
bin/node
|
||||||
bin/npm
|
bin/npm
|
||||||
bin/npx
|
bin/npx
|
||||||
|
|
|
@ -264,7 +264,8 @@ function askForConfig(state, mainCb) {
|
||||||
var jwt = require('jsonwebtoken');
|
var jwt = require('jsonwebtoken');
|
||||||
resp = (resp || '').trim();
|
resp = (resp || '').trim();
|
||||||
try {
|
try {
|
||||||
state.config.token = jwt.decode(resp);
|
jwt.decode(resp);
|
||||||
|
state.config.token = resp;
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
// is not jwt
|
// is not jwt
|
||||||
}
|
}
|
||||||
|
@ -474,6 +475,13 @@ function makeRpc(key) {
|
||||||
function packConfig(config) {
|
function packConfig(config) {
|
||||||
return Object.keys(config).map(function (key) {
|
return Object.keys(config).map(function (key) {
|
||||||
var val = config[key];
|
var val = config[key];
|
||||||
|
if ('undefined' === val) {
|
||||||
|
throw new Error("'undefined' used as a string value");
|
||||||
|
}
|
||||||
|
if ('undefined' === typeof val) {
|
||||||
|
//console.warn('[DEBUG]', key, 'is present but undefined');
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (val && 'object' === typeof val && !Array.isArray(val)) {
|
if (val && 'object' === typeof val && !Array.isArray(val)) {
|
||||||
val = JSON.stringify(val);
|
val = JSON.stringify(val);
|
||||||
}
|
}
|
||||||
|
@ -495,19 +503,18 @@ function getToken(err, state) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
, directory: function (dir, next) {
|
, directory: function (dir, next) {
|
||||||
//console.log('Telebit Relay Discovered:');
|
//console.log('[directory] Telebit Relay Discovered:');
|
||||||
state._apiDirectory = dir;
|
|
||||||
//console.log(dir);
|
//console.log(dir);
|
||||||
//console.log();
|
state._apiDirectory = dir;
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
, tunnelUrl: function (tunnelUrl, next) {
|
, tunnelUrl: function (tunnelUrl, next) {
|
||||||
//console.log('Telebit Relay Tunnel Socket:', tunnelUrl);
|
//console.log('[tunnelUrl] Telebit Relay Tunnel Socket:', tunnelUrl);
|
||||||
state.wss = tunnelUrl;
|
state.wss = tunnelUrl;
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
, requested: function (authReq, next) {
|
, requested: function (authReq, next) {
|
||||||
//console.log("Pairing Requested");
|
//console.log("[requested] Pairing Requested");
|
||||||
state.config._otp = state.config._otp = authReq.otp;
|
state.config._otp = state.config._otp = authReq.otp;
|
||||||
|
|
||||||
if (!state.config.token && state._can_pair) {
|
if (!state.config.token && state._can_pair) {
|
||||||
|
@ -527,12 +534,11 @@ function getToken(err, state) {
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
, connect: function (pretoken, next) {
|
, connect: function (pretoken, next) {
|
||||||
//console.log("Enabling Pairing Locally...");
|
//console.log("[connect] Enabling Pairing Locally...");
|
||||||
state.config.pretoken = pretoken;
|
state.config.pretoken = pretoken;
|
||||||
state._connecting = true;
|
state._connecting = true;
|
||||||
|
|
||||||
// TODO use php-style object querification
|
// TODO use php-style object querification
|
||||||
// TODO XXX
|
|
||||||
utils.putConfig('config', packConfig(state.config), function (err/*, body*/) {
|
utils.putConfig('config', packConfig(state.config), function (err/*, body*/) {
|
||||||
if (err) {
|
if (err) {
|
||||||
state._error = err;
|
state._error = err;
|
||||||
|
@ -545,15 +551,19 @@ function getToken(err, state) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
, offer: function (token, next) {
|
, offer: function (token, next) {
|
||||||
//console.log("Pairing Enabled by Relay");
|
//console.log("[offer] Pairing Enabled by Relay");
|
||||||
state.config.token = token;
|
state.config.token = token;
|
||||||
if (state._error) {
|
if (state._error) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (state._connecting) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
state._connecting = true;
|
state._connecting = true;
|
||||||
|
console.log("Token Offered:");
|
||||||
|
console.log(token);
|
||||||
|
try {
|
||||||
|
console.log(require('jsonwebtoken').decode(token));
|
||||||
|
} catch(e) {
|
||||||
|
console.warn("[warning] could not decode token");
|
||||||
|
}
|
||||||
utils.putConfig('config', packConfig(state.config), function (err/*, body*/) {
|
utils.putConfig('config', packConfig(state.config), function (err/*, body*/) {
|
||||||
if (err) {
|
if (err) {
|
||||||
state._error = err;
|
state._error = err;
|
||||||
|
@ -566,13 +576,13 @@ function getToken(err, state) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
, granted: function (_, next) {
|
, granted: function (_, next) {
|
||||||
//console.log("Pairing complete!");
|
//console.log("[grant] Pairing complete!");
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
, end: function () {
|
, end: function () {
|
||||||
utils.putConfig('enable', [], function (err) {
|
utils.putConfig('enable', [], function (err) {
|
||||||
if (err) { console.error(err); return; }
|
if (err) { console.error(err); return; }
|
||||||
//console.info("Success");
|
console.info("[end] Success");
|
||||||
|
|
||||||
// workaround for https://github.com/nodejs/node/issues/21319
|
// workaround for https://github.com/nodejs/node/issues/21319
|
||||||
if (state._useTty) {
|
if (state._useTty) {
|
||||||
|
@ -644,7 +654,7 @@ function handleConfig(err, config) {
|
||||||
state.config.relay = 'telebit.cloud';
|
state.config.relay = 'telebit.cloud';
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("question the user?", Date.now());
|
//console.log("question the user?", Date.now());
|
||||||
askForConfig(state, function (err, state) {
|
askForConfig(state, function (err, state) {
|
||||||
// no errors actually get passed, so this is just future-proofing
|
// no errors actually get passed, so this is just future-proofing
|
||||||
if (err) { throw err; }
|
if (err) { throw err; }
|
||||||
|
@ -653,7 +663,7 @@ function handleConfig(err, config) {
|
||||||
state.config._otp = common.otp();
|
state.config._otp = common.otp();
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("done questioning:", Date.now());
|
//console.log("done questioning:", Date.now());
|
||||||
state.relay = state.config.relay;
|
state.relay = state.config.relay;
|
||||||
if (!state.token && !state.config.token) {
|
if (!state.token && !state.config.token) {
|
||||||
getToken(err, state);
|
getToken(err, state);
|
||||||
|
@ -664,7 +674,7 @@ function handleConfig(err, config) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("no questioning:");
|
//console.log("no questioning:");
|
||||||
parseCli(state);
|
parseCli(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,7 @@ var tokenpath = path.join(path.dirname(confpath), 'access_token.txt');
|
||||||
var token;
|
var token;
|
||||||
try {
|
try {
|
||||||
token = fs.readFileSync(tokenpath, 'ascii').trim();
|
token = fs.readFileSync(tokenpath, 'ascii').trim();
|
||||||
|
console.log('[DEBUG] access_token', typeof token, token);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
|
@ -129,6 +130,8 @@ function serveControlsHelper() {
|
||||||
// without proper config
|
// without proper config
|
||||||
//
|
//
|
||||||
function saveAndReport(err, _tun) {
|
function saveAndReport(err, _tun) {
|
||||||
|
console.log('[DEBUG] saveAndReport config write', confpath);
|
||||||
|
console.log(YAML.safeDump(snakeCopy(state.config)));
|
||||||
if (err) { throw err; }
|
if (err) { throw err; }
|
||||||
tun = _tun;
|
tun = _tun;
|
||||||
fs.writeFile(confpath, YAML.safeDump(snakeCopy(state.config)), function (err) {
|
fs.writeFile(confpath, YAML.safeDump(snakeCopy(state.config)), function (err) {
|
||||||
|
@ -174,15 +177,27 @@ function serveControlsHelper() {
|
||||||
}
|
}
|
||||||
state.otp = conf._otp || '0000'; // this should only be done on the client side
|
state.otp = conf._otp || '0000'; // this should only be done on the client side
|
||||||
state.config.relay = conf.relay || state.config.relay || '';
|
state.config.relay = conf.relay || state.config.relay || '';
|
||||||
|
console.log();
|
||||||
|
console.log('conf.token', typeof conf.token, conf.token);
|
||||||
|
console.log('state.config.token', typeof state.config.token, state.config.token);
|
||||||
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;
|
state.pretoken = conf.pretoken || state.config.pretoken || null;
|
||||||
if (state.secret) {
|
if (state.secret) {
|
||||||
|
console.log('state.secret');
|
||||||
state.token = common.signToken(state);
|
state.token = common.signToken(state);
|
||||||
}
|
}
|
||||||
if (!state.token) {
|
if (!state.token) {
|
||||||
|
console.log('!state.token');
|
||||||
state.token = conf._token;
|
state.token = conf._token;
|
||||||
}
|
}
|
||||||
|
console.log();
|
||||||
|
console.log('JSON.stringify(conf)');
|
||||||
|
console.log(JSON.stringify(conf));
|
||||||
|
console.log();
|
||||||
|
console.log('JSON.stringify(state)');
|
||||||
|
console.log(JSON.stringify(state));
|
||||||
|
console.log();
|
||||||
if ('undefined' !== typeof conf.newsletter) {
|
if ('undefined' !== typeof conf.newsletter) {
|
||||||
state.config.newsletter = conf.newsletter;
|
state.config.newsletter = conf.newsletter;
|
||||||
}
|
}
|
||||||
|
@ -209,6 +224,7 @@ function serveControlsHelper() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!state.config.relay || !state.config.email || !state.config.agreeTos) {
|
if (!state.config.relay || !state.config.email || !state.config.agreeTos) {
|
||||||
|
console.log('aborting for some reason');
|
||||||
res.statusCode = 400;
|
res.statusCode = 400;
|
||||||
|
|
||||||
res.setHeader('Content-Type', 'application/json');
|
res.setHeader('Content-Type', 'application/json');
|
||||||
|
@ -225,16 +241,20 @@ function serveControlsHelper() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tun) {
|
if (tun) {
|
||||||
|
console.log('ending existing tunnel, starting anew');
|
||||||
tun.end(function () {
|
tun.end(function () {
|
||||||
|
console.log('success ending');
|
||||||
rawTunnel(saveAndReport);
|
rawTunnel(saveAndReport);
|
||||||
});
|
});
|
||||||
tun = null;
|
tun = null;
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
if (!tun) {
|
if (!tun) {
|
||||||
|
console.log('failed to end, but starting anyway');
|
||||||
rawTunnel(saveAndReport);
|
rawTunnel(saveAndReport);
|
||||||
}
|
}
|
||||||
}, 3000);
|
}, 3000);
|
||||||
} else {
|
} else {
|
||||||
|
console.log('no tunnel, starting anew');
|
||||||
rawTunnel(saveAndReport);
|
rawTunnel(saveAndReport);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -602,6 +622,7 @@ function rawTunnel(rawCb) {
|
||||||
state.insecure = state.config.relay_ignore_invalid_certificates;
|
state.insecure = state.config.relay_ignore_invalid_certificates;
|
||||||
// { relay, config, servernames, ports, sortingHat, net, insecure, token, handlers, greenlockConfig }
|
// { relay, config, servernames, ports, sortingHat, net, insecure, token, handlers, greenlockConfig }
|
||||||
|
|
||||||
|
console.log("[DEBUG] token", typeof token, token);
|
||||||
tun = remote.connect({
|
tun = remote.connect({
|
||||||
relay: state.relay
|
relay: state.relay
|
||||||
, wss: state.wss
|
, wss: state.wss
|
||||||
|
@ -659,8 +680,13 @@ state.handlers = {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
, access_token: function (opts) {
|
, access_token: function (opts) {
|
||||||
state.token = opts.jwt;
|
if ('undefined' === opts.jwt || !opts.jwt) {
|
||||||
state.config.token = opts.jwt;
|
console.error("Granted empty access token... ??");
|
||||||
|
console.error(JSON.stringify(opts));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
state.token = opts.jwt || opts.access_token;
|
||||||
|
state.config.token = opts.jwt || opts.access_token;
|
||||||
console.info("Updating '" + tokenpath + "' with new token:");
|
console.info("Updating '" + tokenpath + "' with new token:");
|
||||||
try {
|
try {
|
||||||
require('fs').writeFileSync(tokenpath, opts.jwt);
|
require('fs').writeFileSync(tokenpath, opts.jwt);
|
||||||
|
|
|
@ -32,6 +32,9 @@ function _connect(state) {
|
||||||
state.sortingHat = "./sorting-hat.js";
|
state.sortingHat = "./sorting-hat.js";
|
||||||
}
|
}
|
||||||
if (state.token) {
|
if (state.token) {
|
||||||
|
if ('undefined' === state.token) {
|
||||||
|
throw new Error("passed string 'undefined' as token");
|
||||||
|
}
|
||||||
tokens.push(state.token);
|
tokens.push(state.token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -569,6 +572,12 @@ function _connect(state) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
, append: function (token) {
|
, append: function (token) {
|
||||||
|
if (!token) {
|
||||||
|
throw new Error("attempted to append empty token");
|
||||||
|
}
|
||||||
|
if ('undefined' === token) {
|
||||||
|
throw new Error("attempted to append token as the string 'undefined'");
|
||||||
|
}
|
||||||
if (tokens.indexOf(token) >= 0) {
|
if (tokens.indexOf(token) >= 0) {
|
||||||
return PromiseA.resolve();
|
return PromiseA.resolve();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue