digd.js/lib/httpd.js

242 lines
8.2 KiB
JavaScript
Raw Normal View History

2018-01-10 08:14:05 +00:00
'use strict';
2018-01-10 21:54:08 +00:00
module.exports.create = function (cli, engine/*, dnsd*/) {
2018-01-12 09:03:41 +00:00
var subparts = (cli.subject || '').split('@');
/*
{
"kty": "EC",
"use": "sig",
"crv": "P-256",
"x": "ogbK2nP6SiEIIp4w8oXBn3dcs6kljFfTbgZYG591tUU",
"y": "sB0AekMYwpvbQfAoW-2LlEWdapNhxynfj1zBtWpE9lo",
"alg": "ES256"
}
*/
var jwt;
var jwk;
var privpem;
var pubpem;
if (!subparts[1]) {
subparts = [ 'root', 'localhost' ];
// TODO generate new random key and store it
jwk = {
//"kid": "thumbnail(pubkey)",
"kty": "EC",
"d": "GRIT-yJVlhAsgIChbNanxv41iCxbZszbHHgK8kbZovs",
"use": "sig",
"crv": "P-256",
"x": "ogbK2nP6SiEIIp4w8oXBn3dcs6kljFfTbgZYG591tUU",
"y": "sB0AekMYwpvbQfAoW-2LlEWdapNhxynfj1zBtWpE9lo",
"alg": "ES256"
};
jwt = require('jsonwebtoken');
privpem = require('jwk-to-pem')(jwk, { private: true });
pubpem = require('jwk-to-pem')(jwk, { private: false });
console.log(privpem);
console.log("================================");
console.log(" JWT Write Authorization Token: ");
console.log("================================");
console.log(jwt.sign(
{ sub: subparts[0]
, iss: subparts[1]
, aud: 'localhost'
, scp: '+rw@adns.org'
}
, privpem
, { notBefore: 0 // from now
, expiresIn: '2h'
, algorithm: 'ES256'
}
));
// expressed as "from now"
/*
{ NotBeforeError: jwt not active
at Object.module.exports [as verify] (digd.js/node_modules/jsonwebtoken/verify.js:117:19)
at digd.js/lib/httpd.js:112:15
at Layer.handle [as handle_request] (digd.js/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (digd.js/node_modules/express/lib/router/index.js:317:13)
at digd.js/node_modules/express/lib/router/index.js:284:7
at Function.process_params (digd.js/node_modules/express/lib/router/index.js:335:12)
at next (digd.js/node_modules/express/lib/router/index.js:275:10)
at expressInit (digd.js/node_modules/express/lib/middleware/init.js:40:5)
at Layer.handle [as handle_request] (digd.js/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (digd.js/node_modules/express/lib/router/index.js:317:13)
name: 'NotBeforeError',
message: 'jwt not active',
date: +050046-12-28T01:12:58.000Z }
*/
console.log("===============================");
console.log(" JWT Read Authorization Token: ");
console.log("===============================");
console.log(jwt.sign(
{ sub: subparts[0]
, iss: subparts[1]
, aud: 'localhost'
, scp: '+r@adns.org'
}
, privpem
, { notBefore: 0 // from now
, algorithm: 'ES256'
}
));
console.log("==========================");
}
2018-01-10 08:14:05 +00:00
function runHttp() {
var path = require('path');
var express = require('express');
var app = express();
var httpServer = require('http').createServer(app);
2018-01-12 09:03:41 +00:00
app.use('/api', function (req, res, next) {
var auth = (req.headers.authorization || req.query.token || '').split(/\s+/)[1];
var token;
if (!auth) {
res.statusCode = 403;
res.send({ error: { message: "need authorization" } });
return;
}
jwt = jwt || require('jsonwebtoken');
try {
token = jwt.decode(auth);
} catch (e) {
token = null;
}
if (!token || !token.iss) {
res.statusCode = 403;
res.send({ error: { message: "need jwt-format authorization" } });
return;
}
if (subparts[0] === token.sub && subparts[1] === token.iss) {
try {
/*
// { algorithm: 'ES256' }
{ JsonWebTokenError: invalid algorithm
at Object.module.exports [as verify] (digd.js/node_modules/jsonwebtoken/verify.js:90:17)
at digd.js/lib/httpd.js:82:15
at Layer.handle [as handle_request] (digd.js/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (digd.js/node_modules/express/lib/router/index.js:317:13)
at digd.js/node_modules/express/lib/router/index.js:284:7
at Function.process_params (digd.js/node_modules/express/lib/router/index.js:335:12)
at next (digd.js/node_modules/express/lib/router/index.js:275:10)
at expressInit (digd.js/node_modules/express/lib/middleware/init.js:40:5)
at Layer.handle [as handle_request] (digd.js/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (digd.js/node_modules/express/lib/router/index.js:317:13) name: 'JsonWebTokenError', message: 'invalid algorithm' }
*/
// could be that it's private but expecting public, or public but expecting private
/*
Error: error:0906D06C:PEM routines:PEM_read_bio:no start line
at Verify.verify (crypto.js:381:23)
at verify (digd.js/node_modules/jwa/index.js:68:21)
at Object.verify (digd.js/node_modules/jwa/index.js:85:18)
at Object.jwsVerify [as verify] (digd.js/node_modules/jws/lib/verify-stream.js:54:15)
at Object.module.exports [as verify] (digd.js/node_modules/jsonwebtoken/verify.js:96:17)
at digd.js/lib/httpd.js:82:15
at Layer.handle [as handle_request] (digd.js/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (digd.js/node_modules/express/lib/router/index.js:317:13)
at digd.js/node_modules/express/lib/router/index.js:284:7
at Function.process_params (digd.js/node_modules/express/lib/router/index.js:335:12)
*/
jwt.verify(auth, pubpem, { algorithms: [ 'ES256' ] });
} catch(e) {
res.statusCode = 403;
console.error(e);
console.log(auth);
console.log(jwt.decode(auth, { complete: true }));
res.send({ error: { message: "jwt was not verified authorization" } });
return;
}
}
req.auth = auth;
req.token = token;
next();
});
app.get('/api/verify-auth', function (req, res) {
res.send({ success: true });
});
2018-01-10 08:14:05 +00:00
app.get('/api/peers', function (req, res) {
2018-01-10 21:54:08 +00:00
engine.peers.all(function (err, peers) {
res.send({ peers: peers });
});
2018-01-10 08:14:05 +00:00
});
app.get('/api/zones', function (req, res) {
2018-01-10 08:25:56 +00:00
engine.zones.all(function (err, zones) {
2018-01-10 08:14:05 +00:00
res.send({ zones: zones });
});
});
2018-01-10 21:54:08 +00:00
function mapRecord(r) {
return {
id: r.id
, zone: r.zone
, name: r.name
, tld: r.tld
, type: r.type
, class: r.class
, ttl: r.ttl
, data: r.data
, address: r.address
, exchange: r.exchange
, priority: r.priority
, value: r.value
, aname: r.aname
, flag: r.flag
, tag: r.tag
, weight: r.weight
, port: r.port
, target: r.target
};
}
app.get('/api/zones/:zone/records', function (req, res) {
2018-01-17 08:03:05 +00:00
var zonename = req.params.zone;
engine.zones.get({ names: [ zonename ] }, function (err, zones) {
var zone = engine.zoneToSoa(zones[0]);
zone.class = zone.className;
zone.type = zone.typeName;
engine.records.all(function (err, records) {
records = records.filter(function (r) {
return r.zone === zonename;
}).map(mapRecord);
records.unshift(zone);
res.send({ records: records });
});
2018-01-10 21:54:08 +00:00
});
});
app.get('/api/records', function (req, res) {
2018-01-10 08:25:56 +00:00
engine.records.all(function (err, records) {
2018-01-10 21:54:08 +00:00
res.send({ records: records.map(mapRecord) });
});
});
app.get('/api/records/:name', function (req, res) {
engine.records.all(function (err, records) {
res.send({ records: records.filter(function (r) {
if (r.name === req.params.name) {
return true;
}
var parts = req.params.name.split('.');
parts.shift();
if ('*.' + parts.join('.') === r.name) {
return true;
}
}).map(mapRecord) });
2018-01-10 08:14:05 +00:00
});
});
2018-01-12 09:03:41 +00:00
app.use('/', express.static(path.join(__dirname, 'public')));
2018-01-10 08:25:56 +00:00
httpServer.listen(cli.http, function () {
console.log(httpServer.address().address + '#' + httpServer.address().port + ' (http)');
});
2018-01-10 08:14:05 +00:00
}
runHttp();
};