getting closer to accounts via api
This commit is contained in:
parent
58ed4baff1
commit
e4640a8a00
104
bin/telebitd.js
104
bin/telebitd.js
|
@ -7,6 +7,8 @@ var pkg = require('../package.json');
|
|||
var url = require('url');
|
||||
var path = require('path');
|
||||
var os = require('os');
|
||||
var fs = require('fs');
|
||||
var urequest = require('@coolaj86/urequest');
|
||||
var common = require('../lib/cli-common.js');
|
||||
var http = require('http');
|
||||
var YAML = require('js-yaml');
|
||||
|
@ -397,7 +399,6 @@ function serveControlsHelper() {
|
|||
|
||||
res.end('{"error":{"message":"unrecognized rpc"}}');
|
||||
});
|
||||
var fs = require('fs');
|
||||
if (fs.existsSync(state._ipc.path)) {
|
||||
fs.unlinkSync(state._ipc.path);
|
||||
}
|
||||
|
@ -494,15 +495,7 @@ function connectTunnel() {
|
|||
controlServer.close();
|
||||
}
|
||||
// reverse 2FA otp
|
||||
function leftpad(i, n, c) {
|
||||
while (i.toString().length < (n || 4)) {
|
||||
i = (c || '0') + i;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
function getOtp() {
|
||||
return leftpad(Math.round(Math.random() * 9999), 4, '0');
|
||||
}
|
||||
|
||||
process.on('SIGINT', sigHandler);
|
||||
state.net = state.net || {
|
||||
createConnection: function (info, cb) {
|
||||
|
@ -515,7 +508,6 @@ function connectTunnel() {
|
|||
}
|
||||
};
|
||||
|
||||
state.otp = getOtp();
|
||||
state.greenlockConf = state.config.greenlock || {};
|
||||
state.sortingHat = state.config.sortingHat || path.resolve(__dirname, '..', 'lib/sorting-hat.js');
|
||||
|
||||
|
@ -653,39 +645,79 @@ function rawTunnel(cb) {
|
|||
state.relayUrl = common.parseUrl(state.relay);
|
||||
state.relayHostname = common.parseHostname(state.relay);
|
||||
|
||||
if (!state.config.token && state.config.secret) {
|
||||
var jwt = require('jsonwebtoken');
|
||||
var tokenData = {
|
||||
domains: Object.keys(state.config.servernames || {}).filter(function (name) {
|
||||
return /\./.test(name);
|
||||
})
|
||||
, ports: Object.keys(state.config.ports || {}).filter(function (port) {
|
||||
port = parseInt(port, 10);
|
||||
return port > 0 && port <= 65535;
|
||||
})
|
||||
, aud: aud
|
||||
, iss: Math.round(Date.now() / 1000)
|
||||
urequest({ url: state.relayUrl + common.apiDirectory, json: true }, function (err, resp, body) {
|
||||
state._apiDirectory = body;
|
||||
state.wss = body.tunnel.method + '://' + body.api_host.replace(/:hostname/g, state.relayHostname) + body.tunnel.pathname;
|
||||
|
||||
console.log('api dir:');
|
||||
console.log(body);
|
||||
|
||||
console.log('state.wss:');
|
||||
console.log(state.wss);
|
||||
|
||||
if (!state.config.token && state.config.secret) {
|
||||
var jwt = require('jsonwebtoken');
|
||||
var tokenData = {
|
||||
domains: Object.keys(state.config.servernames || {}).filter(function (name) {
|
||||
return /\./.test(name);
|
||||
})
|
||||
, ports: Object.keys(state.config.ports || {}).filter(function (port) {
|
||||
port = parseInt(port, 10);
|
||||
return port > 0 && port <= 65535;
|
||||
})
|
||||
, aud: state.relayUrl
|
||||
, iss: Math.round(Date.now() / 1000)
|
||||
};
|
||||
|
||||
state.token = jwt.sign(tokenData, state.config.secret);
|
||||
}
|
||||
state.token = state.token || state.config.token;
|
||||
if (state.token) { cb(null, connectTunnel()); return; }
|
||||
|
||||
if (!state.config.email) {
|
||||
cb(new Error("No email... how did that happen?"));
|
||||
return;
|
||||
}
|
||||
// TODO sign token with own private key, including public key and thumbprint
|
||||
// (much like ACME JOSE account)
|
||||
|
||||
state.otp = common.otp();
|
||||
state._auth = {
|
||||
subject: state.config.email
|
||||
, subject_scheme: 'mailto'
|
||||
// TODO create domains list earlier
|
||||
, scope: Object.keys(state.config.servernames || {}).join(',')
|
||||
, otp: state.otp
|
||||
, hostname: os.hostname()
|
||||
// Used for User-Agent
|
||||
, os_type: os.type()
|
||||
, os_platform: os.platform()
|
||||
, os_release: os.release()
|
||||
, os_arch: os.arch()
|
||||
};
|
||||
|
||||
state.token = jwt.sign(tokenData, state.config.secret);
|
||||
}
|
||||
state.token = state.token || state.config.token;
|
||||
|
||||
common.urequest({ url: state.relayUrl + common.apiDirectory, json: true }, function (err, resp, body) {
|
||||
state._apiDirectory = body;
|
||||
state.wss = body.tunnel.method + '://' + body.api_host.replace(/:hostname/g, state.relayHostname) + body.tunnel.pathname
|
||||
|
||||
if (token) {
|
||||
if (err || !body || !body.pair_request) {
|
||||
cb(null, connectTunnel());
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO sign token with own private key, including public key and thumbprint
|
||||
// (much like ACME JOSE account)
|
||||
|
||||
// TODO do auth stuff
|
||||
var pairRequest = url.resolve('https://' + body.api_host.replace(/:hostname/g, state.relayHostname), body.pair_request.pathname);
|
||||
var req = {
|
||||
url: pairRequest
|
||||
, method: body.pair_request.method
|
||||
, json: state._auth
|
||||
};
|
||||
console.log('[telebitd.js] req');
|
||||
console.log(req);
|
||||
urequest(req, function (err, resp, body) {
|
||||
if (err) { console.error('[telebitd.js] pair request', err); }
|
||||
|
||||
cb(null, connectTunnel());
|
||||
console.log(body);
|
||||
// TODO poll for token
|
||||
//cb(null, connectTunnel());
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -37,8 +37,30 @@ common.parseUrl = function (hostname) {
|
|||
hostname = location.protocol.replace(/https?/, 'https') + '//' + hostname + location.pathname;
|
||||
return hostname;
|
||||
};
|
||||
common.parseHostname = function (hostname) {
|
||||
var url = require('url');
|
||||
var location = url.parse(hostname);
|
||||
if (!location.protocol || /\./.test(location.protocol)) {
|
||||
hostname = 'https://' + hostname;
|
||||
location = url.parse(hostname);
|
||||
}
|
||||
//hostname = location.hostname + (location.port ? ':' + location.port : '');
|
||||
//hostname = location.protocol.replace(/https?/, 'https') + '//' + hostname + location.pathname;
|
||||
return location.hostname;
|
||||
};
|
||||
|
||||
common.apiDirectory = '_apis/telebit.cloud/index.json';
|
||||
|
||||
function leftpad(i, n, c) {
|
||||
while (i.toString().length < (n || 4)) {
|
||||
i = (c || '0') + i;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
common.otp = function getOtp() {
|
||||
return leftpad(Math.round(Math.random() * 9999), 4, '0');
|
||||
};
|
||||
|
||||
common.urequest = function (opts, cb) {
|
||||
var https = require('https');
|
||||
// request.js behavior:
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
'use strict';
|
||||
|
||||
var email = 'jon@example.com';
|
||||
|
||||
var urequest = require('@coolaj86/urequest');
|
||||
var req = {
|
||||
url: 'https://api.telebit.ppl.family/api/telebit.cloud/pair_request'
|
||||
, method: 'POST'
|
||||
, headers: { 'cOntEnt-tYpE': 'application/json;charset=utf-8' }
|
||||
, json: {
|
||||
subject: email
|
||||
, subject_scheme: 'mailto'
|
||||
, scope: ''
|
||||
, otp: '321654'
|
||||
, hostname: "Jon's Macbook Pro"
|
||||
, os_type: 'Linux'
|
||||
, os_platform: 'linux'
|
||||
, os_release: '4.4.0-116-generic'
|
||||
, os_arch: 'x64'
|
||||
}
|
||||
};
|
||||
urequest(req, function (err, resp, body) {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
return;
|
||||
}
|
||||
console.log('Location:', resp.headers.location);
|
||||
console.log('Body:');
|
||||
console.log(body);
|
||||
});
|
|
@ -0,0 +1,18 @@
|
|||
'use strict';
|
||||
|
||||
var stateUrl = 'https://api.telebit.ppl.family/api/telebit.cloud/pair_state/bca27428719e9c67805359f1';
|
||||
|
||||
var urequest = require('@coolaj86/urequest');
|
||||
var req = {
|
||||
url: stateUrl
|
||||
, method: 'GET'
|
||||
, json: true
|
||||
};
|
||||
urequest(req, function (err, resp, body) {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
return;
|
||||
}
|
||||
console.log('Done:');
|
||||
console.log(body);
|
||||
});
|
Loading…
Reference in New Issue