use jwt or jws for all requests

This commit is contained in:
AJ ONeal 2019-05-11 22:03:02 -06:00
parent 23a4a230a1
commit 69a28faccf
3 changed files with 58 additions and 17 deletions

View File

@ -587,6 +587,10 @@ function jwtEggspress(req, res, next) {
} catch(e) { } catch(e) {
// ignore // ignore
} }
if (!req.jwk.kid) {
res.send({ error: { message: "JWT must include a SHA thumbprint as the 'kid' (key id)" } });
return;
}
// TODO verify if possible // TODO verify if possible
console.warn("[warn] JWT is not verified yet"); console.warn("[warn] JWT is not verified yet");

View File

@ -25,8 +25,9 @@ function safeFetch(url, opts) {
api.config = function apiConfig() { api.config = function apiConfig() {
return Telebit.reqLocalAsync({ return Telebit.reqLocalAsync({
url: "/api/config" method: "GET"
, method: "GET" , url: "/api/config"
, key: api._key
}).then(function (resp) { }).then(function (resp) {
var json = resp.body; var json = resp.body;
appData.config = json; appData.config = json;
@ -34,17 +35,22 @@ api.config = function apiConfig() {
}); });
}; };
api.status = function apiStatus() { api.status = function apiStatus() {
return Telebit.reqLocalAsync({ url: "/api/status", method: "GET" }).then(function (resp) { return Telebit.reqLocalAsync({
method: "GET"
, url: "/api/status"
, key: api._key
}).then(function (resp) {
var json = resp.body; var json = resp.body;
return json; return json;
}); });
}; };
api.http = function apiHttp(o) { api.http = function apiHttp(o) {
var opts = { var opts = {
url: "/api/http" method: "POST"
, method: "POST" , url: "/api/http"
, headers: { 'Content-Type': 'application/json' } , headers: { 'Content-Type': 'application/json' }
, json: { name: o.name, handler: o.handler, indexes: o.indexes } , json: { name: o.name, handler: o.handler, indexes: o.indexes }
, key: api._key
}; };
return Telebit.reqLocalAsync(opts).then(function (resp) { return Telebit.reqLocalAsync(opts).then(function (resp) {
var json = resp.body; var json = resp.body;
@ -56,10 +62,11 @@ api.http = function apiHttp(o) {
}; };
api.ssh = function apiSsh(port) { api.ssh = function apiSsh(port) {
var opts = { var opts = {
url: "/api/ssh" method: "POST"
, method: "POST" , url: "/api/ssh"
, headers: { 'Content-Type': 'application/json' } , headers: { 'Content-Type': 'application/json' }
, json: { port: port } , json: { port: port }
, key: api._key
}; };
return Telebit.reqLocalAsync(opts).then(function (resp) { return Telebit.reqLocalAsync(opts).then(function (resp) {
var json = resp.body; var json = resp.body;
@ -71,9 +78,10 @@ api.ssh = function apiSsh(port) {
}; };
api.enable = function apiEnable() { api.enable = function apiEnable() {
var opts = { var opts = {
url: "/api/enable" method: "POST"
, method: "POST" , url: "/api/enable"
//, headers: { 'Content-Type': 'application/json' } //, headers: { 'Content-Type': 'application/json' }
, key: api._key
}; };
return Telebit.reqLocalAsync(opts).then(function (resp) { return Telebit.reqLocalAsync(opts).then(function (resp) {
var json = resp.body; var json = resp.body;
@ -85,9 +93,10 @@ api.enable = function apiEnable() {
}; };
api.disable = function apiDisable() { api.disable = function apiDisable() {
var opts = { var opts = {
url: "/api/disable" method: "POST"
, method: "POST" , url: "/api/disable"
//, headers: { 'Content-Type': 'application/json' } //, headers: { 'Content-Type': 'application/json' }
, key: api._key
}; };
return Telebit.reqLocalAsync(opts).then(function (resp) { return Telebit.reqLocalAsync(opts).then(function (resp) {
var json = resp.body; var json = resp.body;
@ -465,8 +474,9 @@ new Vue({
}); });
function run(key) { function run(key) {
// 1. Get ACME directory api._key = key;
// 2. Fetch ACME account // 😁 1. Get ACME directory
// 😁 2. Fetch ACME account
// 3. Test if account has access // 3. Test if account has access
// 4. Show command line auth instructions to auth // 4. Show command line auth instructions to auth
// 5. Sign requests / use JWT // 5. Sign requests / use JWT

View File

@ -1,6 +1,7 @@
;(function (exports) { ;(function (exports) {
'use strict'; 'use strict';
var Keypairs = window.Keypairs;
var common = exports.TELEBIT = {}; var common = exports.TELEBIT = {};
common.debug = true; common.debug = true;
@ -14,7 +15,7 @@ if ('undefined' !== typeof Promise) {
/*globals AbortController*/ /*globals AbortController*/
if ('undefined' !== typeof fetch) { if ('undefined' !== typeof fetch) {
common.requestAsync = function (opts) { common._requestAsync = function (opts) {
// funnel requests through the local server // funnel requests through the local server
// (avoid CORS, for now) // (avoid CORS, for now)
var relayOpts = { var relayOpts = {
@ -44,7 +45,7 @@ if ('undefined' !== typeof fetch) {
}); });
}); });
}; };
common.reqLocalAsync = function (opts) { common._reqLocalAsync = function (opts) {
if (!opts) { opts = {}; } if (!opts) { opts = {}; }
if (opts.json && true !== opts.json) { if (opts.json && true !== opts.json) {
opts.body = opts.json; opts.body = opts.json;
@ -78,9 +79,35 @@ if ('undefined' !== typeof fetch) {
}); });
}; };
} else { } else {
common.requestAsync = require('util').promisify(require('@root/request')); common._requestAsync = require('util').promisify(require('@root/request'));
common.reqLocalAsync = require('util').promisify(require('@root/request')); common._reqLocalAsync = require('util').promisify(require('@root/request'));
} }
common._sign = function (opts) {
var p;
if ('POST' === opts.method || opts.json) {
p = Keypairs.signJws({ jwk: opts.key, payload: opts.json || {} }).then(function (jws) {
opts.json = jws;
});
} else {
p = Keypairs.signJwt({ jwk: opts.key , claims: { iss: false, exp: '60s' } }).then(function (jwt) {
if (!opts.headers) { opts.headers = {}; }
opts.headers.Authorization = 'Bearer ' + jwt;
});
}
return p.then(function () {
return opts;
});
};
common.requestAsync = function (opts) {
return common._sign(opts).then(function (opts) {
return common._requestAsync(opts);
});
};
common.reqLocalAsync = function (opts) {
return common._sign(opts).then(function (opts) {
return common._reqLocalAsync(opts);
});
};
common.parseUrl = function (hostname) { common.parseUrl = function (hostname) {
// add scheme, if missing // add scheme, if missing