forked from coolaj86/walnut.js
		
	(still) half-baked oauth3 layer
This commit is contained in:
		
							parent
							
								
									2b432cb36d
								
							
						
					
					
						commit
						75b9a0e2b3
					
				| @ -1,9 +1,155 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
| 
 | 
 | ||||||
| var PromiseA = require('bluebird'); | var PromiseA = require('bluebird'); | ||||||
| var scoper = require('app-scoped-ids'); |  | ||||||
| 
 | 
 | ||||||
| module.exports.inject = function (app) { | 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]; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   //var jwsUtils = require('./lib/jws-utils').create(signer);
 |   //var jwsUtils = require('./lib/jws-utils').create(signer);
 | ||||||
|   var CORS = require('connect-cors'); |   var CORS = require('connect-cors'); | ||||||
|   var cors = CORS({ credentials: true, headers: [ |   var cors = CORS({ credentials: true, headers: [ | ||||||
| @ -67,38 +213,7 @@ module.exports.inject = function (app) { | |||||||
|     return PromiseA.resolve(token); |     return PromiseA.resolve(token); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   function getToken(req, res, next) { |   function getClient(req, token, priv, Controllers) { | ||||||
|     req.oauth3 = {}; |  | ||||||
| 
 |  | ||||||
|     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; |  | ||||||
| 
 |  | ||||||
|       next(); |  | ||||||
|     }); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   function getClient(req, token, priv) { |  | ||||||
|     if (!token) { |     if (!token) { | ||||||
|       token = req.oauth3.token; |       token = req.oauth3.token; | ||||||
|     } |     } | ||||||
| @ -110,7 +225,7 @@ module.exports.inject = function (app) { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // TODO could get client directly by token.app (id of client)
 |     // TODO could get client directly by token.app (id of client)
 | ||||||
|     priv[cacheId] = ClientsCtrl.login(null, token.k).then(function (apiKey) { |     priv[cacheId] = Controllers.Clients.login(null, token.k).then(function (apiKey) { | ||||||
|       if (!apiKey) { |       if (!apiKey) { | ||||||
|         return PromiseA.reject(new Error("Client no longer valid")); |         return PromiseA.reject(new Error("Client no longer valid")); | ||||||
|       } |       } | ||||||
| @ -124,7 +239,60 @@ module.exports.inject = function (app) { | |||||||
|     return priv[cacheId]; |     return priv[cacheId]; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   function getLoginId(req, token, priv) { |   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*/) { | ||||||
|     if (!token) { |     if (!token) { | ||||||
|       token = req.oauth3.token; |       token = req.oauth3.token; | ||||||
|     } |     } | ||||||
| @ -157,7 +325,7 @@ module.exports.inject = function (app) { | |||||||
|     return priv[cacheId]; |     return priv[cacheId]; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   function getLogin(req, token, priv) { |   function getLogin(req, token, priv, Controllers) { | ||||||
|     if (!token) { |     if (!token) { | ||||||
|       token = req.oauth3.token; |       token = req.oauth3.token; | ||||||
|     } |     } | ||||||
| @ -169,7 +337,8 @@ module.exports.inject = function (app) { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     priv[cacheId] = getLoginId(req, token, priv).then(function (loginId) { |     priv[cacheId] = getLoginId(req, token, priv).then(function (loginId) { | ||||||
|       return LoginsCtrl.rawGet(loginId).then(function (login) { |       // DB.Logins.get(hashId)
 | ||||||
|  |       return Controllers.Logins.rawGet(loginId).then(function (login) { | ||||||
|         priv[cacheId] = login; |         priv[cacheId] = login; | ||||||
| 
 | 
 | ||||||
|         return login; |         return login; | ||||||
| @ -179,86 +348,60 @@ module.exports.inject = function (app) { | |||||||
|     return priv[cacheId]; |     return priv[cacheId]; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   function getAccountsByLogin(req, token, priv, loginId, decrypt) { |   function attachOauth3(req, res, next) { | ||||||
|     return getClient(req, req.oauth.token, priv).then(function (oauthClient) { |     var privs = {}; | ||||||
|       if (decrypt) { |     req.oauth3 = {}; | ||||||
|         loginId = scoper.unscope(loginId, oauthClient.secret); |  | ||||||
|       } |  | ||||||
| 
 | 
 | ||||||
|       return Db.AccountsLogins.find({ loginId: loginId }).then(function (accounts) { |     getAppScopedControllers(req.experienceId).then(function (Controllers) { | ||||||
|         return PromiseA.all(accounts.map(function (obj) { | 
 | ||||||
|           return Db.Accounts.get(obj.accountId)/*.then(function (account) { |       return parseAccessToken(req).then(function (token) { | ||||||
|             account.appScopedId = weakCipher(oauthClient.secret, account.id); |         if (!token) { | ||||||
|             return account; |           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); | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         next(); | ||||||
|       }); |       }); | ||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   function getAccountsByArray(req, arr) { |  | ||||||
|     return PromiseA.all(arr.map(function (accountId) { |  | ||||||
|       return Db.Accounts.get(accountId.id || accountId); |  | ||||||
|     })); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   function getAccounts(req, token, priv) { |  | ||||||
|     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, (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, 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 promiseCredentials(req, res, next) { |  | ||||||
|     var privs = {}; |  | ||||||
| 
 |  | ||||||
|     // TODO modify prototypes?
 |  | ||||||
|     req.oauth3.getClient = function (token) { |  | ||||||
|       getClient(req, token || req.oauth3.token, privs); |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     req.oauth3.getLoginId = function (token) { |  | ||||||
|       getLoginId(req, token || req.oauth3.token, privs); |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     req.oauth3.getLogin = function (token) { |  | ||||||
|       getLogin(req, token || req.oauth3.token, privs); |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     // TODO req.oauth3.getAccountIds
 |  | ||||||
|     req.oauth3.getAccounts = function (token) { |  | ||||||
|       getAccounts(req, token || req.oauth3.token, privs); |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     next(); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   app.use('/', cors); |   app.use('/', cors); | ||||||
| 
 | 
 | ||||||
|   app.use('/', getToken); |   app.use('/', attachOauth3); | ||||||
| 
 |  | ||||||
|   app.use('/', promiseCredentials); |  | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -103,7 +103,7 @@ function loadPages(pkgConf, packagedPage, req, res, next) { | |||||||
|   handlePromise(packagedPage._promise_page); |   handlePromise(packagedPage._promise_page); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function getApi(pkgConf, pkgDeps, packagedApi) { | function getApi(conf, pkgConf, pkgDeps, packagedApi) { | ||||||
|   var PromiseA = require('bluebird'); |   var PromiseA = require('bluebird'); | ||||||
|   var path = require('path'); |   var path = require('path'); | ||||||
|   var pkgpath = path.join(pkgConf.apipath, packagedApi.id/*, (packagedApi.api.version || '')*/); |   var pkgpath = path.join(pkgConf.apipath, packagedApi.id/*, (packagedApi.api.version || '')*/); | ||||||
| @ -155,7 +155,7 @@ function getApi(pkgConf, pkgDeps, packagedApi) { | |||||||
|       packagedApi._api = require('express-lazy')(); |       packagedApi._api = require('express-lazy')(); | ||||||
|       packagedApi._api_app = myApp; |       packagedApi._api_app = myApp; | ||||||
| 
 | 
 | ||||||
|       require('./oauth3-auth').inject(packagedApi._api, pkgConf, pkgDeps); |       require('./oauth3-auth').inject(conf, packagedApi._api, pkgConf, pkgDeps); | ||||||
| 
 | 
 | ||||||
|       // DEBUG
 |       // DEBUG
 | ||||||
|       //
 |       //
 | ||||||
| @ -194,7 +194,7 @@ function getApi(pkgConf, pkgDeps, packagedApi) { | |||||||
|   }); |   }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function loadApi(pkgConf, pkgDeps, packagedApi) { | function loadApi(conf, pkgConf, pkgDeps, packagedApi) { | ||||||
|   function handlePromise(p) { |   function handlePromise(p) { | ||||||
|     return p.then(function (api) { |     return p.then(function (api) { | ||||||
|       packagedApi._api = api; |       packagedApi._api = api; | ||||||
| @ -203,7 +203,7 @@ function loadApi(pkgConf, pkgDeps, packagedApi) { | |||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   if (!packagedApi._promise_api) { |   if (!packagedApi._promise_api) { | ||||||
|     packagedApi._promise_api = getApi(pkgConf, pkgDeps, packagedApi); |     packagedApi._promise_api = getApi(conf, pkgConf, pkgDeps, packagedApi); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   return handlePromise(packagedApi._promise_api); |   return handlePromise(packagedApi._promise_api); | ||||||
| @ -274,13 +274,35 @@ function runApi(opts, router, req, res, next) { | |||||||
|     next(); |     next(); | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|   // appId means hash(api.id + host + path) - also called "experience"
 | 
 | ||||||
|   Object.defineProperty(req, 'appId', { |   // Reaching this point means that there are APIs for this pathname
 | ||||||
|  |   // it is important to identify this host + pathname (example.com/foo) as the app
 | ||||||
|  |   Object.defineProperty(req, 'experienceId', { | ||||||
|     enumerable: true |     enumerable: true | ||||||
|   , configurable: false |   , configurable: false | ||||||
|   , writable: false |   , writable: false | ||||||
|     // TODO this identifier may need to be non-deterministic as to transfer if a domain name changes but is still the "same" app
 |     // TODO this identifier may need to be non-deterministic as to transfer if a domain name changes but is still the "same" app
 | ||||||
|     // (i.e. a company name change. maybe auto vs manual register - just like oauth3?)
 |     // (i.e. a company name change. maybe auto vs manual register - just like oauth3?)
 | ||||||
|  |     // NOTE: probably best to alias the name logically
 | ||||||
|  |   , value: (req.hostname + req.pathname).replace(/\/$/, '') | ||||||
|  |   }); | ||||||
|  |   Object.defineProperty(req, 'escapedExperienceId', { | ||||||
|  |     enumerable: true | ||||||
|  |   , configurable: false | ||||||
|  |   , writable: false | ||||||
|  |     // TODO this identifier may need to be non-deterministic as to transfer if a domain name changes but is still the "same" app
 | ||||||
|  |     // (i.e. a company name change. maybe auto vs manual register - just like oauth3?)
 | ||||||
|  |     // NOTE: probably best to alias the name logically
 | ||||||
|  |   , value: req.experienceId.replace(/\//g, ':') | ||||||
|  |   }); | ||||||
|  |   // packageId should mean hash(api.id + host + path) - also called "api"
 | ||||||
|  |   Object.defineProperty(req, 'packageId', { | ||||||
|  |     enumerable: true | ||||||
|  |   , configurable: false | ||||||
|  |   , writable: false | ||||||
|  |     // TODO this identifier may need to be non-deterministic as to transfer if a domain name changes but is still the "same" app
 | ||||||
|  |     // (i.e. a company name change. maybe auto vs manual register - just like oauth3?)
 | ||||||
|  |     // NOTE: probably best to alias the name logically
 | ||||||
|   , value: packagedApi.domain.id |   , value: packagedApi.domain.id | ||||||
|   }); |   }); | ||||||
|   Object.defineProperty(req, 'appConfig', { |   Object.defineProperty(req, 'appConfig', { | ||||||
| @ -312,7 +334,7 @@ function runApi(opts, router, req, res, next) { | |||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   // console.log("[DEBUG pkgpath]", pkgConf.apipath, packagedApi.id);
 |   // console.log("[DEBUG pkgpath]", pkgConf.apipath, packagedApi.id);
 | ||||||
|   loadApi(pkgConf, pkgDeps, packagedApi).then(function (api) { |   loadApi(opts.conf, pkgConf, pkgDeps, packagedApi).then(function (api) { | ||||||
|     api(req, res, next); |     api(req, res, next); | ||||||
|   }, function (err) { |   }, function (err) { | ||||||
|     console.error('[App Promise Error]'); |     console.error('[App Promise Error]'); | ||||||
|  | |||||||
| @ -225,6 +225,7 @@ module.exports.create = function (webserver, info, state) { | |||||||
|             config: pkgConf |             config: pkgConf | ||||||
|           , deps: pkgDeps |           , deps: pkgDeps | ||||||
|           , services: Services |           , services: Services | ||||||
|  |           , conf: info.conf | ||||||
|           }, req, res, next); |           }, req, res, next); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user