models: move User LDL def into `user.json`
This commit is contained in:
parent
01d17e636a
commit
920d3be6a3
|
@ -2,107 +2,18 @@
|
||||||
* Module Dependencies.
|
* Module Dependencies.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var PersistedModel = require('../../lib/loopback').PersistedModel
|
var loopback = require('../../lib/loopback')
|
||||||
, loopback = require('../../lib/loopback')
|
|
||||||
, path = require('path')
|
, path = require('path')
|
||||||
, SALT_WORK_FACTOR = 10
|
, SALT_WORK_FACTOR = 10
|
||||||
, crypto = require('crypto')
|
, crypto = require('crypto')
|
||||||
, bcrypt = require('bcryptjs')
|
, bcrypt = require('bcryptjs')
|
||||||
, BaseAccessToken = require('./access-token')
|
|
||||||
, DEFAULT_TTL = 1209600 // 2 weeks in seconds
|
, DEFAULT_TTL = 1209600 // 2 weeks in seconds
|
||||||
, DEFAULT_RESET_PW_TTL = 15 * 60 // 15 mins in seconds
|
, DEFAULT_RESET_PW_TTL = 15 * 60 // 15 mins in seconds
|
||||||
, DEFAULT_MAX_TTL = 31556926 // 1 year in seconds
|
, DEFAULT_MAX_TTL = 31556926 // 1 year in seconds
|
||||||
, Role = require('./role').Role
|
|
||||||
, ACL = require('./acl').ACL
|
|
||||||
, assert = require('assert');
|
, assert = require('assert');
|
||||||
|
|
||||||
var debug = require('debug')('loopback:user');
|
var debug = require('debug')('loopback:user');
|
||||||
|
|
||||||
/*!
|
|
||||||
* Default User properties.
|
|
||||||
*/
|
|
||||||
|
|
||||||
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,
|
|
||||||
status: String,
|
|
||||||
created: Date,
|
|
||||||
lastUpdated: Date
|
|
||||||
};
|
|
||||||
|
|
||||||
var options = {
|
|
||||||
hidden: ['password'],
|
|
||||||
acls: [
|
|
||||||
{
|
|
||||||
principalType: ACL.ROLE,
|
|
||||||
principalId: Role.EVERYONE,
|
|
||||||
permission: ACL.DENY
|
|
||||||
},
|
|
||||||
{
|
|
||||||
principalType: ACL.ROLE,
|
|
||||||
principalId: Role.EVERYONE,
|
|
||||||
permission: ACL.ALLOW,
|
|
||||||
property: 'create'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
principalType: ACL.ROLE,
|
|
||||||
principalId: Role.OWNER,
|
|
||||||
permission: ACL.ALLOW,
|
|
||||||
property: 'deleteById'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
principalType: ACL.ROLE,
|
|
||||||
principalId: Role.EVERYONE,
|
|
||||||
permission: ACL.ALLOW,
|
|
||||||
property: "login"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
principalType: ACL.ROLE,
|
|
||||||
principalId: Role.EVERYONE,
|
|
||||||
permission: ACL.ALLOW,
|
|
||||||
property: "logout"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
principalType: ACL.ROLE,
|
|
||||||
principalId: Role.OWNER,
|
|
||||||
permission: ACL.ALLOW,
|
|
||||||
property: "findById"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
principalType: ACL.ROLE,
|
|
||||||
principalId: Role.OWNER,
|
|
||||||
permission: ACL.ALLOW,
|
|
||||||
property: "updateAttributes"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
principalType: ACL.ROLE,
|
|
||||||
principalId: Role.EVERYONE,
|
|
||||||
permission: ACL.ALLOW,
|
|
||||||
property: "confirm"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
principalType: ACL.ROLE,
|
|
||||||
principalId: Role.EVERYONE,
|
|
||||||
permission: ACL.ALLOW,
|
|
||||||
property: "resetPassword",
|
|
||||||
accessType: ACL.EXECUTE
|
|
||||||
}
|
|
||||||
],
|
|
||||||
relations: {
|
|
||||||
accessTokens: {
|
|
||||||
type: 'hasMany',
|
|
||||||
model: 'AccessToken',
|
|
||||||
foreignKey: 'userId'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extends from the built in `loopback.Model` type.
|
* Extends from the built in `loopback.Model` type.
|
||||||
*
|
*
|
||||||
|
@ -122,11 +33,11 @@ var options = {
|
||||||
* @property {Boolean} emailVerified Set when a user's email has been verified via `confirm()`
|
* @property {Boolean} emailVerified Set when a user's email has been verified via `confirm()`
|
||||||
* @property {String} verificationToken Set when `verify()` is called
|
* @property {String} verificationToken Set when `verify()` is called
|
||||||
*
|
*
|
||||||
* @class
|
* @class User
|
||||||
* @inherits {Model}
|
* @inherits {PersistedModel}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var User = module.exports = PersistedModel.extend('User', properties, options);
|
module.exports = function(User) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create access token for the logged in user. This method can be overridden to
|
* Create access token for the logged in user. This method can be overridden to
|
||||||
|
@ -150,8 +61,8 @@ User.prototype.createAccessToken = function(ttl, cb) {
|
||||||
*
|
*
|
||||||
* ```js
|
* ```js
|
||||||
* User.login({username: 'foo', password: 'bar'}, function (err, token) {
|
* User.login({username: 'foo', password: 'bar'}, function (err, token) {
|
||||||
* console.log(token.id);
|
* console.log(token.id);
|
||||||
* });
|
* });
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* @param {Object} credentials
|
* @param {Object} credentials
|
||||||
|
@ -160,7 +71,7 @@ User.prototype.createAccessToken = function(ttl, cb) {
|
||||||
* @param {AccessToken} token
|
* @param {AccessToken} token
|
||||||
*/
|
*/
|
||||||
|
|
||||||
User.login = function (credentials, include, fn) {
|
User.login = function(credentials, include, fn) {
|
||||||
var self = this;
|
var self = this;
|
||||||
if (typeof include === 'function') {
|
if (typeof include === 'function') {
|
||||||
fn = include;
|
fn = include;
|
||||||
|
@ -169,19 +80,18 @@ User.login = function (credentials, include, fn) {
|
||||||
|
|
||||||
include = (include || '');
|
include = (include || '');
|
||||||
if (Array.isArray(include)) {
|
if (Array.isArray(include)) {
|
||||||
include = include.map(function ( val ) {
|
include = include.map(function(val) {
|
||||||
return val.toLowerCase();
|
return val.toLowerCase();
|
||||||
});
|
});
|
||||||
}else {
|
} else {
|
||||||
include = include.toLowerCase();
|
include = include.toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var query = {};
|
var query = {};
|
||||||
if(credentials.email) {
|
if (credentials.email) {
|
||||||
query.email = credentials.email;
|
query.email = credentials.email;
|
||||||
} else if(credentials.username) {
|
} else if (credentials.username) {
|
||||||
query.username = credentials.username;
|
query.username = credentials.username;
|
||||||
} else {
|
} else {
|
||||||
var err = new Error('username or email is required');
|
var err = new Error('username or email is required');
|
||||||
|
@ -193,10 +103,10 @@ User.login = function (credentials, include, fn) {
|
||||||
var defaultError = new Error('login failed');
|
var defaultError = new Error('login failed');
|
||||||
defaultError.statusCode = 401;
|
defaultError.statusCode = 401;
|
||||||
|
|
||||||
if(err) {
|
if (err) {
|
||||||
debug('An error is reported from User.findOne: %j', err);
|
debug('An error is reported from User.findOne: %j', err);
|
||||||
fn(defaultError);
|
fn(defaultError);
|
||||||
} else if(user) {
|
} else if (user) {
|
||||||
if (self.settings.emailVerificationRequired) {
|
if (self.settings.emailVerificationRequired) {
|
||||||
if (!user.emailVerified) {
|
if (!user.emailVerified) {
|
||||||
// Fail to log in if email verification is not done yet
|
// Fail to log in if email verification is not done yet
|
||||||
|
@ -207,10 +117,10 @@ User.login = function (credentials, include, fn) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
user.hasPassword(credentials.password, function(err, isMatch) {
|
user.hasPassword(credentials.password, function(err, isMatch) {
|
||||||
if(err) {
|
if (err) {
|
||||||
debug('An error is reported from User.hasPassword: %j', err);
|
debug('An error is reported from User.hasPassword: %j', err);
|
||||||
fn(defaultError);
|
fn(defaultError);
|
||||||
} else if(isMatch) {
|
} else if (isMatch) {
|
||||||
user.createAccessToken(credentials.ttl, function(err, token) {
|
user.createAccessToken(credentials.ttl, function(err, token) {
|
||||||
if (err) return fn(err);
|
if (err) return fn(err);
|
||||||
if (Array.isArray(include) ? include.indexOf('user') !== -1 : include === 'user') {
|
if (Array.isArray(include) ? include.indexOf('user') !== -1 : include === 'user') {
|
||||||
|
@ -241,8 +151,8 @@ User.login = function (credentials, include, fn) {
|
||||||
*
|
*
|
||||||
* ```js
|
* ```js
|
||||||
* User.logout('asd0a9f8dsj9s0s3223mk', function (err) {
|
* User.logout('asd0a9f8dsj9s0s3223mk', function (err) {
|
||||||
* console.log(err || 'Logged out');
|
* console.log(err || 'Logged out');
|
||||||
* });
|
* });
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* @param {String} accessTokenID
|
* @param {String} accessTokenID
|
||||||
|
@ -250,11 +160,11 @@ User.login = function (credentials, include, fn) {
|
||||||
* @param {Error} err
|
* @param {Error} err
|
||||||
*/
|
*/
|
||||||
|
|
||||||
User.logout = function (tokenId, fn) {
|
User.logout = function(tokenId, fn) {
|
||||||
this.relations.accessTokens.modelTo.findById(tokenId, function (err, accessToken) {
|
this.relations.accessTokens.modelTo.findById(tokenId, function(err, accessToken) {
|
||||||
if(err) {
|
if (err) {
|
||||||
fn(err);
|
fn(err);
|
||||||
} else if(accessToken) {
|
} else if (accessToken) {
|
||||||
accessToken.destroy(fn);
|
accessToken.destroy(fn);
|
||||||
} else {
|
} else {
|
||||||
fn(new Error('could not find accessToken'));
|
fn(new Error('could not find accessToken'));
|
||||||
|
@ -269,10 +179,10 @@ User.logout = function (tokenId, fn) {
|
||||||
* @returns {Boolean}
|
* @returns {Boolean}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
User.prototype.hasPassword = function (plain, fn) {
|
User.prototype.hasPassword = function(plain, fn) {
|
||||||
if(this.password && plain) {
|
if (this.password && plain) {
|
||||||
bcrypt.compare(plain, this.password, function(err, isMatch) {
|
bcrypt.compare(plain, this.password, function(err, isMatch) {
|
||||||
if(err) return fn(err);
|
if (err) return fn(err);
|
||||||
fn(null, isMatch);
|
fn(null, isMatch);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
@ -285,11 +195,11 @@ User.prototype.hasPassword = function (plain, fn) {
|
||||||
*
|
*
|
||||||
* ```js
|
* ```js
|
||||||
* var options = {
|
* var options = {
|
||||||
* type: 'email',
|
* type: 'email',
|
||||||
* to: user.email,
|
* to: user.email,
|
||||||
* template: 'verify.ejs',
|
* template: 'verify.ejs',
|
||||||
* redirect: '/'
|
* redirect: '/'
|
||||||
* };
|
* };
|
||||||
*
|
*
|
||||||
* user.verify(options, next);
|
* user.verify(options, next);
|
||||||
* ```
|
* ```
|
||||||
|
@ -297,7 +207,7 @@ User.prototype.hasPassword = function (plain, fn) {
|
||||||
* @param {Object} options
|
* @param {Object} options
|
||||||
*/
|
*/
|
||||||
|
|
||||||
User.prototype.verify = function (options, fn) {
|
User.prototype.verify = function(options, fn) {
|
||||||
var user = this;
|
var user = this;
|
||||||
var userModel = this.constructor;
|
var userModel = this.constructor;
|
||||||
assert(typeof options === 'object', 'options required when calling user.verify()');
|
assert(typeof options === 'object', 'options required when calling user.verify()');
|
||||||
|
@ -334,12 +244,12 @@ User.prototype.verify = function (options, fn) {
|
||||||
var Email = options.mailer || this.constructor.email || loopback.getModelByType(loopback.Email);
|
var Email = options.mailer || this.constructor.email || loopback.getModelByType(loopback.Email);
|
||||||
|
|
||||||
crypto.randomBytes(64, function(err, buf) {
|
crypto.randomBytes(64, function(err, buf) {
|
||||||
if(err) {
|
if (err) {
|
||||||
fn(err);
|
fn(err);
|
||||||
} else {
|
} else {
|
||||||
user.verificationToken = buf.toString('hex');
|
user.verificationToken = buf.toString('hex');
|
||||||
user.save(function (err) {
|
user.save(function(err) {
|
||||||
if(err) {
|
if (err) {
|
||||||
fn(err);
|
fn(err);
|
||||||
} else {
|
} else {
|
||||||
sendEmail(user);
|
sendEmail(user);
|
||||||
|
@ -363,8 +273,8 @@ User.prototype.verify = function (options, fn) {
|
||||||
subject: options.subject || 'Thanks for Registering',
|
subject: options.subject || 'Thanks for Registering',
|
||||||
text: options.text,
|
text: options.text,
|
||||||
html: template(options)
|
html: template(options)
|
||||||
}, function (err, email) {
|
}, function(err, email) {
|
||||||
if(err) {
|
if (err) {
|
||||||
fn(err);
|
fn(err);
|
||||||
} else {
|
} else {
|
||||||
fn(null, {email: email, token: user.verificationToken, uid: user.id});
|
fn(null, {email: email, token: user.verificationToken, uid: user.id});
|
||||||
|
@ -383,16 +293,16 @@ User.prototype.verify = function (options, fn) {
|
||||||
* @callback {Function} callback
|
* @callback {Function} callback
|
||||||
* @param {Error} err
|
* @param {Error} err
|
||||||
*/
|
*/
|
||||||
User.confirm = function (uid, token, redirect, fn) {
|
User.confirm = function(uid, token, redirect, fn) {
|
||||||
this.findById(uid, function (err, user) {
|
this.findById(uid, function(err, user) {
|
||||||
if(err) {
|
if (err) {
|
||||||
fn(err);
|
fn(err);
|
||||||
} else {
|
} else {
|
||||||
if(user && user.verificationToken === token) {
|
if (user && user.verificationToken === token) {
|
||||||
user.verificationToken = undefined;
|
user.verificationToken = undefined;
|
||||||
user.emailVerified = true;
|
user.emailVerified = true;
|
||||||
user.save(function (err) {
|
user.save(function(err) {
|
||||||
if(err) {
|
if (err) {
|
||||||
fn(err);
|
fn(err);
|
||||||
} else {
|
} else {
|
||||||
fn();
|
fn();
|
||||||
|
@ -427,15 +337,15 @@ User.resetPassword = function(options, cb) {
|
||||||
var ttl = UserModel.settings.resetPasswordTokenTTL || DEFAULT_RESET_PW_TTL;
|
var ttl = UserModel.settings.resetPasswordTokenTTL || DEFAULT_RESET_PW_TTL;
|
||||||
|
|
||||||
options = options || {};
|
options = options || {};
|
||||||
if(typeof options.email === 'string') {
|
if (typeof options.email === 'string') {
|
||||||
UserModel.findOne({ where: {email: options.email} }, function(err, user) {
|
UserModel.findOne({ where: {email: options.email} }, function(err, user) {
|
||||||
if(err) {
|
if (err) {
|
||||||
cb(err);
|
cb(err);
|
||||||
} else if(user) {
|
} else if (user) {
|
||||||
// create a short lived access token for temp login to change password
|
// create a short lived access token for temp login to change password
|
||||||
// TODO(ritch) - eventually this should only allow password change
|
// TODO(ritch) - eventually this should only allow password change
|
||||||
user.accessTokens.create({ttl: ttl}, function(err, accessToken) {
|
user.accessTokens.create({ttl: ttl}, function(err, accessToken) {
|
||||||
if(err) {
|
if (err) {
|
||||||
cb(err);
|
cb(err);
|
||||||
} else {
|
} else {
|
||||||
cb();
|
cb();
|
||||||
|
@ -462,16 +372,16 @@ User.resetPassword = function(options, cb) {
|
||||||
* Setup an extended user model.
|
* Setup an extended user model.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
User.setup = function () {
|
User.setup = function() {
|
||||||
// We need to call the base class's setup method
|
// We need to call the base class's setup method
|
||||||
PersistedModel.setup.call(this);
|
User.base.setup.call(this);
|
||||||
var UserModel = this;
|
var UserModel = this;
|
||||||
|
|
||||||
// max ttl
|
// max ttl
|
||||||
this.settings.maxTTL = this.settings.maxTTL || DEFAULT_MAX_TTL;
|
this.settings.maxTTL = this.settings.maxTTL || DEFAULT_MAX_TTL;
|
||||||
this.settings.ttl = DEFAULT_TTL;
|
this.settings.ttl = DEFAULT_TTL;
|
||||||
|
|
||||||
UserModel.setter.password = function (plain) {
|
UserModel.setter.password = function(plain) {
|
||||||
var salt = bcrypt.genSaltSync(this.constructor.settings.saltWorkFactor || SALT_WORK_FACTOR);
|
var salt = bcrypt.genSaltSync(this.constructor.settings.saltWorkFactor || SALT_WORK_FACTOR);
|
||||||
this.$password = bcrypt.hashSync(plain, salt);
|
this.$password = bcrypt.hashSync(plain, salt);
|
||||||
}
|
}
|
||||||
|
@ -491,13 +401,11 @@ User.setup = function () {
|
||||||
description: 'Login a user with username/email and password',
|
description: 'Login a user with username/email and password',
|
||||||
accepts: [
|
accepts: [
|
||||||
{arg: 'credentials', type: 'object', required: true, http: {source: 'body'}},
|
{arg: 'credentials', type: 'object', required: true, http: {source: 'body'}},
|
||||||
{arg: 'include', type: 'string', http: {source: 'query' }, description:
|
{arg: 'include', type: 'string', http: {source: 'query' }, description: 'Related objects to include in the response. ' +
|
||||||
'Related objects to include in the response. ' +
|
|
||||||
'See the description of return value for more details.'}
|
'See the description of return value for more details.'}
|
||||||
],
|
],
|
||||||
returns: {
|
returns: {
|
||||||
arg: 'accessToken', type: 'object', root: true, description:
|
arg: 'accessToken', type: 'object', root: true, description: 'The response body contains properties of the AccessToken created on login.\n' +
|
||||||
'The response body contains properties of the AccessToken created on login.\n' +
|
|
||||||
'Depending on the value of `include` parameter, the body may contain ' +
|
'Depending on the value of `include` parameter, the body may contain ' +
|
||||||
'additional properties:\n\n' +
|
'additional properties:\n\n' +
|
||||||
' - `user` - `{User}` - Data of the currently logged in user. (`include=user`)\n\n'
|
' - `user` - `{User}` - Data of the currently logged in user. (`include=user`)\n\n'
|
||||||
|
@ -517,8 +425,7 @@ User.setup = function () {
|
||||||
var tokenID = accessToken && accessToken.id;
|
var tokenID = accessToken && accessToken.id;
|
||||||
|
|
||||||
return tokenID;
|
return tokenID;
|
||||||
}, description:
|
}, description: 'Do not supply this argument, it is automatically extracted ' +
|
||||||
'Do not supply this argument, it is automatically extracted ' +
|
|
||||||
'from request headers.'
|
'from request headers.'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
@ -550,9 +457,9 @@ User.setup = function () {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
UserModel.on('attached', function () {
|
UserModel.on('attached', function() {
|
||||||
UserModel.afterRemote('confirm', function (ctx, inst, next) {
|
UserModel.afterRemote('confirm', function(ctx, inst, next) {
|
||||||
if(ctx.req) {
|
if (ctx.req) {
|
||||||
ctx.res.redirect(ctx.req.param('redirect'));
|
ctx.res.redirect(ctx.req.param('redirect'));
|
||||||
} else {
|
} else {
|
||||||
fn(new Error('transport unsupported'));
|
fn(new Error('transport unsupported'));
|
||||||
|
@ -561,8 +468,11 @@ User.setup = function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
// default models
|
// default models
|
||||||
UserModel.email = require('./email');
|
assert(loopback.Email, 'Email model must be defined before User model');
|
||||||
UserModel.accessToken = require('./access-token');
|
UserModel.email = loopback.Email;
|
||||||
|
|
||||||
|
assert(loopback.AccessToken, 'AccessToken model must be defined before User model');
|
||||||
|
UserModel.accessToken = loopback.AccessToken;
|
||||||
|
|
||||||
// email validation regex
|
// email validation regex
|
||||||
var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
||||||
|
@ -579,3 +489,5 @@ User.setup = function () {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
User.setup();
|
User.setup();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
{
|
||||||
|
"name": "User",
|
||||||
|
"properties": {
|
||||||
|
"realm": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"username": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"password": {
|
||||||
|
"type": "string",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"credentials": {
|
||||||
|
"type": "object",
|
||||||
|
"deprecated": true
|
||||||
|
},
|
||||||
|
"challenges": {
|
||||||
|
"type": "object",
|
||||||
|
"deprecated": true
|
||||||
|
},
|
||||||
|
"email": {
|
||||||
|
"type": "string",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"emailVerified": "boolean",
|
||||||
|
"verificationToken": "string",
|
||||||
|
"status": "string",
|
||||||
|
"created": "date",
|
||||||
|
"lastUpdated": "date"
|
||||||
|
},
|
||||||
|
"hidden": ["password"],
|
||||||
|
"acls": [
|
||||||
|
{
|
||||||
|
"principalType": "ROLE",
|
||||||
|
"principalId": "$everyone",
|
||||||
|
"permission": "DENY"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"principalType": "ROLE",
|
||||||
|
"principalId": "$everyone",
|
||||||
|
"permission": "ALLOW",
|
||||||
|
"property": "create"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"principalType": "ROLE",
|
||||||
|
"principalId": "$owner",
|
||||||
|
"permission": "ALLOW",
|
||||||
|
"property": "deleteById"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"principalType": "ROLE",
|
||||||
|
"principalId": "$everyone",
|
||||||
|
"permission": "ALLOW",
|
||||||
|
"property": "login"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"principalType": "ROLE",
|
||||||
|
"principalId": "$everyone",
|
||||||
|
"permission": "ALLOW",
|
||||||
|
"property": "logout"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"principalType": "ROLE",
|
||||||
|
"principalId": "$owner",
|
||||||
|
"permission": "ALLOW",
|
||||||
|
"property": "findById"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"principalType": "ROLE",
|
||||||
|
"principalId": "$owner",
|
||||||
|
"permission": "ALLOW",
|
||||||
|
"property": "updateAttributes"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"principalType": "ROLE",
|
||||||
|
"principalId": "$everyone",
|
||||||
|
"permission": "ACL.ALLOW",
|
||||||
|
"property": "confirm"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"principalType": "ROLE",
|
||||||
|
"principalId": "$everyone",
|
||||||
|
"permission": "ALLOW",
|
||||||
|
"property": "resetPassword",
|
||||||
|
"accessType": "EXECUTE"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"relations": {
|
||||||
|
"accessTokens": {
|
||||||
|
"type": "hasMany",
|
||||||
|
"model": "AccessToken",
|
||||||
|
"foreignKey": "userId"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,12 +1,19 @@
|
||||||
module.exports = function(loopback) {
|
module.exports = function(loopback) {
|
||||||
|
// NOTE(bajtos) we must use static require() due to browserify limitations
|
||||||
|
|
||||||
loopback.Email = require('../common/models/email');
|
loopback.Email = require('../common/models/email');
|
||||||
loopback.User = require('../common/models/user');
|
|
||||||
loopback.Application = require('../common/models/application');
|
loopback.Application = require('../common/models/application');
|
||||||
loopback.AccessToken = require('../common/models/access-token');
|
loopback.AccessToken = require('../common/models/access-token');
|
||||||
loopback.Role = require('../common/models/role').Role;
|
loopback.Role = require('../common/models/role').Role;
|
||||||
loopback.RoleMapping = require('../common/models/role').RoleMapping;
|
loopback.RoleMapping = require('../common/models/role').RoleMapping;
|
||||||
loopback.ACL = require('../common/models/acl').ACL;
|
loopback.ACL = require('../common/models/acl').ACL;
|
||||||
loopback.Scope = require('../common/models/acl').Scope;
|
loopback.Scope = require('../common/models/acl').Scope;
|
||||||
|
|
||||||
|
loopback.User = createModel(
|
||||||
|
require('../common/models/user.json'),
|
||||||
|
require('../common/models/user.js'));
|
||||||
|
|
||||||
loopback.Change = require('../common/models/change');
|
loopback.Change = require('../common/models/change');
|
||||||
loopback.Checkpoint = require('../common/models/checkpoint');
|
loopback.Checkpoint = require('../common/models/checkpoint');
|
||||||
|
|
||||||
|
@ -28,4 +35,10 @@ module.exports = function(loopback) {
|
||||||
loopback.ACL.autoAttach = dataSourceTypes.DB;
|
loopback.ACL.autoAttach = dataSourceTypes.DB;
|
||||||
loopback.Scope.autoAttach = dataSourceTypes.DB;
|
loopback.Scope.autoAttach = dataSourceTypes.DB;
|
||||||
loopback.Application.autoAttach = dataSourceTypes.DB;
|
loopback.Application.autoAttach = dataSourceTypes.DB;
|
||||||
|
|
||||||
|
function createModel(definitionJson, customizeFn) {
|
||||||
|
var Model = loopback.createModel(definitionJson);
|
||||||
|
customizeFn(Model);
|
||||||
|
return Model;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue