| 
									
										
										
										
											2015-12-04 07:00:30 +00:00
										 |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var PromiseA = require('bluebird'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-08 00:51:48 +00:00
										 |  |  | module.exports.inject = function (conf, app, pkgConf, pkgDeps) { | 
					
						
							|  |  |  |   var scoper = require('app-scoped-ids'); | 
					
						
							|  |  |  |   var inProcessCache = {}; | 
					
						
							|  |  |  |   var createClientFactory = require('sqlite3-cluster/client').createClientFactory; | 
					
						
							|  |  |  |   var dir = [ | 
					
						
							|  |  |  |     { tablename: 'codes' | 
					
						
							|  |  |  |     , idname: 'uuid' | 
					
						
							|  |  |  |     , indices: ['createdAt'] | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   , { tablename: 'logins' // coolaj86, coolaj86@gmail.com, +1-317-426-6525
 | 
					
						
							|  |  |  |     , idname: 'hashId' | 
					
						
							|  |  |  |     //, relations: [{ tablename: 'secrets', id: 'hashid', fk: 'loginId' }]
 | 
					
						
							|  |  |  |     , indices: ['createdAt', 'type', 'node'] | 
					
						
							|  |  |  |     //, immutable: false
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   , { tablename: 'verifications' | 
					
						
							|  |  |  |     , idname: 'hashId' // hash(date + node)
 | 
					
						
							|  |  |  |     //, relations: [{ tablename: 'secrets', id: 'hashid', fk: 'loginId' }]
 | 
					
						
							|  |  |  |     , indices: ['createdAt', 'nodeId'] | 
					
						
							|  |  |  |     //, immutable: true
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   , { tablename: 'secrets' | 
					
						
							|  |  |  |     , idname: 'hashId' // hash(node + secret)
 | 
					
						
							|  |  |  |     , indices: ['createdAt'] | 
					
						
							|  |  |  |     //, immutable: true
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   , { tablename: 'recoveryNodes' // just for 1st-party logins
 | 
					
						
							|  |  |  |     , idname: 'hashId' //
 | 
					
						
							|  |  |  |       // TODO how transmit that something should be deleted / disabled?
 | 
					
						
							|  |  |  |     , indices: ['createdAt', 'updatedAt', 'loginHash', 'recoveryNode', 'deleted'] | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     //
 | 
					
						
							|  |  |  |     // Accounts
 | 
					
						
							|  |  |  |     //
 | 
					
						
							|  |  |  |   , { tablename: 'accounts_logins' | 
					
						
							|  |  |  |     , idname: 'id' // hash(accountId + loginId)
 | 
					
						
							|  |  |  |     , indices: ['createdAt', 'revokedAt', 'loginId', 'accountId'] | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   , { tablename: 'accounts' | 
					
						
							|  |  |  |     , idname: 'id' // crypto random id? or hash(name) ?
 | 
					
						
							|  |  |  |     , unique: ['name'] | 
					
						
							|  |  |  |     , indices: ['createdAt', 'updatedAt', 'deletedAt', 'name', 'displayName'] | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     //
 | 
					
						
							|  |  |  |     // OAuth3
 | 
					
						
							|  |  |  |     //
 | 
					
						
							|  |  |  |   , { tablename: 'private_key' | 
					
						
							|  |  |  |     , idname: 'id' | 
					
						
							|  |  |  |     , indices: ['createdAt'] | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   , { tablename: 'oauth_clients' | 
					
						
							|  |  |  |     , idname: 'id' | 
					
						
							|  |  |  |     , indices: ['createdAt', 'updatedAt', 'accountId'] | 
					
						
							|  |  |  |     , hasMany: ['apiKeys'] // TODO
 | 
					
						
							|  |  |  |     , belongsTo: ['account'] | 
					
						
							|  |  |  |     , schema: function () { | 
					
						
							|  |  |  |         return { | 
					
						
							|  |  |  |           test: true | 
					
						
							|  |  |  |         , insecure: true | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   , { tablename: 'api_keys' | 
					
						
							|  |  |  |     , idname: 'id' | 
					
						
							|  |  |  |     , indices: ['createdAt', 'updatedAt', 'oauthClientId'] | 
					
						
							|  |  |  |     , belongsTo: ['oauthClient'] // TODO pluralization
 | 
					
						
							|  |  |  |     , schema: function () { | 
					
						
							|  |  |  |         return { | 
					
						
							|  |  |  |           test: true | 
					
						
							|  |  |  |         , insecure: true | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   , { tablename: 'tokens' // note that a token functions as a session
 | 
					
						
							|  |  |  |     , idname: 'id' | 
					
						
							|  |  |  |     , indices: ['createdAt', 'updatedAt', 'expiresAt', 'revokedAt', 'oauthClientId', 'loginId', 'accountId'] | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   , { tablename: 'grants' | 
					
						
							|  |  |  |     , idname: 'id' // sha256(scope + oauthClientId + (accountId || loginId))
 | 
					
						
							|  |  |  |     , indices: ['createdAt', 'updatedAt', 'oauthClientId', 'loginId', 'accountId'] | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   ]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   function getAppScopedControllers(experienceId) { | 
					
						
							|  |  |  |     if (inProcessCache[experienceId]) { | 
					
						
							|  |  |  |       return PromiseA.resolve(inProcessCache[experienceId]); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     var mq = require('masterquest'); | 
					
						
							|  |  |  |     var path = require('path'); | 
					
						
							|  |  |  |     // TODO how can we encrypt this?
 | 
					
						
							|  |  |  |     var systemFactory = createClientFactory({ | 
					
						
							|  |  |  |       // TODO only complain if the values are different
 | 
					
						
							|  |  |  |         algorithm: 'aes' | 
					
						
							|  |  |  |       , bits: 128 | 
					
						
							|  |  |  |       , mode: 'cbc' | 
					
						
							|  |  |  |       , dirname: path.join(__dirname, '..', '..', 'var') // TODO info.conf
 | 
					
						
							|  |  |  |       //, prefix: appname.replace(/\//g, ':') // 'com.example.'
 | 
					
						
							|  |  |  |       //, dbname: 'cluster'
 | 
					
						
							|  |  |  |       , suffix: '' | 
					
						
							|  |  |  |       , ext: '.sqlcipher' | 
					
						
							|  |  |  |       , sock: conf.sqlite3Sock | 
					
						
							|  |  |  |       , ipcKey: conf.ipcKey | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     var clientFactory = createClientFactory({ | 
					
						
							|  |  |  |     // TODO only complain if the values are different
 | 
					
						
							|  |  |  |       dirname: path.join(__dirname, '..', '..', 'var') // TODO info.conf
 | 
					
						
							|  |  |  |     , prefix: 'com.oauth3' // 'com.example.'
 | 
					
						
							|  |  |  |     //, dbname: 'config'
 | 
					
						
							|  |  |  |     , suffix: '' | 
					
						
							|  |  |  |     , ext: '.sqlite3' | 
					
						
							|  |  |  |     , sock: conf.sqlite3Sock | 
					
						
							|  |  |  |     , ipcKey: conf.ipcKey | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     inProcessCache[experienceId] = systemFactory.create({ | 
					
						
							|  |  |  |       init: true | 
					
						
							|  |  |  |     //, key: '00000000000000000000000000000000'
 | 
					
						
							|  |  |  |     , dbname: experienceId // 'com.example.'
 | 
					
						
							|  |  |  |     }).then(function (sqlStore) { | 
					
						
							|  |  |  |       //var db = factory.
 | 
					
						
							|  |  |  |       return mq.wrap(sqlStore, dir).then(function (models) { | 
					
						
							|  |  |  |         return require('./oauthclient-microservice/lib/sign-token').create(models.PrivateKey).init().then(function (signer) { | 
					
						
							|  |  |  |           var CodesCtrl = require('authcodes').create(models.Codes); | 
					
						
							|  |  |  |           /* models = { Logins, Verifications } */ | 
					
						
							|  |  |  |           var LoginsCtrl = require('./authentication-microservice/lib/logins').create({}, CodesCtrl, models); | 
					
						
							|  |  |  |           /* models = { ApiKeys, OauthClients } */ | 
					
						
							|  |  |  |           var ClientsCtrl = require('./oauthclient-microservice/lib/oauthclients').createController({}, models, signer); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           return { | 
					
						
							|  |  |  |             Codes: CodesCtrl | 
					
						
							|  |  |  |           , Logins: LoginsCtrl | 
					
						
							|  |  |  |           , Clients: ClientsCtrl | 
					
						
							|  |  |  |           , SqlFactory: clientFactory | 
					
						
							|  |  |  |           , models: models | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }).then(function (ctrls) { | 
					
						
							|  |  |  |       inProcessCache[experienceId] = ctrls; | 
					
						
							|  |  |  |       return ctrls; | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return inProcessCache[experienceId]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-04 07:00:30 +00:00
										 |  |  |   //var jwsUtils = require('./lib/jws-utils').create(signer);
 | 
					
						
							|  |  |  |   var CORS = require('connect-cors'); | 
					
						
							| 
									
										
										
										
											2015-12-04 08:11:34 +00:00
										 |  |  |   var cors = CORS({ credentials: true, headers: [ | 
					
						
							| 
									
										
										
										
											2015-12-04 07:00:30 +00:00
										 |  |  |     'X-Requested-With' | 
					
						
							|  |  |  |   , 'X-HTTP-Method-Override' | 
					
						
							|  |  |  |   , 'Content-Type' | 
					
						
							|  |  |  |   , 'Accept' | 
					
						
							|  |  |  |   , 'Authorization' | 
					
						
							| 
									
										
										
										
											2015-12-04 08:11:34 +00:00
										 |  |  |   ], methods: [ "GET", "POST", "PATCH", "PUT", "DELETE" ] }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Allows CORS access to API with ?access_token=
 | 
					
						
							|  |  |  |   // TODO Access-Control-Max-Age: 600
 | 
					
						
							|  |  |  |   // TODO How can we help apps handle this? token?
 | 
					
						
							|  |  |  |   // TODO allow apps to configure trustedDomains, auth, etc
 | 
					
						
							| 
									
										
										
										
											2015-12-04 07:00:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   //function weakDecipher(secret, val) { return require('./weak-crypt').weakDecipher(val, secret); }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   //
 | 
					
						
							|  |  |  |   // Generic Session / Login / Account Routes
 | 
					
						
							|  |  |  |   //
 | 
					
						
							|  |  |  |   function parseAccessToken(req, opts) { | 
					
						
							|  |  |  |     var token; | 
					
						
							|  |  |  |     var parts; | 
					
						
							|  |  |  |     var scheme; | 
					
						
							|  |  |  |     var credentials; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (req.headers && req.headers.authorization) { | 
					
						
							|  |  |  |       parts = req.headers.authorization.split(' '); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (parts.length !== 2) { | 
					
						
							|  |  |  |         return PromiseA.reject(new Error("malformed Authorization header")); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       scheme = parts[0]; | 
					
						
							|  |  |  |       credentials = parts[1]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (-1 !== (opts && opts.schemes || ['token', 'bearer']).indexOf(scheme.toLowerCase())) { | 
					
						
							|  |  |  |         token = credentials; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (req.body && req.body.access_token) { | 
					
						
							|  |  |  |       if (token) { PromiseA.reject(new Error("token exists in header and body")); } | 
					
						
							|  |  |  |       token = req.body.access_token; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // TODO disallow query with req.method === 'GET'
 | 
					
						
							|  |  |  |     // (cookies should be used for protected static assets)
 | 
					
						
							|  |  |  |     if (req.query && req.query.access_token) { | 
					
						
							|  |  |  |       if (token) { PromiseA.reject(new Error("token already exists in either header or body and also in query")); } | 
					
						
							|  |  |  |       token = req.query.access_token; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* | 
					
						
							|  |  |  |     err = new Error(challenge()); | 
					
						
							|  |  |  |     err.code = 'E_BEARER_REALM'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!token) { return PromiseA.reject(err); } | 
					
						
							|  |  |  |     */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return PromiseA.resolve(token); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-08 00:51:48 +00:00
										 |  |  |   function getClient(req, token, priv, Controllers) { | 
					
						
							| 
									
										
										
										
											2015-12-04 21:09:23 +00:00
										 |  |  |     if (!token) { | 
					
						
							|  |  |  |       token = req.oauth3.token; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     var cacheId = '_' + token.k + 'Client'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (priv[cacheId]) { | 
					
						
							|  |  |  |       return PromiseA.resolve(priv[cacheId]); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // TODO could get client directly by token.app (id of client)
 | 
					
						
							| 
									
										
										
										
											2015-12-08 00:51:48 +00:00
										 |  |  |     priv[cacheId] = Controllers.Clients.login(null, token.k).then(function (apiKey) { | 
					
						
							| 
									
										
										
										
											2015-12-04 21:09:23 +00:00
										 |  |  |       if (!apiKey) { | 
					
						
							|  |  |  |         return PromiseA.reject(new Error("Client no longer valid")); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       priv[cacheId + 'Key'] = apiKey; | 
					
						
							|  |  |  |       priv[cacheId] = apiKey.oauthClient; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return apiKey.oauthClient; | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return priv[cacheId]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-08 00:51:48 +00:00
										 |  |  |   function getAccountsByLogin(req, token, priv, Controllers, loginId, decrypt) { | 
					
						
							|  |  |  |     return getClient(req, req.oauth.token, priv).then(function (oauthClient) { | 
					
						
							|  |  |  |       if (decrypt) { | 
					
						
							|  |  |  |         loginId = scoper.unscope(loginId, oauthClient.secret); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return Controllers.models.AccountsLogins.find({ loginId: loginId }).then(function (accounts) { | 
					
						
							|  |  |  |         return PromiseA.all(accounts.map(function (obj) { | 
					
						
							|  |  |  |           return Controllers.models.Accounts.get(obj.accountId)/*.then(function (account) { | 
					
						
							|  |  |  |             account.appScopedId = weakCipher(oauthClient.secret, account.id); | 
					
						
							|  |  |  |             return account; | 
					
						
							|  |  |  |           })*/; | 
					
						
							|  |  |  |         })); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   function getAccountsByArray(req, Controllers, arr) { | 
					
						
							|  |  |  |     return PromiseA.all(arr.map(function (accountId) { | 
					
						
							|  |  |  |       return Controllers.models.Accounts.get(accountId.id || accountId); | 
					
						
							|  |  |  |     })); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   function getAccounts(req, token, priv, Controllers) { | 
					
						
							|  |  |  |     if (!token) { | 
					
						
							|  |  |  |       token = req.oauth3.token; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     var err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (priv._accounts) { | 
					
						
							|  |  |  |       return PromiseA.resolve(priv._accounts); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((req.oauth3.token.idx || req.oauth3.token.usr) && ('password' === req.oauth3.token.grt || 'login' === req.oauth3.token.as)) { | 
					
						
							|  |  |  |       priv._accounts = getAccountsByLogin(req, req.oauth3.token, priv, Controllers, (req.oauth3.token.idx || req.oauth3.token.usr), !!req.oauth3.token.idx); | 
					
						
							|  |  |  |     } else if (req.oauth3.token.axs && req.oauth3.token.axs.length || req.oauth3.token.acx) { | 
					
						
							|  |  |  |       req.oauth3._accounts = getAccountsByArray(req, Controllers, req.oauth3.token.axs && req.oauth3.token.axs.length && req.oauth3.token.axs || [req.oauth3.token.acx]); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       err = new Error("neither login nor accounts were specified"); | 
					
						
							|  |  |  |       err.code = "E_NO_AUTHZ"; | 
					
						
							|  |  |  |       req.oauth3._accounts = PromiseA.reject(err); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     req.oauth3._accounts.then(function (accounts) { | 
					
						
							|  |  |  |       req.oauth3._accounts = accounts; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return accounts; | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return req.oauth3._accounts; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   function getLoginId(req, token, priv/*, Controllers*/) { | 
					
						
							| 
									
										
										
										
											2015-12-04 21:09:23 +00:00
										 |  |  |     if (!token) { | 
					
						
							|  |  |  |       token = req.oauth3.token; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     var cacheId = '_' + token.idx + 'LoginId'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (priv[cacheId]) { | 
					
						
							|  |  |  |       return PromiseA.resolve(priv[cacheId]); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // TODO
 | 
					
						
							|  |  |  |     // this ends up defeating part of the purpose of JWT (few database calls)
 | 
					
						
							|  |  |  |     // perhaps the oauthClient secret should be sent, encrypted with a master key,
 | 
					
						
							|  |  |  |     // with the request? Or just mash the oauthClient secret with the loginId
 | 
					
						
							|  |  |  |     // and encrypt with the master key?
 | 
					
						
							|  |  |  |     priv._loginId = getClient(req, token, priv).then(function (oauthClient) { | 
					
						
							|  |  |  |       var loginId; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (token.idx) { | 
					
						
							|  |  |  |         loginId = scoper.unscope(token.idx, oauthClient.secret); | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         loginId = token.usr; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       priv[cacheId] = loginId; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return loginId; | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return priv[cacheId]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-08 00:51:48 +00:00
										 |  |  |   function getLogin(req, token, priv, Controllers) { | 
					
						
							| 
									
										
										
										
											2015-12-04 21:09:23 +00:00
										 |  |  |     if (!token) { | 
					
						
							|  |  |  |       token = req.oauth3.token; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     var cacheId = '_' + token.idx + 'Login'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (priv[cacheId]) { | 
					
						
							|  |  |  |       return PromiseA.resolve(priv[cacheId]); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     priv[cacheId] = getLoginId(req, token, priv).then(function (loginId) { | 
					
						
							| 
									
										
										
										
											2015-12-08 00:51:48 +00:00
										 |  |  |       // DB.Logins.get(hashId)
 | 
					
						
							|  |  |  |       return Controllers.Logins.rawGet(loginId).then(function (login) { | 
					
						
							| 
									
										
										
										
											2015-12-04 21:09:23 +00:00
										 |  |  |         priv[cacheId] = login; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return login; | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return priv[cacheId]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-08 00:51:48 +00:00
										 |  |  |   function attachOauth3(req, res, next) { | 
					
						
							| 
									
										
										
										
											2015-12-04 21:09:23 +00:00
										 |  |  |     var privs = {}; | 
					
						
							| 
									
										
										
										
											2015-12-08 00:51:48 +00:00
										 |  |  |     req.oauth3 = {}; | 
					
						
							| 
									
										
										
										
											2015-12-04 21:09:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-08 00:51:48 +00:00
										 |  |  |     getAppScopedControllers(req.experienceId).then(function (Controllers) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return parseAccessToken(req).then(function (token) { | 
					
						
							|  |  |  |         if (!token) { | 
					
						
							|  |  |  |           next(); | 
					
						
							|  |  |  |           return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         var jwt = require('jsonwebtoken'); | 
					
						
							|  |  |  |         var data = jwt.decode(token); | 
					
						
							|  |  |  |         var err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!data) { | 
					
						
							|  |  |  |           err = new Error('not a json web token'); | 
					
						
							|  |  |  |           err.code = 'E_NOT_JWT'; | 
					
						
							|  |  |  |           res.send({ | 
					
						
							|  |  |  |             error: err.code | 
					
						
							|  |  |  |           , error_description: err.message | 
					
						
							|  |  |  |           , error_url: 'https://oauth3.org/docs/errors#' + (err.code || 'E_UNKNOWN_EXCEPTION') | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |           // PromiseA.reject(err);
 | 
					
						
							|  |  |  |           return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         req.oauth3.token = token; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         req.oauth3.getLoginId = function (token) { | 
					
						
							|  |  |  |           getLoginId(req, token || req.oauth3.token, privs, Controllers); | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         req.oauth3.getLogin = function (token) { | 
					
						
							|  |  |  |           getLogin(req, token || req.oauth3.token, privs, Controllers); | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // TODO modify prototypes?
 | 
					
						
							|  |  |  |         req.oauth3.getClient = function (token) { | 
					
						
							|  |  |  |           getClient(req, token || req.oauth3.token, privs, Controllers); | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // TODO req.oauth3.getAccountIds
 | 
					
						
							|  |  |  |         req.oauth3.getAccounts = function (token) { | 
					
						
							|  |  |  |           getAccounts(req, token || req.oauth3.token, privs, Controllers); | 
					
						
							|  |  |  |         }; | 
					
						
							| 
									
										
										
										
											2015-12-04 21:09:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-08 00:51:48 +00:00
										 |  |  |         next(); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2015-12-04 21:09:23 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   app.use('/', cors); | 
					
						
							| 
									
										
										
										
											2015-12-04 08:11:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-08 00:51:48 +00:00
										 |  |  |   app.use('/', attachOauth3); | 
					
						
							| 
									
										
										
										
											2015-12-04 07:00:30 +00:00
										 |  |  | }; |