MAJOR: Updates for Authenticated Web UI and CLI #30
| @ -587,6 +587,10 @@ function jwtEggspress(req, res, next) { | ||||
|   } catch(e) { | ||||
|     // 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
 | ||||
|   console.warn("[warn] JWT is not verified yet"); | ||||
|  | ||||
| @ -25,8 +25,9 @@ function safeFetch(url, opts) { | ||||
| 
 | ||||
| api.config = function apiConfig() { | ||||
|   return Telebit.reqLocalAsync({ | ||||
|     url: "/api/config" | ||||
|   , method: "GET" | ||||
|     method: "GET" | ||||
|   , url: "/api/config" | ||||
|   , key: api._key | ||||
|   }).then(function (resp) { | ||||
|     var json = resp.body; | ||||
|     appData.config = json; | ||||
| @ -34,17 +35,22 @@ api.config = function apiConfig() { | ||||
|   }); | ||||
| }; | ||||
| 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; | ||||
|     return json; | ||||
|   }); | ||||
| }; | ||||
| api.http = function apiHttp(o) { | ||||
|   var opts = { | ||||
|     url: "/api/http" | ||||
|   , method: "POST" | ||||
|     method: "POST" | ||||
|   , url: "/api/http" | ||||
|   , headers: { 'Content-Type': 'application/json' } | ||||
|   , json: { name: o.name, handler: o.handler, indexes: o.indexes } | ||||
|   , key: api._key | ||||
|   }; | ||||
|   return Telebit.reqLocalAsync(opts).then(function (resp) { | ||||
|     var json = resp.body; | ||||
| @ -56,10 +62,11 @@ api.http = function apiHttp(o) { | ||||
| }; | ||||
| api.ssh = function apiSsh(port) { | ||||
|   var opts = { | ||||
|     url: "/api/ssh" | ||||
|   , method: "POST" | ||||
|     method: "POST" | ||||
|   , url: "/api/ssh" | ||||
|   , headers: { 'Content-Type': 'application/json' } | ||||
|   , json: { port: port } | ||||
|   , key: api._key | ||||
|   }; | ||||
|   return Telebit.reqLocalAsync(opts).then(function (resp) { | ||||
|     var json = resp.body; | ||||
| @ -71,9 +78,10 @@ api.ssh = function apiSsh(port) { | ||||
| }; | ||||
| api.enable = function apiEnable() { | ||||
|   var opts = { | ||||
|     url: "/api/enable" | ||||
|   , method: "POST" | ||||
|     method: "POST" | ||||
|   , url: "/api/enable" | ||||
|   //, headers: { 'Content-Type': 'application/json' }
 | ||||
|   , key: api._key | ||||
|   }; | ||||
|   return Telebit.reqLocalAsync(opts).then(function (resp) { | ||||
|     var json = resp.body; | ||||
| @ -85,9 +93,10 @@ api.enable = function apiEnable() { | ||||
| }; | ||||
| api.disable = function apiDisable() { | ||||
|   var opts = { | ||||
|     url: "/api/disable" | ||||
|   , method: "POST" | ||||
|     method: "POST" | ||||
|   , url: "/api/disable" | ||||
|   //, headers: { 'Content-Type': 'application/json' }
 | ||||
|   , key: api._key | ||||
|   }; | ||||
|   return Telebit.reqLocalAsync(opts).then(function (resp) { | ||||
|     var json = resp.body; | ||||
| @ -465,8 +474,9 @@ new Vue({ | ||||
| }); | ||||
| 
 | ||||
| function run(key) { | ||||
|   // 1. Get ACME directory
 | ||||
|   // 2. Fetch ACME account
 | ||||
|   api._key = key; | ||||
|   // 😁 1. Get ACME directory
 | ||||
|   // 😁 2. Fetch ACME account
 | ||||
|   // 3. Test if account has access
 | ||||
|   // 4. Show command line auth instructions to auth
 | ||||
|   // 5. Sign requests / use JWT
 | ||||
|  | ||||
| @ -1,6 +1,7 @@ | ||||
| ;(function (exports) { | ||||
| 'use strict'; | ||||
| 
 | ||||
| var Keypairs = window.Keypairs; | ||||
| var common = exports.TELEBIT = {}; | ||||
| common.debug = true; | ||||
| 
 | ||||
| @ -14,7 +15,7 @@ if ('undefined' !== typeof Promise) { | ||||
| 
 | ||||
| /*globals AbortController*/ | ||||
| if ('undefined' !== typeof fetch) { | ||||
|   common.requestAsync = function (opts) { | ||||
|   common._requestAsync = function (opts) { | ||||
|     // funnel requests through the local server
 | ||||
|     // (avoid CORS, for now)
 | ||||
|     var relayOpts = { | ||||
| @ -44,7 +45,7 @@ if ('undefined' !== typeof fetch) { | ||||
|       }); | ||||
|     }); | ||||
|   }; | ||||
|   common.reqLocalAsync = function (opts) { | ||||
|   common._reqLocalAsync = function (opts) { | ||||
|     if (!opts) { opts = {}; } | ||||
|     if (opts.json && true !== opts.json) { | ||||
|       opts.body = opts.json; | ||||
| @ -78,9 +79,35 @@ if ('undefined' !== typeof fetch) { | ||||
|     }); | ||||
|   }; | ||||
| } else { | ||||
|   common.requestAsync = require('util').promisify(require('@root/request')); | ||||
|   common.reqLocalAsync = require('util').promisify(require('@root/request')); | ||||
|   common._requestAsync = 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) { | ||||
|   // add scheme, if missing
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user