Skip to content

Commit

Permalink
Merge branch 'master' of github.com:strongloop/loopback into feature/…
Browse files Browse the repository at this point in the history
…globalize-error-messages

* 'master' of github.com:strongloop/loopback: (25 commits)
  Update strong-remoting dep
  Allow accessType per remote method
  v2.9.0
  Update juggler dep
  v2.8.8
  Fix context middleware to preserve domains
  Fix Geo test cases
  Allow User.hashPassword/validatePassword to be overridden
  Additional password reset unit tests for API and REST  - strongloop#944
  Small formatting update to have consistency with identical logic in other areas.   - strongloop#944
  Simplify the API test for invalidCredentials (removed create), move above REST calls for better grouping of tests   - strongloop#944
  Force request to send body as string, this ensures headers aren't automatically set to application/json  - strongloop#944
  Ensure error checking logic is in place for all REST calls, expand formatting for consistency with existing instances.  - strongloop#944
  Correct invalidCredentials so that it differs from validCredentialsEmailVerified, unit test now passes as desired.  - strongloop#944
  Update to demonstrate unit test is actually failing due to incorrect values of invalidCredentials  - strongloop#944
  v2.8.7
  API and REST tests added to ensure complete and valid credentials are supplied for verified error message to be returned  - tests added as suggested and fail under previous version of User model  - strongloop#931
  Require valid login credentials before verified email check.  - strongloop#931.
  Change urlNotFound.js to url-not-found.js
  Add lib/server-app.js
  ...

Conflicts:
	common/models/user.js
  • Loading branch information
greaterweb committed Jan 8, 2015
2 parents 79d6a5f + 497678e commit acec9dc
Show file tree
Hide file tree
Showing 13 changed files with 460 additions and 74 deletions.
91 changes: 70 additions & 21 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,53 @@
2015-01-07, Version 2.9.0
=========================

* Update juggler dep (Raymond Feng)

* Fix Geo test cases (Raymond Feng)

* Allow User.hashPassword/validatePassword to be overridden (Raymond Feng)


2015-01-07, Version 2.8.8
=========================

* Fix context middleware to preserve domains (Pham Anh Tuan)

* Additional password reset unit tests for API and REST - strongloop/loopback#944 (Ron Edgecomb)

* Small formatting update to have consistency with identical logic in other areas. - strongloop/loopback#944 (Ron Edgecomb)

* Simplify the API test for invalidCredentials (removed create), move above REST calls for better grouping of tests - strongloop/loopback#944 (Ron Edgecomb)

* Force request to send body as string, this ensures headers aren't automatically set to application/json - strongloop/loopback#944 (Ron Edgecomb)

* Ensure error checking logic is in place for all REST calls, expand formatting for consistency with existing instances. - strongloop/loopback#944 (Ron Edgecomb)

* Correct invalidCredentials so that it differs from validCredentialsEmailVerified, unit test now passes as desired. - strongloop/loopback#944 (Ron Edgecomb)

* Update to demonstrate unit test is actually failing due to incorrect values of invalidCredentials - strongloop/loopback#944 (Ron Edgecomb)

* fix jscs warning (Clark Wang)

* fix nestRemoting is nesting hooks from other relations (Clark Wang)


2015-01-06, Version 2.8.7
=========================

* Change urlNotFound.js to url-not-found.js (Rand McKinney)

* Add lib/server-app.js (Rand McKinney)

* package: add versioned sl-blip dependency (Ryan Graham)

* fix User.settings.ttl can't be overridden in sub model (Clark Wang)

* Fix Change.getCheckpointModel() giving new models each call (Farid Neshat)

* Update README.md (Rand McKinney)


2014-12-15, Version 2.8.6
=========================

Expand All @@ -17,19 +67,16 @@

* Fix bcrypt issues for browserify (Raymond Feng)

* Allow native bcrypt for performance (Raymond Feng)


2014-12-08, Version 2.8.3
2014-12-08, Version 2.8.4
=========================

* Allow native bcrypt for performance (Raymond Feng)


2014-12-08, Version 2.8.4
2014-12-08, Version 2.8.3
=========================

* Allow native bcrypt for performance (Raymond Feng)

* Remove unused underscore dependency (Ryan Graham)


Expand Down Expand Up @@ -1251,6 +1298,14 @@

* 2.0.0-beta1 (Ritchie Martori)

* Bump version (Raymond Feng)

* Add postgresql to the keywords (Raymond Feng)

* updated package.json with SOAP and framework keywords (altsang)

* updated package.json with keywords and updated description (Raymond Feng)

* Make app.datasources unique per app instance (Miroslav Bajtoš)

* Add RC version (Ritchie Martori)
Expand Down Expand Up @@ -1316,6 +1371,11 @@
* Add Change model (Ritchie Martori)


2014-05-27, Version 1.8.4
=========================



2014-05-27, Version 1.8.5
=========================

Expand All @@ -1327,14 +1387,8 @@

* updated package.json with keywords and updated description (Raymond Feng)


2014-05-27, Version 1.8.4
=========================

* Add more keywords (Raymond Feng)

* Bump version (Raymond Feng)

* app: flatten model config (Miroslav Bajtoš)

* Fix the test for mocha 1.19.0 (Raymond Feng)
Expand Down Expand Up @@ -1655,15 +1709,6 @@

* Improve jsdox documentation of app object (Miroslav Bajtoš)

* Make sure methods are called in the context of the calling class (Raymond Feng)

* Start to move md to jsdoc (Ritchie Martori)


2014-01-14, Version 1.5.0
=========================



2014-01-14, Version 1.5.1
=========================
Expand All @@ -1674,6 +1719,10 @@

* Start to move md to jsdoc (Ritchie Martori)


2014-01-14, Version 1.5.0
=========================

* Replace `on` with `once` in middleware examples (Miroslav Bajtoš)

* Fix incorrect transports (Ritchie Martori)
Expand Down
2 changes: 1 addition & 1 deletion common/models/change.js
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ module.exports = function(Change) {
Change.getCheckpointModel = function() {
var checkpointModel = this.Checkpoint;
if (checkpointModel) return checkpointModel;
this.checkpoint = checkpointModel = loopback.Checkpoint.extend('checkpoint');
this.Checkpoint = checkpointModel = loopback.Checkpoint.extend('checkpoint');
assert(this.dataSource, 'Cannot getCheckpointModel(): ' + this.modelName
+ ' is not attached to a dataSource');
checkpointModel.attachTo(this.dataSource);
Expand Down
23 changes: 20 additions & 3 deletions common/models/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,24 @@ module.exports = function(User) {
}
};

/*!
* Hash the plain password
*/
User.hashPassword = function(plain) {
this.validatePassword(plain);
var salt = bcrypt.genSaltSync(this.settings.saltWorkFactor || SALT_WORK_FACTOR);
return bcrypt.hashSync(plain, salt);
};

User.validatePassword = function(plain) {
if (typeof plain === 'string' && plain) {
return true;
}
var err = new Error('Invalid password: ' + plain);
err.statusCode = 422;
throw err;
};

/*!
* Setup an extended user model.
*/
Expand All @@ -469,11 +487,10 @@ module.exports = function(User) {

// max ttl
this.settings.maxTTL = this.settings.maxTTL || DEFAULT_MAX_TTL;
this.settings.ttl = DEFAULT_TTL;
this.settings.ttl = this.settings.ttl || DEFAULT_TTL;

UserModel.setter.password = function(plain) {
var salt = bcrypt.genSaltSync(this.constructor.settings.saltWorkFactor || SALT_WORK_FACTOR);
this.$password = bcrypt.hashSync(plain, salt);
this.$password = this.constructor.hashPassword(plain);
};

// Make sure emailVerified is not set by creation
Expand Down
3 changes: 2 additions & 1 deletion docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"title": "LoopBack Documentation",
"content": [
"lib/application.js",
"lib/server-app.js",
"lib/loopback.js",
"lib/registry.js",
"lib/access-context.js",
Expand All @@ -14,7 +15,7 @@
"server/middleware/static.js",
"server/middleware/status.js",
"server/middleware/token.js",
"server/middleware/urlNotFound.js",
"server/middleware/url-not-found.js",
{ "title": "Built-in models", "depth": 2 },
"common/models/access-token.js",
"common/models/acl.js",
Expand Down
46 changes: 39 additions & 7 deletions lib/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,25 @@ Model._getAccessTypeForMethod = function(method) {

var ACL = Model._ACL();

// Check the explicit setting of accessType
if (method.accessType) {
assert(method.accessType === ACL.READ ||
method.accessType === ACL.WRITE ||
method.accessType === ACL.EXECUTE, 'invalid accessType ' +
method.accessType +
'. It must be "READ", "WRITE", or "EXECUTE"');
return method.accessType;
}

// Default GET requests to READ
var verb = method.http && method.http.verb;
if (typeof verb === 'string') {
verb = verb.toUpperCase();
}
if (verb === 'GET' || verb === 'HEAD') {
return ACL.READ;
}

switch (method.name) {
case'create':
return ACL.WRITE;
Expand Down Expand Up @@ -406,6 +425,7 @@ Model.belongsToRemoting = function(relationName, relation, define) {
isStatic: false,
http: {verb: 'get', path: '/' + pathName},
accepts: {arg: 'refresh', type: 'boolean', http: {source: 'query'}},
accessType: 'READ',
description: 'Fetches belongsTo relation ' + relationName,
returns: {arg: relationName, type: modelName, root: true}
}, fn);
Expand All @@ -419,6 +439,7 @@ Model.hasOneRemoting = function(relationName, relation, define) {
http: {verb: 'get', path: '/' + pathName},
accepts: {arg: 'refresh', type: 'boolean', http: {source: 'query'}},
description: 'Fetches hasOne relation ' + relationName,
accessType: 'READ',
returns: {arg: relationName, type: relation.modelTo.modelName, root: true}
}, fn);
};
Expand Down Expand Up @@ -446,6 +467,7 @@ Model.hasManyRemoting = function(relationName, relation, define) {
description: 'Foreign key for ' + relationName, required: true,
http: {source: 'path'}},
description: 'Find a related item by id for ' + relationName,
accessType: 'READ',
returns: {arg: 'result', type: toModelName, root: true},
rest: {after: convertNullToNotFoundError}
}, findByIdFunc);
Expand All @@ -458,6 +480,7 @@ Model.hasManyRemoting = function(relationName, relation, define) {
description: 'Foreign key for ' + relationName, required: true,
http: {source: 'path'}},
description: 'Delete a related item by id for ' + relationName,
accessType: 'WRITE',
returns: []
}, destroyByIdFunc);

Expand All @@ -472,6 +495,7 @@ Model.hasManyRemoting = function(relationName, relation, define) {
{arg: 'data', type: toModelName, http: {source: 'body'}}
],
description: 'Update a related item by id for ' + relationName,
accessType: 'WRITE',
returns: {arg: 'result', type: toModelName, root: true}
}, updateByIdFunc);

Expand All @@ -492,6 +516,7 @@ Model.hasManyRemoting = function(relationName, relation, define) {
description: 'Foreign key for ' + relationName, required: true,
http: {source: 'path'}}].concat(accepts),
description: 'Add a related item by id for ' + relationName,
accessType: 'WRITE',
returns: {arg: relationName, type: modelThrough.modelName, root: true}
}, addFunc);

Expand All @@ -503,6 +528,7 @@ Model.hasManyRemoting = function(relationName, relation, define) {
description: 'Foreign key for ' + relationName, required: true,
http: {source: 'path'}},
description: 'Remove the ' + relationName + ' relation to an item by id',
accessType: 'WRITE',
returns: []
}, removeFunc);

Expand All @@ -516,6 +542,7 @@ Model.hasManyRemoting = function(relationName, relation, define) {
description: 'Foreign key for ' + relationName, required: true,
http: {source: 'path'}},
description: 'Check the existence of ' + relationName + ' relation to an item by id',
accessType: 'READ',
returns: {arg: 'exists', type: 'boolean', root: true},
rest: {
// After hook to map exists to 200/404 for HEAD
Expand Down Expand Up @@ -558,6 +585,7 @@ Model.scopeRemoting = function(scopeName, scope, define) {
http: {verb: 'get', path: '/' + pathName},
accepts: {arg: 'filter', type: 'object'},
description: 'Queries ' + scopeName + ' of ' + this.modelName + '.',
accessType: 'READ',
returns: {arg: scopeName, type: [toModelName], root: true}
});

Expand All @@ -566,20 +594,23 @@ Model.scopeRemoting = function(scopeName, scope, define) {
http: {verb: 'post', path: '/' + pathName},
accepts: {arg: 'data', type: toModelName, http: {source: 'body'}},
description: 'Creates a new instance in ' + scopeName + ' of this model.',
accessType: 'WRITE',
returns: {arg: 'data', type: toModelName, root: true}
});

define('__delete__' + scopeName, {
isStatic: isStatic,
http: {verb: 'delete', path: '/' + pathName},
description: 'Deletes all ' + scopeName + ' of this model.'
description: 'Deletes all ' + scopeName + ' of this model.',
accessType: 'WRITE'
});

define('__count__' + scopeName, {
isStatic: isStatic,
http: {verb: 'get', path: '/' + pathName + '/count'},
accepts: {arg: 'where', type: 'object', description: 'Criteria to match model instances'},
description: 'Counts ' + scopeName + ' of ' + this.modelName + '.',
accessType: 'READ',
returns: {arg: 'count', type: 'number'}
});

Expand Down Expand Up @@ -655,8 +686,9 @@ Model.nestRemoting = function(relationName, options, cb) {
opts.accepts = acceptArgs.concat(method.accepts || []);
opts.returns = [].concat(method.returns || []);
opts.description = method.description;
opts.accessType = method.accessType;
opts.rest = extend({}, method.rest || {});
opts.rest.delegateTo = method.name;
opts.rest.delegateTo = method;

opts.http = [];
var routes = [].concat(method.http || []);
Expand Down Expand Up @@ -720,18 +752,18 @@ Model.nestRemoting = function(relationName, options, cb) {

sharedClass.methods().forEach(function(method) {
var delegateTo = method.rest && method.rest.delegateTo;
if (delegateTo) {
if (delegateTo && delegateTo.ctor == relation.modelTo) {
var before = method.isStatic ? beforeListeners : beforeListeners['prototype'];
var after = method.isStatic ? afterListeners : afterListeners['prototype'];
var m = method.isStatic ? method.name : 'prototype.' + method.name;
if (before && before[delegateTo]) {
if (before && before[delegateTo.name]) {
self.beforeRemote(m, function(ctx, result, next) {
before[delegateTo]._listeners.call(null, ctx, next);
before[delegateTo.name]._listeners.call(null, ctx, next);
});
}
if (after && after[delegateTo]) {
if (after && after[delegateTo.name]) {
self.afterRemote(m, function(ctx, result, next) {
after[delegateTo]._listeners.call(null, ctx, next);
after[delegateTo.name]._listeners.call(null, ctx, next);
});
}
}
Expand Down
Loading

0 comments on commit acec9dc

Please sign in to comment.