cleanup
This commit is contained in:
parent
ae452367c0
commit
a5c448902e
107
bin/telebitd.js
107
bin/telebitd.js
|
@ -31,6 +31,8 @@ var connectTimes = [];
|
|||
var isConnected = false;
|
||||
var eggspress = require('../lib/eggspress.js');
|
||||
var keypairs = require('keypairs');
|
||||
var KEYEXT = '.key.jwk.json';
|
||||
var PUBEXT = '.pub.jwk.json';
|
||||
|
||||
var TelebitRemote = require('../lib/daemon/index.js').TelebitRemote;
|
||||
|
||||
|
@ -140,8 +142,7 @@ controllers.http = function (req, res) {
|
|||
|
||||
if (!req.body) {
|
||||
res.statusCode = 422;
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
res.end(JSON.stringify({"error":{"message":"module \'http\' needs some arguments"}}));
|
||||
res.send({"error":{"message":"module \'http\' needs some arguments"}});
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -153,8 +154,7 @@ controllers.http = function (req, res) {
|
|||
|
||||
if (!portOrPath) {
|
||||
res.statusCode = 422;
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
res.end(JSON.stringify({ error: { message: "module 'http' needs port or path" } }));
|
||||
res.send({ error: { message: "module 'http' needs port or path" } });
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -249,22 +249,20 @@ controllers.http = function (req, res) {
|
|||
}
|
||||
state.config.servernames = state.servernames;
|
||||
saveConfig(function (err) {
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
res.end(JSON.stringify({
|
||||
res.send({
|
||||
success: true
|
||||
, active: active
|
||||
, remote: remoteHost
|
||||
, local: portOrPath
|
||||
, saved: !err
|
||||
, module: 'http'
|
||||
}));
|
||||
});
|
||||
});
|
||||
};
|
||||
controllers.tcp = function (req, res) {
|
||||
if (!req.body) {
|
||||
res.statusCode = 422;
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
res.end(JSON.stringify({ error: { message: "module 'tcp' needs more arguments" } }));
|
||||
res.send({ error: { message: "module 'tcp' needs more arguments" } });
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -298,22 +296,20 @@ controllers.tcp = function (req, res) {
|
|||
}
|
||||
state.config.ports = state.ports;
|
||||
saveConfig(function (err) {
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
res.end(JSON.stringify({
|
||||
res.send({
|
||||
success: true
|
||||
, active: active
|
||||
, remote: remotePort
|
||||
, local: portOrPath
|
||||
, saved: !err
|
||||
, module: 'tcp'
|
||||
}));
|
||||
});
|
||||
});
|
||||
};
|
||||
controllers.ssh = function (req, res) {
|
||||
if (!req.body) {
|
||||
res.statusCode = 422;
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
res.end(JSON.stringify({"error":{"message":"module 'ssh' needs more arguments"}}));
|
||||
res.send({"error":{"message":"module 'ssh' needs more arguments"}});
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -324,15 +320,14 @@ controllers.ssh = function (req, res) {
|
|||
if (false !== local && !local) {
|
||||
local = 22;
|
||||
}
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
res.end(JSON.stringify({
|
||||
res.send({
|
||||
success: true
|
||||
, active: true
|
||||
, remote: Object.keys(state.config.ports)[0]
|
||||
, local: local
|
||||
, saved: !err
|
||||
, module: 'ssh'
|
||||
}));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -351,8 +346,7 @@ controllers.ssh = function (req, res) {
|
|||
sshAuto = parseInt(sshAuto, 10);
|
||||
if (!sshAuto || sshAuto <= 0 || sshAuto > 65535) {
|
||||
res.statusCode = 400;
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
res.end(JSON.stringify({ error: { message: "bad ssh_auto option '" + rawSshAuto + "'" } }));
|
||||
res.send({ error: { message: "bad ssh_auto option '" + rawSshAuto + "'" } });
|
||||
return;
|
||||
}
|
||||
state.config.sshAuto = sshAuto;
|
||||
|
@ -361,15 +355,13 @@ controllers.ssh = function (req, res) {
|
|||
controllers.relay = function (req, res) {
|
||||
if (!req.body) {
|
||||
res.statusCode = 422;
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
res.end(JSON.stringify({"error":{"message":"module \'relay\' needs more arguments"}}));
|
||||
res.send({"error":{"message":"module \'relay\' needs more arguments"}});
|
||||
return;
|
||||
}
|
||||
|
||||
return urequestAsync(req.body).then(function (resp) {
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
resp = resp.toJSON();
|
||||
res.end(JSON.stringify(resp));
|
||||
res.send(resp);
|
||||
});
|
||||
};
|
||||
controllers._nonces = {};
|
||||
|
@ -378,7 +370,7 @@ controllers._requireNonce = function (req, res, next) {
|
|||
var active = (Date.now() - controllers._nonces[nonce]) < (4 * 60 * 60 * 1000);
|
||||
if (!active) {
|
||||
// TODO proper headers and error message
|
||||
res.end({ "error": "invalid or expired nonce", "error_code": "ENONCE" });
|
||||
res.send({ "error": "invalid or expired nonce", "error_code": "ENONCE" });
|
||||
return;
|
||||
}
|
||||
delete controllers._nonces[nonce];
|
||||
|
@ -451,7 +443,7 @@ function jsonEggspress(req, res, next) {
|
|||
req.body = JSON.parse(body);
|
||||
} catch(e) {
|
||||
res.statusCode = 400;
|
||||
res.end('{"error":{"message":"POST body is not valid json"}}');
|
||||
res.send({"error":{"message":"POST body is not valid json"}});
|
||||
return;
|
||||
}
|
||||
next();
|
||||
|
@ -508,12 +500,12 @@ function jwsEggspress(req, res, next) {
|
|||
}
|
||||
|
||||
var vjwk;
|
||||
jwks.some(function (jwk) {
|
||||
DB.pubs.some(function (jwk) {
|
||||
if (jwk.kid === req.jws.header.kid) {
|
||||
vjwk = jwk;
|
||||
}
|
||||
});
|
||||
if ((0 === jwks.length && req.jws.header.jwk)) {
|
||||
if ((0 === DB.pubs.length && req.jws.header.jwk)) {
|
||||
vjwk = req.jws.header.jwk;
|
||||
if (!vjwk.kid) { throw Error("Impossible: no key id"); }
|
||||
}
|
||||
|
@ -524,7 +516,7 @@ function jwsEggspress(req, res, next) {
|
|||
}
|
||||
req.jws.verified = verified;
|
||||
|
||||
if (0 !== jwks.length) {
|
||||
if (0 !== DB.pubs.length) {
|
||||
return;
|
||||
}
|
||||
return keystore.set(vjwk.kid + '.pub.jwk.json', vjwk);
|
||||
|
@ -565,15 +557,14 @@ function handleApi() {
|
|||
dumpy.message = "Please run 'telebit init' to authenticate.";
|
||||
}
|
||||
|
||||
res.end(JSON.stringify(dumpy));
|
||||
res.send(dumpy);
|
||||
}
|
||||
|
||||
function getConfigOnly(req, res) {
|
||||
var resp = JSON.parse(JSON.stringify(state.config));
|
||||
resp.version = pkg.version;
|
||||
resp._otp = state.otp;
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
res.end(JSON.stringify(resp));
|
||||
res.send(resp);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -585,9 +576,8 @@ function handleApi() {
|
|||
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?"}}');
|
||||
res.send({"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;
|
||||
}
|
||||
|
||||
|
@ -599,7 +589,7 @@ function handleApi() {
|
|||
var conf = {};
|
||||
if (!req.body) {
|
||||
res.statusCode = 422;
|
||||
res.end('{"error":{"message":"module \'init\' needs more arguments"}}');
|
||||
res.send({"error":{"message":"module 'init' needs more arguments"}});
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -695,8 +685,7 @@ function handleApi() {
|
|||
console.warn('missing config');
|
||||
res.statusCode = 400;
|
||||
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
res.end(JSON.stringify({
|
||||
res.send({
|
||||
error: {
|
||||
code: "E_INIT"
|
||||
, message: "Missing important config file params"
|
||||
|
@ -704,7 +693,7 @@ function handleApi() {
|
|||
, _config: JSON.stringify(state.config)
|
||||
, _body: JSON.stringify(req.body)
|
||||
}
|
||||
}));
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -729,8 +718,7 @@ function handleApi() {
|
|||
}
|
||||
|
||||
function respondAndClose() {
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
res.end(JSON.stringify({ success: true }));
|
||||
res.send({ success: true });
|
||||
controlServer.close(function () {
|
||||
console.info("[telebitd.js] server closed");
|
||||
setTimeout(function () {
|
||||
|
@ -751,10 +739,9 @@ function handleApi() {
|
|||
}
|
||||
|
||||
res.statusCode = 400;
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
res.end(JSON.stringify({
|
||||
res.send({
|
||||
error: { code: "E_CONFIG", message: "Invalid config file. Please run 'telebit init'" }
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
function saveAndCommit(req, res) {
|
||||
|
@ -763,10 +750,9 @@ function handleApi() {
|
|||
fs.writeFile(confpath, YAML.safeDump(snakeCopy(state.config)), function (err) {
|
||||
if (err) {
|
||||
res.statusCode = 500;
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
res.end(JSON.stringify({
|
||||
res.send({
|
||||
"error":{"message":"Could not save config file. Perhaps you're not running as root?"}
|
||||
}));
|
||||
});
|
||||
return;
|
||||
}
|
||||
listSuccess();
|
||||
|
@ -775,10 +761,9 @@ function handleApi() {
|
|||
|
||||
function handleError(err, req, res) {
|
||||
res.statusCode = 500;
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
res.end(JSON.stringify({
|
||||
res.send({
|
||||
error: { message: err.message, code: err.code }
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
function enable(req, res) {
|
||||
|
@ -808,21 +793,19 @@ function handleApi() {
|
|||
|
||||
if (myRemote) { myRemote.end(); myRemote = null; }
|
||||
fs.writeFile(confpath, YAML.safeDump(snakeCopy(state.config)), function (err) {
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
if (err) {
|
||||
err.message = "Could not save config file. Perhaps you're user doesn't have permission?";
|
||||
handleError(err);
|
||||
return;
|
||||
}
|
||||
res.end('{"success":true}');
|
||||
res.send({"success":true});
|
||||
});
|
||||
}
|
||||
|
||||
function getStatus(req, res) {
|
||||
var now = Date.now();
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
require('../lib/ssh.js').checkSecurity().then(function (ssh) {
|
||||
res.end(JSON.stringify(
|
||||
res.send(
|
||||
{ module: 'status'
|
||||
, version: pkg.version
|
||||
, port: (state.config.ipc && state.config.ipc.port || state._ipc.port || undefined)
|
||||
|
@ -840,7 +823,7 @@ function handleApi() {
|
|||
, ssh_password_authentication: ssh.password_authentication
|
||||
, ssh_requests_password: ssh.requests_password
|
||||
}
|
||||
));
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -876,8 +859,7 @@ function handleApi() {
|
|||
app.use(/\b(status)\b/, getStatus);
|
||||
app.use(/\b(list)\b/, listSuccess);
|
||||
app.use('/', function (req, res) {
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
res.end(JSON.stringify({"error":{"message":"unrecognized rpc"}}));
|
||||
res.send({"error":{"message":"unrecognized rpc"}});
|
||||
});
|
||||
|
||||
return app;
|
||||
|
@ -1430,7 +1412,8 @@ state.net = state.net || {
|
|||
}
|
||||
};
|
||||
|
||||
var jwks = [];
|
||||
var DB = {};
|
||||
DB.pubs = [];
|
||||
var token;
|
||||
var tokenname = "access_token.jwt";
|
||||
try {
|
||||
|
@ -1444,12 +1427,10 @@ try {
|
|||
} catch(e) { onKeystore(); }
|
||||
function onKeystore() {
|
||||
return keystore.all().then(function (list) {
|
||||
var keyext = '.key.jwk.json';
|
||||
var pubext = '.pub.jwk.json';
|
||||
var key;
|
||||
list.forEach(function (el) {
|
||||
// find key
|
||||
if (keyext === el.account.slice(-keyext.length)
|
||||
if (KEYEXT === el.account.slice(-KEYEXT.length)
|
||||
&& el.password.kty && el.password.kid) {
|
||||
key = el.password;
|
||||
return;
|
||||
|
@ -1465,9 +1446,9 @@ function onKeystore() {
|
|||
// (if we sign these we could probably just store them to the fs,
|
||||
// but we do want some way to know that they weren't just willy-nilly
|
||||
// added to the fs my any old program)
|
||||
if (pubext === el.account.slice(-pubext.length)) {
|
||||
if (PUBEXT === el.account.slice(-PUBEXT.length)) {
|
||||
// pre-parsed
|
||||
jwks.push(el.password);
|
||||
DB.pubs.push(el.password);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1485,7 +1466,7 @@ function onKeystore() {
|
|||
var jwk = pair.private;
|
||||
return keypairs.thumbprint({ jwk: jwk }).then(function (kid) {
|
||||
jwk.kid = kid;
|
||||
return keystore.set(kid + keyext, jwk).then(function () {
|
||||
return keystore.set(kid + KEYEXT, jwk).then(function () {
|
||||
var size = (jwk.crv || Buffer.from(jwk.n, 'base64').byteLength * 8);
|
||||
console.info("Generated new %s %s private key with thumbprint %s", jwk.kty, size, kid);
|
||||
state.key = jwk;
|
||||
|
|
|
@ -1,5 +1,14 @@
|
|||
'use strict';
|
||||
|
||||
function eggSend(obj) {
|
||||
/*jslint validthis: true*/
|
||||
var me = this;
|
||||
if (!me.getHeader('content-type')) {
|
||||
me.setHeader('Content-Type', 'application/json');
|
||||
}
|
||||
me.end(JSON.stringify(obj));
|
||||
}
|
||||
|
||||
module.exports = function eggspress() {
|
||||
//var patternsMap = {};
|
||||
var allPatterns = [];
|
||||
|
@ -52,6 +61,9 @@ module.exports = function eggspress() {
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
res.send = eggSend;
|
||||
|
||||
next();
|
||||
};
|
||||
|
||||
|
|
|
@ -154,7 +154,7 @@ module.exports.create = function (state) {
|
|||
}
|
||||
, payload: JSON.stringify(opts.data)
|
||||
}).then(function (jws) {
|
||||
req.setHeader("content-type", 'application/json');
|
||||
req.setHeader("Content-Type", 'application/jose+json');
|
||||
req.write(JSON.stringify(jws));
|
||||
req.end();
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue