Skip to content

Commit

Permalink
Merge branch 'release/1.10.0' into production
Browse files Browse the repository at this point in the history
  • Loading branch information
Raymond Feng committed Jul 16, 2014
2 parents 7e670c8 + 9125218 commit 010cc38
Show file tree
Hide file tree
Showing 18 changed files with 562 additions and 70 deletions.
33 changes: 18 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ LoopBack consists of:

For more details, see http://loopback.io/.

## LoopBack modules
## LoopBack modules

In addition to the [main LoopBack module](https://github.com/strongloop/loopback), LoopBack consists of numerous other modules that implement specific functionality,
In addition to the [main LoopBack module](https://github.com/strongloop/loopback), LoopBack consists of numerous other modules that implement specific functionality,
as illustrated below:

![LoopBack modules](https://github.com/strongloop/loopback/raw/master/docs/assets/lb-modules.png "LoopBack modules")
Expand All @@ -33,36 +33,39 @@ as illustrated below:
* [loopback-connector-mssql](https://github.com/strongloop/loopback-connector-mssql)
* [loopback-connector-postgresql](https://github.com/strongloop/loopback-connector-postgresql)
* [loopback-connector-rest](https://github.com/strongloop/loopback-connector-rest)
* [loopback-connector-soap](https://github.com/strongloop/loopback-connector-soap)
* [loopback-connector-soap](https://github.com/strongloop/loopback-connector-soap)

* Mobile services
* [loopback-push-notification](https://github.com/strongloop/loopback-push-notification)
* [loopback-storage-service](https://github.com/strongloop/loopback-storage-service)
* Mobile Components
* [loopback-component-push](https://github.com/strongloop/loopback-component-push)
* [loopback-component-storage](https://github.com/strongloop/loopback-component-storage)

* Security Components
* [loopback-component-passport](https://github.com/strongloop/loopback-component-passport)

* Clients
* [loopback-ios](https://github.com/strongloop/loopback-ios)
* [strong-remoting-ios](https://github.com/strongloop/strong-remoting-ios)
* [loopback-android](https://github.com/strongloop/loopback-android)
* [strong-remoting-android](https://github.com/strongloop/strong-remoting-android)
* [loopback-angular](https://github.com/strongloop/loopback-angular)
* [loopback-sdk-ios](https://github.com/strongloop/loopback-sdk-ios)
* [loopback-sdk-android](https://github.com/strongloop/loopback-sdk-android)
* [loopback-sdk-angular](https://github.com/strongloop/loopback-sdk-angular)
* [loopback-sdk-angular-cli](https://github.com/strongloop/loopback-sdk-angular-cli)
* [grunt-loopback-sdk-angular](https://github.com/strongloop/grunt-loopback-sdk-angular)

* Tools
* [loopback-explorer](https://github.com/strongloop/loopback-explorer)
* [loopback-workspace](https://github.com/strongloop/loopback-workspace)
* [strong-cli](https://github.com/strongloop/strong-cli)

* Examples
* [loopback-example-database](https://github.com/strongloop/loopback-example-database)
* [loopback-example-datagraph](https://github.com/strongloop/loopback-example-datagraph)
* [loopback-example-full-stack](https://github.com/strongloop/loopback-example-full-stack)
* [loopback-example-office-supplies](https://github.com/strongloop/loopback-example-office-supplies)
* [loopback-example-todo](https://github.com/strongloop/loopback-example-todo)
* [loopback-example-access-control](https://github.com/strongloop/loopback-example-access-control)
* [loopback-example-proxy](https://github.com/strongloop/loopback-example-proxy)
* [strongloop-community/loopback-example-datagraph](https://github.com/strongloop-community/loopback-example-datagraph)
* [strongloop-community/loopback-example-database](https://github.com/strongloop-community/loopback-example-database)
* [strongloop-community/loopback-examples-ios](https://github.com/strongloop-community/loopback-examples-ios)
* [strongloop-community/loopback-example-ssl](https://github.com/strongloop-community/loopback-example-ssl)
* [loopback-example-ssl](https://github.com/strongloop/loopback-example-ssl)

## Resources
## Resources

* [Documentation](http://docs.strongloop.com/display/LB/LoopBack).
* [API documentation](http://apidocs.strongloop.com/loopback).
Expand Down
Binary file modified docs/assets/lb-modules.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions lib/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -879,6 +879,13 @@ app.listen = function(cb) {

server.on('listening', function() {
self.set('port', this.address().port);
if (!self.get('url')) {
// A better default host would be `0.0.0.0`,
// but such URL is not supported by Windows
var host = self.get('host') || '127.0.0.1';
var url = 'http://' + host + ':' + self.get('port') + '/';
self.set('url', url);
}
});

var useAppConfig =
Expand Down
2 changes: 1 addition & 1 deletion lib/connectors/mail.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ module.exports = MailConnector;
*/

function MailConnector(settings) {
assert(typeof settings === 'object', 'cannot initiaze MailConnector without a settings object');
assert(typeof settings === 'object', 'cannot initialize MailConnector without a settings object');
var transports = settings.transports || [];
this.transportsIndex = {};
this.transports = [];
Expand Down
6 changes: 3 additions & 3 deletions lib/middleware/token.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ module.exports = token;
* Check for an access token in cookies, headers, and query string parameters.
* This function always checks for the following:
*
* - `access_token`
* - `X-Access-Token`
* - `authorization`
* - `access_token` (params only)
* - `X-Access-Token` (headers only)
* - `authorization` (headers and cookies)
*
* It checks for these values in cookies, headers, and query string parameters _in addition_ to the items
* specified in the options parameter.
Expand Down
10 changes: 9 additions & 1 deletion lib/models/access-token.js
Original file line number Diff line number Diff line change
Expand Up @@ -209,12 +209,20 @@ function tokenIdForRequest(req, options) {
id = req.header(headers[i]);

if(typeof id === 'string') {
// Add support for oAuth 2.0 bearer token
// http://tools.ietf.org/html/rfc6750
if (id.indexOf('Bearer ') === 0) {
id = id.substring(7);
// Decode from base64
var buf = new Buffer(id, 'base64');
id = buf.toString('utf8');
}
return id;
}
}

if(req.signedCookies) {
for(i = 0, length = headers.length; i < length; i++) {
for(i = 0, length = cookies.length; i < length; i++) {
id = req.signedCookies[cookies[i]];

if(typeof id === 'string') {
Expand Down
26 changes: 22 additions & 4 deletions lib/models/data-model.js
Original file line number Diff line number Diff line change
Expand Up @@ -221,24 +221,42 @@ setRemoting(DataModel.findOne, {
* @param {Function} [cb] - callback called with (err)
*/

DataModel.remove =
DataModel.deleteAll =
DataModel.destroyAll = function destroyAll(where, cb) {
throwNotAttached(this.modelName, 'destroyAll');
};

/**
* Alias for `destroyAll`
*/

DataModel.remove = DataModel.destroyAll;

/**
* Alias for `destroyAll`
*/
DataModel.deleteAll = DataModel.destroyAll;


/**
* Destroy a record by id
* @param {*} id The id value
* @param {Function} cb - callback called with (err)
*/

DataModel.removeById =
DataModel.deleteById =
DataModel.destroyById = function deleteById(id, cb) {
throwNotAttached(this.modelName, 'deleteById');
};

/**
* Alias for deleteById
*/
DataModel.deleteById = DataModel.destroyById;

/**
* Alias for deleteById
*/
DataModel.removeById = DataModel.destroyById;

// deleteById ~ remoting attributes
setRemoting(DataModel.deleteById, {
description: 'Delete a model instance by id from the data source',
Expand Down
4 changes: 1 addition & 3 deletions lib/models/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
*/
var registry = require('../registry');
var compat = require('../compat');
var ModelBuilder = require('loopback-datasource-juggler').ModelBuilder;
var modeler = new ModelBuilder();
var assert = require('assert');

/**
Expand All @@ -14,7 +12,7 @@ var assert = require('assert');
* @param {Object} data
*/

var Model = module.exports = modeler.define('Model');
var Model = module.exports = registry.modelBuilder.define('Model');

Model.shared = true;

Expand Down
33 changes: 20 additions & 13 deletions lib/models/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,11 @@ var properties = {
realm: {type: String},
username: {type: String},
password: {type: String, required: true},
credentials: Object, // deprecated, to be removed in 2.x
challenges: Object, // deprecated, to be removed in 2.x
email: {type: String, required: true},
emailVerified: Boolean,
verificationToken: String,

credentials: [
'UserCredential' // User credentials, private or public, such as private/public keys, Kerberos tickets, oAuth tokens, facebook, google, github ids
],
challenges: [
'Challenge' // Security questions/answers
],
// https://en.wikipedia.org/wiki/Multi-factor_authentication
/*
factors: [
'AuthenticationFactor'
],
*/
status: String,
created: Date,
lastUpdated: Date
Expand Down Expand Up @@ -186,6 +175,15 @@ User.login = function (credentials, include, fn) {
debug('An error is reported from User.findOne: %j', err);
fn(defaultError);
} else if(user) {
if (self.settings.emailVerificationRequired) {
if (!user.emailVerified) {
// Fail to log in if email verification is not done yet
debug('User email has not been verified');
err = new Error('login failed as the email has not been verified');
err.statusCode = 401;
return fn(err);
}
}
user.hasPassword(credentials.password, function(err, isMatch) {
if(err) {
debug('An error is reported from User.hasPassword: %j', err);
Expand Down Expand Up @@ -441,6 +439,15 @@ User.setup = function () {
this.$password = bcrypt.hashSync(plain, salt);
}

// Make sure emailVerified is not set by creation
UserModel.beforeRemote('create', function(ctx, user, next) {
var body = ctx.req.body;
if (body && body.emailVerified) {
body.emailVerified = false;
}
next();
});

loopback.remoteMethod(
UserModel.login,
{
Expand Down
21 changes: 14 additions & 7 deletions lib/registry.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,16 @@

var assert = require('assert');
var extend = require('util')._extend;
var DataSource = require('loopback-datasource-juggler').DataSource;
var juggler = require('loopback-datasource-juggler');
var DataSource = juggler.DataSource;
var ModelBuilder = juggler.ModelBuilder;

var registry = module.exports;

registry.defaultDataSources = {};

registry.modelBuilder = new ModelBuilder();

/**
* Create a named vanilla JavaScript class constructor with an attached
* set of properties and options.
Expand Down Expand Up @@ -179,7 +183,7 @@ registry.configureModel = function(ModelCtor, config) {
* @header loopback.getModel(modelName)
*/
registry.getModel = function(modelName) {
return this.Model.modelBuilder.models[modelName];
return this.modelBuilder.models[modelName];
};

/**
Expand All @@ -194,7 +198,7 @@ registry.getModel = function(modelName) {
registry.getModelByType = function(modelType) {
assert(typeof modelType === 'function',
'The model type must be a constructor');
var models = this.Model.modelBuilder.models;
var models = this.modelBuilder.models;
for(var m in models) {
if(models[m].prototype instanceof modelType) {
return models[m];
Expand All @@ -216,10 +220,10 @@ registry.getModelByType = function(modelType) {
*/

registry.createDataSource = function (name, options) {
var loopback = this;
var ds = new DataSource(name, options, loopback.Model.modelBuilder);
var self = this;
var ds = new DataSource(name, options, self.modelBuilder);
ds.createModel = function (name, properties, settings) {
var ModelCtor = loopback.createModel(name, properties, settings);
var ModelCtor = self.createModel(name, properties, settings);
ModelCtor.attachTo(ds);
return ModelCtor;
};
Expand Down Expand Up @@ -293,7 +297,7 @@ registry.getDefaultDataSourceForType = function(type) {
*/

registry.autoAttach = function() {
var models = this.Model.modelBuilder.models;
var models = this.modelBuilder.models;
assert.equal(typeof models, 'object', 'Cannot autoAttach without a models object');

Object.keys(models).forEach(function(modelName) {
Expand Down Expand Up @@ -327,3 +331,6 @@ registry.DataSource = DataSource;

registry.Model = require('./models/model');
registry.DataModel = require('./models/data-model');

// Set the default model base class. This is done after the Model class is defined.
registry.modelBuilder.defaultModelBaseClass = registry.Model;
32 changes: 15 additions & 17 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,36 +26,36 @@
"mobile",
"mBaaS"
],
"version": "1.9.1",
"version": "1.10.0",
"scripts": {
"test": "mocha -R spec"
},
"dependencies": {
"debug": "~1.0.2",
"express": "~3.5.0",
"strong-remoting": "~1.5.0",
"inflection": "~1.3.7",
"nodemailer": "~0.7.0",
"async": "~0.9.0",
"bcryptjs": "~2.0.1",
"debug": "~1.0.3",
"ejs": "~1.0.0",
"bcryptjs": "~1.0.3",
"underscore.string": "~2.3.3",
"underscore": "~1.6.0",
"express": "3.x",
"inflection": "~1.3.8",
"nodemailer": "~0.7.1",
"strong-remoting": "~1.5.1",
"uid2": "0.0.3",
"async": "~0.9.0"
"underscore": "~1.6.0",
"underscore.string": "~2.3.3"
},
"peerDependencies": {
"loopback-datasource-juggler": ">=1.4.0 <1.7.0"
"loopback-datasource-juggler": "^1.7.0"
},
"devDependencies": {
"loopback-datasource-juggler": ">=1.4.0 <1.7.0",
"loopback-datasource-juggler": "^1.7.0",
"mocha": "~1.20.1",
"strong-task-emitter": "0.0.x",
"supertest": "~0.13.0",
"chai": "~1.9.1",
"loopback-testing": "~0.2.0",
"browserify": "~4.1.11",
"browserify": "~4.2.1",
"grunt": "~0.4.5",
"grunt-browserify": "~2.1.0",
"grunt-browserify": "~2.1.3",
"grunt-contrib-uglify": "~0.5.0",
"grunt-contrib-jshint": "~0.10.0",
"grunt-contrib-watch": "~0.6.1",
Expand All @@ -64,7 +64,7 @@
"karma-firefox-launcher": "~0.1.3",
"karma-html2js-preprocessor": "~0.1.0",
"karma-phantomjs-launcher": "~0.1.4",
"karma": "~0.12.16",
"karma": "~0.12.17",
"karma-browserify": "~0.2.1",
"karma-mocha": "~0.1.4",
"grunt-karma": "~0.8.3"
Expand All @@ -76,8 +76,6 @@
"browser": {
"express": "./lib/browser-express.js",
"connect": false,
"passport": false,
"passport-local": false,
"nodemailer": false
},
"license": {
Expand Down
Loading

0 comments on commit 010cc38

Please sign in to comment.