Merge branch 'release/1.5.1' into production
This commit is contained in:
commit
92457b64b5
|
@ -1,8 +1,9 @@
|
|||
{
|
||||
"title": "LoopBack Documentation",
|
||||
"content": [
|
||||
"docs/api.md",
|
||||
"docs/api-app.md",
|
||||
"lib/application.js",
|
||||
{"title": "Middleware", "depth": 3},
|
||||
"lib/middleware/token.js",
|
||||
"lib/models/access-token.js",
|
||||
"lib/models/access-context.js",
|
||||
"lib/models/acl.js",
|
||||
|
|
|
@ -218,8 +218,6 @@ View generated REST documentation at [http://localhost:3000/_docs](http://localh
|
|||
|
||||
LoopBack includes middleware similar to [Express / Connect middleware](http://expressjs.com/api.html#middleware).
|
||||
|
||||
|
||||
|
||||
#### loopback.token(options)
|
||||
|
||||
**Options**
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/**
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
|
@ -12,13 +12,43 @@ var DataSource = require('loopback-datasource-juggler').DataSource
|
|||
, path = require('path');
|
||||
|
||||
/**
|
||||
* The `App` object represents a Loopback application.
|
||||
*
|
||||
* The App object extends [Express](http://expressjs.com/api.html#express) and
|
||||
* supports
|
||||
* [Express / Connect middleware](http://expressjs.com/api.html#middleware). See
|
||||
* [Express documentation](http://expressjs.com/api.html) for details.
|
||||
*
|
||||
* ```js
|
||||
* var loopback = require('loopback');
|
||||
* var app = loopback();
|
||||
*
|
||||
* app.get('/', function(req, res){
|
||||
* res.send('hello world');
|
||||
* });
|
||||
*
|
||||
* app.listen(3000);
|
||||
* ```
|
||||
*
|
||||
* @class LoopBackApplication
|
||||
* @header app = loopback()
|
||||
*/
|
||||
function App() {
|
||||
// no op
|
||||
}
|
||||
|
||||
/*!
|
||||
* Export the app prototype.
|
||||
*/
|
||||
|
||||
var app = exports = module.exports = {};
|
||||
|
||||
/**
|
||||
* Create a set of remote objects.
|
||||
* Lazily load a set of [remote objects](http://apidocs.strongloop.com/strong-remoting/#remoteobjectsoptions).
|
||||
*
|
||||
* **NOTE:** Calling `app.remotes()` multiple times will only ever return a
|
||||
* single set of remote objects.
|
||||
* @returns {RemoteObjects}
|
||||
*/
|
||||
|
||||
app.remotes = function () {
|
||||
|
@ -29,7 +59,7 @@ app.remotes = function () {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/*!
|
||||
* Remove a route by reference.
|
||||
*/
|
||||
|
||||
|
@ -44,9 +74,24 @@ app.disuse = function (route) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Expose a model.
|
||||
* Define and attach a model to the app. The `Model` will be available on the
|
||||
* `app.models` object.
|
||||
*
|
||||
* @param Model {Model}
|
||||
* ```js
|
||||
* var Widget = app.model('Widget', {dataSource: 'db'});
|
||||
* Widget.create({name: 'pencil'});
|
||||
* app.models.Widget.find(function(err, widgets) {
|
||||
* console.log(widgets[0]); // => {name: 'pencil'}
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @param {String} modelName The name of the model to define
|
||||
* @options {Object} config The model's configuration
|
||||
* @property {String} dataSource The `DataSource` to attach the model to
|
||||
* @property {Object} [options] an object containing `Model` options
|
||||
* @property {Object} [properties] object defining the `Model` properties in [LoopBack Definition Language](http://docs.strongloop.com/loopback-datasource-juggler/#loopback-definition-language)
|
||||
* @end
|
||||
* @returns {ModelConstructor} the model class
|
||||
*/
|
||||
|
||||
app.model = function (Model, config) {
|
||||
|
@ -78,6 +123,9 @@ app.model = function (Model, config) {
|
|||
|
||||
/**
|
||||
* Get all exposed models.
|
||||
*
|
||||
* @header app.models() or app.models.ModelName
|
||||
* @returns {Array} a list of model classes
|
||||
*/
|
||||
|
||||
app.models = function () {
|
||||
|
@ -86,6 +134,9 @@ app.models = function () {
|
|||
|
||||
/**
|
||||
* Define a DataSource.
|
||||
*
|
||||
* @param {String} name The data source name
|
||||
* @param {Object} config The data source config
|
||||
*/
|
||||
|
||||
app.dataSource = function (name, config) {
|
||||
|
@ -121,7 +172,7 @@ app.remotes = function () {
|
|||
return this._remotes || (this._remotes = RemoteObjects.create());
|
||||
}
|
||||
|
||||
/**
|
||||
/*!
|
||||
* Enable documentation
|
||||
*/
|
||||
|
||||
|
@ -189,8 +240,81 @@ app.enableAuth = function() {
|
|||
}
|
||||
|
||||
/**
|
||||
* Initialize the app using JSON and JavaScript files.
|
||||
*
|
||||
* Initialize an application from an options object or a set of JSON and JavaScript files.
|
||||
*
|
||||
* **What happens during an app _boot_?**
|
||||
*
|
||||
* 1. **DataSources** are created from an `options.dataSources` object or `datasources.json` in the current directory
|
||||
* 2. **Models** are created from an `options.models` object or `models.json` in the current directory
|
||||
* 3. Any JavaScript files in the `./models` directory are loaded with `require()`.
|
||||
* 4. Any JavaScript files in the `./boot` directory are loaded with `require()`.
|
||||
*
|
||||
* **Options**
|
||||
*
|
||||
* - `cwd` - _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
|
||||
*
|
||||
* <a name="model-definition"></a>
|
||||
* **Model Definitions**
|
||||
*
|
||||
* The following is an example of an object containing two `Model` definitions: "location" and "inventory".
|
||||
*
|
||||
* ```js
|
||||
* {
|
||||
* "dealership": {
|
||||
* // a reference, by name, to a dataSource definition
|
||||
* "dataSource": "my-db",
|
||||
* // the options passed to Model.extend(name, properties, options)
|
||||
* "options": {
|
||||
* "relations": {
|
||||
* "cars": {
|
||||
* "type": "hasMany",
|
||||
* "model": "Car",
|
||||
* "foreignKey": "dealerId"
|
||||
* }
|
||||
* }
|
||||
* },
|
||||
* // the properties passed to Model.extend(name, properties, options)
|
||||
* "properties": {
|
||||
* "id": {"id": true},
|
||||
* "name": "String",
|
||||
* "zip": "Number",
|
||||
* "address": "String"
|
||||
* }
|
||||
* },
|
||||
* "car": {
|
||||
* "dataSource": "my-db"
|
||||
* "properties": {
|
||||
* "id": {
|
||||
* "type": "String",
|
||||
* "required": true,
|
||||
* "id": true
|
||||
* },
|
||||
* "make": {
|
||||
* "type": "String",
|
||||
* "required": true
|
||||
* },
|
||||
* "model": {
|
||||
* "type": "String",
|
||||
* "required": true
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* **Model definition properties**
|
||||
*
|
||||
* - `dataSource` - **required** - a string containing the name of the data source definition to attach the `Model` to
|
||||
* - `options` - _optional_ - an object containing `Model` options
|
||||
* - `properties` _optional_ - an object defining the `Model` properties in [LoopBack Definition Language](http://docs.strongloop.com/loopback-datasource-juggler/#loopback-definition-language)
|
||||
*
|
||||
* **DataSource definition properties**
|
||||
*
|
||||
* - `connector` - **required** - the name of the [connector](#working-with-data-sources-and-connectors)
|
||||
*
|
||||
*
|
||||
* @throws {Error} If config is not valid
|
||||
* @throws {Error} If boot fails
|
||||
*/
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/**
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
|
@ -6,12 +6,48 @@ var loopback = require('../loopback');
|
|||
var RemoteObjects = require('strong-remoting');
|
||||
var assert = require('assert');
|
||||
|
||||
/**
|
||||
/*!
|
||||
* Export the middleware.
|
||||
*/
|
||||
|
||||
module.exports = token;
|
||||
|
||||
/**
|
||||
* **Options**
|
||||
*
|
||||
* - `cookies` - An `Array` of cookie names
|
||||
* - `headers` - An `Array` of header names
|
||||
* - `params` - An `Array` of param names
|
||||
* - `model` - Specify an AccessToken class to use
|
||||
*
|
||||
* Each array is used to add additional keys to find an `accessToken` for a `request`.
|
||||
*
|
||||
* The following example illustrates how to check for an `accessToken` in a custom cookie, query string parameter
|
||||
* and header called `foo-auth`.
|
||||
*
|
||||
* ```js
|
||||
* app.use(loopback.token({
|
||||
* cookies: ['foo-auth'],
|
||||
* headers: ['foo-auth', 'X-Foo-Auth'],
|
||||
* cookies: ['foo-auth', 'foo_auth']
|
||||
* }));
|
||||
* ```
|
||||
*
|
||||
* **Defaults**
|
||||
*
|
||||
* By default the following names will be checked. These names are appended to any optional names. They will always
|
||||
* be checked, but any names specified will be checked first.
|
||||
*
|
||||
* - **access_token**
|
||||
* - **X-Access-Token**
|
||||
* - **authorization**
|
||||
* - **access_token**
|
||||
*
|
||||
* **NOTE:** The `loopback.token()` middleware will only check for [signed cookies](http://expressjs.com/api.html#req.signedCookies).
|
||||
*
|
||||
* @header loopback.token(options)
|
||||
*/
|
||||
|
||||
function token(options) {
|
||||
options = options || {};
|
||||
var TokenModel = options.model || loopback.AccessToken;
|
||||
|
|
|
@ -12,12 +12,8 @@ var Model = require('../loopback').Model
|
|||
, Role = require('./role').Role
|
||||
, ACL = require('./acl').ACL;
|
||||
|
||||
/**
|
||||
/*!
|
||||
* Default AccessToken properties.
|
||||
*
|
||||
* @property id {String} - Generated token ID
|
||||
* @property ttl {Number} - Time to live
|
||||
* @property created {Date} - When the token was created
|
||||
*/
|
||||
|
||||
var properties = {
|
||||
|
@ -30,6 +26,10 @@ var properties = {
|
|||
|
||||
/**
|
||||
* Token based authentication and access control.
|
||||
*
|
||||
* @property id {String} Generated token ID
|
||||
* @property ttl {Number} Time to live
|
||||
* @property created {Date} When the token was created
|
||||
*
|
||||
* **Default ACLs**
|
||||
*
|
||||
|
|
|
@ -151,7 +151,7 @@ Application.register = function (owner, name, options, cb) {
|
|||
props[p] = options[p];
|
||||
}
|
||||
}
|
||||
Application.create(props, cb);
|
||||
this.create(props, cb);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -176,7 +176,7 @@ Application.prototype.resetKeys = function (cb) {
|
|||
* @param {Error} err
|
||||
*/
|
||||
Application.resetKeys = function (appId, cb) {
|
||||
Application.findById(appId, function (err, app) {
|
||||
this.findById(appId, function (err, app) {
|
||||
if (err) {
|
||||
cb && cb(err, app);
|
||||
return;
|
||||
|
@ -203,7 +203,7 @@ Application.resetKeys = function (appId, cb) {
|
|||
* @param {String} matched - The matching key
|
||||
*/
|
||||
Application.authenticate = function (appId, key, cb) {
|
||||
Application.findById(appId, function (err, app) {
|
||||
this.findById(appId, function (err, app) {
|
||||
if (err || !app) {
|
||||
cb && cb(err, null);
|
||||
return;
|
||||
|
@ -220,8 +220,3 @@ Application.authenticate = function (appId, key, cb) {
|
|||
|
||||
module.exports = Application;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
"Platform",
|
||||
"mBaaS"
|
||||
],
|
||||
"version": "1.5.0",
|
||||
"version": "1.5.1",
|
||||
"scripts": {
|
||||
"test": "mocha -R spec"
|
||||
},
|
||||
|
|
|
@ -167,3 +167,34 @@ 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 app = result;
|
||||
assert.equal(app.owner, 'rfeng');
|
||||
assert.equal(app.name, 'MyApp2');
|
||||
assert.equal(app.description, 'My second mobile application');
|
||||
assert(app.clientKey);
|
||||
assert(app.javaScriptKey);
|
||||
assert(app.restApiKey);
|
||||
assert(app.windowsKey);
|
||||
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) {
|
||||
assert(!err);
|
||||
assert(myApp === null);
|
||||
done(err, myApp);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue