Merge branch 'release/1.6.2' into production
This commit is contained in:
commit
ec3535e550
|
@ -305,7 +305,9 @@ app.enableAuth = function() {
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
this.isAuthEnabled = true;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize an application from an options object or a set of JSON and JavaScript files.
|
* Initialize an application from an options object or a set of JSON and JavaScript files.
|
||||||
|
@ -319,7 +321,7 @@ app.enableAuth = function() {
|
||||||
*
|
*
|
||||||
* **Options**
|
* **Options**
|
||||||
*
|
*
|
||||||
* - `cwd` - _optional_ - the directory to use when loading JSON and JavaScript files
|
* - `appRootDir` - _optional_ - the directory to use when loading JSON and JavaScript files
|
||||||
* - `models` - _optional_ - an object containing `Model` definitions
|
* - `models` - _optional_ - an object containing `Model` definitions
|
||||||
* - `dataSources` - _optional_ - an object containing `DataSource` definitions
|
* - `dataSources` - _optional_ - an object containing `DataSource` definitions
|
||||||
*
|
*
|
||||||
|
|
|
@ -57,6 +57,11 @@ function createApplication() {
|
||||||
|
|
||||||
utils.merge(app, proto);
|
utils.merge(app, proto);
|
||||||
|
|
||||||
|
// Create a new instance of models registry per each app instance
|
||||||
|
app.models = function() {
|
||||||
|
return proto.models.apply(this, arguments);
|
||||||
|
};
|
||||||
|
|
||||||
return app;
|
return app;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -98,12 +98,13 @@ var crypto = require('crypto');
|
||||||
|
|
||||||
function generateKey(hmacKey, algorithm, encoding) {
|
function generateKey(hmacKey, algorithm, encoding) {
|
||||||
hmacKey = hmacKey || 'loopback';
|
hmacKey = hmacKey || 'loopback';
|
||||||
algorithm = algorithm || 'sha256';
|
algorithm = algorithm || 'sha1';
|
||||||
encoding = encoding || 'base64';
|
encoding = encoding || 'hex';
|
||||||
var hmac = crypto.createHmac(algorithm, hmacKey);
|
var hmac = crypto.createHmac(algorithm, hmacKey);
|
||||||
var buf = crypto.randomBytes(64);
|
var buf = crypto.randomBytes(32);
|
||||||
hmac.update(buf);
|
hmac.update(buf);
|
||||||
return hmac.digest('base64');
|
var key = hmac.digest(encoding);
|
||||||
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -121,7 +122,7 @@ var Application = loopback.createModel('Application', ApplicationSchema);
|
||||||
Application.beforeCreate = function (next) {
|
Application.beforeCreate = function (next) {
|
||||||
var app = this;
|
var app = this;
|
||||||
app.created = app.modified = new Date();
|
app.created = app.modified = new Date();
|
||||||
app.id = generateKey('id', 'sha1');
|
app.id = generateKey('id', 'md5');
|
||||||
app.clientKey = generateKey('client');
|
app.clientKey = generateKey('client');
|
||||||
app.javaScriptKey = generateKey('javaScript');
|
app.javaScriptKey = generateKey('javaScript');
|
||||||
app.restApiKey = generateKey('restApi');
|
app.restApiKey = generateKey('restApi');
|
||||||
|
@ -208,13 +209,18 @@ Application.authenticate = function (appId, key, cb) {
|
||||||
cb && cb(err, null);
|
cb && cb(err, null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var matched = null;
|
var result = null;
|
||||||
['clientKey', 'javaScriptKey', 'restApiKey', 'windowsKey', 'masterKey'].forEach(function (k) {
|
var keyNames = ['clientKey', 'javaScriptKey', 'restApiKey', 'windowsKey', 'masterKey'];
|
||||||
if (app[k] === key) {
|
for (var i = 0; i < keyNames.length; i++) {
|
||||||
matched = k;
|
if (app[keyNames[i]] === key) {
|
||||||
|
result = {
|
||||||
|
application: app,
|
||||||
|
keyType: keyNames[i]
|
||||||
|
};
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
cb && cb(null, matched);
|
cb && cb(null, result);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -117,10 +117,20 @@ Model.setup = function () {
|
||||||
/*!
|
/*!
|
||||||
* Get the reference to ACL in a lazy fashion to avoid race condition in require
|
* Get the reference to ACL in a lazy fashion to avoid race condition in require
|
||||||
*/
|
*/
|
||||||
var ACL = null;
|
var _aclModel = null;
|
||||||
function getACL() {
|
Model._ACL = function getACL(ACL) {
|
||||||
return ACL || (ACL = require('./acl').ACL);
|
if(ACL !== undefined) {
|
||||||
|
// The function is used as a setter
|
||||||
|
_aclModel = ACL;
|
||||||
}
|
}
|
||||||
|
if(_aclModel) {
|
||||||
|
return _aclModel;
|
||||||
|
}
|
||||||
|
var aclModel = require('./acl').ACL;
|
||||||
|
_aclModel = loopback.getModelByType(aclModel);
|
||||||
|
return _aclModel;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the given access token can invoke the method
|
* Check if the given access token can invoke the method
|
||||||
|
@ -137,9 +147,9 @@ function getACL() {
|
||||||
Model.checkAccess = function(token, modelId, method, callback) {
|
Model.checkAccess = function(token, modelId, method, callback) {
|
||||||
var ANONYMOUS = require('./access-token').ANONYMOUS;
|
var ANONYMOUS = require('./access-token').ANONYMOUS;
|
||||||
token = token || ANONYMOUS;
|
token = token || ANONYMOUS;
|
||||||
var ACL = getACL();
|
var aclModel = Model._ACL();
|
||||||
var methodName = 'string' === typeof method? method: method && method.name;
|
var methodName = 'string' === typeof method? method: method && method.name;
|
||||||
ACL.checkAccessForToken(token, this.modelName, modelId, methodName, callback);
|
aclModel.checkAccessForToken(token, this.modelName, modelId, methodName, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -158,7 +168,7 @@ Model._getAccessTypeForMethod = function(method) {
|
||||||
'method is a required argument and must be a RemoteMethod object'
|
'method is a required argument and must be a RemoteMethod object'
|
||||||
);
|
);
|
||||||
|
|
||||||
var ACL = getACL();
|
var ACL = Model._ACL();
|
||||||
|
|
||||||
switch(method.name) {
|
switch(method.name) {
|
||||||
case'create':
|
case'create':
|
||||||
|
|
32
package.json
32
package.json
|
@ -9,35 +9,35 @@
|
||||||
"Platform",
|
"Platform",
|
||||||
"mBaaS"
|
"mBaaS"
|
||||||
],
|
],
|
||||||
"version": "1.6.1",
|
"version": "1.6.2",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "mocha -R spec"
|
"test": "mocha -R spec"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"debug": "~0.7.2",
|
"debug": "~0.7.4",
|
||||||
"express": "~3.4.0",
|
"express": "~3.4.8",
|
||||||
"strong-remoting": "~1.2.1",
|
"strong-remoting": "~1.2.4",
|
||||||
"inflection": "~1.2.5",
|
"inflection": "~1.2.7",
|
||||||
"passport": "~0.1.17",
|
"passport": "~0.2.0",
|
||||||
"passport-local": "~0.1.6",
|
"passport-local": "~0.1.6",
|
||||||
"nodemailer": "~0.5.7",
|
"nodemailer": "~0.6.0",
|
||||||
"ejs": "~0.8.4",
|
"ejs": "~0.8.5",
|
||||||
"bcryptjs": "~0.7.10",
|
"bcryptjs": "~0.7.10",
|
||||||
"underscore.string": "~2.3.3",
|
"underscore.string": "~2.3.3",
|
||||||
"underscore": "~1.5.2",
|
"underscore": "~1.6.0",
|
||||||
"uid2": "0.0.3",
|
"uid2": "0.0.3",
|
||||||
"async": "~0.2.9"
|
"async": "~0.2.10"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"loopback-datasource-juggler": "~1.2.13"
|
"loopback-datasource-juggler": "~1.3.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"loopback-datasource-juggler": "~1.2.13",
|
"loopback-datasource-juggler": "~1.3.0",
|
||||||
"mocha": "~1.14.0",
|
"mocha": "~1.17.1",
|
||||||
"strong-task-emitter": "0.0.x",
|
"strong-task-emitter": "0.0.x",
|
||||||
"supertest": "~0.8.1",
|
"supertest": "~0.9.0",
|
||||||
"chai": "~1.8.1",
|
"chai": "~1.9.0",
|
||||||
"loopback-testing": "~0.1.0"
|
"loopback-testing": "~0.1.2"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|
|
@ -76,10 +76,17 @@ describe('app', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('app.models', function() {
|
||||||
|
it('is unique per app instance', function() {
|
||||||
|
var Color = app.model('Color', { dataSource: 'db' });
|
||||||
|
expect(app.models.Color).to.equal(Color);
|
||||||
|
var anotherApp = loopback();
|
||||||
|
expect(anotherApp.models.Color).to.equal(undefined);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('app.boot([options])', function () {
|
describe('app.boot([options])', function () {
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
var app = this.app = loopback();
|
|
||||||
|
|
||||||
app.boot({
|
app.boot({
|
||||||
app: {
|
app: {
|
||||||
port: 3000,
|
port: 3000,
|
||||||
|
@ -393,6 +400,14 @@ describe('app', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('enableAuth', function() {
|
||||||
|
it('should set app.isAuthEnabled to true', function() {
|
||||||
|
expect(app.isAuthEnabled).to.not.equal(true);
|
||||||
|
app.enableAuth();
|
||||||
|
expect(app.isAuthEnabled).to.equal(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('app.get("/", loopback.status())', function () {
|
describe('app.get("/", loopback.status())', function () {
|
||||||
it('should return the status of the application', function (done) {
|
it('should return the status of the application', function (done) {
|
||||||
var app = loopback();
|
var app = loopback();
|
||||||
|
|
|
@ -121,7 +121,8 @@ describe('Application', function () {
|
||||||
it('Authenticate with application id & clientKey', function (done) {
|
it('Authenticate with application id & clientKey', function (done) {
|
||||||
Application.authenticate(registeredApp.id, registeredApp.clientKey,
|
Application.authenticate(registeredApp.id, registeredApp.clientKey,
|
||||||
function (err, result) {
|
function (err, result) {
|
||||||
assert.equal(result, 'clientKey');
|
assert.equal(result.application.id, registeredApp.id);
|
||||||
|
assert.equal(result.keyType, 'clientKey');
|
||||||
done(err, result);
|
done(err, result);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -129,7 +130,8 @@ describe('Application', function () {
|
||||||
it('Authenticate with application id & javaScriptKey', function (done) {
|
it('Authenticate with application id & javaScriptKey', function (done) {
|
||||||
Application.authenticate(registeredApp.id, registeredApp.javaScriptKey,
|
Application.authenticate(registeredApp.id, registeredApp.javaScriptKey,
|
||||||
function (err, result) {
|
function (err, result) {
|
||||||
assert.equal(result, 'javaScriptKey');
|
assert.equal(result.application.id, registeredApp.id);
|
||||||
|
assert.equal(result.keyType, 'javaScriptKey');
|
||||||
done(err, result);
|
done(err, result);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -137,7 +139,8 @@ describe('Application', function () {
|
||||||
it('Authenticate with application id & restApiKey', function (done) {
|
it('Authenticate with application id & restApiKey', function (done) {
|
||||||
Application.authenticate(registeredApp.id, registeredApp.restApiKey,
|
Application.authenticate(registeredApp.id, registeredApp.restApiKey,
|
||||||
function (err, result) {
|
function (err, result) {
|
||||||
assert.equal(result, 'restApiKey');
|
assert.equal(result.application.id, registeredApp.id);
|
||||||
|
assert.equal(result.keyType, 'restApiKey');
|
||||||
done(err, result);
|
done(err, result);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -145,7 +148,8 @@ describe('Application', function () {
|
||||||
it('Authenticate with application id & masterKey', function (done) {
|
it('Authenticate with application id & masterKey', function (done) {
|
||||||
Application.authenticate(registeredApp.id, registeredApp.masterKey,
|
Application.authenticate(registeredApp.id, registeredApp.masterKey,
|
||||||
function (err, result) {
|
function (err, result) {
|
||||||
assert.equal(result, 'masterKey');
|
assert.equal(result.application.id, registeredApp.id);
|
||||||
|
assert.equal(result.keyType, 'masterKey');
|
||||||
done(err, result);
|
done(err, result);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -153,7 +157,8 @@ describe('Application', function () {
|
||||||
it('Authenticate with application id & windowsKey', function (done) {
|
it('Authenticate with application id & windowsKey', function (done) {
|
||||||
Application.authenticate(registeredApp.id, registeredApp.windowsKey,
|
Application.authenticate(registeredApp.id, registeredApp.windowsKey,
|
||||||
function (err, result) {
|
function (err, result) {
|
||||||
assert.equal(result, 'windowsKey');
|
assert.equal(result.application.id, registeredApp.id);
|
||||||
|
assert.equal(result.keyType, 'windowsKey');
|
||||||
done(err, result);
|
done(err, result);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -170,13 +175,14 @@ describe('Application', function () {
|
||||||
describe('Application subclass', function () {
|
describe('Application subclass', function () {
|
||||||
it('should use subclass model name', function (done) {
|
it('should use subclass model name', function (done) {
|
||||||
var MyApp = Application.extend('MyApp');
|
var MyApp = Application.extend('MyApp');
|
||||||
MyApp.attachTo(loopback.createDataSource({connector: loopback.Memory}));
|
var ds = loopback.createDataSource({connector: loopback.Memory});
|
||||||
MyApp.register('rfeng', 'MyApp2',
|
MyApp.attachTo(ds);
|
||||||
{description: 'My second mobile application'}, function (err, result) {
|
MyApp.register('rfeng', 'MyApp123',
|
||||||
|
{description: 'My 123 mobile application'}, function (err, result) {
|
||||||
var app = result;
|
var app = result;
|
||||||
assert.equal(app.owner, 'rfeng');
|
assert.equal(app.owner, 'rfeng');
|
||||||
assert.equal(app.name, 'MyApp2');
|
assert.equal(app.name, 'MyApp123');
|
||||||
assert.equal(app.description, 'My second mobile application');
|
assert.equal(app.description, 'My 123 mobile application');
|
||||||
assert(app.clientKey);
|
assert(app.clientKey);
|
||||||
assert(app.javaScriptKey);
|
assert(app.javaScriptKey);
|
||||||
assert(app.restApiKey);
|
assert(app.restApiKey);
|
||||||
|
@ -184,6 +190,8 @@ describe('Application subclass', function () {
|
||||||
assert(app.masterKey);
|
assert(app.masterKey);
|
||||||
assert(app.created);
|
assert(app.created);
|
||||||
assert(app.modified);
|
assert(app.modified);
|
||||||
|
// Remove all instances from Application model to avoid left-over data
|
||||||
|
Application.destroyAll(function () {
|
||||||
MyApp.findById(app.id, function (err, myApp) {
|
MyApp.findById(app.id, function (err, myApp) {
|
||||||
assert(!err);
|
assert(!err);
|
||||||
assert(myApp);
|
assert(myApp);
|
||||||
|
@ -197,4 +205,5 @@ describe('Application subclass', function () {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
|
@ -612,6 +612,16 @@ describe('Model', function() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('Model._getACLModel()', function() {
|
||||||
|
it('should return the subclass of ACL', function() {
|
||||||
|
var Model = require('../').Model;
|
||||||
|
var acl = ACL.extend('acl');
|
||||||
|
Model._ACL(null); // Reset the ACL class for the base model
|
||||||
|
var model = Model._ACL();
|
||||||
|
assert.equal(model, acl);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// describe('Model.hasAndBelongsToMany()', function() {
|
// describe('Model.hasAndBelongsToMany()', function() {
|
||||||
// it("TODO: implement / document", function(done) {
|
// it("TODO: implement / document", function(done) {
|
||||||
// /* example -
|
// /* example -
|
||||||
|
|
|
@ -17,7 +17,7 @@ request = require('supertest');
|
||||||
loopback.User.settings.saltWorkFactor = 4;
|
loopback.User.settings.saltWorkFactor = 4;
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
app = loopback();
|
this.app = app = loopback();
|
||||||
|
|
||||||
// setup default data sources
|
// setup default data sources
|
||||||
loopback.setDefaultDataSourceForType('db', {
|
loopback.setDefaultDataSourceForType('db', {
|
||||||
|
|
Loading…
Reference in New Issue