diff --git a/packages/apis/com.daplie.goldilocks/index.js b/lib/admin/apis.js similarity index 100% rename from packages/apis/com.daplie.goldilocks/index.js rename to lib/admin/apis.js diff --git a/lib/admin/index.js b/lib/admin/index.js new file mode 100644 index 0000000..e8c146b --- /dev/null +++ b/lib/admin/index.js @@ -0,0 +1,38 @@ +var adminDomains = [ + 'localhost.alpha.daplie.me' +, 'localhost.admin.daplie.me' +, 'alpha.localhost.daplie.me' +, 'admin.localhost.daplie.me' +, 'localhost.daplie.invalid' +]; +module.exports.adminDomains = adminDomains; + +module.exports.create = function (deps, conf) { + 'use strict'; + + var path = require('path'); + var express = require('express'); + var app = express(); + + var apis = require('./apis').create(deps, conf); + function handleApis(req, res, next) { + if (typeof apis[req.params.name] === 'function') { + apis[req.params.name](req, res); + } else { + next(); + } + } + app.use('/api/goldilocks@daplie.com/:name', handleApis); + app.use('/api/com.daplie.goldilocks/:name', handleApis); + + // Serve the static assets for the UI (even though it probably won't be used very + // often since it only works on localhost domains). Note that we are using the default + // .well-known directory from the oauth3 library even though it indicates we have + // capabilities we don't support because it's simpler and it's unlikely anything will + // actually use it to determine our API (it is needed to log into the web page). + app.use('/.well-known', express.static(path.join(__dirname, '../../packages/assets/well-known'))); + app.use('/assets', express.static(path.join(__dirname, '../../packages/assets'))); + app.use('/', express.static(path.join(__dirname, '../../admin/public'))); + + return require('http').createServer(app); +}; diff --git a/lib/app.js b/lib/app.js deleted file mode 100644 index f633712..0000000 --- a/lib/app.js +++ /dev/null @@ -1,325 +0,0 @@ -'use strict'; - -module.exports = function (myDeps, conf, overrideHttp) { - var express = require('express'); - //var finalhandler = require('finalhandler'); - var serveStatic = require('serve-static'); - var serveIndex = require('serve-index'); - //var assetServer = serveStatic(opts.assetsPath); - var path = require('path'); - //var wellKnownServer = serveStatic(path.join(opts.assetsPath, 'well-known')); - - var serveStaticMap = {}; - var serveIndexMap = {}; - var content = conf.content; - //var server; - var goldilocksApis; - var app; - var request; - - function createGoldilocksApis() { - var PromiseA = require('bluebird'); - var OAUTH3 = require('../packages/assets/org.oauth3'); - require('../packages/assets/org.oauth3/oauth3.domains.js'); - require('../packages/assets/org.oauth3/oauth3.dns.js'); - require('../packages/assets/org.oauth3/oauth3.tunnel.js'); - OAUTH3._hooks = require('../packages/assets/org.oauth3/oauth3.node.storage.js'); - - request = request || PromiseA.promisify(require('request')); - - myDeps.PromiseA = PromiseA; - myDeps.OAUTH3 = OAUTH3; - myDeps.recase = require('recase').create({}); - myDeps.request = request; - - return require('../packages/apis/com.daplie.goldilocks').create(myDeps, conf); - } - - app = express(); - - var Sites = { - add: function (sitesMap, site) { - if (!sitesMap[site.$id]) { - sitesMap[site.$id] = site; - } - - if (!site.paths) { - site.paths = []; - } - if (!site.paths._map) { - site.paths._map = {}; - } - site.paths.forEach(function (path) { - - site.paths._map[path.$id] = path; - - if (!path.modules) { - path.modules = []; - } - if (!path.modules._map) { - path.modules._map = {}; - } - path.modules.forEach(function (module) { - - path.modules._map[module.$id] = module; - }); - }); - } - }; - - var opts = overrideHttp || conf.http; - if (!opts.defaults) { - opts.defaults = {}; - } - if (!opts.global) { - opts.global = {}; - } - if (!opts.sites) { - opts.sites = []; - } - opts.sites._map = {}; - opts.sites.forEach(function (site) { - - Sites.add(opts.sites._map, site); - }); - - function mapMap(el, i, arr) { - arr._map[el.$id] = el; - } - opts.global.modules._map = {}; - opts.global.modules.forEach(mapMap); - opts.global.paths._map = {}; - opts.global.paths.forEach(function (path, i, arr) { - mapMap(path, i, arr); - //opts.global.paths._map[path.$id] = path; - path.modules._map = {}; - path.modules.forEach(mapMap); - }); - opts.sites.forEach(function (site) { - site.paths._map = {}; - site.paths.forEach(function (path, i, arr) { - mapMap(path, i, arr); - //site.paths._map[path.$id] = path; - path.modules._map = {}; - path.modules.forEach(mapMap); - }); - }); - opts.defaults.modules._map = {}; - opts.defaults.modules.forEach(mapMap); - opts.defaults.paths._map = {}; - opts.defaults.paths.forEach(function (path, i, arr) { - mapMap(path, i, arr); - //opts.global.paths._map[path.$id] = path; - path.modules._map = {}; - path.modules.forEach(mapMap); - }); - - function _goldApis(req, res, next) { - if (!goldilocksApis) { - goldilocksApis = createGoldilocksApis(); - } - - if (typeof goldilocksApis[req.params.name] === 'function') { - goldilocksApis[req.params.name](req, res); - } else { - next(); - } - } - return app - .use('/api/com.daplie.goldilocks/:name', _goldApis) - .use('/api/goldilocks@daplie.com/:name', _goldApis) - .use('/', function (req, res, next) { - if (!req.headers.host) { - next(new Error('missing HTTP Host header')); - return; - } - - if (content && '/' === req.url) { - // res.setHeader('Content-Type', 'application/octet-stream'); - res.end(content); - return; - } - - //var done = finalhandler(req, res); - var host = req.headers.host; - var hostname = (host||'').split(':')[0].toLowerCase(); - - console.log('opts.global', opts.global); - var sites = [ opts.global || null, opts.sites._map[hostname] || null, opts.defaults || null ]; - var loadables = { - serve: function (config, hostname, pathname, req, res, next) { - var originalUrl = req.url; - var dirpaths = config.paths.slice(0); - - function nextServe() { - var dirname = dirpaths.pop(); - if (!dirname) { - req.url = originalUrl; - next(); - return; - } - - console.log('[serve]', req.url, hostname, pathname, dirname); - dirname = path.resolve(conf.cwd, dirname.replace(/:hostname/, hostname)); - if (!serveStaticMap[dirname]) { - serveStaticMap[dirname] = serveStatic(dirname); - } - - serveStaticMap[dirname](req, res, nextServe); - } - - req.url = req.url.substr(pathname.length - 1); - nextServe(); - } - , indexes: function (config, hostname, pathname, req, res, next) { - var originalUrl = req.url; - var dirpaths = config.paths.slice(0); - - function nextIndex() { - var dirname = dirpaths.pop(); - if (!dirname) { - req.url = originalUrl; - next(); - return; - } - - console.log('[indexes]', req.url, hostname, pathname, dirname); - dirname = path.resolve(conf.cwd, dirname.replace(/:hostname/, hostname)); - if (!serveStaticMap[dirname]) { - serveIndexMap[dirname] = serveIndex(dirname); - } - serveIndexMap[dirname](req, res, nextIndex); - } - - req.url = req.url.substr(pathname.length - 1); - nextIndex(); - } - , app: function (config, hostname, pathname, req, res, next) { - //var appfile = path.resolve(/*process.cwd(), */config.path.replace(/:hostname/, hostname)); - var appfile = config.path.replace(/:hostname/, hostname); - try { - var app = require(appfile); - app(req, res, next); - } catch (err) { - next(); - } - } - }; - - function runModule(module, hostname, pathname, modulename, req, res, next) { - if (!loadables[modulename]) { - next(new Error("no module '" + modulename + "' found")); - return; - } - loadables[modulename](module, hostname, pathname, req, res, next); - } - - function iterModules(modules, hostname, pathname, req, res, next) { - console.log('modules'); - console.log(modules); - var modulenames = Object.keys(modules._map); - - function nextModule() { - var modulename = modulenames.pop(); - if (!modulename) { - next(); - return; - } - - console.log('modules', modules); - runModule(modules._map[modulename], hostname, pathname, modulename, req, res, nextModule); - } - - nextModule(); - } - - function iterPaths(site, hostname, req, res, next) { - console.log('site', hostname); - console.log(site); - var pathnames = Object.keys(site.paths._map); - console.log('pathnames', pathnames); - pathnames = pathnames.filter(function (pathname) { - // TODO ensure that pathname has trailing / - return (0 === req.url.indexOf(pathname)); - //return req.url.match(pathname); - }); - pathnames.sort(function (a, b) { - return b.length - a.length; - }); - console.log('pathnames', pathnames); - - function nextPath() { - var pathname = pathnames.shift(); - if (!pathname) { - next(); - return; - } - - console.log('iterPaths', hostname, pathname, req.url); - iterModules(site.paths._map[pathname].modules, hostname, pathname, req, res, nextPath); - } - - nextPath(); - } - - function nextSite() { - console.log('hostname', hostname, sites); - var site; - if (!sites.length) { - next(); // 404 - return; - } - site = sites.shift(); - if (!site) { - nextSite(); - return; - } - iterPaths(site, hostname, req, res, nextSite); - } - - nextSite(); - - /* - function serveStaticly(server) { - function serveTheStatic() { - server.serve(req, res, function (err) { - if (err) { return done(err); } - server.index(req, res, function (err) { - if (err) { return done(err); } - req.url = req.url.replace(/\/assets/, ''); - assetServer(req, res, function () { - if (err) { return done(err); } - req.url = req.url.replace(/\/\.well-known/, ''); - wellKnownServer(req, res, done); - }); - }); - }); - } - - if (server.expressApp) { - server.expressApp(req, res, serveTheStatic); - return; - } - - serveTheStatic(); - } - - if (opts.livereload) { - res.__my_livereload = ''; - res.__my_addLen = res.__my_livereload.length; - - // TODO modify prototype instead of each instance? - res.__write = res.write; - res.write = _reloadWrite; - } - - console.log('hostname:', hostname, opts.sites[0].paths); - - addServer(hostname); - server = hostsMap[hostname] || hostsMap[opts.sites[0].name]; - serveStaticly(server); - */ - }); -}; diff --git a/lib/modules/admin.js b/lib/modules/admin.js deleted file mode 100644 index d22b168..0000000 --- a/lib/modules/admin.js +++ /dev/null @@ -1,67 +0,0 @@ -var adminDomains = [ - 'localhost.alpha.daplie.me' -, 'localhost.admin.daplie.me' -, 'alpha.localhost.daplie.me' -, 'admin.localhost.daplie.me' -, 'localhost.daplie.invalid' -]; -module.exports.adminDomains = adminDomains; - -module.exports.create = function (deps, conf) { - 'use strict'; - - var path = require('path'); - //var defaultServername = 'localhost.daplie.me'; - //var defaultWebRoot = '.'; - var assetsPath = path.join(__dirname, '..', '..', 'packages', 'assets'); - var opts = {}; - - opts.global = opts.global || {}; - opts.sites = opts.sites || []; - opts.sites._map = {}; - - // argv.sites - - opts.groups = []; - - // 'packages', 'assets', 'com.daplie.goldilocks' - opts.global = { - modules: [ // TODO uh-oh we've got a mixed bag of modules (various types), a true map - { $id: 'greenlock', email: opts.email, tos: opts.tos } - , { $id: 'rvpn', email: opts.email, tos: opts.tos } - //, { $id: 'content', content: content } - , { $id: 'livereload', on: opts.livereload } - , { $id: 'app', path: opts.expressApp } - ] - , paths: [ - { $id: '/assets/', modules: [ { $id: 'serve', paths: [ assetsPath ] } ] } - // TODO figure this b out - , { $id: '/.well-known/', modules: [ - { $id: 'serve', paths: [ path.join(assetsPath, 'well-known') ] } - ] } - ] - }; - opts.defaults = { - modules: [] - , paths: [ - /* - { $id: '/', modules: [ - { $id: 'serve', paths: [ defaultWebRoot ] } - , { $id: 'indexes', paths: [ defaultWebRoot ] } - ] } - */ - ] - }; - adminDomains.forEach(function (id) { - opts.sites.push({ - $id: id - , paths: [ - { $id: '/', modules: [ { $id: 'serve', paths: [ path.resolve(__dirname, '..', '..', 'admin', 'public') ] } ] } - , { $id: '/api/', modules: [ { $id: 'app', path: path.join(__dirname, 'admin') } ] } - ] - }); - }); - - var app = require('../app.js')(deps, conf, opts); - return require('http').createServer(app); -}; diff --git a/lib/modules/http.js b/lib/modules/http.js index 636b6bc..365b09a 100644 --- a/lib/modules/http.js +++ b/lib/modules/http.js @@ -202,11 +202,11 @@ module.exports.create = function (deps, conf, greenlockMiddleware) { var host = separatePort(headers.host).host; if (!adminDomains) { - adminDomains = require('./admin').adminDomains; + adminDomains = require('../admin').adminDomains; } if (adminDomains.indexOf(host) !== -1) { if (!adminServer) { - adminServer = require('./admin').create(deps, conf); + adminServer = require('../admin').create(deps, conf); } return emitConnection(adminServer, conn, opts); } diff --git a/lib/worker.js b/lib/worker.js index 56991bc..d7ad1c1 100644 --- a/lib/worker.js +++ b/lib/worker.js @@ -19,10 +19,20 @@ function update(conf) { } function create(conf) { + var PromiseA = require('bluebird'); + var OAUTH3 = require('../packages/assets/org.oauth3'); + require('../packages/assets/org.oauth3/oauth3.domains.js'); + require('../packages/assets/org.oauth3/oauth3.dns.js'); + require('../packages/assets/org.oauth3/oauth3.tunnel.js'); + OAUTH3._hooks = require('../packages/assets/org.oauth3/oauth3.node.storage.js'); + config = conf; var deps = { messenger: process - , PromiseA: require('bluebird') + , PromiseA: PromiseA + , OAUTH3: OAUTH3 + , request: PromiseA.promisify(require('request')) + , recase: require('recase').create({}) // Note that if a custom createConnections is used it will be called with different // sets of custom options based on what is actually being proxied. Most notably the // HTTP proxying connection creation is not something we currently control. diff --git a/packages/apis/com.daplie.goldilocks/test.js b/packages/apis/com.daplie.goldilocks/test.js deleted file mode 100644 index 77b55de..0000000 --- a/packages/apis/com.daplie.goldilocks/test.js +++ /dev/null @@ -1,23 +0,0 @@ -'use strict'; - -var api = require('./index.js').api; -var OAUTH3 = require('../../assets/org.oauth3/'); -// these all auto-register -require('../../assets/org.oauth3/oauth3.domains.js'); -require('../../assets/org.oauth3/oauth3.dns.js'); -require('../../assets/org.oauth3/oauth3.tunnel.js'); -OAUTH3._hooks = require('../../assets/org.oauth3/oauth3.node.storage.js'); - -api.tunnel( - { - OAUTH3: OAUTH3 - , options: { - device: { - hostname: 'test.local' - , id: '' - } - } - } - // OAUTH3.hooks.session.get('oauth3.org').then(function (result) { console.log(result) }); -, require('./test.session.json') -);