| 
									
										
										
										
											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-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-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() { | 
					
						
							|  |  |  |     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.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return PromiseA.resolve() | 
					
						
							|  |  |  |     .then(function () { | 
					
						
							|  |  |  |       var dns = PromiseA.promisifyAll(require('dns')); | 
					
						
							|  |  |  |       var proms = testDomains.map(function (dom) { | 
					
						
							|  |  |  |         return dns.resolve6Async(dom) | 
					
						
							|  |  |  |           .catch(function (err) { | 
					
						
							|  |  |  |             if (err.code === 'ENODATA') { | 
					
						
							|  |  |  |               return dns.resolve4Async(dom); | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |               return PromiseA.reject(err); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           }) | 
					
						
							|  |  |  |           .then(function (result) { | 
					
						
							|  |  |  |             return result[0]; | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       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) { | 
					
						
							|  |  |  |         return request('https://'+dom).then(function (resp) { | 
					
						
							|  |  |  |           if (resp.statusCode >= 300 && resp.statusCode < 400) { | 
					
						
							|  |  |  |             return resp.headers.location; | 
					
						
							|  |  |  |           } else { | 
					
						
							|  |  |  |             return 'https://'+dom; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       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-03-02 00:58:45 -07:00
										 |  |  |   return { | 
					
						
							|  |  |  |     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-04-05 12:49:48 -06:00
										 |  |  |   , tunnel: function (req, res) { | 
					
						
							| 
									
										
										
										
											2017-06-09 16:33:49 -06:00
										 |  |  |       if (handleCors(req, res)) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2017-04-05 12:49:48 -06:00
										 |  |  |       isAuthorized(req, res, function () { | 
					
						
							| 
									
										
										
										
											2017-05-30 12:15:19 -06:00
										 |  |  |         if ('POST' !== req.method) { | 
					
						
							|  |  |  |           res.setHeader('Content-Type', 'application/json'); | 
					
						
							| 
									
										
										
										
											2017-06-14 10:58:56 -06:00
										 |  |  |           return deps.tunnelClients.get(req.userId).then(function (result) { | 
					
						
							| 
									
										
										
										
											2017-05-30 12:15:19 -06:00
										 |  |  |             res.end(JSON.stringify(result)); | 
					
						
							|  |  |  |           }, function (err) { | 
					
						
							| 
									
										
										
										
											2017-06-12 13:09:51 -06:00
										 |  |  |             res.statusCode = 500; | 
					
						
							| 
									
										
										
										
											2017-05-30 12:15:19 -06:00
										 |  |  |             res.end(JSON.stringify({ error: { message: err.message, code: err.code, uri: err.uri } })); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-12 13:09:51 -06:00
										 |  |  |         return deps.storage.owners.get(req.userId).then(function (session) { | 
					
						
							| 
									
										
										
										
											2017-06-23 17:22:45 -06:00
										 |  |  |           return deps.tunnelClients.start(session).then(function () { | 
					
						
							| 
									
										
										
										
											2017-06-12 13:09:51 -06:00
										 |  |  |             res.setHeader('Content-Type', 'application/json;'); | 
					
						
							|  |  |  |             res.end(JSON.stringify({ success: true })); | 
					
						
							|  |  |  |           }, function (err) { | 
					
						
							|  |  |  |             res.setHeader('Content-Type', 'application/json;'); | 
					
						
							|  |  |  |             res.statusCode = 500; | 
					
						
							|  |  |  |             res.end(JSON.stringify({ error: { message: err.message, code: err.code, uri: err.uri } })); | 
					
						
							| 
									
										
										
										
											2017-04-05 12:49:48 -06:00
										 |  |  |           }); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-03-02 00:58:45 -07:00
										 |  |  |   , config: function (req, res) { | 
					
						
							| 
									
										
										
										
											2017-06-09 16:33:49 -06:00
										 |  |  |       if (handleCors(req, res)) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2017-03-02 00:58:45 -07:00
										 |  |  |       isAuthorized(req, res, function () { | 
					
						
							|  |  |  |         if ('POST' !== req.method) { | 
					
						
							|  |  |  |           res.setHeader('Content-Type', 'application/json;'); | 
					
						
							| 
									
										
										
										
											2017-04-27 16:50:03 -06:00
										 |  |  |           res.end(JSON.stringify(deps.recase.snakeCopy(conf))); | 
					
						
							| 
									
										
										
										
											2017-03-02 00:58:45 -07:00
										 |  |  |           return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         jsonParser(req, res, function () { | 
					
						
							| 
									
										
										
										
											2017-06-09 11:18:05 -06:00
										 |  |  |           console.log('config POST body', req.body); | 
					
						
							| 
									
										
										
										
											2017-03-02 00:58:45 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-09 11:18:05 -06:00
										 |  |  |           // Since we are sending the changes to another process we don't really
 | 
					
						
							|  |  |  |           // have a good way of seeing if it worked, so always report success
 | 
					
						
							|  |  |  |           deps.storage.config.save(req.body); | 
					
						
							|  |  |  |           res.setHeader('Content-Type', 'application/json;'); | 
					
						
							|  |  |  |           res.end('{"success":true}'); | 
					
						
							| 
									
										
										
										
											2017-03-02 00:58:45 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											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-26 11:34:42 -06:00
										 |  |  |   , loopback: function (req, res) { | 
					
						
							| 
									
										
										
										
											2017-06-26 18:12:00 -06:00
										 |  |  |       if (handleCors(req, res, 'GET')) { | 
					
						
							| 
									
										
										
										
											2017-06-26 11:34:42 -06:00
										 |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       isAuthorized(req, res, function () { | 
					
						
							| 
									
										
										
										
											2017-06-27 10:39:59 -06:00
										 |  |  |         var prom; | 
					
						
							|  |  |  |         var query = require('querystring').parse(require('url').parse(req.url).query); | 
					
						
							|  |  |  |         if (query.provider) { | 
					
						
							|  |  |  |           prom = deps.loopback(query.provider); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           prom = deps.storage.owners.get(req.userId).then(function (session) { | 
					
						
							|  |  |  |             return deps.loopback(session.token.aud); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-26 11:34:42 -06:00
										 |  |  |         res.setHeader('Content-Type', 'application/json'); | 
					
						
							| 
									
										
										
										
											2017-06-27 10:39:59 -06:00
										 |  |  |         prom.then(function (result) { | 
					
						
							| 
									
										
										
										
											2017-06-26 18:12:00 -06:00
										 |  |  |           res.end(JSON.stringify(result)); | 
					
						
							| 
									
										
										
										
											2017-06-26 11:34:42 -06:00
										 |  |  |         }, function (err) { | 
					
						
							| 
									
										
										
										
											2017-06-26 18:12:00 -06:00
										 |  |  |           res.end(JSON.stringify({error: {message: err.message, code: err.code}})); | 
					
						
							| 
									
										
										
										
											2017-06-26 11:34:42 -06:00
										 |  |  |         }); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											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
										 |  |  |   }; | 
					
						
							|  |  |  | }; |