MAJOR: Updates for Authenticated Web UI and CLI #30
| @ -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"); | ||||||
|  | |||||||
| @ -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
 | ||||||
|  | |||||||
| @ -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
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user