MAJOR: Updates for Authenticated Web UI and CLI #30

Open
coolaj86 wants to merge 77 commits from next into master
3 changed files with 110 additions and 25 deletions
Showing only changes of commit ce20b058e6 - Show all commits

View File

@ -27,6 +27,7 @@ var snakeCopy = recase.snakeCopy.bind(recase);
var TPLS = TOML.parse(fs.readFileSync(path.join(__dirname, "../lib/en-us.toml"), 'utf8'));
var startTime = Date.now();
var connectTimes = [];
var isConnected = false;
var TelebitRemote = require('../lib/daemon/index.js').TelebitRemote;
@ -628,17 +629,17 @@ function handleApi(req, res) {
res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify(
{ module: 'status'
, port: (state.config.ipc && state.config.ipc.port || state._ipc.port || undefined)
, status: (state.config.disable ? 'disabled' : 'enabled')
, ready: ((state.config.relay && (state.config.token || state.config.agreeTos)) ? true : false)
, active: !!myRemote
, connected: 'maybe (todo)'
, version: pkg.version
, servernames: state.servernames
, port: (state.config.ipc && state.config.ipc.port || state._ipc.port || undefined)
, enabled: !state.config.disable
, active: !!myRemote
, initialized: (state.config.relay && state.config.token && state.config.agreeTos) ? true : false
, connected: isConnected
, proctime: Math.round(process.uptime() * 1000)
, uptime: now - startTime
, runtime: connectTimes.length && (now - connectTimes[0]) || 0
, runtime: isConnected && connectTimes.length && (now - connectTimes[0]) || 0
, reconnects: connectTimes.length
, servernames: state.servernames
}
));
}
@ -707,7 +708,8 @@ function handleApi(req, res) {
res.end(JSON.stringify({"error":{"message":"unrecognized rpc"}}));
}
if (!req.headers['content-length'] && !req.headers['content-type']) {
var hasLength = req.headers['content-length'] > 0;
if (!hasLength && !req.headers['content-type']) {
route();
return;
}
@ -1042,6 +1044,7 @@ function rawStartTelebitRemote(keepAlive) {
}
function onConnect() {
isConnected = true;
connectTimes.unshift(Date.now());
console.info('[connect] relay established');
myRemote.removeListener('error', onConnectError);
@ -1060,6 +1063,7 @@ function rawStartTelebitRemote(keepAlive) {
function onConnectError(err) {
myRemote = null;
isConnected = false;
if (handleError(err, 'onConnectError')) {
if (!keepAlive.state) {
reject(err);
@ -1075,6 +1079,7 @@ function rawStartTelebitRemote(keepAlive) {
}
function retryLoop() {
isConnected = false;
console.warn('[Warn] disconnected. Will retry?', keepAlive.state);
if (keepAlive.state) {
safeReload(10 * 1000).then(resolve).catch(reject);

View File

@ -7,7 +7,7 @@
<script>document.body.hidden = true;</script>
<div class="v-app">
<h1>Telebit (Remote) Setup</h1>
<h1>Telebit (Remote) Setup v{{ config.version }}</h1>
<section v-if="views.flash.error">
{{ views.flash.error }}
@ -115,6 +115,19 @@
</section>
<section v-if="views.section.status">
<button v-if="!status.enabled" v-on:click="enable">Enable</button>
<button v-if="status.enabled" v-on:click="disable">Disable</button>
<br>
http://localhost:{{ status.port }}
<br>
Proctime: {{ statusProctime }}
<br>
Uptime: {{ statusUptime }}
<br>
Runtime: {{ statusRuntime }}
<br>
Reconnects: {{ status.reconnects }}
<br>
<pre><code>{{ status }}</code></pre>
</section>

View File

@ -37,14 +37,26 @@ api.status = function apiStatus() {
return json;
});
};
api.initialize = function apiInitialize() {
api.enable = function apiEnable() {
var opts = {
url: "/api/xxinitxx"
url: "/api/enable"
, method: "POST"
, headers: {
'Content-Type': 'application/json'
}
, body: JSON.stringify(telebitState.config)
//, headers: { 'Content-Type': 'application/json' }
};
return Telebit.reqLocalAsync(opts).then(function (resp) {
var json = resp.body;
appData.initResult = json;
window.alert("Error: [success] " + JSON.stringify(json, null, 2));
return json;
}).catch(function (err) {
window.alert("Error: [init] " + (err.message || JSON.stringify(err, null, 2)));
});
};
api.disable = function apiDisable() {
var opts = {
url: "/api/disable"
, method: "POST"
//, headers: { 'Content-Type': 'application/json' }
};
return Telebit.reqLocalAsync(opts).then(function (resp) {
var json = resp.body;
@ -107,8 +119,8 @@ var TELEBIT_RELAYS = [
var PRODUCTION_ACME = 'https://acme-v02.api.letsencrypt.org/directory';
var STAGING_ACME = 'https://acme-staging-v02.api.letsencrypt.org/directory';
var appData = {
config: null
, status: null
config: {}
, status: {}
, init: {
teletos: true
, letos: true
@ -181,11 +193,11 @@ var appMethods = {
, betaRelay: function () {
appData.init.relay = BETA_RELAY;
}
, defaultRhubarb: function () {
appData.init.rhubarb = DEFAULT_RELAY;
, enable: function () {
api.enable();
}
, betaRhubarb: function () {
appData.init.rhubarb = BETA_RELAY;
, disable: function () {
api.disable();
}
};
var appStates = {
@ -200,9 +212,15 @@ var appStates = {
}
, status: function () {
appData.views.section = { status: true };
return api.status().then(function (status) {
var tok = setInterval(function () {
api.status().then(function (status) {
appData.status = status;
});
}, 2000);
return function cancelState() {
clearInterval(tok);
};
}
};
@ -216,23 +234,72 @@ function changeState(newstate) {
}
location.hash = newhash;
}
/*globals Promise*/
window.addEventListener('hashchange', setState, false);
function setState(/*ev*/) {
//ev.oldURL
//ev.newURL
if (appData.exit) {
appData.exit.then(function (exit) {
if ('function' === typeof appData.exit) {
exit();
}
});
}
var parts = location.hash.substr(1).replace(/^\//, '').replace(/\/$/, '').split('/');
var fn = appStates;
parts.forEach(function (s) {
console.log("state:", s);
fn = fn[s];
});
fn();
appData.exit = Promise.resolve(fn());
//appMethods.states[newstate]();
}
function msToHumanReadable(ms) {
var uptime = ms;
var uptimed = uptime / 1000;
var minute = 60;
var hour = 60 * minute;
var day = 24 * hour;
var days = 0;
var times = [];
while (uptimed > day) {
uptimed -= day;
days += 1;
}
times.push(days + " days ");
var hours = 0;
while (uptimed > hour) {
uptimed -= hour;
hours += 1;
}
times.push(hours.toString().padStart(2, "0") + " h ");
var minutes = 0;
while (uptimed > minute) {
uptimed -= minute;
minutes += 1;
}
times.push(minutes.toString().padStart(2, "0") + " m ");
var seconds = Math.round(uptimed);
times.push(seconds.toString().padStart(2, "0") + " s ");
return times.join('');
}
new Vue({
el: ".v-app"
, data: appData
, computed: {
statusProctime: function () {
return msToHumanReadable(this.status.proctime);
}
, statusRuntime: function () {
return msToHumanReadable(this.status.runtime);
}
, statusUptime: function () {
return msToHumanReadable(this.status.uptime);
}
}
, methods: appMethods
});