Merge branch 'release/1.6.2' into production
This commit is contained in:
commit
ec3535e550
|
@ -305,7 +305,9 @@ app.enableAuth = function() {
|
|||
next();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.isAuthEnabled = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize an application from an options object or a set of JSON and JavaScript files.
|
||||
|
@ -319,7 +321,7 @@ app.enableAuth = function() {
|
|||
*
|
||||
* **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
|
||||
* - `dataSources` - _optional_ - an object containing `DataSource` definitions
|
||||
*
|
||||
|
|
|
@ -57,6 +57,11 @@ function createApplication() {
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -98,12 +98,13 @@ var crypto = require('crypto');
|
|||
|
||||
function generateKey(hmacKey, algorithm, encoding) {
|
||||
hmacKey = hmacKey || 'loopback';
|
||||
algorithm = algorithm || 'sha256';
|
||||
encoding = encoding || 'base64';
|
||||
algorithm = algorithm || 'sha1';
|
||||
encoding = encoding || 'hex';
|
||||
var hmac = crypto.createHmac(algorithm, hmacKey);
|
||||
var buf = crypto.randomBytes(64);
|
||||
var buf = crypto.randomBytes(32);
|
||||
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) {
|
||||
var app = this;
|
||||
app.created = app.modified = new Date();
|
||||
app.id = generateKey('id', 'sha1');
|
||||
app.id = generateKey('id', 'md5');
|
||||
app.clientKey = generateKey('client');
|
||||
app.javaScriptKey = generateKey('javaScript');
|
||||
app.restApiKey = generateKey('restApi');
|
||||
|
@ -208,13 +209,18 @@ Application.authenticate = function (appId, key, cb) {
|
|||
cb && cb(err, null);
|
||||
return;
|
||||
}
|
||||
var matched = null;
|
||||
['clientKey', 'javaScriptKey', 'restApiKey', 'windowsKey', 'masterKey'].forEach(function (k) {
|
||||
if (app[k] === key) {
|
||||
matched = k;
|
||||
var result = null;
|
||||
var keyNames = ['clientKey', 'javaScriptKey', 'restApiKey', 'windowsKey', 'masterKey'];
|
||||
for (var i = 0; i < keyNames.length; i++) {
|
||||
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
|
||||
*/
|
||||
var ACL = null;
|
||||
function getACL() {
|
||||
return ACL || (ACL = require('./acl').ACL);
|
||||
}
|
||||
var _aclModel = null;
|
||||
Model._ACL = function getACL(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
|
||||
|
@ -137,9 +147,9 @@ function getACL() {
|
|||
Model.checkAccess = function(token, modelId, method, callback) {
|
||||
var ANONYMOUS = require('./access-token').ANONYMOUS;
|
||||
token = token || ANONYMOUS;
|
||||
var ACL = getACL();
|
||||
var aclModel = Model._ACL();
|
||||
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'
|
||||
);
|
||||
|
||||
var ACL = getACL();
|
||||
var ACL = Model._ACL();
|
||||
|
||||
switch(method.name) {
|
||||
case'create':
|
||||
|
|
32
package.json
32
package.json
|
@ -9,35 +9,35 @@
|
|||
"Platform",
|
||||
"mBaaS"
|
||||
],
|
||||
"version": "1.6.1",
|
||||
"version": "1.6.2",
|
||||
"scripts": {
|
||||
"test": "mocha -R spec"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": "~0.7.2",
|
||||
"express": "~3.4.0",
|
||||
"strong-remoting": "~1.2.1",
|
||||
"inflection": "~1.2.5",
|
||||
"passport": "~0.1.17",
|
||||
"debug": "~0.7.4",
|
||||
"express": "~3.4.8",
|
||||
"strong-remoting": "~1.2.4",
|
||||
"inflection": "~1.2.7",
|
||||
"passport": "~0.2.0",
|
||||
"passport-local": "~0.1.6",
|
||||
"nodemailer": "~0.5.7",
|
||||
"ejs": "~0.8.4",
|
||||
"nodemailer": "~0.6.0",
|
||||
"ejs": "~0.8.5",
|
||||
"bcryptjs": "~0.7.10",
|
||||
"underscore.string": "~2.3.3",
|
||||
"underscore": "~1.5.2",
|
||||
"underscore": "~1.6.0",
|
||||
"uid2": "0.0.3",
|
||||
"async": "~0.2.9"
|
||||
"async": "~0.2.10"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"loopback-datasource-juggler": "~1.2.13"
|
||||
"loopback-datasource-juggler": "~1.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"loopback-datasource-juggler": "~1.2.13",
|
||||
"mocha": "~1.14.0",
|
||||
"loopback-datasource-juggler": "~1.3.0",
|
||||
"mocha": "~1.17.1",
|
||||
"strong-task-emitter": "0.0.x",
|
||||
"supertest": "~0.8.1",
|
||||
"chai": "~1.8.1",
|
||||
"loopback-testing": "~0.1.0"
|
||||
"supertest": "~0.9.0",
|
||||
"chai": "~1.9.0",
|
||||
"loopback-testing": "~0.1.2"
|
||||
},
|
||||
"repository": {
|
||||
"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 () {
|
||||
beforeEach(function () {
|
||||
var app = this.app = loopback();
|
||||
|
||||
app.boot({
|
||||
app: {
|
||||
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 () {
|
||||
it('should return the status of the application', function (done) {
|
||||
var app = loopback();
|
||||
|
|
|
@ -121,7 +121,8 @@ describe('Application', function () {
|
|||
it('Authenticate with application id & clientKey', function (done) {
|
||||
Application.authenticate(registeredApp.id, registeredApp.clientKey,
|
||||
function (err, result) {
|
||||
assert.equal(result, 'clientKey');
|
||||
assert.equal(result.application.id, registeredApp.id);
|
||||
assert.equal(result.keyType, 'clientKey');
|
||||
done(err, result);
|
||||
});
|
||||
});
|
||||
|
@ -129,7 +130,8 @@ describe('Application', function () {
|
|||
it('Authenticate with application id & javaScriptKey', function (done) {
|
||||
Application.authenticate(registeredApp.id, registeredApp.javaScriptKey,
|
||||
function (err, result) {
|
||||
assert.equal(result, 'javaScriptKey');
|
||||
assert.equal(result.application.id, registeredApp.id);
|
||||
assert.equal(result.keyType, 'javaScriptKey');
|
||||
done(err, result);
|
||||
});
|
||||
});
|
||||
|
@ -137,7 +139,8 @@ describe('Application', function () {
|
|||
it('Authenticate with application id & restApiKey', function (done) {
|
||||
Application.authenticate(registeredApp.id, registeredApp.restApiKey,
|
||||
function (err, result) {
|
||||
assert.equal(result, 'restApiKey');
|
||||
assert.equal(result.application.id, registeredApp.id);
|
||||
assert.equal(result.keyType, 'restApiKey');
|
||||
done(err, result);
|
||||
});
|
||||
});
|
||||
|
@ -145,7 +148,8 @@ describe('Application', function () {
|
|||
it('Authenticate with application id & masterKey', function (done) {
|
||||
Application.authenticate(registeredApp.id, registeredApp.masterKey,
|
||||
function (err, result) {
|
||||
assert.equal(result, 'masterKey');
|
||||
assert.equal(result.application.id, registeredApp.id);
|
||||
assert.equal(result.keyType, 'masterKey');
|
||||
done(err, result);
|
||||
});
|
||||
});
|
||||
|
@ -153,7 +157,8 @@ describe('Application', function () {
|
|||
it('Authenticate with application id & windowsKey', function (done) {
|
||||
Application.authenticate(registeredApp.id, registeredApp.windowsKey,
|
||||
function (err, result) {
|
||||
assert.equal(result, 'windowsKey');
|
||||
assert.equal(result.application.id, registeredApp.id);
|
||||
assert.equal(result.keyType, 'windowsKey');
|
||||
done(err, result);
|
||||
});
|
||||
});
|
||||
|
@ -170,13 +175,14 @@ describe('Application', function () {
|
|||
describe('Application subclass', function () {
|
||||
it('should use subclass model name', function (done) {
|
||||
var MyApp = Application.extend('MyApp');
|
||||
MyApp.attachTo(loopback.createDataSource({connector: loopback.Memory}));
|
||||
MyApp.register('rfeng', 'MyApp2',
|
||||
{description: 'My second mobile application'}, function (err, result) {
|
||||
var ds = loopback.createDataSource({connector: loopback.Memory});
|
||||
MyApp.attachTo(ds);
|
||||
MyApp.register('rfeng', 'MyApp123',
|
||||
{description: 'My 123 mobile application'}, function (err, result) {
|
||||
var app = result;
|
||||
assert.equal(app.owner, 'rfeng');
|
||||
assert.equal(app.name, 'MyApp2');
|
||||
assert.equal(app.description, 'My second mobile application');
|
||||
assert.equal(app.name, 'MyApp123');
|
||||
assert.equal(app.description, 'My 123 mobile application');
|
||||
assert(app.clientKey);
|
||||
assert(app.javaScriptKey);
|
||||
assert(app.restApiKey);
|
||||
|
@ -184,14 +190,17 @@ describe('Application subclass', function () {
|
|||
assert(app.masterKey);
|
||||
assert(app.created);
|
||||
assert(app.modified);
|
||||
MyApp.findById(app.id, function (err, myApp) {
|
||||
assert(!err);
|
||||
assert(myApp);
|
||||
|
||||
Application.findById(app.id, function (err, myApp) {
|
||||
// Remove all instances from Application model to avoid left-over data
|
||||
Application.destroyAll(function () {
|
||||
MyApp.findById(app.id, function (err, myApp) {
|
||||
assert(!err);
|
||||
assert(myApp === null);
|
||||
done(err, myApp);
|
||||
assert(myApp);
|
||||
|
||||
Application.findById(app.id, function (err, myApp) {
|
||||
assert(!err);
|
||||
assert(myApp === null);
|
||||
done(err, myApp);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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() {
|
||||
// it("TODO: implement / document", function(done) {
|
||||
// /* example -
|
||||
|
|
|
@ -17,7 +17,7 @@ request = require('supertest');
|
|||
loopback.User.settings.saltWorkFactor = 4;
|
||||
|
||||
beforeEach(function () {
|
||||
app = loopback();
|
||||
this.app = app = loopback();
|
||||
|
||||
// setup default data sources
|
||||
loopback.setDefaultDataSourceForType('db', {
|
||||
|
|
Loading…
Reference in New Issue