update ddns, update oauth3
This commit is contained in:
parent
75b9a0e2b3
commit
f99ce93430
|
@ -1,90 +0,0 @@
|
||||||
#!/usr/bin/env node
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var PromiseA = require('bluebird').Promise;
|
|
||||||
var https = require('https');
|
|
||||||
var fs = PromiseA.promisifyAll(require('fs'));
|
|
||||||
|
|
||||||
module.exports.update = function (opts) {
|
|
||||||
return new PromiseA(function (resolve, reject) {
|
|
||||||
var options;
|
|
||||||
var hostname = opts.hostname || opts.updater;
|
|
||||||
var port = opts.port;
|
|
||||||
var pathname = opts.pathname;
|
|
||||||
var req;
|
|
||||||
|
|
||||||
if (!hostname) {
|
|
||||||
throw new Error('Please specify a DDNS host as opts.hostname');
|
|
||||||
}
|
|
||||||
if (!pathname) {
|
|
||||||
throw new Error('Please specify the api route as opts.pathname');
|
|
||||||
}
|
|
||||||
|
|
||||||
options = {
|
|
||||||
host: hostname
|
|
||||||
, port: port
|
|
||||||
, method: 'POST'
|
|
||||||
, headers: {
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
}
|
|
||||||
, path: pathname
|
|
||||||
//, auth: opts.auth || 'admin:secret'
|
|
||||||
};
|
|
||||||
|
|
||||||
if (opts.cacert) {
|
|
||||||
if (!Array.isArray(opts.cacert)) {
|
|
||||||
opts.cacert = [opts.cacert];
|
|
||||||
}
|
|
||||||
options.ca = opts.cacert;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opts.token || opts.jwt) {
|
|
||||||
options.headers.Authorization = 'Bearer ' + (opts.token || opts.jwt);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (false === opts.cacert) {
|
|
||||||
options.rejectUnauthorized = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
options.ca = (options.ca||[]).map(function (str) {
|
|
||||||
if ('string' === typeof str && str.length < 1000) {
|
|
||||||
str = fs.readFileAsync(str);
|
|
||||||
}
|
|
||||||
return str;
|
|
||||||
});
|
|
||||||
|
|
||||||
return PromiseA.all(options.ca).then(function (cas) {
|
|
||||||
options.ca = cas;
|
|
||||||
options.agent = new https.Agent(options);
|
|
||||||
|
|
||||||
req = https.request(options, function(res) {
|
|
||||||
var textData = '';
|
|
||||||
|
|
||||||
res.on('error', function (err) {
|
|
||||||
reject(err);
|
|
||||||
});
|
|
||||||
res.on('data', function (chunk) {
|
|
||||||
textData += chunk.toString();
|
|
||||||
// console.log(chunk.toString());
|
|
||||||
});
|
|
||||||
res.on('end', function () {
|
|
||||||
var err;
|
|
||||||
try {
|
|
||||||
resolve(JSON.parse(textData));
|
|
||||||
} catch(e) {
|
|
||||||
err = new Error("Unparsable Server Response");
|
|
||||||
err.code = 'E_INVALID_SERVER_RESPONSE';
|
|
||||||
err.data = textData;
|
|
||||||
reject(err);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
req.on('error', function (err) {
|
|
||||||
reject(err);
|
|
||||||
});
|
|
||||||
|
|
||||||
req.end(JSON.stringify(opts.ddns, null, ' '));
|
|
||||||
}, reject);
|
|
||||||
});
|
|
||||||
};
|
|
|
@ -1,6 +1,6 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var updateIp = require('../holepunch/helpers/update-ip.js').update;
|
var updateIp = require('ddns-cli').update;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @param {string[]} hostnames - A list of hostnames
|
* @param {string[]} hostnames - A list of hostnames
|
||||||
|
|
|
@ -129,55 +129,5 @@ function touch(conf, state) {
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
//var config = require('./device.json');
|
|
||||||
|
|
||||||
// require('ssl-root-cas').inject();
|
|
||||||
// TODO try SNI loopback.example.com as result of api.ipify.com with loopback token
|
|
||||||
|
|
||||||
/*
|
|
||||||
function phoneHome() {
|
|
||||||
var holepunch = require('./holepunch/beacon');
|
|
||||||
var ports;
|
|
||||||
|
|
||||||
ports = [
|
|
||||||
{ private: 65022
|
|
||||||
, public: 65022
|
|
||||||
, protocol: 'tcp'
|
|
||||||
, ttl: 0
|
|
||||||
, test: { service: 'ssh' }
|
|
||||||
, testable: false
|
|
||||||
}
|
|
||||||
, { private: 650443
|
|
||||||
, public: 650443
|
|
||||||
, protocol: 'tcp'
|
|
||||||
, ttl: 0
|
|
||||||
, test: { service: 'https' }
|
|
||||||
}
|
|
||||||
, { private: 65080
|
|
||||||
, public: 65080
|
|
||||||
, protocol: 'tcp'
|
|
||||||
, ttl: 0
|
|
||||||
, test: { service: 'http' }
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
// TODO return a middleware
|
|
||||||
holepunch.run(require('./redirects.json').reduce(function (all, redirect) {
|
|
||||||
if (!all[redirect.from.hostname]) {
|
|
||||||
all[redirect.from.hostname] = true;
|
|
||||||
all.push(redirect.from.hostname);
|
|
||||||
}
|
|
||||||
if (!all[redirect.to.hostname]) {
|
|
||||||
all[redirect.to.hostname] = true;
|
|
||||||
all.push(redirect.to.hostname);
|
|
||||||
}
|
|
||||||
|
|
||||||
return all;
|
|
||||||
}, []), ports).catch(function () {
|
|
||||||
console.error("Couldn't phone home. Oh well");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
module.exports.init = init;
|
module.exports.init = init;
|
||||||
module.exports.touch = touch;
|
module.exports.touch = touch;
|
||||||
|
|
|
@ -1,407 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var PromiseA = require('bluebird');
|
|
||||||
|
|
||||||
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 CORS = require('connect-cors');
|
|
||||||
var cors = CORS({ credentials: true, headers: [
|
|
||||||
'X-Requested-With'
|
|
||||||
, 'X-HTTP-Method-Override'
|
|
||||||
, 'Content-Type'
|
|
||||||
, 'Accept'
|
|
||||||
, 'Authorization'
|
|
||||||
], 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
|
|
||||||
|
|
||||||
//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);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getClient(req, token, priv, Controllers) {
|
|
||||||
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)
|
|
||||||
priv[cacheId] = Controllers.Clients.login(null, token.k).then(function (apiKey) {
|
|
||||||
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];
|
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
|
||||||
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];
|
|
||||||
}
|
|
||||||
|
|
||||||
function getLogin(req, token, priv, Controllers) {
|
|
||||||
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) {
|
|
||||||
// DB.Logins.get(hashId)
|
|
||||||
return Controllers.Logins.rawGet(loginId).then(function (login) {
|
|
||||||
priv[cacheId] = login;
|
|
||||||
|
|
||||||
return login;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return priv[cacheId];
|
|
||||||
}
|
|
||||||
|
|
||||||
function attachOauth3(req, res, next) {
|
|
||||||
var privs = {};
|
|
||||||
req.oauth3 = {};
|
|
||||||
|
|
||||||
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);
|
|
||||||
};
|
|
||||||
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
app.use('/', cors);
|
|
||||||
|
|
||||||
app.use('/', attachOauth3);
|
|
||||||
};
|
|
|
@ -104,7 +104,7 @@ function loadPages(pkgConf, packagedPage, req, res, next) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getApi(conf, pkgConf, pkgDeps, packagedApi) {
|
function getApi(conf, pkgConf, pkgDeps, packagedApi) {
|
||||||
var PromiseA = require('bluebird');
|
var PromiseA = pkgDeps.Promise;
|
||||||
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,9 @@ function getApi(conf, 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(conf, packagedApi._api, pkgConf, pkgDeps);
|
pkgDeps.getOauth3Controllers =
|
||||||
|
packagedApi._getOauth3Controllers = require('oauthcommon/example-oauthmodels').create(conf).getControllers;
|
||||||
|
require('oauthcommon').inject(packagedApi._getOauth3Controllers, packagedApi._api, pkgConf, pkgDeps);
|
||||||
|
|
||||||
// DEBUG
|
// DEBUG
|
||||||
//
|
//
|
||||||
|
@ -245,16 +247,18 @@ function layerItUp(pkgConf, router, req, res, next) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function runApi(opts, router, req, res, next) {
|
function runApi(opts, router, req, res, next) {
|
||||||
|
var path = require('path');
|
||||||
var pkgConf = opts.config;
|
var pkgConf = opts.config;
|
||||||
var pkgDeps = opts.deps;
|
var pkgDeps = opts.deps;
|
||||||
//var Services = opts.Services;
|
//var Services = opts.Services;
|
||||||
var packagedApi;
|
var packagedApi;
|
||||||
|
var pathname;
|
||||||
|
|
||||||
// TODO compile packagesMap
|
// TODO compile packagesMap
|
||||||
// TODO people may want to use the framework in a non-framework way (i.e. to conceal the module name)
|
// TODO people may want to use the framework in a non-framework way (i.e. to conceal the module name)
|
||||||
router.packagedApis.some(function (_packagedApi) {
|
router.packagedApis.some(function (_packagedApi) {
|
||||||
// console.log('[DEBUG _packagedApi.id]', _packagedApi.id);
|
// console.log('[DEBUG _packagedApi.id]', _packagedApi.id);
|
||||||
var pathname = router.pathname;
|
pathname = router.pathname;
|
||||||
if ('/' === pathname) {
|
if ('/' === pathname) {
|
||||||
pathname = '';
|
pathname = '';
|
||||||
}
|
}
|
||||||
|
@ -284,7 +288,7 @@ function runApi(opts, router, req, res, next) {
|
||||||
// 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
|
// NOTE: probably best to alias the name logically
|
||||||
, value: (req.hostname + req.pathname).replace(/\/$/, '')
|
, value: (path.join(req.hostname, pathname || '')).replace(/\/$/, '')
|
||||||
});
|
});
|
||||||
Object.defineProperty(req, 'escapedExperienceId', {
|
Object.defineProperty(req, 'escapedExperienceId', {
|
||||||
enumerable: true
|
enumerable: true
|
||||||
|
|
|
@ -193,6 +193,7 @@ module.exports.create = function (webserver, info, state) {
|
||||||
, Promise: PromiseA
|
, Promise: PromiseA
|
||||||
, express: express
|
, express: express
|
||||||
, app: app
|
, app: app
|
||||||
|
//, oauthmodels: require('oauthcommon/example-oauthmodels').create(info.conf)
|
||||||
};
|
};
|
||||||
var Services = require('./services-loader').create(pkgConf, {
|
var Services = require('./services-loader').create(pkgConf, {
|
||||||
memstore: memstore
|
memstore: memstore
|
||||||
|
|
|
@ -57,7 +57,7 @@
|
||||||
"cookie-session": "1.x",
|
"cookie-session": "1.x",
|
||||||
"cookie-signature": "^1.0.6",
|
"cookie-signature": "^1.0.6",
|
||||||
"crc": "^3.2.1",
|
"crc": "^3.2.1",
|
||||||
"masterquest-sqlite3": "git://github.com/coolaj86/masterquest-sqlite3.git",
|
"ddns-cli": "^1.2.1",
|
||||||
"debug": "^2.1.3",
|
"debug": "^2.1.3",
|
||||||
"depd": "^1.0.0",
|
"depd": "^1.0.0",
|
||||||
"destroy": "^1.0.3",
|
"destroy": "^1.0.3",
|
||||||
|
@ -81,6 +81,7 @@
|
||||||
"json-storage": "2.x",
|
"json-storage": "2.x",
|
||||||
"jsonwebtoken": "^5.4.0",
|
"jsonwebtoken": "^5.4.0",
|
||||||
"lodash": "2.x",
|
"lodash": "2.x",
|
||||||
|
"masterquest-sqlite3": "git://github.com/coolaj86/masterquest-sqlite3.git",
|
||||||
"media-typer": "^0.3.0",
|
"media-typer": "^0.3.0",
|
||||||
"methods": "^1.1.1",
|
"methods": "^1.1.1",
|
||||||
"mime": "^1.3.4",
|
"mime": "^1.3.4",
|
||||||
|
@ -104,7 +105,7 @@
|
||||||
"request": "2.44.0",
|
"request": "2.44.0",
|
||||||
"request-ip": "^1.1.1",
|
"request-ip": "^1.1.1",
|
||||||
"scmp": "1.x",
|
"scmp": "1.x",
|
||||||
"secret-utils": "1.x",
|
"secret-utils": "^2.0.0",
|
||||||
"semver": "^4.3.1",
|
"semver": "^4.3.1",
|
||||||
"send": "^0.12.2",
|
"send": "^0.12.2",
|
||||||
"serve-favicon": "2.x",
|
"serve-favicon": "2.x",
|
||||||
|
|
Loading…
Reference in New Issue