| 
									
										
										
										
											2017-02-28 14:55:48 -07:00
										 |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-05 12:49:48 -06:00
										 |  |  | module.exports.dependencies = [ 'OAUTH3', 'storage.owners', 'options.device' ]; | 
					
						
							| 
									
										
										
										
											2017-04-26 20:16:47 -06:00
										 |  |  | module.exports.create = function (deps, conf) { | 
					
						
							| 
									
										
										
										
											2017-03-02 00:58:45 -07:00
										 |  |  |   var scmp = require('scmp'); | 
					
						
							|  |  |  |   var crypto = require('crypto'); | 
					
						
							|  |  |  |   var jwt = require('jsonwebtoken'); | 
					
						
							| 
									
										
										
										
											2017-02-28 14:55:48 -07:00
										 |  |  |   var bodyParser = require('body-parser'); | 
					
						
							|  |  |  |   var jsonParser = bodyParser.json({ | 
					
						
							|  |  |  |     inflate: true, limit: '100kb', reviver: null, strict: true /* type, verify */ | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-09 16:33:49 -06:00
										 |  |  |   function handleCors(req, res, methods) { | 
					
						
							|  |  |  |     if (!methods) { | 
					
						
							|  |  |  |       methods = ['GET', 'POST']; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (!Array.isArray(methods)) { | 
					
						
							|  |  |  |       methods = [ methods ]; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     res.setHeader('Access-Control-Allow-Origin', req.headers.origin || '*'); | 
					
						
							|  |  |  |     res.setHeader('Access-Control-Allow-Methods', methods.join(', ')); | 
					
						
							|  |  |  |     res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); | 
					
						
							| 
									
										
										
										
											2017-10-25 13:35:06 -06:00
										 |  |  |     res.setHeader('Access-Control-Allow-Credentials', 'true'); | 
					
						
							| 
									
										
										
										
											2017-06-09 16:33:49 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-20 16:29:07 -06:00
										 |  |  |     if (req.method.toUpperCase() === 'OPTIONS') { | 
					
						
							|  |  |  |       res.setHeader('Allow', methods.join(', ')); | 
					
						
							|  |  |  |       res.end(); | 
					
						
							|  |  |  |       return true; | 
					
						
							| 
									
										
										
										
											2017-06-09 16:33:49 -06:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-20 16:29:07 -06:00
										 |  |  |     if (methods.indexOf('*') >= 0) { | 
					
						
							|  |  |  |       return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (methods.indexOf(req.method.toUpperCase()) < 0) { | 
					
						
							|  |  |  |       res.statusCode = 405; | 
					
						
							|  |  |  |       res.setHeader('Content-Type', 'application/json'); | 
					
						
							|  |  |  |       res.end(JSON.stringify({ error: { message: 'method '+req.method+' not allowed', code: 'EBADMETHOD'}})); | 
					
						
							|  |  |  |       return true; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-06-09 16:33:49 -06:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-10-03 19:11:49 -06:00
										 |  |  |   function makeCorsHandler(methods) { | 
					
						
							|  |  |  |     return function corsHandler(req, res, next) { | 
					
						
							|  |  |  |       if (!handleCors(req, res, methods)) { | 
					
						
							|  |  |  |         next(); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-06-09 16:33:49 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-17 16:16:57 -06:00
										 |  |  |   function handlePromise(req, res, prom) { | 
					
						
							|  |  |  |     prom.then(function (result) { | 
					
						
							|  |  |  |       res.send(deps.recase.snakeCopy(result)); | 
					
						
							|  |  |  |     }).catch(function (err) { | 
					
						
							| 
									
										
										
										
											2017-10-17 18:36:36 -06:00
										 |  |  |       if (conf.debug) { | 
					
						
							|  |  |  |         console.log(err); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2017-10-17 16:16:57 -06:00
										 |  |  |       res.statusCode = err.statusCode || 500; | 
					
						
							|  |  |  |       err.message = err.message || err.toString(); | 
					
						
							|  |  |  |       res.end(JSON.stringify({error: {message: err.message, code: err.code}})); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-02 00:58:45 -07:00
										 |  |  |   function isAuthorized(req, res, fn) { | 
					
						
							|  |  |  |     var auth = jwt.decode((req.headers.authorization||'').replace(/^bearer\s+/i, '')); | 
					
						
							|  |  |  |     if (!auth) { | 
					
						
							| 
									
										
										
										
											2017-06-12 13:09:51 -06:00
										 |  |  |       res.statusCode = 401; | 
					
						
							| 
									
										
										
										
											2017-02-28 14:55:48 -07:00
										 |  |  |       res.setHeader('Content-Type', 'application/json;'); | 
					
						
							| 
									
										
										
										
											2017-03-02 00:58:45 -07:00
										 |  |  |       res.end(JSON.stringify({ error: { message: "no token", code: 'E_NO_TOKEN', uri: undefined } })); | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     var id = crypto.createHash('sha256').update(auth.sub).digest('hex'); | 
					
						
							|  |  |  |     return deps.storage.owners.exists(id).then(function (exists) { | 
					
						
							|  |  |  |       if (!exists) { | 
					
						
							| 
									
										
										
										
											2017-06-12 13:09:51 -06:00
										 |  |  |         res.statusCode = 401; | 
					
						
							| 
									
										
										
										
											2017-03-02 00:58:45 -07:00
										 |  |  |         res.setHeader('Content-Type', 'application/json;'); | 
					
						
							|  |  |  |         res.end(JSON.stringify({ error: { message: "not authorized", code: 'E_NO_AUTHZ', uri: undefined } })); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-05 12:49:48 -06:00
										 |  |  |       req.userId = id; | 
					
						
							| 
									
										
										
										
											2017-03-02 00:58:45 -07:00
										 |  |  |       fn(); | 
					
						
							| 
									
										
										
										
											2017-02-28 14:55:48 -07:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2017-03-02 00:58:45 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-20 15:33:45 -06:00
										 |  |  |   function checkPaywall() { | 
					
						
							| 
									
										
										
										
											2017-07-10 17:06:34 -06:00
										 |  |  |     var url = require('url'); | 
					
						
							| 
									
										
										
										
											2017-06-20 15:33:45 -06:00
										 |  |  |     var PromiseA = require('bluebird'); | 
					
						
							|  |  |  |     var testDomains = [ | 
					
						
							|  |  |  |       'daplie.com' | 
					
						
							|  |  |  |     , 'duckduckgo.com' | 
					
						
							|  |  |  |     , 'google.com' | 
					
						
							|  |  |  |     , 'amazon.com' | 
					
						
							|  |  |  |     , 'facebook.com' | 
					
						
							|  |  |  |     , 'msn.com' | 
					
						
							|  |  |  |     , 'yahoo.com' | 
					
						
							|  |  |  |     ]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // While this is not being developed behind a paywall the current idea is that
 | 
					
						
							|  |  |  |     // a paywall will either manipulate DNS queries to point to the paywall gate,
 | 
					
						
							|  |  |  |     // or redirect HTTP requests to the paywall gate. So we check for both and
 | 
					
						
							|  |  |  |     // hope we can detect most hotel/ISP paywalls out there in the world.
 | 
					
						
							| 
									
										
										
										
											2017-07-17 16:28:34 -06:00
										 |  |  |     //
 | 
					
						
							|  |  |  |     // It is also possible that the paywall will prevent any unknown traffic from
 | 
					
						
							|  |  |  |     // leaving the network, so the DNS queries could fail if the unit is set to
 | 
					
						
							|  |  |  |     // use nameservers other than the paywall router.
 | 
					
						
							| 
									
										
										
										
											2017-06-20 15:33:45 -06:00
										 |  |  |     return PromiseA.resolve() | 
					
						
							|  |  |  |     .then(function () { | 
					
						
							|  |  |  |       var dns = PromiseA.promisifyAll(require('dns')); | 
					
						
							|  |  |  |       var proms = testDomains.map(function (dom) { | 
					
						
							|  |  |  |         return dns.resolve6Async(dom) | 
					
						
							| 
									
										
										
										
											2017-07-14 17:04:24 -06:00
										 |  |  |           .catch(function () { | 
					
						
							|  |  |  |             return dns.resolve4Async(dom); | 
					
						
							| 
									
										
										
										
											2017-06-20 15:33:45 -06:00
										 |  |  |           }) | 
					
						
							|  |  |  |           .then(function (result) { | 
					
						
							|  |  |  |             return result[0]; | 
					
						
							| 
									
										
										
										
											2017-07-17 16:28:34 -06:00
										 |  |  |           }, function () { | 
					
						
							|  |  |  |             return null; | 
					
						
							| 
									
										
										
										
											2017-06-20 15:33:45 -06:00
										 |  |  |           }); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return PromiseA.all(proms).then(function (addrs) { | 
					
						
							|  |  |  |         var unique = addrs.filter(function (value, ind, self) { | 
					
						
							|  |  |  |           return value && self.indexOf(value) === ind; | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |         // It is possible some walls might have exceptions that leave some of the domains
 | 
					
						
							|  |  |  |         // we test alone, so we might have more than one unique address even behind an
 | 
					
						
							|  |  |  |         // active paywall.
 | 
					
						
							|  |  |  |         return unique.length < addrs.length; | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }) | 
					
						
							|  |  |  |     .then(function (paywall) { | 
					
						
							|  |  |  |       if (paywall) { | 
					
						
							|  |  |  |         return paywall; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       var request = deps.request.defaults({ | 
					
						
							|  |  |  |         followRedirect: false | 
					
						
							|  |  |  |       , headers: { | 
					
						
							|  |  |  |           connection: 'close' | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       var proms = testDomains.map(function (dom) { | 
					
						
							| 
									
										
										
										
											2017-07-10 17:06:34 -06:00
										 |  |  |         return request('http://'+dom).then(function (resp) { | 
					
						
							| 
									
										
										
										
											2017-06-20 15:33:45 -06:00
										 |  |  |           if (resp.statusCode >= 300 && resp.statusCode < 400) { | 
					
						
							| 
									
										
										
										
											2017-07-10 17:06:34 -06:00
										 |  |  |             return url.parse(resp.headers.location).hostname; | 
					
						
							| 
									
										
										
										
											2017-06-20 15:33:45 -06:00
										 |  |  |           } else { | 
					
						
							| 
									
										
										
										
											2017-07-10 17:06:34 -06:00
										 |  |  |             return dom; | 
					
						
							| 
									
										
										
										
											2017-06-20 15:33:45 -06:00
										 |  |  |           } | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return PromiseA.all(proms).then(function (urls) { | 
					
						
							|  |  |  |         var unique = urls.filter(function (value, ind, self) { | 
					
						
							|  |  |  |           return value && self.indexOf(value) === ind; | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |         return unique.length < urls.length; | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }) | 
					
						
							|  |  |  |     ; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-03 19:11:49 -06:00
										 |  |  |   // This object contains all of the API endpoints written before we changed how
 | 
					
						
							|  |  |  |   // the API routing is handled. Eventually it will hopefully disappear, but for
 | 
					
						
							|  |  |  |   // now we're focusing on the things that need changing more.
 | 
					
						
							|  |  |  |   var oldEndPoints = { | 
					
						
							| 
									
										
										
										
											2017-03-02 00:58:45 -07:00
										 |  |  |     init: function (req, res) { | 
					
						
							| 
									
										
										
										
											2017-07-06 11:25:30 -06:00
										 |  |  |       if (handleCors(req, res, ['GET', 'POST'])) { | 
					
						
							| 
									
										
										
										
											2017-06-09 16:33:49 -06:00
										 |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-06 11:25:30 -06:00
										 |  |  |       if ('POST' !== req.method) { | 
					
						
							|  |  |  |         // It should be safe to give the list of owner IDs to an un-authenticated
 | 
					
						
							|  |  |  |         // request because the ID is the sha256 of the PPID and shouldn't be reversible
 | 
					
						
							|  |  |  |         return deps.storage.owners.all().then(function (results) { | 
					
						
							|  |  |  |           var ids = results.map(function (owner) { | 
					
						
							|  |  |  |             return owner.id; | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |           res.setHeader('Content-Type', 'application/json'); | 
					
						
							|  |  |  |           res.end(JSON.stringify(ids)); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-02 00:58:45 -07:00
										 |  |  |       jsonParser(req, res, function () { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-18 14:48:49 -06:00
										 |  |  |       return deps.PromiseA.resolve().then(function () { | 
					
						
							| 
									
										
										
										
											2017-06-09 16:33:49 -06:00
										 |  |  |         console.log('init POST body', req.body); | 
					
						
							| 
									
										
										
										
											2017-03-18 14:48:49 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         var auth = jwt.decode((req.headers.authorization||'').replace(/^bearer\s+/i, '')); | 
					
						
							|  |  |  |         var token = jwt.decode(req.body.access_token); | 
					
						
							|  |  |  |         var refresh = jwt.decode(req.body.refresh_token); | 
					
						
							|  |  |  |         auth.sub = auth.sub || auth.acx.id; | 
					
						
							|  |  |  |         token.sub = token.sub || token.acx.id; | 
					
						
							|  |  |  |         refresh.sub = refresh.sub || refresh.acx.id; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // TODO validate token with issuer, but as-is the sub is already a secret
 | 
					
						
							|  |  |  |         var id = crypto.createHash('sha256').update(auth.sub).digest('hex'); | 
					
						
							|  |  |  |         var tid = crypto.createHash('sha256').update(token.sub).digest('hex'); | 
					
						
							|  |  |  |         var rid = crypto.createHash('sha256').update(refresh.sub).digest('hex'); | 
					
						
							| 
									
										
										
										
											2017-04-05 12:49:48 -06:00
										 |  |  |         var session = { | 
					
						
							|  |  |  |           access_token: req.body.access_token | 
					
						
							|  |  |  |         , token: token | 
					
						
							|  |  |  |         , refresh_token: req.body.refresh_token | 
					
						
							|  |  |  |         , refresh: refresh | 
					
						
							|  |  |  |         }; | 
					
						
							| 
									
										
										
										
											2017-03-18 14:48:49 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         console.log('ids', id, tid, rid); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (req.body.ip_url) { | 
					
						
							|  |  |  |           // TODO set options / GunDB
 | 
					
						
							| 
									
										
										
										
											2017-04-26 20:16:47 -06:00
										 |  |  |           conf.ip_url = req.body.ip_url; | 
					
						
							| 
									
										
										
										
											2017-03-18 14:48:49 -06:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return deps.storage.owners.all().then(function (results) { | 
					
						
							|  |  |  |           console.log('results', results); | 
					
						
							|  |  |  |           var err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           // There is no owner yet. First come, first serve.
 | 
					
						
							|  |  |  |           if (!results || !results.length) { | 
					
						
							|  |  |  |             if (tid !== id || rid !== id) { | 
					
						
							|  |  |  |               err = new Error( | 
					
						
							|  |  |  |                 "When creating an owner the Authorization Bearer and Token and Refresh must all match" | 
					
						
							|  |  |  |               ); | 
					
						
							| 
									
										
										
										
											2017-06-12 13:09:51 -06:00
										 |  |  |               err.statusCode = 400; | 
					
						
							| 
									
										
										
										
											2017-03-18 14:48:49 -06:00
										 |  |  |               return deps.PromiseA.reject(err); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             console.log('no owner, creating'); | 
					
						
							| 
									
										
										
										
											2017-04-05 12:49:48 -06:00
										 |  |  |             return deps.storage.owners.set(id, session); | 
					
						
							| 
									
										
										
										
											2017-03-18 14:48:49 -06:00
										 |  |  |           } | 
					
						
							|  |  |  |           console.log('has results'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           // There are onwers. Is this one of them?
 | 
					
						
							|  |  |  |           if (!results.some(function (token) { | 
					
						
							|  |  |  |             return scmp(id, token.id); | 
					
						
							|  |  |  |           })) { | 
					
						
							|  |  |  |             err = new Error("Authorization token does not belong to an existing owner."); | 
					
						
							| 
									
										
										
										
											2017-06-12 13:09:51 -06:00
										 |  |  |             err.statusCode = 401; | 
					
						
							| 
									
										
										
										
											2017-03-02 00:58:45 -07:00
										 |  |  |             return deps.PromiseA.reject(err); | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2017-03-18 14:48:49 -06:00
										 |  |  |           console.log('has correct owner'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           // We're adding an owner, unless it already exists
 | 
					
						
							|  |  |  |           if (!results.some(function (token) { | 
					
						
							|  |  |  |             return scmp(tid, token.id); | 
					
						
							|  |  |  |           })) { | 
					
						
							|  |  |  |             console.log('adds new owner with existing owner'); | 
					
						
							| 
									
										
										
										
											2017-06-23 17:47:04 -06:00
										 |  |  |             return deps.storage.owners.set(tid, session); | 
					
						
							| 
									
										
										
										
											2017-03-18 14:48:49 -06:00
										 |  |  |           } | 
					
						
							|  |  |  |         }).then(function () { | 
					
						
							|  |  |  |           res.setHeader('Content-Type', 'application/json;'); | 
					
						
							|  |  |  |           res.end(JSON.stringify({ success: true })); | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2017-06-09 16:33:49 -06:00
										 |  |  |       }) | 
					
						
							|  |  |  |       .catch(function (err) { | 
					
						
							| 
									
										
										
										
											2017-03-02 00:58:45 -07:00
										 |  |  |         res.setHeader('Content-Type', 'application/json;'); | 
					
						
							| 
									
										
										
										
											2017-06-12 13:09:51 -06:00
										 |  |  |         res.statusCode = err.statusCode || 500; | 
					
						
							| 
									
										
										
										
											2017-03-02 00:58:45 -07:00
										 |  |  |         res.end(JSON.stringify({ error: { message: err.message, code: err.code, uri: err.uri } })); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-03-18 14:48:49 -06:00
										 |  |  |   , request: function (req, res) { | 
					
						
							| 
									
										
										
										
											2017-06-09 16:33:49 -06:00
										 |  |  |       if (handleCors(req, res, '*')) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2017-03-18 14:48:49 -06:00
										 |  |  |       isAuthorized(req, res, function () { | 
					
						
							| 
									
										
										
										
											2017-05-30 12:15:19 -06:00
										 |  |  |       jsonParser(req, res, function () { | 
					
						
							| 
									
										
										
										
											2017-03-18 14:48:49 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         deps.request({ | 
					
						
							|  |  |  |           method: req.body.method || 'GET' | 
					
						
							|  |  |  |         , url: req.body.url | 
					
						
							|  |  |  |         , headers: req.body.headers | 
					
						
							|  |  |  |         , body: req.body.data | 
					
						
							|  |  |  |         }).then(function (resp) { | 
					
						
							|  |  |  |           if (resp.body instanceof Buffer || 'string' === typeof resp.body) { | 
					
						
							|  |  |  |             resp.body = JSON.parse(resp.body); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           return { | 
					
						
							|  |  |  |             statusCode: resp.statusCode | 
					
						
							|  |  |  |           , status: resp.status | 
					
						
							|  |  |  |           , headers: resp.headers | 
					
						
							|  |  |  |           , body: resp.body | 
					
						
							|  |  |  |           , data: resp.data | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  |         }).then(function (result) { | 
					
						
							|  |  |  |           res.send(result); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-06-20 15:33:45 -06:00
										 |  |  |   , paywall_check: function (req, res) { | 
					
						
							|  |  |  |       if (handleCors(req, res, 'GET')) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       isAuthorized(req, res, function () { | 
					
						
							|  |  |  |         res.setHeader('Content-Type', 'application/json;'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         checkPaywall().then(function (paywall) { | 
					
						
							|  |  |  |           res.end(JSON.stringify({paywall: paywall})); | 
					
						
							|  |  |  |         }, function (err) { | 
					
						
							|  |  |  |           err.message = err.message || err.toString(); | 
					
						
							|  |  |  |           res.statusCode = 500; | 
					
						
							|  |  |  |           res.end(JSON.stringify({error: {message: err.message, code: err.code}})); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-06-20 18:16:11 -06:00
										 |  |  |   , socks5: function (req, res) { | 
					
						
							|  |  |  |       if (handleCors(req, res, ['GET', 'POST', 'DELETE'])) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       isAuthorized(req, res, function () { | 
					
						
							|  |  |  |         var method = req.method.toUpperCase(); | 
					
						
							|  |  |  |         var prom; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (method === 'POST') { | 
					
						
							|  |  |  |           prom = deps.socks5.start(); | 
					
						
							|  |  |  |         } else if (method === 'DELETE') { | 
					
						
							|  |  |  |           prom = deps.socks5.stop(); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           prom = deps.socks5.curState(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         res.setHeader('Content-Type', 'application/json;'); | 
					
						
							|  |  |  |         prom.then(function (result) { | 
					
						
							|  |  |  |           res.end(JSON.stringify(result)); | 
					
						
							|  |  |  |         }, function (err) { | 
					
						
							|  |  |  |           err.message = err.message || err.toString(); | 
					
						
							|  |  |  |           res.statusCode = 500; | 
					
						
							|  |  |  |           res.end(JSON.stringify({error: {message: err.message, code: err.code}})); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-02-28 14:55:48 -07:00
										 |  |  |   }; | 
					
						
							| 
									
										
										
										
											2017-10-03 19:11:49 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |   function handleOldApis(req, res, next) { | 
					
						
							|  |  |  |     if (typeof oldEndPoints[req.params.name] === 'function') { | 
					
						
							|  |  |  |       oldEndPoints[req.params.name](req, res); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       next(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   var config = { restful: {} }; | 
					
						
							| 
									
										
										
										
											2017-10-04 14:42:19 -06:00
										 |  |  |   config.restful.readConfig = function (req, res, next) { | 
					
						
							| 
									
										
										
										
											2017-10-11 12:18:01 -06:00
										 |  |  |     var part = new (require('./config').ConfigChanger)(conf); | 
					
						
							| 
									
										
										
										
											2017-10-04 14:42:19 -06:00
										 |  |  |     if (req.params.group) { | 
					
						
							|  |  |  |       part = part[req.params.group]; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-10-11 12:18:01 -06:00
										 |  |  |     if (part && req.params.domId) { | 
					
						
							| 
									
										
										
										
											2017-10-11 17:13:33 -06:00
										 |  |  |       part = part.domains.findId(req.params.domId); | 
					
						
							| 
									
										
										
										
											2017-10-04 14:42:19 -06:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-10-11 12:18:01 -06:00
										 |  |  |     if (part && req.params.mod) { | 
					
						
							|  |  |  |       part = part[req.params.mod]; | 
					
						
							| 
									
										
										
										
											2017-10-04 14:42:19 -06:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-10-11 12:18:01 -06:00
										 |  |  |     if (part && req.params.modGrp) { | 
					
						
							|  |  |  |       part = part[req.params.modGrp]; | 
					
						
							| 
									
										
										
										
											2017-10-04 14:42:19 -06:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-10-11 12:18:01 -06:00
										 |  |  |     if (part && req.params.modId) { | 
					
						
							| 
									
										
										
										
											2017-10-11 17:13:33 -06:00
										 |  |  |       part = part.findId(req.params.modId); | 
					
						
							| 
									
										
										
										
											2017-10-04 14:42:19 -06:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (part) { | 
					
						
							|  |  |  |       res.send(deps.recase.snakeCopy(part)); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       next(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-10-03 19:11:49 -06:00
										 |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-11 17:13:33 -06:00
										 |  |  |   config.save = function (changer) { | 
					
						
							|  |  |  |     var errors = changer.validate(); | 
					
						
							|  |  |  |     if (errors.length) { | 
					
						
							|  |  |  |       throw Object.assign(new Error(), errors[0], {statusCode: 400}); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return deps.storage.config.save(changer); | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  |   config.restful.saveBaseConfig = function (req, res, next) { | 
					
						
							| 
									
										
										
										
											2017-10-10 11:08:19 -06:00
										 |  |  |     console.log('config POST body', JSON.stringify(req.body)); | 
					
						
							| 
									
										
										
										
											2017-10-11 17:13:33 -06:00
										 |  |  |     if (req.params.group === 'domains') { | 
					
						
							|  |  |  |       next(); | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-10-10 11:08:19 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-17 16:16:57 -06:00
										 |  |  |     var promise = deps.PromiseA.resolve().then(function () { | 
					
						
							| 
									
										
										
										
											2017-10-10 11:08:19 -06:00
										 |  |  |       var update; | 
					
						
							|  |  |  |       if (req.params.group) { | 
					
						
							|  |  |  |         update = {}; | 
					
						
							|  |  |  |         update[req.params.group] = req.body; | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         update = req.body; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       var changer = new (require('./config').ConfigChanger)(conf); | 
					
						
							| 
									
										
										
										
											2017-10-11 17:13:33 -06:00
										 |  |  |       changer.update(update); | 
					
						
							|  |  |  |       return config.save(changer); | 
					
						
							| 
									
										
										
										
											2017-10-17 16:16:57 -06:00
										 |  |  |     }).then(function (newConf) { | 
					
						
							| 
									
										
										
										
											2017-10-10 11:08:19 -06:00
										 |  |  |       if (req.params.group) { | 
					
						
							| 
									
										
										
										
											2017-10-17 16:16:57 -06:00
										 |  |  |         return newConf[req.params.group]; | 
					
						
							| 
									
										
										
										
											2017-10-10 11:08:19 -06:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2017-10-17 16:16:57 -06:00
										 |  |  |       return newConf; | 
					
						
							| 
									
										
										
										
											2017-10-10 11:08:19 -06:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2017-10-17 16:16:57 -06:00
										 |  |  |     handlePromise(req, res, promise); | 
					
						
							| 
									
										
										
										
											2017-10-10 11:08:19 -06:00
										 |  |  |   }; | 
					
						
							| 
									
										
										
										
											2017-10-11 17:13:33 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |   config.extractModList = function (changer, params) { | 
					
						
							| 
									
										
										
										
											2017-10-10 11:08:19 -06:00
										 |  |  |     var err; | 
					
						
							| 
									
										
										
										
											2017-10-11 17:13:33 -06:00
										 |  |  |     if (params.domId) { | 
					
						
							|  |  |  |       var dom = changer.domains.find(function (dom) { | 
					
						
							|  |  |  |         return dom.id === params.domId; | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (!dom) { | 
					
						
							|  |  |  |         err = new Error("no domain with ID '"+params.domId+"'"); | 
					
						
							|  |  |  |       } else if (!dom.modules[params.group]) { | 
					
						
							|  |  |  |         err = new Error("domains don't contain '"+params.group+"' modules"); | 
					
						
							| 
									
										
										
										
											2017-10-10 11:08:19 -06:00
										 |  |  |       } else { | 
					
						
							| 
									
										
										
										
											2017-10-11 17:13:33 -06:00
										 |  |  |         return dom.modules[params.group]; | 
					
						
							| 
									
										
										
										
											2017-10-10 11:08:19 -06:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2017-10-11 17:13:33 -06:00
										 |  |  |     } else { | 
					
						
							|  |  |  |       if (!changer[params.group] || !changer[params.group].modules) { | 
					
						
							|  |  |  |         err = new Error("'"+params.group+"' is not a valid settings group or doesn't support modules"); | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         return changer[params.group].modules; | 
					
						
							| 
									
										
										
										
											2017-10-10 11:08:19 -06:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2017-10-11 17:13:33 -06:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     err.statusCode = 404; | 
					
						
							|  |  |  |     throw err; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  |   config.restful.createModule = function (req, res, next) { | 
					
						
							|  |  |  |     if (req.params.group === 'domains') { | 
					
						
							|  |  |  |       next(); | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-17 16:16:57 -06:00
										 |  |  |     var promise = deps.PromiseA.resolve().then(function () { | 
					
						
							| 
									
										
										
										
											2017-10-11 17:13:33 -06:00
										 |  |  |       var changer = new (require('./config').ConfigChanger)(conf); | 
					
						
							|  |  |  |       var modList = config.extractModList(changer, req.params); | 
					
						
							| 
									
										
										
										
											2017-10-10 11:08:19 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-11 12:18:01 -06:00
										 |  |  |       var update = req.body; | 
					
						
							|  |  |  |       if (!Array.isArray(update)) { | 
					
						
							|  |  |  |         update = [ update ]; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       update.forEach(modList.add, modList); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-11 17:13:33 -06:00
										 |  |  |       return config.save(changer); | 
					
						
							|  |  |  |     }).then(function (newConf) { | 
					
						
							| 
									
										
										
										
											2017-10-17 16:16:57 -06:00
										 |  |  |       return config.extractModList(newConf, req.params); | 
					
						
							| 
									
										
										
										
											2017-10-11 17:13:33 -06:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2017-10-17 16:16:57 -06:00
										 |  |  |     handlePromise(req, res, promise); | 
					
						
							| 
									
										
										
										
											2017-10-11 17:13:33 -06:00
										 |  |  |   }; | 
					
						
							|  |  |  |   config.restful.updateModule = function (req, res, next) { | 
					
						
							|  |  |  |     if (req.params.group === 'domains') { | 
					
						
							|  |  |  |       next(); | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-10-10 11:08:19 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-17 16:16:57 -06:00
										 |  |  |     var promise = deps.PromiseA.resolve().then(function () { | 
					
						
							| 
									
										
										
										
											2017-10-11 17:13:33 -06:00
										 |  |  |       var changer = new (require('./config').ConfigChanger)(conf); | 
					
						
							|  |  |  |       var modList = config.extractModList(changer, req.params); | 
					
						
							|  |  |  |       modList.update(req.params.modId, req.body); | 
					
						
							|  |  |  |       return config.save(changer); | 
					
						
							|  |  |  |     }).then(function (newConf) { | 
					
						
							| 
									
										
										
										
											2017-10-17 16:16:57 -06:00
										 |  |  |       return config.extractModule(newConf, req.params).find(function (mod) { | 
					
						
							|  |  |  |         return mod.id === req.params.modId; | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2017-10-11 17:13:33 -06:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2017-10-17 16:16:57 -06:00
										 |  |  |     handlePromise(req, res, promise); | 
					
						
							| 
									
										
										
										
											2017-10-11 17:13:33 -06:00
										 |  |  |   }; | 
					
						
							|  |  |  |   config.restful.removeModule = function (req, res, next) { | 
					
						
							|  |  |  |     if (req.params.group === 'domains') { | 
					
						
							|  |  |  |       next(); | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-17 16:16:57 -06:00
										 |  |  |     var promise = deps.PromiseA.resolve().then(function () { | 
					
						
							| 
									
										
										
										
											2017-10-11 17:13:33 -06:00
										 |  |  |       var changer = new (require('./config').ConfigChanger)(conf); | 
					
						
							|  |  |  |       var modList = config.extractModList(changer, req.params); | 
					
						
							|  |  |  |       modList.remove(req.params.modId); | 
					
						
							|  |  |  |       return config.save(changer); | 
					
						
							|  |  |  |     }).then(function (newConf) { | 
					
						
							| 
									
										
										
										
											2017-10-17 16:16:57 -06:00
										 |  |  |       return config.extractModList(newConf, req.params); | 
					
						
							| 
									
										
										
										
											2017-10-10 11:08:19 -06:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2017-10-17 16:16:57 -06:00
										 |  |  |     handlePromise(req, res, promise); | 
					
						
							| 
									
										
										
										
											2017-10-10 11:08:19 -06:00
										 |  |  |   }; | 
					
						
							| 
									
										
										
										
											2017-10-11 17:13:33 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-10 11:08:19 -06:00
										 |  |  |   config.restful.createDomain = function (req, res) { | 
					
						
							| 
									
										
										
										
											2017-10-17 16:16:57 -06:00
										 |  |  |     var promise = deps.PromiseA.resolve().then(function () { | 
					
						
							| 
									
										
										
										
											2017-10-10 11:08:19 -06:00
										 |  |  |       var changer = new (require('./config').ConfigChanger)(conf); | 
					
						
							| 
									
										
										
										
											2017-10-11 12:18:01 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |       var update = req.body; | 
					
						
							|  |  |  |       if (!Array.isArray(update)) { | 
					
						
							|  |  |  |         update = [ update ]; | 
					
						
							| 
									
										
										
										
											2017-10-10 11:08:19 -06:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2017-10-11 12:18:01 -06:00
										 |  |  |       update.forEach(changer.domains.add, changer.domains); | 
					
						
							| 
									
										
										
										
											2017-10-11 17:13:33 -06:00
										 |  |  |       return config.save(changer); | 
					
						
							| 
									
										
										
										
											2017-10-17 16:16:57 -06:00
										 |  |  |     }).then(function (newConf) { | 
					
						
							|  |  |  |       return newConf.domains; | 
					
						
							| 
									
										
										
										
											2017-10-11 17:13:33 -06:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2017-10-17 16:16:57 -06:00
										 |  |  |     handlePromise(req, res, promise); | 
					
						
							| 
									
										
										
										
											2017-10-11 17:13:33 -06:00
										 |  |  |   }; | 
					
						
							|  |  |  |   config.restful.updateDomain = function (req, res) { | 
					
						
							| 
									
										
										
										
											2017-10-17 16:16:57 -06:00
										 |  |  |     var promise = deps.PromiseA.resolve().then(function () { | 
					
						
							| 
									
										
										
										
											2017-10-11 17:13:33 -06:00
										 |  |  |       if (req.body.modules) { | 
					
						
							|  |  |  |         throw Object.assign(new Error('do not add modules with this route'), {statusCode: 400}); | 
					
						
							| 
									
										
										
										
											2017-10-10 11:08:19 -06:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-11 17:13:33 -06:00
										 |  |  |       var changer = new (require('./config').ConfigChanger)(conf); | 
					
						
							|  |  |  |       changer.domains.update(req.params.domId, req.body); | 
					
						
							|  |  |  |       return config.save(changer); | 
					
						
							| 
									
										
										
										
											2017-10-17 16:16:57 -06:00
										 |  |  |     }).then(function (newConf) { | 
					
						
							|  |  |  |       return newConf.domains.find(function (dom) { | 
					
						
							|  |  |  |         return dom.id === req.params.domId; | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2017-10-11 17:13:33 -06:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2017-10-17 16:16:57 -06:00
										 |  |  |     handlePromise(req, res, promise); | 
					
						
							| 
									
										
										
										
											2017-10-11 17:13:33 -06:00
										 |  |  |   }; | 
					
						
							|  |  |  |   config.restful.removeDomain = function (req, res) { | 
					
						
							| 
									
										
										
										
											2017-10-17 16:16:57 -06:00
										 |  |  |     var promise = deps.PromiseA.resolve().then(function () { | 
					
						
							| 
									
										
										
										
											2017-10-11 17:13:33 -06:00
										 |  |  |       var changer = new (require('./config').ConfigChanger)(conf); | 
					
						
							|  |  |  |       changer.domains.remove(req.params.domId); | 
					
						
							|  |  |  |       return config.save(changer); | 
					
						
							| 
									
										
										
										
											2017-10-17 16:16:57 -06:00
										 |  |  |     }).then(function (newConf) { | 
					
						
							|  |  |  |       return newConf.domains; | 
					
						
							| 
									
										
										
										
											2017-10-10 11:08:19 -06:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2017-10-17 16:16:57 -06:00
										 |  |  |     handlePromise(req, res, promise); | 
					
						
							| 
									
										
										
										
											2017-10-03 19:11:49 -06:00
										 |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-17 18:36:36 -06:00
										 |  |  |   var tokens = { restful: {} }; | 
					
						
							|  |  |  |   tokens.restful.getAll = function (req, res) { | 
					
						
							|  |  |  |     handlePromise(req, res, deps.storage.tokens.all()); | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  |   tokens.restful.getOne = function (req, res) { | 
					
						
							|  |  |  |     handlePromise(req, res, deps.storage.tokens.get(req.params.id)); | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  |   tokens.restful.save = function (req, res) { | 
					
						
							|  |  |  |     handlePromise(req, res, deps.storage.tokens.save(req.body)); | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  |   tokens.restful.revoke = function (req, res) { | 
					
						
							|  |  |  |     var promise = deps.storage.tokens.remove(req.params.id).then(function (success) { | 
					
						
							|  |  |  |       return {success: success}; | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     handlePromise(req, res, promise); | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-03 19:11:49 -06:00
										 |  |  |   var app = require('express')(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Handle all of the API endpoints using the old definition style, and then we can
 | 
					
						
							|  |  |  |   // add middleware without worrying too much about the consequences to older code.
 | 
					
						
							|  |  |  |   app.use('/:name', handleOldApis); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-25 13:35:06 -06:00
										 |  |  |   // Not all routes support all of these methods, but not worth making this more specific
 | 
					
						
							|  |  |  |   app.use('/', makeCorsHandler(['GET', 'POST', 'PUT', 'DELETE']), isAuthorized, jsonParser); | 
					
						
							| 
									
										
										
										
											2017-10-03 19:11:49 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-05 18:10:59 -06:00
										 |  |  |   app.get(   '/config',                                                 config.restful.readConfig); | 
					
						
							|  |  |  |   app.get(   '/config/:group',                                          config.restful.readConfig); | 
					
						
							| 
									
										
										
										
											2017-10-11 12:18:01 -06:00
										 |  |  |   app.get(   '/config/:group/:mod(modules)/:modId?',                    config.restful.readConfig); | 
					
						
							|  |  |  |   app.get(   '/config/domains/:domId/:mod(modules)?',                   config.restful.readConfig); | 
					
						
							|  |  |  |   app.get(   '/config/domains/:domId/:mod(modules)/:modGrp/:modId?',    config.restful.readConfig); | 
					
						
							| 
									
										
										
										
											2017-10-10 11:08:19 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-11 17:13:33 -06:00
										 |  |  |   app.post(  '/config',                                       config.restful.saveBaseConfig); | 
					
						
							|  |  |  |   app.post(  '/config/:group',                                config.restful.saveBaseConfig); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   app.post(  '/config/:group/modules',                        config.restful.createModule); | 
					
						
							|  |  |  |   app.put(   '/config/:group/modules/:modId',                 config.restful.updateModule); | 
					
						
							|  |  |  |   app.delete('/config/:group/modules/:modId',                 config.restful.removeModule); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   app.post(  '/config/domains/:domId/modules/:group',         config.restful.createModule); | 
					
						
							|  |  |  |   app.put(   '/config/domains/:domId/modules/:group/:modId',  config.restful.updateModule); | 
					
						
							|  |  |  |   app.delete('/config/domains/:domId/modules/:group/:modId',  config.restful.removeModule); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   app.post(  '/config/domains',                               config.restful.createDomain); | 
					
						
							|  |  |  |   app.put(   '/config/domains/:domId',                        config.restful.updateDomain); | 
					
						
							|  |  |  |   app.delete('/config/domains/:domId',                        config.restful.removeDomain); | 
					
						
							| 
									
										
										
										
											2017-10-10 11:08:19 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-17 18:36:36 -06:00
										 |  |  |   app.get(   '/tokens',         tokens.restful.getAll); | 
					
						
							|  |  |  |   app.get(   '/tokens/:id',     tokens.restful.getOne); | 
					
						
							|  |  |  |   app.post(  '/tokens',         tokens.restful.save); | 
					
						
							|  |  |  |   app.delete('/tokens/:id',     tokens.restful.revoke); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-03 19:11:49 -06:00
										 |  |  |   return app; | 
					
						
							| 
									
										
										
										
											2017-02-28 14:55:48 -07:00
										 |  |  | }; |